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
This commit is contained in:
Luca Boccassi 2018-03-09 16:47:42 +00:00 committed by Simon Giesecke
parent 7abb8388d6
commit 19060345e4
15 changed files with 75 additions and 15 deletions

View File

@ -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:

View File

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

View File

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

View File

@ -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],

View File

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

View File

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

View File

@ -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];

View File

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

View File

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

View File

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

View File

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

View File

@ -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;

View File

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

View File

@ -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}";

View File

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