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 | SETUP_TEARDOWN_TESTCONTEXT |
34 | |
35 | const int MAX_SENDS = 10000; |
36 | |
37 | enum TestType |
38 | { |
39 | BIND_FIRST, |
40 | CONNECT_FIRST |
41 | }; |
42 | |
43 | void test_defaults () |
44 | { |
45 | // Set up bind socket |
46 | void *bind_socket = test_context_socket (ZMQ_PULL); |
47 | TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (bind_socket, "inproc://a" )); |
48 | |
49 | // Set up connect socket |
50 | void *connect_socket = test_context_socket (ZMQ_PUSH); |
51 | TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (connect_socket, "inproc://a" )); |
52 | |
53 | // Send until we block |
54 | int send_count = 0; |
55 | while (send_count < MAX_SENDS |
56 | && zmq_send (connect_socket, NULL, 0, ZMQ_DONTWAIT) == 0) |
57 | ++send_count; |
58 | |
59 | msleep (SETTLE_TIME); |
60 | |
61 | // Now receive all sent messages |
62 | int recv_count = 0; |
63 | while (zmq_recv (bind_socket, NULL, 0, ZMQ_DONTWAIT) == 0) |
64 | ++recv_count; |
65 | |
66 | TEST_ASSERT_EQUAL_INT (send_count, recv_count); |
67 | |
68 | // Clean up |
69 | test_context_socket_close (connect_socket); |
70 | test_context_socket_close (bind_socket); |
71 | |
72 | // Default values are 1000 on send and 1000 one receive, so 2000 total |
73 | TEST_ASSERT_EQUAL_INT (2000, send_count); |
74 | } |
75 | |
76 | int count_msg (int send_hwm_, int recv_hwm_, TestType test_type_) |
77 | { |
78 | void *bind_socket; |
79 | void *connect_socket; |
80 | if (test_type_ == BIND_FIRST) { |
81 | // Set up bind socket |
82 | bind_socket = test_context_socket (ZMQ_PULL); |
83 | TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt ( |
84 | bind_socket, ZMQ_RCVHWM, &recv_hwm_, sizeof (recv_hwm_))); |
85 | TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (bind_socket, "inproc://a" )); |
86 | |
87 | // Set up connect socket |
88 | connect_socket = test_context_socket (ZMQ_PUSH); |
89 | TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt ( |
90 | connect_socket, ZMQ_SNDHWM, &send_hwm_, sizeof (send_hwm_))); |
91 | TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (connect_socket, "inproc://a" )); |
92 | |
93 | // we must wait for the connect to succeed here, unfortunately we don't |
94 | // have monitoring events for inproc, so we just hope SETTLE_TIME suffices |
95 | msleep (SETTLE_TIME); |
96 | } else { |
97 | // Set up connect socket |
98 | connect_socket = test_context_socket (ZMQ_PUSH); |
99 | TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt ( |
100 | connect_socket, ZMQ_SNDHWM, &send_hwm_, sizeof (send_hwm_))); |
101 | TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (connect_socket, "inproc://a" )); |
102 | |
103 | // Set up bind socket |
104 | bind_socket = test_context_socket (ZMQ_PULL); |
105 | TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt ( |
106 | bind_socket, ZMQ_RCVHWM, &recv_hwm_, sizeof (recv_hwm_))); |
107 | TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (bind_socket, "inproc://a" )); |
108 | } |
109 | |
110 | // Send until we block |
111 | int send_count = 0; |
112 | while (send_count < MAX_SENDS |
113 | && zmq_send (connect_socket, NULL, 0, ZMQ_DONTWAIT) == 0) |
114 | ++send_count; |
115 | |
116 | // Now receive all sent messages |
117 | int recv_count = 0; |
118 | while (zmq_recv (bind_socket, NULL, 0, ZMQ_DONTWAIT) == 0) |
119 | ++recv_count; |
120 | |
121 | TEST_ASSERT_EQUAL_INT (send_count, recv_count); |
122 | |
123 | // Now it should be possible to send one more. |
124 | send_string_expect_success (connect_socket, NULL, 0); |
125 | |
126 | // Consume the remaining message. |
127 | recv_string_expect_success (bind_socket, NULL, 0); |
128 | |
129 | // Clean up |
130 | test_context_socket_close (connect_socket); |
131 | test_context_socket_close (bind_socket); |
132 | |
133 | return send_count; |
134 | } |
135 | |
136 | int test_inproc_bind_first (int send_hwm_, int recv_hwm_) |
137 | { |
138 | return count_msg (send_hwm_, recv_hwm_, BIND_FIRST); |
139 | } |
140 | |
141 | int test_inproc_connect_first (int send_hwm_, int recv_hwm_) |
142 | { |
143 | return count_msg (send_hwm_, recv_hwm_, CONNECT_FIRST); |
144 | } |
145 | |
146 | int test_inproc_connect_and_close_first (int send_hwm_, int recv_hwm_) |
147 | { |
148 | // Set up connect socket |
149 | void *connect_socket = test_context_socket (ZMQ_PUSH); |
150 | TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (connect_socket, ZMQ_SNDHWM, |
151 | &send_hwm_, sizeof (send_hwm_))); |
152 | TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (connect_socket, "inproc://a" )); |
153 | |
154 | // Send until we block |
155 | int send_count = 0; |
156 | while (send_count < MAX_SENDS |
157 | && zmq_send (connect_socket, NULL, 0, ZMQ_DONTWAIT) == 0) |
158 | ++send_count; |
159 | |
160 | // Close connect |
161 | test_context_socket_close (connect_socket); |
162 | |
163 | // Set up bind socket |
164 | void *bind_socket = test_context_socket (ZMQ_PULL); |
165 | TEST_ASSERT_SUCCESS_ERRNO ( |
166 | zmq_setsockopt (bind_socket, ZMQ_RCVHWM, &recv_hwm_, sizeof (recv_hwm_))); |
167 | TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (bind_socket, "inproc://a" )); |
168 | |
169 | // Now receive all sent messages |
170 | int recv_count = 0; |
171 | while (zmq_recv (bind_socket, NULL, 0, ZMQ_DONTWAIT) == 0) |
172 | ++recv_count; |
173 | |
174 | TEST_ASSERT_EQUAL_INT (send_count, recv_count); |
175 | |
176 | // Clean up |
177 | test_context_socket_close (bind_socket); |
178 | |
179 | return send_count; |
180 | } |
181 | |
182 | int test_inproc_bind_and_close_first (int send_hwm_, int /* recv_hwm */) |
183 | { |
184 | // Set up bind socket |
185 | void *bind_socket = test_context_socket (ZMQ_PUSH); |
186 | TEST_ASSERT_SUCCESS_ERRNO ( |
187 | zmq_setsockopt (bind_socket, ZMQ_SNDHWM, &send_hwm_, sizeof (send_hwm_))); |
188 | TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (bind_socket, "inproc://a" )); |
189 | |
190 | // Send until we block |
191 | int send_count = 0; |
192 | while (send_count < MAX_SENDS |
193 | && zmq_send (bind_socket, NULL, 0, ZMQ_DONTWAIT) == 0) |
194 | ++send_count; |
195 | |
196 | // Close bind |
197 | test_context_socket_close (bind_socket); |
198 | |
199 | /* TODO Can't currently do connect without then wiring up a bind as things hang, this needs top be fixed. |
200 | // Set up connect socket |
201 | void *connect_socket = test_context_socket (ZMQ_PULL); |
202 | TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (connect_socket, ZMQ_RCVHWM, &recv_hwm, sizeof (recv_hwm))); |
203 | TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (connect_socket, "inproc://a")); |
204 | |
205 | // Now receive all sent messages |
206 | int recv_count = 0; |
207 | while (zmq_recv (connect_socket, NULL, 0, ZMQ_DONTWAIT) == 0) |
208 | ++recv_count; |
209 | |
210 | TEST_ASSERT_EQUAL_INT(send_count, recv_count); |
211 | */ |
212 | |
213 | // Clean up |
214 | //test_context_socket_close (connect_socket); |
215 | |
216 | return send_count; |
217 | } |
218 | |
219 | void test_infinite_both_inproc_bind_first () |
220 | { |
221 | int count = test_inproc_bind_first (0, 0); |
222 | TEST_ASSERT_EQUAL_INT (MAX_SENDS, count); |
223 | } |
224 | |
225 | void test_infinite_both_inproc_connect_first () |
226 | { |
227 | int count = test_inproc_connect_first (0, 0); |
228 | TEST_ASSERT_EQUAL_INT (MAX_SENDS, count); |
229 | } |
230 | |
231 | void test_infinite_receive_inproc_bind_first () |
232 | { |
233 | int count = test_inproc_bind_first (1, 0); |
234 | TEST_ASSERT_EQUAL_INT (MAX_SENDS, count); |
235 | } |
236 | |
237 | void test_infinite_receive_inproc_connect_first () |
238 | { |
239 | int count = test_inproc_connect_first (1, 0); |
240 | TEST_ASSERT_EQUAL_INT (MAX_SENDS, count); |
241 | } |
242 | |
243 | void test_infinite_send_inproc_bind_first () |
244 | { |
245 | int count = test_inproc_bind_first (0, 1); |
246 | TEST_ASSERT_EQUAL_INT (MAX_SENDS, count); |
247 | } |
248 | |
249 | void test_infinite_send_inproc_connect_first () |
250 | { |
251 | int count = test_inproc_connect_first (0, 1); |
252 | TEST_ASSERT_EQUAL_INT (MAX_SENDS, count); |
253 | } |
254 | |
255 | void test_finite_both_bind_first () |
256 | { |
257 | // Send and recv buffers hwm 1, so total that can be queued is 2 |
258 | int count = test_inproc_bind_first (1, 1); |
259 | TEST_ASSERT_EQUAL_INT (2, count); |
260 | } |
261 | void test_finite_both_connect_first () |
262 | { |
263 | // Send and recv buffers hwm 1, so total that can be queued is 2 |
264 | int count = test_inproc_connect_first (1, 1); |
265 | TEST_ASSERT_EQUAL_INT (2, count); |
266 | } |
267 | |
268 | void test_infinite_recv_connect_and_close_first () |
269 | { |
270 | // Send hwm of 1, send before bind so total that can be queued is 1 |
271 | int count = test_inproc_connect_and_close_first (1, 0); |
272 | TEST_ASSERT_EQUAL_INT (1, count); |
273 | } |
274 | |
275 | void test_infinite_recv_bind_and_close_first () |
276 | { |
277 | // Send hwm of 1, send from bind side before connect so total that can be queued should be 1, |
278 | // however currently all messages get thrown away before the connect. BUG? |
279 | /*int count = */ test_inproc_bind_and_close_first (1, 0); |
280 | // TEST_ASSERT_EQUAL_INT (1, count); |
281 | } |
282 | |
283 | int main (void) |
284 | { |
285 | setup_test_environment (); |
286 | |
287 | UNITY_BEGIN (); |
288 | RUN_TEST (test_defaults); |
289 | |
290 | RUN_TEST (test_infinite_both_inproc_bind_first); |
291 | RUN_TEST (test_infinite_both_inproc_connect_first); |
292 | |
293 | RUN_TEST (test_infinite_receive_inproc_bind_first); |
294 | RUN_TEST (test_infinite_receive_inproc_connect_first); |
295 | |
296 | RUN_TEST (test_infinite_send_inproc_bind_first); |
297 | RUN_TEST (test_infinite_send_inproc_connect_first); |
298 | |
299 | RUN_TEST (test_finite_both_bind_first); |
300 | RUN_TEST (test_finite_both_connect_first); |
301 | |
302 | RUN_TEST (test_infinite_recv_connect_and_close_first); |
303 | RUN_TEST (test_infinite_recv_bind_and_close_first); |
304 | |
305 | return UNITY_END (); |
306 | } |
307 | |