]> git.proxmox.com Git - mirror_qemu.git/blobdiff - tests/test-util-sockets.c
iotests/303: use dot slash for qcow2.py running
[mirror_qemu.git] / tests / test-util-sockets.c
index af9f5c0c700c09322727dd9455fd5f0197dbc6c9..67486055ede1920b5d12bf57ef0185fb611d51c7 100644 (file)
@@ -52,6 +52,7 @@ static void test_fd_is_socket_good(void)
 
 static int mon_fd = -1;
 static const char *mon_fdname;
+__thread Monitor *cur_mon;
 
 int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp)
 {
@@ -65,17 +66,16 @@ int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp)
 }
 
 /*
- * Syms of stubs in libqemuutil.a are discarded at .o file granularity.
- * To replace monitor_get_fd() we must ensure everything in
- * stubs/monitor.c is defined, to make sure monitor.o is discarded
+ * Syms of stubs in libqemuutil.a are discarded at .o file
+ * granularity.  To replace monitor_get_fd() and monitor_cur(), we
+ * must ensure that we also replace any other symbol that is used in
+ * the binary and would be taken from the same stub object file,
  * otherwise we get duplicate syms at link time.
  */
-__thread Monitor *cur_mon;
+Monitor *monitor_cur(void) { return cur_mon; }
 int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) { abort(); }
-void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp) {}
-void monitor_init_hmp(Chardev *chr, bool use_readline, Error **errp) {}
-
 
+#ifndef _WIN32
 static void test_socket_fd_pass_name_good(void)
 {
     SocketAddress addr;
@@ -227,100 +227,113 @@ static void test_socket_fd_pass_num_nocli(void)
 
     g_free(addr.u.fd.str);
 }
+#endif
+
+#ifdef CONFIG_LINUX
+
+#define ABSTRACT_SOCKET_VARIANTS 3
 
-#ifdef __linux__
-static gchar *abstract_sock_name;
+typedef struct {
+    SocketAddress *server, *client[ABSTRACT_SOCKET_VARIANTS];
+    bool expect_connect[ABSTRACT_SOCKET_VARIANTS];
+} abstract_socket_matrix_row;
 
-static gpointer unix_server_thread_func(gpointer user_data)
+static gpointer unix_client_thread_func(gpointer user_data)
 {
-    SocketAddress addr;
+    abstract_socket_matrix_row *row = user_data;
     Error *err = NULL;
-    int fd = -1;
-    int connfd = -1;
+    int i, fd;
+
+    for (i = 0; i < ABSTRACT_SOCKET_VARIANTS; i++) {
+        if (row->expect_connect[i]) {
+            fd = socket_connect(row->client[i], &error_abort);
+            g_assert_cmpint(fd, >=, 0);
+        } else {
+            fd = socket_connect(row->client[i], &err);
+            g_assert_cmpint(fd, ==, -1);
+            error_free_or_abort(&err);
+        }
+        close(fd);
+    }
+    return NULL;
+}
+
+static void test_socket_unix_abstract_row(abstract_socket_matrix_row *test)
+{
+    int fd, connfd, i;
+    GThread *cli;
     struct sockaddr_un un;
     socklen_t len = sizeof(un);
 
-    addr.type = SOCKET_ADDRESS_TYPE_UNIX;
-    addr.u.q_unix.path = abstract_sock_name;
-    addr.u.q_unix.tight = user_data != NULL;
-    addr.u.q_unix.abstract = true;
+    /* Last one must connect, or else accept() below hangs */
+    assert(test->expect_connect[ABSTRACT_SOCKET_VARIANTS - 1]);
 
-    fd = socket_listen(&addr, 1, &err);
+    fd = socket_listen(test->server, 1, &error_abort);
     g_assert_cmpint(fd, >=, 0);
     g_assert(fd_is_socket(fd));
 
-    connfd = accept(fd, (struct sockaddr *)&un, &len);
-    g_assert_cmpint(connfd, !=, -1);
+    cli = g_thread_new("abstract_unix_client",
+                       unix_client_thread_func,
+                       test);
+
+    for (i = 0; i < ABSTRACT_SOCKET_VARIANTS; i++) {
+        if (test->expect_connect[i]) {
+            connfd = accept(fd, (struct sockaddr *)&un, &len);
+            g_assert_cmpint(connfd, !=, -1);
+            close(connfd);
+        }
+    }
 
     close(fd);
-
-    return NULL;
+    g_thread_join(cli);
 }
 
