SETUP_TEARDOWN_TESTCONTEXT void test_reconnect_ivl_against_pair_socket (const char *my_endpoint_, void *sb_) { void *sc = test_context_socket (ZMQ_PAIR); int interval = -1; TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (sc, ZMQ_RECONNECT_IVL, &interval, sizeof (int))); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sc, my_endpoint_)); bounce (sb_, sc); TEST_ASSERT_SUCCESS_ERRNO (zmq_unbind (sb_, my_endpoint_)); expect_bounce_fail (sb_, sc); TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (sb_, my_endpoint_)); expect_bounce_fail (sb_, sc); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sc, my_endpoint_)); bounce (sb_, sc); test_context_socket_close (sc); }
SETUP_TEARDOWN_TESTCONTEXT void test_diffserv () { int tos = 0x28; int o_tos; size_t tos_size = sizeof (tos); char my_endpoint[MAX_SOCKET_STRING]; void *sb = test_context_socket (ZMQ_PAIR); TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (sb, ZMQ_TOS, &tos, tos_size)); bind_loopback_ipv4 (sb, my_endpoint, sizeof (my_endpoint)); TEST_ASSERT_SUCCESS_ERRNO (zmq_getsockopt (sb, ZMQ_TOS, &o_tos, &tos_size)); TEST_ASSERT_EQUAL (tos, o_tos); void *sc = test_context_socket (ZMQ_PAIR); tos = 0x58; TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (sc, ZMQ_TOS, &tos, tos_size)); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sc, my_endpoint)); TEST_ASSERT_SUCCESS_ERRNO (zmq_getsockopt (sc, ZMQ_TOS, &o_tos, &tos_size)); TEST_ASSERT_EQUAL (tos, o_tos); // Wireshark can be used to verify that the server socket is // using DSCP 0x28 in packets to the client while the client // is using 0x58 in packets to the server. bounce (sb, sc); test_context_socket_close (sc); test_context_socket_close (sb); }
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_ctx_shutdown () { // Set up our context and sockets void *ctx = zmq_ctx_new (); TEST_ASSERT_NOT_NULL (ctx); void *socket = zmq_socket (ctx, ZMQ_PULL); TEST_ASSERT_NOT_NULL (socket); // Spawn a thread to receive on socket void *receiver_thread = zmq_threadstart (&receiver, socket); // Wait for thread to start up and block msleep (SETTLE_TIME); // Shutdown context, if we used destroy here we would deadlock. TEST_ASSERT_SUCCESS_ERRNO (zmq_ctx_shutdown (ctx)); // Wait for thread to finish zmq_threadclose (receiver_thread); // Close the socket. TEST_ASSERT_SUCCESS_ERRNO (zmq_close (socket)); // Destory the context, will now not hang as we have closed the socket. TEST_ASSERT_SUCCESS_ERRNO (zmq_ctx_destroy (ctx)); }
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_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_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); }
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); }
SETUP_TEARDOWN_TESTCONTEXT // Read one event off the monitor socket; return value and address // by reference, if not null, and event number by value. Returns -1 // in case of error. static int get_monitor_event (void *monitor_) { for (int i = 0; i < 2; i++) { // First frame in message contains event number and value zmq_msg_t msg; TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_init (&msg)); if (zmq_msg_recv (&msg, monitor_, ZMQ_DONTWAIT) == -1) { msleep (SETTLE_TIME); continue; // Interrupted, presumably } TEST_ASSERT_TRUE (zmq_msg_more (&msg)); uint8_t *data = (uint8_t *) zmq_msg_data (&msg); uint16_t event = *(uint16_t *) (data); // Second frame in message contains event address TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_init (&msg)); if (zmq_msg_recv (&msg, monitor_, 0) == -1) { return -1; // Interrupted, presumably } TEST_ASSERT_FALSE (zmq_msg_more (&msg)); return event; } return -1; }
static void *worker (void *s_) { TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (s_, "tipc://{5560,0}@0.0.0")); // Start closing the socket while the connecting process is underway. TEST_ASSERT_SUCCESS_ERRNO (zmq_close (s_)); return NULL; }
static void set_hwm (void *skt) { int hwm = HWM; TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (skt, ZMQ_SNDHWM, &hwm, sizeof (hwm))); TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (skt, ZMQ_RCVHWM, &hwm, sizeof (hwm))); }
void create_xpub_with_2_subs (void **pub_, void **sub0_, void **sub1_) { *pub_ = test_context_socket (ZMQ_XPUB); TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (*pub_, test_endpoint)); *sub0_ = test_context_socket (ZMQ_SUB); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (*sub0_, test_endpoint)); *sub1_ = test_context_socket (ZMQ_SUB); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (*sub1_, test_endpoint)); }
SETUP_TEARDOWN_TESTCONTEXT static void do_bind_and_verify (void *s_, const char *endpoint_) { TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (s_, endpoint_)); char reported[255]; size_t size = 255; TEST_ASSERT_SUCCESS_ERRNO ( zmq_getsockopt (s_, ZMQ_LAST_ENDPOINT, reported, &size)); TEST_ASSERT_EQUAL_STRING (endpoint_, reported); }
static void simult_conn (void *endpt_) { // Pull out arguments - endpoint string const char *endpt = static_cast<const char *> (endpt_); // Connect // do not use test_context_socket here, as it is not thread-safe void *connect_socket = zmq_socket (get_test_context (), ZMQ_SUB); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (connect_socket, endpt)); // Cleanup TEST_ASSERT_SUCCESS_ERRNO (zmq_close (connect_socket)); }
static void simult_bind (void *endpt_) { // Pull out arguments - context followed by endpoint string const char *endpt = static_cast<const char *> (endpt_); // Bind // do not use test_context_socket here, as it is not thread-safe void *bind_socket = zmq_socket (get_test_context (), ZMQ_PUB); TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (bind_socket, endpt)); // Cleanup TEST_ASSERT_SUCCESS_ERRNO (zmq_close (bind_socket)); }
static void setup_server () { // Server socket will accept connections server = test_context_socket (ZMQ_DEALER); TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (server, ZMQ_ROUTING_ID, "IDENT", 6)); TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, domain, strlen (domain))); const int as_server = 1; TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (server, ZMQ_PLAIN_SERVER, &as_server, sizeof (int))); bind_loopback_ipv4 (server, my_endpoint, sizeof my_endpoint); }
void test_roundtrip () { void *sb = test_context_socket (ZMQ_REP); TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (sb, "inproc://a")); void *sc = test_context_socket (ZMQ_REQ); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sc, "inproc://a")); bounce (sb, sc); test_context_socket_close (sc); test_context_socket_close (sb); }
void test_reconnect_ivl_tcp (const char *address) { size_t len = MAX_SOCKET_STRING; char my_endpoint[MAX_SOCKET_STRING]; void *sb = test_context_socket (ZMQ_PAIR); TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (sb, address)); TEST_ASSERT_SUCCESS_ERRNO ( zmq_getsockopt (sb, ZMQ_LAST_ENDPOINT, my_endpoint, &len)); test_reconnect_ivl_against_pair_socket (my_endpoint, sb); test_context_socket_close (sb); }
static void pusher (void * /*unused*/) { // Connect first // do not use test_context_socket here, as it is not thread-safe void *connect_socket = zmq_socket (get_test_context (), ZMQ_PAIR); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (connect_socket, "inproc://sink")); // Queue up some data send_string_expect_success (connect_socket, "foobar", 0); // Cleanup TEST_ASSERT_SUCCESS_ERRNO (zmq_close (connect_socket)); }
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; }
void test_plain_wrong_credentials_fails () { // Check PLAIN security -- failed authentication void *client = test_context_socket (ZMQ_DEALER); const char username[] = "wronguser"; const char password[] = "wrongpass"; TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (client, ZMQ_PLAIN_USERNAME, username, strlen (username))); TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (client, ZMQ_PLAIN_PASSWORD, password, strlen (password))); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (client, my_endpoint)); expect_bounce_fail (server, client); test_context_socket_close_zero_linger (client); }
void test_plain_client_as_server_fails () { // Check PLAIN security with badly configured client (as_server) // This will be caught by the plain_server class, not passed to ZAP void *client = test_context_socket (ZMQ_DEALER); TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (client, ZMQ_ZAP_DOMAIN, domain, strlen (domain))); const int as_server = 1; TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (client, ZMQ_PLAIN_SERVER, &as_server, sizeof (int))); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (client, my_endpoint)); expect_bounce_fail (server, client); test_context_socket_close_zero_linger (client); }
void test_plain_success () { // Check PLAIN security with correct username/password void *client = test_context_socket (ZMQ_DEALER); const char username[] = "admin"; TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (client, ZMQ_PLAIN_USERNAME, username, strlen (username))); const char password[] = "password"; TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (client, ZMQ_PLAIN_PASSWORD, password, strlen (password))); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (client, my_endpoint)); bounce (server, client); test_context_socket_close (client); }
void test_ctx_destroy () { // Set up our context and sockets void *ctx = zmq_ctx_new (); TEST_ASSERT_NOT_NULL (ctx); void *socket = zmq_socket (ctx, ZMQ_PULL); TEST_ASSERT_NOT_NULL (socket); // Close the socket TEST_ASSERT_SUCCESS_ERRNO (zmq_close (socket)); // Destroy the context TEST_ASSERT_SUCCESS_ERRNO (zmq_ctx_destroy (ctx)); }
void test_io_completion_port () { void *const s = test_context_socket (ZMQ_PAIR); SOCKET fd; size_t fd_size = sizeof fd; TEST_ASSERT_SUCCESS_ERRNO (zmq_getsockopt (s, ZMQ_FD, &fd, &fd_size)); ::WSAPROTOCOL_INFO pi; TEST_ASSERT_SUCCESS_RAW_ERRNO ( ::WSADuplicateSocket (fd, ::GetCurrentProcessId (), &pi)); const SOCKET socket = ::WSASocket (pi.iAddressFamily /*AF_INET*/, pi.iSocketType /*SOCK_STREAM*/, pi.iProtocol /*IPPROTO_TCP*/, &pi, 0, 0); const HANDLE iocp = ::CreateIoCompletionPort (INVALID_HANDLE_VALUE, NULL, 0, 0); TEST_ASSERT_NOT_EQUAL (NULL, iocp); const HANDLE res = ::CreateIoCompletionPort (reinterpret_cast<HANDLE> (socket), iocp, 0, 0); TEST_ASSERT_NOT_EQUAL (NULL, res); TEST_ASSERT_SUCCESS_RAW_ERRNO (closesocket (socket)); TEST_ASSERT_TRUE (CloseHandle (iocp)); test_context_socket_close (s); }
void test_setsockopt_heartbeat_success (const int value_) { void *const socket = test_context_socket (ZMQ_PAIR); TEST_ASSERT_SUCCESS_ERRNO ( zmq_setsockopt (socket, ZMQ_HEARTBEAT_TTL, &value_, sizeof (value_))); int value_read; size_t value_read_size = sizeof (value_read); TEST_ASSERT_SUCCESS_ERRNO (zmq_getsockopt (socket, ZMQ_HEARTBEAT_TTL, &value_read, &value_read_size)); TEST_ASSERT_EQUAL_INT (value_ - value_ % deciseconds_per_millisecond, value_read); test_context_socket_close (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_pair_tcp_connect_by_name () { // all other tcp test cases bind to a loopback wildcard address, then // retrieve the bound endpoint, which is numerical, and use that to // connect. this test cases specifically uses "localhost" to connect // to ensure that names are correctly resolved void *sb = test_context_socket (ZMQ_PAIR); char bound_endpoint[MAX_SOCKET_STRING]; bind_loopback_ipv4 (sb, bound_endpoint, sizeof bound_endpoint); // extract the bound port number const char *pos = strrchr (bound_endpoint, ':'); TEST_ASSERT_NOT_NULL (pos); const char connect_endpoint_prefix[] = "tcp://localhost"; char connect_endpoint[MAX_SOCKET_STRING]; strcpy (connect_endpoint, connect_endpoint_prefix); strcat (connect_endpoint, pos); void *sc = test_context_socket (ZMQ_PAIR); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sc, connect_endpoint)); bounce (sb, sc); test_context_socket_close (sc); test_context_socket_close (sb); }
void test_connect_only () { void *connect_socket = test_context_socket (ZMQ_PUSH); TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (connect_socket, "inproc://a")); test_context_socket_close (connect_socket); }