From 4a4818403249306f03f0730f757ac4ff3899c218 Mon Sep 17 00:00:00 2001 From: Simon Giesecke Date: Mon, 10 Dec 2018 06:04:38 -0500 Subject: [PATCH] Problem: tests without test framework Solution: migrate to unity --- Makefile.am | 18 ++- tests/test_pair_inproc.cpp | 93 +++++++------- tests/test_pair_ipc.cpp | 54 +++++---- tests/test_pair_tipc.cpp | 59 ++++----- tests/test_rebind_ipc.cpp | 86 +++++++------ tests/test_req_relaxed.cpp | 186 +++++++++++++++------------- tests/test_spec_req.cpp | 240 +++++++++++++++++++------------------ 7 files changed, 383 insertions(+), 353 deletions(-) diff --git a/Makefile.am b/Makefile.am index 8027683b..5123fe50 100644 --- a/Makefile.am +++ b/Makefile.am @@ -465,7 +465,8 @@ tests_test_system_LDADD = src/libzmq.la tests_test_pair_inproc_SOURCES = \ tests/test_pair_inproc.cpp \ tests/testutil.hpp -tests_test_pair_inproc_LDADD = src/libzmq.la +tests_test_pair_inproc_LDADD = src/libzmq.la ${UNITY_LIBS} +tests_test_pair_inproc_CPPFLAGS = ${UNITY_CPPFLAGS} tests_test_pair_tcp_SOURCES = \ tests/test_pair_tcp.cpp \ @@ -594,7 +595,8 @@ tests_test_security_zap_SOURCES = \ tests_test_security_zap_LDADD = src/libzmq.la tests_test_spec_req_SOURCES = tests/test_spec_req.cpp -tests_test_spec_req_LDADD = src/libzmq.la +tests_test_spec_req_LDADD = src/libzmq.la ${UNITY_LIBS} +tests_test_spec_req_CPPFLAGS = ${UNITY_CPPFLAGS} tests_test_spec_rep_SOURCES = tests/test_spec_rep.cpp tests_test_spec_rep_LDADD = src/libzmq.la ${UNITY_LIBS} @@ -617,7 +619,8 @@ tests_test_req_correlate_LDADD = src/libzmq.la ${UNITY_LIBS} tests_test_req_correlate_CPPFLAGS = ${UNITY_CPPFLAGS} tests_test_req_relaxed_SOURCES = tests/test_req_relaxed.cpp -tests_test_req_relaxed_LDADD = src/libzmq.la +tests_test_req_relaxed_LDADD = src/libzmq.la ${UNITY_LIBS} +tests_test_req_relaxed_CPPFLAGS = ${UNITY_CPPFLAGS} tests_test_conflate_SOURCES = tests/test_conflate.cpp tests_test_conflate_LDADD = src/libzmq.la ${UNITY_LIBS} @@ -788,10 +791,12 @@ tests_test_ipc_wildcard_LDADD = src/libzmq.la tests_test_pair_ipc_SOURCES = \ tests/test_pair_ipc.cpp \ tests/testutil.hpp -tests_test_pair_ipc_LDADD = src/libzmq.la +tests_test_pair_ipc_LDADD = src/libzmq.la ${UNITY_LIBS} +tests_test_pair_ipc_CPPFLAGS = ${UNITY_CPPFLAGS} tests_test_rebind_ipc_SOURCES = tests/test_rebind_ipc.cpp -tests_test_rebind_ipc_LDADD = src/libzmq.la +tests_test_rebind_ipc_LDADD = src/libzmq.la ${UNITY_LIBS} +tests_test_rebind_ipc_CPPFLAGS = ${UNITY_CPPFLAGS} tests_test_reqrep_ipc_SOURCES = \ tests/test_reqrep_ipc.cpp \ @@ -845,7 +850,8 @@ tests_test_connect_delay_tipc_LDADD = src/libzmq.la ${UNITY_LIBS} tests_test_connect_delay_tipc_CPPFLAGS = ${UNITY_CPPFLAGS} tests_test_pair_tipc_SOURCES = tests/test_pair_tipc.cpp -tests_test_pair_tipc_LDADD = src/libzmq.la +tests_test_pair_tipc_LDADD = src/libzmq.la ${UNITY_LIBS} +tests_test_pair_tipc_CPPFLAGS = ${UNITY_CPPFLAGS} tests_test_reqrep_device_tipc_SOURCES = tests/test_reqrep_device_tipc.cpp tests_test_reqrep_device_tipc_LDADD = src/libzmq.la ${UNITY_LIBS} diff --git a/tests/test_pair_inproc.cpp b/tests/test_pair_inproc.cpp index a891caf7..efbd9301 100644 --- a/tests/test_pair_inproc.cpp +++ b/tests/test_pair_inproc.cpp @@ -28,54 +28,55 @@ */ #include "testutil.hpp" +#include "testutil_unity.hpp" -int main (void) +#include + +void *sb; +void *sc; + +void setUp () +{ + setup_test_context (); + + sb = test_context_socket (ZMQ_PAIR); + TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (sb, "inproc://a")); + + sc = test_context_socket (ZMQ_PAIR); + TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sc, "inproc://a")); +} + +void tearDown () +{ + test_context_socket_close (sc); + test_context_socket_close (sb); + + teardown_test_context (); +} + +void test_roundtrip () +{ + bounce (sb, sc); +} + +// TODO it appears that this has nothing to do with pair or inproc, and belongs somewhere else +void test_zmq_send_const () +{ + TEST_ASSERT_EQUAL_INT (3, TEST_ASSERT_SUCCESS_ERRNO ( + zmq_send_const (sb, "foo", 3, ZMQ_SNDMORE))); + TEST_ASSERT_EQUAL_INT ( + 6, TEST_ASSERT_SUCCESS_ERRNO (zmq_send_const (sb, "foobar", 6, 0))); + + recv_string_expect_success (sc, "foo", 0); + recv_string_expect_success (sc, "foobar", 0); +} + +int main () { setup_test_environment (); - void *ctx = zmq_ctx_new (); - assert (ctx); - void *sb = zmq_socket (ctx, ZMQ_PAIR); - assert (sb); - int rc = zmq_bind (sb, "inproc://a"); - assert (rc == 0); - - void *sc = zmq_socket (ctx, ZMQ_PAIR); - assert (sc); - rc = zmq_connect (sc, "inproc://a"); - assert (rc == 0); - - bounce (sb, sc); - - // Test zmq_send_const - rc = zmq_send_const (sb, "foo", 3, ZMQ_SNDMORE); - assert (rc == 3); - rc = zmq_send_const (sb, "foobar", 6, 0); - assert (rc == 6); - - zmq_msg_t msg; - rc = zmq_msg_init (&msg); - assert (rc == 0); - rc = zmq_msg_recv (&msg, sc, 0); - assert (rc == 3); - assert (zmq_msg_size (&msg) == 3); - void *data = zmq_msg_data (&msg); - assert (memcmp ("foo", data, 3) == 0); - rc = zmq_msg_recv (&msg, sc, 0); - assert (rc == 6); - data = zmq_msg_data (&msg); - assert (memcmp ("foobar", data, 6) == 0); - - // Cleanup - - rc = zmq_close (sc); - assert (rc == 0); - - rc = zmq_close (sb); - assert (rc == 0); - - rc = zmq_ctx_term (ctx); - assert (rc == 0); - - return 0; + UNITY_BEGIN (); + RUN_TEST (test_roundtrip); + RUN_TEST (test_zmq_send_const); + return UNITY_END (); } diff --git a/tests/test_pair_ipc.cpp b/tests/test_pair_ipc.cpp index 84a38e09..c9a216dd 100644 --- a/tests/test_pair_ipc.cpp +++ b/tests/test_pair_ipc.cpp @@ -28,33 +28,39 @@ */ #include "testutil.hpp" +#include "testutil_unity.hpp" + +#include + +void setUp () +{ + setup_test_context (); +} + +void tearDown () +{ + teardown_test_context (); +} + +void test_roundtrip () +{ + void *sb = test_context_socket (ZMQ_PAIR); + TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (sb, "ipc:///tmp/test_pair_ipc")); + + void *sc = test_context_socket (ZMQ_PAIR); + TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sc, "ipc:///tmp/test_pair_ipc")); + + bounce (sb, sc); + + test_context_socket_close (sc); + test_context_socket_close (sb); +} int main (void) { setup_test_environment (); - void *ctx = zmq_ctx_new (); - assert (ctx); - void *sb = zmq_socket (ctx, ZMQ_PAIR); - assert (sb); - int rc = zmq_bind (sb, "ipc:///tmp/test_pair_ipc"); - assert (rc == 0); - - void *sc = zmq_socket (ctx, ZMQ_PAIR); - assert (sc); - rc = zmq_connect (sc, "ipc:///tmp/test_pair_ipc"); - assert (rc == 0); - - bounce (sb, sc); - - rc = zmq_close (sc); - assert (rc == 0); - - rc = zmq_close (sb); - assert (rc == 0); - - rc = zmq_ctx_term (ctx); - assert (rc == 0); - - return 0; + UNITY_BEGIN (); + RUN_TEST (test_roundtrip); + return UNITY_END (); } diff --git a/tests/test_pair_tipc.cpp b/tests/test_pair_tipc.cpp index a694706a..d3803fb7 100644 --- a/tests/test_pair_tipc.cpp +++ b/tests/test_pair_tipc.cpp @@ -29,39 +29,42 @@ #include #include "testutil.hpp" +#include "testutil_unity.hpp" -int main (void) +#include + +void setUp () +{ + setup_test_context (); +} + +void tearDown () +{ + teardown_test_context (); +} + +void test_roundtrip () +{ + void *sb = test_context_socket (ZMQ_PAIR); + TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (sb, "tipc://{5560,0,0}")); + + void *sc = test_context_socket (ZMQ_PAIR); + TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sc, "tipc://{5560,0}@0.0.0")); + + bounce (sb, sc); + + test_context_socket_close (sc); + test_context_socket_close (sb); +} + +int main () { if (!is_tipc_available ()) { printf ("TIPC environment unavailable, skipping test\n"); return 77; } - fprintf (stderr, "test_pair_tipc running...\n"); - - void *ctx = zmq_init (1); - assert (ctx); - - void *sb = zmq_socket (ctx, ZMQ_PAIR); - assert (sb); - int rc = zmq_bind (sb, "tipc://{5560,0,0}"); - assert (rc == 0); - - void *sc = zmq_socket (ctx, ZMQ_PAIR); - assert (sc); - rc = zmq_connect (sc, "tipc://{5560,0}@0.0.0"); - assert (rc == 0); - - bounce (sb, sc); - - rc = zmq_close (sc); - assert (rc == 0); - - rc = zmq_close (sb); - assert (rc == 0); - - rc = zmq_ctx_term (ctx); - assert (rc == 0); - - return 0; + UNITY_BEGIN (); + RUN_TEST (test_roundtrip); + return UNITY_END (); } diff --git a/tests/test_rebind_ipc.cpp b/tests/test_rebind_ipc.cpp index 000c9b39..830d1803 100644 --- a/tests/test_rebind_ipc.cpp +++ b/tests/test_rebind_ipc.cpp @@ -28,57 +28,51 @@ */ #include "testutil.hpp" +#include "testutil_unity.hpp" + +#include + +void setUp () +{ + setup_test_context (); +} + +void tearDown () +{ + teardown_test_context (); +} static const char *SOCKET_ADDR = "ipc:///tmp/test_rebind_ipc"; +void test_rebind_ipc () +{ + void *sb0 = test_context_socket (ZMQ_PUSH); + void *sb1 = test_context_socket (ZMQ_PUSH); -int main (void) + TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (sb0, SOCKET_ADDR)); + + void *sc = test_context_socket (ZMQ_PULL); + TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sc, SOCKET_ADDR)); + + 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, SOCKET_ADDR)); + + send_string_expect_success (sb1, "42", 0); + recv_string_expect_success (sc, "42", 0); + + test_context_socket_close (sc); + test_context_socket_close (sb1); +} + +int main () { setup_test_environment (); - void *ctx = zmq_ctx_new (); - assert (ctx); - - void *sb0 = zmq_socket (ctx, ZMQ_PUSH); - assert (sb0); - void *sb1 = zmq_socket (ctx, ZMQ_PUSH); - assert (sb1); - - int rc = zmq_bind (sb0, SOCKET_ADDR); - assert (rc == 0); - - void *sc = zmq_socket (ctx, ZMQ_PULL); - assert (sc); - rc = zmq_connect (sc, SOCKET_ADDR); - assert (rc == 0); - - rc = zmq_send (sb0, "42", 2, 0); - assert (rc == 2); - - char buffer[2]; - rc = zmq_recv (sc, buffer, 2, 0); - assert (rc == 2); - - rc = zmq_close (sb0); - assert (rc == 0); - - rc = zmq_bind (sb1, SOCKET_ADDR); - assert (rc == 0); - - rc = zmq_send (sb1, "42", 2, 0); - assert (rc == 2); - - rc = zmq_recv (sc, buffer, 2, 0); - assert (rc == 2); - - rc = zmq_close (sc); - assert (rc == 0); - - rc = zmq_close (sb1); - assert (rc == 0); - - rc = zmq_ctx_term (ctx); - assert (rc == 0); - - return 0; + UNITY_BEGIN (); + RUN_TEST (test_rebind_ipc); + return UNITY_END (); } diff --git a/tests/test_req_relaxed.cpp b/tests/test_req_relaxed.cpp index cd938e66..7165ce91 100644 --- a/tests/test_req_relaxed.cpp +++ b/tests/test_req_relaxed.cpp @@ -29,26 +29,74 @@ #include "testutil.hpp" +#include "testutil.hpp" +#include "testutil_unity.hpp" + +#include + +const size_t services = 5; + +void *req; +void *rep[services]; + +void setUp () +{ + setup_test_context (); + + char my_endpoint[MAX_SOCKET_STRING]; + req = test_context_socket (ZMQ_REQ); + + int enabled = 1; + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_setsockopt (req, ZMQ_REQ_RELAXED, &enabled, sizeof (int))); + + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_setsockopt (req, ZMQ_REQ_CORRELATE, &enabled, sizeof (int))); + + bind_loopback_ipv4 (req, my_endpoint, sizeof (my_endpoint)); + + for (size_t peer = 0; peer < services; peer++) { + rep[peer] = test_context_socket (ZMQ_REP); + + int timeout = 500; + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_setsockopt (rep[peer], ZMQ_RCVTIMEO, &timeout, sizeof (int))); + + TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (rep[peer], my_endpoint)); + } + // We have to give the connects time to finish otherwise the requests + // will not properly round-robin. We could alternatively connect the + // REQ sockets to the REP sockets. + msleep (SETTLE_TIME); +} + +void tearDown () +{ + test_context_socket_close_zero_linger (req); + for (size_t peer = 0; peer < services; peer++) + test_context_socket_close_zero_linger (rep[peer]); + + teardown_test_context (); +} + static void bounce (void *socket_) { int more; size_t more_size = sizeof (more); do { zmq_msg_t recv_part, sent_part; - int rc = zmq_msg_init (&recv_part); - assert (rc == 0); + TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_init (&recv_part)); - rc = zmq_msg_recv (&recv_part, socket_, 0); - assert (rc != -1); + TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_recv (&recv_part, socket_, 0)); - rc = zmq_getsockopt (socket_, ZMQ_RCVMORE, &more, &more_size); - assert (rc == 0); + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_getsockopt (socket_, ZMQ_RCVMORE, &more, &more_size)); zmq_msg_init (&sent_part); zmq_msg_copy (&sent_part, &recv_part); - rc = zmq_msg_send (&sent_part, socket_, more ? ZMQ_SNDMORE : 0); - assert (rc != -1); + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_msg_send (&sent_part, socket_, more ? ZMQ_SNDMORE : 0)); zmq_msg_close (&recv_part); } while (more); @@ -56,73 +104,33 @@ static void bounce (void *socket_) static int get_events (void *socket_) { - int rc; int events; size_t events_size = sizeof (events); - rc = zmq_getsockopt (socket_, ZMQ_EVENTS, &events, &events_size); - assert (rc == 0); + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_getsockopt (socket_, ZMQ_EVENTS, &events, &events_size)); return events; } -int main (void) +void test_case_1 () { - setup_test_environment (); - size_t len = MAX_SOCKET_STRING; - char my_endpoint[MAX_SOCKET_STRING]; - void *ctx = zmq_ctx_new (); - assert (ctx); - - void *req = zmq_socket (ctx, ZMQ_REQ); - assert (req); - - int enabled = 1; - int rc = zmq_setsockopt (req, ZMQ_REQ_RELAXED, &enabled, sizeof (int)); - assert (rc == 0); - - rc = zmq_setsockopt (req, ZMQ_REQ_CORRELATE, &enabled, sizeof (int)); - assert (rc == 0); - - rc = zmq_bind (req, "tcp://127.0.0.1:*"); - assert (rc == 0); - rc = zmq_getsockopt (req, ZMQ_LAST_ENDPOINT, my_endpoint, &len); - assert (rc == 0); - - const size_t services = 5; - void *rep[services]; - for (size_t peer = 0; peer < services; peer++) { - rep[peer] = zmq_socket (ctx, ZMQ_REP); - assert (rep[peer]); - - int timeout = 500; - rc = zmq_setsockopt (rep[peer], ZMQ_RCVTIMEO, &timeout, sizeof (int)); - assert (rc == 0); - - rc = zmq_connect (rep[peer], my_endpoint); - assert (rc == 0); - } - // We have to give the connects time to finish otherwise the requests - // will not properly round-robin. We could alternatively connect the - // REQ sockets to the REP sockets. - msleep (SETTLE_TIME); - // Case 1: Second send() before a reply arrives in a pipe. int events = get_events (req); - assert (events == ZMQ_POLLOUT); + TEST_ASSERT_EQUAL_INT (ZMQ_POLLOUT, events); // Send a request, ensure it arrives, don't send a reply s_send_seq (req, "A", "B", SEQ_END); s_recv_seq (rep[0], "A", "B", SEQ_END); events = get_events (req); - assert (events == ZMQ_POLLOUT); + TEST_ASSERT_EQUAL_INT (ZMQ_POLLOUT, events); // Send another request on the REQ socket s_send_seq (req, "C", "D", SEQ_END); s_recv_seq (rep[1], "C", "D", SEQ_END); events = get_events (req); - assert (events == ZMQ_POLLOUT); + TEST_ASSERT_EQUAL_INT (ZMQ_POLLOUT, events); // Send a reply to the first request - that should be discarded by the REQ s_send_seq (rep[0], "WRONG", SEQ_END); @@ -136,10 +144,15 @@ int main (void) s_recv_seq (rep[2], "E", SEQ_END); s_send_seq (rep[2], "F", "G", SEQ_END); s_recv_seq (req, "F", "G", SEQ_END); +} - +void test_case_2 () +{ // Case 2: Second send() after a reply is already in a pipe on the REQ. + // TODO instead of rerunning the previous test cases, only do the relevant parts (or change the peer) + test_case_1 (); + // Send a request, ensure it arrives, send a reply s_send_seq (req, "H", SEQ_END); s_recv_seq (rep[3], "H", SEQ_END); @@ -155,49 +168,50 @@ int main (void) // Send the expected reply s_send_seq (rep[4], "GOOD", SEQ_END); s_recv_seq (req, "GOOD", SEQ_END); +} +void test_case_3 () +{ // Case 3: Check issue #1690. Two send() in a row should not close the // communication pipes. For example pipe from req to rep[0] should not be // closed after executing Case 1. So rep[0] should be the next to receive, // not rep[1]. + + // TODO instead of rerunning the previous test cases, only do the relevant parts (or change the peer) + test_case_2 (); + s_send_seq (req, "J", SEQ_END); s_recv_seq (rep[0], "J", SEQ_END); +} - close_zero_linger (req); - for (size_t peer = 0; peer < services; peer++) - close_zero_linger (rep[peer]); - - // Wait for disconnects. - msleep (SETTLE_TIME); +void test_case_4 () +{ + // TODO this test case does not use the sockets from setUp // Case 4: Check issue #1695. As messages may pile up before a responder // is available, we check that responses to messages other than the last // sent one are correctly discarded by the REQ pipe // Setup REQ socket as client - req = zmq_socket (ctx, ZMQ_REQ); - assert (req); + void *req = test_context_socket (ZMQ_REQ); - rc = zmq_setsockopt (req, ZMQ_REQ_RELAXED, &enabled, sizeof (int)); - assert (rc == 0); + int enabled = 1; + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_setsockopt (req, ZMQ_REQ_RELAXED, &enabled, sizeof (int))); + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_setsockopt (req, ZMQ_REQ_CORRELATE, &enabled, sizeof (int))); - rc = zmq_setsockopt (req, ZMQ_REQ_CORRELATE, &enabled, sizeof (int)); - assert (rc == 0); - - rc = zmq_connect (req, ENDPOINT_0); - assert (rc == 0); + TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (req, ENDPOINT_0)); // Setup ROUTER socket as server but do not bind it just yet - void *router = zmq_socket (ctx, ZMQ_ROUTER); - assert (router); + void *router = test_context_socket (ZMQ_ROUTER); // Send two requests s_send_seq (req, "TO_BE_DISCARDED", SEQ_END); s_send_seq (req, "TO_BE_ANSWERED", SEQ_END); // Bind server allowing it to receive messages - rc = zmq_bind (router, ENDPOINT_0); - assert (rc == 0); + TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (router, ENDPOINT_0)); // Read the two messages and send them back as is bounce (router); @@ -207,14 +221,18 @@ int main (void) // the expected answer is "TO_BE_ANSWERED", not "TO_BE_DISCARDED". s_recv_seq (req, "TO_BE_ANSWERED", SEQ_END); - close_zero_linger (req); - close_zero_linger (router); - - // Wait for disconnects. - msleep (SETTLE_TIME); - - rc = zmq_ctx_term (ctx); - assert (rc == 0); - - return 0; + test_context_socket_close_zero_linger (req); + test_context_socket_close_zero_linger (router); +} + +int main () +{ + setup_test_environment (); + + UNITY_BEGIN (); + RUN_TEST (test_case_1); + RUN_TEST (test_case_2); + RUN_TEST (test_case_3); + RUN_TEST (test_case_4); + return UNITY_END (); } diff --git a/tests/test_spec_req.cpp b/tests/test_spec_req.cpp index 2844553b..13029b18 100644 --- a/tests/test_spec_req.cpp +++ b/tests/test_spec_req.cpp @@ -28,33 +28,40 @@ */ #include "testutil.hpp" +#include "testutil_unity.hpp" + +#include + +void setUp () +{ + setup_test_context (); +} + +void tearDown () +{ + teardown_test_context (); +} -const char *bind_address = 0; char connect_address[MAX_SOCKET_STRING]; -void test_round_robin_out (void *ctx_) +void test_round_robin_out (const char *bind_address_) { - void *req = zmq_socket (ctx_, ZMQ_REQ); - assert (req); + void *req = test_context_socket (ZMQ_REQ); - int rc = zmq_bind (req, bind_address); - assert (rc == 0); + TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (req, bind_address_)); size_t len = MAX_SOCKET_STRING; - rc = zmq_getsockopt (req, ZMQ_LAST_ENDPOINT, connect_address, &len); - assert (rc == 0); + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_getsockopt (req, ZMQ_LAST_ENDPOINT, connect_address, &len)); const size_t services = 5; void *rep[services]; for (size_t peer = 0; peer < services; peer++) { - rep[peer] = zmq_socket (ctx_, ZMQ_REP); - assert (rep[peer]); + rep[peer] = test_context_socket (ZMQ_REP); int timeout = 250; - rc = zmq_setsockopt (rep[peer], ZMQ_RCVTIMEO, &timeout, sizeof (int)); - assert (rc == 0); - - rc = zmq_connect (rep[peer], connect_address); - assert (rc == 0); + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_setsockopt (rep[peer], ZMQ_RCVTIMEO, &timeout, sizeof (int))); + TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (rep[peer], connect_address)); } // We have to give the connects time to finish otherwise the requests // will not properly round-robin. We could alternatively connect the @@ -69,47 +76,37 @@ void test_round_robin_out (void *ctx_) s_recv_seq (req, "DEF", SEQ_END); } - close_zero_linger (req); + test_context_socket_close_zero_linger (req); for (size_t peer = 0; peer < services; peer++) - close_zero_linger (rep[peer]); - - // Wait for disconnects. - msleep (SETTLE_TIME); + test_context_socket_close_zero_linger (rep[peer]); } -void test_req_only_listens_to_current_peer (void *ctx_) +void test_req_only_listens_to_current_peer (const char *bind_address_) { - void *req = zmq_socket (ctx_, ZMQ_REQ); - assert (req); + void *req = test_context_socket (ZMQ_REQ); - int rc = zmq_setsockopt (req, ZMQ_ROUTING_ID, "A", 2); - assert (rc == 0); + TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (req, ZMQ_ROUTING_ID, "A", 2)); - rc = zmq_bind (req, bind_address); - assert (rc == 0); + TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (req, bind_address_)); size_t len = MAX_SOCKET_STRING; - rc = zmq_getsockopt (req, ZMQ_LAST_ENDPOINT, connect_address, &len); - assert (rc == 0); + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_getsockopt (req, ZMQ_LAST_ENDPOINT, connect_address, &len)); const size_t services = 3; void *router[services]; for (size_t i = 0; i < services; ++i) { - router[i] = zmq_socket (ctx_, ZMQ_ROUTER); - assert (router[i]); + router[i] = test_context_socket (ZMQ_ROUTER); int timeout = 250; - rc = - zmq_setsockopt (router[i], ZMQ_RCVTIMEO, &timeout, sizeof (timeout)); - assert (rc == 0); + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_setsockopt (router[i], ZMQ_RCVTIMEO, &timeout, sizeof (timeout))); int enabled = 1; - rc = zmq_setsockopt (router[i], ZMQ_ROUTER_MANDATORY, &enabled, - sizeof (enabled)); - assert (rc == 0); + TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt ( + router[i], ZMQ_ROUTER_MANDATORY, &enabled, sizeof (enabled))); - rc = zmq_connect (router[i], connect_address); - assert (rc == 0); + TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (router[i], connect_address)); } // Wait for connects to finish. @@ -119,8 +116,8 @@ void test_req_only_listens_to_current_peer (void *ctx_) // There still is a race condition when a stale peer's message // arrives at the REQ just after a request was sent to that peer. // To avoid that happening in the test, sleep for a bit. - rc = zmq_poll (0, 0, 10); - assert (rc == 0); + TEST_ASSERT_EQUAL_INT (1, + TEST_ASSERT_SUCCESS_ERRNO (zmq_poll (0, 0, 10))); s_send_seq (req, "ABC", SEQ_END); @@ -138,30 +135,22 @@ void test_req_only_listens_to_current_peer (void *ctx_) s_recv_seq (req, "GOOD", SEQ_END); } - close_zero_linger (req); + test_context_socket_close_zero_linger (req); for (size_t i = 0; i < services; ++i) - close_zero_linger (router[i]); - - // Wait for disconnects. - msleep (SETTLE_TIME); + test_context_socket_close_zero_linger (router[i]); } -void test_req_message_format (void *ctx_) +void test_req_message_format (const char *bind_address_) { - void *req = zmq_socket (ctx_, ZMQ_REQ); - assert (req); + void *req = test_context_socket (ZMQ_REQ); + void *router = test_context_socket (ZMQ_ROUTER); - void *router = zmq_socket (ctx_, ZMQ_ROUTER); - assert (router); - - int rc = zmq_bind (req, bind_address); - assert (rc == 0); + TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (req, bind_address_)); size_t len = MAX_SOCKET_STRING; - rc = zmq_getsockopt (req, ZMQ_LAST_ENDPOINT, connect_address, &len); - assert (rc == 0); + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_getsockopt (req, ZMQ_LAST_ENDPOINT, connect_address, &len)); - rc = zmq_connect (router, connect_address); - assert (rc == 0); + TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (router, connect_address)); // Send a multi-part request. s_send_seq (req, "ABC", "DEF", SEQ_END); @@ -170,99 +159,112 @@ void test_req_message_format (void *ctx_) zmq_msg_init (&msg); // Receive peer routing id - rc = zmq_msg_recv (&msg, router, 0); - assert (rc != -1); - assert (zmq_msg_size (&msg) > 0); + TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_recv (&msg, router, 0)); + TEST_ASSERT_GREATER_THAN_INT (0, zmq_msg_size (&msg)); zmq_msg_t peer_id_msg; zmq_msg_init (&peer_id_msg); zmq_msg_copy (&peer_id_msg, &msg); int more = 0; size_t more_size = sizeof (more); - rc = zmq_getsockopt (router, ZMQ_RCVMORE, &more, &more_size); - assert (rc == 0); - assert (more); + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_getsockopt (router, ZMQ_RCVMORE, &more, &more_size)); + TEST_ASSERT_TRUE (more); // Receive the rest. s_recv_seq (router, 0, "ABC", "DEF", SEQ_END); // Send back a single-part reply. - rc = zmq_msg_send (&peer_id_msg, router, ZMQ_SNDMORE); - assert (rc != -1); + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_msg_send (&peer_id_msg, router, ZMQ_SNDMORE)); s_send_seq (router, 0, "GHI", SEQ_END); // Receive reply. s_recv_seq (req, "GHI", SEQ_END); - rc = zmq_msg_close (&msg); - assert (rc == 0); + TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&msg)); + TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&peer_id_msg)); - rc = zmq_msg_close (&peer_id_msg); - assert (rc == 0); - - close_zero_linger (req); - close_zero_linger (router); - - // Wait for disconnects. - msleep (SETTLE_TIME); + test_context_socket_close_zero_linger (req); + test_context_socket_close_zero_linger (router); } -void test_block_on_send_no_peers (void *ctx_) +void test_block_on_send_no_peers () { - void *sc = zmq_socket (ctx_, ZMQ_REQ); - assert (sc); + void *sc = test_context_socket (ZMQ_REQ); int timeout = 250; - int rc = zmq_setsockopt (sc, ZMQ_SNDTIMEO, &timeout, sizeof (timeout)); - assert (rc == 0); + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_setsockopt (sc, ZMQ_SNDTIMEO, &timeout, sizeof (timeout))); - rc = zmq_send (sc, 0, 0, ZMQ_DONTWAIT); - assert (rc == -1); - assert (errno == EAGAIN); + TEST_ASSERT_FAILURE_ERRNO (EAGAIN, zmq_send (sc, 0, 0, ZMQ_DONTWAIT)); + TEST_ASSERT_FAILURE_ERRNO (EAGAIN, zmq_send (sc, 0, 0, 0)); - rc = zmq_send (sc, 0, 0, 0); - assert (rc == -1); - assert (errno == EAGAIN); - - rc = zmq_close (sc); - assert (rc == 0); + test_context_socket_close (sc); } -int main (void) +const char bind_inproc[] = "inproc://a"; +const char bind_tcp[] = "tcp://127.0.0.1:*"; + +void test_round_robin_out_inproc () +{ + test_round_robin_out (bind_inproc); +} + +void test_round_robin_out_tcp () +{ + test_round_robin_out (bind_tcp); +} + +void test_req_message_format_inproc () +{ + test_req_message_format (bind_inproc); +} + +void test_req_message_format_tcp () +{ + test_req_message_format (bind_tcp); +} + +void test_req_only_listens_to_current_peer_inproc () +{ + test_req_only_listens_to_current_peer (bind_inproc); +} + +void test_req_only_listens_to_current_peer_tcp () +{ + test_req_only_listens_to_current_peer (bind_tcp); +} + +int main () { setup_test_environment (); - void *ctx = zmq_ctx_new (); - assert (ctx); - const char *binds[] = {"inproc://a", "tcp://127.0.0.1:*"}; + UNITY_BEGIN (); - for (int transport = 0; transport < 2; transport++) { - bind_address = binds[transport]; + // SHALL route outgoing messages to connected peers using a round-robin + // strategy. + RUN_TEST (test_round_robin_out_inproc); + RUN_TEST (test_round_robin_out_tcp); - // SHALL route outgoing messages to connected peers using a round-robin - // strategy. - test_round_robin_out (ctx); + // The request and reply messages SHALL have this format on the wire: + // * A delimiter, consisting of an empty frame, added by the REQ socket. + // * One or more data frames, comprising the message visible to the + // application. + RUN_TEST (test_req_message_format_inproc); + RUN_TEST (test_req_message_format_tcp); - // The request and reply messages SHALL have this format on the wire: - // * A delimiter, consisting of an empty frame, added by the REQ socket. - // * One or more data frames, comprising the message visible to the - // application. - test_req_message_format (ctx); + // SHALL block on sending, or return a suitable error, when it has no + // connected peers. + RUN_TEST (test_block_on_send_no_peers); - // SHALL block on sending, or return a suitable error, when it has no - // connected peers. - test_block_on_send_no_peers (ctx); + // SHALL accept an incoming message only from the last peer that it sent a + // request to. + // SHALL discard silently any messages received from other peers. + // TODO PH: this test is still failing; disabled for now to allow build to + // complete. + // RUN_TEST (test_req_only_listens_to_current_peer_inproc); + // RUN_TEST (test_req_only_listens_to_current_peer_tcp); - // SHALL accept an incoming message only from the last peer that it sent a - // request to. - // SHALL discard silently any messages received from other peers. - // PH: this test is still failing; disabled for now to allow build to - // complete. - // test_req_only_listens_to_current_peer (ctx); - } - - int rc = zmq_ctx_term (ctx); - assert (rc == 0); - - return 0; + return UNITY_END (); }