Problem: test utilities are in headers and recompiled for every test

Solution: move test utilities to separate testutil library
This commit is contained in:
Simon Giesecke 2019-03-23 06:27:12 -04:00
parent cbd4157638
commit 347708bcf2
12 changed files with 1774 additions and 1446 deletions

1
.gitignore vendored
View File

@ -7,6 +7,7 @@ doc/Makefile
Makefile.in
configure
libtool
libtestutil.a
libunity.a
config
config.status

View File

@ -463,314 +463,328 @@ 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 ${UNITY_LIBS}
tests_test_system_CPPFLAGS = ${UNITY_CPPFLAGS}
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_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_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_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_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_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 ${UNITY_LIBS}
tests_test_msg_flags_CPPFLAGS = ${UNITY_CPPFLAGS}
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 ${UNITY_LIBS}
tests_test_msg_ffn_CPPFLAGS = ${UNITY_CPPFLAGS}
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_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 ${UNITY_LIBS}
tests_test_disconnect_inproc_CPPFLAGS = ${UNITY_CPPFLAGS}
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 ${UNITY_LIBS}
tests_test_ctx_options_CPPFLAGS = ${UNITY_CPPFLAGS}
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_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 ${UNITY_LIBS}
tests_test_proxy_CPPFLAGS = ${UNITY_CPPFLAGS}
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 ${UNITY_LIBS}
tests_test_proxy_single_socket_CPPFLAGS = ${UNITY_CPPFLAGS}
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 ${UNITY_LIBS}
tests_test_proxy_terminate_CPPFLAGS = ${UNITY_CPPFLAGS}
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 ${UNITY_LIBS}
tests_test_getsockopt_memset_CPPFLAGS = ${UNITY_CPPFLAGS}
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 ${UNITY_LIBS}
tests_test_many_sockets_CPPFLAGS = ${UNITY_CPPFLAGS}
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
@ -795,9 +809,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
@ -823,54 +837,54 @@ 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_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_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_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 ${UNITY_LIBS}
tests_test_fork_CPPFLAGS = ${UNITY_CPPFLAGS}
tests_test_fork_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
tests_test_fork_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
endif
endif
@ -890,40 +904,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 ${UNITY_LIBS}
tests_test_router_mandatory_tipc_CPPFLAGS = ${UNITY_CPPFLAGS}
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 ${UNITY_LIBS}
tests_test_term_endpoint_tipc_CPPFLAGS = ${UNITY_CPPFLAGS}
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
@ -931,8 +945,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 ${UNITY_LIBS}
tests_test_security_gssapi_CPPFLAGS = ${UNITY_CPPFLAGS}
tests_test_security_gssapi_LDADD = src/libzmq.la ${TESTUTIL_LIBS}
tests_test_security_gssapi_CPPFLAGS = ${TESTUTIL_CPPFLAGS}
endif
@ -941,8 +955,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
@ -950,14 +964,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 ${UNITY_LIBS}
test_pair_vmci_CPPFLAGS = ${UNITY_CPPFLAGS}
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 ${UNITY_LIBS}
test_reqrep_vmci_CPPFLAGS = ${UNITY_CPPFLAGS}
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@
@ -975,40 +989,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
@ -1022,52 +1036,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}

View File

@ -173,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()
@ -181,12 +207,7 @@ 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}")
foreach(test ${tests})
@ -196,14 +217,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

365
tests/testutil.cpp Normal file
View File

@ -0,0 +1,365 @@
/*
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"
const char *SEQ_END = (const char *) 1;
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 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);
}
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) {
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_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 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 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);
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 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
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;
}

View File

@ -100,7 +100,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 +119,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 +134,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)))
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

View File

@ -0,0 +1,346 @@
/*
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"
// 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));
}
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);
}

View File

@ -30,114 +30,33 @@
#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 expect_monitor_event (void *monitor_, int expected_event_);
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_);
}
int 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 expected_err_);
// expects that one or more occurrences of the expected event are received
// via the specified socket monitor
@ -149,216 +68,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

398
tests/testutil_security.cpp Normal file
View File

@ -0,0 +1,398 @@
/*
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"
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);
}
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);
}

View File

@ -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
@ -330,24 +124,7 @@ void zap_handler (void * /*unused_*/)
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_));
}
const char *monitor_endpoint_);
void setup_context_and_server_side (
void **zap_control_,
@ -358,84 +135,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 +154,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

302
tests/testutil_unity.cpp Normal file
View File

@ -0,0 +1,302 @@
/*
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"
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);
}
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;
}
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_);
// 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

View File

@ -35,85 +35,22 @@ 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
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_);
#define TEST_ASSERT_SUCCESS_MESSAGE_ERRNO(expr, msg) \
test_assert_success_message_errno_helper (expr, msg, #expr)
@ -134,28 +71,9 @@ 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);
}
void send_string_expect_success (void *socket_, const char *str_, int flags_);
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);
}
void recv_string_expect_success (void *socket_, const char *str_, int flags_);
template <size_t SIZE>
void send_array_expect_success (void *socket_,
@ -184,187 +102,45 @@ void recv_array_expect_success (void *socket_,
}
// 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;
}
void *internal_manage_test_context (bool init_, bool clear_);
#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_);
void internal_manage_test_sockets (void *socket_, bool 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 ();
void setup_test_context ()
{
internal_manage_test_context (true, false);
}
void *get_test_context ();
void *get_test_context ()
{
return internal_manage_test_context (false, false);
}
void teardown_test_context ();
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 *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_);
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_context_socket_close_zero_linger (void *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_));
}
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_);
}
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_);
}
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_);
}
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");
}
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_);
}
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);
}
void make_random_ipc_endpoint (char *out_endpoint_);
#endif

View File

@ -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})