void run_poller (void *data_) { struct poller_test_data_t *poller_test_data = (struct poller_test_data_t *) data_; void *socket = zmq_socket (poller_test_data->ctx, poller_test_data->socket_type); TEST_ASSERT_NOT_NULL (socket); void *poller = zmq_poller_new (); TEST_ASSERT_NOT_NULL (poller); TEST_ASSERT_SUCCESS_ERRNO ( zmq_poller_add (poller, socket, NULL, ZMQ_POLLIN)); zmq_atomic_counter_set (poller_test_data->counter, 1); zmq_poller_event_t event; TEST_ASSERT_FAILURE_ERRNO (ETERM, zmq_poller_wait (poller, &event, -1)); TEST_ASSERT_SUCCESS_ERRNO (zmq_poller_destroy (&poller)); // Close the socket TEST_ASSERT_SUCCESS_ERRNO (zmq_close (socket)); }
void test_setsockopt_heartbeat_ttl_more_than_max_fails () { void *const socket = test_context_socket (ZMQ_PAIR); const int value = heartbeat_ttl_max + 1; TEST_ASSERT_FAILURE_ERRNO ( EINVAL, zmq_setsockopt (socket, ZMQ_HEARTBEAT_TTL, &value, sizeof (value))); test_context_socket_close (socket); }
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); }
void create_duplicate_subscription (void *pub_, void *sub0_, void *sub1_) { // Subscribe for A TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (sub0_, ZMQ_SUBSCRIBE, topic_a, 1)); // Receive subscriptions from subscriber recv_array_expect_success (pub_, subscribe_a_msg, 0); // Subscribe again for A on the other socket TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (sub1_, 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)); }
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_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_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); }
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); }