From 19060345e4eb9e1e9410d8567364f25c94696689 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Fri, 9 Mar 2018 16:47:42 +0000 Subject: [PATCH] Problem: TIPC availability check is too strict (#2977) * Problem: TIPC availability check is too strict Solution: at build time only check if the API is available. In the tests do a first check and a skip if the functionality is not available. TIPC needs an in-tree but not loaded by default kernel module, tipc.ko to be loaded, which requires root, so it is unlikely to be available on any build system by default. This will allow most distributions to ship with TIPC support built in, and to avoid tests failure if the module is not there. * Problem: no Travis tests for TIPC Solution: mark one job with sudo: required and load the kernel module * Problem: CMake fails when test returns 77 (skip) Solution: set property to let it mark the test as skipped as intended --- .travis.yml | 3 ++- builds/cmake/Modules/ZMQSourceRunChecks.cmake | 7 ------ ci_build.sh | 4 ++++ configure.ac | 7 ------ tests/CMakeLists.txt | 1 + tests/test_address_tipc.cpp | 5 ++++ tests/test_connect_delay_tipc.cpp | 5 ++++ tests/test_pair_tipc.cpp | 5 ++++ tests/test_reqrep_device_tipc.cpp | 5 ++++ tests/test_reqrep_tipc.cpp | 5 ++++ tests/test_router_mandatory_tipc.cpp | 5 ++++ tests/test_shutdown_stress_tipc.cpp | 5 ++++ tests/test_sub_forward_tipc.cpp | 5 ++++ tests/test_term_endpoint_tipc.cpp | 5 ++++ tests/testutil.hpp | 23 +++++++++++++++++++ 15 files changed, 75 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index b87f722d..9001d948 100644 --- a/.travis.yml +++ b/.travis.yml @@ -57,8 +57,9 @@ matrix: - libsodium-dev - asciidoc - xmlto - - env: BUILD_TYPE=default CURVE=libsodium DRAFT=enabled GSSAPI=enabled PGM=enabled NORM=enabled + - env: BUILD_TYPE=default CURVE=libsodium DRAFT=enabled GSSAPI=enabled PGM=enabled NORM=enabled TIPC=enabled os: linux + sudo: required addons: apt: sources: diff --git a/builds/cmake/Modules/ZMQSourceRunChecks.cmake b/builds/cmake/Modules/ZMQSourceRunChecks.cmake index 8d6ab87d..46010fce 100644 --- a/builds/cmake/Modules/ZMQSourceRunChecks.cmake +++ b/builds/cmake/Modules/ZMQSourceRunChecks.cmake @@ -195,19 +195,12 @@ int main(int argc, char *argv []) { struct sockaddr_tipc topsrv; int sd = socket(AF_TIPC, SOCK_SEQPACKET, 0); - if (sd == -EAFNOSUPPORT) { - return 1; - } memset(&topsrv, 0, sizeof(topsrv)); topsrv.family = AF_TIPC; topsrv.addrtype = TIPC_ADDR_NAME; topsrv.addr.name.name.type = TIPC_TOP_SRV; topsrv.addr.name.name.instance = TIPC_TOP_SRV; fcntl(sd, F_SETFL, O_NONBLOCK); - if (connect(sd, (struct sockaddr *)&topsrv, sizeof(topsrv)) != 0) { - if (errno != EINPROGRESS) - return -1; - } } " ZMQ_HAVE_TIPC) diff --git a/ci_build.sh b/ci_build.sh index 7a8a39f0..dd8060e1 100755 --- a/ci_build.sh +++ b/ci_build.sh @@ -48,6 +48,10 @@ if [ $BUILD_TYPE == "default" ]; then CONFIG_OPTS+=("--with-norm=yes") fi + if [ -n "$TIPC" ] && [ "$TIPC" == "enabled" ]; then + sudo modprobe tipc + fi + if [ -n "$POLLER" ]; then CONFIG_OPTS+=("--with-poller=${POLLER}") fi diff --git a/configure.ac b/configure.ac index f397d131..fbce6ea3 100644 --- a/configure.ac +++ b/configure.ac @@ -93,19 +93,12 @@ AC_RUN_IFELSE( ]],[[ struct sockaddr_tipc topsrv; int sd = socket(AF_TIPC, SOCK_SEQPACKET, 0); - if (sd == -EAFNOSUPPORT) { - return 1; - } memset(&topsrv, 0, sizeof(topsrv)); topsrv.family = AF_TIPC; topsrv.addrtype = TIPC_ADDR_NAME; topsrv.addr.name.name.type = TIPC_TOP_SRV; topsrv.addr.name.name.instance = TIPC_TOP_SRV; fcntl(sd, F_SETFL, O_NONBLOCK); - if (connect(sd, (struct sockaddr *)&topsrv, sizeof(topsrv)) != 0) { - if (errno != EINPROGRESS) - return -1; - } ]]) ], [libzmq_tipc_support=yes], diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 56d8d9f3..930b29b1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -203,6 +203,7 @@ foreach(test ${tests}) add_test(NAME ${test} COMMAND ${test}) endif() set_tests_properties(${test} PROPERTIES TIMEOUT 10) + set_tests_properties(${test} PROPERTIES SKIP_RETURN_CODE 77) endforeach() #override timeout for these tests diff --git a/tests/test_address_tipc.cpp b/tests/test_address_tipc.cpp index 966a29a9..55aa0d93 100644 --- a/tests/test_address_tipc.cpp +++ b/tests/test_address_tipc.cpp @@ -131,6 +131,11 @@ int main () { setup_test_environment (); + if (!is_tipc_available ()) { + printf ("TIPC environment unavailable, skipping test\n"); + return 77; + } + UNITY_BEGIN (); RUN_TEST (test_tipc_port_name_and_domain); RUN_TEST (test_tipc_port_identity); diff --git a/tests/test_connect_delay_tipc.cpp b/tests/test_connect_delay_tipc.cpp index 03df8ee1..d800d480 100644 --- a/tests/test_connect_delay_tipc.cpp +++ b/tests/test_connect_delay_tipc.cpp @@ -31,6 +31,11 @@ int main (void) { + if (!is_tipc_available ()) { + printf ("TIPC environment unavailable, skipping test\n"); + return 77; + } + int val; int rc; char buffer[16]; diff --git a/tests/test_pair_tipc.cpp b/tests/test_pair_tipc.cpp index 9c373171..a694706a 100644 --- a/tests/test_pair_tipc.cpp +++ b/tests/test_pair_tipc.cpp @@ -32,6 +32,11 @@ int main (void) { + if (!is_tipc_available ()) { + printf ("TIPC environment unavailable, skipping test\n"); + return 77; + } + fprintf (stderr, "test_pair_tipc running...\n"); void *ctx = zmq_init (1); diff --git a/tests/test_reqrep_device_tipc.cpp b/tests/test_reqrep_device_tipc.cpp index 29123159..dd527778 100644 --- a/tests/test_reqrep_device_tipc.cpp +++ b/tests/test_reqrep_device_tipc.cpp @@ -31,6 +31,11 @@ int main (void) { + if (!is_tipc_available ()) { + printf ("TIPC environment unavailable, skipping test\n"); + return 77; + } + fprintf (stderr, "test_reqrep_device_tipc running...\n"); void *ctx = zmq_init (1); diff --git a/tests/test_reqrep_tipc.cpp b/tests/test_reqrep_tipc.cpp index b4d5c981..4dc5c08f 100644 --- a/tests/test_reqrep_tipc.cpp +++ b/tests/test_reqrep_tipc.cpp @@ -31,6 +31,11 @@ int main (void) { + if (!is_tipc_available ()) { + printf ("TIPC environment unavailable, skipping test\n"); + return 77; + } + fprintf (stderr, "test_reqrep_tipc running...\n"); void *ctx = zmq_init (1); diff --git a/tests/test_router_mandatory_tipc.cpp b/tests/test_router_mandatory_tipc.cpp index b2634c06..dbb8b7cc 100644 --- a/tests/test_router_mandatory_tipc.cpp +++ b/tests/test_router_mandatory_tipc.cpp @@ -32,6 +32,11 @@ int main (void) { + if (!is_tipc_available ()) { + printf ("TIPC environment unavailable, skipping test\n"); + return 77; + } + fprintf (stderr, "test_router_mandatory_tipc running...\n"); void *ctx = zmq_init (1); diff --git a/tests/test_shutdown_stress_tipc.cpp b/tests/test_shutdown_stress_tipc.cpp index 68f78ca5..a2ba55b1 100644 --- a/tests/test_shutdown_stress_tipc.cpp +++ b/tests/test_shutdown_stress_tipc.cpp @@ -49,6 +49,11 @@ static void *worker (void *s) int main (void) { + if (!is_tipc_available ()) { + printf ("TIPC environment unavailable, skipping test\n"); + return 77; + } + void *ctx; void *s1; void *s2; diff --git a/tests/test_sub_forward_tipc.cpp b/tests/test_sub_forward_tipc.cpp index 173cb025..79cb6190 100644 --- a/tests/test_sub_forward_tipc.cpp +++ b/tests/test_sub_forward_tipc.cpp @@ -31,6 +31,11 @@ int main (void) { + if (!is_tipc_available ()) { + printf ("TIPC environment unavailable, skipping test\n"); + return 77; + } + fprintf (stderr, "test_sub_forward running...\n"); void *ctx = zmq_init (1); diff --git a/tests/test_term_endpoint_tipc.cpp b/tests/test_term_endpoint_tipc.cpp index 87d7b4a1..153f13ed 100644 --- a/tests/test_term_endpoint_tipc.cpp +++ b/tests/test_term_endpoint_tipc.cpp @@ -31,6 +31,11 @@ int main (void) { + if (!is_tipc_available ()) { + printf ("TIPC environment unavailable, skipping test\n"); + return 77; + } + int rc; char buf[32]; const char *ep = "tipc://{5560,0,0}"; diff --git a/tests/testutil.hpp b/tests/testutil.hpp index 9ab92331..dad38433 100644 --- a/tests/testutil.hpp +++ b/tests/testutil.hpp @@ -389,6 +389,29 @@ int is_ipv6_available (void) #endif // _WIN32_WINNT < 0x0600 } +// 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 +} + #if defined(ZMQ_HAVE_WINDOWS) int close (int fd)