]> git.ipfire.org Git - thirdparty/dbus.git/commitdiff
test: Skip TCP tests if getaddrinfo doesn't work
authorSimon McVittie <smcv@collabora.com>
Mon, 4 Jun 2018 15:27:50 +0000 (16:27 +0100)
committerSimon McVittie <smcv@collabora.com>
Mon, 4 Jun 2018 16:56:31 +0000 (17:56 +0100)
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
<https://cwrap.org/nss_wrapper.html>:

    cat > hosts <<EOF
    127.0.0.1 localhost
    EOF
    bwrap \
    ... \
    env \
    LD_PRELOAD=libnss_wrapper.so \
    NSS_WRAPPER_HOSTS=$(pwd)/hosts \
    ${builddir}/test/test-loopback --tap
    ...
    # listening at tcp:host=127.0.0.1,port=39219,family=ipv4,guid=...

but for systems where that does't work, we should be prepared to skip
the affected tests.

Signed-off-by: Simon McVittie <smcv@collabora.com>
Reviewed-by: Philip Withnall <withnall@endlessm.com>
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=106812
(cherry picked from commit f1faafd59bec67d347edb10447c4b9b18193458c)

test/corrupt.c
test/fdpass.c
test/internals/server-oom.c
test/loopback.c
test/relay.c
test/test-utils-glib.c
test/test-utils-glib.h

index a2fad64d5cfa8d34954b11d6f3d9578dc461f974..a6a912f4d5ae04763ddcacdc2d468b8153e457ee 100644 (file)
@@ -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");
index 0ea7518c32a7ca9a991fb011636935659125d4e0..4a3edc4e7fb272450675a58ba5f54a2440599d38 100644 (file)
@@ -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);
index 9aeadd342bd5a4c81dd47110cf81e9767dff5241..4c3ab058aa4a0ebe2bab40e54b59c54bc67e6cc2 100644 (file)
@@ -84,6 +84,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))
     {
index c0bf400f8a385bc14ff3be63022425d667fa986e..b8725b7e7ea085f92f573328e8943b05ef145a03 100644 (file)
@@ -40,6 +40,7 @@
 typedef struct {
     TestMainContext *ctx;
     DBusError e;
+    gboolean skip;
 
     DBusServer *server;
     DBusConnection *server_conn;
@@ -97,6 +98,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);
@@ -124,6 +133,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="));
@@ -146,6 +158,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 */
@@ -166,6 +181,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);
@@ -266,13 +284,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);
@@ -328,6 +350,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",
index 5f90546022cf21bb35b78efc11e5ed5f7ba29d8e..2b3efb96cd69d3d2d31efc4c8c3b8340161d153b 100644 (file)
@@ -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. */
index adbe21c00123343fd2afe316c844db147984ccfc..28a3684874089fb656db2a31fe06b94432e41759 100644 (file)
 # include <io.h>
 # include <windows.h>
 #else
+# include <netdb.h>
 # include <signal.h>
 # include <unistd.h>
+# include <sys/socket.h>
 # include <sys/types.h>
 # include <pwd.h>
 #endif
@@ -645,3 +647,58 @@ test_mkdir (const gchar *path,
                g_strerror (saved_errno));
     }
 }
+
+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
+}
index b170e871ce3b65244eaf98f1b1f1eb724e67ea2a..e62121cb90048e700f1f03d7edc9a2c6c7e0fd85 100644 (file)
@@ -106,4 +106,6 @@ backported_g_steal_pointer (gpointer pointer_to_pointer)
 }
 #endif
 
+gboolean test_check_tcp_works (void);
+
 #endif