From 7afff388cba598e266aedd19b864dac323dd4915 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Mon, 4 Jun 2018 16:27:50 +0100 Subject: [PATCH 5/5] test: Skip TCP tests if getaddrinfo doesn't work For example, this can be the case in bubblewrap or Debian pbuilder after unsharing the network namespace: bwrap \ --bind / / \ --dev-bind /dev /dev \ --bind /dev/shm /dev/shm \ --bind /dev/pts /dev/pts \ --unshare-net \ ${builddir}/test/test-loopback --tap ... ok 1 /connect/tcp # SKIP Name resolution does not work here: getaddrinfo("127.0.0.1", "0", {flags=ADDRCONFIG, family=INET, socktype=STREAM, protocol=TCP}): Name or service not known On some systems this can be circumvented by using nss_wrapper from : cat > hosts < --- test/corrupt.c | 21 ++++++++++++++ test/fdpass.c | 38 +++++++++++++++++++++++-- test/internals/server-oom.c | 5 ++++ test/loopback.c | 27 +++++++++++++++++- test/relay.c | 18 ++++++++++++ test/test-utils-glib.c | 57 +++++++++++++++++++++++++++++++++++++ test/test-utils-glib.h | 2 ++ 7 files changed, 165 insertions(+), 3 deletions(-) diff --git a/test/corrupt.c b/test/corrupt.c index a2fad64d..a6a912f4 100644 --- a/test/corrupt.c +++ b/test/corrupt.c @@ -36,6 +36,7 @@ typedef struct { DBusError e; TestMainContext *ctx; + gboolean skip; DBusServer *server; DBusConnection *server_conn; @@ -85,6 +86,14 @@ setup (Fixture *f, dbus_error_init (&f->e); g_queue_init (&f->client_messages); + if ((g_str_has_prefix (addr, "tcp:") || + g_str_has_prefix (addr, "nonce-tcp:")) && + !test_check_tcp_works ()) + { + f->skip = TRUE; + return; + } + f->server = dbus_server_listen (addr, &f->e); assert_no_error (&f->e); g_assert (f->server != NULL); @@ -101,6 +110,9 @@ test_connect (Fixture *f, dbus_bool_t have_mem; char *address = NULL; + if (f->skip) + return; + g_assert (f->server_conn == NULL); address = dbus_server_get_address (f->server); @@ -129,6 +141,9 @@ test_message (Fixture *f, dbus_uint32_t serial; DBusMessage *outgoing, *incoming; + if (f->skip) + return; + test_connect (f, addr); outgoing = dbus_message_new_signal ("/com/example/Hello", @@ -213,6 +228,9 @@ test_corrupt (Fixture *f, int fd; DBusMessage *incoming; + if (f->skip) + return; + test_message (f, addr); dbus_connection_flush (f->server_conn); @@ -277,6 +295,9 @@ test_byte_order (Fixture *f, DBusMessage *message; dbus_bool_t mem; + if (f->skip) + return; + test_message (f, addr); message = dbus_message_new_signal ("/", "a.b", "c"); diff --git a/test/fdpass.c b/test/fdpass.c index 0ea7518c..4a3edc4e 100644 --- a/test/fdpass.c +++ b/test/fdpass.c @@ -79,6 +79,7 @@ _DBUS_STATIC_ASSERT (MAX_MESSAGE_UNIX_FDS < TOO_MANY_FDS); typedef struct { TestMainContext *ctx; DBusError e; + gboolean skip; DBusServer *server; @@ -172,6 +173,9 @@ test_connect (Fixture *f, { char *address; + if (f->skip) + return; + g_assert (f->left_server_conn == NULL); g_assert (f->right_server_conn == NULL); @@ -251,6 +255,14 @@ setup_common (Fixture *f, dbus_error_init (&f->e); g_queue_init (&f->messages); + if ((g_str_has_prefix (address, "tcp:") || + g_str_has_prefix (address, "nonce-tcp:")) && + !test_check_tcp_works ()) + { + f->skip = TRUE; + return; + } + f->server = dbus_server_listen (address, &f->e); assert_no_error (&f->e); g_assert (f->server != NULL); @@ -289,6 +301,9 @@ static void test_unsupported (Fixture *f, gconstpointer data) { + if (f->skip) + return; + test_connect (f, FALSE); if (dbus_connection_can_send_type (f->left_client_conn, @@ -321,6 +336,9 @@ test_relay (Fixture *f, struct stat stat_before; struct stat stat_after; + if (f->skip) + return; + test_connect (f, TRUE); outgoing = dbus_message_new_signal ("/com/example/Hello", @@ -403,6 +421,9 @@ test_limit (Fixture *f, DBusMessage *outgoing, *incoming; int i; + if (f->skip) + return; + test_connect (f, TRUE); outgoing = dbus_message_new_signal ("/com/example/Hello", @@ -461,6 +482,9 @@ test_too_many (Fixture *f, DBusMessage *outgoing; unsigned int i; + if (f->skip) + return; + test_connect (f, TRUE); outgoing = dbus_message_new_signal ("/com/example/Hello", @@ -513,6 +537,12 @@ test_too_many_split (Fixture *f, DBusString buffer; int fds[TOO_MANY_FDS]; int done; +#ifdef HAVE_GETRLIMIT + struct rlimit lim; +#endif + + if (f->skip) + return; /* This test deliberately pushes up against OS limits, so skip it * if we don't have enough fds. 4 times the maximum per message @@ -520,8 +550,6 @@ test_too_many_split (Fixture *f, * we actually send, the copy that we potentially receive, and some * spare capacity for everything else. */ #ifdef HAVE_GETRLIMIT - struct rlimit lim; - if (getrlimit (RLIMIT_NOFILE, &lim) == 0) { if (lim.rlim_cur != RLIM_INFINITY && @@ -643,6 +671,9 @@ test_flood (Fixture *f, DBusMessage *outgoing[SOME_MESSAGES]; dbus_uint32_t serial; + if (f->skip) + return; + test_connect (f, TRUE); for (j = 0; j < SOME_MESSAGES; j++) @@ -715,6 +746,9 @@ test_odd_limit (Fixture *f, DBusMessage *outgoing; int i; + if (f->skip) + return; + test_connect (f, TRUE); dbus_connection_set_max_message_unix_fds (f->left_server_conn, 7); dbus_connection_set_max_message_unix_fds (f->right_server_conn, 7); diff --git a/test/internals/server-oom.c b/test/internals/server-oom.c index 839adb84..5d7fa4d0 100644 --- a/test/internals/server-oom.c +++ b/test/internals/server-oom.c @@ -85,6 +85,11 @@ test_oom_wrapper (gconstpointer data) { const OOMTestCase *test = data; + if ((g_str_has_prefix (test->data, "tcp:") || + g_str_has_prefix (test->data, "nonce-tcp:")) && + !test_check_tcp_works ()) + return; + if (!_dbus_test_oom_handling (test->name, test->function, (void *) test->data)) { diff --git a/test/loopback.c b/test/loopback.c index 9702fb33..5ab8be9c 100644 --- a/test/loopback.c +++ b/test/loopback.c @@ -41,6 +41,7 @@ typedef struct { TestMainContext *ctx; DBusError e; + gboolean skip; DBusServer *server; DBusConnection *server_conn; @@ -98,6 +99,14 @@ setup (Fixture *f, dbus_error_init (&f->e); g_queue_init (&f->server_messages); + if ((g_str_has_prefix (addr, "tcp:") || + g_str_has_prefix (addr, "nonce-tcp:")) && + !test_check_tcp_works ()) + { + f->skip = TRUE; + return; + } + f->server = dbus_server_listen (addr, &f->e); assert_no_error (&f->e); g_assert (f->server != NULL); @@ -125,6 +134,9 @@ setup_runtime (Fixture *f, setup (f, addr); + if (f->skip) + return; + listening_at = dbus_server_get_address (f->server); g_test_message ("listening at %s", listening_at); g_assert (g_str_has_prefix (listening_at, "unix:path=")); @@ -147,6 +159,9 @@ setup_no_runtime (Fixture *f, setup (f, addr); + if (f->skip) + return; + listening_at = dbus_server_get_address (f->server); g_test_message ("listening at %s", listening_at); /* we have fallen back to something in /tmp, either abstract or not */ @@ -169,6 +184,9 @@ test_connect (Fixture *f, int n_entries; dbus_bool_t ok; + if (f->skip) + return; + g_assert (f->server_conn == NULL); address = dbus_server_get_address (f->server); @@ -294,13 +312,17 @@ test_bad_guid (Fixture *f, gconstpointer addr G_GNUC_UNUSED) { DBusMessage *incoming; - char *address = dbus_server_get_address (f->server); + char *address; gchar *guid; + if (f->skip) + return; + g_test_bug ("39720"); g_assert (f->server_conn == NULL); + address = dbus_server_get_address (f->server); g_assert (strstr (address, "guid=") != NULL); guid = strstr (address, "guid="); g_assert_cmpuint (strlen (guid), >=, 5 + 32); @@ -356,6 +378,9 @@ test_message (Fixture *f, dbus_uint32_t serial; DBusMessage *outgoing, *incoming; + if (f->skip) + return; + test_connect (f, addr); outgoing = dbus_message_new_signal ("/com/example/Hello", diff --git a/test/relay.c b/test/relay.c index 5f905460..2b3efb96 100644 --- a/test/relay.c +++ b/test/relay.c @@ -46,6 +46,7 @@ typedef struct { TestMainContext *ctx; DBusError e; + gboolean skip; DBusServer *server; @@ -128,6 +129,14 @@ setup (Fixture *f, dbus_error_init (&f->e); g_queue_init (&f->messages); + if ((g_str_has_prefix (address, "tcp:") || + g_str_has_prefix (address, "nonce-tcp:")) && + !test_check_tcp_works ()) + { + f->skip = TRUE; + return; + } + f->server = dbus_server_listen (address, &f->e); assert_no_error (&f->e); g_assert (f->server != NULL); @@ -144,6 +153,9 @@ test_connect (Fixture *f, dbus_bool_t have_mem; char *address; + if (f->skip) + return; + g_assert (f->left_server_conn == NULL); g_assert (f->right_server_conn == NULL); @@ -205,6 +217,9 @@ test_relay (Fixture *f, { DBusMessage *incoming; + if (f->skip) + return; + test_connect (f, data); send_one (f, "First"); @@ -237,6 +252,9 @@ test_limit (Fixture *f, DBusMessage *incoming; guint i; + if (f->skip) + return; + test_connect (f, data); /* This was an attempt to reproduce fd.o #34393. It didn't work. */ diff --git a/test/test-utils-glib.c b/test/test-utils-glib.c index a9bbbb26..ec9971c5 100644 --- a/test/test-utils-glib.c +++ b/test/test-utils-glib.c @@ -34,8 +34,10 @@ # include # include #else +# include # include # include +# include # include # include #endif @@ -762,3 +764,58 @@ test_main_context_call_and_wait (TestMainContext *ctx, dbus_clear_pending_call (&pc); return g_steal_pointer (&reply); } + +gboolean +test_check_tcp_works (void) +{ +#ifdef DBUS_UNIX + /* In pathological container environments, we might not have a + * working 127.0.0.1 */ + int res; + struct addrinfo *addrs = NULL; + struct addrinfo hints; + int saved_errno; + + _DBUS_ZERO (hints); +#ifdef AI_ADDRCONFIG + hints.ai_flags |= AI_ADDRCONFIG; +#endif + hints.ai_flags = AI_ADDRCONFIG; + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + res = getaddrinfo ("127.0.0.1", "0", &hints, &addrs); + saved_errno = errno; + + if (res != 0) + { + const gchar *system_message; + gchar *skip_message; + +#ifdef EAI_SYSTEM + if (res == EAI_SYSTEM) + system_message = g_strerror (saved_errno); + else +#endif + system_message = gai_strerror (res); + + skip_message = g_strdup_printf ("Name resolution does not work here: " + "getaddrinfo(\"127.0.0.1\", \"0\", " + "{flags=ADDRCONFIG, family=INET," + "socktype=STREAM, protocol=TCP}): " + "%s", + system_message); + g_test_skip (skip_message); + free (skip_message); + } + + if (addrs != NULL) + freeaddrinfo (addrs); + + return (res == 0); +#else + /* Assume that on Windows, TCP always works */ + return TRUE; +#endif +} diff --git a/test/test-utils-glib.h b/test/test-utils-glib.h index 755e8c7c..a2712c05 100644 --- a/test/test-utils-glib.h +++ b/test/test-utils-glib.h @@ -121,4 +121,6 @@ backported_g_steal_pointer (gpointer pointer_to_pointer) } #endif +gboolean test_check_tcp_works (void); + #endif -- 2.17.1