test_req_relaxed.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MPL-2.0 */
2 
3 #include "testutil.hpp"
4 #include "testutil_unity.hpp"
5 
6 #include <unity.h>
7 
8 const size_t services = 5;
9 
10 void *req;
11 void *rep[services];
12 
13 void setUp ()
14 {
16 
19 
20  int enabled = 1;
22  zmq_setsockopt (req, ZMQ_REQ_RELAXED, &enabled, sizeof (int)));
23 
25  zmq_setsockopt (req, ZMQ_REQ_CORRELATE, &enabled, sizeof (int)));
26 
28 
29  for (size_t peer = 0; peer < services; peer++) {
31 
33 
34  // These tests require strict ordering, so wait for the connections to
35  // happen before opening the next, so that messages flow in the
36  // expected direction
38  }
39 }
40 
41 void tearDown ()
42 {
44  for (size_t peer = 0; peer < services; peer++)
46 
48 }
49 
50 static void bounce (void *socket_)
51 {
52  int more;
53  size_t more_size = sizeof (more);
54  do {
55  zmq_msg_t recv_part, sent_part;
57 
58  TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_recv (&recv_part, socket_, 0));
59 
61  zmq_getsockopt (socket_, ZMQ_RCVMORE, &more, &more_size));
62 
63  zmq_msg_init (&sent_part);
64  zmq_msg_copy (&sent_part, &recv_part);
65 
67  zmq_msg_send (&sent_part, socket_, more ? ZMQ_SNDMORE : 0));
68 
69  zmq_msg_close (&recv_part);
70  } while (more);
71 }
72 
73 static int get_events (void *socket_)
74 {
75  int events;
76  size_t events_size = sizeof (events);
78  zmq_getsockopt (socket_, ZMQ_EVENTS, &events, &events_size));
79  return events;
80 }
81 
82 void test_case_1 ()
83 {
84  // Case 1: Second send() before a reply arrives in a pipe.
85 
86  int events = get_events (req);
88 
89  // Send a request, ensure it arrives, don't send a reply
90  s_send_seq (req, "A", "B", SEQ_END);
91  s_recv_seq (rep[0], "A", "B", SEQ_END);
92 
93  events = get_events (req);
95 
96  // Send another request on the REQ socket
97  s_send_seq (req, "C", "D", SEQ_END);
98  s_recv_seq (rep[1], "C", "D", SEQ_END);
99 
100  events = get_events (req);
102 
103  // Send a reply to the first request - that should be discarded by the REQ
104  s_send_seq (rep[0], "WRONG", SEQ_END);
105 
106  // Send the expected reply
107  s_send_seq (rep[1], "OK", SEQ_END);
108  s_recv_seq (req, "OK", SEQ_END);
109 
110  // Another standard req-rep cycle, just to check
111  s_send_seq (req, "E", SEQ_END);
112  s_recv_seq (rep[2], "E", SEQ_END);
113  s_send_seq (rep[2], "F", "G", SEQ_END);
114  s_recv_seq (req, "F", "G", SEQ_END);
115 }
116 
117 void test_case_2 ()
118 {
119  // Case 2: Second send() after a reply is already in a pipe on the REQ.
120 
121  // TODO instead of rerunning the previous test cases, only do the relevant parts (or change the peer)
122  test_case_1 ();
123 
124  // Send a request, ensure it arrives, send a reply
125  s_send_seq (req, "H", SEQ_END);
126  s_recv_seq (rep[3], "H", SEQ_END);
127  s_send_seq (rep[3], "BAD", SEQ_END);
128 
129  // Wait for message to be there.
131 
132  // Without receiving that reply, send another request on the REQ socket
133  s_send_seq (req, "I", SEQ_END);
134  s_recv_seq (rep[4], "I", SEQ_END);
135 
136  // Send the expected reply
137  s_send_seq (rep[4], "GOOD", SEQ_END);
138  s_recv_seq (req, "GOOD", SEQ_END);
139 }
140 
141 void test_case_3 ()
142 {
143  // Case 3: Check issue #1690. Two send() in a row should not close the
144  // communication pipes. For example pipe from req to rep[0] should not be
145  // closed after executing Case 1. So rep[0] should be the next to receive,
146  // not rep[1].
147 
148  // TODO instead of rerunning the previous test cases, only do the relevant parts (or change the peer)
149  test_case_2 ();
150 
151  s_send_seq (req, "J", SEQ_END);
152  s_recv_seq (rep[0], "J", SEQ_END);
153 }
154 
155 void test_case_4 ()
156 {
157  // TODO this test case does not use the sockets from setUp
158 
159  // Case 4: Check issue #1695. As messages may pile up before a responder
160  // is available, we check that responses to messages other than the last
161  // sent one are correctly discarded by the REQ pipe
162 
163  // Setup REQ socket as client
164  void *req = test_context_socket (ZMQ_REQ);
165 
166  int enabled = 1;
168  zmq_setsockopt (req, ZMQ_REQ_RELAXED, &enabled, sizeof (int)));
170  zmq_setsockopt (req, ZMQ_REQ_CORRELATE, &enabled, sizeof (int)));
171 
173 
174  // Setup ROUTER socket as server but do not bind it just yet
175  void *router = test_context_socket (ZMQ_ROUTER);
176 
177  // Send two requests
178  s_send_seq (req, "TO_BE_DISCARDED", SEQ_END);
179  s_send_seq (req, "TO_BE_ANSWERED", SEQ_END);
180 
181  // Bind server allowing it to receive messages
183 
184  // Read the two messages and send them back as is
185  bounce (router);
186  bounce (router);
187 
188  // Read the expected correlated reply. As the ZMQ_REQ_CORRELATE is active,
189  // the expected answer is "TO_BE_ANSWERED", not "TO_BE_DISCARDED".
190  s_recv_seq (req, "TO_BE_ANSWERED", SEQ_END);
191 
194 }
195 
196 int main ()
197 {
199 
200  UNITY_BEGIN ();
205  return UNITY_END ();
206 }
ENDPOINT_0
#define ENDPOINT_0
Definition: libzmq/tests/testutil.hpp:39
bounce
static void bounce(void *socket_)
Definition: test_req_relaxed.cpp:50
UNITY_END
return UNITY_END()
ZMQ_EVENTS
#define ZMQ_EVENTS
Definition: zmq.h:286
main
int main()
Definition: test_req_relaxed.cpp:196
msleep
void msleep(int milliseconds_)
Definition: testutil.cpp:227
zmq_msg_send
ZMQ_EXPORT int zmq_msg_send(zmq_msg_t *msg_, void *s_, int flags_)
Definition: zmq.cpp:609
tearDown
void tearDown()
Definition: test_req_relaxed.cpp:41
RUN_TEST
#define RUN_TEST(func)
Definition: unity_internals.h:615
setup_test_context
void setup_test_context()
Definition: testutil_unity.cpp:179
bind_loopback_ipv4
void bind_loopback_ipv4(void *socket_, char *my_endpoint_, size_t len_)
Definition: testutil_unity.cpp:246
teardown_test_context
void teardown_test_context()
Definition: testutil_unity.cpp:189
rep
void * rep[services]
Definition: test_req_relaxed.cpp:11
services
const size_t services
Definition: test_req_relaxed.cpp:8
test_context_socket_close_zero_linger
void * test_context_socket_close_zero_linger(void *socket_)
Definition: testutil_unity.cpp:215
ZMQ_REQ
#define ZMQ_REQ
Definition: zmq.h:261
test_case_2
void test_case_2()
Definition: test_req_relaxed.cpp:117
zmq_connect
ZMQ_EXPORT int zmq_connect(void *s_, const char *addr_)
Definition: zmq.cpp:307
ZMQ_REQ_RELAXED
#define ZMQ_REQ_RELAXED
Definition: zmq.h:318
test_case_1
void test_case_1()
Definition: test_req_relaxed.cpp:82
enabled
GLenum GLenum GLsizei const GLuint GLboolean enabled
Definition: glcorearb.h:4174
testutil_unity.hpp
ZMQ_POLLOUT
#define ZMQ_POLLOUT
Definition: zmq.h:483
zmq_setsockopt
ZMQ_EXPORT int zmq_setsockopt(void *s_, int option_, const void *optval_, size_t optvallen_)
Definition: zmq.cpp:250
testutil.hpp
ZMQ_ROUTER
#define ZMQ_ROUTER
Definition: zmq.h:264
zmq_msg_t
Definition: zmq.h:218
ZMQ_REP
#define ZMQ_REP
Definition: zmq.h:262
my_endpoint
char my_endpoint[MAX_SOCKET_STRING]
Definition: test_security_curve.cpp:31
MAX_SOCKET_STRING
#define MAX_SOCKET_STRING
Definition: libzmq/tests/testutil.hpp:35
zmq_bind
ZMQ_EXPORT int zmq_bind(void *s_, const char *addr_)
Definition: zmq.cpp:299
zmq_msg_recv
ZMQ_EXPORT int zmq_msg_recv(zmq_msg_t *msg_, void *s_, int flags_)
Definition: zmq.cpp:617
test_context_socket
void * test_context_socket(int type_)
Definition: testutil_unity.cpp:200
SETTLE_TIME
#define SETTLE_TIME
Definition: libzmq/tests/testutil.hpp:31
TEST_ASSERT_EQUAL_INT
#define TEST_ASSERT_EQUAL_INT(expected, actual)
Definition: unity.h:128
zmq_msg_init
ZMQ_EXPORT int zmq_msg_init(zmq_msg_t *msg_)
Definition: zmq.cpp:587
unity.h
SEQ_END
const char * SEQ_END
Definition: testutil.cpp:47
req
void * req
Definition: test_req_relaxed.cpp:10
s_send_seq
void s_send_seq(void *socket_,...)
Definition: testutil.cpp:135
setup_test_environment
void setup_test_environment(int timeout_seconds_)
Definition: testutil.cpp:201
UNITY_BEGIN
UNITY_BEGIN()
s_recv_seq
void s_recv_seq(void *socket_,...)
Definition: testutil.cpp:158
zmq_msg_copy
ZMQ_EXPORT int zmq_msg_copy(zmq_msg_t *dest_, zmq_msg_t *src_)
Definition: zmq.cpp:636
ZMQ_SNDMORE
#define ZMQ_SNDMORE
Definition: zmq.h:359
ZMQ_REQ_CORRELATE
#define ZMQ_REQ_CORRELATE
Definition: zmq.h:317
test_case_3
void test_case_3()
Definition: test_req_relaxed.cpp:141
setUp
void setUp()
Definition: test_req_relaxed.cpp:13
get_events
static int get_events(void *socket_)
Definition: test_req_relaxed.cpp:73
ZMQ_RCVMORE
#define ZMQ_RCVMORE
Definition: zmq.h:284
zmq_msg_close
ZMQ_EXPORT int zmq_msg_close(zmq_msg_t *msg_)
Definition: zmq.cpp:625
test_case_4
void test_case_4()
Definition: test_req_relaxed.cpp:155
TEST_ASSERT_SUCCESS_ERRNO
#define TEST_ASSERT_SUCCESS_ERRNO(expr)
Definition: proxy_thr.cpp:47
zmq_getsockopt
ZMQ_EXPORT int zmq_getsockopt(void *s_, int option_, void *optval_, size_t *optvallen_)
Definition: zmq.cpp:261


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:59