void test_rebind_ipc () { char my_endpoint[32]; make_random_ipc_endpoint (my_endpoint); void *sb0 = test_context_socket (ZMQ_PUSH); void *sb1 = test_context_socket (ZMQ_PUSH); TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (sb0, my_endpoint)); void *sc = test_context_socket (ZMQ_PULL); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sc, my_endpoint)); send_string_expect_success (sb0, "42", 0); recv_string_expect_success (sc, "42", 0); test_context_socket_close (sb0); TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (sb1, my_endpoint)); send_string_expect_success (sb1, "42", 0); recv_string_expect_success (sc, "42", 0); test_context_socket_close (sc); test_context_socket_close (sb1); }
void test_send_disconnected_with_delay () { // TEST 3 // This time we want to validate that the same blocking behaviour // occurs with an existing connection that is broken. We will send // messages to a connected pipe, disconnect and verify the messages // block. Then we reconnect and verify messages flow again. void *backend = test_context_socket (ZMQ_DEALER); void *frontend = test_context_socket (ZMQ_DEALER); int zero = 0; TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (backend, ZMQ_LINGER, &zero, sizeof (zero))); TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (frontend, ZMQ_LINGER, &zero, sizeof (zero))); // Frontend connects to backend using DELAY_ATTACH_ON_CONNECT int on = 1; TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (frontend, ZMQ_DELAY_ATTACH_ON_CONNECT, &on, sizeof (on))); TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (backend, "tipc://{5560,0,0}")); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (frontend, "tipc://{5560,0}@0.0.0")); // Ping backend to frontend so we know when the connection is up send_string_expect_success (backend, "Hello", 0); recv_string_expect_success (frontend, "Hello", 0); // Send message from frontend to backend send_string_expect_success (frontend, "Hello", ZMQ_DONTWAIT); test_context_socket_close (backend); // Give time to process disconnect msleep (SETTLE_TIME); // Send a message, should fail TEST_ASSERT_FAILURE_ERRNO (EAGAIN, zmq_send (frontend, "Hello", 5, ZMQ_DONTWAIT)); // Recreate backend socket backend = test_context_socket (ZMQ_DEALER); TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (backend, ZMQ_LINGER, &zero, sizeof (zero))); TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (backend, "tipc://{5560,0,0}")); // Ping backend to frontend so we know when the connection is up send_string_expect_success (backend, "Hello", 0); recv_string_expect_success (frontend, "Hello", 0); // After the reconnect, should succeed send_string_expect_success (frontend, "Hello", ZMQ_DONTWAIT); test_context_socket_close (backend); test_context_socket_close (frontend); }
SETUP_TEARDOWN_TESTCONTEXT void test () { // Create a publisher void *pub = test_context_socket (ZMQ_XPUB); TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (pub, "inproc://soname")); // set pub socket options TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (pub, ZMQ_XPUB_WELCOME_MSG, "W", 1)); // Create a subscriber void *sub = test_context_socket (ZMQ_SUB); // Subscribe to the welcome message TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (sub, ZMQ_SUBSCRIBE, "W", 1)); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sub, "inproc://soname")); const uint8_t buffer[2] = {1, 'W'}; // Receive the welcome subscription recv_array_expect_success (pub, buffer, 0); // Receive the welcome message recv_string_expect_success (sub, "W", 0); // Clean up. test_context_socket_close (pub); test_context_socket_close (sub); }
void test_connect_before_bind_pub_sub () { // Connect first void *connect_socket = test_context_socket (ZMQ_PUB); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (connect_socket, "inproc://cbbps")); // Queue up some data, this will be dropped send_string_expect_success (connect_socket, "before", 0); // Now bind void *bind_socket = test_context_socket (ZMQ_SUB); TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (bind_socket, ZMQ_SUBSCRIBE, "", 0)); TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (bind_socket, "inproc://cbbps")); // Wait for pub-sub connection to happen msleep (SETTLE_TIME); // Queue up some data, this not will be dropped send_string_expect_success (connect_socket, "after", 0); // Read pending message recv_string_expect_success (bind_socket, "after", 0); // Cleanup test_context_socket_close (connect_socket); test_context_socket_close (bind_socket); }
void test_multiple_connects () { const unsigned int no_of_connects = 10; void *connect_socket[no_of_connects]; // Connect first for (unsigned int i = 0; i < no_of_connects; ++i) { connect_socket[i] = test_context_socket (ZMQ_PUSH); TEST_ASSERT_SUCCESS_ERRNO ( zmq_connect (connect_socket[i], "inproc://multiple")); // Queue up some data send_string_expect_success (connect_socket[i], "foobar", 0); } // Now bind void *bind_socket = test_context_socket (ZMQ_PULL); TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (bind_socket, "inproc://multiple")); for (unsigned int i = 0; i < no_of_connects; ++i) { recv_string_expect_success (bind_socket, "foobar", 0); } // Cleanup for (unsigned int i = 0; i < no_of_connects; ++i) { test_context_socket_close (connect_socket[i]); } test_context_socket_close (bind_socket); }
void test_multiple_threads () { const unsigned int no_of_threads = 30; void *threads[no_of_threads]; // Connect first for (unsigned int i = 0; i < no_of_threads; ++i) { threads[i] = zmq_threadstart (&pusher, NULL); } // Now bind void *bind_socket = test_context_socket (ZMQ_PULL); TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (bind_socket, "inproc://sink")); for (unsigned int i = 0; i < no_of_threads; ++i) { // Read pending message recv_string_expect_success (bind_socket, "foobar", 0); } // Cleanup for (unsigned int i = 0; i < no_of_threads; ++i) { zmq_threadclose (threads[i]); } test_context_socket_close (bind_socket); }
void test_unbind () { // Bind and unbind socket 1 void *bind_socket1 = test_context_socket (ZMQ_PAIR); TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (bind_socket1, "inproc://unbind")); TEST_ASSERT_SUCCESS_ERRNO (zmq_unbind (bind_socket1, "inproc://unbind")); // Bind socket 2 void *bind_socket2 = test_context_socket (ZMQ_PAIR); TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (bind_socket2, "inproc://unbind")); // Now connect void *connect_socket = test_context_socket (ZMQ_PAIR); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (connect_socket, "inproc://unbind")); // Queue up some data send_string_expect_success (connect_socket, "foobar", 0); // Read pending message recv_string_expect_success (bind_socket2, "foobar", 0); // Cleanup test_context_socket_close (connect_socket); test_context_socket_close (bind_socket1); test_context_socket_close (bind_socket2); }
void test_xpub_verbose_one_sub () { void *pub = test_context_socket (ZMQ_XPUB); TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (pub, test_endpoint)); void *sub = test_context_socket (ZMQ_SUB); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sub, test_endpoint)); // Subscribe for A TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (sub, ZMQ_SUBSCRIBE, topic_a, 1)); // Receive subscriptions from subscriber recv_array_expect_success (pub, subscribe_a_msg, 0); // Subscribe socket for B instead TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (sub, ZMQ_SUBSCRIBE, topic_b, 1)); // Receive subscriptions from subscriber recv_array_expect_success (pub, subscribe_b_msg, 0); // Subscribe again for A again TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (sub, ZMQ_SUBSCRIBE, topic_a, 1)); // This time it is duplicated, so it will be filtered out TEST_ASSERT_FAILURE_ERRNO (EAGAIN, zmq_recv (pub, NULL, 0, ZMQ_DONTWAIT)); int verbose = 1; TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (pub, ZMQ_XPUB_VERBOSE, &verbose, sizeof (int))); // Subscribe socket for A again TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (sub, ZMQ_SUBSCRIBE, topic_a, 1)); // This time with VERBOSE the duplicated sub will be received recv_array_expect_success (pub, subscribe_a_msg, 0); // Sending A message and B Message send_string_expect_success (pub, topic_a, 0); send_string_expect_success (pub, topic_b, 0); recv_string_expect_success (sub, topic_a, 0); recv_string_expect_success (sub, topic_b, 0); // Clean up. test_context_socket_close (pub); test_context_socket_close (sub); }
void test_xpub_verbose_two_subs () { void *pub, *sub0, *sub1; create_xpub_with_2_subs (&pub, &sub0, &sub1); create_duplicate_subscription (pub, sub0, sub1); // Subscribe socket for B instead TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (sub0, ZMQ_SUBSCRIBE, topic_b, 1)); // Receive subscriptions from subscriber recv_array_expect_success (pub, subscribe_b_msg, 0); int verbose = 1; TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (pub, ZMQ_XPUB_VERBOSE, &verbose, sizeof (int))); // Subscribe socket for A again TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (sub1, ZMQ_SUBSCRIBE, topic_a, 1)); // This time with VERBOSE the duplicated sub will be received recv_array_expect_success (pub, subscribe_a_msg, 0); // Sending A message and B Message send_string_expect_success (pub, topic_a, 0); send_string_expect_success (pub, topic_b, 0); recv_string_expect_success (sub0, topic_a, 0); recv_string_expect_success (sub1, topic_a, 0); recv_string_expect_success (sub0, topic_b, 0); // Clean up. test_context_socket_close (pub); test_context_socket_close (sub0); test_context_socket_close (sub1); }
int test_defaults (int send_hwm_, int msg_cnt_, const char *endpoint) { size_t len = SOCKET_STRING_LEN; char pub_endpoint[SOCKET_STRING_LEN]; // Set up and bind XPUB socket void *pub_socket = test_context_socket (ZMQ_XPUB); TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (pub_socket, endpoint)); TEST_ASSERT_SUCCESS_ERRNO ( zmq_getsockopt (pub_socket, ZMQ_LAST_ENDPOINT, pub_endpoint, &len)); // Set up and connect SUB socket void *sub_socket = test_context_socket (ZMQ_SUB); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sub_socket, pub_endpoint)); //set a hwm on publisher TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (pub_socket, ZMQ_SNDHWM, &send_hwm_, sizeof (send_hwm_))); TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (sub_socket, ZMQ_SUBSCRIBE, 0, 0)); // Wait before starting TX operations till 1 subscriber has subscribed // (in this test there's 1 subscriber only) const char subscription_to_all_topics[] = {1, 0}; recv_string_expect_success (pub_socket, subscription_to_all_topics, 0); // Send until we reach "mute" state int send_count = 0; while (send_count < msg_cnt_ && zmq_send (pub_socket, "test message", 13, ZMQ_DONTWAIT) == 13) ++send_count; TEST_ASSERT_EQUAL_INT (send_hwm_, send_count); msleep (SETTLE_TIME); // Now receive all sent messages int recv_count = 0; char dummybuff[64]; while (13 == zmq_recv (sub_socket, &dummybuff, 64, ZMQ_DONTWAIT)) { ++recv_count; } TEST_ASSERT_EQUAL_INT (send_hwm_, recv_count); // Clean up test_context_socket_close (sub_socket); test_context_socket_close (pub_socket); return recv_count; }
SETUP_TEARDOWN_TESTCONTEXT void test () { char endpoint1[MAX_SOCKET_STRING]; char endpoint2[MAX_SOCKET_STRING]; // First, create an intermediate device void *xpub = test_context_socket (ZMQ_XPUB); bind_loopback_ipv4 (xpub, endpoint1, sizeof (endpoint1)); void *xsub = test_context_socket (ZMQ_XSUB); bind_loopback_ipv4 (xsub, endpoint2, sizeof (endpoint2)); // Create a publisher void *pub = test_context_socket (ZMQ_PUB); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (pub, endpoint2)); // Create a subscriber void *sub = test_context_socket (ZMQ_SUB); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sub, endpoint1)); // Subscribe for all messages. TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (sub, ZMQ_SUBSCRIBE, "", 0)); // Pass the subscription upstream through the device char buff[32]; int size; TEST_ASSERT_SUCCESS_ERRNO (size = zmq_recv (xpub, buff, sizeof (buff), 0)); TEST_ASSERT_SUCCESS_ERRNO (zmq_send (xsub, buff, size, 0)); // Wait a bit till the subscription gets to the publisher msleep (SETTLE_TIME); // Send an empty message send_string_expect_success (pub, "", 0); // Pass the message downstream through the device TEST_ASSERT_SUCCESS_ERRNO (size = zmq_recv (xsub, buff, sizeof (buff), 0)); TEST_ASSERT_SUCCESS_ERRNO (zmq_send (xpub, buff, size, 0)); // Receive the message in the subscriber recv_string_expect_success (sub, "", 0); // Clean up. test_context_socket_close (xpub); test_context_socket_close (xsub); test_context_socket_close (pub); test_context_socket_close (sub); }
void test_stream_2_stream () { char buff[256]; const char msg[] = "hi 1"; const int disabled = 0; const int zero = 0; char my_endpoint[MAX_SOCKET_STRING]; // Set up listener STREAM. void *rbind = test_context_socket (ZMQ_STREAM); TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (rbind, ZMQ_STREAM_NOTIFY, &disabled, sizeof (disabled))); TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (rbind, ZMQ_LINGER, &zero, sizeof zero)); bind_loopback_ipv4 (rbind, my_endpoint, sizeof my_endpoint); // Set up connection stream. void *rconn1 = test_context_socket (ZMQ_STREAM); TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (rconn1, ZMQ_LINGER, &zero, sizeof zero)); // Do the connection. TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (rconn1, ZMQ_CONNECT_ROUTING_ID, rconn1routing_id, strlen (rconn1routing_id))); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (rconn1, my_endpoint)); /* Uncomment to test assert on duplicate routing id. // Test duplicate connect attempt. TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (rconn1, ZMQ_CONNECT_ROUTING_ID, rconn1routing_id, strlen(rconn1routing_id))); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (rconn1, bindip)); */ // Send data to the bound stream. send_string_expect_success (rconn1, rconn1routing_id, ZMQ_SNDMORE); send_string_expect_success (rconn1, msg, 0); // Accept data on the bound stream. TEST_ASSERT_GREATER_THAN ( 0, TEST_ASSERT_SUCCESS_ERRNO (zmq_recv (rbind, buff, 256, 0))); TEST_ASSERT_EQUAL (0, buff[0]); // an auto-generated routing id recv_string_expect_success (rbind, msg, 0); // Handle close of the socket. TEST_ASSERT_SUCCESS_ERRNO (zmq_unbind (rbind, my_endpoint)); test_context_socket_close (rbind); test_context_socket_close (rconn1); }
SETUP_TEARDOWN_TESTCONTEXT void test () { // First, create an intermediate device. void *xpub = test_context_socket (ZMQ_XPUB); TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (xpub, "tipc://{5560,0,0}")); void *xsub = test_context_socket (ZMQ_XSUB); TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (xsub, "tipc://{5561,0,0}")); // Create a publisher. void *pub = test_context_socket (ZMQ_PUB); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (pub, "tipc://{5561,0}@0.0.0")); // Create a subscriber. void *sub = test_context_socket (ZMQ_SUB); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sub, "tipc://{5560,0}@0.0.0")); // TODO the remainder of this method is duplicated with test_sub_forward // Subscribe for all messages. TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (sub, ZMQ_SUBSCRIBE, "", 0)); // Pass the subscription upstream through the device char buff[32]; int size; TEST_ASSERT_SUCCESS_ERRNO (size = zmq_recv (xpub, buff, sizeof (buff), 0)); TEST_ASSERT_SUCCESS_ERRNO (zmq_send (xsub, buff, size, 0)); // Wait a bit till the subscription gets to the publisher msleep (SETTLE_TIME); // Send an empty message send_string_expect_success (pub, "", 0); // Pass the message downstream through the device TEST_ASSERT_SUCCESS_ERRNO (size = zmq_recv (xsub, buff, sizeof (buff), 0)); TEST_ASSERT_SUCCESS_ERRNO (zmq_send (xpub, buff, size, 0)); // Receive the message in the subscriber recv_string_expect_success (sub, "", 0); // Clean up. test_context_socket_close (xpub); test_context_socket_close (xsub); test_context_socket_close (pub); test_context_socket_close (sub); }
void test_bind_before_connect () { // Bind first void *bind_socket = test_context_socket (ZMQ_PAIR); TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (bind_socket, "inproc://bbc")); // Now connect void *connect_socket = test_context_socket (ZMQ_PAIR); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (connect_socket, "inproc://bbc")); // Queue up some data send_string_expect_success (connect_socket, "foobar", 0); // Read pending message recv_string_expect_success (bind_socket, "foobar", 0); // Cleanup test_context_socket_close (connect_socket); test_context_socket_close (bind_socket); }
void test_basic () { size_t len = MAX_SOCKET_STRING; char my_endpoint[MAX_SOCKET_STRING]; void *router = test_context_socket (ZMQ_ROUTER); TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (router, "tcp://127.0.0.1:*")); TEST_ASSERT_SUCCESS_ERRNO ( zmq_getsockopt (router, ZMQ_LAST_ENDPOINT, my_endpoint, &len)); // Send a message to an unknown peer with the default setting // This will not report any error send_string_expect_success (router, "UNKNOWN", ZMQ_SNDMORE); send_string_expect_success (router, "DATA", 0); // Send a message to an unknown peer with mandatory routing // This will fail int mandatory = 1; TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (router, ZMQ_ROUTER_MANDATORY, &mandatory, sizeof (mandatory))); int rc = zmq_send (router, "UNKNOWN", 7, ZMQ_SNDMORE); TEST_ASSERT_EQUAL_INT (-1, rc); TEST_ASSERT_EQUAL_INT (EHOSTUNREACH, errno); // Create dealer called "X" and connect it to our router void *dealer = test_context_socket (ZMQ_DEALER); TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (dealer, ZMQ_ROUTING_ID, "X", 1)); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (dealer, my_endpoint)); // Get message from dealer to know when connection is ready send_string_expect_success (dealer, "Hello", 0); recv_string_expect_success (router, "X", 0); // Send a message to connected dealer now // It should work send_string_expect_success (router, "X", ZMQ_SNDMORE); send_string_expect_success (router, "Hello", 0); test_context_socket_close (router); test_context_socket_close (dealer); }
void test_router_2_router (bool named_) { char buff[256]; const char msg[] = "hi 1"; const int zero = 0; char my_endpoint[MAX_SOCKET_STRING]; // Create bind socket. void *rbind = test_context_socket (ZMQ_ROUTER); TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (rbind, ZMQ_LINGER, &zero, sizeof (zero))); bind_loopback_ipv4 (rbind, my_endpoint, sizeof my_endpoint); // Create connection socket. void *rconn1 = test_context_socket (ZMQ_ROUTER); TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (rconn1, ZMQ_LINGER, &zero, sizeof (zero))); // If we're in named mode, set some identities. if (named_) { TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (rbind, ZMQ_ROUTING_ID, x_routing_id, 1)); TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (rconn1, ZMQ_ROUTING_ID, y_routing_id, 1)); } // Make call to connect using a connect_routing_id. TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (rconn1, ZMQ_CONNECT_ROUTING_ID, rconn1routing_id, strlen (rconn1routing_id))); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (rconn1, my_endpoint)); /* Uncomment to test assert on duplicate routing id // Test duplicate connect attempt. TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (rconn1, ZMQ_CONNECT_ROUTING_ID, rconn1routing_id, strlen (rconn1routing_id))); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (rconn1, bindip)); */ // Send some data. send_string_expect_success (rconn1, rconn1routing_id, ZMQ_SNDMORE); send_string_expect_success (rconn1, msg, 0); // Receive the name. const int routing_id_len = zmq_recv (rbind, buff, 256, 0); if (named_) { TEST_ASSERT_EQUAL_INT (strlen (y_routing_id), routing_id_len); TEST_ASSERT_EQUAL_STRING_LEN (y_routing_id, buff, routing_id_len); } else { TEST_ASSERT_TRUE (routing_id_len && 0 == buff[0]); } // Receive the data. recv_string_expect_success (rbind, msg, 0); // Send some data back. const int ret = zmq_send (rbind, buff, routing_id_len, ZMQ_SNDMORE); TEST_ASSERT_EQUAL_INT (routing_id_len, ret); send_string_expect_success (rbind, "ok", 0); // If bound socket identity naming a problem, we'll likely see something funky here. recv_string_expect_success (rconn1, rconn1routing_id, 0); recv_string_expect_success (rconn1, "ok", 0); TEST_ASSERT_SUCCESS_ERRNO (zmq_unbind (rbind, my_endpoint)); test_context_socket_close (rbind); test_context_socket_close (rconn1); }
void test_xpub_verboser_two_subs () { void *pub, *sub0, *sub1; create_xpub_with_2_subs (&pub, &sub0, &sub1); create_duplicate_subscription (pub, sub0, sub1); // Unsubscribe for A, this time it exists in XPUB TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (sub0, ZMQ_UNSUBSCRIBE, topic_a, 1)); // sub1 is still subscribed, so no notification TEST_ASSERT_FAILURE_ERRNO (EAGAIN, zmq_recv (pub, NULL, 0, ZMQ_DONTWAIT)); // Unsubscribe the second socket to trigger the notification TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (sub1, ZMQ_UNSUBSCRIBE, topic_a, 1)); // Receive unsubscriptions since all sockets are gone recv_array_expect_success (pub, unsubscribe_a_msg, 0); // Make really sure there is only one notification TEST_ASSERT_FAILURE_ERRNO (EAGAIN, zmq_recv (pub, NULL, 0, ZMQ_DONTWAIT)); int verbose = 1; TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (pub, ZMQ_XPUB_VERBOSER, &verbose, sizeof (int))); // Subscribe socket for A again TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (sub0, ZMQ_SUBSCRIBE, topic_a, 1)); // Subscribe socket for A again TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (sub1, ZMQ_SUBSCRIBE, topic_a, 1)); // Receive subscriptions from subscriber, did not exist anymore recv_array_expect_success (pub, subscribe_a_msg, 0); // VERBOSER is set, so subs from both sockets are received recv_array_expect_success (pub, subscribe_a_msg, 0); // Sending A message to make sure everything still works send_string_expect_success (pub, topic_a, 0); recv_string_expect_success (sub0, topic_a, 0); recv_string_expect_success (sub1, topic_a, 0); // Unsubscribe for A TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (sub1, ZMQ_UNSUBSCRIBE, topic_a, 1)); // Receive unsubscriptions from first subscriber due to VERBOSER recv_array_expect_success (pub, unsubscribe_a_msg, 0); // Unsubscribe for A again from the other socket TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (sub0, ZMQ_UNSUBSCRIBE, topic_a, 1)); // Receive unsubscriptions from first subscriber due to VERBOSER recv_array_expect_success (pub, unsubscribe_a_msg, 0); // Unsubscribe again to make sure it gets filtered now TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (sub1, ZMQ_UNSUBSCRIBE, topic_a, 1)); // Unmatched, so XSUB filters even with VERBOSER TEST_ASSERT_FAILURE_ERRNO (EAGAIN, zmq_recv (pub, NULL, 0, ZMQ_DONTWAIT)); // Clean up. test_context_socket_close (pub); test_context_socket_close (sub0); test_context_socket_close (sub1); }
int test_blocking (int send_hwm_, int msg_cnt_, const char *endpoint) { size_t len = SOCKET_STRING_LEN; char pub_endpoint[SOCKET_STRING_LEN]; // Set up bind socket void *pub_socket = test_context_socket (ZMQ_XPUB); TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (pub_socket, endpoint)); TEST_ASSERT_SUCCESS_ERRNO ( zmq_getsockopt (pub_socket, ZMQ_LAST_ENDPOINT, pub_endpoint, &len)); // Set up connect socket void *sub_socket = test_context_socket (ZMQ_SUB); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sub_socket, pub_endpoint)); //set a hwm on publisher TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (pub_socket, ZMQ_SNDHWM, &send_hwm_, sizeof (send_hwm_))); int wait = 1; TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (pub_socket, ZMQ_XPUB_NODROP, &wait, sizeof (wait))); int timeout_ms = 10; TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt ( sub_socket, ZMQ_RCVTIMEO, &timeout_ms, sizeof (timeout_ms))); TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (sub_socket, ZMQ_SUBSCRIBE, 0, 0)); // Wait before starting TX operations till 1 subscriber has subscribed // (in this test there's 1 subscriber only) const char subscription_to_all_topics[] = {1, 0}; recv_string_expect_success (pub_socket, subscription_to_all_topics, 0); // Send until we block int send_count = 0; int recv_count = 0; int blocked_count = 0; int is_termination = 0; while (send_count < msg_cnt_) { const int rc = zmq_send (pub_socket, NULL, 0, ZMQ_DONTWAIT); if (rc == 0) { ++send_count; } else if (-1 == rc) { // if the PUB socket blocks due to HWM, errno should be EAGAIN: blocked_count++; TEST_ASSERT_EQUAL_INT (EAGAIN, errno); recv_count += receive (sub_socket, &is_termination); } } // if send_hwm_ < msg_cnt_, we should block at least once: TEST_ASSERT (blocked_count > 0); // dequeue SUB socket again, to make sure XPUB has space to send the termination message recv_count += receive (sub_socket, &is_termination); // send termination message send_string_expect_success (pub_socket, "end", 0); // now block on the SUB side till we get the termination message while (is_termination == 0) recv_count += receive (sub_socket, &is_termination); // remove termination message from the count: recv_count--; TEST_ASSERT_EQUAL_INT (send_count, recv_count); // Clean up test_context_socket_close (sub_socket); test_context_socket_close (pub_socket); return recv_count; }
void test_router_2_router_while_receiving () { char buff[256]; const char msg[] = "hi 1"; const int zero = 0; char x_endpoint[MAX_SOCKET_STRING]; char z_endpoint[MAX_SOCKET_STRING]; // Create xbind socket. void *xbind = test_context_socket (ZMQ_ROUTER); TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (xbind, ZMQ_LINGER, &zero, sizeof (zero))); bind_loopback_ipv4 (xbind, x_endpoint, sizeof x_endpoint); // Create zbind socket. void *zbind = test_context_socket (ZMQ_ROUTER); TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (zbind, ZMQ_LINGER, &zero, sizeof (zero))); bind_loopback_ipv4 (zbind, z_endpoint, sizeof z_endpoint); // Create connection socket. void *yconn = test_context_socket (ZMQ_ROUTER); TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (yconn, ZMQ_LINGER, &zero, sizeof (zero))); // set identities for each socket TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt ( xbind, ZMQ_ROUTING_ID, x_routing_id, strlen (x_routing_id))); TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (yconn, ZMQ_ROUTING_ID, y_routing_id, 2)); TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt ( zbind, ZMQ_ROUTING_ID, z_routing_id, strlen (z_routing_id))); // Connect Y to X using a routing id TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt ( yconn, ZMQ_CONNECT_ROUTING_ID, x_routing_id, strlen (x_routing_id))); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (yconn, x_endpoint)); // Send some data from Y to X. send_string_expect_success (yconn, x_routing_id, ZMQ_SNDMORE); send_string_expect_success (yconn, msg, 0); // wait for the Y->X message to be received msleep (SETTLE_TIME); // Now X tries to connect to Z and send a message TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt ( xbind, ZMQ_CONNECT_ROUTING_ID, z_routing_id, strlen (z_routing_id))); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (xbind, z_endpoint)); // Try to send some data from X to Z. send_string_expect_success (xbind, z_routing_id, ZMQ_SNDMORE); send_string_expect_success (xbind, msg, 0); // wait for the X->Z message to be received (so that our non-blocking check will actually // fail if the message is routed to Y) msleep (SETTLE_TIME); // nothing should have been received on the Y socket TEST_ASSERT_FAILURE_ERRNO (EAGAIN, zmq_recv (yconn, buff, 256, ZMQ_DONTWAIT)); // the message should have been received on the Z socket recv_string_expect_success (zbind, x_routing_id, 0); recv_string_expect_success (zbind, msg, 0); TEST_ASSERT_SUCCESS_ERRNO (zmq_unbind (xbind, x_endpoint)); TEST_ASSERT_SUCCESS_ERRNO (zmq_unbind (zbind, z_endpoint)); test_context_socket_close (yconn); test_context_socket_close (xbind); test_context_socket_close (zbind); }
void test_xpub_verboser_one_sub () { // Create a publisher void *pub = test_context_socket (ZMQ_XPUB); TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (pub, test_endpoint)); // Create a subscriber void *sub = test_context_socket (ZMQ_SUB); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sub, test_endpoint)); // Unsubscribe for A, does not exist yet TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (sub, ZMQ_UNSUBSCRIBE, topic_a, 1)); // Does not exist, so it will be filtered out by XSUB TEST_ASSERT_FAILURE_ERRNO (EAGAIN, zmq_recv (pub, NULL, 0, ZMQ_DONTWAIT)); // Subscribe for A TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (sub, ZMQ_SUBSCRIBE, topic_a, 1)); // Receive subscriptions from subscriber recv_array_expect_success (pub, subscribe_a_msg, 0); // Subscribe again for A again, XSUB will increase refcount TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (sub, ZMQ_SUBSCRIBE, topic_a, 1)); // This time it is duplicated, so it will be filtered out by XPUB TEST_ASSERT_FAILURE_ERRNO (EAGAIN, zmq_recv (pub, NULL, 0, ZMQ_DONTWAIT)); // Unsubscribe for A, this time it exists in XPUB TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (sub, ZMQ_UNSUBSCRIBE, topic_a, 1)); // XSUB refcounts and will not actually send unsub to PUB until the number // of unsubs match the earlier subs TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (sub, ZMQ_UNSUBSCRIBE, topic_a, 1)); // Receive unsubscriptions from subscriber recv_array_expect_success (pub, unsubscribe_a_msg, 0); // XSUB only sends the last and final unsub, so XPUB will only receive 1 TEST_ASSERT_FAILURE_ERRNO (EAGAIN, zmq_recv (pub, NULL, 0, ZMQ_DONTWAIT)); // Unsubscribe for A, does not exist anymore TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (sub, ZMQ_UNSUBSCRIBE, topic_a, 1)); // Does not exist, so it will be filtered out by XSUB TEST_ASSERT_FAILURE_ERRNO (EAGAIN, zmq_recv (pub, NULL, 0, ZMQ_DONTWAIT)); int verbose = 1; TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (pub, ZMQ_XPUB_VERBOSER, &verbose, sizeof (int))); // Subscribe socket for A again TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (sub, ZMQ_SUBSCRIBE, topic_a, 1)); // Receive subscriptions from subscriber, did not exist anymore recv_array_expect_success (pub, subscribe_a_msg, 0); // Sending A message to make sure everything still works send_string_expect_success (pub, topic_a, 0); recv_string_expect_success (sub, topic_a, 0); // Unsubscribe for A, this time it exists TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (sub, ZMQ_UNSUBSCRIBE, topic_a, 1)); // Receive unsubscriptions from subscriber recv_array_expect_success (pub, unsubscribe_a_msg, 0); // Unsubscribe for A again, it does not exist anymore so XSUB will filter TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (sub, ZMQ_UNSUBSCRIBE, topic_a, 1)); // XSUB only sends unsub if it matched it in its trie, IOW: it will only // send it if it existed in the first place even with XPUB_VERBBOSER TEST_ASSERT_FAILURE_ERRNO (EAGAIN, zmq_recv (pub, NULL, 0, ZMQ_DONTWAIT)); // Clean up. test_context_socket_close (pub); test_context_socket_close (sub); }
static void test_stream_to_dealer () { int rc; char my_endpoint[MAX_SOCKET_STRING]; // We'll be using this socket in raw mode void *stream = test_context_socket (ZMQ_STREAM); int zero = 0; TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (stream, ZMQ_LINGER, &zero, sizeof (zero))); int enabled = 1; TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (stream, ZMQ_STREAM_NOTIFY, &enabled, sizeof (enabled))); bind_loopback_ipv4 (stream, my_endpoint, sizeof my_endpoint); // We'll be using this socket as the other peer void *dealer = test_context_socket (ZMQ_DEALER); TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (dealer, ZMQ_LINGER, &zero, sizeof (zero))); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (dealer, my_endpoint)); // Send a message on the dealer socket send_string_expect_success (dealer, "Hello", 0); // Connecting sends a zero message // First frame is routing id zmq_msg_t routing_id; TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_init (&routing_id)); TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_recv (&routing_id, stream, 0)); TEST_ASSERT_TRUE (zmq_msg_more (&routing_id)); // Verify the existence of Peer-Address metadata char const *peer_address = zmq_msg_gets (&routing_id, "Peer-Address"); TEST_ASSERT_NOT_NULL (peer_address); TEST_ASSERT_EQUAL_STRING ("127.0.0.1", peer_address); // Second frame is zero byte buffer[255]; TEST_ASSERT_EQUAL_INT ( 0, TEST_ASSERT_SUCCESS_ERRNO (zmq_recv (stream, buffer, 255, 0))); // Verify the existence of Peer-Address metadata peer_address = zmq_msg_gets (&routing_id, "Peer-Address"); TEST_ASSERT_NOT_NULL (peer_address); TEST_ASSERT_EQUAL_STRING ("127.0.0.1", peer_address); // Real data follows // First frame is routing id TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_recv (&routing_id, stream, 0)); TEST_ASSERT_TRUE (zmq_msg_more (&routing_id)); // Verify the existence of Peer-Address metadata peer_address = zmq_msg_gets (&routing_id, "Peer-Address"); TEST_ASSERT_NOT_NULL (peer_address); TEST_ASSERT_EQUAL_STRING ("127.0.0.1", peer_address); // Second frame is greeting signature recv_array_expect_success (stream, greeting.signature, 0); // Send our own protocol greeting TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_send (&routing_id, stream, ZMQ_SNDMORE)); TEST_ASSERT_EQUAL_INT ( sizeof (greeting), TEST_ASSERT_SUCCESS_ERRNO ( zmq_send (stream, &greeting, sizeof (greeting), 0))); // Now we expect the data from the DEALER socket // We want the rest of greeting along with the Ready command int bytes_read = 0; while (bytes_read < 97) { // First frame is the routing id of the connection (each time) TEST_ASSERT_GREATER_THAN_INT ( 0, TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_recv (&routing_id, stream, 0))); TEST_ASSERT_TRUE (zmq_msg_more (&routing_id)); // Second frame contains the next chunk of data TEST_ASSERT_SUCCESS_ERRNO ( rc = zmq_recv (stream, buffer + bytes_read, 255 - bytes_read, 0)); bytes_read += rc; } // First two bytes are major and minor version numbers. TEST_ASSERT_EQUAL_INT (3, buffer[0]); // ZMTP/3.0 TEST_ASSERT_EQUAL_INT (0, buffer[1]); // Mechanism is "NULL" TEST_ASSERT_EQUAL_INT8_ARRAY (buffer + 2, "NULL\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 20); TEST_ASSERT_EQUAL_INT8_ARRAY (buffer + 54, "\4\51\5READY", 8); TEST_ASSERT_EQUAL_INT8_ARRAY (buffer + 62, "\13Socket-Type\0\0\0\6DEALER", 22); TEST_ASSERT_EQUAL_INT8_ARRAY (buffer + 84, "\10Identity\0\0\0\0", 13); // Announce we are ready memcpy (buffer, "\4\51\5READY", 8); memcpy (buffer + 8, "\13Socket-Type\0\0\0\6ROUTER", 22); memcpy (buffer + 30, "\10Identity\0\0\0\0", 13); // Send Ready command TEST_ASSERT_GREATER_THAN_INT (0, TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_send ( &routing_id, stream, ZMQ_SNDMORE))); TEST_ASSERT_EQUAL_INT ( 43, TEST_ASSERT_SUCCESS_ERRNO (zmq_send (stream, buffer, 43, 0))); // Now we expect the data from the DEALER socket // First frame is, again, the routing id of the connection TEST_ASSERT_GREATER_THAN_INT ( 0, TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_recv (&routing_id, stream, 0))); TEST_ASSERT_TRUE (zmq_msg_more (&routing_id)); // Third frame contains Hello message from DEALER TEST_ASSERT_EQUAL_INT (7, TEST_ASSERT_SUCCESS_ERRNO ( zmq_recv (stream, buffer, sizeof buffer, 0))); // Then we have a 5-byte message "Hello" TEST_ASSERT_EQUAL_INT (0, buffer[0]); // Flags = 0 TEST_ASSERT_EQUAL_INT (5, buffer[1]); // Size = 5 TEST_ASSERT_EQUAL_INT8_ARRAY (buffer + 2, "Hello", 5); // Send "World" back to DEALER TEST_ASSERT_GREATER_THAN_INT (0, TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_send ( &routing_id, stream, ZMQ_SNDMORE))); byte world[] = {0, 5, 'W', 'o', 'r', 'l', 'd'}; TEST_ASSERT_EQUAL_INT ( sizeof (world), TEST_ASSERT_SUCCESS_ERRNO (zmq_send (stream, world, sizeof (world), 0))); // Expect response on DEALER socket recv_string_expect_success (dealer, "World", 0); // Test large messages over STREAM socket #define size 64000 uint8_t msgout[size]; memset (msgout, 0xAB, size); zmq_send (dealer, msgout, size, 0); uint8_t msgin[9 + size]; memset (msgin, 0, 9 + size); bytes_read = 0; while (bytes_read < 9 + size) { // Get routing id frame TEST_ASSERT_GREATER_THAN_INT ( 0, TEST_ASSERT_SUCCESS_ERRNO (zmq_recv (stream, buffer, 256, 0))); // Get next chunk TEST_ASSERT_GREATER_THAN_INT ( 0, TEST_ASSERT_SUCCESS_ERRNO (rc = zmq_recv (stream, msgin + bytes_read, 9 + size - bytes_read, 0))); bytes_read += rc; } for (int byte_nbr = 0; byte_nbr < size; byte_nbr++) { TEST_ASSERT_EQUAL_UINT8 (0xAB, msgin[9 + byte_nbr]); } test_context_socket_close (dealer); test_context_socket_close (stream); }
void test_get_peer_state () { #ifdef ZMQ_BUILD_DRAFT_API void *router = test_context_socket (ZMQ_ROUTER); int mandatory = 1; TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (router, ZMQ_ROUTER_MANDATORY, &mandatory, sizeof (mandatory))); const char *my_endpoint = "inproc://test_get_peer_state"; TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (router, my_endpoint)); void *dealer1 = test_context_socket (ZMQ_DEALER); void *dealer2 = test_context_socket (ZMQ_DEALER); // Lower HWMs to allow doing the test with fewer messages const int hwm = 100; TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (router, ZMQ_SNDHWM, &hwm, sizeof (int))); TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (dealer1, ZMQ_RCVHWM, &hwm, sizeof (int))); TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (dealer2, ZMQ_RCVHWM, &hwm, sizeof (int))); const char *dealer1_routing_id = "X"; const char *dealer2_routing_id = "Y"; // Name dealer1 "X" and connect it to our router TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (dealer1, ZMQ_ROUTING_ID, dealer1_routing_id, 1)); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (dealer1, my_endpoint)); // Name dealer2 "Y" and connect it to our router TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (dealer2, ZMQ_ROUTING_ID, dealer2_routing_id, 1)); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (dealer2, my_endpoint)); // Get message from both dealers to know when connection is ready send_string_expect_success (dealer1, "Hello", 0); recv_string_expect_success (router, dealer1_routing_id, 0); recv_string_expect_success (router, "Hello", 0); send_string_expect_success (dealer2, "Hello", 0); recv_string_expect_success (router, dealer2_routing_id, 0); recv_string_expect_success (router, "Hello", 0); void *poller = zmq_poller_new (); TEST_ASSERT_NOT_NULL (poller); // Poll on router and dealer1, but not on dealer2 TEST_ASSERT_SUCCESS_ERRNO ( zmq_poller_add (poller, router, NULL, ZMQ_POLLOUT)); TEST_ASSERT_SUCCESS_ERRNO ( zmq_poller_add (poller, dealer1, NULL, ZMQ_POLLIN)); const unsigned int count = 10000; const unsigned int event_size = 2; bool dealer2_blocked = false; unsigned int dealer1_sent = 0, dealer2_sent = 0, dealer1_received = 0; zmq_poller_event_t events[event_size]; for (unsigned int iteration = 0; iteration < count; ++iteration) { TEST_ASSERT_SUCCESS_ERRNO ( zmq_poller_wait_all (poller, events, event_size, -1)); for (unsigned int event_no = 0; event_no < event_size; ++event_no) { const zmq_poller_event_t ¤t_event = events[event_no]; if (current_event.socket == router && current_event.events & ZMQ_POLLOUT) { if (send_msg_to_peer_if_ready (router, dealer1_routing_id)) ++dealer1_sent; if (send_msg_to_peer_if_ready (router, dealer2_routing_id)) ++dealer2_sent; else dealer2_blocked = true; } if (current_event.socket == dealer1 && current_event.events & ZMQ_POLLIN) { recv_string_expect_success (dealer1, "Hello", ZMQ_DONTWAIT); int more; size_t more_size = sizeof (more); TEST_ASSERT_SUCCESS_ERRNO ( zmq_getsockopt (dealer1, ZMQ_RCVMORE, &more, &more_size)); TEST_ASSERT_FALSE (more); ++dealer1_received; } // never read from dealer2, so its pipe becomes full eventually } } printf ("dealer1_sent = %u, dealer2_sent = %u, dealer1_received = %u\n", dealer1_sent, dealer2_sent, dealer1_received); TEST_ASSERT_TRUE (dealer2_blocked); zmq_poller_destroy (&poller); test_context_socket_close (router); test_context_socket_close (dealer1); test_context_socket_close (dealer2); #endif }