-static gpointer unix_client_thread_func(gpointer user_data)
+static void test_socket_unix_abstract(void)
 {
-    SocketAddress addr;
-    Error *err = NULL;
-    int fd = -1;
+    SocketAddress addr, addr_tight, addr_padded;
+    abstract_socket_matrix_row matrix[ABSTRACT_SOCKET_VARIANTS] = {
+        { &addr,
+          { &addr_tight, &addr_padded, &addr },
+          { true, false, true } },
+        { &addr_tight,
+          { &addr_padded, &addr, &addr_tight },
+          { false, true, true } },
+        { &addr_padded,
+          { &addr, &addr_tight, &addr_padded },
+          { false, false, true } }
+    };
+    int i;
 
     addr.type = SOCKET_ADDRESS_TYPE_UNIX;
-    addr.u.q_unix.path = abstract_sock_name;
-    addr.u.q_unix.tight = user_data != NULL;
+    addr.u.q_unix.path = g_strdup_printf("unix-%d-%u",
+                                         getpid(), g_random_int());
+    addr.u.q_unix.has_abstract = true;
     addr.u.q_unix.abstract = true;
+    addr.u.q_unix.has_tight = false;
+    addr.u.q_unix.tight = false;
 
-    fd = socket_connect(&addr, &err);
+    addr_tight = addr;
+    addr_tight.u.q_unix.has_tight = true;
+    addr_tight.u.q_unix.tight = true;
 
-    g_assert_cmpint(fd, >=, 0);
+    addr_padded = addr;
+    addr_padded.u.q_unix.has_tight = true;
+    addr_padded.u.q_unix.tight = false;
 
-    close(fd);
+    for (i = 0; i < ABSTRACT_SOCKET_VARIANTS; i++) {
+        test_socket_unix_abstract_row(&matrix[i]);
+    }
 
-    return NULL;
+    g_free(addr.u.q_unix.path);
 }
 
-static void test_socket_unix_abstract_good(void)
-{
-    GRand *r = g_rand_new();
-
-    abstract_sock_name = g_strdup_printf("unix-%d-%d", getpid(),
-                                         g_rand_int_range(r, 100, 1000));
-
-    /* non tight socklen serv and cli */
-    GThread *serv = g_thread_new("abstract_unix_server",
-                                 unix_server_thread_func,
-                                 NULL);
-
-    sleep(1);
-
-    GThread *cli = g_thread_new("abstract_unix_client",
-                                unix_client_thread_func,
-                                NULL);
-
-    g_thread_join(cli);
-    g_thread_join(serv);
-
-    /* tight socklen serv and cli */
-    serv = g_thread_new("abstract_unix_server",
-                        unix_server_thread_func,
-                        (gpointer)1);
-
-    sleep(1);
-
-    cli = g_thread_new("abstract_unix_client",
-                       unix_client_thread_func,
-                       (gpointer)1);
-
-    g_thread_join(cli);
-    g_thread_join(serv);
-
-    g_free(abstract_sock_name);
-    g_rand_free(r);
-}
-#endif
+#endif  /* CONFIG_LINUX */
 
 int main(int argc, char **argv)
 {
     bool has_ipv4, has_ipv6;
 
+    qemu_init_main_loop(&error_abort);
     socket_init();
 
     g_test_init(&argc, &argv, NULL);
@@ -340,6 +353,7 @@ int main(int argc, char **argv)
                         test_fd_is_socket_bad);
         g_test_add_func("/util/socket/is-socket/good",
                         test_fd_is_socket_good);
+#ifndef _WIN32
         g_test_add_func("/socket/fd-pass/name/good",
                         test_socket_fd_pass_name_good);
         g_test_add_func("/socket/fd-pass/name/bad",
@@ -352,11 +366,12 @@ int main(int argc, char **argv)
                         test_socket_fd_pass_num_bad);
         g_test_add_func("/socket/fd-pass/num/nocli",
                         test_socket_fd_pass_num_nocli);
+#endif
     }
 
-#ifdef __linux__
-    g_test_add_func("/util/socket/unix-abstract/good",
-                    test_socket_unix_abstract_good);
+#ifdef CONFIG_LINUX
+    g_test_add_func("/util/socket/unix-abstract",
+                    test_socket_unix_abstract);
 #endif
 
 end: