From aa77c03a37f0e5e60838f6b148508435bf633ea1 Mon Sep 17 00:00:00 2001 From: githejie Date: Fri, 9 Aug 2024 14:47:01 +0800 Subject: [PATCH 1/2] Add tests for sockopt ZMQ_RECONNECT_STOP_AFTER_DISCONNECT --- tests/test_reconnect_options.cpp | 43 ++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/tests/test_reconnect_options.cpp b/tests/test_reconnect_options.cpp index af34934b..43d8cc5a 100644 --- a/tests/test_reconnect_options.cpp +++ b/tests/test_reconnect_options.cpp @@ -246,6 +246,46 @@ void reconnect_stop_on_handshake_failed () } #endif +#if defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_HAVE_IPC) +// test stopping reconnect after disconnect +void reconnect_stop_after_disconnect () +{ + // Setup sub socket + void *sub = test_context_socket (ZMQ_SUB); + // Monitor all events on sub + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_socket_monitor (sub, "inproc://monitor-sub", ZMQ_EVENT_ALL)); + // Create socket for collecting monitor events + void *sub_mon = test_context_socket (ZMQ_PAIR); + // Connect so they'll get events + TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sub_mon, "inproc://monitor-sub")); + // Set option to stop reconnecting after disconnect + int stopReconnectAfterDisconnect = ZMQ_RECONNECT_STOP_AFTER_DISCONNECT; + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_setsockopt (sub, ZMQ_RECONNECT_STOP, &stopReconnectAfterDisconnect, + sizeof (stopReconnectAfterDisconnect))); + + // Connect to a dummy that cannot be connected + TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sub, "ipc://@dummy")); + + // Confirm that connect failed and reconnect + expect_monitor_event (sub_mon, ZMQ_EVENT_CLOSED); + expect_monitor_event (sub_mon, ZMQ_EVENT_CONNECT_RETRIED); + + // Disconnect the sub socket + TEST_ASSERT_SUCCESS_ERRNO (zmq_disconnect (sub, "ipc://@dummy")); + + // Confirm that connect failed and will not reconnect + expect_monitor_event (sub_mon, ZMQ_EVENT_CLOSED); + + // Close sub + test_context_socket_close_zero_linger (sub); + + // Close monitor + test_context_socket_close_zero_linger (sub_mon); +} +#endif + void setUp () { setup_test_context (); @@ -267,6 +307,9 @@ int main (void) #ifdef ZMQ_BUILD_DRAFT_API RUN_TEST (reconnect_stop_on_refused); RUN_TEST (reconnect_stop_on_handshake_failed); +#endif +#if defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_HAVE_IPC) + RUN_TEST (reconnect_stop_after_disconnect); #endif return UNITY_END (); } From ce17349f8bafcf3f73061f7297a18613c0ee7d3f Mon Sep 17 00:00:00 2001 From: githejie Date: Fri, 9 Aug 2024 15:05:36 +0800 Subject: [PATCH 2/2] Problem: tests reconnect_stop_after_disconnect failed Solution: this test failed because "_disconnected" is not initialized in constructor, and the behavior of reconnect will not be as designed when "_disconnected" is randomly assigned to true. So we specify it as false in initialize list to solve this problem. --- src/socket_base.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/socket_base.cpp b/src/socket_base.cpp index 5a9adcde..c76ff98d 100644 --- a/src/socket_base.cpp +++ b/src/socket_base.cpp @@ -228,7 +228,8 @@ zmq::socket_base_t::socket_base_t (ctx_t *parent_, _monitor_events (0), _thread_safe (thread_safe_), _reaper_signaler (NULL), - _monitor_sync () + _monitor_sync (), + _disconnected (false) { options.socket_id = sid_; options.ipv6 = (parent_->get (ZMQ_IPV6) != 0);