mirror of
https://github.com/zeromq/libzmq.git
synced 2025-01-19 00:46:05 +01:00
Merge pull request #3459 from sigiesec/migrate-testutil
Migrate testutil* to Unity, and build testutil as separate library
This commit is contained in:
commit
6d77558c77
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,6 +7,7 @@ doc/Makefile
|
||||
Makefile.in
|
||||
configure
|
||||
libtool
|
||||
libtestutil.a
|
||||
libunity.a
|
||||
config
|
||||
config.status
|
||||
|
532
Makefile.am
532
Makefile.am
@ -463,304 +463,316 @@ test_apps = \
|
||||
|
||||
UNITY_CPPFLAGS = -I$(top_srcdir)/external/unity -DUNITY_USE_COMMAND_LINE_ARGS -DUNITY_EXCLUDE_FLOAT
|
||||
UNITY_LIBS = $(top_builddir)/external/unity/libunity.a
|
||||
noinst_LIBRARIES = external/unity/libunity.a
|
||||
external_unity_libunity_a_SOURCES = external/unity/unity.c \
|
||||
external/unity/unity.h \
|
||||
external/unity/unity_internals.h
|
||||
|
||||
TESTUTIL_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
TESTUTIL_LIBS = $(top_builddir)/tests/libtestutil.a ${UNITY_LIBS}
|
||||
tests_libtestutil_a_SOURCES = \
|
||||
tests/testutil.cpp \
|
||||
tests/testutil.hpp \
|
||||
tests/testutil_monitoring.cpp \
|
||||
tests/testutil_monitoring.hpp \
|
||||
tests/testutil_security.cpp \
|
||||
tests/testutil_security.hpp \
|
||||
tests/testutil_unity.cpp \
|
||||
tests/testutil_unity.hpp
|
||||
tests_libtestutil_a_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
|
||||
noinst_LIBRARIES = external/unity/libunity.a tests/libtestutil.a
|
||||
|
||||
tests_test_ancillaries_SOURCES = tests/test_ancillaries.cpp
|
||||
tests_test_ancillaries_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_ancillaries_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_ancillaries_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_ancillaries_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_system_SOURCES = tests/test_system.cpp
|
||||
tests_test_system_LDADD = src/libzmq.la
|
||||
tests_test_system_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_system_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_pair_inproc_SOURCES = \
|
||||
tests/test_pair_inproc.cpp \
|
||||
tests/testutil.hpp
|
||||
tests_test_pair_inproc_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_pair_inproc_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_pair_inproc_SOURCES = tests/test_pair_inproc.cpp
|
||||
tests_test_pair_inproc_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_pair_inproc_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_pair_tcp_SOURCES = \
|
||||
tests/test_pair_tcp.cpp \
|
||||
tests/testutil.hpp
|
||||
tests_test_pair_tcp_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_pair_tcp_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_pair_tcp_SOURCES = tests/test_pair_tcp.cpp
|
||||
tests_test_pair_tcp_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_pair_tcp_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_reqrep_inproc_SOURCES = \
|
||||
tests/test_reqrep_inproc.cpp \
|
||||
tests/testutil.hpp
|
||||
tests_test_reqrep_inproc_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_reqrep_inproc_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_reqrep_inproc_SOURCES = tests/test_reqrep_inproc.cpp
|
||||
tests_test_reqrep_inproc_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_reqrep_inproc_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_reqrep_tcp_SOURCES = \
|
||||
tests/test_reqrep_tcp.cpp \
|
||||
tests/testutil.hpp
|
||||
tests_test_reqrep_tcp_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_reqrep_tcp_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_reqrep_tcp_SOURCES = tests/test_reqrep_tcp.cpp
|
||||
tests_test_reqrep_tcp_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_reqrep_tcp_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_hwm_SOURCES = tests/test_hwm.cpp tests/testutil_unity.hpp
|
||||
tests_test_hwm_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_hwm_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_hwm_SOURCES = tests/test_hwm.cpp
|
||||
tests_test_hwm_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_hwm_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_hwm_pubsub_SOURCES = tests/test_hwm_pubsub.cpp
|
||||
tests_test_hwm_pubsub_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_hwm_pubsub_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_hwm_pubsub_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_hwm_pubsub_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_reqrep_device_SOURCES = tests/test_reqrep_device.cpp
|
||||
tests_test_reqrep_device_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_reqrep_device_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_reqrep_device_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_reqrep_device_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_sub_forward_SOURCES = tests/test_sub_forward.cpp
|
||||
tests_test_sub_forward_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_sub_forward_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_sub_forward_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_sub_forward_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_invalid_rep_SOURCES = tests/test_invalid_rep.cpp
|
||||
tests_test_invalid_rep_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_invalid_rep_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_invalid_rep_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_invalid_rep_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_msg_flags_SOURCES = tests/test_msg_flags.cpp
|
||||
tests_test_msg_flags_LDADD = src/libzmq.la
|
||||
tests_test_msg_flags_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_msg_flags_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_msg_ffn_SOURCES = tests/test_msg_ffn.cpp
|
||||
tests_test_msg_ffn_LDADD = src/libzmq.la
|
||||
tests_test_msg_ffn_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_msg_ffn_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_connect_resolve_SOURCES = tests/test_connect_resolve.cpp
|
||||
tests_test_connect_resolve_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_connect_resolve_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_connect_resolve_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_connect_resolve_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_immediate_SOURCES = tests/test_immediate.cpp
|
||||
tests_test_immediate_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_immediate_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_immediate_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_immediate_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_last_endpoint_SOURCES = tests/test_last_endpoint.cpp
|
||||
tests_test_last_endpoint_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_last_endpoint_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_last_endpoint_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_last_endpoint_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_term_endpoint_SOURCES = tests/test_term_endpoint.cpp
|
||||
tests_test_term_endpoint_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_term_endpoint_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_term_endpoint_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_term_endpoint_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_srcfd_SOURCES = tests/test_srcfd.cpp
|
||||
tests_test_srcfd_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_srcfd_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_srcfd_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_srcfd_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_monitor_SOURCES = tests/test_monitor.cpp
|
||||
tests_test_monitor_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_monitor_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_monitor_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_monitor_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_router_mandatory_SOURCES = tests/test_router_mandatory.cpp tests/testutil_unity.hpp
|
||||
tests_test_router_mandatory_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_router_mandatory_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_router_mandatory_SOURCES = tests/test_router_mandatory.cpp
|
||||
tests_test_router_mandatory_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_router_mandatory_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_router_mandatory_hwm_SOURCES = tests/test_router_mandatory_hwm.cpp
|
||||
tests_test_router_mandatory_hwm_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_router_mandatory_hwm_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_router_mandatory_hwm_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_router_mandatory_hwm_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_router_handover_SOURCES = tests/test_router_handover.cpp
|
||||
tests_test_router_handover_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_router_handover_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_router_handover_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_router_handover_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_probe_router_SOURCES = tests/test_probe_router.cpp
|
||||
tests_test_probe_router_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_probe_router_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_probe_router_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_probe_router_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_stream_SOURCES = tests/test_stream.cpp
|
||||
tests_test_stream_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_stream_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_stream_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_stream_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_stream_empty_SOURCES = tests/test_stream_empty.cpp
|
||||
tests_test_stream_empty_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_stream_empty_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_stream_empty_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_stream_empty_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_stream_timeout_SOURCES = tests/test_stream_timeout.cpp
|
||||
tests_test_stream_timeout_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_stream_timeout_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_stream_timeout_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_stream_timeout_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_stream_disconnect_SOURCES = tests/test_stream_disconnect.cpp
|
||||
tests_test_stream_disconnect_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_stream_disconnect_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_stream_disconnect_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_stream_disconnect_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_disconnect_inproc_SOURCES = tests/test_disconnect_inproc.cpp
|
||||
tests_test_disconnect_inproc_LDADD = src/libzmq.la
|
||||
tests_test_disconnect_inproc_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_disconnect_inproc_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_unbind_wildcard_SOURCES = tests/test_unbind_wildcard.cpp
|
||||
tests_test_unbind_wildcard_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_unbind_wildcard_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_unbind_wildcard_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_unbind_wildcard_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_ctx_options_SOURCES = tests/test_ctx_options.cpp
|
||||
tests_test_ctx_options_LDADD = src/libzmq.la
|
||||
tests_test_ctx_options_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_ctx_options_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_iov_SOURCES = tests/test_iov.cpp
|
||||
tests_test_iov_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_iov_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_iov_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_iov_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_ctx_destroy_SOURCES = tests/test_ctx_destroy.cpp
|
||||
tests_test_ctx_destroy_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_ctx_destroy_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_ctx_destroy_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_ctx_destroy_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_security_no_zap_handler_SOURCES = tests/test_security_no_zap_handler.cpp
|
||||
tests_test_security_no_zap_handler_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_security_no_zap_handler_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_security_no_zap_handler_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_security_no_zap_handler_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_security_null_SOURCES = tests/test_security_null.cpp
|
||||
tests_test_security_null_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_security_null_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_security_null_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_security_null_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_security_plain_SOURCES = tests/test_security_plain.cpp
|
||||
tests_test_security_plain_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_security_plain_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_security_plain_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_security_plain_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_security_zap_SOURCES = \
|
||||
tests/test_security_zap.cpp \
|
||||
tests/testutil_monitoring.hpp \
|
||||
tests/testutil_security.hpp \
|
||||
tests/testutil.hpp
|
||||
tests_test_security_zap_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_security_zap_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_security_zap_SOURCES = tests/test_security_zap.cpp
|
||||
tests_test_security_zap_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_security_zap_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_spec_req_SOURCES = tests/test_spec_req.cpp
|
||||
tests_test_spec_req_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_spec_req_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_spec_req_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_spec_req_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_spec_rep_SOURCES = tests/test_spec_rep.cpp
|
||||
tests_test_spec_rep_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_spec_rep_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_spec_rep_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_spec_rep_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_spec_dealer_SOURCES = tests/test_spec_dealer.cpp
|
||||
tests_test_spec_dealer_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_spec_dealer_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_spec_dealer_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_spec_dealer_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_spec_router_SOURCES = tests/test_spec_router.cpp
|
||||
tests_test_spec_router_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_spec_router_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_spec_router_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_spec_router_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_spec_pushpull_SOURCES = tests/test_spec_pushpull.cpp
|
||||
tests_test_spec_pushpull_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_spec_pushpull_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_spec_pushpull_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_spec_pushpull_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_req_correlate_SOURCES = tests/test_req_correlate.cpp
|
||||
tests_test_req_correlate_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_req_correlate_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_req_correlate_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_req_correlate_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_req_relaxed_SOURCES = tests/test_req_relaxed.cpp
|
||||
tests_test_req_relaxed_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_req_relaxed_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_req_relaxed_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_req_relaxed_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_conflate_SOURCES = tests/test_conflate.cpp
|
||||
tests_test_conflate_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_conflate_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_conflate_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_conflate_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_inproc_connect_SOURCES = tests/test_inproc_connect.cpp
|
||||
tests_test_inproc_connect_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_inproc_connect_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_inproc_connect_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_inproc_connect_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_issue_566_SOURCES = tests/test_issue_566.cpp
|
||||
tests_test_issue_566_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_issue_566_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_issue_566_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_issue_566_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_proxy_SOURCES = tests/test_proxy.cpp
|
||||
tests_test_proxy_LDADD = src/libzmq.la
|
||||
tests_test_proxy_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_proxy_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_proxy_hwm_SOURCES = tests/test_proxy_hwm.cpp
|
||||
tests_test_proxy_hwm_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_proxy_hwm_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_proxy_hwm_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_proxy_hwm_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_proxy_single_socket_SOURCES = tests/test_proxy_single_socket.cpp
|
||||
tests_test_proxy_single_socket_LDADD = src/libzmq.la
|
||||
tests_test_proxy_single_socket_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_proxy_single_socket_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_proxy_terminate_SOURCES = tests/test_proxy_terminate.cpp
|
||||
tests_test_proxy_terminate_LDADD = src/libzmq.la
|
||||
tests_test_proxy_terminate_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_proxy_terminate_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_getsockopt_memset_SOURCES = tests/test_getsockopt_memset.cpp
|
||||
tests_test_getsockopt_memset_LDADD = src/libzmq.la
|
||||
tests_test_getsockopt_memset_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_getsockopt_memset_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_many_sockets_SOURCES = tests/test_many_sockets.cpp
|
||||
tests_test_many_sockets_LDADD = src/libzmq.la
|
||||
tests_test_many_sockets_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_many_sockets_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_diffserv_SOURCES = tests/test_diffserv.cpp
|
||||
tests_test_diffserv_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_diffserv_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_diffserv_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_diffserv_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_connect_rid_SOURCES = tests/test_connect_rid.cpp
|
||||
tests_test_connect_rid_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_connect_rid_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_connect_rid_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_connect_rid_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_bind_src_address_SOURCES = tests/test_bind_src_address.cpp
|
||||
tests_test_bind_src_address_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_bind_src_address_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_bind_src_address_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_bind_src_address_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_metadata_SOURCES = tests/test_metadata.cpp
|
||||
tests_test_metadata_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_metadata_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_metadata_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_metadata_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_capabilities_SOURCES = tests/test_capabilities.cpp
|
||||
tests_test_capabilities_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_capabilities_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_capabilities_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_capabilities_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_xpub_nodrop_SOURCES = tests/test_xpub_nodrop.cpp
|
||||
tests_test_xpub_nodrop_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_xpub_nodrop_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_xpub_nodrop_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_xpub_nodrop_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_xpub_manual_SOURCES = tests/test_xpub_manual.cpp
|
||||
tests_test_xpub_manual_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_xpub_manual_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_xpub_manual_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_xpub_manual_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_xpub_welcome_msg_SOURCES = tests/test_xpub_welcome_msg.cpp
|
||||
tests_test_xpub_welcome_msg_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_xpub_welcome_msg_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_xpub_welcome_msg_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_xpub_welcome_msg_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_xpub_verbose_SOURCES = tests/test_xpub_verbose.cpp
|
||||
tests_test_xpub_verbose_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_xpub_verbose_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_xpub_verbose_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_xpub_verbose_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_atomics_SOURCES = tests/test_atomics.cpp
|
||||
tests_test_atomics_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_atomics_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_atomics_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_atomics_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_sockopt_hwm_SOURCES = tests/test_sockopt_hwm.cpp
|
||||
tests_test_sockopt_hwm_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_sockopt_hwm_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_sockopt_hwm_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_sockopt_hwm_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_setsockopt_SOURCES = tests/test_setsockopt.cpp
|
||||
tests_test_setsockopt_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_setsockopt_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_setsockopt_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_setsockopt_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_heartbeats_SOURCES = tests/test_heartbeats.cpp
|
||||
tests_test_heartbeats_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_heartbeats_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_heartbeats_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_heartbeats_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_stream_exceeds_buffer_SOURCES = tests/test_stream_exceeds_buffer.cpp
|
||||
tests_test_stream_exceeds_buffer_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_stream_exceeds_buffer_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_stream_exceeds_buffer_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_stream_exceeds_buffer_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_pub_invert_matching_SOURCES = tests/test_pub_invert_matching.cpp
|
||||
tests_test_pub_invert_matching_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_pub_invert_matching_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_pub_invert_matching_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_pub_invert_matching_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_bind_after_connect_tcp_SOURCES = tests/test_bind_after_connect_tcp.cpp
|
||||
tests_test_bind_after_connect_tcp_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_bind_after_connect_tcp_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_bind_after_connect_tcp_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_bind_after_connect_tcp_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_base85_SOURCES = tests/test_base85.cpp
|
||||
tests_test_base85_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_base85_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_base85_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_base85_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_sodium_SOURCES = tests/test_sodium.cpp
|
||||
tests_test_sodium_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_sodium_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_sodium_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_sodium_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_socket_null_SOURCES = tests/test_socket_null.cpp
|
||||
tests_test_socket_null_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_socket_null_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_socket_null_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_socket_null_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_reconnect_ivl_SOURCES = tests/test_reconnect_ivl.cpp
|
||||
tests_test_reconnect_ivl_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_reconnect_ivl_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_reconnect_ivl_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_reconnect_ivl_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_mock_pub_sub_SOURCES = tests/test_mock_pub_sub.cpp
|
||||
tests_test_mock_pub_sub_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_mock_pub_sub_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_mock_pub_sub_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_mock_pub_sub_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
if HAVE_CURVE
|
||||
|
||||
@ -769,9 +781,7 @@ test_apps += \
|
||||
|
||||
tests_test_security_curve_SOURCES = \
|
||||
tests/test_security_curve.cpp \
|
||||
tests/testutil_security.hpp \
|
||||
tests/testutil.hpp \
|
||||
src/curve_client_tools.hpp \
|
||||
src/curve_client_tools.hpp \
|
||||
src/clock.hpp \
|
||||
src/clock.cpp \
|
||||
src/random.hpp \
|
||||
@ -785,9 +795,9 @@ tests_test_security_curve_SOURCES += \
|
||||
endif
|
||||
|
||||
tests_test_security_curve_LDADD = \
|
||||
src/libzmq.la ${UNITY_LIBS} $(LIBUNWIND_LIBS)
|
||||
src/libzmq.la ${TESTUTIL_LIBS} $(LIBUNWIND_LIBS)
|
||||
tests_test_security_curve_CPPFLAGS = \
|
||||
${UNITY_CPPFLAGS} \
|
||||
${TESTUTIL_CPPFLAGS} \
|
||||
${LIBUNWIND_CFLAGS}
|
||||
|
||||
if USE_LIBSODIUM
|
||||
@ -813,53 +823,48 @@ test_apps += \
|
||||
tests/test_filter_ipc
|
||||
|
||||
tests_test_shutdown_stress_SOURCES = tests/test_shutdown_stress.cpp
|
||||
tests_test_shutdown_stress_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_shutdown_stress_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_shutdown_stress_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_shutdown_stress_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_ipc_wildcard_SOURCES = tests/test_ipc_wildcard.cpp
|
||||
tests_test_ipc_wildcard_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_ipc_wildcard_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_ipc_wildcard_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_ipc_wildcard_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_pair_ipc_SOURCES = \
|
||||
tests/test_pair_ipc.cpp \
|
||||
tests/testutil.hpp
|
||||
tests_test_pair_ipc_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_pair_ipc_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_pair_ipc_SOURCES = tests/test_pair_ipc.cpp
|
||||
tests_test_pair_ipc_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_pair_ipc_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_rebind_ipc_SOURCES = tests/test_rebind_ipc.cpp
|
||||
tests_test_rebind_ipc_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_rebind_ipc_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_rebind_ipc_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_rebind_ipc_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_reqrep_ipc_SOURCES = \
|
||||
tests/test_reqrep_ipc.cpp \
|
||||
tests/testutil.hpp
|
||||
tests_test_reqrep_ipc_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_reqrep_ipc_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_reqrep_ipc_SOURCES = tests/test_reqrep_ipc.cpp
|
||||
tests_test_reqrep_ipc_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_reqrep_ipc_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_timeo_SOURCES = tests/test_timeo.cpp
|
||||
tests_test_timeo_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_timeo_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_timeo_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_timeo_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_filter_ipc_SOURCES = tests/test_filter_ipc.cpp
|
||||
tests_test_filter_ipc_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_filter_ipc_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_filter_ipc_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_filter_ipc_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_use_fd_SOURCES = \
|
||||
tests/test_use_fd.cpp \
|
||||
tests/testutil.hpp
|
||||
tests_test_use_fd_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_use_fd_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_use_fd_SOURCES = tests/test_use_fd.cpp
|
||||
tests_test_use_fd_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_use_fd_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_zmq_poll_fd_SOURCES = tests/test_zmq_poll_fd.cpp
|
||||
tests_test_zmq_poll_fd_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_zmq_poll_fd_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_zmq_poll_fd_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_zmq_poll_fd_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
if HAVE_FORK
|
||||
if !VALGRIND_ENABLED
|
||||
test_apps += tests/test_fork
|
||||
|
||||
tests_test_fork_SOURCES = tests/test_fork.cpp
|
||||
tests_test_fork_LDADD = src/libzmq.la
|
||||
tests_test_fork_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_fork_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
endif
|
||||
endif
|
||||
@ -879,38 +884,40 @@ test_apps += \
|
||||
tests/test_address_tipc
|
||||
|
||||
tests_test_connect_delay_tipc_SOURCES = tests/test_connect_delay_tipc.cpp
|
||||
tests_test_connect_delay_tipc_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_connect_delay_tipc_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_connect_delay_tipc_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_connect_delay_tipc_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_pair_tipc_SOURCES = tests/test_pair_tipc.cpp
|
||||
tests_test_pair_tipc_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_pair_tipc_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_pair_tipc_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_pair_tipc_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_reqrep_device_tipc_SOURCES = tests/test_reqrep_device_tipc.cpp
|
||||
tests_test_reqrep_device_tipc_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_reqrep_device_tipc_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_reqrep_device_tipc_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_reqrep_device_tipc_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_reqrep_tipc_SOURCES = tests/test_reqrep_tipc.cpp
|
||||
tests_test_reqrep_tipc_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_reqrep_tipc_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_reqrep_tipc_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_reqrep_tipc_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_router_mandatory_tipc_SOURCES = tests/test_router_mandatory_tipc.cpp
|
||||
tests_test_router_mandatory_tipc_LDADD = src/libzmq.la
|
||||
tests_test_router_mandatory_tipc_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_router_mandatory_tipc_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_shutdown_stress_tipc_SOURCES = tests/test_shutdown_stress_tipc.cpp
|
||||
tests_test_shutdown_stress_tipc_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_shutdown_stress_tipc_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_shutdown_stress_tipc_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_shutdown_stress_tipc_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_sub_forward_tipc_SOURCES = tests/test_sub_forward_tipc.cpp
|
||||
tests_test_sub_forward_tipc_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_sub_forward_tipc_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_sub_forward_tipc_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_sub_forward_tipc_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_term_endpoint_tipc_SOURCES = tests/test_term_endpoint_tipc.cpp
|
||||
tests_test_term_endpoint_tipc_LDADD = src/libzmq.la
|
||||
tests_test_term_endpoint_tipc_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_term_endpoint_tipc_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_address_tipc_SOURCES = tests/test_address_tipc.cpp
|
||||
tests_test_address_tipc_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_address_tipc_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_address_tipc_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_address_tipc_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
endif
|
||||
|
||||
@ -918,7 +925,8 @@ if BUILD_GSSAPI
|
||||
test_apps += tests/test_security_gssapi
|
||||
|
||||
tests_test_security_gssapi_SOURCES = tests/test_security_gssapi.cpp
|
||||
tests_test_security_gssapi_LDADD = src/libzmq.la
|
||||
tests_test_security_gssapi_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_security_gssapi_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
endif
|
||||
|
||||
@ -927,8 +935,8 @@ test_apps += tests/test_abstract_ipc \
|
||||
tests/test_many_sockets
|
||||
|
||||
tests_test_abstract_ipc_SOURCES = tests/test_abstract_ipc.cpp
|
||||
tests_test_abstract_ipc_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_abstract_ipc_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_abstract_ipc_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_abstract_ipc_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
endif
|
||||
|
||||
@ -936,12 +944,14 @@ if HAVE_VMCI
|
||||
test_apps += test_pair_vmci test_reqrep_vmci
|
||||
|
||||
test_pair_vmci_SOURCES = tests/test_pair_vmci.cpp
|
||||
test_pair_vmci_LDADD = src/libzmq.la
|
||||
test_pair_vmci_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
test_pair_vmci_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
test_pair_vmci_LDFLAGS = @LIBZMQ_VMCI_LDFLAGS@
|
||||
test_pair_vmci_CXXFLAGS = @LIBZMQ_VMCI_CXXFLAGS@
|
||||
|
||||
test_reqrep_vmci_SOURCES = tests/test_reqrep_vmci.cpp
|
||||
test_reqrep_vmci_LDADD = src/libzmq.la
|
||||
test_reqrep_vmci_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
test_reqrep_vmci_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
test_reqrep_vmci_LDFLAGS = @LIBZMQ_VMCI_LDFLAGS@
|
||||
test_reqrep_vmci_CXXFLAGS = @LIBZMQ_VMCI_CXXFLAGS@
|
||||
|
||||
@ -959,40 +969,40 @@ test_apps += tests/test_poller \
|
||||
tests/test_router_notify
|
||||
|
||||
tests_test_poller_SOURCES = tests/test_poller.cpp
|
||||
tests_test_poller_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_poller_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_poller_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_poller_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_client_server_SOURCES = tests/test_client_server.cpp
|
||||
tests_test_client_server_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_client_server_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_client_server_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_client_server_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_thread_safe_SOURCES = tests/test_thread_safe.cpp
|
||||
tests_test_thread_safe_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_thread_safe_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_thread_safe_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_thread_safe_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_timers_SOURCES = tests/test_timers.cpp
|
||||
tests_test_timers_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_timers_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_timers_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_timers_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_radio_dish_SOURCES = tests/test_radio_dish.cpp
|
||||
tests_test_radio_dish_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_radio_dish_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_radio_dish_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_radio_dish_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_scatter_gather_SOURCES = tests/test_scatter_gather.cpp
|
||||
tests_test_scatter_gather_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_scatter_gather_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_scatter_gather_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_scatter_gather_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_dgram_SOURCES = tests/test_dgram.cpp
|
||||
tests_test_dgram_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_dgram_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_dgram_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_dgram_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_app_meta_SOURCES = tests/test_app_meta.cpp
|
||||
tests_test_app_meta_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_app_meta_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_app_meta_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_app_meta_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
|
||||
tests_test_router_notify_SOURCES = tests/test_router_notify.cpp
|
||||
tests_test_router_notify_LDADD = src/libzmq.la ${UNITY_LIBS}
|
||||
tests_test_router_notify_CPPFLAGS = ${UNITY_CPPFLAGS}
|
||||
tests_test_router_notify_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
|
||||
tests_test_router_notify_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
|
||||
endif
|
||||
|
||||
if ENABLE_STATIC
|
||||
@ -1006,52 +1016,58 @@ test_apps += \
|
||||
unittests/unittest_radix_tree
|
||||
|
||||
unittests_unittest_poller_SOURCES = unittests/unittest_poller.cpp
|
||||
unittests_unittest_poller_CPPFLAGS = -I$(top_srcdir)/src ${UNITY_CPPFLAGS} $(CODE_COVERAGE_CPPFLAGS)
|
||||
unittests_unittest_poller_CPPFLAGS = -I$(top_srcdir)/src ${TESTUTIL_CPPFLAGS} $(CODE_COVERAGE_CPPFLAGS)
|
||||
unittests_unittest_poller_CXXFLAGS = $(CODE_COVERAGE_CXXFLAGS)
|
||||
unittests_unittest_poller_LDADD = $(top_builddir)/src/.libs/libzmq.a \
|
||||
${src_libzmq_la_LIBADD} \
|
||||
${UNITY_LIBS} \
|
||||
$(CODE_COVERAGE_LDFLAGS)
|
||||
unittests_unittest_poller_LDADD = \
|
||||
${TESTUTIL_LIBS} \
|
||||
$(top_builddir)/src/.libs/libzmq.a \
|
||||
${src_libzmq_la_LIBADD} \
|
||||
$(CODE_COVERAGE_LDFLAGS)
|
||||
|
||||
unittests_unittest_ypipe_SOURCES = unittests/unittest_ypipe.cpp
|
||||
unittests_unittest_ypipe_CPPFLAGS = -I$(top_srcdir)/src ${UNITY_CPPFLAGS} $(CODE_COVERAGE_CPPFLAGS)
|
||||
unittests_unittest_ypipe_CPPFLAGS = -I$(top_srcdir)/src ${TESTUTIL_CPPFLAGS} $(CODE_COVERAGE_CPPFLAGS)
|
||||
unittests_unittest_ypipe_CXXFLAGS = $(CODE_COVERAGE_CXXFLAGS)
|
||||
unittests_unittest_ypipe_LDADD = $(top_builddir)/src/.libs/libzmq.a \
|
||||
${src_libzmq_la_LIBADD} \
|
||||
${UNITY_LIBS} \
|
||||
$(CODE_COVERAGE_LDFLAGS)
|
||||
unittests_unittest_ypipe_LDADD = \
|
||||
${TESTUTIL_LIBS} \
|
||||
$(top_builddir)/src/.libs/libzmq.a \
|
||||
${src_libzmq_la_LIBADD} \
|
||||
$(CODE_COVERAGE_LDFLAGS)
|
||||
|
||||
unittests_unittest_mtrie_SOURCES = unittests/unittest_mtrie.cpp
|
||||
unittests_unittest_mtrie_CPPFLAGS = -I$(top_srcdir)/src ${UNITY_CPPFLAGS} $(CODE_COVERAGE_CPPFLAGS)
|
||||
unittests_unittest_mtrie_CPPFLAGS = -I$(top_srcdir)/src ${TESTUTIL_CPPFLAGS} $(CODE_COVERAGE_CPPFLAGS)
|
||||
unittests_unittest_mtrie_CXXFLAGS = $(CODE_COVERAGE_CXXFLAGS)
|
||||
unittests_unittest_mtrie_LDADD = $(top_builddir)/src/.libs/libzmq.a \
|
||||
${src_libzmq_la_LIBADD} \
|
||||
${UNITY_LIBS} \
|
||||
$(CODE_COVERAGE_LDFLAGS)
|
||||
unittests_unittest_mtrie_LDADD = \
|
||||
${TESTUTIL_LIBS} \
|
||||
$(top_builddir)/src/.libs/libzmq.a \
|
||||
${src_libzmq_la_LIBADD} \
|
||||
$(CODE_COVERAGE_LDFLAGS)
|
||||
|
||||
unittests_unittest_ip_resolver_SOURCES = unittests/unittest_ip_resolver.cpp unittests/unittest_resolver_common.hpp
|
||||
unittests_unittest_ip_resolver_CPPFLAGS = -I$(top_srcdir)/src ${UNITY_CPPFLAGS} $(CODE_COVERAGE_CPPFLAGS)
|
||||
unittests_unittest_ip_resolver_CPPFLAGS = -I$(top_srcdir)/src ${TESTUTIL_CPPFLAGS} $(CODE_COVERAGE_CPPFLAGS)
|
||||
unittests_unittest_ip_resolver_CXXFLAGS = $(CODE_COVERAGE_CXXFLAGS)
|
||||
unittests_unittest_ip_resolver_LDADD = $(top_builddir)/src/.libs/libzmq.a \
|
||||
${src_libzmq_la_LIBADD} \
|
||||
${UNITY_LIBS} \
|
||||
$(CODE_COVERAGE_LDFLAGS)
|
||||
unittests_unittest_ip_resolver_LDADD = \
|
||||
${TESTUTIL_LIBS} \
|
||||
$(top_builddir)/src/.libs/libzmq.a \
|
||||
${src_libzmq_la_LIBADD} \
|
||||
$(CODE_COVERAGE_LDFLAGS)
|
||||
|
||||
unittests_unittest_udp_address_SOURCES = unittests/unittest_udp_address.cpp unittests/unittest_resolver_common.hpp
|
||||
unittests_unittest_udp_address_CPPFLAGS = -I$(top_srcdir)/src ${UNITY_CPPFLAGS} $(CODE_COVERAGE_CPPFLAGS)
|
||||
unittests_unittest_udp_address_CPPFLAGS = -I$(top_srcdir)/src ${TESTUTIL_CPPFLAGS} $(CODE_COVERAGE_CPPFLAGS)
|
||||
unittests_unittest_udp_address_CXXFLAGS = $(CODE_COVERAGE_CXXFLAGS)
|
||||
unittests_unittest_udp_address_LDADD = $(top_builddir)/src/.libs/libzmq.a \
|
||||
${src_libzmq_la_LIBADD} \
|
||||
${UNITY_LIBS} \
|
||||
$(CODE_COVERAGE_LDFLAGS)
|
||||
unittests_unittest_udp_address_LDADD = \
|
||||
${TESTUTIL_LIBS} \
|
||||
$(top_builddir)/src/.libs/libzmq.a \
|
||||
${src_libzmq_la_LIBADD} \
|
||||
$(CODE_COVERAGE_LDFLAGS)
|
||||
|
||||
unittests_unittest_radix_tree_SOURCES = unittests/unittest_radix_tree.cpp
|
||||
unittests_unittest_radix_tree_CPPFLAGS = -I$(top_srcdir)/src ${UNITY_CPPFLAGS} $(CODE_COVERAGE_CPPFLAGS)
|
||||
unittests_unittest_radix_tree_CPPFLAGS = -I$(top_srcdir)/src ${TESTUTIL_CPPFLAGS} $(CODE_COVERAGE_CPPFLAGS)
|
||||
unittests_unittest_radix_tree_CXXFLAGS = $(CODE_COVERAGE_CXXFLAGS)
|
||||
unittests_unittest_radix_tree_LDADD = $(top_builddir)/src/.libs/libzmq.a \
|
||||
${src_libzmq_la_LIBADD} \
|
||||
${UNITY_LIBS} \
|
||||
$(CODE_COVERAGE_LDFLAGS)
|
||||
unittests_unittest_radix_tree_LDADD = \
|
||||
${TESTUTIL_LIBS} \
|
||||
$(top_builddir)/src/.libs/libzmq.a \
|
||||
${src_libzmq_la_LIBADD} \
|
||||
$(CODE_COVERAGE_LDFLAGS)
|
||||
endif
|
||||
|
||||
check_PROGRAMS = ${test_apps}
|
||||
|
@ -33,6 +33,7 @@
|
||||
#if !defined ZMQ_HAVE_WINDOWS
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
#include "address.hpp"
|
||||
|
@ -136,7 +136,7 @@ zmq::socks_request_t::socks_request_t (uint8_t command_,
|
||||
hostname (ZMQ_MOVE (hostname_)),
|
||||
port (port_)
|
||||
{
|
||||
zmq_assert (hostname_.size () <= UINT8_MAX);
|
||||
zmq_assert (hostname.size () <= UINT8_MAX);
|
||||
}
|
||||
|
||||
zmq::socks_request_encoder_t::socks_request_encoder_t () :
|
||||
|
@ -297,13 +297,20 @@ void zmq::stream_engine_t::terminate ()
|
||||
}
|
||||
|
||||
void zmq::stream_engine_t::in_event ()
|
||||
{
|
||||
// ignore errors
|
||||
const bool res = in_event_internal ();
|
||||
LIBZMQ_UNUSED (res);
|
||||
}
|
||||
|
||||
bool zmq::stream_engine_t::in_event_internal ()
|
||||
{
|
||||
zmq_assert (!_io_error);
|
||||
|
||||
// If still handshaking, receive and process the greeting message.
|
||||
if (unlikely (_handshaking))
|
||||
if (!handshake ())
|
||||
return;
|
||||
return false;
|
||||
|
||||
zmq_assert (_decoder);
|
||||
|
||||
@ -311,7 +318,7 @@ void zmq::stream_engine_t::in_event ()
|
||||
if (_input_stopped) {
|
||||
rm_fd (_handle);
|
||||
_io_error = true;
|
||||
return;
|
||||
return true; // TODO or return false in this case too?
|
||||
}
|
||||
|
||||
// If there's no data to process in the buffer...
|
||||
@ -329,12 +336,14 @@ void zmq::stream_engine_t::in_event ()
|
||||
// connection closed by peer
|
||||
errno = EPIPE;
|
||||
error (connection_error);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
if (rc == -1) {
|
||||
if (errno != EAGAIN)
|
||||
if (errno != EAGAIN) {
|
||||
error (connection_error);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Adjust input size
|
||||
@ -363,13 +372,14 @@ void zmq::stream_engine_t::in_event ()
|
||||
if (rc == -1) {
|
||||
if (errno != EAGAIN) {
|
||||
error (protocol_error);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
_input_stopped = true;
|
||||
reset_pollin (_handle);
|
||||
}
|
||||
|
||||
_session->flush ();
|
||||
return true;
|
||||
}
|
||||
|
||||
void zmq::stream_engine_t::out_event ()
|
||||
@ -497,7 +507,8 @@ bool zmq::stream_engine_t::restart_input ()
|
||||
_session->flush ();
|
||||
|
||||
// Speculative read.
|
||||
in_event ();
|
||||
if (!in_event_internal ())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -87,6 +87,8 @@ class stream_engine_t : public io_object_t, public i_engine
|
||||
void timer_event (int id_);
|
||||
|
||||
private:
|
||||
bool in_event_internal ();
|
||||
|
||||
// Unplug the engine from the session.
|
||||
void unplug ();
|
||||
|
||||
|
@ -75,6 +75,11 @@ set(tests
|
||||
test_mock_pub_sub
|
||||
)
|
||||
|
||||
if(NOT WIN32)
|
||||
list(APPEND tests
|
||||
test_security_gssapi)
|
||||
endif()
|
||||
|
||||
if(ZMQ_HAVE_CURVE)
|
||||
list(APPEND tests
|
||||
test_security_curve)
|
||||
@ -168,6 +173,32 @@ set_target_properties(unity PROPERTIES
|
||||
target_compile_definitions(unity PUBLIC "UNITY_USE_COMMAND_LINE_ARGS" "UNITY_EXCLUDE_FLOAT")
|
||||
target_include_directories(unity PUBLIC "${CMAKE_CURRENT_LIST_DIR}/../external/unity")
|
||||
|
||||
set(TESTUTIL_SOURCES
|
||||
testutil.cpp
|
||||
testutil.hpp
|
||||
testutil_monitoring.cpp
|
||||
testutil_monitoring.hpp
|
||||
testutil_security.cpp
|
||||
testutil_security.hpp
|
||||
testutil_unity.cpp
|
||||
testutil_unity.hpp
|
||||
)
|
||||
if(BUILD_STATIC)
|
||||
add_library(testutil-static STATIC ${TESTUTIL_SOURCES})
|
||||
target_link_libraries(testutil-static libzmq-static ${OPTIONAL_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} unity)
|
||||
endif()
|
||||
if(BUILD_SHARED)
|
||||
add_library(testutil STATIC ${TESTUTIL_SOURCES})
|
||||
target_link_libraries(testutil libzmq ${OPTIONAL_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} unity)
|
||||
endif()
|
||||
if(BUILD_STATIC AND NOT BUILD_SHARED)
|
||||
# use testutil-static for both tests and unit tests
|
||||
set(TESTUTIL_LIB testutil-static)
|
||||
else()
|
||||
# use testutil for tests and testutil-static for unit tests
|
||||
set(TESTUTIL_LIB testutil)
|
||||
endif()
|
||||
|
||||
if(MSVC_VERSION LESS 1700)
|
||||
set_source_files_properties("${CMAKE_CURRENT_LIST_DIR}/../external/unity/unity.c" PROPERTIES LANGUAGE CXX)
|
||||
endif()
|
||||
@ -176,13 +207,11 @@ if(MSVC_VERSION LESS 1600)
|
||||
target_compile_definitions(unity PUBLIC "UNITY_EXCLUDE_STDINT_H")
|
||||
endif()
|
||||
|
||||
# add library and include dirs for all targets
|
||||
if(BUILD_SHARED)
|
||||
link_libraries(libzmq ${OPTIONAL_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} unity)
|
||||
else()
|
||||
link_libraries(libzmq-static ${OPTIONAL_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} unity)
|
||||
endif()
|
||||
# add include dirs for all targets
|
||||
include_directories("${ZeroMQ_SOURCE_DIR}/../include" "${ZeroMQ_BINARY_DIR}")
|
||||
if(WIN32)
|
||||
add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
|
||||
endif()
|
||||
|
||||
foreach(test ${tests})
|
||||
# target_sources not supported before CMake 3.1
|
||||
@ -191,14 +220,11 @@ foreach(test ${tests})
|
||||
"../src/tweetnacl.c"
|
||||
"../src/err.cpp"
|
||||
"../src/random.cpp"
|
||||
"../src/clock.cpp"
|
||||
"testutil_security.hpp")
|
||||
elseif(${test} MATCHES test_security_zap)
|
||||
add_executable(${test} ${test}.cpp
|
||||
"testutil_security.hpp")
|
||||
"../src/clock.cpp")
|
||||
else()
|
||||
add_executable(${test} ${test}.cpp "testutil.hpp" "testutil_unity.hpp" "testutil_monitoring.hpp")
|
||||
add_executable(${test} ${test}.cpp)
|
||||
endif()
|
||||
target_link_libraries(${test} ${TESTUTIL_LIB})
|
||||
if(WIN32)
|
||||
# This is the output for Debug dynamic builds on Visual Studio 6.0
|
||||
# You should provide the correct directory, don't know how to do it automatically
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <string.h>
|
||||
#include <unity.h>
|
||||
|
||||
void setUp ()
|
||||
|
@ -57,7 +57,7 @@ void test_version ()
|
||||
|
||||
void test_strerrror ()
|
||||
{
|
||||
assert (zmq_strerror (EINVAL));
|
||||
TEST_ASSERT_NOT_NULL (zmq_strerror (EINVAL));
|
||||
}
|
||||
|
||||
int main ()
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "testutil_unity.hpp"
|
||||
#include <unity.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
|
@ -44,7 +44,8 @@ static void receiver (void *socket_)
|
||||
{
|
||||
char buffer[16];
|
||||
int rc = zmq_recv (socket_, &buffer, sizeof (buffer), 0);
|
||||
assert (rc == -1);
|
||||
// TODO which error is expected here? use TEST_ASSERT_FAILURE_ERRNO instead
|
||||
TEST_ASSERT_EQUAL_INT (-1, rc);
|
||||
}
|
||||
|
||||
void test_ctx_destroy ()
|
||||
|
@ -29,6 +29,17 @@
|
||||
|
||||
#include <limits>
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
}
|
||||
|
||||
void tearDown ()
|
||||
{
|
||||
teardown_test_context ();
|
||||
}
|
||||
|
||||
#define WAIT_FOR_BACKGROUND_THREAD_INSPECTION (0)
|
||||
|
||||
@ -36,6 +47,7 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <unistd.h> // for sleep()
|
||||
#include <sched.h>
|
||||
|
||||
#define TEST_POLICY \
|
||||
(SCHED_OTHER) // NOTE: SCHED_OTHER is the default Linux scheduler
|
||||
@ -74,27 +86,25 @@ bool is_allowed_to_raise_priority ()
|
||||
#endif
|
||||
|
||||
|
||||
void test_ctx_thread_opts (void *ctx_)
|
||||
void test_ctx_thread_opts ()
|
||||
{
|
||||
int rc;
|
||||
|
||||
// verify that setting negative values (e.g., default values) fail:
|
||||
rc =
|
||||
zmq_ctx_set (ctx_, ZMQ_THREAD_SCHED_POLICY, ZMQ_THREAD_SCHED_POLICY_DFLT);
|
||||
assert (rc == -1 && errno == EINVAL);
|
||||
rc = zmq_ctx_set (ctx_, ZMQ_THREAD_PRIORITY, ZMQ_THREAD_PRIORITY_DFLT);
|
||||
assert (rc == -1 && errno == EINVAL);
|
||||
TEST_ASSERT_FAILURE_ERRNO (
|
||||
EINVAL, zmq_ctx_set (get_test_context (), ZMQ_THREAD_SCHED_POLICY,
|
||||
ZMQ_THREAD_SCHED_POLICY_DFLT));
|
||||
TEST_ASSERT_FAILURE_ERRNO (EINVAL, zmq_ctx_set (get_test_context (),
|
||||
ZMQ_THREAD_PRIORITY,
|
||||
ZMQ_THREAD_PRIORITY_DFLT));
|
||||
|
||||
|
||||
// test scheduling policy:
|
||||
|
||||
// set context options that alter the background thread CPU scheduling/affinity settings;
|
||||
// as of ZMQ 4.2.3 this has an effect only on POSIX systems (nothing happens on Windows, but still it should return success):
|
||||
rc = zmq_ctx_set (ctx_, ZMQ_THREAD_SCHED_POLICY, TEST_POLICY);
|
||||
assert (rc == 0);
|
||||
rc = zmq_ctx_get (ctx_, ZMQ_THREAD_SCHED_POLICY);
|
||||
assert (rc == TEST_POLICY);
|
||||
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_ctx_set (get_test_context (), ZMQ_THREAD_SCHED_POLICY, TEST_POLICY));
|
||||
TEST_ASSERT_EQUAL_INT (
|
||||
TEST_POLICY, zmq_ctx_get (get_test_context (), ZMQ_THREAD_SCHED_POLICY));
|
||||
|
||||
// test priority:
|
||||
|
||||
@ -108,10 +118,9 @@ void test_ctx_thread_opts (void *ctx_)
|
||||
// However changing the nice value of a process requires appropriate permissions...
|
||||
// check that the current effective user is able to do that:
|
||||
if (is_allowed_to_raise_priority ()) {
|
||||
rc = zmq_ctx_set (
|
||||
ctx_, ZMQ_THREAD_PRIORITY,
|
||||
1 /* any positive value different than the default will be ok */);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_ctx_set (
|
||||
get_test_context (), ZMQ_THREAD_PRIORITY,
|
||||
1 /* any positive value different than the default will be ok */));
|
||||
}
|
||||
|
||||
|
||||
@ -125,17 +134,17 @@ void test_ctx_thread_opts (void *ctx_)
|
||||
int cpus_add[] = {0, 1};
|
||||
for (unsigned int idx = 0; idx < sizeof (cpus_add) / sizeof (cpus_add[0]);
|
||||
idx++) {
|
||||
rc = zmq_ctx_set (ctx_, ZMQ_THREAD_AFFINITY_CPU_ADD, cpus_add[idx]);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_ctx_set (
|
||||
get_test_context (), ZMQ_THREAD_AFFINITY_CPU_ADD, cpus_add[idx]));
|
||||
}
|
||||
|
||||
// you can also remove CPUs from list of affinities:
|
||||
int cpus_remove[] = {1};
|
||||
for (unsigned int idx = 0;
|
||||
idx < sizeof (cpus_remove) / sizeof (cpus_remove[0]); idx++) {
|
||||
rc =
|
||||
zmq_ctx_set (ctx_, ZMQ_THREAD_AFFINITY_CPU_REMOVE, cpus_remove[idx]);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_ctx_set (get_test_context (),
|
||||
ZMQ_THREAD_AFFINITY_CPU_REMOVE,
|
||||
cpus_remove[idx]));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -143,103 +152,116 @@ void test_ctx_thread_opts (void *ctx_)
|
||||
#ifdef ZMQ_THREAD_NAME_PREFIX
|
||||
// test thread name prefix:
|
||||
|
||||
rc = zmq_ctx_set (ctx_, ZMQ_THREAD_NAME_PREFIX, 1234);
|
||||
assert (rc == 0);
|
||||
rc = zmq_ctx_get (ctx_, ZMQ_THREAD_NAME_PREFIX);
|
||||
assert (rc == 1234);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_ctx_set (get_test_context (), ZMQ_THREAD_NAME_PREFIX, 1234));
|
||||
TEST_ASSERT_EQUAL_INT (
|
||||
1234, zmq_ctx_get (get_test_context (), ZMQ_THREAD_NAME_PREFIX));
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_ctx_zero_copy (void *ctx_)
|
||||
void test_ctx_zero_copy ()
|
||||
{
|
||||
#ifdef ZMQ_ZERO_COPY_RECV
|
||||
int zero_copy;
|
||||
// Default value is 1.
|
||||
zero_copy = zmq_ctx_get (ctx_, ZMQ_ZERO_COPY_RECV);
|
||||
assert (zero_copy == 1);
|
||||
zero_copy = zmq_ctx_get (get_test_context (), ZMQ_ZERO_COPY_RECV);
|
||||
TEST_ASSERT_EQUAL_INT (1, zero_copy);
|
||||
|
||||
// Test we can set it to 0.
|
||||
assert (0 == zmq_ctx_set (ctx_, ZMQ_ZERO_COPY_RECV, 0));
|
||||
zero_copy = zmq_ctx_get (ctx_, ZMQ_ZERO_COPY_RECV);
|
||||
assert (zero_copy == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_ctx_set (get_test_context (), ZMQ_ZERO_COPY_RECV, 0));
|
||||
zero_copy = zmq_ctx_get (get_test_context (), ZMQ_ZERO_COPY_RECV);
|
||||
TEST_ASSERT_EQUAL_INT (0, zero_copy);
|
||||
|
||||
// Create a TCP socket pair using the context and test that messages can be
|
||||
// received. Note that inproc sockets cannot be used for this test.
|
||||
void *pull = zmq_socket (ctx_, ZMQ_PULL);
|
||||
assert (0 == zmq_bind (pull, "tcp://127.0.0.1:*"));
|
||||
void *pull = zmq_socket (get_test_context (), ZMQ_PULL);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (pull, "tcp://127.0.0.1:*"));
|
||||
|
||||
void *push = zmq_socket (ctx_, ZMQ_PUSH);
|
||||
void *push = zmq_socket (get_test_context (), ZMQ_PUSH);
|
||||
size_t endpoint_len = MAX_SOCKET_STRING;
|
||||
char endpoint[MAX_SOCKET_STRING];
|
||||
assert (
|
||||
0 == zmq_getsockopt (pull, ZMQ_LAST_ENDPOINT, endpoint, &endpoint_len));
|
||||
assert (0 == zmq_connect (push, endpoint));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_getsockopt (pull, ZMQ_LAST_ENDPOINT, endpoint, &endpoint_len));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (push, endpoint));
|
||||
|
||||
const char *small_str = "abcd";
|
||||
const char *large_str =
|
||||
"01234567890123456789012345678901234567890123456789";
|
||||
|
||||
assert (4 == zmq_send (push, (void *) small_str, 4, 0));
|
||||
assert (40 == zmq_send (push, (void *) large_str, 40, 0));
|
||||
send_string_expect_success (push, small_str, 0);
|
||||
send_string_expect_success (push, large_str, 0);
|
||||
|
||||
zmq_msg_t small_msg, large_msg;
|
||||
zmq_msg_init (&small_msg);
|
||||
zmq_msg_init (&large_msg);
|
||||
assert (4 == zmq_msg_recv (&small_msg, pull, 0));
|
||||
assert (40 == zmq_msg_recv (&large_msg, pull, 0));
|
||||
assert (!strncmp (small_str, (const char *) zmq_msg_data (&small_msg), 4));
|
||||
assert (!strncmp (large_str, (const char *) zmq_msg_data (&large_msg), 40));
|
||||
recv_string_expect_success (pull, small_str, 0);
|
||||
recv_string_expect_success (pull, large_str, 0);
|
||||
|
||||
// Clean up.
|
||||
assert (0 == zmq_close (push));
|
||||
assert (0 == zmq_close (pull));
|
||||
assert (0 == zmq_msg_close (&small_msg));
|
||||
assert (0 == zmq_msg_close (&large_msg));
|
||||
assert (0 == zmq_ctx_set (ctx_, ZMQ_ZERO_COPY_RECV, 1));
|
||||
zero_copy = zmq_ctx_get (ctx_, ZMQ_ZERO_COPY_RECV);
|
||||
assert (zero_copy == 1);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_close (push));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_close (pull));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_ctx_set (get_test_context (), ZMQ_ZERO_COPY_RECV, 1));
|
||||
TEST_ASSERT_EQUAL_INT (
|
||||
1, zmq_ctx_get (get_test_context (), ZMQ_ZERO_COPY_RECV));
|
||||
#endif
|
||||
}
|
||||
|
||||
int main (void)
|
||||
void test_ctx_option_max_sockets ()
|
||||
{
|
||||
setup_test_environment ();
|
||||
int rc;
|
||||
TEST_ASSERT_EQUAL_INT (ZMQ_MAX_SOCKETS_DFLT,
|
||||
zmq_ctx_get (get_test_context (), ZMQ_MAX_SOCKETS));
|
||||
}
|
||||
|
||||
// Set up our context and sockets
|
||||
void *ctx = zmq_ctx_new ();
|
||||
assert (ctx);
|
||||
|
||||
assert (zmq_ctx_get (ctx, ZMQ_MAX_SOCKETS) == ZMQ_MAX_SOCKETS_DFLT);
|
||||
void test_ctx_option_socket_limit ()
|
||||
{
|
||||
#if defined(ZMQ_USE_SELECT)
|
||||
assert (zmq_ctx_get (ctx, ZMQ_SOCKET_LIMIT) == FD_SETSIZE - 1);
|
||||
TEST_ASSERT_EQUAL_INT (FD_SETSIZE - 1, zmq_ctx_get (ctx, ZMQ_SOCKET_LIMIT));
|
||||
#elif defined(ZMQ_USE_POLL) || defined(ZMQ_USE_EPOLL) \
|
||||
|| defined(ZMQ_USE_DEVPOLL) || defined(ZMQ_USE_KQUEUE)
|
||||
assert (zmq_ctx_get (ctx, ZMQ_SOCKET_LIMIT) == 65535);
|
||||
TEST_ASSERT_EQUAL_INT (65535, zmq_ctx_get (ctx, ZMQ_SOCKET_LIMIT));
|
||||
#endif
|
||||
assert (zmq_ctx_get (ctx, ZMQ_IO_THREADS) == ZMQ_IO_THREADS_DFLT);
|
||||
assert (zmq_ctx_get (ctx, ZMQ_IPV6) == 0);
|
||||
}
|
||||
|
||||
void test_ctx_option_io_threads ()
|
||||
{
|
||||
TEST_ASSERT_EQUAL_INT (ZMQ_IO_THREADS_DFLT,
|
||||
zmq_ctx_get (get_test_context (), ZMQ_IO_THREADS));
|
||||
}
|
||||
|
||||
void test_ctx_option_ipv6 ()
|
||||
{
|
||||
TEST_ASSERT_EQUAL_INT (0, zmq_ctx_get (get_test_context (), ZMQ_IPV6));
|
||||
}
|
||||
|
||||
void test_ctx_option_msg_t_size ()
|
||||
{
|
||||
#if defined(ZMQ_MSG_T_SIZE)
|
||||
assert (zmq_ctx_get (ctx, ZMQ_MSG_T_SIZE) == sizeof (zmq_msg_t));
|
||||
TEST_ASSERT_EQUAL_INT (sizeof (zmq_msg_t),
|
||||
zmq_ctx_get (get_test_context (), ZMQ_MSG_T_SIZE));
|
||||
#endif
|
||||
}
|
||||
|
||||
rc = zmq_ctx_set (ctx, ZMQ_IPV6, true);
|
||||
assert (zmq_ctx_get (ctx, ZMQ_IPV6) == 1);
|
||||
void test_ctx_option_ipv6_set ()
|
||||
{
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_ctx_set (get_test_context (), ZMQ_IPV6, true));
|
||||
TEST_ASSERT_EQUAL_INT (1, zmq_ctx_get (get_test_context (), ZMQ_IPV6));
|
||||
}
|
||||
|
||||
test_ctx_thread_opts (ctx);
|
||||
test_ctx_zero_copy (ctx);
|
||||
void test_ctx_option_blocky ()
|
||||
{
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_ctx_set (get_test_context (), ZMQ_IPV6, true));
|
||||
|
||||
void *router = zmq_socket (ctx, ZMQ_ROUTER);
|
||||
void *router = test_context_socket (ZMQ_ROUTER);
|
||||
int value;
|
||||
size_t optsize = sizeof (int);
|
||||
rc = zmq_getsockopt (router, ZMQ_IPV6, &value, &optsize);
|
||||
assert (rc == 0);
|
||||
assert (value == 1);
|
||||
rc = zmq_getsockopt (router, ZMQ_LINGER, &value, &optsize);
|
||||
assert (rc == 0);
|
||||
assert (value == -1);
|
||||
rc = zmq_close (router);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_getsockopt (router, ZMQ_IPV6, &value, &optsize));
|
||||
TEST_ASSERT_EQUAL_INT (1, value);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_getsockopt (router, ZMQ_LINGER, &value, &optsize));
|
||||
TEST_ASSERT_EQUAL_INT (-1, value);
|
||||
test_context_socket_close (router);
|
||||
|
||||
#if WAIT_FOR_BACKGROUND_THREAD_INSPECTION
|
||||
// this is useful when you want to use an external tool (like top or taskset) to view
|
||||
@ -250,17 +272,30 @@ int main (void)
|
||||
sleep (100);
|
||||
#endif
|
||||
|
||||
rc = zmq_ctx_set (ctx, ZMQ_BLOCKY, false);
|
||||
assert (zmq_ctx_get (ctx, ZMQ_BLOCKY) == 0);
|
||||
router = zmq_socket (ctx, ZMQ_ROUTER);
|
||||
rc = zmq_getsockopt (router, ZMQ_LINGER, &value, &optsize);
|
||||
assert (rc == 0);
|
||||
assert (value == 0);
|
||||
rc = zmq_close (router);
|
||||
assert (rc == 0);
|
||||
|
||||
rc = zmq_ctx_term (ctx);
|
||||
assert (rc == 0);
|
||||
|
||||
return 0;
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_ctx_set (get_test_context (), ZMQ_BLOCKY, false));
|
||||
TEST_ASSERT_EQUAL_INT (0, TEST_ASSERT_SUCCESS_ERRNO ((zmq_ctx_get (
|
||||
get_test_context (), ZMQ_BLOCKY))));
|
||||
router = test_context_socket (ZMQ_ROUTER);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_getsockopt (router, ZMQ_LINGER, &value, &optsize));
|
||||
TEST_ASSERT_EQUAL_INT (0, value);
|
||||
test_context_socket_close (router);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
setup_test_environment ();
|
||||
|
||||
UNITY_BEGIN ();
|
||||
RUN_TEST (test_ctx_option_max_sockets);
|
||||
RUN_TEST (test_ctx_option_socket_limit);
|
||||
RUN_TEST (test_ctx_option_io_threads);
|
||||
RUN_TEST (test_ctx_option_ipv6);
|
||||
RUN_TEST (test_ctx_option_msg_t_size);
|
||||
RUN_TEST (test_ctx_option_ipv6_set);
|
||||
RUN_TEST (test_ctx_thread_opts);
|
||||
RUN_TEST (test_ctx_zero_copy);
|
||||
RUN_TEST (test_ctx_option_blocky);
|
||||
return UNITY_END ();
|
||||
}
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unity.h>
|
||||
|
||||
void setUp ()
|
||||
|
@ -28,46 +28,43 @@
|
||||
*/
|
||||
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
}
|
||||
|
||||
void tearDown ()
|
||||
{
|
||||
teardown_test_context ();
|
||||
}
|
||||
|
||||
/// Initialize a zeromq message with a given null-terminated string
|
||||
#define ZMQ_PREPARE_STRING(msg, data, size) \
|
||||
\
|
||||
zmq_msg_init (&msg) \
|
||||
&& printf ("zmq_msg_init: %s\n", zmq_strerror (errno)); \
|
||||
\
|
||||
zmq_msg_init_size (&msg, size + 1) \
|
||||
&& printf ("zmq_msg_init_size: %s\n", zmq_strerror (errno)); \
|
||||
\
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_init (&msg)); \
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_init_size (&msg, size + 1)); \
|
||||
memcpy (zmq_msg_data (&msg), data, size + 1);
|
||||
|
||||
// TODO: this code fails to meet our style guidelines, and needs rewriting
|
||||
|
||||
static int publicationsReceived = 0;
|
||||
static bool isSubscribed = false;
|
||||
|
||||
int main (int, char **)
|
||||
void test_disconnect_inproc ()
|
||||
{
|
||||
setup_test_environment ();
|
||||
void *context = zmq_ctx_new ();
|
||||
void *pub_socket;
|
||||
void *sub_socket;
|
||||
void *pub_socket = test_context_socket (ZMQ_XPUB);
|
||||
void *sub_socket = test_context_socket (ZMQ_SUB);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (sub_socket, ZMQ_SUBSCRIBE, "foo", 3));
|
||||
|
||||
(pub_socket = zmq_socket (context, ZMQ_XPUB))
|
||||
|| printf ("zmq_socket: %s\n", zmq_strerror (errno));
|
||||
(sub_socket = zmq_socket (context, ZMQ_SUB))
|
||||
|| printf ("zmq_socket: %s\n", zmq_strerror (errno));
|
||||
zmq_setsockopt (sub_socket, ZMQ_SUBSCRIBE, "foo", 3)
|
||||
&& printf ("zmq_setsockopt: %s\n", zmq_strerror (errno));
|
||||
|
||||
zmq_bind (pub_socket, "inproc://someInProcDescriptor")
|
||||
&& printf ("zmq_bind: %s\n", zmq_strerror (errno));
|
||||
//zmq_bind(pubSocket, "tcp://127.0.0.1:30010") && printf("zmq_bind: %s\n", zmq_strerror(errno));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_bind (pub_socket, "inproc://someInProcDescriptor"));
|
||||
|
||||
int more;
|
||||
size_t more_size = sizeof (more);
|
||||
int iteration = 0;
|
||||
|
||||
while (1) {
|
||||
for (int iteration = 0;; ++iteration) {
|
||||
zmq_pollitem_t items[] = {
|
||||
{sub_socket, 0, ZMQ_POLLIN, 0}, // read publications
|
||||
{pub_socket, 0, ZMQ_POLLIN, 0}, // read subscriptions
|
||||
@ -75,77 +72,73 @@ int main (int, char **)
|
||||
int rc = zmq_poll (items, 2, 100);
|
||||
|
||||
if (items[1].revents & ZMQ_POLLIN) {
|
||||
while (1) {
|
||||
for (more = 1; more;) {
|
||||
zmq_msg_t msg;
|
||||
zmq_msg_init (&msg);
|
||||
zmq_msg_recv (&msg, pub_socket, 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_recv (&msg, pub_socket, 0));
|
||||
char *buffer = (char *) zmq_msg_data (&msg);
|
||||
|
||||
if (buffer[0] == 0) {
|
||||
assert (isSubscribed);
|
||||
TEST_ASSERT_TRUE (isSubscribed);
|
||||
isSubscribed = false;
|
||||
} else {
|
||||
assert (!isSubscribed);
|
||||
TEST_ASSERT_FALSE (isSubscribed);
|
||||
isSubscribed = true;
|
||||
}
|
||||
|
||||
zmq_getsockopt (pub_socket, ZMQ_RCVMORE, &more, &more_size);
|
||||
zmq_msg_close (&msg);
|
||||
|
||||
if (!more)
|
||||
break; // Last message part
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_getsockopt (pub_socket, ZMQ_RCVMORE, &more, &more_size));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&msg));
|
||||
}
|
||||
}
|
||||
|
||||
if (items[0].revents & ZMQ_POLLIN) {
|
||||
while (1) {
|
||||
more = 1;
|
||||
for (more = 1; more;) {
|
||||
zmq_msg_t msg;
|
||||
zmq_msg_init (&msg);
|
||||
zmq_msg_recv (&msg, sub_socket, 0);
|
||||
zmq_getsockopt (sub_socket, ZMQ_RCVMORE, &more, &more_size);
|
||||
zmq_msg_close (&msg);
|
||||
|
||||
if (!more) {
|
||||
publicationsReceived++;
|
||||
break; // Last message part
|
||||
}
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_init (&msg));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_recv (&msg, sub_socket, 0));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_getsockopt (sub_socket, ZMQ_RCVMORE, &more, &more_size));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&msg));
|
||||
}
|
||||
publicationsReceived++;
|
||||
}
|
||||
if (iteration == 1) {
|
||||
zmq_connect (sub_socket, "inproc://someInProcDescriptor")
|
||||
&& printf ("zmq_connect: %s\n", zmq_strerror (errno));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_connect (sub_socket, "inproc://someInProcDescriptor"));
|
||||
msleep (SETTLE_TIME);
|
||||
}
|
||||
if (iteration == 4) {
|
||||
zmq_disconnect (sub_socket, "inproc://someInProcDescriptor")
|
||||
&& printf ("zmq_disconnect(%d): %s\n", errno,
|
||||
zmq_strerror (errno));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_disconnect (sub_socket, "inproc://someInProcDescriptor"));
|
||||
}
|
||||
if (iteration > 4 && rc == 0)
|
||||
break;
|
||||
|
||||
zmq_msg_t channel_envlp;
|
||||
ZMQ_PREPARE_STRING (channel_envlp, "foo", 3);
|
||||
zmq_msg_send (&channel_envlp, pub_socket, ZMQ_SNDMORE) >= 0
|
||||
|| printf ("zmq_msg_send: %s\n", zmq_strerror (errno));
|
||||
zmq_msg_close (&channel_envlp)
|
||||
&& printf ("zmq_msg_close: %s\n", zmq_strerror (errno));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_msg_send (&channel_envlp, pub_socket, ZMQ_SNDMORE));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&channel_envlp));
|
||||
|
||||
zmq_msg_t message;
|
||||
ZMQ_PREPARE_STRING (message, "this is foo!", 12);
|
||||
zmq_msg_send (&message, pub_socket, 0) >= 0
|
||||
|| printf ("zmq_msg_send: %s\n", zmq_strerror (errno));
|
||||
zmq_msg_close (&message)
|
||||
&& printf ("zmq_msg_close: %s\n", zmq_strerror (errno));
|
||||
|
||||
iteration++;
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_send (&message, pub_socket, 0));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&message));
|
||||
}
|
||||
assert (publicationsReceived == 3);
|
||||
assert (!isSubscribed);
|
||||
TEST_ASSERT_EQUAL_INT (3, publicationsReceived);
|
||||
TEST_ASSERT_FALSE (isSubscribed);
|
||||
|
||||
zmq_close (pub_socket) && printf ("zmq_close: %s", zmq_strerror (errno));
|
||||
zmq_close (sub_socket) && printf ("zmq_close: %s", zmq_strerror (errno));
|
||||
|
||||
zmq_ctx_term (context);
|
||||
return 0;
|
||||
test_context_socket_close (pub_socket);
|
||||
test_context_socket_close (sub_socket);
|
||||
}
|
||||
|
||||
int main (int, char **)
|
||||
{
|
||||
setup_test_environment ();
|
||||
|
||||
UNITY_BEGIN ();
|
||||
RUN_TEST (test_disconnect_inproc);
|
||||
return UNITY_END ();
|
||||
}
|
||||
|
@ -30,6 +30,9 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <grp.h>
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
@ -117,7 +120,7 @@ void init_groups ()
|
||||
// Get the group and supplemental groups of the process owner
|
||||
gid_t groups[100];
|
||||
int ngroups = getgroups (100, groups);
|
||||
assert (ngroups != -1);
|
||||
TEST_ASSERT_NOT_EQUAL (-1, ngroups);
|
||||
group = getgid ();
|
||||
supgroup = group;
|
||||
notgroup = group + 1;
|
||||
|
@ -28,41 +28,50 @@
|
||||
*/
|
||||
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
}
|
||||
|
||||
void tearDown ()
|
||||
{
|
||||
teardown_test_context ();
|
||||
}
|
||||
|
||||
const char *address = "tcp://127.0.0.1:*";
|
||||
char connect_address[MAX_SOCKET_STRING];
|
||||
|
||||
#define NUM_MESSAGES 5
|
||||
|
||||
int main (void)
|
||||
void test_fork ()
|
||||
{
|
||||
#if !defined(ZMQ_HAVE_WINDOWS)
|
||||
setup_test_environment ();
|
||||
void *ctx = zmq_ctx_new ();
|
||||
assert (ctx);
|
||||
|
||||
// Create and bind pull socket to receive messages
|
||||
void *pull = zmq_socket (ctx, ZMQ_PULL);
|
||||
assert (pull);
|
||||
int rc = zmq_bind (pull, address);
|
||||
assert (rc == 0);
|
||||
size_t len = MAX_SOCKET_STRING;
|
||||
rc = zmq_getsockopt (pull, ZMQ_LAST_ENDPOINT, connect_address, &len);
|
||||
assert (rc == 0);
|
||||
void *pull = test_context_socket (ZMQ_PULL);
|
||||
bind_loopback_ipv4 (pull, connect_address, sizeof connect_address);
|
||||
|
||||
int pid = fork ();
|
||||
if (pid == 0) {
|
||||
// use regular assertions in the child process
|
||||
|
||||
// Child process
|
||||
// Immediately close parent sockets and context
|
||||
zmq_close (pull);
|
||||
zmq_ctx_term (ctx);
|
||||
zmq_ctx_term (get_test_context ());
|
||||
|
||||
// Create new context, socket, connect and send some messages
|
||||
void *child_ctx = zmq_ctx_new ();
|
||||
assert (child_ctx);
|
||||
void *push = zmq_socket (child_ctx, ZMQ_PUSH);
|
||||
assert (push);
|
||||
rc = zmq_connect (push, connect_address);
|
||||
int rc = zmq_connect (push, connect_address);
|
||||
assert (rc == 0);
|
||||
int count;
|
||||
for (count = 0; count < NUM_MESSAGES; count++)
|
||||
@ -75,24 +84,28 @@ int main (void)
|
||||
// Parent process
|
||||
int count;
|
||||
for (count = 0; count < NUM_MESSAGES; count++) {
|
||||
char buffer[5];
|
||||
int num_bytes = zmq_recv (pull, buffer, 5, 0);
|
||||
assert (num_bytes == 5);
|
||||
recv_string_expect_success (pull, "Hello", 0);
|
||||
}
|
||||
int child_status;
|
||||
while (true) {
|
||||
rc = waitpid (pid, &child_status, 0);
|
||||
int rc = waitpid (pid, &child_status, 0);
|
||||
if (rc == -1 && errno == EINTR)
|
||||
continue;
|
||||
assert (rc > 0);
|
||||
TEST_ASSERT_GREATER_THAN (0, rc);
|
||||
// Verify the status code of the child was zero
|
||||
assert (WEXITSTATUS (child_status) == 0);
|
||||
TEST_ASSERT_EQUAL (0, WEXITSTATUS (child_status));
|
||||
break;
|
||||
}
|
||||
zmq_close (pull);
|
||||
zmq_ctx_term (ctx);
|
||||
exit (0);
|
||||
test_context_socket_close (pull);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
setup_test_environment ();
|
||||
|
||||
UNITY_BEGIN ();
|
||||
RUN_TEST (test_fork);
|
||||
return UNITY_END ();
|
||||
}
|
||||
|
@ -23,42 +23,46 @@
|
||||
*/
|
||||
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
int main (void)
|
||||
#include <string.h>
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
}
|
||||
|
||||
void tearDown ()
|
||||
{
|
||||
teardown_test_context ();
|
||||
}
|
||||
|
||||
void test_getsockopt_memset ()
|
||||
{
|
||||
int64_t more;
|
||||
size_t more_size = sizeof (more);
|
||||
|
||||
setup_test_environment ();
|
||||
void *ctx = zmq_ctx_new ();
|
||||
assert (ctx);
|
||||
void *sb = test_context_socket (ZMQ_PUB);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (sb, "inproc://a"));
|
||||
|
||||
void *sb = zmq_socket (ctx, ZMQ_PUB);
|
||||
assert (sb);
|
||||
int rc = zmq_bind (sb, "inproc://a");
|
||||
assert (rc == 0);
|
||||
|
||||
void *sc = zmq_socket (ctx, ZMQ_SUB);
|
||||
assert (sc);
|
||||
rc = zmq_connect (sc, "inproc://a");
|
||||
assert (rc == 0);
|
||||
void *sc = test_context_socket (ZMQ_SUB);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sc, "inproc://a"));
|
||||
|
||||
memset (&more, 0xFF, sizeof (int64_t));
|
||||
zmq_getsockopt (sc, ZMQ_RCVMORE, &more, &more_size);
|
||||
assert (more_size == sizeof (int));
|
||||
assert (more == 0);
|
||||
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_getsockopt (sc, ZMQ_RCVMORE, &more, &more_size));
|
||||
TEST_ASSERT_EQUAL_INT (sizeof (int), more_size);
|
||||
TEST_ASSERT_EQUAL_INT (0, more);
|
||||
|
||||
// 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;
|
||||
test_context_socket_close (sc);
|
||||
test_context_socket_close (sb);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
setup_test_environment ();
|
||||
|
||||
UNITY_BEGIN ();
|
||||
RUN_TEST (test_getsockopt_memset);
|
||||
return UNITY_END ();
|
||||
}
|
||||
|
@ -26,10 +26,13 @@
|
||||
typedef SOCKET raw_socket;
|
||||
#else
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
typedef int raw_socket;
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// TODO remove this here, either ensure that UINT16_MAX is always properly
|
||||
// defined or handle this at a more central location
|
||||
|
@ -191,12 +191,8 @@ int test_inproc_connect_and_close_first (int send_hwm_, int recv_hwm_)
|
||||
|
||||
int test_inproc_bind_and_close_first (int send_hwm_, int /* recv_hwm */)
|
||||
{
|
||||
void *ctx = zmq_ctx_new ();
|
||||
TEST_ASSERT_NOT_NULL (ctx);
|
||||
|
||||
// Set up bind socket
|
||||
void *bind_socket = zmq_socket (ctx, ZMQ_PUSH);
|
||||
TEST_ASSERT_NOT_NULL (bind_socket);
|
||||
void *bind_socket = test_context_socket (ZMQ_PUSH);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (bind_socket, ZMQ_SNDHWM, &send_hwm_, sizeof (send_hwm_)));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (bind_socket, "inproc://a"));
|
||||
@ -208,12 +204,11 @@ int test_inproc_bind_and_close_first (int send_hwm_, int /* recv_hwm */)
|
||||
++send_count;
|
||||
|
||||
// Close bind
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_close (bind_socket));
|
||||
test_context_socket_close (bind_socket);
|
||||
|
||||
/* TODO Can't currently do connect without then wiring up a bind as things hang, this needs top be fixed.
|
||||
// Set up connect socket
|
||||
void *connect_socket = zmq_socket (ctx, ZMQ_PULL);
|
||||
TEST_ASSERT_NOT_NULL(connect_socket);
|
||||
void *connect_socket = test_context_socket (ZMQ_PULL);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (connect_socket, ZMQ_RCVHWM, &recv_hwm, sizeof (recv_hwm)));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (connect_socket, "inproc://a"));
|
||||
|
||||
@ -226,9 +221,7 @@ int test_inproc_bind_and_close_first (int send_hwm_, int /* recv_hwm */)
|
||||
*/
|
||||
|
||||
// Clean up
|
||||
//TEST_ASSERT_SUCCESS_ERRNO (zmq_close (connect_socket));
|
||||
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_ctx_term (ctx));
|
||||
//test_context_socket_close (connect_socket);
|
||||
|
||||
return send_count;
|
||||
}
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
// NOTE: on OSX the endpoint returned by ZMQ_LAST_ENDPOINT may be quite long,
|
||||
// ensure we have extra space for that:
|
||||
#define SOCKET_STRING_LEN (MAX_SOCKET_STRING * 4)
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unity.h>
|
||||
|
||||
void setUp ()
|
||||
@ -55,7 +57,9 @@ struct iovec
|
||||
|
||||
static void do_check (void *sb_, void *sc_, size_t msg_size_)
|
||||
{
|
||||
assert (sb_ && sc_ && msg_size_ > 0);
|
||||
TEST_ASSERT_NOT_NULL (sb_);
|
||||
TEST_ASSERT_NOT_NULL (sc_);
|
||||
TEST_ASSERT_GREATER_THAN (0, msg_size_);
|
||||
|
||||
const char msg_val = '1';
|
||||
const int num_messages = 10;
|
||||
@ -76,8 +80,8 @@ static void do_check (void *sb_, void *sc_, size_t msg_size_)
|
||||
send_iov[i].iov_len = msg_size_;
|
||||
memcpy (send_iov[i].iov_base, ref_msg, msg_size_);
|
||||
|
||||
// TODO: this assertion only checks if memcpy behaves as expected... remove this?
|
||||
assert (memcmp (ref_msg, send_iov[i].iov_base, msg_size_) == 0);
|
||||
// TODO: this assertion only checks if memcpy behaves as expected... remove this or assert something else?
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY (ref_msg, send_iov[i].iov_base, msg_size_);
|
||||
}
|
||||
|
||||
// Test errors - zmq_recviov - null socket
|
||||
|
@ -44,12 +44,12 @@ void tearDown ()
|
||||
|
||||
static void do_bind_and_verify (void *s_, const char *endpoint_)
|
||||
{
|
||||
int rc = zmq_bind (s_, endpoint_);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (s_, endpoint_));
|
||||
char reported[255];
|
||||
size_t size = 255;
|
||||
rc = zmq_getsockopt (s_, ZMQ_LAST_ENDPOINT, reported, &size);
|
||||
assert (rc == 0 && strcmp (reported, endpoint_) == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_getsockopt (s_, ZMQ_LAST_ENDPOINT, reported, &size));
|
||||
TEST_ASSERT_EQUAL_STRING (endpoint_, reported);
|
||||
}
|
||||
|
||||
void test_last_endpoint ()
|
||||
|
@ -28,75 +28,81 @@
|
||||
*/
|
||||
|
||||
#include "testutil.hpp"
|
||||
#include <zmq.h>
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <vector>
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
}
|
||||
|
||||
void tearDown ()
|
||||
{
|
||||
teardown_test_context ();
|
||||
}
|
||||
|
||||
void test_system_max ()
|
||||
{
|
||||
// Keep allocating sockets until we run out of system resources
|
||||
const int no_of_sockets = 2 * 65536;
|
||||
void *ctx = zmq_ctx_new ();
|
||||
zmq_ctx_set (ctx, ZMQ_MAX_SOCKETS, no_of_sockets);
|
||||
zmq_ctx_set (get_test_context (), ZMQ_MAX_SOCKETS, no_of_sockets);
|
||||
std::vector<void *> sockets;
|
||||
|
||||
while (true) {
|
||||
void *socket = zmq_socket (ctx, ZMQ_PAIR);
|
||||
void *socket = zmq_socket (get_test_context (), ZMQ_PAIR);
|
||||
if (!socket)
|
||||
break;
|
||||
sockets.push_back (socket);
|
||||
}
|
||||
assert (static_cast<int> (sockets.size ()) <= no_of_sockets);
|
||||
TEST_ASSERT_LESS_OR_EQUAL (no_of_sockets,
|
||||
static_cast<int> (sockets.size ()));
|
||||
printf ("Socket creation failed after %i sockets\n",
|
||||
static_cast<int> (sockets.size ()));
|
||||
|
||||
// System is out of resources, further calls to zmq_socket should return NULL
|
||||
for (unsigned int i = 0; i < 10; ++i) {
|
||||
void *socket = zmq_socket (ctx, ZMQ_PAIR);
|
||||
assert (socket == NULL);
|
||||
void *socket = zmq_socket (get_test_context (), ZMQ_PAIR);
|
||||
TEST_ASSERT_NULL (socket);
|
||||
}
|
||||
// Clean up.
|
||||
for (unsigned int i = 0; i < sockets.size (); ++i)
|
||||
zmq_close (sockets[i]);
|
||||
|
||||
zmq_ctx_destroy (ctx);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_close (sockets[i]));
|
||||
}
|
||||
|
||||
void test_zmq_default_max ()
|
||||
{
|
||||
// Keep allocating sockets until we hit the default limit
|
||||
void *ctx = zmq_ctx_new ();
|
||||
std::vector<void *> sockets;
|
||||
|
||||
while (true) {
|
||||
void *socket = zmq_socket (ctx, ZMQ_PAIR);
|
||||
void *socket = zmq_socket (get_test_context (), ZMQ_PAIR);
|
||||
if (!socket)
|
||||
break;
|
||||
sockets.push_back (socket);
|
||||
}
|
||||
// We may stop sooner if system has fewer available sockets
|
||||
assert (sockets.size () <= ZMQ_MAX_SOCKETS_DFLT);
|
||||
TEST_ASSERT_LESS_OR_EQUAL (ZMQ_MAX_SOCKETS_DFLT, sockets.size ());
|
||||
|
||||
// Further calls to zmq_socket should return NULL
|
||||
for (unsigned int i = 0; i < 10; ++i) {
|
||||
void *socket = zmq_socket (ctx, ZMQ_PAIR);
|
||||
assert (socket == NULL);
|
||||
void *socket = zmq_socket (get_test_context (), ZMQ_PAIR);
|
||||
TEST_ASSERT_NULL (socket);
|
||||
}
|
||||
|
||||
// Clean up
|
||||
for (unsigned int i = 0; i < sockets.size (); ++i)
|
||||
zmq_close (sockets[i]);
|
||||
|
||||
zmq_ctx_destroy (ctx);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_close (sockets[i]));
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
setup_test_environment ();
|
||||
|
||||
test_system_max ();
|
||||
test_zmq_default_max ();
|
||||
|
||||
return 0;
|
||||
UNITY_BEGIN ();
|
||||
RUN_TEST (test_system_max);
|
||||
RUN_TEST (test_zmq_default_max);
|
||||
return UNITY_END ();
|
||||
}
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unity.h>
|
||||
|
||||
void setUp ()
|
||||
@ -57,8 +58,8 @@ static void zap_handler (void *handler_)
|
||||
char *routing_id = s_recv (handler_);
|
||||
char *mechanism = s_recv (handler_);
|
||||
|
||||
assert (streq (version, "1.0"));
|
||||
assert (streq (mechanism, "NULL"));
|
||||
TEST_ASSERT_EQUAL_STRING ("1.0", version);
|
||||
TEST_ASSERT_EQUAL_STRING ("NULL", mechanism);
|
||||
|
||||
s_sendmore (handler_, version);
|
||||
s_sendmore (handler_, sequence);
|
||||
|
@ -27,9 +27,12 @@
|
||||
typedef SOCKET raw_socket;
|
||||
#else
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
typedef int raw_socket;
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
|
@ -32,6 +32,9 @@
|
||||
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
@ -99,7 +102,7 @@ void test_monitor_basic ()
|
||||
int event = get_monitor_event (client_mon, NULL, NULL);
|
||||
if (event == ZMQ_EVENT_CONNECT_DELAYED)
|
||||
event = get_monitor_event (client_mon, NULL, NULL);
|
||||
assert (event == ZMQ_EVENT_CONNECTED);
|
||||
TEST_ASSERT_EQUAL_INT (ZMQ_EVENT_CONNECTED, event);
|
||||
expect_monitor_event (client_mon, ZMQ_EVENT_HANDSHAKE_SUCCEEDED);
|
||||
event = get_monitor_event (client_mon, NULL, NULL);
|
||||
if (event == ZMQ_EVENT_DISCONNECTED) {
|
||||
|
@ -28,6 +28,19 @@
|
||||
*/
|
||||
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
}
|
||||
|
||||
void tearDown ()
|
||||
{
|
||||
teardown_test_context ();
|
||||
}
|
||||
|
||||
void ffn (void *data_, void *hint_)
|
||||
{
|
||||
@ -36,29 +49,16 @@ void ffn (void *data_, void *hint_)
|
||||
memcpy (hint_, (void *) "freed", 5);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
void test_msg_ffn ()
|
||||
{
|
||||
setup_test_environment ();
|
||||
// Create the infrastructure
|
||||
void *ctx = zmq_ctx_new ();
|
||||
assert (ctx);
|
||||
|
||||
size_t len = MAX_SOCKET_STRING;
|
||||
char my_endpoint[MAX_SOCKET_STRING];
|
||||
|
||||
void *router = zmq_socket (ctx, ZMQ_ROUTER);
|
||||
assert (router);
|
||||
void *router = test_context_socket (ZMQ_ROUTER);
|
||||
bind_loopback_ipv4 (router, my_endpoint, sizeof my_endpoint);
|
||||
|
||||
int rc = zmq_bind (router, "tcp://127.0.0.1:*");
|
||||
assert (rc == 0);
|
||||
rc = zmq_getsockopt (router, ZMQ_LAST_ENDPOINT, my_endpoint, &len);
|
||||
assert (rc == 0);
|
||||
|
||||
void *dealer = zmq_socket (ctx, ZMQ_DEALER);
|
||||
assert (dealer);
|
||||
|
||||
rc = zmq_connect (dealer, my_endpoint);
|
||||
assert (rc == 0);
|
||||
void *dealer = test_context_socket (ZMQ_DEALER);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (dealer, my_endpoint));
|
||||
|
||||
// Test that creating and closing a message triggers ffn
|
||||
zmq_msg_t msg;
|
||||
@ -67,80 +67,68 @@ int main (void)
|
||||
memset (data, 0, 255);
|
||||
memcpy (data, (void *) "data", 4);
|
||||
memcpy (hint, (void *) "hint", 4);
|
||||
rc = zmq_msg_init_data (&msg, (void *) data, 255, ffn, (void *) hint);
|
||||
assert (rc == 0);
|
||||
rc = zmq_msg_close (&msg);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_msg_init_data (&msg, (void *) data, 255, ffn, (void *) hint));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&msg));
|
||||
|
||||
msleep (SETTLE_TIME);
|
||||
assert (memcmp (hint, "freed", 5) == 0);
|
||||
TEST_ASSERT_EQUAL_STRING_LEN ("freed", hint, 5);
|
||||
memcpy (hint, (void *) "hint", 4);
|
||||
|
||||
// Making and closing a copy triggers ffn
|
||||
zmq_msg_t msg2;
|
||||
zmq_msg_init (&msg2);
|
||||
rc = zmq_msg_init_data (&msg, (void *) data, 255, ffn, (void *) hint);
|
||||
assert (rc == 0);
|
||||
rc = zmq_msg_copy (&msg2, &msg);
|
||||
assert (rc == 0);
|
||||
rc = zmq_msg_close (&msg2);
|
||||
assert (rc == 0);
|
||||
rc = zmq_msg_close (&msg);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_msg_init_data (&msg, (void *) data, 255, ffn, (void *) hint));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_copy (&msg2, &msg));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&msg2));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&msg));
|
||||
|
||||
msleep (SETTLE_TIME);
|
||||
assert (memcmp (hint, "freed", 5) == 0);
|
||||
TEST_ASSERT_EQUAL_STRING_LEN ("freed", hint, 5);
|
||||
memcpy (hint, (void *) "hint", 4);
|
||||
|
||||
// Test that sending a message triggers ffn
|
||||
rc = zmq_msg_init_data (&msg, (void *) data, 255, ffn, (void *) hint);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_msg_init_data (&msg, (void *) data, 255, ffn, (void *) hint));
|
||||
|
||||
zmq_msg_send (&msg, dealer, 0);
|
||||
char buf[255];
|
||||
rc = zmq_recv (router, buf, 255, 0);
|
||||
assert (rc > -1);
|
||||
rc = zmq_recv (router, buf, 255, 0);
|
||||
assert (rc == 255);
|
||||
assert (memcmp (data, buf, 4) == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_recv (router, buf, 255, 0));
|
||||
TEST_ASSERT_EQUAL_INT (255, zmq_recv (router, buf, 255, 0));
|
||||
TEST_ASSERT_EQUAL_STRING_LEN (data, buf, 4);
|
||||
|
||||
msleep (SETTLE_TIME);
|
||||
assert (memcmp (hint, "freed", 5) == 0);
|
||||
TEST_ASSERT_EQUAL_STRING_LEN ("freed", hint, 5);
|
||||
memcpy (hint, (void *) "hint", 4);
|
||||
rc = zmq_msg_close (&msg);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&msg));
|
||||
|
||||
// Sending a copy of a message triggers ffn
|
||||
rc = zmq_msg_init (&msg2);
|
||||
assert (rc == 0);
|
||||
rc = zmq_msg_init_data (&msg, (void *) data, 255, ffn, (void *) hint);
|
||||
assert (rc == 0);
|
||||
rc = zmq_msg_copy (&msg2, &msg);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_init (&msg2));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_msg_init_data (&msg, (void *) data, 255, ffn, (void *) hint));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_copy (&msg2, &msg));
|
||||
|
||||
zmq_msg_send (&msg, dealer, 0);
|
||||
rc = zmq_recv (router, buf, 255, 0);
|
||||
assert (rc > -1);
|
||||
rc = zmq_recv (router, buf, 255, 0);
|
||||
assert (rc == 255);
|
||||
assert (memcmp (data, buf, 4) == 0);
|
||||
rc = zmq_msg_close (&msg2);
|
||||
assert (rc == 0);
|
||||
rc = zmq_msg_close (&msg);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_recv (router, buf, 255, 0));
|
||||
TEST_ASSERT_EQUAL_INT (255, zmq_recv (router, buf, 255, 0));
|
||||
TEST_ASSERT_EQUAL_STRING_LEN (data, buf, 4);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&msg2));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&msg));
|
||||
|
||||
msleep (SETTLE_TIME);
|
||||
assert (memcmp (hint, "freed", 5) == 0);
|
||||
memcpy (hint, (void *) "hint", 4);
|
||||
TEST_ASSERT_EQUAL_STRING_LEN ("freed", hint, 5);
|
||||
|
||||
// Deallocate the infrastructure.
|
||||
rc = zmq_close (router);
|
||||
assert (rc == 0);
|
||||
|
||||
rc = zmq_close (dealer);
|
||||
assert (rc == 0);
|
||||
|
||||
rc = zmq_ctx_term (ctx);
|
||||
assert (rc == 0);
|
||||
return 0;
|
||||
test_context_socket_close (router);
|
||||
test_context_socket_close (dealer);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
setup_test_environment ();
|
||||
|
||||
UNITY_BEGIN ();
|
||||
RUN_TEST (test_msg_ffn);
|
||||
return UNITY_END ();
|
||||
}
|
||||
|
@ -28,99 +28,98 @@
|
||||
*/
|
||||
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
int main (void)
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
}
|
||||
|
||||
void tearDown ()
|
||||
{
|
||||
teardown_test_context ();
|
||||
}
|
||||
|
||||
void test_more ()
|
||||
{
|
||||
setup_test_environment ();
|
||||
// Create the infrastructure
|
||||
void *ctx = zmq_ctx_new ();
|
||||
assert (ctx);
|
||||
void *sb = test_context_socket (ZMQ_ROUTER);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (sb, "inproc://a"));
|
||||
|
||||
void *sb = zmq_socket (ctx, ZMQ_ROUTER);
|
||||
assert (sb);
|
||||
|
||||
int rc = zmq_bind (sb, "inproc://a");
|
||||
assert (rc == 0);
|
||||
|
||||
void *sc = zmq_socket (ctx, ZMQ_DEALER);
|
||||
assert (sc);
|
||||
|
||||
rc = zmq_connect (sc, "inproc://a");
|
||||
assert (rc == 0);
|
||||
void *sc = test_context_socket (ZMQ_DEALER);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sc, "inproc://a"));
|
||||
|
||||
// Send 2-part message.
|
||||
rc = zmq_send (sc, "A", 1, ZMQ_SNDMORE);
|
||||
assert (rc == 1);
|
||||
rc = zmq_send (sc, "B", 1, 0);
|
||||
assert (rc == 1);
|
||||
send_string_expect_success (sc, "A", ZMQ_SNDMORE);
|
||||
send_string_expect_success (sc, "B", 0);
|
||||
|
||||
// Routing id comes first.
|
||||
zmq_msg_t msg;
|
||||
rc = zmq_msg_init (&msg);
|
||||
assert (rc == 0);
|
||||
rc = zmq_msg_recv (&msg, sb, 0);
|
||||
assert (rc >= 0);
|
||||
int more = zmq_msg_more (&msg);
|
||||
assert (more == 1);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_init (&msg));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_recv (&msg, sb, 0));
|
||||
TEST_ASSERT_EQUAL_INT (1, TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_more (&msg)));
|
||||
|
||||
// Then the first part of the message body.
|
||||
rc = zmq_msg_recv (&msg, sb, 0);
|
||||
assert (rc == 1);
|
||||
more = zmq_msg_more (&msg);
|
||||
assert (more == 1);
|
||||
TEST_ASSERT_EQUAL_INT (
|
||||
1, TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_recv (&msg, sb, 0)));
|
||||
TEST_ASSERT_EQUAL_INT (1, TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_more (&msg)));
|
||||
|
||||
// And finally, the second part of the message body.
|
||||
rc = zmq_msg_recv (&msg, sb, 0);
|
||||
assert (rc == 1);
|
||||
more = zmq_msg_more (&msg);
|
||||
assert (more == 0);
|
||||
|
||||
// Test ZMQ_SHARED property (case 1, refcounted messages)
|
||||
zmq_msg_t msg_a;
|
||||
rc = zmq_msg_init_size (&msg_a, 1024); // large enough to be a type_lmsg
|
||||
assert (rc == 0);
|
||||
|
||||
// Message is not shared
|
||||
rc = zmq_msg_get (&msg_a, ZMQ_SHARED);
|
||||
assert (rc == 0);
|
||||
|
||||
zmq_msg_t msg_b;
|
||||
rc = zmq_msg_init (&msg_b);
|
||||
assert (rc == 0);
|
||||
|
||||
rc = zmq_msg_copy (&msg_b, &msg_a);
|
||||
assert (rc == 0);
|
||||
|
||||
// Message is now shared
|
||||
rc = zmq_msg_get (&msg_b, ZMQ_SHARED);
|
||||
assert (rc == 1);
|
||||
|
||||
// cleanup
|
||||
rc = zmq_msg_close (&msg_a);
|
||||
assert (rc == 0);
|
||||
rc = zmq_msg_close (&msg_b);
|
||||
assert (rc == 0);
|
||||
|
||||
// Test ZMQ_SHARED property (case 2, constant data messages)
|
||||
rc = zmq_msg_init_data (&msg_a, (void *) "TEST", 5, 0, 0);
|
||||
assert (rc == 0);
|
||||
|
||||
// Message reports as shared
|
||||
rc = zmq_msg_get (&msg_a, ZMQ_SHARED);
|
||||
assert (rc == 1);
|
||||
|
||||
// cleanup
|
||||
rc = zmq_msg_close (&msg_a);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_EQUAL_INT (
|
||||
1, TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_recv (&msg, sb, 0)));
|
||||
TEST_ASSERT_EQUAL_INT (0, TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_more (&msg)));
|
||||
|
||||
// Deallocate the infrastructure.
|
||||
rc = zmq_close (sc);
|
||||
assert (rc == 0);
|
||||
|
||||
rc = zmq_close (sb);
|
||||
assert (rc == 0);
|
||||
|
||||
rc = zmq_ctx_term (ctx);
|
||||
assert (rc == 0);
|
||||
return 0;
|
||||
test_context_socket_close (sc);
|
||||
test_context_socket_close (sb);
|
||||
}
|
||||
|
||||
void test_shared_refcounted ()
|
||||
{
|
||||
// Test ZMQ_SHARED property (case 1, refcounted messages)
|
||||
zmq_msg_t msg_a;
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_msg_init_size (&msg_a, 1024)); // large enough to be a type_lmsg
|
||||
|
||||
// Message is not shared
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_get (&msg_a, ZMQ_SHARED));
|
||||
|
||||
zmq_msg_t msg_b;
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_init (&msg_b));
|
||||
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_copy (&msg_b, &msg_a));
|
||||
|
||||
// Message is now shared
|
||||
TEST_ASSERT_EQUAL_INT (
|
||||
1, TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_get (&msg_b, ZMQ_SHARED)));
|
||||
|
||||
// cleanup
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&msg_a));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&msg_b));
|
||||
}
|
||||
|
||||
void test_shared_const ()
|
||||
{
|
||||
zmq_msg_t msg_a;
|
||||
// Test ZMQ_SHARED property (case 2, constant data messages)
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_msg_init_data (&msg_a, (void *) "TEST", 5, 0, 0));
|
||||
|
||||
// Message reports as shared
|
||||
TEST_ASSERT_EQUAL_INT (
|
||||
1, TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_get (&msg_a, ZMQ_SHARED)));
|
||||
|
||||
// cleanup
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&msg_a));
|
||||
}
|
||||
|
||||
int main ()
|
||||
{
|
||||
setup_test_environment ();
|
||||
|
||||
UNITY_BEGIN ();
|
||||
RUN_TEST (test_more);
|
||||
RUN_TEST (test_shared_refcounted);
|
||||
RUN_TEST (test_shared_const);
|
||||
return UNITY_END ();
|
||||
}
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
|
@ -45,9 +45,8 @@ typedef void (*extra_func_t) (void *socket_);
|
||||
void set_sockopt_bind_to_device (void *socket)
|
||||
{
|
||||
const char device[] = "lo";
|
||||
int rc =
|
||||
zmq_setsockopt (socket, ZMQ_BINDTODEVICE, &device, sizeof (device) - 1);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (socket, ZMQ_BINDTODEVICE, &device, sizeof (device) - 1));
|
||||
}
|
||||
|
||||
// TODO this is duplicated from test_pair_tcp
|
||||
|
@ -32,37 +32,41 @@
|
||||
#include <vmci_sockets.h>
|
||||
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
int main (void)
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_environment ();
|
||||
void *ctx = zmq_ctx_new ();
|
||||
assert (ctx);
|
||||
setup_test_context ();
|
||||
}
|
||||
|
||||
void tearDown ()
|
||||
{
|
||||
teardown_test_context ();
|
||||
}
|
||||
|
||||
void test_pair_vmci ()
|
||||
{
|
||||
std::stringstream s;
|
||||
s << "vmci://" << VMCISock_GetLocalCID () << ":" << 5560;
|
||||
std::string endpoint = s.str ();
|
||||
|
||||
void *sb = zmq_socket (ctx, ZMQ_PAIR);
|
||||
assert (sb);
|
||||
int rc = zmq_bind (sb, endpoint.c_str ());
|
||||
assert (rc == 0);
|
||||
void *sb = test_context_socket (ZMQ_PAIR);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (sb, endpoint.c_str ()));
|
||||
|
||||
void *sc = zmq_socket (ctx, ZMQ_PAIR);
|
||||
assert (sc);
|
||||
rc = zmq_connect (sc, endpoint.c_str ());
|
||||
assert (rc == 0);
|
||||
void *sc = test_context_socket (ZMQ_PAIR);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sc, endpoint.c_str ()));
|
||||
|
||||
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;
|
||||
test_context_socket_close (sc);
|
||||
test_context_socket_close (sb);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
setup_test_environment ();
|
||||
|
||||
UNITY_BEGIN ();
|
||||
RUN_TEST (test_pair_vmci);
|
||||
return UNITY_END ();
|
||||
}
|
||||
|
@ -33,6 +33,13 @@
|
||||
#include <unity.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
|
@ -28,19 +28,20 @@
|
||||
*/
|
||||
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
// Asynchronous client-to-server (DEALER to ROUTER) - pure libzmq
|
||||
//
|
||||
// While this example runs in a single process, that is to make
|
||||
// it easier to start and stop the example. Each task may have its own
|
||||
// context and conceptually acts as a separate process. To have this
|
||||
// behaviour, it is necessary to replace the inproc transport of the
|
||||
// control socket by a tcp transport.
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// This is our client task
|
||||
// It connects to the server, and then sends a request once per second
|
||||
// It collects responses as they arrive, and it prints them out. We will
|
||||
// run several client tasks in parallel, each with a different random ID.
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
}
|
||||
|
||||
void tearDown ()
|
||||
{
|
||||
teardown_test_context ();
|
||||
}
|
||||
|
||||
#define CONTENT_SIZE 13
|
||||
#define CONTENT_SIZE_MAX 32
|
||||
@ -52,7 +53,6 @@
|
||||
|
||||
struct thread_data
|
||||
{
|
||||
void *ctx;
|
||||
int id;
|
||||
};
|
||||
|
||||
@ -73,49 +73,56 @@ typedef struct
|
||||
void *g_clients_pkts_out = NULL;
|
||||
void *g_workers_pkts_out = NULL;
|
||||
|
||||
// Asynchronous client-to-server (DEALER to ROUTER) - pure libzmq
|
||||
//
|
||||
// While this example runs in a single process, that is to make
|
||||
// it easier to start and stop the example. Each task may have its own
|
||||
// context and conceptually acts as a separate process. To have this
|
||||
// behaviour, it is necessary to replace the inproc transport of the
|
||||
// control socket by a tcp transport.
|
||||
|
||||
// This is our client task
|
||||
// It connects to the server, and then sends a request once per second
|
||||
// It collects responses as they arrive, and it prints them out. We will
|
||||
// run several client tasks in parallel, each with a different random ID.
|
||||
|
||||
static void client_task (void *db_)
|
||||
{
|
||||
struct thread_data *databag = (struct thread_data *) db_;
|
||||
// Endpoint socket gets random port to avoid test failing when port in use
|
||||
void *endpoint = zmq_socket (databag->ctx, ZMQ_PAIR);
|
||||
assert (endpoint);
|
||||
void *endpoint = zmq_socket (get_test_context (), ZMQ_PAIR);
|
||||
TEST_ASSERT_NOT_NULL (endpoint);
|
||||
int linger = 0;
|
||||
int rc = zmq_setsockopt (endpoint, ZMQ_LINGER, &linger, sizeof (linger));
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (endpoint, ZMQ_LINGER, &linger, sizeof (linger)));
|
||||
char endpoint_source[256];
|
||||
sprintf (endpoint_source, "inproc://endpoint%d", databag->id);
|
||||
rc = zmq_connect (endpoint, endpoint_source);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (endpoint, endpoint_source));
|
||||
char *my_endpoint = s_recv (endpoint);
|
||||
assert (my_endpoint);
|
||||
TEST_ASSERT_NOT_NULL (my_endpoint);
|
||||
|
||||
void *client = zmq_socket (databag->ctx, ZMQ_DEALER);
|
||||
assert (client);
|
||||
void *client = zmq_socket (get_test_context (), ZMQ_DEALER);
|
||||
TEST_ASSERT_NOT_NULL (client);
|
||||
|
||||
// Control socket receives terminate command from main over inproc
|
||||
void *control = zmq_socket (databag->ctx, ZMQ_SUB);
|
||||
assert (control);
|
||||
rc = zmq_setsockopt (control, ZMQ_SUBSCRIBE, "", 0);
|
||||
assert (rc == 0);
|
||||
rc = zmq_setsockopt (control, ZMQ_LINGER, &linger, sizeof (linger));
|
||||
assert (rc == 0);
|
||||
rc = zmq_connect (control, "inproc://control");
|
||||
assert (rc == 0);
|
||||
void *control = zmq_socket (get_test_context (), ZMQ_SUB);
|
||||
TEST_ASSERT_NOT_NULL (control);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (control, ZMQ_SUBSCRIBE, "", 0));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (control, ZMQ_LINGER, &linger, sizeof (linger)));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (control, "inproc://control"));
|
||||
|
||||
char content[CONTENT_SIZE_MAX] = {};
|
||||
// Set random routing id to make tracing easier
|
||||
char routing_id[ROUTING_ID_SIZE] = {};
|
||||
sprintf (routing_id, "%04X-%04X", rand () % 0xFFFF, rand () % 0xFFFF);
|
||||
rc =
|
||||
zmq_setsockopt (client, ZMQ_ROUTING_ID, routing_id,
|
||||
ROUTING_ID_SIZE); // includes '\0' as an helper for printf
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
|
||||
client, ZMQ_ROUTING_ID, routing_id,
|
||||
ROUTING_ID_SIZE)); // includes '\0' as an helper for printf
|
||||
linger = 0;
|
||||
rc = zmq_setsockopt (client, ZMQ_LINGER, &linger, sizeof (linger));
|
||||
assert (rc == 0);
|
||||
rc = zmq_connect (client, my_endpoint);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (client, ZMQ_LINGER, &linger, sizeof (linger)));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (client, my_endpoint));
|
||||
|
||||
zmq_pollitem_t items[] = {{client, 0, ZMQ_POLLIN, 0},
|
||||
{control, 0, ZMQ_POLLIN, 0}};
|
||||
@ -130,20 +137,21 @@ static void client_task (void *db_)
|
||||
if (items[0].revents & ZMQ_POLLIN) {
|
||||
int rcvmore;
|
||||
size_t sz = sizeof (rcvmore);
|
||||
rc = zmq_recv (client, content, CONTENT_SIZE_MAX, 0);
|
||||
assert (rc == CONTENT_SIZE);
|
||||
int rc = TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_recv (client, content, CONTENT_SIZE_MAX, 0));
|
||||
TEST_ASSERT_EQUAL_INT (CONTENT_SIZE, rc);
|
||||
if (is_verbose)
|
||||
printf (
|
||||
"client receive - routing_id = %s content = %s\n",
|
||||
routing_id, content);
|
||||
// Check that message is still the same
|
||||
assert (memcmp (content, "request #", 9) == 0);
|
||||
rc = zmq_getsockopt (client, ZMQ_RCVMORE, &rcvmore, &sz);
|
||||
assert (rc == 0);
|
||||
assert (!rcvmore);
|
||||
TEST_ASSERT_EQUAL_STRING_LEN ("request #", content, 9);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_getsockopt (client, ZMQ_RCVMORE, &rcvmore, &sz));
|
||||
TEST_ASSERT_FALSE (rcvmore);
|
||||
}
|
||||
if (items[1].revents & ZMQ_POLLIN) {
|
||||
rc = zmq_recv (control, content, CONTENT_SIZE_MAX, 0);
|
||||
int rc = zmq_recv (control, content, CONTENT_SIZE_MAX, 0);
|
||||
|
||||
if (rc > 0) {
|
||||
content[rc] = 0; // NULL-terminate the command string
|
||||
@ -170,17 +178,14 @@ static void client_task (void *db_)
|
||||
routing_id, request_nbr);
|
||||
zmq_atomic_counter_inc (g_clients_pkts_out);
|
||||
|
||||
rc = zmq_send (client, content, CONTENT_SIZE, 0);
|
||||
assert (rc == CONTENT_SIZE);
|
||||
TEST_ASSERT_EQUAL_INT (CONTENT_SIZE,
|
||||
zmq_send (client, content, CONTENT_SIZE, 0));
|
||||
}
|
||||
}
|
||||
|
||||
rc = zmq_close (client);
|
||||
assert (rc == 0);
|
||||
rc = zmq_close (control);
|
||||
assert (rc == 0);
|
||||
rc = zmq_close (endpoint);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_close (client));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_close (control));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_close (endpoint));
|
||||
free (my_endpoint);
|
||||
}
|
||||
|
||||
@ -190,80 +195,68 @@ static void client_task (void *db_)
|
||||
// one request at a time but one client can talk to multiple workers at
|
||||
// once.
|
||||
|
||||
static void server_worker (void *ctx_);
|
||||
static void server_worker (void * /*unused_*/);
|
||||
|
||||
void server_task (void *ctx_)
|
||||
void server_task (void * /*unused_*/)
|
||||
{
|
||||
// Frontend socket talks to clients over TCP
|
||||
size_t len = MAX_SOCKET_STRING;
|
||||
char my_endpoint[MAX_SOCKET_STRING];
|
||||
void *frontend = zmq_socket (ctx_, ZMQ_ROUTER);
|
||||
assert (frontend);
|
||||
void *frontend = zmq_socket (get_test_context (), ZMQ_ROUTER);
|
||||
TEST_ASSERT_NOT_NULL (frontend);
|
||||
int linger = 0;
|
||||
int rc = zmq_setsockopt (frontend, ZMQ_LINGER, &linger, sizeof (linger));
|
||||
assert (rc == 0);
|
||||
rc = zmq_bind (frontend, "tcp://127.0.0.1:*");
|
||||
assert (rc == 0);
|
||||
rc = zmq_getsockopt (frontend, ZMQ_LAST_ENDPOINT, my_endpoint, &len);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (frontend, ZMQ_LINGER, &linger, sizeof (linger)));
|
||||
bind_loopback_ipv4 (frontend, my_endpoint, sizeof my_endpoint);
|
||||
|
||||
// Backend socket talks to workers over inproc
|
||||
void *backend = zmq_socket (ctx_, ZMQ_DEALER);
|
||||
assert (backend);
|
||||
rc = zmq_setsockopt (backend, ZMQ_LINGER, &linger, sizeof (linger));
|
||||
assert (rc == 0);
|
||||
rc = zmq_bind (backend, "inproc://backend");
|
||||
assert (rc == 0);
|
||||
void *backend = zmq_socket (get_test_context (), ZMQ_DEALER);
|
||||
TEST_ASSERT_NOT_NULL (backend);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (backend, ZMQ_LINGER, &linger, sizeof (linger)));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (backend, "inproc://backend"));
|
||||
|
||||
// Control socket receives terminate command from main over inproc
|
||||
void *control = zmq_socket (ctx_, ZMQ_REP);
|
||||
assert (control);
|
||||
rc = zmq_setsockopt (control, ZMQ_LINGER, &linger, sizeof (linger));
|
||||
assert (rc == 0);
|
||||
rc = zmq_connect (control, "inproc://control_proxy");
|
||||
assert (rc == 0);
|
||||
void *control = zmq_socket (get_test_context (), ZMQ_REP);
|
||||
TEST_ASSERT_NOT_NULL (control);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (control, ZMQ_LINGER, &linger, sizeof (linger)));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (control, "inproc://control_proxy"));
|
||||
|
||||
// Launch pool of worker threads, precise number is not critical
|
||||
int thread_nbr;
|
||||
void *threads[5];
|
||||
for (thread_nbr = 0; thread_nbr < QT_WORKERS; thread_nbr++)
|
||||
threads[thread_nbr] = zmq_threadstart (&server_worker, ctx_);
|
||||
threads[thread_nbr] = zmq_threadstart (&server_worker, NULL);
|
||||
|
||||
// Endpoint socket sends random port to avoid test failing when port in use
|
||||
void *endpoint_receivers[QT_CLIENTS];
|
||||
char endpoint_source[256];
|
||||
for (int i = 0; i < QT_CLIENTS; ++i) {
|
||||
endpoint_receivers[i] = zmq_socket (ctx_, ZMQ_PAIR);
|
||||
assert (endpoint_receivers[i]);
|
||||
rc = zmq_setsockopt (endpoint_receivers[i], ZMQ_LINGER, &linger,
|
||||
sizeof (linger));
|
||||
assert (rc == 0);
|
||||
endpoint_receivers[i] = zmq_socket (get_test_context (), ZMQ_PAIR);
|
||||
TEST_ASSERT_NOT_NULL (endpoint_receivers[i]);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
|
||||
endpoint_receivers[i], ZMQ_LINGER, &linger, sizeof (linger)));
|
||||
sprintf (endpoint_source, "inproc://endpoint%d", i);
|
||||
rc = zmq_bind (endpoint_receivers[i], endpoint_source);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_bind (endpoint_receivers[i], endpoint_source));
|
||||
}
|
||||
|
||||
for (int i = 0; i < QT_CLIENTS; ++i) {
|
||||
rc = s_send (endpoint_receivers[i], my_endpoint);
|
||||
assert (rc > 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (s_send (endpoint_receivers[i], my_endpoint));
|
||||
}
|
||||
|
||||
// Connect backend to frontend via a proxy
|
||||
rc = zmq_proxy_steerable (frontend, backend, NULL, control);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_proxy_steerable (frontend, backend, NULL, control));
|
||||
|
||||
for (thread_nbr = 0; thread_nbr < QT_WORKERS; thread_nbr++)
|
||||
zmq_threadclose (threads[thread_nbr]);
|
||||
|
||||
rc = zmq_close (frontend);
|
||||
assert (rc == 0);
|
||||
rc = zmq_close (backend);
|
||||
assert (rc == 0);
|
||||
rc = zmq_close (control);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_close (frontend));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_close (backend));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_close (control));
|
||||
for (int i = 0; i < QT_CLIENTS; ++i) {
|
||||
rc = zmq_close (endpoint_receivers[i]);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_close (endpoint_receivers[i]));
|
||||
}
|
||||
}
|
||||
|
||||
@ -271,25 +264,22 @@ void server_task (void *ctx_)
|
||||
// of replies back, with random delays between replies:
|
||||
// The comments in the first column, if suppressed, makes it a poller version
|
||||
|
||||
static void server_worker (void *ctx_)
|
||||
static void server_worker (void * /*unused_*/)
|
||||
{
|
||||
void *worker = zmq_socket (ctx_, ZMQ_DEALER);
|
||||
assert (worker);
|
||||
void *worker = zmq_socket (get_test_context (), ZMQ_DEALER);
|
||||
TEST_ASSERT_NOT_NULL (worker);
|
||||
int linger = 0;
|
||||
int rc = zmq_setsockopt (worker, ZMQ_LINGER, &linger, sizeof (linger));
|
||||
assert (rc == 0);
|
||||
rc = zmq_connect (worker, "inproc://backend");
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (worker, ZMQ_LINGER, &linger, sizeof (linger)));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (worker, "inproc://backend"));
|
||||
|
||||
// Control socket receives terminate command from main over inproc
|
||||
void *control = zmq_socket (ctx_, ZMQ_SUB);
|
||||
assert (control);
|
||||
rc = zmq_setsockopt (control, ZMQ_SUBSCRIBE, "", 0);
|
||||
assert (rc == 0);
|
||||
rc = zmq_setsockopt (control, ZMQ_LINGER, &linger, sizeof (linger));
|
||||
assert (rc == 0);
|
||||
rc = zmq_connect (control, "inproc://control");
|
||||
assert (rc == 0);
|
||||
void *control = zmq_socket (get_test_context (), ZMQ_SUB);
|
||||
TEST_ASSERT_NOT_NULL (control);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (control, ZMQ_SUBSCRIBE, "", 0));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (control, ZMQ_LINGER, &linger, sizeof (linger)));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (control, "inproc://control"));
|
||||
|
||||
char content[CONTENT_SIZE_MAX] =
|
||||
{}; // bigger than what we need to check that
|
||||
@ -299,8 +289,8 @@ static void server_worker (void *ctx_)
|
||||
bool run = true;
|
||||
bool keep_sending = true;
|
||||
while (run) {
|
||||
rc = zmq_recv (control, content, CONTENT_SIZE_MAX,
|
||||
ZMQ_DONTWAIT); // usually, rc == -1 (no message)
|
||||
int rc = zmq_recv (control, content, CONTENT_SIZE_MAX,
|
||||
ZMQ_DONTWAIT); // usually, rc == -1 (no message)
|
||||
if (rc > 0) {
|
||||
content[rc] = 0; // NULL-terminate the command string
|
||||
if (is_verbose)
|
||||
@ -315,7 +305,7 @@ static void server_worker (void *ctx_)
|
||||
rc = zmq_recv (worker, routing_id, ROUTING_ID_SIZE_MAX, ZMQ_DONTWAIT);
|
||||
if (rc == ROUTING_ID_SIZE) {
|
||||
rc = zmq_recv (worker, content, CONTENT_SIZE_MAX, 0);
|
||||
assert (rc == CONTENT_SIZE);
|
||||
TEST_ASSERT_EQUAL_INT (CONTENT_SIZE, rc);
|
||||
if (is_verbose)
|
||||
printf ("server receive - routing_id = %s content = %s\n",
|
||||
routing_id, content);
|
||||
@ -335,17 +325,15 @@ static void server_worker (void *ctx_)
|
||||
|
||||
rc = zmq_send (worker, routing_id, ROUTING_ID_SIZE,
|
||||
ZMQ_SNDMORE);
|
||||
assert (rc == ROUTING_ID_SIZE);
|
||||
TEST_ASSERT_EQUAL_INT (ROUTING_ID_SIZE, rc);
|
||||
rc = zmq_send (worker, content, CONTENT_SIZE, 0);
|
||||
assert (rc == CONTENT_SIZE);
|
||||
TEST_ASSERT_EQUAL_INT (CONTENT_SIZE, rc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rc = zmq_close (worker);
|
||||
assert (rc == 0);
|
||||
rc = zmq_close (control);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_close (worker));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_close (control));
|
||||
}
|
||||
|
||||
uint64_t recv_stat (void *sock_, bool last_)
|
||||
@ -353,19 +341,17 @@ uint64_t recv_stat (void *sock_, bool last_)
|
||||
uint64_t res;
|
||||
zmq_msg_t stats_msg;
|
||||
|
||||
int rc = zmq_msg_init (&stats_msg);
|
||||
assert (rc == 0);
|
||||
rc = zmq_recvmsg (sock_, &stats_msg, 0);
|
||||
assert (rc == sizeof (uint64_t));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_init (&stats_msg));
|
||||
TEST_ASSERT_EQUAL_INT (sizeof (uint64_t),
|
||||
zmq_recvmsg (sock_, &stats_msg, 0));
|
||||
memcpy (&res, zmq_msg_data (&stats_msg), zmq_msg_size (&stats_msg));
|
||||
rc = zmq_msg_close (&stats_msg);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&stats_msg));
|
||||
|
||||
int more;
|
||||
size_t moresz = sizeof more;
|
||||
rc = zmq_getsockopt (sock_, ZMQ_RCVMORE, &more, &moresz);
|
||||
assert (rc == 0);
|
||||
assert ((last_ && !more) || (!last_ && more));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_getsockopt (sock_, ZMQ_RCVMORE, &more, &moresz));
|
||||
TEST_ASSERT_TRUE ((last_ && !more) || (!last_ && more));
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -375,10 +361,8 @@ uint64_t recv_stat (void *sock_, bool last_)
|
||||
void check_proxy_stats (void *control_proxy_)
|
||||
{
|
||||
zmq_proxy_stats_t total_stats;
|
||||
int rc;
|
||||
|
||||
rc = zmq_send (control_proxy_, "STATISTICS", 10, 0);
|
||||
assert (rc == 10);
|
||||
send_string_expect_success (control_proxy_, "STATISTICS", 0);
|
||||
|
||||
// first frame of the reply contains FRONTEND stats:
|
||||
total_stats.frontend.msg_in = recv_stat (control_proxy_, false);
|
||||
@ -413,91 +397,82 @@ void check_proxy_stats (void *control_proxy_)
|
||||
printf ("workers sent out %d replies\n",
|
||||
zmq_atomic_counter_value (g_workers_pkts_out));
|
||||
}
|
||||
assert (total_stats.frontend.msg_in
|
||||
== (unsigned) zmq_atomic_counter_value (g_clients_pkts_out));
|
||||
assert (total_stats.frontend.msg_out
|
||||
== (unsigned) zmq_atomic_counter_value (g_workers_pkts_out));
|
||||
assert (total_stats.backend.msg_in
|
||||
== (unsigned) zmq_atomic_counter_value (g_workers_pkts_out));
|
||||
assert (total_stats.backend.msg_out
|
||||
== (unsigned) zmq_atomic_counter_value (g_clients_pkts_out));
|
||||
TEST_ASSERT_EQUAL_UINT (
|
||||
(unsigned) zmq_atomic_counter_value (g_clients_pkts_out),
|
||||
total_stats.frontend.msg_in);
|
||||
TEST_ASSERT_EQUAL_UINT (
|
||||
(unsigned) zmq_atomic_counter_value (g_workers_pkts_out),
|
||||
total_stats.frontend.msg_out);
|
||||
TEST_ASSERT_EQUAL_UINT (
|
||||
(unsigned) zmq_atomic_counter_value (g_workers_pkts_out),
|
||||
total_stats.backend.msg_in);
|
||||
TEST_ASSERT_EQUAL_UINT (
|
||||
(unsigned) zmq_atomic_counter_value (g_clients_pkts_out),
|
||||
total_stats.backend.msg_out);
|
||||
}
|
||||
|
||||
|
||||
// The main thread simply starts several clients and a server, and then
|
||||
// waits for the server to finish.
|
||||
|
||||
int main (void)
|
||||
void test_proxy ()
|
||||
{
|
||||
setup_test_environment ();
|
||||
|
||||
void *ctx = zmq_ctx_new ();
|
||||
assert (ctx);
|
||||
|
||||
g_clients_pkts_out = zmq_atomic_counter_new ();
|
||||
g_workers_pkts_out = zmq_atomic_counter_new ();
|
||||
|
||||
|
||||
// Control socket receives terminate command from main over inproc
|
||||
void *control = zmq_socket (ctx, ZMQ_PUB);
|
||||
assert (control);
|
||||
void *control = test_context_socket (ZMQ_PUB);
|
||||
int linger = 0;
|
||||
int rc = zmq_setsockopt (control, ZMQ_LINGER, &linger, sizeof (linger));
|
||||
assert (rc == 0);
|
||||
rc = zmq_bind (control, "inproc://control");
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (control, ZMQ_LINGER, &linger, sizeof (linger)));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (control, "inproc://control"));
|
||||
|
||||
// Control socket receives terminate command from main over inproc
|
||||
void *control_proxy = zmq_socket (ctx, ZMQ_REQ);
|
||||
assert (control_proxy);
|
||||
rc = zmq_setsockopt (control_proxy, ZMQ_LINGER, &linger, sizeof (linger));
|
||||
assert (rc == 0);
|
||||
rc = zmq_bind (control_proxy, "inproc://control_proxy");
|
||||
assert (rc == 0);
|
||||
void *control_proxy = test_context_socket (ZMQ_REQ);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (control_proxy, ZMQ_LINGER, &linger, sizeof (linger)));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_bind (control_proxy, "inproc://control_proxy"));
|
||||
|
||||
void *threads[QT_CLIENTS + 1];
|
||||
struct thread_data databags[QT_CLIENTS + 1];
|
||||
for (int i = 0; i < QT_CLIENTS; i++) {
|
||||
databags[i].ctx = ctx;
|
||||
databags[i].id = i;
|
||||
threads[i] = zmq_threadstart (&client_task, &databags[i]);
|
||||
}
|
||||
threads[QT_CLIENTS] = zmq_threadstart (&server_task, ctx);
|
||||
threads[QT_CLIENTS] = zmq_threadstart (&server_task, NULL);
|
||||
msleep (500); // Run for 500 ms then quit
|
||||
|
||||
|
||||
if (is_verbose)
|
||||
printf ("stopping all clients and server workers\n");
|
||||
rc = zmq_send (control, "STOP", 4, 0);
|
||||
assert (rc == 4);
|
||||
send_string_expect_success (control, "STOP", 0);
|
||||
|
||||
msleep (500); // Wait for all clients and workers to STOP
|
||||
|
||||
|
||||
if (is_verbose)
|
||||
printf ("retrieving stats from the proxy\n");
|
||||
check_proxy_stats (control_proxy);
|
||||
|
||||
if (is_verbose)
|
||||
printf ("shutting down all clients and server workers\n");
|
||||
rc = zmq_send (control, "TERMINATE", 9, 0);
|
||||
assert (rc == 9);
|
||||
send_string_expect_success (control, "TERMINATE", 0);
|
||||
|
||||
if (is_verbose)
|
||||
printf ("shutting down the proxy\n");
|
||||
rc = zmq_send (control_proxy, "TERMINATE", 9, 0);
|
||||
assert (rc == 9);
|
||||
send_string_expect_success (control_proxy, "TERMINATE", 0);
|
||||
|
||||
|
||||
rc = zmq_close (control);
|
||||
assert (rc == 0);
|
||||
rc = zmq_close (control_proxy);
|
||||
assert (rc == 0);
|
||||
test_context_socket_close (control);
|
||||
test_context_socket_close (control_proxy);
|
||||
|
||||
for (int i = 0; i < QT_CLIENTS + 1; i++)
|
||||
zmq_threadclose (threads[i]);
|
||||
|
||||
rc = zmq_ctx_term (ctx);
|
||||
assert (rc == 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
setup_test_environment ();
|
||||
|
||||
UNITY_BEGIN ();
|
||||
RUN_TEST (test_proxy);
|
||||
return UNITY_END ();
|
||||
}
|
||||
|
@ -29,7 +29,10 @@
|
||||
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
#include <string.h>
|
||||
#include <unity.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
|
||||
//
|
||||
// Asynchronous proxy test using ZMQ_XPUB_NODROP and HWM:
|
||||
|
@ -28,92 +28,83 @@
|
||||
*/
|
||||
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
}
|
||||
|
||||
void tearDown ()
|
||||
{
|
||||
teardown_test_context ();
|
||||
}
|
||||
|
||||
// This is our server task.
|
||||
// It runs a proxy with a single REP socket as both frontend and backend.
|
||||
|
||||
void server_task (void *ctx_)
|
||||
void server_task (void * /*unused_*/)
|
||||
{
|
||||
size_t len = MAX_SOCKET_STRING;
|
||||
char my_endpoint[MAX_SOCKET_STRING];
|
||||
void *rep = zmq_socket (ctx_, ZMQ_REP);
|
||||
assert (rep);
|
||||
int rc = zmq_bind (rep, "tcp://127.0.0.1:*");
|
||||
assert (rc == 0);
|
||||
rc = zmq_getsockopt (rep, ZMQ_LAST_ENDPOINT, my_endpoint, &len);
|
||||
assert (rc == 0);
|
||||
void *rep = zmq_socket (get_test_context (), ZMQ_REP);
|
||||
TEST_ASSERT_NOT_NULL (rep);
|
||||
bind_loopback_ipv4 (rep, my_endpoint, sizeof my_endpoint);
|
||||
|
||||
// Control socket receives terminate command from main over inproc
|
||||
void *control = zmq_socket (ctx_, ZMQ_REQ);
|
||||
assert (control);
|
||||
rc = zmq_connect (control, "inproc://control");
|
||||
assert (rc == 0);
|
||||
rc = s_send (control, my_endpoint);
|
||||
assert (rc > 0);
|
||||
void *control = zmq_socket (get_test_context (), ZMQ_REQ);
|
||||
TEST_ASSERT_NOT_NULL (control);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (control, "inproc://control"));
|
||||
TEST_ASSERT_GREATER_THAN_INT (
|
||||
0, TEST_ASSERT_SUCCESS_ERRNO (s_send (control, my_endpoint)));
|
||||
|
||||
// Use rep as both frontend and backend
|
||||
rc = zmq_proxy_steerable (rep, rep, NULL, control);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_proxy_steerable (rep, rep, NULL, control));
|
||||
|
||||
rc = zmq_close (rep);
|
||||
assert (rc == 0);
|
||||
rc = zmq_close (control);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_close (rep));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_close (control));
|
||||
}
|
||||
|
||||
|
||||
// The main thread simply starts several clients and a server, and then
|
||||
// waits for the server to finish.
|
||||
void test_proxy_single_socket ()
|
||||
{
|
||||
void *server_thread = zmq_threadstart (&server_task, NULL);
|
||||
|
||||
// Control socket receives terminate command from main over inproc
|
||||
void *control = test_context_socket (ZMQ_REP);
|
||||
TEST_ASSERT_NOT_NULL (control);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (control, "inproc://control"));
|
||||
char *my_endpoint = s_recv (control);
|
||||
TEST_ASSERT_NOT_NULL (my_endpoint);
|
||||
|
||||
// client socket pings proxy over tcp
|
||||
void *req = test_context_socket (ZMQ_REQ);
|
||||
TEST_ASSERT_NOT_NULL (req);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (req, my_endpoint));
|
||||
|
||||
send_string_expect_success (req, "msg1", 0);
|
||||
recv_string_expect_success (req, "msg1", 0);
|
||||
|
||||
send_string_expect_success (req, "msg22", 0);
|
||||
recv_string_expect_success (req, "msg22", 0);
|
||||
|
||||
send_string_expect_success (control, "TERMINATE", 0);
|
||||
|
||||
test_context_socket_close (control);
|
||||
test_context_socket_close (req);
|
||||
free (my_endpoint);
|
||||
|
||||
zmq_threadclose (server_thread);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
setup_test_environment ();
|
||||
|
||||
void *ctx = zmq_ctx_new ();
|
||||
assert (ctx);
|
||||
|
||||
void *server_thread = zmq_threadstart (&server_task, ctx);
|
||||
|
||||
// Control socket receives terminate command from main over inproc
|
||||
void *control = zmq_socket (ctx, ZMQ_REP);
|
||||
assert (control);
|
||||
int rc = zmq_bind (control, "inproc://control");
|
||||
assert (rc == 0);
|
||||
char *my_endpoint = s_recv (control);
|
||||
assert (my_endpoint);
|
||||
|
||||
// client socket pings proxy over tcp
|
||||
void *req = zmq_socket (ctx, ZMQ_REQ);
|
||||
assert (req);
|
||||
rc = zmq_connect (req, my_endpoint);
|
||||
assert (rc == 0);
|
||||
|
||||
char buf[255];
|
||||
rc = zmq_send (req, "msg1", 4, 0);
|
||||
assert (rc == 4);
|
||||
rc = zmq_recv (req, buf, 255, 0);
|
||||
assert (rc == 4);
|
||||
assert (memcmp (buf, "msg1", 4) == 0);
|
||||
|
||||
rc = zmq_send (req, "msg22", 5, 0);
|
||||
assert (rc == 5);
|
||||
rc = zmq_recv (req, buf, 255, 0);
|
||||
assert (rc == 5);
|
||||
assert (memcmp (buf, "msg22", 5) == 0);
|
||||
|
||||
rc = zmq_send (control, "TERMINATE", 9, 0);
|
||||
assert (rc == 9);
|
||||
|
||||
rc = zmq_close (control);
|
||||
assert (rc == 0);
|
||||
rc = zmq_close (req);
|
||||
assert (rc == 0);
|
||||
free (my_endpoint);
|
||||
|
||||
zmq_threadclose (server_thread);
|
||||
|
||||
rc = zmq_ctx_term (ctx);
|
||||
assert (rc == 0);
|
||||
return 0;
|
||||
UNITY_BEGIN ();
|
||||
RUN_TEST (test_proxy_single_socket);
|
||||
return UNITY_END ();
|
||||
}
|
||||
|
@ -28,104 +28,98 @@
|
||||
*/
|
||||
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
}
|
||||
|
||||
void tearDown ()
|
||||
{
|
||||
teardown_test_context ();
|
||||
}
|
||||
|
||||
// This is a test for issue #1382. The server thread creates a SUB-PUSH
|
||||
// steerable proxy. The main process then sends messages to the SUB
|
||||
// but there is no pull on the other side, previously the proxy blocks
|
||||
// in writing to the backend, preventing the proxy from terminating
|
||||
|
||||
void server_task (void *ctx_)
|
||||
void server_task (void * /*unused_*/)
|
||||
{
|
||||
size_t len = MAX_SOCKET_STRING;
|
||||
char my_endpoint[MAX_SOCKET_STRING];
|
||||
// Frontend socket talks to main process
|
||||
void *frontend = zmq_socket (ctx_, ZMQ_SUB);
|
||||
assert (frontend);
|
||||
int rc = zmq_setsockopt (frontend, ZMQ_SUBSCRIBE, "", 0);
|
||||
assert (rc == 0);
|
||||
rc = zmq_bind (frontend, "tcp://127.0.0.1:*");
|
||||
assert (rc == 0);
|
||||
rc = zmq_getsockopt (frontend, ZMQ_LAST_ENDPOINT, my_endpoint, &len);
|
||||
assert (rc == 0);
|
||||
void *frontend = zmq_socket (get_test_context (), ZMQ_SUB);
|
||||
TEST_ASSERT_NOT_NULL (frontend);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (frontend, ZMQ_SUBSCRIBE, "", 0));
|
||||
bind_loopback_ipv4 (frontend, my_endpoint, sizeof my_endpoint);
|
||||
|
||||
// Nice socket which is never read
|
||||
void *backend = zmq_socket (ctx_, ZMQ_PUSH);
|
||||
assert (backend);
|
||||
rc = zmq_bind (backend, "tcp://127.0.0.1:*");
|
||||
assert (rc == 0);
|
||||
void *backend = zmq_socket (get_test_context (), ZMQ_PUSH);
|
||||
TEST_ASSERT_NOT_NULL (backend);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (backend, "tcp://127.0.0.1:*"));
|
||||
|
||||
// Control socket receives terminate command from main over inproc
|
||||
void *control = zmq_socket (ctx_, ZMQ_REQ);
|
||||
assert (control);
|
||||
rc = zmq_connect (control, "inproc://control");
|
||||
assert (rc == 0);
|
||||
rc = s_send (control, my_endpoint);
|
||||
assert (rc > 0);
|
||||
void *control = zmq_socket (get_test_context (), ZMQ_REQ);
|
||||
TEST_ASSERT_NOT_NULL (control);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (control, "inproc://control"));
|
||||
TEST_ASSERT_GREATER_THAN_INT (
|
||||
0, TEST_ASSERT_SUCCESS_ERRNO (s_send (control, my_endpoint)));
|
||||
|
||||
// Connect backend to frontend via a proxy
|
||||
rc = zmq_proxy_steerable (frontend, backend, NULL, control);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_proxy_steerable (frontend, backend, NULL, control));
|
||||
|
||||
rc = zmq_close (frontend);
|
||||
assert (rc == 0);
|
||||
rc = zmq_close (backend);
|
||||
assert (rc == 0);
|
||||
rc = zmq_close (control);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_close (frontend));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_close (backend));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_close (control));
|
||||
}
|
||||
|
||||
|
||||
// The main thread simply starts a basic steerable proxy server, publishes some messages, and then
|
||||
// waits for the server to terminate.
|
||||
void test_proxy_terminate ()
|
||||
{
|
||||
void *thread = zmq_threadstart (&server_task, NULL);
|
||||
|
||||
// Control socket receives terminate command from main over inproc
|
||||
void *control = test_context_socket (ZMQ_REP);
|
||||
TEST_ASSERT_NOT_NULL (control);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (control, "inproc://control"));
|
||||
char *my_endpoint = s_recv (control);
|
||||
TEST_ASSERT_NOT_NULL (my_endpoint);
|
||||
|
||||
msleep (500); // Run for 500 ms
|
||||
|
||||
// Start a secondary publisher which writes data to the SUB-PUSH server socket
|
||||
void *publisher = test_context_socket (ZMQ_PUB);
|
||||
TEST_ASSERT_NOT_NULL (publisher);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (publisher, my_endpoint));
|
||||
|
||||
msleep (SETTLE_TIME);
|
||||
send_string_expect_success (publisher, "This is a test", 0);
|
||||
|
||||
msleep (50);
|
||||
send_string_expect_success (publisher, "This is a test", 0);
|
||||
|
||||
msleep (50);
|
||||
send_string_expect_success (publisher, "This is a test", 0);
|
||||
send_string_expect_success (control, "TERMINATE", 0);
|
||||
|
||||
test_context_socket_close (publisher);
|
||||
test_context_socket_close (control);
|
||||
free (my_endpoint);
|
||||
|
||||
zmq_threadclose (thread);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
setup_test_environment ();
|
||||
|
||||
void *ctx = zmq_ctx_new ();
|
||||
assert (ctx);
|
||||
|
||||
void *thread = zmq_threadstart (&server_task, ctx);
|
||||
|
||||
// Control socket receives terminate command from main over inproc
|
||||
void *control = zmq_socket (ctx, ZMQ_REP);
|
||||
assert (control);
|
||||
int rc = zmq_bind (control, "inproc://control");
|
||||
assert (rc == 0);
|
||||
char *my_endpoint = s_recv (control);
|
||||
assert (my_endpoint);
|
||||
|
||||
msleep (500); // Run for 500 ms
|
||||
|
||||
// Start a secondary publisher which writes data to the SUB-PUSH server socket
|
||||
void *publisher = zmq_socket (ctx, ZMQ_PUB);
|
||||
assert (publisher);
|
||||
rc = zmq_connect (publisher, my_endpoint);
|
||||
assert (rc == 0);
|
||||
|
||||
msleep (SETTLE_TIME);
|
||||
rc = zmq_send (publisher, "This is a test", 14, 0);
|
||||
assert (rc == 14);
|
||||
|
||||
msleep (50);
|
||||
rc = zmq_send (publisher, "This is a test", 14, 0);
|
||||
assert (rc == 14);
|
||||
|
||||
msleep (50);
|
||||
rc = zmq_send (publisher, "This is a test", 14, 0);
|
||||
assert (rc == 14);
|
||||
rc = zmq_send (control, "TERMINATE", 9, 0);
|
||||
assert (rc == 9);
|
||||
|
||||
rc = zmq_close (publisher);
|
||||
assert (rc == 0);
|
||||
rc = zmq_close (control);
|
||||
assert (rc == 0);
|
||||
free (my_endpoint);
|
||||
|
||||
zmq_threadclose (thread);
|
||||
|
||||
rc = zmq_ctx_term (ctx);
|
||||
assert (rc == 0);
|
||||
return 0;
|
||||
UNITY_BEGIN ();
|
||||
RUN_TEST (test_proxy_terminate);
|
||||
return UNITY_END ();
|
||||
}
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
|
@ -32,6 +32,15 @@
|
||||
|
||||
#include <unity.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
// Helper macro to define the v4/v6 function pairs
|
||||
#define MAKE_TEST_V4V6(_test) \
|
||||
static void _test##_ipv4 () { _test (false); } \
|
||||
|
@ -79,7 +79,7 @@ void test_req_correlate ()
|
||||
|
||||
// Receive request id 1
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_recv (&msg, router, 0));
|
||||
assert (zmq_msg_size (&msg) == sizeof (uint32_t));
|
||||
TEST_ASSERT_EQUAL_UINT (sizeof (uint32_t), zmq_msg_size (&msg));
|
||||
const uint32_t req_id = *static_cast<uint32_t *> (zmq_msg_data (&msg));
|
||||
zmq_msg_t req_id_msg;
|
||||
zmq_msg_init (&req_id_msg);
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unity.h>
|
||||
|
||||
void setUp ()
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
|
@ -32,37 +32,41 @@
|
||||
#include <vmci_sockets.h>
|
||||
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
int main (void)
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_environment ();
|
||||
void *ctx = zmq_ctx_new ();
|
||||
assert (ctx);
|
||||
setup_test_context ();
|
||||
}
|
||||
|
||||
void tearDown ()
|
||||
{
|
||||
teardown_test_context ();
|
||||
}
|
||||
|
||||
void test_reqrep_vmci ()
|
||||
{
|
||||
std::stringstream s;
|
||||
s << "vmci://" << VMCISock_GetLocalCID () << ":" << 5560;
|
||||
std::string endpoint = s.str ();
|
||||
|
||||
void *sb = zmq_socket (ctx, ZMQ_REP);
|
||||
assert (sb);
|
||||
int rc = zmq_bind (sb, endpoint.c_str ());
|
||||
assert (rc == 0);
|
||||
void *sb = test_context_socket (ZMQ_REP);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (sb, endpoint.c_str ()));
|
||||
|
||||
void *sc = zmq_socket (ctx, ZMQ_REQ);
|
||||
assert (sc);
|
||||
rc = zmq_connect (sc, endpoint.c_str ());
|
||||
assert (rc == 0);
|
||||
void *sc = test_context_socket (ZMQ_REQ);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sc, endpoint.c_str ()));
|
||||
|
||||
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;
|
||||
test_context_socket_close (sc);
|
||||
test_context_socket_close (sb);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
setup_test_environment ();
|
||||
|
||||
UNITY_BEGIN ();
|
||||
RUN_TEST (test_reqrep_vmci);
|
||||
return UNITY_END ();
|
||||
}
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <string.h>
|
||||
#include <unity.h>
|
||||
|
||||
void setUp ()
|
||||
|
@ -30,47 +30,49 @@
|
||||
#include <stdio.h>
|
||||
#include "testutil.hpp"
|
||||
|
||||
int main (void)
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
}
|
||||
|
||||
void tearDown ()
|
||||
{
|
||||
teardown_test_context ();
|
||||
}
|
||||
|
||||
void test_router_mandatory_tipc ()
|
||||
{
|
||||
if (!is_tipc_available ()) {
|
||||
printf ("TIPC environment unavailable, skipping test\n");
|
||||
return 77;
|
||||
TEST_IGNORE_MESSAGE ("TIPC environment unavailable, skipping test");
|
||||
}
|
||||
|
||||
fprintf (stderr, "test_router_mandatory_tipc running...\n");
|
||||
|
||||
void *ctx = zmq_init (1);
|
||||
assert (ctx);
|
||||
|
||||
// Creating the first socket.
|
||||
void *sa = zmq_socket (ctx, ZMQ_ROUTER);
|
||||
assert (sa);
|
||||
void *sa = test_context_socket (ZMQ_ROUTER);
|
||||
|
||||
int rc = zmq_bind (sa, "tipc://{15560,0,0}");
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (sa, "tipc://{15560,0,0}"));
|
||||
|
||||
// Sending a message to an unknown peer with the default setting
|
||||
rc = zmq_send (sa, "UNKNOWN", 7, ZMQ_SNDMORE);
|
||||
assert (rc == 7);
|
||||
rc = zmq_send (sa, "DATA", 4, 0);
|
||||
assert (rc == 4);
|
||||
send_string_expect_success (sa, "UNKNOWN", ZMQ_SNDMORE);
|
||||
send_string_expect_success (sa, "DATA", 0);
|
||||
|
||||
int mandatory = 1;
|
||||
|
||||
// Set mandatory routing on socket
|
||||
rc =
|
||||
zmq_setsockopt (sa, ZMQ_ROUTER_MANDATORY, &mandatory, sizeof (mandatory));
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (sa, ZMQ_ROUTER_MANDATORY,
|
||||
&mandatory, sizeof (mandatory)));
|
||||
|
||||
// Send a message and check that it fails
|
||||
rc = zmq_send (sa, "UNKNOWN", 7, ZMQ_SNDMORE | ZMQ_DONTWAIT);
|
||||
assert (rc == -1 && errno == EHOSTUNREACH);
|
||||
TEST_ASSERT_FAILURE_ERRNO (
|
||||
EHOSTUNREACH, zmq_send (sa, "UNKNOWN", 7, ZMQ_SNDMORE | ZMQ_DONTWAIT));
|
||||
|
||||
rc = zmq_close (sa);
|
||||
assert (rc == 0);
|
||||
|
||||
rc = zmq_ctx_term (ctx);
|
||||
assert (rc == 0);
|
||||
|
||||
return 0;
|
||||
test_context_socket_close (sa);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
UNITY_BEGIN ();
|
||||
RUN_TEST (test_router_mandatory_tipc);
|
||||
return UNITY_END ();
|
||||
}
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <string.h>
|
||||
#include <unity.h>
|
||||
|
||||
void setUp ()
|
||||
|
@ -28,6 +28,7 @@
|
||||
*/
|
||||
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
#if defined(ZMQ_HAVE_WINDOWS)
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
@ -40,6 +41,9 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// This test requires a KRB5 environment with the following
|
||||
// service principal (substitute your host.domain and REALM):
|
||||
//
|
||||
@ -55,42 +59,6 @@ const char *name = "zmqtest2";
|
||||
|
||||
static volatile int zap_deny_all = 0;
|
||||
|
||||
// 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_, int *value_, char **address_)
|
||||
{
|
||||
// First frame in message contains event number and value
|
||||
zmq_msg_t msg;
|
||||
zmq_msg_init (&msg);
|
||||
if (zmq_msg_recv (&msg, monitor_, 0) == -1)
|
||||
return -1; // Interruped, presumably
|
||||
assert (zmq_msg_more (&msg));
|
||||
|
||||
uint8_t *data = (uint8_t *) zmq_msg_data (&msg);
|
||||
uint16_t event = *(uint16_t *) (data);
|
||||
if (value_)
|
||||
*value_ = *(uint32_t *) (data + 2);
|
||||
zmq_msg_close (&msg);
|
||||
|
||||
// Second frame in message contains event address
|
||||
zmq_msg_init (&msg);
|
||||
if (zmq_msg_recv (&msg, monitor_, 0) == -1)
|
||||
return -1; // Interruped, presumably
|
||||
assert (!zmq_msg_more (&msg));
|
||||
|
||||
if (address_) {
|
||||
uint8_t *data = (uint8_t *) zmq_msg_data (&msg);
|
||||
size_t size = zmq_msg_size (&msg);
|
||||
*address_ = (char *) malloc (size + 1);
|
||||
memcpy (*address_, data, size);
|
||||
*address_[size] = 0;
|
||||
}
|
||||
zmq_msg_close (&msg);
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// This methods receives and validates ZAP requestes (allowing or denying
|
||||
// each client connection).
|
||||
@ -111,8 +79,8 @@ static void zap_handler (void *handler_)
|
||||
char *mechanism = s_recv (handler_);
|
||||
char *principal = s_recv (handler_);
|
||||
|
||||
assert (streq (version, "1.0"));
|
||||
assert (streq (mechanism, "GSSAPI"));
|
||||
TEST_ASSERT_EQUAL_STRING ("1.0", version);
|
||||
TEST_ASSERT_EQUAL_STRING ("GSSAPI", mechanism);
|
||||
|
||||
s_sendmore (handler_, version);
|
||||
s_sendmore (handler_, sequence);
|
||||
@ -141,113 +109,190 @@ static void zap_handler (void *handler_)
|
||||
zmq_close (handler_);
|
||||
}
|
||||
|
||||
void test_valid_creds (void *ctx_,
|
||||
void *server_,
|
||||
void *server_mon_,
|
||||
char *endpoint_)
|
||||
static char my_endpoint[MAX_SOCKET_STRING];
|
||||
static void *zap_thread;
|
||||
static void *server;
|
||||
static void *server_mon;
|
||||
|
||||
void check_krb_available ()
|
||||
{
|
||||
void *client = zmq_socket (ctx_, ZMQ_DEALER);
|
||||
assert (client);
|
||||
int rc = zmq_setsockopt (client, ZMQ_GSSAPI_SERVICE_PRINCIPAL, name,
|
||||
strlen (name) + 1);
|
||||
assert (rc == 0);
|
||||
rc = zmq_setsockopt (client, ZMQ_GSSAPI_PRINCIPAL, name, strlen (name) + 1);
|
||||
assert (rc == 0);
|
||||
if (!getenv ("KRB5_KTNAME") || !getenv ("KRB5_CLIENT_KTNAME")) {
|
||||
TEST_IGNORE_MESSAGE ("KRB5 environment unavailable, skipping test");
|
||||
}
|
||||
}
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
|
||||
zap_thread = 0;
|
||||
server = NULL;
|
||||
server_mon = NULL;
|
||||
|
||||
check_krb_available ();
|
||||
|
||||
// Spawn ZAP handler
|
||||
// We create and bind ZAP socket in main thread to avoid case
|
||||
// where child thread does not start up fast enough.
|
||||
void *handler = zmq_socket (get_test_context (), ZMQ_REP);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (handler, "inproc://zeromq.zap.01"));
|
||||
zap_thread = zmq_threadstart (&zap_handler, handler);
|
||||
|
||||
// Server socket will accept connections
|
||||
server = test_context_socket (ZMQ_DEALER);
|
||||
int as_server = 1;
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (server, ZMQ_GSSAPI_SERVER, &as_server, sizeof (int)));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (server, ZMQ_GSSAPI_PRINCIPAL, name, strlen (name) + 1));
|
||||
int name_type = ZMQ_GSSAPI_NT_HOSTBASED;
|
||||
rc = zmq_setsockopt (client, ZMQ_GSSAPI_PRINCIPAL_NAMETYPE, &name_type,
|
||||
sizeof (name_type));
|
||||
assert (rc == 0);
|
||||
rc = zmq_connect (client, endpoint_);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
|
||||
server, ZMQ_GSSAPI_PRINCIPAL_NAMETYPE, &name_type, sizeof (name_type)));
|
||||
bind_loopback_ipv4 (server, my_endpoint, sizeof my_endpoint);
|
||||
|
||||
bounce (server_, client);
|
||||
rc = zmq_close (client);
|
||||
assert (rc == 0);
|
||||
// Monitor handshake events on the server
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_socket_monitor (
|
||||
server, "inproc://monitor-server",
|
||||
ZMQ_EVENT_HANDSHAKE_SUCCEEDED | ZMQ_EVENT_HANDSHAKE_FAILED_AUTH
|
||||
| ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL));
|
||||
|
||||
int event = get_monitor_event (server_mon_, NULL, NULL);
|
||||
assert (event == ZMQ_EVENT_HANDSHAKE_SUCCEEDED);
|
||||
// Create socket for collecting monitor events
|
||||
server_mon = test_context_socket (ZMQ_PAIR);
|
||||
|
||||
// Connect it to the inproc endpoints so they'll get events
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_connect (server_mon, "inproc://monitor-server"));
|
||||
}
|
||||
|
||||
void tearDown ()
|
||||
{
|
||||
// Shutdown
|
||||
if (server_mon)
|
||||
test_context_socket_close_zero_linger (server_mon);
|
||||
if (server)
|
||||
test_context_socket_close (server);
|
||||
teardown_test_context ();
|
||||
|
||||
// Wait until ZAP handler terminates
|
||||
if (zap_thread)
|
||||
zmq_threadclose (zap_thread);
|
||||
}
|
||||
|
||||
// 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_, int *value_, char **address_)
|
||||
{
|
||||
// First frame in message contains event number and value
|
||||
zmq_msg_t msg;
|
||||
zmq_msg_init (&msg);
|
||||
if (zmq_msg_recv (&msg, monitor_, 0) == -1)
|
||||
return -1; // Interruped, presumably
|
||||
TEST_ASSERT_TRUE (zmq_msg_more (&msg));
|
||||
|
||||
uint8_t *data = (uint8_t *) zmq_msg_data (&msg);
|
||||
uint16_t event = *(uint16_t *) (data);
|
||||
if (value_)
|
||||
*value_ = *(uint32_t *) (data + 2);
|
||||
zmq_msg_close (&msg);
|
||||
|
||||
// Second frame in message contains event address
|
||||
zmq_msg_init (&msg);
|
||||
if (zmq_msg_recv (&msg, monitor_, 0) == -1)
|
||||
return -1; // Interruped, presumably
|
||||
TEST_ASSERT_FALSE (zmq_msg_more (&msg));
|
||||
|
||||
if (address_) {
|
||||
uint8_t *data = (uint8_t *) zmq_msg_data (&msg);
|
||||
size_t size = zmq_msg_size (&msg);
|
||||
*address_ = (char *) malloc (size + 1);
|
||||
memcpy (*address_, data, size);
|
||||
*address_[size] = 0;
|
||||
}
|
||||
zmq_msg_close (&msg);
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
void test_valid_creds ()
|
||||
{
|
||||
void *client = test_context_socket (ZMQ_DEALER);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
|
||||
client, ZMQ_GSSAPI_SERVICE_PRINCIPAL, name, strlen (name) + 1));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (client, ZMQ_GSSAPI_PRINCIPAL, name, strlen (name) + 1));
|
||||
int name_type = ZMQ_GSSAPI_NT_HOSTBASED;
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
|
||||
client, ZMQ_GSSAPI_PRINCIPAL_NAMETYPE, &name_type, sizeof (name_type)));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (client, my_endpoint));
|
||||
|
||||
bounce (server, client);
|
||||
test_context_socket_close (client);
|
||||
|
||||
int event = get_monitor_event (server_mon, NULL, NULL);
|
||||
TEST_ASSERT_EQUAL_INT (ZMQ_EVENT_HANDSHAKE_SUCCEEDED, event);
|
||||
}
|
||||
|
||||
// Check security with valid but unauthorized credentials
|
||||
// Note: ZAP may see multiple requests - after a failure, client will
|
||||
// fall back to other crypto types for principal, if available.
|
||||
void test_unauth_creds (void *ctx_,
|
||||
void *server_,
|
||||
void *server_mon_,
|
||||
char *endpoint_)
|
||||
void test_unauth_creds ()
|
||||
{
|
||||
void *client = zmq_socket (ctx_, ZMQ_DEALER);
|
||||
assert (client);
|
||||
int rc = zmq_setsockopt (client, ZMQ_GSSAPI_SERVICE_PRINCIPAL, name,
|
||||
strlen (name) + 1);
|
||||
assert (rc == 0);
|
||||
rc = zmq_setsockopt (client, ZMQ_GSSAPI_PRINCIPAL, name, strlen (name) + 1);
|
||||
assert (rc == 0);
|
||||
void *client = test_context_socket (ZMQ_DEALER);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
|
||||
client, ZMQ_GSSAPI_SERVICE_PRINCIPAL, name, strlen (name) + 1));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (client, ZMQ_GSSAPI_PRINCIPAL, name, strlen (name) + 1));
|
||||
int name_type = ZMQ_GSSAPI_NT_HOSTBASED;
|
||||
rc = zmq_setsockopt (client, ZMQ_GSSAPI_PRINCIPAL_NAMETYPE, &name_type,
|
||||
sizeof (name_type));
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
|
||||
client, ZMQ_GSSAPI_PRINCIPAL_NAMETYPE, &name_type, sizeof (name_type)));
|
||||
zap_deny_all = 1;
|
||||
rc = zmq_connect (client, endpoint_);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (client, my_endpoint));
|
||||
|
||||
expect_bounce_fail (server_, client);
|
||||
close_zero_linger (client);
|
||||
expect_bounce_fail (server, client);
|
||||
test_context_socket_close_zero_linger (client);
|
||||
|
||||
int event = get_monitor_event (server_mon_, NULL, NULL);
|
||||
assert (event == ZMQ_EVENT_HANDSHAKE_FAILED_AUTH);
|
||||
int event = get_monitor_event (server_mon, NULL, NULL);
|
||||
TEST_ASSERT_EQUAL_INT (ZMQ_EVENT_HANDSHAKE_FAILED_AUTH, event);
|
||||
}
|
||||
|
||||
// Check GSSAPI security with NULL client credentials
|
||||
// This must be caught by the gssapi_server class, not passed to ZAP
|
||||
void test_null_creds (void *ctx_,
|
||||
void *server_,
|
||||
void *server_mon_,
|
||||
char *endpoint_)
|
||||
void test_null_creds ()
|
||||
{
|
||||
void *client = zmq_socket (ctx_, ZMQ_DEALER);
|
||||
assert (client);
|
||||
int rc = zmq_connect (client, endpoint_);
|
||||
assert (rc == 0);
|
||||
expect_bounce_fail (server_, client);
|
||||
close_zero_linger (client);
|
||||
void *client = test_context_socket (ZMQ_DEALER);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (client, my_endpoint));
|
||||
expect_bounce_fail (server, client);
|
||||
test_context_socket_close_zero_linger (client);
|
||||
|
||||
int error;
|
||||
int event = get_monitor_event (server_mon_, &error, NULL);
|
||||
assert (event == ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL);
|
||||
assert (error == ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH);
|
||||
int event = get_monitor_event (server_mon, &error, NULL);
|
||||
TEST_ASSERT_EQUAL_INT (ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL, event);
|
||||
TEST_ASSERT_EQUAL_INT (ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH, error);
|
||||
}
|
||||
|
||||
// Check GSSAPI security with PLAIN client credentials
|
||||
// This must be caught by the curve_server class, not passed to ZAP
|
||||
void test_plain_creds (void *ctx_,
|
||||
void *server_,
|
||||
void *server_mon_,
|
||||
char *endpoint_)
|
||||
void test_plain_creds ()
|
||||
{
|
||||
void *client = zmq_socket (ctx_, ZMQ_DEALER);
|
||||
assert (client);
|
||||
int rc = zmq_setsockopt (client, ZMQ_PLAIN_USERNAME, "admin", 5);
|
||||
assert (rc == 0);
|
||||
rc = zmq_setsockopt (client, ZMQ_PLAIN_PASSWORD, "password", 8);
|
||||
assert (rc == 0);
|
||||
rc = zmq_connect (client, endpoint_);
|
||||
assert (rc == 0);
|
||||
expect_bounce_fail (server_, client);
|
||||
close_zero_linger (client);
|
||||
void *client = test_context_socket (ZMQ_DEALER);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (client, ZMQ_PLAIN_USERNAME, "admin", 5));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (client, ZMQ_PLAIN_PASSWORD, "password", 8));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (client, my_endpoint));
|
||||
expect_bounce_fail (server, client);
|
||||
test_context_socket_close_zero_linger (client);
|
||||
}
|
||||
|
||||
// Unauthenticated messages from a vanilla socket shouldn't be received
|
||||
void test_vanilla_socket (void *ctx_,
|
||||
void *server_,
|
||||
void *server_mon_,
|
||||
char *endpoint_)
|
||||
void test_vanilla_socket ()
|
||||
{
|
||||
struct sockaddr_in ip4addr;
|
||||
int s;
|
||||
unsigned short int port;
|
||||
int rc = sscanf (endpoint_, "tcp://127.0.0.1:%hu", &port);
|
||||
assert (rc == 1);
|
||||
int rc = sscanf (my_endpoint, "tcp://127.0.0.1:%hu", &port);
|
||||
TEST_ASSERT_EQUAL_INT (1, rc);
|
||||
ip4addr.sin_family = AF_INET;
|
||||
ip4addr.sin_port = htons (port);
|
||||
#if defined(ZMQ_HAVE_WINDOWS) && (_WIN32_WINNT < 0x0600)
|
||||
@ -258,95 +303,34 @@ void test_vanilla_socket (void *ctx_,
|
||||
|
||||
s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
rc = connect (s, (struct sockaddr *) &ip4addr, sizeof (ip4addr));
|
||||
assert (rc > -1);
|
||||
TEST_ASSERT_GREATER_THAN (-1, rc);
|
||||
// send anonymous ZMTP/1.0 greeting
|
||||
send (s, "\x01\x00", 2, 0);
|
||||
// send sneaky message that shouldn't be received
|
||||
send (s, "\x08\x00sneaky\0", 9, 0);
|
||||
int timeout = 250;
|
||||
zmq_setsockopt (server_, ZMQ_RCVTIMEO, &timeout, sizeof (timeout));
|
||||
char *buf = s_recv (server_);
|
||||
zmq_setsockopt (server, ZMQ_RCVTIMEO, &timeout, sizeof (timeout));
|
||||
char *buf = s_recv (server);
|
||||
if (buf != NULL) {
|
||||
printf ("Received unauthenticated message: %s\n", buf);
|
||||
assert (buf == NULL);
|
||||
TEST_ASSERT_NULL (buf);
|
||||
}
|
||||
close (s);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
if (!getenv ("KRB5_KTNAME") || !getenv ("KRB5_CLIENT_KTNAME")) {
|
||||
printf ("KRB5 environment unavailable, skipping test\n");
|
||||
return 77; // SKIP
|
||||
}
|
||||
// Avoid entanglements with user's credential cache
|
||||
setenv ("KRB5CCNAME", "MEMORY", 1);
|
||||
|
||||
setup_test_environment ();
|
||||
void *ctx = zmq_ctx_new ();
|
||||
assert (ctx);
|
||||
|
||||
size_t len = MAX_SOCKET_STRING;
|
||||
char my_endpoint[MAX_SOCKET_STRING];
|
||||
|
||||
// Spawn ZAP handler
|
||||
// We create and bind ZAP socket in main thread to avoid case
|
||||
// where child thread does not start up fast enough.
|
||||
void *handler = zmq_socket (ctx, ZMQ_REP);
|
||||
assert (handler);
|
||||
int rc = zmq_bind (handler, "inproc://zeromq.zap.01");
|
||||
assert (rc == 0);
|
||||
void *zap_thread = zmq_threadstart (&zap_handler, handler);
|
||||
|
||||
// Server socket will accept connections
|
||||
void *server = zmq_socket (ctx, ZMQ_DEALER);
|
||||
assert (server);
|
||||
int as_server = 1;
|
||||
rc = zmq_setsockopt (server, ZMQ_GSSAPI_SERVER, &as_server, sizeof (int));
|
||||
assert (rc == 0);
|
||||
rc = zmq_setsockopt (server, ZMQ_GSSAPI_PRINCIPAL, name, strlen (name) + 1);
|
||||
assert (rc == 0);
|
||||
int name_type = ZMQ_GSSAPI_NT_HOSTBASED;
|
||||
rc = zmq_setsockopt (server, ZMQ_GSSAPI_PRINCIPAL_NAMETYPE, &name_type,
|
||||
sizeof (name_type));
|
||||
assert (rc == 0);
|
||||
rc = zmq_bind (server, "tcp://127.0.0.1:*");
|
||||
assert (rc == 0);
|
||||
rc = zmq_getsockopt (server, ZMQ_LAST_ENDPOINT, my_endpoint, &len);
|
||||
assert (rc == 0);
|
||||
|
||||
// Monitor handshake events on the server
|
||||
rc = zmq_socket_monitor (server, "inproc://monitor-server",
|
||||
ZMQ_EVENT_HANDSHAKE_SUCCEEDED
|
||||
| ZMQ_EVENT_HANDSHAKE_FAILED_AUTH
|
||||
| ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL);
|
||||
assert (rc == 0);
|
||||
|
||||
// Create socket for collecting monitor events
|
||||
void *server_mon = NULL;
|
||||
server_mon = zmq_socket (ctx, ZMQ_PAIR);
|
||||
assert (server_mon);
|
||||
|
||||
// Connect it to the inproc endpoints so they'll get events
|
||||
rc = zmq_connect (server_mon, "inproc://monitor-server");
|
||||
assert (rc == 0);
|
||||
|
||||
// Attempt various connections
|
||||
test_valid_creds (ctx, server, server_mon, my_endpoint);
|
||||
test_null_creds (ctx, server, server_mon, my_endpoint);
|
||||
test_plain_creds (ctx, server, server_mon, my_endpoint);
|
||||
test_vanilla_socket (ctx, server, server_mon, my_endpoint);
|
||||
test_unauth_creds (ctx, server, server_mon, my_endpoint);
|
||||
|
||||
// Shutdown
|
||||
close_zero_linger (server_mon);
|
||||
rc = zmq_close (server);
|
||||
assert (rc == 0);
|
||||
rc = zmq_ctx_term (ctx);
|
||||
assert (rc == 0);
|
||||
|
||||
// Wait until ZAP handler terminates
|
||||
zmq_threadclose (zap_thread);
|
||||
|
||||
UNITY_BEGIN ();
|
||||
RUN_TEST (test_valid_creds);
|
||||
RUN_TEST (test_null_creds);
|
||||
RUN_TEST (test_plain_creds);
|
||||
RUN_TEST (test_vanilla_socket);
|
||||
RUN_TEST (test_unauth_creds);
|
||||
return UNITY_END ();
|
||||
return 0;
|
||||
}
|
||||
|
@ -42,6 +42,8 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
static void zap_handler (void *handler_)
|
||||
{
|
||||
// Process ZAP requests forever
|
||||
@ -56,8 +58,8 @@ static void zap_handler (void *handler_)
|
||||
char *routing_id = s_recv (handler_);
|
||||
char *mechanism = s_recv (handler_);
|
||||
|
||||
assert (streq (version, "1.0"));
|
||||
assert (streq (mechanism, "NULL"));
|
||||
TEST_ASSERT_EQUAL_STRING ("1.0", version);
|
||||
TEST_ASSERT_EQUAL_STRING ("NULL", mechanism);
|
||||
|
||||
s_sendmore (handler_, version);
|
||||
s_sendmore (handler_, sequence);
|
||||
|
@ -42,6 +42,9 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static void zap_handler (void *zap_)
|
||||
{
|
||||
// Process ZAP requests forever
|
||||
@ -57,9 +60,9 @@ static void zap_handler (void *zap_)
|
||||
char *username = s_recv (zap_);
|
||||
char *password = s_recv (zap_);
|
||||
|
||||
assert (streq (version, "1.0"));
|
||||
assert (streq (mechanism, "PLAIN"));
|
||||
assert (streq (routing_id, "IDENT"));
|
||||
TEST_ASSERT_EQUAL_STRING ("1.0", version);
|
||||
TEST_ASSERT_EQUAL_STRING ("PLAIN", mechanism);
|
||||
TEST_ASSERT_EQUAL_STRING ("IDENT", routing_id);
|
||||
|
||||
s_sendmore (zap_, version);
|
||||
s_sendmore (zap_, sequence);
|
||||
@ -83,8 +86,7 @@ static void zap_handler (void *zap_)
|
||||
free (username);
|
||||
free (password);
|
||||
}
|
||||
int rc = zmq_close (zap_);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_close (zap_));
|
||||
}
|
||||
|
||||
void *zap_thread;
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
}
|
||||
|
@ -30,6 +30,9 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unity.h>
|
||||
|
||||
void setUp ()
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unity.h>
|
||||
|
||||
void setUp ()
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <string.h>
|
||||
#include <unity.h>
|
||||
|
||||
void setUp ()
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
|
@ -30,6 +30,14 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
|
@ -30,6 +30,9 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
|
@ -28,6 +28,7 @@
|
||||
*/
|
||||
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#if defined(ZMQ_HAVE_WINDOWS)
|
||||
#include <winsock2.h>
|
||||
@ -38,6 +39,16 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
}
|
||||
|
||||
void tearDown ()
|
||||
{
|
||||
teardown_test_context ();
|
||||
}
|
||||
|
||||
// Solaris has a default of 256 max files per process
|
||||
#ifdef ZMQ_HAVE_SOLARIS
|
||||
#define MAX_SOCKETS 200
|
||||
@ -62,6 +73,43 @@ void initialise_network (void)
|
||||
|
||||
#endif
|
||||
|
||||
void test_localhost ()
|
||||
{
|
||||
// Check that we have local networking via ZeroMQ
|
||||
void *dealer = test_context_socket (ZMQ_DEALER);
|
||||
if (zmq_bind (dealer, "tcp://127.0.0.1:*") == -1) {
|
||||
TEST_FAIL_MESSAGE (
|
||||
"E: Cannot find 127.0.0.1 -- your system does not have local\n"
|
||||
"E: networking. Please fix this before running libzmq checks.\n");
|
||||
}
|
||||
|
||||
test_context_socket_close (dealer);
|
||||
}
|
||||
|
||||
void test_max_sockets ()
|
||||
{
|
||||
// Check that we can create 1,000 sockets
|
||||
fd_t handle[MAX_SOCKETS];
|
||||
int count;
|
||||
for (count = 0; count < MAX_SOCKETS; count++) {
|
||||
handle[count] = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (handle[count] == -1) {
|
||||
printf ("W: Only able to create %d sockets on this box\n", count);
|
||||
const char msg[] =
|
||||
"I: Tune your system to increase maximum allowed file handles\n"
|
||||
#if !defined(ZMQ_HAVE_WINDOWS)
|
||||
"I: Run 'ulimit -n 1200' in bash\n"
|
||||
#endif
|
||||
;
|
||||
TEST_FAIL_MESSAGE (msg);
|
||||
}
|
||||
}
|
||||
// Release the socket handles
|
||||
for (count = 0; count < MAX_SOCKETS; count++) {
|
||||
close (handle[count]);
|
||||
}
|
||||
}
|
||||
|
||||
// This test case stresses the system to shake out known configuration
|
||||
// problems. We're direct system calls when necessary. Some code may
|
||||
// need wrapping to be properly portable.
|
||||
@ -70,37 +118,8 @@ int main (void)
|
||||
{
|
||||
initialise_network ();
|
||||
|
||||
// Check that we have local networking via ZeroMQ
|
||||
void *ctx = zmq_ctx_new ();
|
||||
assert (ctx);
|
||||
void *dealer = zmq_socket (ctx, ZMQ_DEALER);
|
||||
if (zmq_bind (dealer, "tcp://127.0.0.1:*") == -1) {
|
||||
printf (
|
||||
"E: Cannot find 127.0.0.1 -- your system does not have local\n");
|
||||
printf (
|
||||
"E: networking. Please fix this before running libzmq checks.\n");
|
||||
return -1;
|
||||
}
|
||||
// Check that we can create 1,000 sockets
|
||||
fd_t handle[MAX_SOCKETS];
|
||||
int count;
|
||||
for (count = 0; count < MAX_SOCKETS; count++) {
|
||||
handle[count] = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (handle[count] == -1) {
|
||||
printf ("W: Only able to create %d sockets on this box\n", count);
|
||||
printf (
|
||||
"I: Tune your system to increase maximum allowed file handles\n");
|
||||
#if !defined(ZMQ_HAVE_WINDOWS)
|
||||
printf ("I: Run 'ulimit -n 1200' in bash\n");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
// Release the socket handles
|
||||
for (count = 0; count < MAX_SOCKETS; count++) {
|
||||
close (handle[count]);
|
||||
}
|
||||
|
||||
zmq_close (dealer);
|
||||
zmq_ctx_term (ctx);
|
||||
UNITY_BEGIN ();
|
||||
RUN_TEST (test_localhost);
|
||||
RUN_TEST (test_max_sockets);
|
||||
return UNITY_END ();
|
||||
}
|
||||
|
@ -28,98 +28,84 @@
|
||||
*/
|
||||
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
int main (void)
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
}
|
||||
|
||||
void tearDown ()
|
||||
{
|
||||
teardown_test_context ();
|
||||
}
|
||||
|
||||
const char ep[] = "tipc://{5560,0,0}";
|
||||
const char name[] = "tipc://{5560,0}@0.0.0";
|
||||
|
||||
void test_term_endpoint_unbind_tipc ()
|
||||
{
|
||||
if (!is_tipc_available ()) {
|
||||
printf ("TIPC environment unavailable, skipping test\n");
|
||||
return 77;
|
||||
TEST_IGNORE_MESSAGE ("TIPC environment unavailable, skipping test\n");
|
||||
}
|
||||
|
||||
int rc;
|
||||
char buf[32];
|
||||
const char *ep = "tipc://{5560,0,0}";
|
||||
const char *name = "tipc://{5560,0}@0.0.0";
|
||||
|
||||
fprintf (stderr, "unbind endpoint test running...\n");
|
||||
|
||||
// Create infrastructure.
|
||||
void *ctx = zmq_init (1);
|
||||
assert (ctx);
|
||||
void *push = zmq_socket (ctx, ZMQ_PUSH);
|
||||
assert (push);
|
||||
rc = zmq_bind (push, ep);
|
||||
assert (rc == 0);
|
||||
void *pull = zmq_socket (ctx, ZMQ_PULL);
|
||||
assert (pull);
|
||||
rc = zmq_connect (pull, name);
|
||||
assert (rc == 0);
|
||||
void *push = test_context_socket (ZMQ_PUSH);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (push, ep));
|
||||
void *pull = test_context_socket (ZMQ_PULL);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (pull, name));
|
||||
|
||||
// Pass one message through to ensure the connection is established.
|
||||
rc = zmq_send (push, "ABC", 3, 0);
|
||||
assert (rc == 3);
|
||||
rc = zmq_recv (pull, buf, sizeof (buf), 0);
|
||||
assert (rc == 3);
|
||||
send_string_expect_success (push, "ABC", 0);
|
||||
recv_string_expect_success (pull, "ABC", 0);
|
||||
|
||||
// Unbind the lisnening endpoint
|
||||
rc = zmq_unbind (push, ep);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_unbind (push, ep));
|
||||
|
||||
// Let events some time
|
||||
msleep (SETTLE_TIME);
|
||||
|
||||
// Check that sending would block (there's no outbound connection).
|
||||
rc = zmq_send (push, "ABC", 3, ZMQ_DONTWAIT);
|
||||
assert (rc == -1 && zmq_errno () == EAGAIN);
|
||||
TEST_ASSERT_FAILURE_ERRNO (EAGAIN, zmq_send (push, "ABC", 3, ZMQ_DONTWAIT));
|
||||
|
||||
// Clean up.
|
||||
rc = zmq_close (pull);
|
||||
assert (rc == 0);
|
||||
rc = zmq_close (push);
|
||||
assert (rc == 0);
|
||||
rc = zmq_ctx_term (ctx);
|
||||
assert (rc == 0);
|
||||
|
||||
|
||||
// Now the other way round.
|
||||
fprintf (stderr, "disconnect endpoint test running...\n");
|
||||
test_context_socket_close (pull);
|
||||
test_context_socket_close (push);
|
||||
}
|
||||
|
||||
void test_term_endpoint_disconnect_tipc ()
|
||||
{
|
||||
if (!is_tipc_available ()) {
|
||||
TEST_IGNORE_MESSAGE ("TIPC environment unavailable, skipping test\n");
|
||||
}
|
||||
|
||||
// Create infrastructure.
|
||||
ctx = zmq_init (1);
|
||||
assert (ctx);
|
||||
push = zmq_socket (ctx, ZMQ_PUSH);
|
||||
assert (push);
|
||||
rc = zmq_connect (push, name);
|
||||
assert (rc == 0);
|
||||
pull = zmq_socket (ctx, ZMQ_PULL);
|
||||
assert (pull);
|
||||
rc = zmq_bind (pull, ep);
|
||||
assert (rc == 0);
|
||||
void *push = test_context_socket (ZMQ_PUSH);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (push, name));
|
||||
void *pull = test_context_socket (ZMQ_PULL);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (pull, ep));
|
||||
|
||||
// Pass one message through to ensure the connection is established.
|
||||
rc = zmq_send (push, "ABC", 3, 0);
|
||||
assert (rc == 3);
|
||||
rc = zmq_recv (pull, buf, sizeof (buf), 0);
|
||||
assert (rc == 3);
|
||||
send_string_expect_success (push, "ABC", 0);
|
||||
recv_string_expect_success (pull, "ABC", 0);
|
||||
|
||||
// Disconnect the bound endpoint
|
||||
rc = zmq_disconnect (push, name);
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_disconnect (push, name));
|
||||
|
||||
msleep (SETTLE_TIME);
|
||||
|
||||
// Check that sending would block (there's no inbound connections).
|
||||
rc = zmq_send (push, "ABC", 3, ZMQ_DONTWAIT);
|
||||
assert (rc == -1 && zmq_errno () == EAGAIN);
|
||||
TEST_ASSERT_FAILURE_ERRNO (EAGAIN, zmq_send (push, "ABC", 3, ZMQ_DONTWAIT));
|
||||
|
||||
// Clean up.
|
||||
rc = zmq_close (pull);
|
||||
assert (rc == 0);
|
||||
rc = zmq_close (push);
|
||||
assert (rc == 0);
|
||||
rc = zmq_ctx_term (ctx);
|
||||
assert (rc == 0);
|
||||
|
||||
return 0;
|
||||
test_context_socket_close (pull);
|
||||
test_context_socket_close (push);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
UNITY_BEGIN ();
|
||||
RUN_TEST (test_term_endpoint_unbind_tipc);
|
||||
RUN_TEST (test_term_endpoint_disconnect_tipc);
|
||||
return UNITY_END ();
|
||||
}
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
|
@ -30,7 +30,10 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unity.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
@ -47,6 +50,7 @@ void tearDown ()
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int setup_socket_and_set_fd (void *zmq_socket_,
|
||||
int af_,
|
||||
|
@ -31,8 +31,13 @@
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <unity.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
setup_test_context ();
|
||||
|
389
tests/testutil.cpp
Normal file
389
tests/testutil.cpp
Normal file
@ -0,0 +1,389 @@
|
||||
/*
|
||||
Copyright (c) 2007-2019 Contributors as noted in the AUTHORS file
|
||||
|
||||
This file is part of libzmq, the ZeroMQ core engine in C++.
|
||||
|
||||
libzmq is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License (LGPL) as published
|
||||
by the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
As a special exception, the Contributors give you permission to link
|
||||
this library with independent modules to produce an executable,
|
||||
regardless of the license terms of these independent modules, and to
|
||||
copy and distribute the resulting executable under terms of your choice,
|
||||
provided that you also meet, for each linked independent module, the
|
||||
terms and conditions of the license of that module. An independent
|
||||
module is a module which is not derived from or based on this library.
|
||||
If you modify this library, you must extend this exception to your
|
||||
version of the library.
|
||||
|
||||
libzmq is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined _WIN32
|
||||
#include "../src/windows.hpp"
|
||||
#if defined _MSC_VER
|
||||
#include <crtdbg.h>
|
||||
#pragma warning(disable : 4996)
|
||||
// iphlpapi is needed for if_nametoindex (not on Windows XP)
|
||||
#if !defined ZMQ_HAVE_WINDOWS_TARGET_XP
|
||||
#pragma comment(lib, "iphlpapi")
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <grp.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
#include <netdb.h>
|
||||
#if defined(ZMQ_HAVE_AIX)
|
||||
#include <sys/types.h>
|
||||
#include <sys/socketvar.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
const char *SEQ_END = (const char *) 1;
|
||||
|
||||
const char bounce_content[] = "12345678ABCDEFGH12345678abcdefgh";
|
||||
|
||||
static void send_bounce_msg (void *socket_)
|
||||
{
|
||||
send_string_expect_success (socket_, bounce_content, ZMQ_SNDMORE);
|
||||
send_string_expect_success (socket_, bounce_content, 0);
|
||||
}
|
||||
|
||||
static void recv_bounce_msg (void *socket_)
|
||||
{
|
||||
recv_string_expect_success (socket_, bounce_content, 0);
|
||||
int rcvmore;
|
||||
size_t sz = sizeof (rcvmore);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_getsockopt (socket_, ZMQ_RCVMORE, &rcvmore, &sz));
|
||||
TEST_ASSERT_TRUE (rcvmore);
|
||||
recv_string_expect_success (socket_, bounce_content, 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_getsockopt (socket_, ZMQ_RCVMORE, &rcvmore, &sz));
|
||||
TEST_ASSERT_FALSE (rcvmore);
|
||||
}
|
||||
|
||||
void bounce (void *server_, void *client_)
|
||||
{
|
||||
// Send message from client to server
|
||||
send_bounce_msg (client_);
|
||||
|
||||
// Receive message at server side and
|
||||
// check that message is still the same
|
||||
recv_bounce_msg (server_);
|
||||
|
||||
// Send two parts back to client
|
||||
send_bounce_msg (server_);
|
||||
|
||||
// Receive the two parts at the client side
|
||||
recv_bounce_msg (client_);
|
||||
}
|
||||
|
||||
static void send_bounce_msg_may_fail (void *socket_)
|
||||
{
|
||||
int timeout = 250;
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (socket_, ZMQ_SNDTIMEO, &timeout, sizeof (int)));
|
||||
int rc = zmq_send (socket_, bounce_content, 32, ZMQ_SNDMORE);
|
||||
TEST_ASSERT_TRUE ((rc == 32) || ((rc == -1) && (errno == EAGAIN)));
|
||||
rc = zmq_send (socket_, bounce_content, 32, 0);
|
||||
TEST_ASSERT_TRUE ((rc == 32) || ((rc == -1) && (errno == EAGAIN)));
|
||||
}
|
||||
|
||||
static void recv_bounce_msg_fail (void *socket_)
|
||||
{
|
||||
int timeout = 250;
|
||||
char buffer[32];
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (socket_, ZMQ_RCVTIMEO, &timeout, sizeof (int)));
|
||||
TEST_ASSERT_FAILURE_ERRNO (EAGAIN, zmq_recv (socket_, buffer, 32, 0));
|
||||
}
|
||||
|
||||
void expect_bounce_fail (void *server_, void *client_)
|
||||
{
|
||||
// Send message from client to server
|
||||
send_bounce_msg_may_fail (client_);
|
||||
|
||||
// Receive message at server side (should not succeed)
|
||||
recv_bounce_msg_fail (server_);
|
||||
|
||||
// Send message from server to client to test other direction
|
||||
// If connection failed, send may block, without a timeout
|
||||
send_bounce_msg_may_fail (server_);
|
||||
|
||||
// Receive message at client side (should not succeed)
|
||||
recv_bounce_msg_fail (client_);
|
||||
}
|
||||
|
||||
char *s_recv (void *socket_)
|
||||
{
|
||||
char buffer[256];
|
||||
int size = zmq_recv (socket_, buffer, 255, 0);
|
||||
if (size == -1)
|
||||
return NULL;
|
||||
if (size > 255)
|
||||
size = 255;
|
||||
buffer[size] = 0;
|
||||
return strdup (buffer);
|
||||
}
|
||||
|
||||
int s_send (void *socket_, const char *string_)
|
||||
{
|
||||
int size = zmq_send (socket_, string_, strlen (string_), 0);
|
||||
return size;
|
||||
}
|
||||
|
||||
int s_sendmore (void *socket_, const char *string_)
|
||||
{
|
||||
int size = zmq_send (socket_, string_, strlen (string_), ZMQ_SNDMORE);
|
||||
return size;
|
||||
}
|
||||
|
||||
void s_send_seq (void *socket_, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, socket_);
|
||||
const char *data = va_arg (ap, const char *);
|
||||
while (true) {
|
||||
const char *prev = data;
|
||||
data = va_arg (ap, const char *);
|
||||
bool end = data == SEQ_END;
|
||||
|
||||
if (!prev) {
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_send (socket_, 0, 0, end ? 0 : ZMQ_SNDMORE));
|
||||
} else {
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_send (
|
||||
socket_, prev, strlen (prev) + 1, end ? 0 : ZMQ_SNDMORE));
|
||||
}
|
||||
if (end)
|
||||
break;
|
||||
}
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
void s_recv_seq (void *socket_, ...)
|
||||
{
|
||||
zmq_msg_t msg;
|
||||
zmq_msg_init (&msg);
|
||||
|
||||
int more;
|
||||
size_t more_size = sizeof (more);
|
||||
|
||||
va_list ap;
|
||||
va_start (ap, socket_);
|
||||
const char *data = va_arg (ap, const char *);
|
||||
|
||||
while (true) {
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_recv (&msg, socket_, 0));
|
||||
|
||||
if (!data)
|
||||
TEST_ASSERT_EQUAL_INT (0, zmq_msg_size (&msg));
|
||||
else
|
||||
TEST_ASSERT_EQUAL_STRING (data, (const char *) zmq_msg_data (&msg));
|
||||
|
||||
data = va_arg (ap, const char *);
|
||||
bool end = data == SEQ_END;
|
||||
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_getsockopt (socket_, ZMQ_RCVMORE, &more, &more_size));
|
||||
|
||||
TEST_ASSERT_TRUE (!more == end);
|
||||
if (end)
|
||||
break;
|
||||
}
|
||||
va_end (ap);
|
||||
|
||||
zmq_msg_close (&msg);
|
||||
}
|
||||
|
||||
void close_zero_linger (void *socket_)
|
||||
{
|
||||
int linger = 0;
|
||||
int rc = zmq_setsockopt (socket_, ZMQ_LINGER, &linger, sizeof (linger));
|
||||
TEST_ASSERT_TRUE (rc == 0 || errno == ETERM);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_close (socket_));
|
||||
}
|
||||
|
||||
void setup_test_environment ()
|
||||
{
|
||||
#if defined _WIN32
|
||||
#if defined _MSC_VER
|
||||
_set_abort_behavior (0, _WRITE_ABORT_MSG);
|
||||
_CrtSetReportMode (_CRT_ASSERT, _CRTDBG_MODE_FILE);
|
||||
_CrtSetReportFile (_CRT_ASSERT, _CRTDBG_FILE_STDERR);
|
||||
#endif
|
||||
#else
|
||||
#if defined ZMQ_HAVE_CYGWIN
|
||||
// abort test after 121 seconds
|
||||
alarm (121);
|
||||
#else
|
||||
#if !defined ZMQ_DISABLE_TEST_TIMEOUT
|
||||
// abort test after 60 seconds
|
||||
alarm (60);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if defined __MVS__
|
||||
// z/OS UNIX System Services: Ignore SIGPIPE during test runs, as a
|
||||
// workaround for no SO_NOGSIGPIPE socket option.
|
||||
signal (SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
}
|
||||
|
||||
void msleep (int milliseconds_)
|
||||
{
|
||||
#ifdef ZMQ_HAVE_WINDOWS
|
||||
Sleep (milliseconds_);
|
||||
#else
|
||||
usleep (static_cast<useconds_t> (milliseconds_) * 1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
int is_ipv6_available ()
|
||||
{
|
||||
#if defined(ZMQ_HAVE_WINDOWS) && (_WIN32_WINNT < 0x0600)
|
||||
return 0;
|
||||
#else
|
||||
int rc, ipv6 = 1;
|
||||
struct sockaddr_in6 test_addr;
|
||||
|
||||
memset (&test_addr, 0, sizeof (test_addr));
|
||||
test_addr.sin6_family = AF_INET6;
|
||||
inet_pton (AF_INET6, "::1", &(test_addr.sin6_addr));
|
||||
|
||||
fd_t fd = socket (AF_INET6, SOCK_STREAM, IPPROTO_IP);
|
||||
if (fd == retired_fd)
|
||||
ipv6 = 0;
|
||||
else {
|
||||
#ifdef ZMQ_HAVE_WINDOWS
|
||||
setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (const char *) &ipv6,
|
||||
sizeof (int));
|
||||
rc = setsockopt (fd, IPPROTO_IPV6, IPV6_V6ONLY, (const char *) &ipv6,
|
||||
sizeof (int));
|
||||
if (rc == SOCKET_ERROR)
|
||||
ipv6 = 0;
|
||||
else {
|
||||
rc = bind (fd, (struct sockaddr *) &test_addr, sizeof (test_addr));
|
||||
if (rc == SOCKET_ERROR)
|
||||
ipv6 = 0;
|
||||
}
|
||||
#else
|
||||
setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &ipv6, sizeof (int));
|
||||
rc = setsockopt (fd, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6, sizeof (int));
|
||||
if (rc != 0)
|
||||
ipv6 = 0;
|
||||
else {
|
||||
rc = bind (fd, (struct sockaddr *) &test_addr, sizeof (test_addr));
|
||||
if (rc != 0)
|
||||
ipv6 = 0;
|
||||
}
|
||||
#endif
|
||||
close (fd);
|
||||
}
|
||||
|
||||
return ipv6;
|
||||
#endif // _WIN32_WINNT < 0x0600
|
||||
}
|
||||
|
||||
int is_tipc_available ()
|
||||
{
|
||||
#ifndef ZMQ_HAVE_TIPC
|
||||
return 0;
|
||||
#else
|
||||
int tipc = 0;
|
||||
|
||||
void *ctx = zmq_init (1);
|
||||
TEST_ASSERT_NOT_NULL (ctx);
|
||||
void *rep = zmq_socket (ctx, ZMQ_REP);
|
||||
TEST_ASSERT_NOT_NULL (rep);
|
||||
tipc = zmq_bind (rep, "tipc://{5560,0,0}");
|
||||
|
||||
zmq_close (rep);
|
||||
zmq_ctx_term (ctx);
|
||||
|
||||
return tipc == 0;
|
||||
#endif // ZMQ_HAVE_TIPC
|
||||
}
|
||||
|
||||
int test_inet_pton (int af_, const char *src_, void *dst_)
|
||||
{
|
||||
#if defined(ZMQ_HAVE_WINDOWS) && (_WIN32_WINNT < 0x0600)
|
||||
if (af_ == AF_INET) {
|
||||
struct in_addr *ip4addr = (struct in_addr *) dst_;
|
||||
|
||||
ip4addr->s_addr = inet_addr (src_);
|
||||
|
||||
// INADDR_NONE is -1 which is also a valid representation for IP
|
||||
// 255.255.255.255
|
||||
if (ip4addr->s_addr == INADDR_NONE
|
||||
&& strcmp (src_, "255.255.255.255") != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Success
|
||||
return 1;
|
||||
} else {
|
||||
// Not supported.
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
return inet_pton (af_, src_, dst_);
|
||||
#endif
|
||||
}
|
||||
|
||||
sockaddr_in bind_bsd_socket (int socket)
|
||||
{
|
||||
struct sockaddr_in saddr;
|
||||
memset (&saddr, 0, sizeof (saddr));
|
||||
saddr.sin_family = AF_INET;
|
||||
saddr.sin_addr.s_addr = INADDR_ANY;
|
||||
#if !defined(_WIN32_WINNT) || (_WIN32_WINNT >= 0x0600)
|
||||
saddr.sin_port = 0;
|
||||
#else
|
||||
saddr.sin_port = htons (PORT_6);
|
||||
#endif
|
||||
|
||||
TEST_ASSERT_SUCCESS_RAW_ERRNO (
|
||||
bind (socket, (struct sockaddr *) &saddr, sizeof (saddr)));
|
||||
|
||||
#if !defined(_WIN32_WINNT) || (_WIN32_WINNT >= 0x0600)
|
||||
socklen_t saddr_len = sizeof (saddr);
|
||||
TEST_ASSERT_SUCCESS_RAW_ERRNO (
|
||||
getsockname (socket, (struct sockaddr *) &saddr, &saddr_len));
|
||||
#endif
|
||||
|
||||
return saddr;
|
||||
}
|
||||
|
||||
bool streq (const char *lhs, const char *rhs)
|
||||
{
|
||||
return strcmp (lhs, rhs) == 0;
|
||||
}
|
||||
|
||||
bool strneq (const char *lhs, const char *rhs)
|
||||
{
|
||||
return strcmp (lhs, rhs) != 0;
|
||||
}
|
@ -58,40 +58,6 @@
|
||||
#define PORT_6 5561
|
||||
|
||||
#undef NDEBUG
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
|
||||
#if defined _WIN32
|
||||
#include "../src/windows.hpp"
|
||||
#if defined _MSC_VER
|
||||
#include <crtdbg.h>
|
||||
#pragma warning(disable : 4996)
|
||||
// iphlpapi is needed for if_nametoindex (not on Windows XP)
|
||||
#if !defined ZMQ_HAVE_WINDOWS_TARGET_XP
|
||||
#pragma comment(lib, "iphlpapi")
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <grp.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
#include <netdb.h>
|
||||
#if defined(ZMQ_HAVE_AIX)
|
||||
#include <sys/types.h>
|
||||
#include <sys/socketvar.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// duplicated from fd.hpp
|
||||
#ifdef ZMQ_HAVE_WINDOWS
|
||||
@ -100,7 +66,7 @@
|
||||
#include <stdexcept>
|
||||
#define close closesocket
|
||||
typedef int socket_size_t;
|
||||
const char *as_setsockopt_opt_t (const void *opt)
|
||||
inline const char *as_setsockopt_opt_t (const void *opt)
|
||||
{
|
||||
return static_cast<const char *> (opt);
|
||||
}
|
||||
@ -119,7 +85,7 @@ enum
|
||||
#endif
|
||||
#else
|
||||
typedef size_t socket_size_t;
|
||||
const void *as_setsockopt_opt_t (const void *opt_)
|
||||
inline const void *as_setsockopt_opt_t (const void *opt_)
|
||||
{
|
||||
return opt_;
|
||||
}
|
||||
@ -134,373 +100,67 @@ enum
|
||||
|
||||
// Bounce a message from client to server and back
|
||||
// For REQ/REP or DEALER/DEALER pairs only
|
||||
void bounce (void *server_, void *client_)
|
||||
{
|
||||
const char *content = "12345678ABCDEFGH12345678abcdefgh";
|
||||
|
||||
// Send message from client to server
|
||||
int rc = zmq_send (client_, content, 32, ZMQ_SNDMORE);
|
||||
assert (rc == 32);
|
||||
rc = zmq_send (client_, content, 32, 0);
|
||||
assert (rc == 32);
|
||||
|
||||
// Receive message at server side
|
||||
char buffer[32];
|
||||
rc = zmq_recv (server_, buffer, 32, 0);
|
||||
assert (rc == 32);
|
||||
// Check that message is still the same
|
||||
assert (memcmp (buffer, content, 32) == 0);
|
||||
int rcvmore;
|
||||
size_t sz = sizeof (rcvmore);
|
||||
rc = zmq_getsockopt (server_, ZMQ_RCVMORE, &rcvmore, &sz);
|
||||
assert (rc == 0);
|
||||
assert (rcvmore);
|
||||
rc = zmq_recv (server_, buffer, 32, 0);
|
||||
assert (rc == 32);
|
||||
// Check that message is still the same
|
||||
assert (memcmp (buffer, content, 32) == 0);
|
||||
rc = zmq_getsockopt (server_, ZMQ_RCVMORE, &rcvmore, &sz);
|
||||
assert (rc == 0);
|
||||
assert (!rcvmore);
|
||||
|
||||
// Send two parts back to client
|
||||
rc = zmq_send (server_, buffer, 32, ZMQ_SNDMORE);
|
||||
assert (rc == 32);
|
||||
rc = zmq_send (server_, buffer, 32, 0);
|
||||
assert (rc == 32);
|
||||
|
||||
// Receive the two parts at the client side
|
||||
rc = zmq_recv (client_, buffer, 32, 0);
|
||||
assert (rc == 32);
|
||||
// Check that message is still the same
|
||||
assert (memcmp (buffer, content, 32) == 0);
|
||||
rc = zmq_getsockopt (client_, ZMQ_RCVMORE, &rcvmore, &sz);
|
||||
assert (rc == 0);
|
||||
assert (rcvmore);
|
||||
rc = zmq_recv (client_, buffer, 32, 0);
|
||||
assert (rc == 32);
|
||||
// Check that message is still the same
|
||||
assert (memcmp (buffer, content, 32) == 0);
|
||||
rc = zmq_getsockopt (client_, ZMQ_RCVMORE, &rcvmore, &sz);
|
||||
assert (rc == 0);
|
||||
assert (!rcvmore);
|
||||
}
|
||||
void bounce (void *server_, void *client_);
|
||||
|
||||
// Same as bounce, but expect messages to never arrive
|
||||
// for security or subscriber reasons.
|
||||
void expect_bounce_fail (void *server_, void *client_)
|
||||
{
|
||||
const char *content = "12345678ABCDEFGH12345678abcdefgh";
|
||||
char buffer[32];
|
||||
int timeout = 250;
|
||||
|
||||
// Send message from client to server
|
||||
int rc = zmq_setsockopt (client_, ZMQ_SNDTIMEO, &timeout, sizeof (int));
|
||||
assert (rc == 0);
|
||||
rc = zmq_send (client_, content, 32, ZMQ_SNDMORE);
|
||||
assert ((rc == 32) || ((rc == -1) && (errno == EAGAIN)));
|
||||
rc = zmq_send (client_, content, 32, 0);
|
||||
assert ((rc == 32) || ((rc == -1) && (errno == EAGAIN)));
|
||||
|
||||
// Receive message at server side (should not succeed)
|
||||
rc = zmq_setsockopt (server_, ZMQ_RCVTIMEO, &timeout, sizeof (int));
|
||||
assert (rc == 0);
|
||||
rc = zmq_recv (server_, buffer, 32, 0);
|
||||
assert (rc == -1);
|
||||
assert (zmq_errno () == EAGAIN);
|
||||
|
||||
// Send message from server to client to test other direction
|
||||
// If connection failed, send may block, without a timeout
|
||||
rc = zmq_setsockopt (server_, ZMQ_SNDTIMEO, &timeout, sizeof (int));
|
||||
assert (rc == 0);
|
||||
rc = zmq_send (server_, content, 32, ZMQ_SNDMORE);
|
||||
assert (rc == 32 || (rc == -1 && zmq_errno () == EAGAIN));
|
||||
rc = zmq_send (server_, content, 32, 0);
|
||||
assert (rc == 32 || (rc == -1 && zmq_errno () == EAGAIN));
|
||||
|
||||
// Receive message at client side (should not succeed)
|
||||
rc = zmq_setsockopt (client_, ZMQ_RCVTIMEO, &timeout, sizeof (int));
|
||||
assert (rc == 0);
|
||||
rc = zmq_recv (client_, buffer, 32, 0);
|
||||
assert (rc == -1);
|
||||
assert (zmq_errno () == EAGAIN);
|
||||
}
|
||||
void expect_bounce_fail (void *server_, void *client_);
|
||||
|
||||
// Receive 0MQ string from socket and convert into C string
|
||||
// Caller must free returned string. Returns NULL if the context
|
||||
// is being terminated.
|
||||
char *s_recv (void *socket_)
|
||||
{
|
||||
char buffer[256];
|
||||
int size = zmq_recv (socket_, buffer, 255, 0);
|
||||
if (size == -1)
|
||||
return NULL;
|
||||
if (size > 255)
|
||||
size = 255;
|
||||
buffer[size] = 0;
|
||||
return strdup (buffer);
|
||||
}
|
||||
char *s_recv (void *socket_);
|
||||
|
||||
// Convert C string to 0MQ string and send to socket
|
||||
int s_send (void *socket_, const char *string_)
|
||||
{
|
||||
int size = zmq_send (socket_, string_, strlen (string_), 0);
|
||||
return size;
|
||||
}
|
||||
int s_send (void *socket_, const char *string_);
|
||||
|
||||
// Sends string as 0MQ string, as multipart non-terminal
|
||||
int s_sendmore (void *socket_, const char *string_)
|
||||
{
|
||||
int size = zmq_send (socket_, string_, strlen (string_), ZMQ_SNDMORE);
|
||||
return size;
|
||||
}
|
||||
int s_sendmore (void *socket_, const char *string_);
|
||||
|
||||
#define streq(s1, s2) (!strcmp ((s1), (s2)))
|
||||
#define strneq(s1, s2) (strcmp ((s1), (s2)))
|
||||
bool streq (const char *lhs, const char *rhs);
|
||||
bool strneq (const char *lhs, const char *rhs);
|
||||
|
||||
const char *SEQ_END = (const char *) 1;
|
||||
extern const char *SEQ_END;
|
||||
|
||||
// Sends a message composed of frames that are C strings or null frames.
|
||||
// The list must be terminated by SEQ_END.
|
||||
// Example: s_send_seq (req, "ABC", 0, "DEF", SEQ_END);
|
||||
|
||||
void s_send_seq (void *socket_, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, socket_);
|
||||
const char *data = va_arg (ap, const char *);
|
||||
while (true) {
|
||||
const char *prev = data;
|
||||
data = va_arg (ap, const char *);
|
||||
bool end = data == SEQ_END;
|
||||
|
||||
if (!prev) {
|
||||
int rc = zmq_send (socket_, 0, 0, end ? 0 : ZMQ_SNDMORE);
|
||||
assert (rc != -1);
|
||||
} else {
|
||||
int rc = zmq_send (socket_, prev, strlen (prev) + 1,
|
||||
end ? 0 : ZMQ_SNDMORE);
|
||||
assert (rc != -1);
|
||||
}
|
||||
if (end)
|
||||
break;
|
||||
}
|
||||
va_end (ap);
|
||||
}
|
||||
void s_send_seq (void *socket_, ...);
|
||||
|
||||
// Receives message a number of frames long and checks that the frames have
|
||||
// the given data which can be either C strings or 0 for a null frame.
|
||||
// The list must be terminated by SEQ_END.
|
||||
// Example: s_recv_seq (rep, "ABC", 0, "DEF", SEQ_END);
|
||||
|
||||
void s_recv_seq (void *socket_, ...)
|
||||
{
|
||||
zmq_msg_t msg;
|
||||
zmq_msg_init (&msg);
|
||||
|
||||
int more;
|
||||
size_t more_size = sizeof (more);
|
||||
|
||||
va_list ap;
|
||||
va_start (ap, socket_);
|
||||
const char *data = va_arg (ap, const char *);
|
||||
|
||||
while (true) {
|
||||
int rc = zmq_msg_recv (&msg, socket_, 0);
|
||||
assert (rc != -1);
|
||||
|
||||
if (!data)
|
||||
assert (zmq_msg_size (&msg) == 0);
|
||||
else
|
||||
assert (strcmp (data, (const char *) zmq_msg_data (&msg)) == 0);
|
||||
|
||||
data = va_arg (ap, const char *);
|
||||
bool end = data == SEQ_END;
|
||||
|
||||
rc = zmq_getsockopt (socket_, ZMQ_RCVMORE, &more, &more_size);
|
||||
assert (rc == 0);
|
||||
|
||||
assert (!more == end);
|
||||
if (end)
|
||||
break;
|
||||
}
|
||||
va_end (ap);
|
||||
|
||||
zmq_msg_close (&msg);
|
||||
}
|
||||
void s_recv_seq (void *socket_, ...);
|
||||
|
||||
|
||||
// Sets a zero linger period on a socket and closes it.
|
||||
void close_zero_linger (void *socket_)
|
||||
{
|
||||
int linger = 0;
|
||||
int rc = zmq_setsockopt (socket_, ZMQ_LINGER, &linger, sizeof (linger));
|
||||
assert (rc == 0 || errno == ETERM);
|
||||
rc = zmq_close (socket_);
|
||||
assert (rc == 0);
|
||||
}
|
||||
void close_zero_linger (void *socket_);
|
||||
|
||||
void setup_test_environment (void)
|
||||
{
|
||||
#if defined _WIN32
|
||||
#if defined _MSC_VER
|
||||
_set_abort_behavior (0, _WRITE_ABORT_MSG);
|
||||
_CrtSetReportMode (_CRT_ASSERT, _CRTDBG_MODE_FILE);
|
||||
_CrtSetReportFile (_CRT_ASSERT, _CRTDBG_FILE_STDERR);
|
||||
#endif
|
||||
#else
|
||||
#if defined ZMQ_HAVE_CYGWIN
|
||||
// abort test after 121 seconds
|
||||
alarm (121);
|
||||
#else
|
||||
#if !defined ZMQ_DISABLE_TEST_TIMEOUT
|
||||
// abort test after 60 seconds
|
||||
alarm (60);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if defined __MVS__
|
||||
// z/OS UNIX System Services: Ignore SIGPIPE during test runs, as a
|
||||
// workaround for no SO_NOGSIGPIPE socket option.
|
||||
signal (SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
}
|
||||
void setup_test_environment (void);
|
||||
|
||||
// Provide portable millisecond sleep
|
||||
// http://www.cplusplus.com/forum/unices/60161/
|
||||
// http://en.cppreference.com/w/cpp/thread/sleep_for
|
||||
|
||||
void msleep (int milliseconds_)
|
||||
{
|
||||
#ifdef ZMQ_HAVE_WINDOWS
|
||||
Sleep (milliseconds_);
|
||||
#else
|
||||
usleep (static_cast<useconds_t> (milliseconds_) * 1000);
|
||||
#endif
|
||||
}
|
||||
void msleep (int milliseconds_);
|
||||
|
||||
// check if IPv6 is available (0/false if not, 1/true if it is)
|
||||
// only way to reliably check is to actually open a socket and try to bind it
|
||||
int is_ipv6_available (void)
|
||||
{
|
||||
#if defined(ZMQ_HAVE_WINDOWS) && (_WIN32_WINNT < 0x0600)
|
||||
return 0;
|
||||
#else
|
||||
int rc, ipv6 = 1;
|
||||
struct sockaddr_in6 test_addr;
|
||||
|
||||
memset (&test_addr, 0, sizeof (test_addr));
|
||||
test_addr.sin6_family = AF_INET6;
|
||||
inet_pton (AF_INET6, "::1", &(test_addr.sin6_addr));
|
||||
|
||||
fd_t fd = socket (AF_INET6, SOCK_STREAM, IPPROTO_IP);
|
||||
if (fd == retired_fd)
|
||||
ipv6 = 0;
|
||||
else {
|
||||
#ifdef ZMQ_HAVE_WINDOWS
|
||||
setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (const char *) &ipv6,
|
||||
sizeof (int));
|
||||
rc = setsockopt (fd, IPPROTO_IPV6, IPV6_V6ONLY, (const char *) &ipv6,
|
||||
sizeof (int));
|
||||
if (rc == SOCKET_ERROR)
|
||||
ipv6 = 0;
|
||||
else {
|
||||
rc = bind (fd, (struct sockaddr *) &test_addr, sizeof (test_addr));
|
||||
if (rc == SOCKET_ERROR)
|
||||
ipv6 = 0;
|
||||
}
|
||||
#else
|
||||
setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &ipv6, sizeof (int));
|
||||
rc = setsockopt (fd, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6, sizeof (int));
|
||||
if (rc != 0)
|
||||
ipv6 = 0;
|
||||
else {
|
||||
rc = bind (fd, (struct sockaddr *) &test_addr, sizeof (test_addr));
|
||||
if (rc != 0)
|
||||
ipv6 = 0;
|
||||
}
|
||||
#endif
|
||||
close (fd);
|
||||
}
|
||||
|
||||
return ipv6;
|
||||
#endif // _WIN32_WINNT < 0x0600
|
||||
}
|
||||
int is_ipv6_available (void);
|
||||
|
||||
// check if tipc is available (0/false if not, 1/true if it is)
|
||||
// only way to reliably check is to actually open a socket and try to bind it
|
||||
// as it depends on a non-default kernel module to be already loaded
|
||||
int is_tipc_available (void)
|
||||
{
|
||||
#ifndef ZMQ_HAVE_TIPC
|
||||
return 0;
|
||||
#else
|
||||
int tipc = 0;
|
||||
|
||||
void *ctx = zmq_init (1);
|
||||
assert (ctx);
|
||||
void *rep = zmq_socket (ctx, ZMQ_REP);
|
||||
assert (rep);
|
||||
tipc = zmq_bind (rep, "tipc://{5560,0,0}");
|
||||
|
||||
zmq_close (rep);
|
||||
zmq_ctx_term (ctx);
|
||||
|
||||
return tipc == 0;
|
||||
#endif // ZMQ_HAVE_TIPC
|
||||
}
|
||||
int is_tipc_available (void);
|
||||
|
||||
// Wrapper around 'inet_pton' for systems that don't support it (e.g. Windows
|
||||
// XP)
|
||||
int test_inet_pton (int af_, const char *src_, void *dst_)
|
||||
{
|
||||
#if defined(ZMQ_HAVE_WINDOWS) && (_WIN32_WINNT < 0x0600)
|
||||
if (af_ == AF_INET) {
|
||||
struct in_addr *ip4addr = (struct in_addr *) dst_;
|
||||
|
||||
ip4addr->s_addr = inet_addr (src_);
|
||||
|
||||
// INADDR_NONE is -1 which is also a valid representation for IP
|
||||
// 255.255.255.255
|
||||
if (ip4addr->s_addr == INADDR_NONE
|
||||
&& strcmp (src_, "255.255.255.255") != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Success
|
||||
return 1;
|
||||
} else {
|
||||
// Not supported.
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
return inet_pton (af_, src_, dst_);
|
||||
#endif
|
||||
}
|
||||
int test_inet_pton (int af_, const char *src_, void *dst_);
|
||||
|
||||
// Binds an ipv4 BSD socket to an ephemeral port, returns the compiled sockaddr
|
||||
struct sockaddr_in bind_bsd_socket (int socket)
|
||||
{
|
||||
struct sockaddr_in saddr;
|
||||
memset (&saddr, 0, sizeof (saddr));
|
||||
saddr.sin_family = AF_INET;
|
||||
saddr.sin_addr.s_addr = INADDR_ANY;
|
||||
#if !defined(_WIN32_WINNT) || (_WIN32_WINNT >= 0x0600)
|
||||
saddr.sin_port = 0;
|
||||
#else
|
||||
saddr.sin_port = htons (PORT_6);
|
||||
#endif
|
||||
|
||||
int rc = bind (socket, (struct sockaddr *) &saddr, sizeof (saddr));
|
||||
assert (rc == 0);
|
||||
|
||||
#if !defined(_WIN32_WINNT) || (_WIN32_WINNT >= 0x0600)
|
||||
socklen_t saddr_len = sizeof (saddr);
|
||||
rc = getsockname (socket, (struct sockaddr *) &saddr, &saddr_len);
|
||||
assert (rc == 0);
|
||||
#endif
|
||||
|
||||
return saddr;
|
||||
}
|
||||
struct sockaddr_in bind_bsd_socket (int socket);
|
||||
|
||||
#endif
|
||||
|
349
tests/testutil_monitoring.cpp
Normal file
349
tests/testutil_monitoring.cpp
Normal file
@ -0,0 +1,349 @@
|
||||
/*
|
||||
Copyright (c) 2007-2019 Contributors as noted in the AUTHORS file
|
||||
|
||||
This file is part of libzmq, the ZeroMQ core engine in C++.
|
||||
|
||||
libzmq is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License (LGPL) as published
|
||||
by the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
As a special exception, the Contributors give you permission to link
|
||||
this library with independent modules to produce an executable,
|
||||
regardless of the license terms of these independent modules, and to
|
||||
copy and distribute the resulting executable under terms of your choice,
|
||||
provided that you also meet, for each linked independent module, the
|
||||
terms and conditions of the license of that module. An independent
|
||||
module is a module which is not derived from or based on this library.
|
||||
If you modify this library, you must extend this exception to your
|
||||
version of the library.
|
||||
|
||||
libzmq is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "testutil_monitoring.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// 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_internal (void *monitor_,
|
||||
int *value_,
|
||||
char **address_,
|
||||
int recv_flag_)
|
||||
{
|
||||
// First frame in message contains event number and value
|
||||
zmq_msg_t msg;
|
||||
zmq_msg_init (&msg);
|
||||
if (zmq_msg_recv (&msg, monitor_, recv_flag_) == -1) {
|
||||
TEST_ASSERT_FAILURE_ERRNO (EAGAIN, -1);
|
||||
return -1; // timed out or no message available
|
||||
}
|
||||
TEST_ASSERT_TRUE (zmq_msg_more (&msg));
|
||||
|
||||
uint8_t *data = (uint8_t *) zmq_msg_data (&msg);
|
||||
uint16_t event = *(uint16_t *) (data);
|
||||
if (value_)
|
||||
memcpy (value_, data + 2, sizeof (uint32_t));
|
||||
|
||||
// Second frame in message contains event address
|
||||
zmq_msg_init (&msg);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_recv (&msg, monitor_, recv_flag_));
|
||||
TEST_ASSERT_FALSE (zmq_msg_more (&msg));
|
||||
|
||||
if (address_) {
|
||||
uint8_t *data = (uint8_t *) zmq_msg_data (&msg);
|
||||
size_t size = zmq_msg_size (&msg);
|
||||
*address_ = (char *) malloc (size + 1);
|
||||
memcpy (*address_, data, size);
|
||||
(*address_)[size] = 0;
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
int get_monitor_event_with_timeout (void *monitor_,
|
||||
int *value_,
|
||||
char **address_,
|
||||
int timeout_)
|
||||
{
|
||||
int res;
|
||||
if (timeout_ == -1) {
|
||||
// process infinite timeout in small steps to allow the user
|
||||
// to see some information on the console
|
||||
|
||||
int timeout_step = 250;
|
||||
int wait_time = 0;
|
||||
zmq_setsockopt (monitor_, ZMQ_RCVTIMEO, &timeout_step,
|
||||
sizeof (timeout_step));
|
||||
while (
|
||||
(res = get_monitor_event_internal (monitor_, value_, address_, 0))
|
||||
== -1) {
|
||||
wait_time += timeout_step;
|
||||
fprintf (stderr, "Still waiting for monitor event after %i ms\n",
|
||||
wait_time);
|
||||
}
|
||||
} else {
|
||||
zmq_setsockopt (monitor_, ZMQ_RCVTIMEO, &timeout_, sizeof (timeout_));
|
||||
res = get_monitor_event_internal (monitor_, value_, address_, 0);
|
||||
}
|
||||
int timeout_infinite = -1;
|
||||
zmq_setsockopt (monitor_, ZMQ_RCVTIMEO, &timeout_infinite,
|
||||
sizeof (timeout_infinite));
|
||||
return res;
|
||||
}
|
||||
|
||||
int get_monitor_event (void *monitor_, int *value_, char **address_)
|
||||
{
|
||||
return get_monitor_event_with_timeout (monitor_, value_, address_, -1);
|
||||
}
|
||||
|
||||
void expect_monitor_event (void *monitor_, int expected_event_)
|
||||
{
|
||||
TEST_ASSERT_EQUAL_HEX (expected_event_,
|
||||
get_monitor_event (monitor_, NULL, NULL));
|
||||
}
|
||||
|
||||
static void print_unexpected_event (char *buf_,
|
||||
size_t buf_size_,
|
||||
int event_,
|
||||
int err_,
|
||||
int expected_event_,
|
||||
int expected_err_)
|
||||
{
|
||||
snprintf (buf_, buf_size_,
|
||||
"Unexpected event: 0x%x, value = %i/0x%x (expected: 0x%x, value "
|
||||
"= %i/0x%x)\n",
|
||||
event_, err_, err_, expected_event_, expected_err_,
|
||||
expected_err_);
|
||||
}
|
||||
|
||||
void print_unexpected_event_stderr (int event_,
|
||||
int err_,
|
||||
int expected_event_,
|
||||
int expected_err_)
|
||||
{
|
||||
char buf[256];
|
||||
print_unexpected_event (buf, sizeof buf, event_, err_, expected_event_,
|
||||
expected_err_);
|
||||
fputs (buf, stderr);
|
||||
}
|
||||
|
||||
int expect_monitor_event_multiple (void *server_mon_,
|
||||
int expected_event_,
|
||||
int expected_err_,
|
||||
bool optional_)
|
||||
{
|
||||
int count_of_expected_events = 0;
|
||||
int client_closed_connection = 0;
|
||||
int timeout = 250;
|
||||
int wait_time = 0;
|
||||
|
||||
int event;
|
||||
int err;
|
||||
while ((event =
|
||||
get_monitor_event_with_timeout (server_mon_, &err, NULL, timeout))
|
||||
!= -1
|
||||
|| !count_of_expected_events) {
|
||||
if (event == -1) {
|
||||
if (optional_)
|
||||
break;
|
||||
wait_time += timeout;
|
||||
fprintf (stderr,
|
||||
"Still waiting for first event after %ims (expected event "
|
||||
"%x (value %i/0x%x))\n",
|
||||
wait_time, expected_event_, expected_err_, expected_err_);
|
||||
continue;
|
||||
}
|
||||
// ignore errors with EPIPE/ECONNRESET/ECONNABORTED, which can happen
|
||||
// ECONNRESET can happen on very slow machines, when the engine writes
|
||||
// to the peer and then tries to read the socket before the peer reads
|
||||
// ECONNABORTED happens when a client aborts a connection via RST/timeout
|
||||
if (event == ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL
|
||||
&& ((err == EPIPE && expected_err_ != EPIPE) || err == ECONNRESET
|
||||
|| err == ECONNABORTED)) {
|
||||
fprintf (stderr,
|
||||
"Ignored event (skipping any further events): %x (err = "
|
||||
"%i == %s)\n",
|
||||
event, err, zmq_strerror (err));
|
||||
client_closed_connection = 1;
|
||||
break;
|
||||
}
|
||||
if (event != expected_event_
|
||||
|| (-1 != expected_err_ && err != expected_err_)) {
|
||||
char buf[256];
|
||||
print_unexpected_event (buf, sizeof buf, event, err,
|
||||
expected_event_, expected_err_);
|
||||
TEST_FAIL_MESSAGE (buf);
|
||||
}
|
||||
++count_of_expected_events;
|
||||
}
|
||||
TEST_ASSERT_TRUE (optional_ || count_of_expected_events > 0
|
||||
|| client_closed_connection);
|
||||
|
||||
return count_of_expected_events;
|
||||
}
|
||||
|
||||
static int64_t get_monitor_event_internal_v2 (void *monitor_,
|
||||
uint64_t *value_,
|
||||
char **local_address_,
|
||||
char **remote_address_,
|
||||
int recv_flag_)
|
||||
{
|
||||
// First frame in message contains event number
|
||||
zmq_msg_t msg;
|
||||
zmq_msg_init (&msg);
|
||||
if (zmq_msg_recv (&msg, monitor_, recv_flag_) == -1) {
|
||||
TEST_ASSERT_FAILURE_ERRNO (EAGAIN, -1);
|
||||
return -1; // timed out or no message available
|
||||
}
|
||||
TEST_ASSERT_TRUE (zmq_msg_more (&msg));
|
||||
TEST_ASSERT_EQUAL_UINT (sizeof (uint64_t), zmq_msg_size (&msg));
|
||||
|
||||
uint64_t event;
|
||||
memcpy (&event, zmq_msg_data (&msg), sizeof (event));
|
||||
zmq_msg_close (&msg);
|
||||
|
||||
// Second frame in message contains the number of values
|
||||
zmq_msg_init (&msg);
|
||||
if (zmq_msg_recv (&msg, monitor_, recv_flag_) == -1) {
|
||||
TEST_ASSERT_FAILURE_ERRNO (EAGAIN, -1);
|
||||
return -1; // timed out or no message available
|
||||
}
|
||||
TEST_ASSERT_TRUE (zmq_msg_more (&msg));
|
||||
TEST_ASSERT_EQUAL_UINT (sizeof (uint64_t), zmq_msg_size (&msg));
|
||||
|
||||
uint64_t value_count;
|
||||
memcpy (&value_count, zmq_msg_data (&msg), sizeof (value_count));
|
||||
zmq_msg_close (&msg);
|
||||
|
||||
for (uint64_t i = 0; i < value_count; ++i) {
|
||||
// Subsequent frames in message contain event values
|
||||
zmq_msg_init (&msg);
|
||||
if (zmq_msg_recv (&msg, monitor_, recv_flag_) == -1) {
|
||||
TEST_ASSERT_FAILURE_ERRNO (EAGAIN, -1);
|
||||
return -1; // timed out or no message available
|
||||
}
|
||||
TEST_ASSERT_TRUE (zmq_msg_more (&msg));
|
||||
TEST_ASSERT_EQUAL_UINT (sizeof (uint64_t), zmq_msg_size (&msg));
|
||||
|
||||
if (value_ && value_ + i)
|
||||
memcpy (value_ + i, zmq_msg_data (&msg), sizeof (*value_));
|
||||
zmq_msg_close (&msg);
|
||||
}
|
||||
|
||||
// Second-to-last frame in message contains local address
|
||||
zmq_msg_init (&msg);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_recv (&msg, monitor_, recv_flag_));
|
||||
TEST_ASSERT_TRUE (zmq_msg_more (&msg));
|
||||
|
||||
if (local_address_) {
|
||||
uint8_t *data = (uint8_t *) zmq_msg_data (&msg);
|
||||
size_t size = zmq_msg_size (&msg);
|
||||
*local_address_ = (char *) malloc (size + 1);
|
||||
memcpy (*local_address_, data, size);
|
||||
(*local_address_)[size] = 0;
|
||||
}
|
||||
zmq_msg_close (&msg);
|
||||
|
||||
// Last frame in message contains remote address
|
||||
zmq_msg_init (&msg);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_recv (&msg, monitor_, recv_flag_));
|
||||
TEST_ASSERT_TRUE (!zmq_msg_more (&msg));
|
||||
|
||||
if (remote_address_) {
|
||||
uint8_t *data = (uint8_t *) zmq_msg_data (&msg);
|
||||
size_t size = zmq_msg_size (&msg);
|
||||
*remote_address_ = (char *) malloc (size + 1);
|
||||
memcpy (*remote_address_, data, size);
|
||||
(*remote_address_)[size] = 0;
|
||||
}
|
||||
zmq_msg_close (&msg);
|
||||
return event;
|
||||
}
|
||||
|
||||
static int64_t get_monitor_event_with_timeout_v2 (void *monitor_,
|
||||
uint64_t *value_,
|
||||
char **local_address_,
|
||||
char **remote_address_,
|
||||
int timeout_)
|
||||
{
|
||||
int64_t res;
|
||||
if (timeout_ == -1) {
|
||||
// process infinite timeout in small steps to allow the user
|
||||
// to see some information on the console
|
||||
|
||||
int timeout_step = 250;
|
||||
int wait_time = 0;
|
||||
zmq_setsockopt (monitor_, ZMQ_RCVTIMEO, &timeout_step,
|
||||
sizeof (timeout_step));
|
||||
while ((res = get_monitor_event_internal_v2 (
|
||||
monitor_, value_, local_address_, remote_address_, 0))
|
||||
== -1) {
|
||||
wait_time += timeout_step;
|
||||
fprintf (stderr, "Still waiting for monitor event after %i ms\n",
|
||||
wait_time);
|
||||
}
|
||||
} else {
|
||||
zmq_setsockopt (monitor_, ZMQ_RCVTIMEO, &timeout_, sizeof (timeout_));
|
||||
res = get_monitor_event_internal_v2 (monitor_, value_, local_address_,
|
||||
remote_address_, 0);
|
||||
}
|
||||
int timeout_infinite = -1;
|
||||
zmq_setsockopt (monitor_, ZMQ_RCVTIMEO, &timeout_infinite,
|
||||
sizeof (timeout_infinite));
|
||||
return res;
|
||||
}
|
||||
|
||||
int64_t get_monitor_event_v2 (void *monitor_,
|
||||
uint64_t *value_,
|
||||
char **local_address_,
|
||||
char **remote_address_)
|
||||
{
|
||||
return get_monitor_event_with_timeout_v2 (monitor_, value_, local_address_,
|
||||
remote_address_, -1);
|
||||
}
|
||||
|
||||
void expect_monitor_event_v2 (void *monitor_,
|
||||
int64_t expected_event_,
|
||||
const char *expected_local_address_,
|
||||
const char *expected_remote_address_)
|
||||
{
|
||||
char *local_address = NULL;
|
||||
char *remote_address = NULL;
|
||||
int64_t event = get_monitor_event_v2 (
|
||||
monitor_, NULL, expected_local_address_ ? &local_address : NULL,
|
||||
expected_remote_address_ ? &remote_address : NULL);
|
||||
bool failed = false;
|
||||
char buf[256];
|
||||
char *pos = buf;
|
||||
if (event != expected_event_) {
|
||||
pos += snprintf (pos, sizeof buf - (pos - buf),
|
||||
"Expected monitor event %llx, but received %llx\n",
|
||||
(long long) expected_event_, (long long) event);
|
||||
failed = true;
|
||||
}
|
||||
if (expected_local_address_
|
||||
&& 0 != strcmp (local_address, expected_local_address_)) {
|
||||
pos += snprintf (pos, sizeof buf - (pos - buf),
|
||||
"Expected local address %s, but received %s\n",
|
||||
expected_local_address_, local_address);
|
||||
}
|
||||
if (expected_remote_address_
|
||||
&& 0 != strcmp (remote_address, expected_remote_address_)) {
|
||||
pos += snprintf (pos, sizeof buf - (pos - buf),
|
||||
"Expected remote address %s, but received %s\n",
|
||||
expected_remote_address_, remote_address);
|
||||
}
|
||||
free (local_address);
|
||||
free (remote_address);
|
||||
TEST_ASSERT_FALSE_MESSAGE (failed, buf);
|
||||
}
|
@ -30,114 +30,26 @@
|
||||
#ifndef __TESTUTIL_MONITORING_HPP_INCLUDED__
|
||||
#define __TESTUTIL_MONITORING_HPP_INCLUDED__
|
||||
|
||||
#include "testutil_unity.hpp"
|
||||
#include "../include/zmq.h"
|
||||
#include "../src/stdint.hpp"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
// General, i.e. non-security specific, monitor utilities
|
||||
|
||||
// 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_internal (void *monitor_,
|
||||
int *value_,
|
||||
char **address_,
|
||||
int recv_flag_)
|
||||
{
|
||||
// First frame in message contains event number and value
|
||||
zmq_msg_t msg;
|
||||
zmq_msg_init (&msg);
|
||||
if (zmq_msg_recv (&msg, monitor_, recv_flag_) == -1) {
|
||||
TEST_ASSERT_FAILURE_ERRNO (EAGAIN, -1);
|
||||
return -1; // timed out or no message available
|
||||
}
|
||||
TEST_ASSERT_TRUE (zmq_msg_more (&msg));
|
||||
|
||||
uint8_t *data = (uint8_t *) zmq_msg_data (&msg);
|
||||
uint16_t event = *(uint16_t *) (data);
|
||||
if (value_)
|
||||
memcpy (value_, data + 2, sizeof (uint32_t));
|
||||
|
||||
// Second frame in message contains event address
|
||||
zmq_msg_init (&msg);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_recv (&msg, monitor_, recv_flag_));
|
||||
TEST_ASSERT_FALSE (zmq_msg_more (&msg));
|
||||
|
||||
if (address_) {
|
||||
uint8_t *data = (uint8_t *) zmq_msg_data (&msg);
|
||||
size_t size = zmq_msg_size (&msg);
|
||||
*address_ = (char *) malloc (size + 1);
|
||||
memcpy (*address_, data, size);
|
||||
(*address_)[size] = 0;
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
int get_monitor_event_with_timeout (void *monitor_,
|
||||
int *value_,
|
||||
char **address_,
|
||||
int timeout_)
|
||||
{
|
||||
int res;
|
||||
if (timeout_ == -1) {
|
||||
// process infinite timeout in small steps to allow the user
|
||||
// to see some information on the console
|
||||
int timeout_);
|
||||
|
||||
int timeout_step = 250;
|
||||
int wait_time = 0;
|
||||
zmq_setsockopt (monitor_, ZMQ_RCVTIMEO, &timeout_step,
|
||||
sizeof (timeout_step));
|
||||
while (
|
||||
(res = get_monitor_event_internal (monitor_, value_, address_, 0))
|
||||
== -1) {
|
||||
wait_time += timeout_step;
|
||||
fprintf (stderr, "Still waiting for monitor event after %i ms\n",
|
||||
wait_time);
|
||||
}
|
||||
} else {
|
||||
zmq_setsockopt (monitor_, ZMQ_RCVTIMEO, &timeout_, sizeof (timeout_));
|
||||
res = get_monitor_event_internal (monitor_, value_, address_, 0);
|
||||
}
|
||||
int timeout_infinite = -1;
|
||||
zmq_setsockopt (monitor_, ZMQ_RCVTIMEO, &timeout_infinite,
|
||||
sizeof (timeout_infinite));
|
||||
return res;
|
||||
}
|
||||
int get_monitor_event (void *monitor_, int *value_, char **address_);
|
||||
|
||||
int get_monitor_event (void *monitor_, int *value_, char **address_)
|
||||
{
|
||||
return get_monitor_event_with_timeout (monitor_, value_, address_, -1);
|
||||
}
|
||||
|
||||
void expect_monitor_event (void *monitor_, int expected_event_)
|
||||
{
|
||||
TEST_ASSERT_EQUAL_HEX (expected_event_,
|
||||
get_monitor_event (monitor_, NULL, NULL));
|
||||
}
|
||||
|
||||
void print_unexpected_event (char *buf_,
|
||||
size_t buf_size_,
|
||||
int event_,
|
||||
int err_,
|
||||
int expected_event_,
|
||||
int expected_err_)
|
||||
{
|
||||
snprintf (buf_, buf_size_,
|
||||
"Unexpected event: 0x%x, value = %i/0x%x (expected: 0x%x, value "
|
||||
"= %i/0x%x)\n",
|
||||
event_, err_, err_, expected_event_, expected_err_,
|
||||
expected_err_);
|
||||
}
|
||||
void expect_monitor_event (void *monitor_, int expected_event_);
|
||||
|
||||
void print_unexpected_event_stderr (int event_,
|
||||
int err_,
|
||||
int expected_event_,
|
||||
int expected_err_)
|
||||
{
|
||||
char buf[256];
|
||||
print_unexpected_event (buf, sizeof buf, event_, err_, expected_event_,
|
||||
expected_err_);
|
||||
fputs (buf, stderr);
|
||||
}
|
||||
int expected_err_);
|
||||
|
||||
// expects that one or more occurrences of the expected event are received
|
||||
// via the specified socket monitor
|
||||
@ -149,216 +61,15 @@ void print_unexpected_event_stderr (int event_,
|
||||
int expect_monitor_event_multiple (void *server_mon_,
|
||||
int expected_event_,
|
||||
int expected_err_ = -1,
|
||||
bool optional_ = false)
|
||||
{
|
||||
int count_of_expected_events = 0;
|
||||
int client_closed_connection = 0;
|
||||
int timeout = 250;
|
||||
int wait_time = 0;
|
||||
|
||||
int event;
|
||||
int err;
|
||||
while ((event =
|
||||
get_monitor_event_with_timeout (server_mon_, &err, NULL, timeout))
|
||||
!= -1
|
||||
|| !count_of_expected_events) {
|
||||
if (event == -1) {
|
||||
if (optional_)
|
||||
break;
|
||||
wait_time += timeout;
|
||||
fprintf (stderr,
|
||||
"Still waiting for first event after %ims (expected event "
|
||||
"%x (value %i/0x%x))\n",
|
||||
wait_time, expected_event_, expected_err_, expected_err_);
|
||||
continue;
|
||||
}
|
||||
// ignore errors with EPIPE/ECONNRESET/ECONNABORTED, which can happen
|
||||
// ECONNRESET can happen on very slow machines, when the engine writes
|
||||
// to the peer and then tries to read the socket before the peer reads
|
||||
// ECONNABORTED happens when a client aborts a connection via RST/timeout
|
||||
if (event == ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL
|
||||
&& ((err == EPIPE && expected_err_ != EPIPE) || err == ECONNRESET
|
||||
|| err == ECONNABORTED)) {
|
||||
fprintf (stderr,
|
||||
"Ignored event (skipping any further events): %x (err = "
|
||||
"%i == %s)\n",
|
||||
event, err, zmq_strerror (err));
|
||||
client_closed_connection = 1;
|
||||
break;
|
||||
}
|
||||
if (event != expected_event_
|
||||
|| (-1 != expected_err_ && err != expected_err_)) {
|
||||
char buf[256];
|
||||
print_unexpected_event (buf, sizeof buf, event, err,
|
||||
expected_event_, expected_err_);
|
||||
TEST_FAIL_MESSAGE (buf);
|
||||
}
|
||||
++count_of_expected_events;
|
||||
}
|
||||
TEST_ASSERT_TRUE (optional_ || count_of_expected_events > 0
|
||||
|| client_closed_connection);
|
||||
|
||||
return count_of_expected_events;
|
||||
}
|
||||
|
||||
#if (defined ZMQ_CURRENT_EVENT_VERSION && ZMQ_CURRENT_EVENT_VERSION >= 2) \
|
||||
|| (defined ZMQ_CURRENT_EVENT_VERSION \
|
||||
&& ZMQ_CURRENT_EVENT_VERSION_DRAFT >= 2)
|
||||
static int64_t get_monitor_event_internal_v2 (void *monitor_,
|
||||
uint64_t *value_,
|
||||
char **local_address_,
|
||||
char **remote_address_,
|
||||
int recv_flag_)
|
||||
{
|
||||
// First frame in message contains event number
|
||||
zmq_msg_t msg;
|
||||
zmq_msg_init (&msg);
|
||||
if (zmq_msg_recv (&msg, monitor_, recv_flag_) == -1) {
|
||||
TEST_ASSERT_FAILURE_ERRNO (EAGAIN, -1);
|
||||
return -1; // timed out or no message available
|
||||
}
|
||||
TEST_ASSERT_TRUE (zmq_msg_more (&msg));
|
||||
TEST_ASSERT_EQUAL_UINT (sizeof (uint64_t), zmq_msg_size (&msg));
|
||||
|
||||
uint64_t event;
|
||||
memcpy (&event, zmq_msg_data (&msg), sizeof (event));
|
||||
zmq_msg_close (&msg);
|
||||
|
||||
// Second frame in message contains the number of values
|
||||
zmq_msg_init (&msg);
|
||||
if (zmq_msg_recv (&msg, monitor_, recv_flag_) == -1) {
|
||||
TEST_ASSERT_FAILURE_ERRNO (EAGAIN, -1);
|
||||
return -1; // timed out or no message available
|
||||
}
|
||||
TEST_ASSERT_TRUE (zmq_msg_more (&msg));
|
||||
TEST_ASSERT_EQUAL_UINT (sizeof (uint64_t), zmq_msg_size (&msg));
|
||||
|
||||
uint64_t value_count;
|
||||
memcpy (&value_count, zmq_msg_data (&msg), sizeof (value_count));
|
||||
zmq_msg_close (&msg);
|
||||
|
||||
for (uint64_t i = 0; i < value_count; ++i) {
|
||||
// Subsequent frames in message contain event values
|
||||
zmq_msg_init (&msg);
|
||||
if (zmq_msg_recv (&msg, monitor_, recv_flag_) == -1) {
|
||||
TEST_ASSERT_FAILURE_ERRNO (EAGAIN, -1);
|
||||
return -1; // timed out or no message available
|
||||
}
|
||||
TEST_ASSERT_TRUE (zmq_msg_more (&msg));
|
||||
TEST_ASSERT_EQUAL_UINT (sizeof (uint64_t), zmq_msg_size (&msg));
|
||||
|
||||
if (value_ && value_ + i)
|
||||
memcpy (value_ + i, zmq_msg_data (&msg), sizeof (*value_));
|
||||
zmq_msg_close (&msg);
|
||||
}
|
||||
|
||||
// Second-to-last frame in message contains local address
|
||||
zmq_msg_init (&msg);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_recv (&msg, monitor_, recv_flag_));
|
||||
TEST_ASSERT_TRUE (zmq_msg_more (&msg));
|
||||
|
||||
if (local_address_) {
|
||||
uint8_t *data = (uint8_t *) zmq_msg_data (&msg);
|
||||
size_t size = zmq_msg_size (&msg);
|
||||
*local_address_ = (char *) malloc (size + 1);
|
||||
memcpy (*local_address_, data, size);
|
||||
(*local_address_)[size] = 0;
|
||||
}
|
||||
zmq_msg_close (&msg);
|
||||
|
||||
// Last frame in message contains remote address
|
||||
zmq_msg_init (&msg);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_recv (&msg, monitor_, recv_flag_));
|
||||
TEST_ASSERT_TRUE (!zmq_msg_more (&msg));
|
||||
|
||||
if (remote_address_) {
|
||||
uint8_t *data = (uint8_t *) zmq_msg_data (&msg);
|
||||
size_t size = zmq_msg_size (&msg);
|
||||
*remote_address_ = (char *) malloc (size + 1);
|
||||
memcpy (*remote_address_, data, size);
|
||||
(*remote_address_)[size] = 0;
|
||||
}
|
||||
zmq_msg_close (&msg);
|
||||
return event;
|
||||
}
|
||||
|
||||
int64_t get_monitor_event_with_timeout_v2 (void *monitor_,
|
||||
uint64_t *value_,
|
||||
char **local_address_,
|
||||
char **remote_address_,
|
||||
int timeout_)
|
||||
{
|
||||
int64_t res;
|
||||
if (timeout_ == -1) {
|
||||
// process infinite timeout in small steps to allow the user
|
||||
// to see some information on the console
|
||||
|
||||
int timeout_step = 250;
|
||||
int wait_time = 0;
|
||||
zmq_setsockopt (monitor_, ZMQ_RCVTIMEO, &timeout_step,
|
||||
sizeof (timeout_step));
|
||||
while ((res = get_monitor_event_internal_v2 (
|
||||
monitor_, value_, local_address_, remote_address_, 0))
|
||||
== -1) {
|
||||
wait_time += timeout_step;
|
||||
fprintf (stderr, "Still waiting for monitor event after %i ms\n",
|
||||
wait_time);
|
||||
}
|
||||
} else {
|
||||
zmq_setsockopt (monitor_, ZMQ_RCVTIMEO, &timeout_, sizeof (timeout_));
|
||||
res = get_monitor_event_internal_v2 (monitor_, value_, local_address_,
|
||||
remote_address_, 0);
|
||||
}
|
||||
int timeout_infinite = -1;
|
||||
zmq_setsockopt (monitor_, ZMQ_RCVTIMEO, &timeout_infinite,
|
||||
sizeof (timeout_infinite));
|
||||
return res;
|
||||
}
|
||||
bool optional_ = false);
|
||||
|
||||
int64_t get_monitor_event_v2 (void *monitor_,
|
||||
uint64_t *value_,
|
||||
char **local_address_,
|
||||
char **remote_address_)
|
||||
{
|
||||
return get_monitor_event_with_timeout_v2 (monitor_, value_, local_address_,
|
||||
remote_address_, -1);
|
||||
}
|
||||
char **remote_address_);
|
||||
|
||||
void expect_monitor_event_v2 (void *monitor_,
|
||||
int64_t expected_event_,
|
||||
const char *expected_local_address_ = NULL,
|
||||
const char *expected_remote_address_ = NULL)
|
||||
{
|
||||
char *local_address = NULL;
|
||||
char *remote_address = NULL;
|
||||
int64_t event = get_monitor_event_v2 (
|
||||
monitor_, NULL, expected_local_address_ ? &local_address : NULL,
|
||||
expected_remote_address_ ? &remote_address : NULL);
|
||||
bool failed = false;
|
||||
char buf[256];
|
||||
char *pos = buf;
|
||||
if (event != expected_event_) {
|
||||
pos += snprintf (pos, sizeof buf - (pos - buf),
|
||||
"Expected monitor event %llx, but received %llx\n",
|
||||
(long long) expected_event_, (long long) event);
|
||||
failed = true;
|
||||
}
|
||||
if (expected_local_address_
|
||||
&& 0 != strcmp (local_address, expected_local_address_)) {
|
||||
pos += snprintf (pos, sizeof buf - (pos - buf),
|
||||
"Expected local address %s, but received %s\n",
|
||||
expected_local_address_, local_address);
|
||||
}
|
||||
if (expected_remote_address_
|
||||
&& 0 != strcmp (remote_address, expected_remote_address_)) {
|
||||
pos += snprintf (pos, sizeof buf - (pos - buf),
|
||||
"Expected remote address %s, but received %s\n",
|
||||
expected_remote_address_, remote_address);
|
||||
}
|
||||
free (local_address);
|
||||
free (remote_address);
|
||||
TEST_ASSERT_FALSE_MESSAGE (failed, buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
const char *expected_remote_address_ = NULL);
|
||||
#endif
|
||||
|
401
tests/testutil_security.cpp
Normal file
401
tests/testutil_security.cpp
Normal file
@ -0,0 +1,401 @@
|
||||
/*
|
||||
Copyright (c) 2007-2019 Contributors as noted in the AUTHORS file
|
||||
|
||||
This file is part of libzmq, the ZeroMQ core engine in C++.
|
||||
|
||||
libzmq is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License (LGPL) as published
|
||||
by the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
As a special exception, the Contributors give you permission to link
|
||||
this library with independent modules to produce an executable,
|
||||
regardless of the license terms of these independent modules, and to
|
||||
copy and distribute the resulting executable under terms of your choice,
|
||||
provided that you also meet, for each linked independent module, the
|
||||
terms and conditions of the license of that module. An independent
|
||||
module is a module which is not derived from or based on this library.
|
||||
If you modify this library, you must extend this exception to your
|
||||
version of the library.
|
||||
|
||||
libzmq is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "testutil_security.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
const char *test_zap_domain = "ZAPTEST";
|
||||
|
||||
void socket_config_null_client (void *server_, void *server_secret_)
|
||||
{
|
||||
LIBZMQ_UNUSED (server_);
|
||||
LIBZMQ_UNUSED (server_secret_);
|
||||
}
|
||||
|
||||
void socket_config_null_server (void *server_, void *server_secret_)
|
||||
{
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
|
||||
server_, ZMQ_ZAP_DOMAIN, test_zap_domain, strlen (test_zap_domain)));
|
||||
#ifdef ZMQ_ZAP_ENFORCE_DOMAIN
|
||||
int required = server_secret_ ? *(int *) server_secret_ : 0;
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (server_, ZMQ_ZAP_ENFORCE_DOMAIN,
|
||||
&required, sizeof (int)));
|
||||
#else
|
||||
LIBZMQ_UNUSED (server_secret_);
|
||||
#endif
|
||||
}
|
||||
|
||||
static const char test_plain_username[] = "testuser";
|
||||
static const char test_plain_password[] = "testpass";
|
||||
|
||||
void socket_config_plain_client (void *server_, void *server_secret_)
|
||||
{
|
||||
LIBZMQ_UNUSED (server_secret_);
|
||||
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (server_, ZMQ_PLAIN_PASSWORD, test_plain_password, 8));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (server_, ZMQ_PLAIN_USERNAME, test_plain_username, 8));
|
||||
}
|
||||
|
||||
void socket_config_plain_server (void *server_, void *server_secret_)
|
||||
{
|
||||
LIBZMQ_UNUSED (server_secret_);
|
||||
|
||||
int as_server = 1;
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (server_, ZMQ_PLAIN_SERVER, &as_server, sizeof (int)));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
|
||||
server_, ZMQ_ZAP_DOMAIN, test_zap_domain, strlen (test_zap_domain)));
|
||||
}
|
||||
|
||||
char valid_client_public[41];
|
||||
char valid_client_secret[41];
|
||||
char valid_server_public[41];
|
||||
char valid_server_secret[41];
|
||||
|
||||
void setup_testutil_security_curve ()
|
||||
{
|
||||
// Generate new keypairs for these tests
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_curve_keypair (valid_client_public, valid_client_secret));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_curve_keypair (valid_server_public, valid_server_secret));
|
||||
}
|
||||
|
||||
void socket_config_curve_server (void *server_, void *server_secret_)
|
||||
{
|
||||
int as_server = 1;
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (server_, ZMQ_CURVE_SERVER, &as_server, sizeof (int)));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (server_, ZMQ_CURVE_SECRETKEY, server_secret_, 41));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
|
||||
server_, ZMQ_ZAP_DOMAIN, test_zap_domain, strlen (test_zap_domain)));
|
||||
|
||||
#ifdef ZMQ_ZAP_ENFORCE_DOMAIN
|
||||
int required = 1;
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (server_, ZMQ_ZAP_ENFORCE_DOMAIN,
|
||||
&required, sizeof (int)));
|
||||
#endif
|
||||
}
|
||||
|
||||
void socket_config_curve_client (void *client_, void *data_)
|
||||
{
|
||||
curve_client_data_t *curve_client_data =
|
||||
static_cast<curve_client_data_t *> (data_);
|
||||
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
|
||||
client_, ZMQ_CURVE_SERVERKEY, curve_client_data->server_public, 41));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
|
||||
client_, ZMQ_CURVE_PUBLICKEY, curve_client_data->client_public, 41));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
|
||||
client_, ZMQ_CURVE_SECRETKEY, curve_client_data->client_secret, 41));
|
||||
}
|
||||
|
||||
void *zap_requests_handled;
|
||||
|
||||
void zap_handler_generic (zap_protocol_t zap_protocol_,
|
||||
const char *expected_routing_id_)
|
||||
{
|
||||
void *control = zmq_socket (get_test_context (), ZMQ_REQ);
|
||||
TEST_ASSERT_NOT_NULL (control);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_connect (control, "inproc://handler-control"));
|
||||
|
||||
void *handler = zmq_socket (get_test_context (), ZMQ_REP);
|
||||
TEST_ASSERT_NOT_NULL (handler);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (handler, "inproc://zeromq.zap.01"));
|
||||
|
||||
// Signal main thread that we are ready
|
||||
send_string_expect_success (control, "GO", 0);
|
||||
|
||||
zmq_pollitem_t items[] = {
|
||||
{control, 0, ZMQ_POLLIN, 0},
|
||||
{handler, 0, ZMQ_POLLIN, 0},
|
||||
};
|
||||
|
||||
// if ordered not to receive the request, ignore the second poll item
|
||||
const int numitems = (zap_protocol_ == zap_do_not_recv) ? 1 : 2;
|
||||
|
||||
// Process ZAP requests forever
|
||||
while (zmq_poll (items, numitems, -1) >= 0) {
|
||||
if (items[0].revents & ZMQ_POLLIN) {
|
||||
recv_string_expect_success (control, "STOP", 0);
|
||||
break; // Terminating - main thread signal
|
||||
}
|
||||
if (!(items[1].revents & ZMQ_POLLIN))
|
||||
continue;
|
||||
|
||||
char *version = s_recv (handler);
|
||||
if (!version)
|
||||
break; // Terminating - peer's socket closed
|
||||
if (zap_protocol_ == zap_disconnect) {
|
||||
free (version);
|
||||
break;
|
||||
}
|
||||
|
||||
char *sequence = s_recv (handler);
|
||||
char *domain = s_recv (handler);
|
||||
char *address = s_recv (handler);
|
||||
char *routing_id = s_recv (handler);
|
||||
char *mechanism = s_recv (handler);
|
||||
bool authentication_succeeded = false;
|
||||
if (streq (mechanism, "CURVE")) {
|
||||
uint8_t client_key[32];
|
||||
TEST_ASSERT_EQUAL_INT (32, TEST_ASSERT_SUCCESS_ERRNO (zmq_recv (
|
||||
handler, client_key, 32, 0)));
|
||||
|
||||
char client_key_text[41];
|
||||
zmq_z85_encode (client_key_text, client_key, 32);
|
||||
|
||||
authentication_succeeded =
|
||||
streq (client_key_text, valid_client_public);
|
||||
} else if (streq (mechanism, "PLAIN")) {
|
||||
char client_username[32];
|
||||
int size = TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_recv (handler, client_username, 32, 0));
|
||||
client_username[size] = 0;
|
||||
|
||||
char client_password[32];
|
||||
size = TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_recv (handler, client_password, 32, 0));
|
||||
client_password[size] = 0;
|
||||
|
||||
authentication_succeeded =
|
||||
streq (test_plain_username, client_username)
|
||||
&& streq (test_plain_password, client_password);
|
||||
} else if (streq (mechanism, "NULL")) {
|
||||
authentication_succeeded = true;
|
||||
} else {
|
||||
char msg[128];
|
||||
printf ("Unsupported mechanism: %s\n", mechanism);
|
||||
TEST_FAIL_MESSAGE (msg);
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING ("1.0", version);
|
||||
TEST_ASSERT_EQUAL_STRING (expected_routing_id_, routing_id);
|
||||
|
||||
s_sendmore (handler, zap_protocol_ == zap_wrong_version
|
||||
? "invalid_version"
|
||||
: version);
|
||||
s_sendmore (handler, zap_protocol_ == zap_wrong_request_id
|
||||
? "invalid_request_id"
|
||||
: sequence);
|
||||
|
||||
if (authentication_succeeded) {
|
||||
const char *status_code;
|
||||
switch (zap_protocol_) {
|
||||
case zap_status_internal_error:
|
||||
status_code = "500";
|
||||
break;
|
||||
case zap_status_temporary_failure:
|
||||
status_code = "300";
|
||||
break;
|
||||
case zap_status_invalid:
|
||||
status_code = "invalid_status";
|
||||
break;
|
||||
default:
|
||||
status_code = "200";
|
||||
}
|
||||
s_sendmore (handler, status_code);
|
||||
s_sendmore (handler, "OK");
|
||||
s_sendmore (handler, "anonymous");
|
||||
if (zap_protocol_ == zap_too_many_parts) {
|
||||
s_sendmore (handler, "");
|
||||
}
|
||||
if (zap_protocol_ != zap_do_not_send)
|
||||
s_send (handler, "");
|
||||
} else {
|
||||
s_sendmore (handler, "400");
|
||||
s_sendmore (handler, "Invalid client public key");
|
||||
s_sendmore (handler, "");
|
||||
if (zap_protocol_ != zap_do_not_send)
|
||||
s_send (handler, "");
|
||||
}
|
||||
free (version);
|
||||
free (sequence);
|
||||
free (domain);
|
||||
free (address);
|
||||
free (routing_id);
|
||||
free (mechanism);
|
||||
|
||||
zmq_atomic_counter_inc (zap_requests_handled);
|
||||
}
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_unbind (handler, "inproc://zeromq.zap.01"));
|
||||
close_zero_linger (handler);
|
||||
|
||||
if (zap_protocol_ != zap_disconnect) {
|
||||
send_string_expect_success (control, "STOPPED", 0);
|
||||
}
|
||||
close_zero_linger (control);
|
||||
}
|
||||
|
||||
void zap_handler (void *)
|
||||
{
|
||||
zap_handler_generic (zap_ok);
|
||||
}
|
||||
|
||||
static void setup_handshake_socket_monitor (void *server_,
|
||||
void **server_mon_,
|
||||
const char *monitor_endpoint_)
|
||||
{
|
||||
// Monitor handshake events on the server
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_socket_monitor (
|
||||
server_, monitor_endpoint_,
|
||||
ZMQ_EVENT_HANDSHAKE_SUCCEEDED | ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL
|
||||
| ZMQ_EVENT_HANDSHAKE_FAILED_AUTH
|
||||
| ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL));
|
||||
|
||||
// Create socket for collecting monitor events
|
||||
*server_mon_ = test_context_socket (ZMQ_PAIR);
|
||||
int linger = 0;
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (*server_mon_, ZMQ_LINGER, &linger, sizeof (linger)));
|
||||
|
||||
// Connect it to the inproc endpoints so they'll get events
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (*server_mon_, monitor_endpoint_));
|
||||
}
|
||||
|
||||
void setup_context_and_server_side (void **zap_control_,
|
||||
void **zap_thread_,
|
||||
void **server_,
|
||||
void **server_mon_,
|
||||
char *my_endpoint_,
|
||||
zmq_thread_fn zap_handler_,
|
||||
socket_config_fn socket_config_,
|
||||
void *socket_config_data_,
|
||||
const char *routing_id_)
|
||||
{
|
||||
// Spawn ZAP handler
|
||||
zap_requests_handled = zmq_atomic_counter_new ();
|
||||
TEST_ASSERT_NOT_NULL (zap_requests_handled);
|
||||
|
||||
*zap_control_ = test_context_socket (ZMQ_REP);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_bind (*zap_control_, "inproc://handler-control"));
|
||||
int linger = 0;
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (*zap_control_, ZMQ_LINGER, &linger, sizeof (linger)));
|
||||
|
||||
if (zap_handler_ != NULL) {
|
||||
*zap_thread_ = zmq_threadstart (zap_handler_, NULL);
|
||||
|
||||
recv_string_expect_success (*zap_control_, "GO", 0);
|
||||
} else
|
||||
*zap_thread_ = NULL;
|
||||
|
||||
// Server socket will accept connections
|
||||
*server_ = test_context_socket (ZMQ_DEALER);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (*server_, ZMQ_LINGER, &linger, sizeof (linger)));
|
||||
|
||||
socket_config_ (*server_, socket_config_data_);
|
||||
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
|
||||
*server_, ZMQ_ROUTING_ID, routing_id_, strlen (routing_id_)));
|
||||
|
||||
bind_loopback_ipv4 (*server_, my_endpoint_, MAX_SOCKET_STRING);
|
||||
|
||||
const char server_monitor_endpoint[] = "inproc://monitor-server";
|
||||
setup_handshake_socket_monitor (*server_, server_mon_,
|
||||
server_monitor_endpoint);
|
||||
}
|
||||
|
||||
void shutdown_context_and_server_side (void *zap_thread_,
|
||||
void *server_,
|
||||
void *server_mon_,
|
||||
void *zap_control_,
|
||||
bool zap_handler_stopped_)
|
||||
{
|
||||
if (zap_thread_ && !zap_handler_stopped_) {
|
||||
send_string_expect_success (zap_control_, "STOP", 0);
|
||||
recv_string_expect_success (zap_control_, "STOPPED", 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_unbind (zap_control_, "inproc://handler-control"));
|
||||
}
|
||||
test_context_socket_close (zap_control_);
|
||||
test_context_socket_close (server_mon_);
|
||||
test_context_socket_close (server_);
|
||||
|
||||
// Wait until ZAP handler terminates
|
||||
if (zap_thread_)
|
||||
zmq_threadclose (zap_thread_);
|
||||
|
||||
zmq_atomic_counter_destroy (&zap_requests_handled);
|
||||
}
|
||||
|
||||
void *create_and_connect_client (char *my_endpoint_,
|
||||
socket_config_fn socket_config_,
|
||||
void *socket_config_data_,
|
||||
void **client_mon_)
|
||||
{
|
||||
void *client = test_context_socket (ZMQ_DEALER);
|
||||
|
||||
socket_config_ (client, socket_config_data_);
|
||||
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (client, my_endpoint_));
|
||||
|
||||
if (client_mon_) {
|
||||
setup_handshake_socket_monitor (client, client_mon_,
|
||||
"inproc://client-monitor");
|
||||
}
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
void expect_new_client_bounce_fail (char *my_endpoint_,
|
||||
void *server_,
|
||||
socket_config_fn socket_config_,
|
||||
void *socket_config_data_,
|
||||
void **client_mon_,
|
||||
int expected_client_event_,
|
||||
int expected_client_value_)
|
||||
{
|
||||
void *my_client_mon;
|
||||
TEST_ASSERT_TRUE (client_mon_ == NULL || expected_client_event_ == 0);
|
||||
if (expected_client_event_ != 0)
|
||||
client_mon_ = &my_client_mon;
|
||||
void *client = create_and_connect_client (my_endpoint_, socket_config_,
|
||||
socket_config_data_, client_mon_);
|
||||
expect_bounce_fail (server_, client);
|
||||
|
||||
if (expected_client_event_ != 0) {
|
||||
int events_received = 0;
|
||||
events_received = expect_monitor_event_multiple (
|
||||
my_client_mon, expected_client_event_, expected_client_value_, false);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT (1, events_received);
|
||||
|
||||
test_context_socket_close (my_client_mon);
|
||||
}
|
||||
|
||||
test_context_socket_close_zero_linger (client);
|
||||
}
|
@ -37,86 +37,27 @@
|
||||
|
||||
typedef void(socket_config_fn) (void *, void *);
|
||||
|
||||
const char *test_zap_domain = "ZAPTEST";
|
||||
|
||||
// NULL specific functions
|
||||
void socket_config_null_client (void *server_, void *server_secret_)
|
||||
{
|
||||
LIBZMQ_UNUSED (server_);
|
||||
LIBZMQ_UNUSED (server_secret_);
|
||||
}
|
||||
void socket_config_null_client (void *server_, void *server_secret_);
|
||||
|
||||
void socket_config_null_server (void *server_, void *server_secret_)
|
||||
{
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
|
||||
server_, ZMQ_ZAP_DOMAIN, test_zap_domain, strlen (test_zap_domain)));
|
||||
#ifdef ZMQ_ZAP_ENFORCE_DOMAIN
|
||||
int required = server_secret_ ? *(int *) server_secret_ : 0;
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (server_, ZMQ_ZAP_ENFORCE_DOMAIN,
|
||||
&required, sizeof (int)));
|
||||
#else
|
||||
LIBZMQ_UNUSED (server_secret_);
|
||||
#endif
|
||||
}
|
||||
void socket_config_null_server (void *server_, void *server_secret_);
|
||||
|
||||
// PLAIN specific functions
|
||||
const char *test_plain_username = "testuser";
|
||||
const char *test_plain_password = "testpass";
|
||||
void socket_config_plain_client (void *server_, void *server_secret_);
|
||||
|
||||
void socket_config_plain_client (void *server_, void *server_secret_)
|
||||
{
|
||||
LIBZMQ_UNUSED (server_secret_);
|
||||
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (server_, ZMQ_PLAIN_PASSWORD, test_plain_password, 8));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (server_, ZMQ_PLAIN_USERNAME, test_plain_username, 8));
|
||||
}
|
||||
|
||||
void socket_config_plain_server (void *server_, void *server_secret_)
|
||||
{
|
||||
LIBZMQ_UNUSED (server_secret_);
|
||||
|
||||
int as_server = 1;
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (server_, ZMQ_PLAIN_SERVER, &as_server, sizeof (int)));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
|
||||
server_, ZMQ_ZAP_DOMAIN, test_zap_domain, strlen (test_zap_domain)));
|
||||
}
|
||||
void socket_config_plain_server (void *server_, void *server_secret_);
|
||||
|
||||
// CURVE specific functions
|
||||
|
||||
// We'll generate random test keys at startup
|
||||
char valid_client_public[41];
|
||||
char valid_client_secret[41];
|
||||
char valid_server_public[41];
|
||||
char valid_server_secret[41];
|
||||
extern char valid_client_public[41];
|
||||
extern char valid_client_secret[41];
|
||||
extern char valid_server_public[41];
|
||||
extern char valid_server_secret[41];
|
||||
|
||||
void setup_testutil_security_curve ()
|
||||
{
|
||||
// Generate new keypairs for these tests
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_curve_keypair (valid_client_public, valid_client_secret));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_curve_keypair (valid_server_public, valid_server_secret));
|
||||
}
|
||||
void setup_testutil_security_curve ();
|
||||
|
||||
void socket_config_curve_server (void *server_, void *server_secret_)
|
||||
{
|
||||
int as_server = 1;
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (server_, ZMQ_CURVE_SERVER, &as_server, sizeof (int)));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (server_, ZMQ_CURVE_SECRETKEY, server_secret_, 41));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
|
||||
server_, ZMQ_ZAP_DOMAIN, test_zap_domain, strlen (test_zap_domain)));
|
||||
|
||||
#ifdef ZMQ_ZAP_ENFORCE_DOMAIN
|
||||
int required = 1;
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (server_, ZMQ_ZAP_ENFORCE_DOMAIN,
|
||||
&required, sizeof (int)));
|
||||
#endif
|
||||
}
|
||||
void socket_config_curve_server (void *server_, void *server_secret_);
|
||||
|
||||
struct curve_client_data_t
|
||||
{
|
||||
@ -125,18 +66,7 @@ struct curve_client_data_t
|
||||
const char *client_secret;
|
||||
};
|
||||
|
||||
void socket_config_curve_client (void *client_, void *data_)
|
||||
{
|
||||
curve_client_data_t *curve_client_data =
|
||||
static_cast<curve_client_data_t *> (data_);
|
||||
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
|
||||
client_, ZMQ_CURVE_SERVERKEY, curve_client_data->server_public, 41));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
|
||||
client_, ZMQ_CURVE_PUBLICKEY, curve_client_data->client_public, 41));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
|
||||
client_, ZMQ_CURVE_SECRETKEY, curve_client_data->client_secret, 41));
|
||||
}
|
||||
void socket_config_curve_client (void *client_, void *data_);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// This methods receives and validates ZAP requests (allowing or denying
|
||||
@ -158,148 +88,12 @@ enum zap_protocol_t
|
||||
zap_do_not_send
|
||||
};
|
||||
|
||||
void *zap_requests_handled;
|
||||
extern void *zap_requests_handled;
|
||||
|
||||
void zap_handler_generic (zap_protocol_t zap_protocol_,
|
||||
const char *expected_routing_id_ = "IDENT")
|
||||
{
|
||||
void *control = zmq_socket (get_test_context (), ZMQ_REQ);
|
||||
TEST_ASSERT_NOT_NULL (control);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_connect (control, "inproc://handler-control"));
|
||||
const char *expected_routing_id_ = "IDENT");
|
||||
|
||||
void *handler = zmq_socket (get_test_context (), ZMQ_REP);
|
||||
TEST_ASSERT_NOT_NULL (handler);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (handler, "inproc://zeromq.zap.01"));
|
||||
|
||||
// Signal main thread that we are ready
|
||||
send_string_expect_success (control, "GO", 0);
|
||||
|
||||
zmq_pollitem_t items[] = {
|
||||
{control, 0, ZMQ_POLLIN, 0},
|
||||
{handler, 0, ZMQ_POLLIN, 0},
|
||||
};
|
||||
|
||||
// if ordered not to receive the request, ignore the second poll item
|
||||
const int numitems = (zap_protocol_ == zap_do_not_recv) ? 1 : 2;
|
||||
|
||||
// Process ZAP requests forever
|
||||
while (zmq_poll (items, numitems, -1) >= 0) {
|
||||
if (items[0].revents & ZMQ_POLLIN) {
|
||||
recv_string_expect_success (control, "STOP", 0);
|
||||
break; // Terminating - main thread signal
|
||||
}
|
||||
if (!(items[1].revents & ZMQ_POLLIN))
|
||||
continue;
|
||||
|
||||
char *version = s_recv (handler);
|
||||
if (!version)
|
||||
break; // Terminating - peer's socket closed
|
||||
if (zap_protocol_ == zap_disconnect) {
|
||||
free (version);
|
||||
break;
|
||||
}
|
||||
|
||||
char *sequence = s_recv (handler);
|
||||
char *domain = s_recv (handler);
|
||||
char *address = s_recv (handler);
|
||||
char *routing_id = s_recv (handler);
|
||||
char *mechanism = s_recv (handler);
|
||||
bool authentication_succeeded = false;
|
||||
if (streq (mechanism, "CURVE")) {
|
||||
uint8_t client_key[32];
|
||||
TEST_ASSERT_EQUAL_INT (32, TEST_ASSERT_SUCCESS_ERRNO (zmq_recv (
|
||||
handler, client_key, 32, 0)));
|
||||
|
||||
char client_key_text[41];
|
||||
zmq_z85_encode (client_key_text, client_key, 32);
|
||||
|
||||
authentication_succeeded =
|
||||
streq (client_key_text, valid_client_public);
|
||||
} else if (streq (mechanism, "PLAIN")) {
|
||||
char client_username[32];
|
||||
int size = TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_recv (handler, client_username, 32, 0));
|
||||
client_username[size] = 0;
|
||||
|
||||
char client_password[32];
|
||||
size = TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_recv (handler, client_password, 32, 0));
|
||||
client_password[size] = 0;
|
||||
|
||||
authentication_succeeded =
|
||||
streq (test_plain_username, client_username)
|
||||
&& streq (test_plain_password, client_password);
|
||||
} else if (streq (mechanism, "NULL")) {
|
||||
authentication_succeeded = true;
|
||||
} else {
|
||||
char msg[128];
|
||||
printf ("Unsupported mechanism: %s\n", mechanism);
|
||||
TEST_FAIL_MESSAGE (msg);
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING ("1.0", version);
|
||||
TEST_ASSERT_EQUAL_STRING (expected_routing_id_, routing_id);
|
||||
|
||||
s_sendmore (handler, zap_protocol_ == zap_wrong_version
|
||||
? "invalid_version"
|
||||
: version);
|
||||
s_sendmore (handler, zap_protocol_ == zap_wrong_request_id
|
||||
? "invalid_request_id"
|
||||
: sequence);
|
||||
|
||||
if (authentication_succeeded) {
|
||||
const char *status_code;
|
||||
switch (zap_protocol_) {
|
||||
case zap_status_internal_error:
|
||||
status_code = "500";
|
||||
break;
|
||||
case zap_status_temporary_failure:
|
||||
status_code = "300";
|
||||
break;
|
||||
case zap_status_invalid:
|
||||
status_code = "invalid_status";
|
||||
break;
|
||||
default:
|
||||
status_code = "200";
|
||||
}
|
||||
s_sendmore (handler, status_code);
|
||||
s_sendmore (handler, "OK");
|
||||
s_sendmore (handler, "anonymous");
|
||||
if (zap_protocol_ == zap_too_many_parts) {
|
||||
s_sendmore (handler, "");
|
||||
}
|
||||
if (zap_protocol_ != zap_do_not_send)
|
||||
s_send (handler, "");
|
||||
} else {
|
||||
s_sendmore (handler, "400");
|
||||
s_sendmore (handler, "Invalid client public key");
|
||||
s_sendmore (handler, "");
|
||||
if (zap_protocol_ != zap_do_not_send)
|
||||
s_send (handler, "");
|
||||
}
|
||||
free (version);
|
||||
free (sequence);
|
||||
free (domain);
|
||||
free (address);
|
||||
free (routing_id);
|
||||
free (mechanism);
|
||||
|
||||
zmq_atomic_counter_inc (zap_requests_handled);
|
||||
}
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_unbind (handler, "inproc://zeromq.zap.01"));
|
||||
close_zero_linger (handler);
|
||||
|
||||
if (zap_protocol_ != zap_disconnect) {
|
||||
send_string_expect_success (control, "STOPPED", 0);
|
||||
}
|
||||
close_zero_linger (control);
|
||||
}
|
||||
|
||||
void zap_handler (void * /*unused_*/)
|
||||
{
|
||||
zap_handler_generic (zap_ok);
|
||||
}
|
||||
void zap_handler (void * /*unused_*/);
|
||||
|
||||
// Security-specific monitor event utilities
|
||||
|
||||
@ -328,27 +122,6 @@ void zap_handler (void * /*unused_*/)
|
||||
TEST_ASSERT_EQUAL_INT (0, event_count); \
|
||||
}
|
||||
|
||||
void setup_handshake_socket_monitor (void *server_,
|
||||
void **server_mon_,
|
||||
const char *monitor_endpoint_)
|
||||
{
|
||||
// Monitor handshake events on the server
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_socket_monitor (
|
||||
server_, monitor_endpoint_,
|
||||
ZMQ_EVENT_HANDSHAKE_SUCCEEDED | ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL
|
||||
| ZMQ_EVENT_HANDSHAKE_FAILED_AUTH
|
||||
| ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL));
|
||||
|
||||
// Create socket for collecting monitor events
|
||||
*server_mon_ = test_context_socket (ZMQ_PAIR);
|
||||
int linger = 0;
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (*server_mon_, ZMQ_LINGER, &linger, sizeof (linger)));
|
||||
|
||||
// Connect it to the inproc endpoints so they'll get events
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (*server_mon_, monitor_endpoint_));
|
||||
}
|
||||
|
||||
void setup_context_and_server_side (
|
||||
void **zap_control_,
|
||||
void **zap_thread_,
|
||||
@ -358,84 +131,18 @@ void setup_context_and_server_side (
|
||||
zmq_thread_fn zap_handler_ = &zap_handler,
|
||||
socket_config_fn socket_config_ = &socket_config_curve_server,
|
||||
void *socket_config_data_ = valid_server_secret,
|
||||
const char *routing_id_ = "IDENT")
|
||||
{
|
||||
// Spawn ZAP handler
|
||||
zap_requests_handled = zmq_atomic_counter_new ();
|
||||
TEST_ASSERT_NOT_NULL (zap_requests_handled);
|
||||
|
||||
*zap_control_ = test_context_socket (ZMQ_REP);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_bind (*zap_control_, "inproc://handler-control"));
|
||||
int linger = 0;
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (*zap_control_, ZMQ_LINGER, &linger, sizeof (linger)));
|
||||
|
||||
if (zap_handler_ != NULL) {
|
||||
*zap_thread_ = zmq_threadstart (zap_handler_, NULL);
|
||||
|
||||
recv_string_expect_success (*zap_control_, "GO", 0);
|
||||
} else
|
||||
*zap_thread_ = NULL;
|
||||
|
||||
// Server socket will accept connections
|
||||
*server_ = test_context_socket (ZMQ_DEALER);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (*server_, ZMQ_LINGER, &linger, sizeof (linger)));
|
||||
|
||||
socket_config_ (*server_, socket_config_data_);
|
||||
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
|
||||
*server_, ZMQ_ROUTING_ID, routing_id_, strlen (routing_id_)));
|
||||
|
||||
bind_loopback_ipv4 (*server_, my_endpoint_, MAX_SOCKET_STRING);
|
||||
|
||||
const char server_monitor_endpoint[] = "inproc://monitor-server";
|
||||
setup_handshake_socket_monitor (*server_, server_mon_,
|
||||
server_monitor_endpoint);
|
||||
}
|
||||
const char *routing_id_ = "IDENT");
|
||||
|
||||
void shutdown_context_and_server_side (void *zap_thread_,
|
||||
void *server_,
|
||||
void *server_mon_,
|
||||
void *zap_control_,
|
||||
bool zap_handler_stopped_ = false)
|
||||
{
|
||||
if (zap_thread_ && !zap_handler_stopped_) {
|
||||
send_string_expect_success (zap_control_, "STOP", 0);
|
||||
recv_string_expect_success (zap_control_, "STOPPED", 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_unbind (zap_control_, "inproc://handler-control"));
|
||||
}
|
||||
test_context_socket_close (zap_control_);
|
||||
test_context_socket_close (server_mon_);
|
||||
test_context_socket_close (server_);
|
||||
|
||||
// Wait until ZAP handler terminates
|
||||
if (zap_thread_)
|
||||
zmq_threadclose (zap_thread_);
|
||||
|
||||
zmq_atomic_counter_destroy (&zap_requests_handled);
|
||||
}
|
||||
bool zap_handler_stopped_ = false);
|
||||
|
||||
void *create_and_connect_client (char *my_endpoint_,
|
||||
socket_config_fn socket_config_,
|
||||
void *socket_config_data_,
|
||||
void **client_mon_ = NULL)
|
||||
{
|
||||
void *client = test_context_socket (ZMQ_DEALER);
|
||||
|
||||
socket_config_ (client, socket_config_data_);
|
||||
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (client, my_endpoint_));
|
||||
|
||||
if (client_mon_) {
|
||||
setup_handshake_socket_monitor (client, client_mon_,
|
||||
"inproc://client-monitor");
|
||||
}
|
||||
|
||||
return client;
|
||||
}
|
||||
void **client_mon_ = NULL);
|
||||
|
||||
void expect_new_client_bounce_fail (char *my_endpoint_,
|
||||
void *server_,
|
||||
@ -443,27 +150,6 @@ void expect_new_client_bounce_fail (char *my_endpoint_,
|
||||
void *socket_config_data_,
|
||||
void **client_mon_ = NULL,
|
||||
int expected_client_event_ = 0,
|
||||
int expected_client_value_ = 0)
|
||||
{
|
||||
void *my_client_mon;
|
||||
TEST_ASSERT_TRUE (client_mon_ == NULL || expected_client_event_ == 0);
|
||||
if (expected_client_event_ != 0)
|
||||
client_mon_ = &my_client_mon;
|
||||
void *client = create_and_connect_client (my_endpoint_, socket_config_,
|
||||
socket_config_data_, client_mon_);
|
||||
expect_bounce_fail (server_, client);
|
||||
|
||||
if (expected_client_event_ != 0) {
|
||||
int events_received = 0;
|
||||
events_received = expect_monitor_event_multiple (
|
||||
my_client_mon, expected_client_event_, expected_client_value_, false);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT (1, events_received);
|
||||
|
||||
test_context_socket_close (my_client_mon);
|
||||
}
|
||||
|
||||
test_context_socket_close_zero_linger (client);
|
||||
}
|
||||
int expected_client_value_ = 0);
|
||||
|
||||
#endif
|
||||
|
309
tests/testutil_unity.cpp
Normal file
309
tests/testutil_unity.cpp
Normal file
@ -0,0 +1,309 @@
|
||||
/*
|
||||
Copyright (c) 2007-2019 Contributors as noted in the AUTHORS file
|
||||
|
||||
This file is part of libzmq, the ZeroMQ core engine in C++.
|
||||
|
||||
libzmq is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License (LGPL) as published
|
||||
by the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
As a special exception, the Contributors give you permission to link
|
||||
this library with independent modules to produce an executable,
|
||||
regardless of the license terms of these independent modules, and to
|
||||
copy and distribute the resulting executable under terms of your choice,
|
||||
provided that you also meet, for each linked independent module, the
|
||||
terms and conditions of the license of that module. An independent
|
||||
module is a module which is not derived from or based on this library.
|
||||
If you modify this library, you must extend this exception to your
|
||||
version of the library.
|
||||
|
||||
libzmq is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
int test_assert_success_message_errno_helper (int rc_,
|
||||
const char *msg_,
|
||||
const char *expr_)
|
||||
{
|
||||
if (rc_ == -1) {
|
||||
char buffer[512];
|
||||
buffer[sizeof (buffer) - 1] =
|
||||
0; // to ensure defined behavior with VC++ <= 2013
|
||||
snprintf (buffer, sizeof (buffer) - 1,
|
||||
"%s failed%s%s%s, errno = %i (%s)", expr_,
|
||||
msg_ ? " (additional info: " : "", msg_ ? msg_ : "",
|
||||
msg_ ? ")" : "", zmq_errno (), zmq_strerror (zmq_errno ()));
|
||||
TEST_FAIL_MESSAGE (buffer);
|
||||
}
|
||||
return rc_;
|
||||
}
|
||||
|
||||
int test_assert_success_message_raw_errno_helper (int rc_,
|
||||
const char *msg_,
|
||||
const char *expr_)
|
||||
{
|
||||
if (rc_ == -1) {
|
||||
#if defined ZMQ_HAVE_WINDOWS
|
||||
int current_errno = WSAGetLastError ();
|
||||
#else
|
||||
int current_errno = errno;
|
||||
#endif
|
||||
|
||||
char buffer[512];
|
||||
buffer[sizeof (buffer) - 1] =
|
||||
0; // to ensure defined behavior with VC++ <= 2013
|
||||
snprintf (buffer, sizeof (buffer) - 1, "%s failed%s%s%s, errno = %i",
|
||||
expr_, msg_ ? " (additional info: " : "", msg_ ? msg_ : "",
|
||||
msg_ ? ")" : "", current_errno);
|
||||
TEST_FAIL_MESSAGE (buffer);
|
||||
}
|
||||
return rc_;
|
||||
}
|
||||
|
||||
int test_assert_failure_message_raw_errno_helper (int rc_,
|
||||
int expected_errno_,
|
||||
const char *msg_,
|
||||
const char *expr_)
|
||||
{
|
||||
char buffer[512];
|
||||
buffer[sizeof (buffer) - 1] =
|
||||
0; // to ensure defined behavior with VC++ <= 2013
|
||||
if (rc_ != -1) {
|
||||
snprintf (buffer, sizeof (buffer) - 1,
|
||||
"%s was unexpectedly successful%s%s%s, expected "
|
||||
"errno = %i, actual return value = %i",
|
||||
expr_, msg_ ? " (additional info: " : "", msg_ ? msg_ : "",
|
||||
msg_ ? ")" : "", expected_errno_, rc_);
|
||||
TEST_FAIL_MESSAGE (buffer);
|
||||
} else {
|
||||
#if defined ZMQ_HAVE_WINDOWS
|
||||
int current_errno = WSAGetLastError ();
|
||||
#else
|
||||
int current_errno = errno;
|
||||
#endif
|
||||
if (current_errno != expected_errno_) {
|
||||
snprintf (buffer, sizeof (buffer) - 1,
|
||||
"%s failed with an unexpected error%s%s%s, expected "
|
||||
"errno = %i, actual errno = %i",
|
||||
expr_, msg_ ? " (additional info: " : "",
|
||||
msg_ ? msg_ : "", msg_ ? ")" : "", expected_errno_,
|
||||
current_errno);
|
||||
TEST_FAIL_MESSAGE (buffer);
|
||||
}
|
||||
}
|
||||
return rc_;
|
||||
}
|
||||
|
||||
void send_string_expect_success (void *socket_, const char *str_, int flags_)
|
||||
{
|
||||
const size_t len = str_ ? strlen (str_) : 0;
|
||||
const int rc = zmq_send (socket_, str_, len, flags_);
|
||||
TEST_ASSERT_EQUAL_INT ((int) len, rc);
|
||||
}
|
||||
|
||||
void recv_string_expect_success (void *socket_, const char *str_, int flags_)
|
||||
{
|
||||
const size_t len = str_ ? strlen (str_) : 0;
|
||||
char buffer[255];
|
||||
TEST_ASSERT_LESS_OR_EQUAL_MESSAGE (sizeof (buffer), len,
|
||||
"recv_string_expect_success cannot be "
|
||||
"used for strings longer than 255 "
|
||||
"characters");
|
||||
|
||||
const int rc = TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_recv (socket_, buffer, sizeof (buffer), flags_));
|
||||
TEST_ASSERT_EQUAL_INT ((int) len, rc);
|
||||
if (str_)
|
||||
TEST_ASSERT_EQUAL_STRING_LEN (str_, buffer, len);
|
||||
}
|
||||
|
||||
static void *internal_manage_test_context (bool init_, bool clear_)
|
||||
{
|
||||
static void *test_context = NULL;
|
||||
if (clear_) {
|
||||
TEST_ASSERT_NOT_NULL (test_context);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_ctx_term (test_context));
|
||||
test_context = NULL;
|
||||
} else {
|
||||
if (init_) {
|
||||
TEST_ASSERT_NULL (test_context);
|
||||
test_context = zmq_ctx_new ();
|
||||
TEST_ASSERT_NOT_NULL (test_context);
|
||||
}
|
||||
}
|
||||
return test_context;
|
||||
}
|
||||
|
||||
static void internal_manage_test_sockets (void *socket_, bool add_)
|
||||
{
|
||||
static void *test_sockets[MAX_TEST_SOCKETS];
|
||||
static size_t test_socket_count = 0;
|
||||
if (!socket_) {
|
||||
TEST_ASSERT_FALSE (add_);
|
||||
|
||||
// force-close all sockets
|
||||
if (test_socket_count) {
|
||||
for (size_t i = 0; i < test_socket_count; ++i) {
|
||||
close_zero_linger (test_sockets[i]);
|
||||
}
|
||||
fprintf (stderr,
|
||||
"WARNING: Forced closure of %i sockets, this is an "
|
||||
"implementation error unless the test case failed\n",
|
||||
(int) test_socket_count);
|
||||
test_socket_count = 0;
|
||||
}
|
||||
} else {
|
||||
if (add_) {
|
||||
++test_socket_count;
|
||||
TEST_ASSERT_LESS_THAN_MESSAGE (MAX_TEST_SOCKETS, test_socket_count,
|
||||
"MAX_TEST_SOCKETS must be "
|
||||
"increased, or you cannot use the "
|
||||
"test context");
|
||||
test_sockets[test_socket_count - 1] = socket_;
|
||||
} else {
|
||||
bool found = false;
|
||||
for (size_t i = 0; i < test_socket_count; ++i) {
|
||||
if (test_sockets[i] == socket_) {
|
||||
found = true;
|
||||
}
|
||||
if (found) {
|
||||
if (i < test_socket_count)
|
||||
test_sockets[i] = test_sockets[i + 1];
|
||||
}
|
||||
}
|
||||
TEST_ASSERT_TRUE_MESSAGE (found,
|
||||
"Attempted to close a socket that was "
|
||||
"not created by test_context_socket");
|
||||
--test_socket_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setup_test_context ()
|
||||
{
|
||||
internal_manage_test_context (true, false);
|
||||
}
|
||||
|
||||
void *get_test_context ()
|
||||
{
|
||||
return internal_manage_test_context (false, false);
|
||||
}
|
||||
|
||||
void teardown_test_context ()
|
||||
{
|
||||
// this condition allows an explicit call to teardown_test_context from a
|
||||
// test. if this is never used, it should probably be removed, to detect
|
||||
// misuses
|
||||
if (get_test_context ()) {
|
||||
internal_manage_test_sockets (NULL, false);
|
||||
internal_manage_test_context (false, true);
|
||||
}
|
||||
}
|
||||
|
||||
void *test_context_socket (int type_)
|
||||
{
|
||||
void *const socket = zmq_socket (get_test_context (), type_);
|
||||
TEST_ASSERT_NOT_NULL (socket);
|
||||
internal_manage_test_sockets (socket, true);
|
||||
return socket;
|
||||
}
|
||||
|
||||
void *test_context_socket_close (void *socket_)
|
||||
{
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_close (socket_));
|
||||
internal_manage_test_sockets (socket_, false);
|
||||
return socket_;
|
||||
}
|
||||
|
||||
void *test_context_socket_close_zero_linger (void *socket_)
|
||||
{
|
||||
const int linger = 0;
|
||||
int rc = zmq_setsockopt (socket_, ZMQ_LINGER, &linger, sizeof (linger));
|
||||
TEST_ASSERT_TRUE (rc == 0 || zmq_errno () == ETERM);
|
||||
return test_context_socket_close (socket_);
|
||||
}
|
||||
|
||||
void test_bind (void *socket_,
|
||||
const char *bind_address_,
|
||||
char *my_endpoint_,
|
||||
size_t len_)
|
||||
{
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (socket_, bind_address_));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_getsockopt (socket_, ZMQ_LAST_ENDPOINT, my_endpoint_, &len_));
|
||||
}
|
||||
|
||||
void bind_loopback (void *socket_, int ipv6_, char *my_endpoint_, size_t len_)
|
||||
{
|
||||
if (ipv6_ && !is_ipv6_available ()) {
|
||||
TEST_IGNORE_MESSAGE ("ipv6 is not available");
|
||||
}
|
||||
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (socket_, ZMQ_IPV6, &ipv6_, sizeof (int)));
|
||||
|
||||
test_bind (socket_, ipv6_ ? "tcp://[::1]:*" : "tcp://127.0.0.1:*",
|
||||
my_endpoint_, len_);
|
||||
}
|
||||
|
||||
void bind_loopback_ipv4 (void *socket_, char *my_endpoint_, size_t len_)
|
||||
{
|
||||
bind_loopback (socket_, false, my_endpoint_, len_);
|
||||
}
|
||||
|
||||
void bind_loopback_ipv6 (void *socket_, char *my_endpoint_, size_t len_)
|
||||
{
|
||||
bind_loopback (socket_, true, my_endpoint_, len_);
|
||||
}
|
||||
|
||||
void bind_loopback_ipc (void *socket_, char *my_endpoint_, size_t len_)
|
||||
{
|
||||
if (!zmq_has ("ipc")) {
|
||||
TEST_IGNORE_MESSAGE ("ipc is not available");
|
||||
}
|
||||
|
||||
test_bind (socket_, "ipc://*", my_endpoint_, len_);
|
||||
}
|
||||
|
||||
void bind_loopback_tipc (void *socket_, char *my_endpoint_, size_t len_)
|
||||
{
|
||||
if (!is_tipc_available ()) {
|
||||
TEST_IGNORE_MESSAGE ("tipc is not available");
|
||||
}
|
||||
|
||||
test_bind (socket_, "tipc://<*>", my_endpoint_, len_);
|
||||
}
|
||||
|
||||
#if !defined(ZMQ_HAVE_WINDOWS) && !defined(ZMQ_HAVE_GNU)
|
||||
void make_random_ipc_endpoint (char *out_endpoint_)
|
||||
{
|
||||
char random_file[16];
|
||||
strcpy (random_file, "tmpXXXXXX");
|
||||
|
||||
#ifdef HAVE_MKDTEMP
|
||||
TEST_ASSERT_TRUE (mkdtemp (random_file));
|
||||
strcat (random_file, "/ipc");
|
||||
#else
|
||||
int fd = mkstemp (random_file);
|
||||
TEST_ASSERT_TRUE (fd != -1);
|
||||
close (fd);
|
||||
#endif
|
||||
|
||||
strcpy (out_endpoint_, "ipc://");
|
||||
strcat (out_endpoint_, random_file);
|
||||
}
|
||||
#endif
|
@ -35,98 +35,77 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <unity.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1800
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
// Internal helper functions that are not intended to be directly called from
|
||||
// tests. They must be declared in the header since they are used by macros.
|
||||
|
||||
int test_assert_success_message_errno_helper (int rc_,
|
||||
const char *msg_,
|
||||
const char *expr_)
|
||||
{
|
||||
if (rc_ == -1) {
|
||||
char buffer[512];
|
||||
buffer[sizeof (buffer) - 1] =
|
||||
0; // to ensure defined behavior with VC++ <= 2013
|
||||
snprintf (buffer, sizeof (buffer) - 1,
|
||||
"%s failed%s%s%s, errno = %i (%s)", expr_,
|
||||
msg_ ? " (additional info: " : "", msg_ ? msg_ : "",
|
||||
msg_ ? ")" : "", zmq_errno (), zmq_strerror (zmq_errno ()));
|
||||
TEST_FAIL_MESSAGE (buffer);
|
||||
}
|
||||
return rc_;
|
||||
}
|
||||
const char *expr_);
|
||||
|
||||
int test_assert_success_message_raw_errno_helper (int rc_,
|
||||
const char *msg_,
|
||||
const char *expr_)
|
||||
{
|
||||
if (rc_ == -1) {
|
||||
#if defined ZMQ_HAVE_WINDOWS
|
||||
int current_errno = WSAGetLastError ();
|
||||
#else
|
||||
int current_errno = errno;
|
||||
#endif
|
||||
|
||||
char buffer[512];
|
||||
buffer[sizeof (buffer) - 1] =
|
||||
0; // to ensure defined behavior with VC++ <= 2013
|
||||
snprintf (buffer, sizeof (buffer) - 1, "%s failed%s%s%s, errno = %i",
|
||||
expr_, msg_ ? " (additional info: " : "", msg_ ? msg_ : "",
|
||||
msg_ ? ")" : "", current_errno);
|
||||
TEST_FAIL_MESSAGE (buffer);
|
||||
}
|
||||
return rc_;
|
||||
}
|
||||
const char *expr_);
|
||||
|
||||
int test_assert_failure_message_raw_errno_helper (int rc_,
|
||||
int expected_errno_,
|
||||
const char *msg_,
|
||||
const char *expr_)
|
||||
{
|
||||
char buffer[512];
|
||||
buffer[sizeof (buffer) - 1] =
|
||||
0; // to ensure defined behavior with VC++ <= 2013
|
||||
if (rc_ != -1) {
|
||||
snprintf (buffer, sizeof (buffer) - 1,
|
||||
"%s was unexpectedly successful%s%s%s, expected "
|
||||
"errno = %i, actual return value = %i",
|
||||
expr_, msg_ ? " (additional info: " : "", msg_ ? msg_ : "",
|
||||
msg_ ? ")" : "", expected_errno_, rc_);
|
||||
TEST_FAIL_MESSAGE (buffer);
|
||||
} else {
|
||||
#if defined ZMQ_HAVE_WINDOWS
|
||||
int current_errno = WSAGetLastError ();
|
||||
#else
|
||||
int current_errno = errno;
|
||||
#endif
|
||||
if (current_errno != expected_errno_) {
|
||||
snprintf (buffer, sizeof (buffer) - 1,
|
||||
"%s failed with an unexpected error%s%s%s, expected "
|
||||
"errno = %i, actual errno = %i",
|
||||
expr_, msg_ ? " (additional info: " : "",
|
||||
msg_ ? msg_ : "", msg_ ? ")" : "", expected_errno_,
|
||||
current_errno);
|
||||
TEST_FAIL_MESSAGE (buffer);
|
||||
}
|
||||
}
|
||||
return rc_;
|
||||
}
|
||||
const char *expr_);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Macros extending Unity's TEST_ASSERT_* macros in a similar fashion.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// For TEST_ASSERT_SUCCESS_ERRNO, TEST_ASSERT_SUCCESS_MESSAGE_ERRNO and
|
||||
// TEST_ASSERT_FAILURE_ERRNO, 'expr' must be an expression evaluating
|
||||
// to a result in the style of a libzmq API function, i.e. an integer which
|
||||
// is non-negative in case of success, and -1 in case of a failure, and sets
|
||||
// the value returned by zmq_errno () to the error code.
|
||||
// TEST_ASSERT_SUCCESS_RAW_ERRNO and TEST_ASSERT_FAILURE_RAW_ERRNO are similar,
|
||||
// but used with the native socket API functions, and expect that the error
|
||||
// code can be retrieved in the native way (i.e. WSAGetLastError on Windows,
|
||||
// and errno otherwise).
|
||||
|
||||
// Asserts that the libzmq API 'expr' is successful. In case of a failure, the
|
||||
// assertion message includes the literal 'expr', the error number as
|
||||
// determined by zmq_errno(), and the additional 'msg'.
|
||||
// In case of success, the result of the macro is the result of 'expr'.
|
||||
#define TEST_ASSERT_SUCCESS_MESSAGE_ERRNO(expr, msg) \
|
||||
test_assert_success_message_errno_helper (expr, msg, #expr)
|
||||
|
||||
// Asserts that the libzmq API 'expr' is successful. In case of a failure, the
|
||||
// assertion message includes the literal 'expr' and the error code.
|
||||
// A typical use would be:
|
||||
// TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (socket, endpoint));
|
||||
// In case of success, the result of the macro is the result of 'expr'.
|
||||
//
|
||||
// If an additional message should be displayed in case of a failure, use
|
||||
// TEST_ASSERT_SUCCESS_MESSAGE_ERRNO.
|
||||
#define TEST_ASSERT_SUCCESS_ERRNO(expr) \
|
||||
test_assert_success_message_errno_helper (expr, NULL, #expr)
|
||||
|
||||
// Asserts that the socket API 'expr' is successful. In case of a failure, the
|
||||
// assertion message includes the literal 'expr' and the error code.
|
||||
// A typical use would be:
|
||||
// TEST_ASSERT_SUCCESS_RAW_ERRNO (send (fd, buffer, 64, 0));
|
||||
// In case of success, the result of the macro is the result of 'expr'.
|
||||
#define TEST_ASSERT_SUCCESS_RAW_ERRNO(expr) \
|
||||
test_assert_success_message_raw_errno_helper (expr, NULL, #expr)
|
||||
|
||||
// Asserts that the socket API 'expr' is not successful, and the error code is
|
||||
// 'error_code'. In case of an unexpected succces, or a failure with an
|
||||
// unexpected error code, the assertion message includes the literal 'expr'
|
||||
// and, in case of a failure, the actual error code.
|
||||
#define TEST_ASSERT_FAILURE_RAW_ERRNO(error_code, expr) \
|
||||
test_assert_failure_message_raw_errno_helper (expr, error_code, NULL, #expr)
|
||||
|
||||
// Asserts that the libzmq API 'expr' is not successful, and the error code is
|
||||
// 'error_code'. In case of an unexpected succces, or a failure with an
|
||||
// unexpected error code, the assertion message includes the literal 'expr'
|
||||
// and, in case of a failure, the actual error code.
|
||||
#define TEST_ASSERT_FAILURE_ERRNO(error_code, expr) \
|
||||
{ \
|
||||
int _rc = (expr); \
|
||||
@ -134,29 +113,35 @@ int test_assert_failure_message_raw_errno_helper (int rc_,
|
||||
TEST_ASSERT_EQUAL_INT (error_code, errno); \
|
||||
}
|
||||
|
||||
void send_string_expect_success (void *socket_, const char *str_, int flags_)
|
||||
{
|
||||
const size_t len = str_ ? strlen (str_) : 0;
|
||||
const int rc = zmq_send (socket_, str_, len, flags_);
|
||||
TEST_ASSERT_EQUAL_INT ((int) len, rc);
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Utility functions for testing sending and receiving.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void recv_string_expect_success (void *socket_, const char *str_, int flags_)
|
||||
{
|
||||
const size_t len = str_ ? strlen (str_) : 0;
|
||||
char buffer[255];
|
||||
TEST_ASSERT_LESS_OR_EQUAL_MESSAGE (sizeof (buffer), len,
|
||||
"recv_string_expect_success cannot be "
|
||||
"used for strings longer than 255 "
|
||||
"characters");
|
||||
// Sends a string via a libzmq socket, and expects the operation to be
|
||||
// successful (the meaning of which depends on the socket type and configured
|
||||
// options, and might include dropping the message). Otherwise, a Unity test
|
||||
// assertion is triggered.
|
||||
// 'socket_' must be the libzmq socket to use for sending.
|
||||
// 'str_' must be a 0-terminated string.
|
||||
// 'flags_' are as documented by the zmq_send function.
|
||||
void send_string_expect_success (void *socket_, const char *str_, int flags_);
|
||||
|
||||
const int rc = TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_recv (socket_, buffer, sizeof (buffer), flags_));
|
||||
TEST_ASSERT_EQUAL_INT ((int) len, rc);
|
||||
if (str_)
|
||||
TEST_ASSERT_EQUAL_STRING_LEN (str_, buffer, len);
|
||||
}
|
||||
// Receives a message via a libzmq socket, and expects the operation to be
|
||||
// successful, and the message to be a given string. Otherwise, a Unity test
|
||||
// assertion is triggered.
|
||||
// 'socket_' must be the libzmq socket to use for receiving.
|
||||
// 'str_' must be a 0-terminated string.
|
||||
// 'flags_' are as documented by the zmq_recv function.
|
||||
void recv_string_expect_success (void *socket_, const char *str_, int flags_);
|
||||
|
||||
// Sends a byte array via a libzmq socket, and expects the operation to be
|
||||
// successful (the meaning of which depends on the socket type and configured
|
||||
// options, and might include dropping the message). Otherwise, a Unity test
|
||||
// assertion is triggered.
|
||||
// 'socket_' must be the libzmq socket to use for sending.
|
||||
// 'array_' must be a C uint8_t array. The array size is automatically
|
||||
// determined via template argument deduction.
|
||||
// 'flags_' are as documented by the zmq_send function.
|
||||
template <size_t SIZE>
|
||||
void send_array_expect_success (void *socket_,
|
||||
const uint8_t (&array_)[SIZE],
|
||||
@ -166,6 +151,13 @@ void send_array_expect_success (void *socket_,
|
||||
TEST_ASSERT_EQUAL_INT (static_cast<int> (SIZE), rc);
|
||||
}
|
||||
|
||||
// Receives a message via a libzmq socket, and expects the operation to be
|
||||
// successful, and the message to be a given byte array. Otherwise, a Unity
|
||||
// test assertion is triggered.
|
||||
// 'socket_' must be the libzmq socket to use for receiving.
|
||||
// 'array_' must be a C uint8_t array. The array size is automatically
|
||||
// determined via template argument deduction.
|
||||
// 'flags_' are as documented by the zmq_recv function.
|
||||
template <size_t SIZE>
|
||||
void recv_array_expect_success (void *socket_,
|
||||
const uint8_t (&array_)[SIZE],
|
||||
@ -183,188 +175,87 @@ void recv_array_expect_success (void *socket_,
|
||||
TEST_ASSERT_EQUAL_UINT8_ARRAY (array_, buffer, SIZE);
|
||||
}
|
||||
|
||||
// do not call from tests directly, use setup_test_context, get_test_context and teardown_test_context only
|
||||
void *internal_manage_test_context (bool init_, bool clear_)
|
||||
{
|
||||
static void *test_context = NULL;
|
||||
if (clear_) {
|
||||
TEST_ASSERT_NOT_NULL (test_context);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_ctx_term (test_context));
|
||||
test_context = NULL;
|
||||
} else {
|
||||
if (init_) {
|
||||
TEST_ASSERT_NULL (test_context);
|
||||
test_context = zmq_ctx_new ();
|
||||
TEST_ASSERT_NOT_NULL (test_context);
|
||||
}
|
||||
}
|
||||
return test_context;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Utility function for handling a test libzmq context, that is set up and
|
||||
// torn down for each Unity test case, such that a clean context is available
|
||||
// for each test case, and some consistency checks can be performed.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// The maximum number of sockets that can be managed by the test context.
|
||||
#define MAX_TEST_SOCKETS 128
|
||||
|
||||
void internal_manage_test_sockets (void *socket_, bool add_)
|
||||
{
|
||||
static void *test_sockets[MAX_TEST_SOCKETS];
|
||||
static size_t test_socket_count = 0;
|
||||
if (!socket_) {
|
||||
assert (!add_);
|
||||
// Expected to be called during Unity's setUp function.
|
||||
void setup_test_context ();
|
||||
|
||||
// force-close all sockets
|
||||
if (test_socket_count) {
|
||||
for (size_t i = 0; i < test_socket_count; ++i) {
|
||||
close_zero_linger (test_sockets[i]);
|
||||
}
|
||||
fprintf (stderr,
|
||||
"WARNING: Forced closure of %i sockets, this is an "
|
||||
"implementation error unless the test case failed\n",
|
||||
(int) test_socket_count);
|
||||
test_socket_count = 0;
|
||||
}
|
||||
} else {
|
||||
if (add_) {
|
||||
++test_socket_count;
|
||||
TEST_ASSERT_LESS_THAN_MESSAGE (MAX_TEST_SOCKETS, test_socket_count,
|
||||
"MAX_TEST_SOCKETS must be "
|
||||
"increased, or you cannot use the "
|
||||
"test context");
|
||||
test_sockets[test_socket_count - 1] = socket_;
|
||||
} else {
|
||||
bool found = false;
|
||||
for (size_t i = 0; i < test_socket_count; ++i) {
|
||||
if (test_sockets[i] == socket_) {
|
||||
found = true;
|
||||
}
|
||||
if (found) {
|
||||
if (i < test_socket_count)
|
||||
test_sockets[i] = test_sockets[i + 1];
|
||||
}
|
||||
}
|
||||
TEST_ASSERT_TRUE_MESSAGE (found,
|
||||
"Attempted to close a socket that was "
|
||||
"not created by test_context_socket");
|
||||
--test_socket_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Returns the test context, e.g. to create sockets in another thread using
|
||||
// zmq_socket, or set context options.
|
||||
void *get_test_context ();
|
||||
|
||||
void setup_test_context ()
|
||||
{
|
||||
internal_manage_test_context (true, false);
|
||||
}
|
||||
// Expected to be called during Unity's tearDown function. Checks that all
|
||||
// sockets created via test_context_socket have been properly closed using
|
||||
// test_context_socket_close or test_context_socket_close_zero_linger, and generates a warning otherwise.
|
||||
void teardown_test_context ();
|
||||
|
||||
void *get_test_context ()
|
||||
{
|
||||
return internal_manage_test_context (false, false);
|
||||
}
|
||||
// Creates a libzmq socket on the test context, and tracks its lifecycle.
|
||||
// You MUST use test_context_socket_close or test_context_socket_close_zero_linger
|
||||
// to close a socket created via this function, otherwise undefined behaviour
|
||||
// will result.
|
||||
// CAUTION: this function is not thread-safe, and may only be used from the
|
||||
// main thread.
|
||||
void *test_context_socket (int type_);
|
||||
|
||||
void teardown_test_context ()
|
||||
{
|
||||
// this condition allows an explicit call to teardown_test_context from a
|
||||
// test. if this is never used, it should probably be removed, to detect
|
||||
// misuses
|
||||
if (get_test_context ()) {
|
||||
internal_manage_test_sockets (NULL, false);
|
||||
internal_manage_test_context (false, true);
|
||||
}
|
||||
}
|
||||
// Closes a socket created via test_context_socket.
|
||||
// CAUTION: this function is not thread-safe, and may only be used from the
|
||||
// main thread.
|
||||
void *test_context_socket_close (void *socket_);
|
||||
|
||||
void *test_context_socket (int type_)
|
||||
{
|
||||
void *const socket = zmq_socket (get_test_context (), type_);
|
||||
TEST_ASSERT_NOT_NULL (socket);
|
||||
internal_manage_test_sockets (socket, true);
|
||||
return socket;
|
||||
}
|
||||
// Closes a socket created via test_context_socket after setting its linger
|
||||
// timeout to 0.
|
||||
// CAUTION: this function is not thread-safe, and may only be used from the
|
||||
// main thread.
|
||||
void *test_context_socket_close_zero_linger (void *socket_);
|
||||
|
||||
void *test_context_socket_close (void *socket_)
|
||||
{
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_close (socket_));
|
||||
internal_manage_test_sockets (socket_, false);
|
||||
return socket_;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Utility function for handling wildcard binds.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void *test_context_socket_close_zero_linger (void *socket_)
|
||||
{
|
||||
const int linger = 0;
|
||||
int rc = zmq_setsockopt (socket_, ZMQ_LINGER, &linger, sizeof (linger));
|
||||
TEST_ASSERT_TRUE (rc == 0 || zmq_errno () == ETERM);
|
||||
return test_context_socket_close (socket_);
|
||||
}
|
||||
// All function binds a socket to some wildcard address, and retrieve the bound
|
||||
// endpoint via the ZMQ_LAST_ENDPOINT socket option to a given buffer.
|
||||
// Triggers a Unity test assertion in case of a failure (including the buffer
|
||||
// being too small for the resulting endpoint string).
|
||||
|
||||
// Binds to an explicitly given (wildcard) address.
|
||||
// TODO redesign such that this function is not necessary to be exposed, but
|
||||
// the protocol to use is rather specified via an enum value
|
||||
void test_bind (void *socket_,
|
||||
const char *bind_address_,
|
||||
char *my_endpoint_,
|
||||
size_t len_)
|
||||
{
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (socket_, bind_address_));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_getsockopt (socket_, ZMQ_LAST_ENDPOINT, my_endpoint_, &len_));
|
||||
}
|
||||
size_t len_);
|
||||
|
||||
void bind_loopback (void *socket_, int ipv6_, char *my_endpoint_, size_t len_)
|
||||
{
|
||||
if (ipv6_ && !is_ipv6_available ()) {
|
||||
TEST_IGNORE_MESSAGE ("ipv6 is not available");
|
||||
}
|
||||
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (socket_, ZMQ_IPV6, &ipv6_, sizeof (int)));
|
||||
|
||||
test_bind (socket_, ipv6_ ? "tcp://[::1]:*" : "tcp://127.0.0.1:*",
|
||||
my_endpoint_, len_);
|
||||
}
|
||||
// Binds to a tcp endpoint using the ipv4 or ipv6 loopback wildcard address.
|
||||
void bind_loopback (void *socket_, int ipv6_, char *my_endpoint_, size_t len_);
|
||||
|
||||
typedef void (*bind_function_t) (void *socket_,
|
||||
char *my_endpoint_,
|
||||
size_t len_);
|
||||
|
||||
void bind_loopback_ipv4 (void *socket_, char *my_endpoint_, size_t len_)
|
||||
{
|
||||
bind_loopback (socket_, false, my_endpoint_, len_);
|
||||
}
|
||||
// Binds to a tcp endpoint using the ipv4 loopback wildcard address.
|
||||
void bind_loopback_ipv4 (void *socket_, char *my_endpoint_, size_t len_);
|
||||
|
||||
void bind_loopback_ipv6 (void *socket_, char *my_endpoint_, size_t len_)
|
||||
{
|
||||
bind_loopback (socket_, true, my_endpoint_, len_);
|
||||
}
|
||||
// Binds to a tcp endpoint using the ipv6 loopback wildcard address.
|
||||
void bind_loopback_ipv6 (void *socket_, char *my_endpoint_, size_t len_);
|
||||
|
||||
void bind_loopback_ipc (void *socket_, char *my_endpoint_, size_t len_)
|
||||
{
|
||||
if (!zmq_has ("ipc")) {
|
||||
TEST_IGNORE_MESSAGE ("ipc is not available");
|
||||
}
|
||||
// Binds to an ipc endpoint using the ipc wildcard address.
|
||||
// Note that the returned address cannot be reused to bind a second socket.
|
||||
// If you need to do this, use make_random_ipc_endpoint instead.
|
||||
void bind_loopback_ipc (void *socket_, char *my_endpoint_, size_t len_);
|
||||
|
||||
test_bind (socket_, "ipc://*", my_endpoint_, len_);
|
||||
}
|
||||
|
||||
void bind_loopback_tipc (void *socket_, char *my_endpoint_, size_t len_)
|
||||
{
|
||||
if (!is_tipc_available ()) {
|
||||
TEST_IGNORE_MESSAGE ("tipc is not available");
|
||||
}
|
||||
|
||||
test_bind (socket_, "tipc://<*>", my_endpoint_, len_);
|
||||
}
|
||||
// Binds to an ipc endpoint using the tipc wildcard address.
|
||||
void bind_loopback_tipc (void *socket_, char *my_endpoint_, size_t len_);
|
||||
|
||||
#if !defined(ZMQ_HAVE_WINDOWS) && !defined(ZMQ_HAVE_GNU)
|
||||
// utility function to create a random IPC endpoint, similar to what a ipc://*
|
||||
// wildcard binding does, but in a way it can be reused for multiple binds
|
||||
void make_random_ipc_endpoint (char *out_endpoint_)
|
||||
{
|
||||
char random_file[16];
|
||||
strcpy (random_file, "tmpXXXXXX");
|
||||
|
||||
#ifdef HAVE_MKDTEMP
|
||||
TEST_ASSERT_TRUE (mkdtemp (random_file));
|
||||
strcat (random_file, "/ipc");
|
||||
#else
|
||||
int fd = mkstemp (random_file);
|
||||
TEST_ASSERT_TRUE (fd != -1);
|
||||
close (fd);
|
||||
#endif
|
||||
|
||||
strcpy (out_endpoint_, "ipc://");
|
||||
strcat (out_endpoint_, random_file);
|
||||
}
|
||||
// TODO also add a len parameter here
|
||||
void make_random_ipc_endpoint (char *out_endpoint_);
|
||||
#endif
|
||||
|
@ -35,7 +35,7 @@ foreach(test ${unittests})
|
||||
link_directories(${test} PRIVATE "${ZeroMQ_SOURCE_DIR}/../lib")
|
||||
endif()
|
||||
|
||||
target_link_libraries(${test} libzmq-static ${OPTIONAL_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} unity)
|
||||
target_link_libraries(${test} testutil-static)
|
||||
|
||||
if(RT_LIBRARY)
|
||||
target_link_libraries(${test} ${RT_LIBRARY})
|
||||
|
@ -25,6 +25,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include <ip_resolver.hpp>
|
||||
#include <ip.hpp>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
void setUp ()
|
||||
{
|
||||
}
|
||||
@ -62,7 +68,7 @@ class test_ip_resolver_t : public zmq::ip_resolver_t
|
||||
unsigned lut_len = sizeof (dns_lut) / sizeof (dns_lut[0]);
|
||||
struct addrinfo ai;
|
||||
|
||||
assert (service_ == NULL);
|
||||
TEST_ASSERT_NULL (service_);
|
||||
|
||||
bool ipv6 = (hints_->ai_family == AF_INET6);
|
||||
bool no_dns = (hints_->ai_flags & AI_NUMERICHOST) != 0;
|
||||
@ -805,9 +811,7 @@ static void test_addr (int family_, const char *addr_, bool multicast_)
|
||||
test_ip_resolver_t resolver (resolver_opts);
|
||||
zmq::ip_addr_t addr;
|
||||
|
||||
int rc = resolver.resolve (&addr, addr_);
|
||||
|
||||
assert (rc == 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (resolver.resolve (&addr, addr_));
|
||||
|
||||
TEST_ASSERT_EQUAL (family_, addr.family ());
|
||||
TEST_ASSERT_EQUAL (multicast_, addr.is_multicast ());
|
||||
|
@ -21,28 +21,30 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define __UNITTEST_RESOLVER_COMMON_INCLUDED__
|
||||
|
||||
#include <ip_resolver.hpp>
|
||||
#include <string.h>
|
||||
|
||||
// Attempt a resolution and test the results.
|
||||
//
|
||||
// On windows we can receive an IPv4 address even when an IPv6 is requested, if
|
||||
// we're in this situation then we compare to 'expected_addr_v4_failover_'
|
||||
// instead.
|
||||
void validate_address(int family, const zmq::ip_addr_t *addr_,
|
||||
const char *expected_addr_,
|
||||
uint16_t expected_port_ = 0,
|
||||
uint16_t expected_zone_ = 0,
|
||||
const char *expected_addr_v4_failover_ = NULL)
|
||||
void validate_address (int family,
|
||||
const zmq::ip_addr_t *addr_,
|
||||
const char *expected_addr_,
|
||||
uint16_t expected_port_ = 0,
|
||||
uint16_t expected_zone_ = 0,
|
||||
const char *expected_addr_v4_failover_ = NULL)
|
||||
{
|
||||
#if defined ZMQ_HAVE_WINDOWS
|
||||
if (family == AF_INET6 && expected_addr_v4_failover_ != NULL &&
|
||||
addr_->family () == AF_INET) {
|
||||
#if defined ZMQ_HAVE_WINDOWS
|
||||
if (family == AF_INET6 && expected_addr_v4_failover_ != NULL
|
||||
&& addr_->family () == AF_INET) {
|
||||
// We've requested an IPv6 but the system gave us an IPv4, use the
|
||||
// failover address
|
||||
family = AF_INET;
|
||||
expected_addr_ = expected_addr_v4_failover_;
|
||||
}
|
||||
#else
|
||||
(void)expected_addr_v4_failover_;
|
||||
(void) expected_addr_v4_failover_;
|
||||
#endif
|
||||
|
||||
TEST_ASSERT_EQUAL (family, addr_->family ());
|
||||
@ -51,7 +53,8 @@ void validate_address(int family, const zmq::ip_addr_t *addr_,
|
||||
struct in6_addr expected_addr;
|
||||
const sockaddr_in6 *ip6_addr = &addr_->ipv6;
|
||||
|
||||
assert (test_inet_pton (AF_INET6, expected_addr_, &expected_addr) == 1);
|
||||
TEST_ASSERT_EQUAL (
|
||||
1, test_inet_pton (AF_INET6, expected_addr_, &expected_addr));
|
||||
|
||||
int neq = memcmp (&ip6_addr->sin6_addr, &expected_addr,
|
||||
sizeof (expected_addr_));
|
||||
@ -63,7 +66,8 @@ void validate_address(int family, const zmq::ip_addr_t *addr_,
|
||||
struct in_addr expected_addr;
|
||||
const sockaddr_in *ip4_addr = &addr_->ipv4;
|
||||
|
||||
assert (test_inet_pton (AF_INET, expected_addr_, &expected_addr) == 1);
|
||||
TEST_ASSERT_EQUAL (
|
||||
1, test_inet_pton (AF_INET, expected_addr_, &expected_addr));
|
||||
|
||||
TEST_ASSERT_EQUAL (expected_addr.s_addr, ip4_addr->sin_addr.s_addr);
|
||||
TEST_ASSERT_EQUAL (htons (expected_port_), ip4_addr->sin_port);
|
||||
|
Loading…
x
Reference in New Issue
Block a user