1/*
2 Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file
3
4 This file is part of libzmq, the ZeroMQ core engine in C++.
5
6 libzmq is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License (LGPL) as published
8 by the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 As a special exception, the Contributors give you permission to link
12 this library with independent modules to produce an executable,
13 regardless of the license terms of these independent modules, and to
14 copy and distribute the resulting executable under terms of your choice,
15 provided that you also meet, for each linked independent module, the
16 terms and conditions of the license of that module. An independent
17 module is a module which is not derived from or based on this library.
18 If you modify this library, you must extend this exception to your
19 version of the library.
20
21 libzmq is distributed in the hope that it will be useful, but WITHOUT
22 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
24 License for more details.
25
26 You should have received a copy of the GNU Lesser General Public License
27 along with this program. If not, see <http://www.gnu.org/licenses/>.
28*/
29
30#include "testutil.hpp"
31#include "testutil_unity.hpp"
32
33#include <unity.h>
34
35void setUp ()
36{
37}
38
39void tearDown ()
40{
41}
42
43static void receiver (void *socket_)
44{
45 char buffer[16];
46 int rc = zmq_recv (socket_, &buffer, sizeof (buffer), 0);
47 // TODO which error is expected here? use TEST_ASSERT_FAILURE_ERRNO instead
48 TEST_ASSERT_EQUAL_INT (-1, rc);
49}
50
51void test_ctx_destroy ()
52{
53 // Set up our context and sockets
54 void *ctx = zmq_ctx_new ();
55 TEST_ASSERT_NOT_NULL (ctx);
56
57 void *socket = zmq_socket (ctx, ZMQ_PULL);
58 TEST_ASSERT_NOT_NULL (socket);
59
60 // Close the socket
61 TEST_ASSERT_SUCCESS_ERRNO (zmq_close (socket));
62
63 // Destroy the context
64 TEST_ASSERT_SUCCESS_ERRNO (zmq_ctx_destroy (ctx));
65}
66
67void test_ctx_shutdown ()
68{
69 // Set up our context and sockets
70 void *ctx = zmq_ctx_new ();
71 TEST_ASSERT_NOT_NULL (ctx);
72
73 void *socket = zmq_socket (ctx, ZMQ_PULL);
74 TEST_ASSERT_NOT_NULL (socket);
75
76 // Spawn a thread to receive on socket
77 void *receiver_thread = zmq_threadstart (&receiver, socket);
78
79 // Wait for thread to start up and block
80 msleep (SETTLE_TIME);
81
82 // Shutdown context, if we used destroy here we would deadlock.
83 TEST_ASSERT_SUCCESS_ERRNO (zmq_ctx_shutdown (ctx));
84
85 // Wait for thread to finish
86 zmq_threadclose (receiver_thread);
87
88 // Close the socket.
89 TEST_ASSERT_SUCCESS_ERRNO (zmq_close (socket));
90
91 // Destory the context, will now not hang as we have closed the socket.
92 TEST_ASSERT_SUCCESS_ERRNO (zmq_ctx_destroy (ctx));
93}
94
95void test_zmq_ctx_term_null_fails ()
96{
97 int rc = zmq_ctx_term (NULL);
98 TEST_ASSERT_EQUAL_INT (-1, rc);
99 TEST_ASSERT_EQUAL_INT (EFAULT, errno);
100}
101
102void test_zmq_term_null_fails ()
103{
104 int rc = zmq_term (NULL);
105 TEST_ASSERT_EQUAL_INT (-1, rc);
106 TEST_ASSERT_EQUAL_INT (EFAULT, errno);
107}
108
109void test_zmq_ctx_shutdown_null_fails ()
110{
111 int rc = zmq_ctx_shutdown (NULL);
112 TEST_ASSERT_EQUAL_INT (-1, rc);
113 TEST_ASSERT_EQUAL_INT (EFAULT, errno);
114}
115
116#ifdef ZMQ_HAVE_POLLER
117struct poller_test_data_t
118{
119 int socket_type;
120 void *ctx;
121 void *counter;
122};
123
124void run_poller (void *data_)
125{
126 struct poller_test_data_t *poller_test_data =
127 static_cast<struct poller_test_data_t *> (data_);
128
129 void *socket =
130 zmq_socket (poller_test_data->ctx, poller_test_data->socket_type);
131 TEST_ASSERT_NOT_NULL (socket);
132
133 void *poller = zmq_poller_new ();
134 TEST_ASSERT_NOT_NULL (poller);
135
136 TEST_ASSERT_SUCCESS_ERRNO (
137 zmq_poller_add (poller, socket, NULL, ZMQ_POLLIN));
138
139 zmq_atomic_counter_set (poller_test_data->counter, 1);
140
141 zmq_poller_event_t event;
142 TEST_ASSERT_FAILURE_ERRNO (ETERM, zmq_poller_wait (poller, &event, -1));
143
144 TEST_ASSERT_SUCCESS_ERRNO (zmq_poller_destroy (&poller));
145
146 // Close the socket
147 TEST_ASSERT_SUCCESS_ERRNO (zmq_close (socket));
148}
149#endif
150
151void test_poller_exists_with_socket_on_zmq_ctx_term (const int socket_type_)
152{
153#ifdef ZMQ_HAVE_POLLER
154 struct poller_test_data_t poller_test_data;
155
156 poller_test_data.socket_type = socket_type_;
157
158 // Set up our context and sockets
159 poller_test_data.ctx = zmq_ctx_new ();
160 TEST_ASSERT_NOT_NULL (poller_test_data.ctx);
161
162 poller_test_data.counter = zmq_atomic_counter_new ();
163 TEST_ASSERT_NOT_NULL (poller_test_data.counter);
164
165 void *thread = zmq_threadstart (run_poller, &poller_test_data);
166 TEST_ASSERT_NOT_NULL (thread);
167
168 while (zmq_atomic_counter_value (poller_test_data.counter) == 0) {
169 msleep (10);
170 }
171
172 // Destroy the context
173 TEST_ASSERT_SUCCESS_ERRNO (zmq_ctx_destroy (poller_test_data.ctx));
174
175 zmq_threadclose (thread);
176
177 zmq_atomic_counter_destroy (&poller_test_data.counter);
178#else
179 TEST_IGNORE_MESSAGE ("libzmq without zmq_poller_* support, ignoring test");
180#endif
181}
182
183void test_poller_exists_with_socket_on_zmq_ctx_term_thread_safe_socket ()
184{
185#ifdef ZMQ_BUILD_DRAFT_API
186 test_poller_exists_with_socket_on_zmq_ctx_term (ZMQ_CLIENT);
187#else
188 TEST_IGNORE_MESSAGE ("libzmq without DRAFT support, ignoring test");
189#endif
190}
191
192void test_poller_exists_with_socket_on_zmq_ctx_term_non_thread_safe_socket ()
193{
194 test_poller_exists_with_socket_on_zmq_ctx_term (ZMQ_DEALER);
195}
196
197int main (void)
198{
199 setup_test_environment ();
200
201 UNITY_BEGIN ();
202 RUN_TEST (test_ctx_destroy);
203 RUN_TEST (test_ctx_shutdown);
204 RUN_TEST (test_zmq_ctx_term_null_fails);
205 RUN_TEST (test_zmq_term_null_fails);
206 RUN_TEST (test_zmq_ctx_shutdown_null_fails);
207
208 RUN_TEST (
209 test_poller_exists_with_socket_on_zmq_ctx_term_non_thread_safe_socket);
210 RUN_TEST (
211 test_poller_exists_with_socket_on_zmq_ctx_term_thread_safe_socket);
212
213 return UNITY_END ();
214}
215