xref: /qemu/tests/unit/test-util-sockets.c (revision 130d4824222cf062ed8ee3c5ab9fa2bd852b33b6)
158dc31f1SDaniel P. Berrange /*
258dc31f1SDaniel P. Berrange  * Tests for util/qemu-sockets.c
358dc31f1SDaniel P. Berrange  *
458dc31f1SDaniel P. Berrange  * Copyright 2018 Red Hat, Inc.
558dc31f1SDaniel P. Berrange  *
658dc31f1SDaniel P. Berrange  * This program is free software; you can redistribute it and/or modify
758dc31f1SDaniel P. Berrange  * it under the terms of the GNU General Public License as published by
858dc31f1SDaniel P. Berrange  * the Free Software Foundation; either version 2 of the License, or
958dc31f1SDaniel P. Berrange  * (at your option) any later version.
1058dc31f1SDaniel P. Berrange  *
1158dc31f1SDaniel P. Berrange  * This program is distributed in the hope that it will be useful,
1258dc31f1SDaniel P. Berrange  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1358dc31f1SDaniel P. Berrange  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1458dc31f1SDaniel P. Berrange  * GNU General Public License for more details.
1558dc31f1SDaniel P. Berrange  *
1658dc31f1SDaniel P. Berrange  * You should have received a copy of the GNU General Public License
1758dc31f1SDaniel P. Berrange  * along with this library; if not, see <http://www.gnu.org/licenses/>.
1858dc31f1SDaniel P. Berrange  *
1958dc31f1SDaniel P. Berrange  */
2058dc31f1SDaniel P. Berrange 
2158dc31f1SDaniel P. Berrange #include "qemu/osdep.h"
2258dc31f1SDaniel P. Berrange #include "qemu-common.h"
2358dc31f1SDaniel P. Berrange #include "qemu/sockets.h"
2458dc31f1SDaniel P. Berrange #include "qapi/error.h"
2558dc31f1SDaniel P. Berrange #include "socket-helpers.h"
2630bdb3c5SDaniel P. Berrange #include "monitor/monitor.h"
2758dc31f1SDaniel P. Berrange 
2858dc31f1SDaniel P. Berrange static void test_fd_is_socket_bad(void)
2958dc31f1SDaniel P. Berrange {
3058dc31f1SDaniel P. Berrange     char *tmp = g_strdup("qemu-test-util-sockets-XXXXXX");
3158dc31f1SDaniel P. Berrange     int fd = mkstemp(tmp);
3258dc31f1SDaniel P. Berrange     if (fd != 0) {
3358dc31f1SDaniel P. Berrange         unlink(tmp);
3458dc31f1SDaniel P. Berrange     }
3558dc31f1SDaniel P. Berrange     g_free(tmp);
3658dc31f1SDaniel P. Berrange 
3758dc31f1SDaniel P. Berrange     g_assert(fd >= 0);
3858dc31f1SDaniel P. Berrange 
3958dc31f1SDaniel P. Berrange     g_assert(!fd_is_socket(fd));
4058dc31f1SDaniel P. Berrange     close(fd);
4158dc31f1SDaniel P. Berrange }
4258dc31f1SDaniel P. Berrange 
4358dc31f1SDaniel P. Berrange static void test_fd_is_socket_good(void)
4458dc31f1SDaniel P. Berrange {
4558dc31f1SDaniel P. Berrange     int fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
4658dc31f1SDaniel P. Berrange 
4758dc31f1SDaniel P. Berrange     g_assert(fd >= 0);
4858dc31f1SDaniel P. Berrange 
4958dc31f1SDaniel P. Berrange     g_assert(fd_is_socket(fd));
5058dc31f1SDaniel P. Berrange     close(fd);
5158dc31f1SDaniel P. Berrange }
5258dc31f1SDaniel P. Berrange 
5330bdb3c5SDaniel P. Berrange static int mon_fd = -1;
5430bdb3c5SDaniel P. Berrange static const char *mon_fdname;
55947e4744SKevin Wolf __thread Monitor *cur_mon;
5630bdb3c5SDaniel P. Berrange 
5730bdb3c5SDaniel P. Berrange int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp)
5830bdb3c5SDaniel P. Berrange {
5930bdb3c5SDaniel P. Berrange     g_assert(cur_mon);
6030bdb3c5SDaniel P. Berrange     g_assert(mon == cur_mon);
6130bdb3c5SDaniel P. Berrange     if (mon_fd == -1 || !g_str_equal(mon_fdname, fdname)) {
6230bdb3c5SDaniel P. Berrange         error_setg(errp, "No fd named %s", fdname);
6330bdb3c5SDaniel P. Berrange         return -1;
6430bdb3c5SDaniel P. Berrange     }
6530bdb3c5SDaniel P. Berrange     return dup(mon_fd);
6630bdb3c5SDaniel P. Berrange }
6730bdb3c5SDaniel P. Berrange 
68d2a71d74SThomas Huth /*
69947e4744SKevin Wolf  * Syms of stubs in libqemuutil.a are discarded at .o file
70947e4744SKevin Wolf  * granularity.  To replace monitor_get_fd() and monitor_cur(), we
71947e4744SKevin Wolf  * must ensure that we also replace any other symbol that is used in
72947e4744SKevin Wolf  * the binary and would be taken from the same stub object file,
7330bdb3c5SDaniel P. Berrange  * otherwise we get duplicate syms at link time.
7430bdb3c5SDaniel P. Berrange  */
75947e4744SKevin Wolf Monitor *monitor_cur(void) { return cur_mon; }
76*130d4824SMarkus Armbruster Monitor *monitor_set_cur(Coroutine *co, Monitor *mon) { abort(); }
77637de4dbSMarkus Armbruster int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) { abort(); }
7830bdb3c5SDaniel P. Berrange 
798330bd53SYonggang Luo #ifndef _WIN32
801723d6b1SDaniel P. Berrange static void test_socket_fd_pass_name_good(void)
8130bdb3c5SDaniel P. Berrange {
8230bdb3c5SDaniel P. Berrange     SocketAddress addr;
8330bdb3c5SDaniel P. Berrange     int fd;
8430bdb3c5SDaniel P. Berrange 
8530bdb3c5SDaniel P. Berrange     cur_mon = g_malloc(1); /* Fake a monitor */
8630bdb3c5SDaniel P. Berrange     mon_fdname = "myfd";
8730bdb3c5SDaniel P. Berrange     mon_fd = qemu_socket(AF_INET, SOCK_STREAM, 0);
8830bdb3c5SDaniel P. Berrange     g_assert_cmpint(mon_fd, >, STDERR_FILENO);
8930bdb3c5SDaniel P. Berrange 
9030bdb3c5SDaniel P. Berrange     addr.type = SOCKET_ADDRESS_TYPE_FD;
9130bdb3c5SDaniel P. Berrange     addr.u.fd.str = g_strdup(mon_fdname);
9230bdb3c5SDaniel P. Berrange 
9330bdb3c5SDaniel P. Berrange     fd = socket_connect(&addr, &error_abort);
9430bdb3c5SDaniel P. Berrange     g_assert_cmpint(fd, !=, -1);
9530bdb3c5SDaniel P. Berrange     g_assert_cmpint(fd, !=, mon_fd);
9630bdb3c5SDaniel P. Berrange     close(fd);
9730bdb3c5SDaniel P. Berrange 
98e5b6353cSJuan Quintela     fd = socket_listen(&addr, 1, &error_abort);
9930bdb3c5SDaniel P. Berrange     g_assert_cmpint(fd, !=, -1);
10030bdb3c5SDaniel P. Berrange     g_assert_cmpint(fd, !=, mon_fd);
10130bdb3c5SDaniel P. Berrange     close(fd);
10230bdb3c5SDaniel P. Berrange 
10330bdb3c5SDaniel P. Berrange     g_free(addr.u.fd.str);
10430bdb3c5SDaniel P. Berrange     mon_fdname = NULL;
10530bdb3c5SDaniel P. Berrange     close(mon_fd);
10630bdb3c5SDaniel P. Berrange     mon_fd = -1;
10730bdb3c5SDaniel P. Berrange     g_free(cur_mon);
10830bdb3c5SDaniel P. Berrange     cur_mon = NULL;
10930bdb3c5SDaniel P. Berrange }
11030bdb3c5SDaniel P. Berrange 
1111723d6b1SDaniel P. Berrange static void test_socket_fd_pass_name_bad(void)
11230bdb3c5SDaniel P. Berrange {
11330bdb3c5SDaniel P. Berrange     SocketAddress addr;
11430bdb3c5SDaniel P. Berrange     Error *err = NULL;
11530bdb3c5SDaniel P. Berrange     int fd;
11630bdb3c5SDaniel P. Berrange 
11730bdb3c5SDaniel P. Berrange     cur_mon = g_malloc(1); /* Fake a monitor */
11830bdb3c5SDaniel P. Berrange     mon_fdname = "myfd";
11930bdb3c5SDaniel P. Berrange     mon_fd = dup(STDOUT_FILENO);
12030bdb3c5SDaniel P. Berrange     g_assert_cmpint(mon_fd, >, STDERR_FILENO);
12130bdb3c5SDaniel P. Berrange 
12230bdb3c5SDaniel P. Berrange     addr.type = SOCKET_ADDRESS_TYPE_FD;
12330bdb3c5SDaniel P. Berrange     addr.u.fd.str = g_strdup(mon_fdname);
12430bdb3c5SDaniel P. Berrange 
12530bdb3c5SDaniel P. Berrange     fd = socket_connect(&addr, &err);
12630bdb3c5SDaniel P. Berrange     g_assert_cmpint(fd, ==, -1);
12730bdb3c5SDaniel P. Berrange     error_free_or_abort(&err);
12830bdb3c5SDaniel P. Berrange 
129e5b6353cSJuan Quintela     fd = socket_listen(&addr, 1, &err);
13030bdb3c5SDaniel P. Berrange     g_assert_cmpint(fd, ==, -1);
13130bdb3c5SDaniel P. Berrange     error_free_or_abort(&err);
13230bdb3c5SDaniel P. Berrange 
13330bdb3c5SDaniel P. Berrange     g_free(addr.u.fd.str);
13430bdb3c5SDaniel P. Berrange     mon_fdname = NULL;
13530bdb3c5SDaniel P. Berrange     close(mon_fd);
13630bdb3c5SDaniel P. Berrange     mon_fd = -1;
13730bdb3c5SDaniel P. Berrange     g_free(cur_mon);
13830bdb3c5SDaniel P. Berrange     cur_mon = NULL;
13930bdb3c5SDaniel P. Berrange }
14030bdb3c5SDaniel P. Berrange 
1411723d6b1SDaniel P. Berrange static void test_socket_fd_pass_name_nomon(void)
1421723d6b1SDaniel P. Berrange {
1431723d6b1SDaniel P. Berrange     SocketAddress addr;
1441723d6b1SDaniel P. Berrange     Error *err = NULL;
1451723d6b1SDaniel P. Berrange     int fd;
1461723d6b1SDaniel P. Berrange 
1471723d6b1SDaniel P. Berrange     g_assert(cur_mon == NULL);
1481723d6b1SDaniel P. Berrange 
1491723d6b1SDaniel P. Berrange     addr.type = SOCKET_ADDRESS_TYPE_FD;
1501723d6b1SDaniel P. Berrange     addr.u.fd.str = g_strdup("myfd");
1511723d6b1SDaniel P. Berrange 
1521723d6b1SDaniel P. Berrange     fd = socket_connect(&addr, &err);
1531723d6b1SDaniel P. Berrange     g_assert_cmpint(fd, ==, -1);
1541723d6b1SDaniel P. Berrange     error_free_or_abort(&err);
1551723d6b1SDaniel P. Berrange 
156e5b6353cSJuan Quintela     fd = socket_listen(&addr, 1, &err);
1571723d6b1SDaniel P. Berrange     g_assert_cmpint(fd, ==, -1);
1581723d6b1SDaniel P. Berrange     error_free_or_abort(&err);
1591723d6b1SDaniel P. Berrange 
1601723d6b1SDaniel P. Berrange     g_free(addr.u.fd.str);
1611723d6b1SDaniel P. Berrange }
1621723d6b1SDaniel P. Berrange 
1631723d6b1SDaniel P. Berrange 
1641723d6b1SDaniel P. Berrange static void test_socket_fd_pass_num_good(void)
1651723d6b1SDaniel P. Berrange {
1661723d6b1SDaniel P. Berrange     SocketAddress addr;
1671723d6b1SDaniel P. Berrange     int fd, sfd;
1681723d6b1SDaniel P. Berrange 
1691723d6b1SDaniel P. Berrange     g_assert(cur_mon == NULL);
1701723d6b1SDaniel P. Berrange     sfd = qemu_socket(AF_INET, SOCK_STREAM, 0);
1711723d6b1SDaniel P. Berrange     g_assert_cmpint(sfd, >, STDERR_FILENO);
1721723d6b1SDaniel P. Berrange 
1731723d6b1SDaniel P. Berrange     addr.type = SOCKET_ADDRESS_TYPE_FD;
1741723d6b1SDaniel P. Berrange     addr.u.fd.str = g_strdup_printf("%d", sfd);
1751723d6b1SDaniel P. Berrange 
1761723d6b1SDaniel P. Berrange     fd = socket_connect(&addr, &error_abort);
1771723d6b1SDaniel P. Berrange     g_assert_cmpint(fd, ==, sfd);
1781723d6b1SDaniel P. Berrange 
179e5b6353cSJuan Quintela     fd = socket_listen(&addr, 1, &error_abort);
1801723d6b1SDaniel P. Berrange     g_assert_cmpint(fd, ==, sfd);
1811723d6b1SDaniel P. Berrange 
1821723d6b1SDaniel P. Berrange     g_free(addr.u.fd.str);
1831723d6b1SDaniel P. Berrange     close(sfd);
1841723d6b1SDaniel P. Berrange }
1851723d6b1SDaniel P. Berrange 
1861723d6b1SDaniel P. Berrange static void test_socket_fd_pass_num_bad(void)
1871723d6b1SDaniel P. Berrange {
1881723d6b1SDaniel P. Berrange     SocketAddress addr;
1891723d6b1SDaniel P. Berrange     Error *err = NULL;
1901723d6b1SDaniel P. Berrange     int fd, sfd;
1911723d6b1SDaniel P. Berrange 
1921723d6b1SDaniel P. Berrange     g_assert(cur_mon == NULL);
1931723d6b1SDaniel P. Berrange     sfd = dup(STDOUT_FILENO);
1941723d6b1SDaniel P. Berrange 
1951723d6b1SDaniel P. Berrange     addr.type = SOCKET_ADDRESS_TYPE_FD;
1961723d6b1SDaniel P. Berrange     addr.u.fd.str = g_strdup_printf("%d", sfd);
1971723d6b1SDaniel P. Berrange 
1981723d6b1SDaniel P. Berrange     fd = socket_connect(&addr, &err);
1991723d6b1SDaniel P. Berrange     g_assert_cmpint(fd, ==, -1);
2001723d6b1SDaniel P. Berrange     error_free_or_abort(&err);
2011723d6b1SDaniel P. Berrange 
202e5b6353cSJuan Quintela     fd = socket_listen(&addr, 1, &err);
2031723d6b1SDaniel P. Berrange     g_assert_cmpint(fd, ==, -1);
2041723d6b1SDaniel P. Berrange     error_free_or_abort(&err);
2051723d6b1SDaniel P. Berrange 
2061723d6b1SDaniel P. Berrange     g_free(addr.u.fd.str);
2071723d6b1SDaniel P. Berrange     close(sfd);
2081723d6b1SDaniel P. Berrange }
2091723d6b1SDaniel P. Berrange 
2101723d6b1SDaniel P. Berrange static void test_socket_fd_pass_num_nocli(void)
2111723d6b1SDaniel P. Berrange {
2121723d6b1SDaniel P. Berrange     SocketAddress addr;
2131723d6b1SDaniel P. Berrange     Error *err = NULL;
2141723d6b1SDaniel P. Berrange     int fd;
2151723d6b1SDaniel P. Berrange 
2161723d6b1SDaniel P. Berrange     cur_mon = g_malloc(1); /* Fake a monitor */
2171723d6b1SDaniel P. Berrange 
2181723d6b1SDaniel P. Berrange     addr.type = SOCKET_ADDRESS_TYPE_FD;
2191723d6b1SDaniel P. Berrange     addr.u.fd.str = g_strdup_printf("%d", STDOUT_FILENO);
2201723d6b1SDaniel P. Berrange 
2211723d6b1SDaniel P. Berrange     fd = socket_connect(&addr, &err);
2221723d6b1SDaniel P. Berrange     g_assert_cmpint(fd, ==, -1);
2231723d6b1SDaniel P. Berrange     error_free_or_abort(&err);
2241723d6b1SDaniel P. Berrange 
225e5b6353cSJuan Quintela     fd = socket_listen(&addr, 1, &err);
2261723d6b1SDaniel P. Berrange     g_assert_cmpint(fd, ==, -1);
2271723d6b1SDaniel P. Berrange     error_free_or_abort(&err);
2281723d6b1SDaniel P. Berrange 
2291723d6b1SDaniel P. Berrange     g_free(addr.u.fd.str);
2301723d6b1SDaniel P. Berrange }
2318330bd53SYonggang Luo #endif
2321723d6b1SDaniel P. Berrange 
2338acefc79SMarkus Armbruster #ifdef CONFIG_LINUX
234a72f6754SMarkus Armbruster 
235a72f6754SMarkus Armbruster #define ABSTRACT_SOCKET_VARIANTS 3
236a72f6754SMarkus Armbruster 
237a72f6754SMarkus Armbruster typedef struct {
238a72f6754SMarkus Armbruster     SocketAddress *server, *client[ABSTRACT_SOCKET_VARIANTS];
239a72f6754SMarkus Armbruster     bool expect_connect[ABSTRACT_SOCKET_VARIANTS];
240a72f6754SMarkus Armbruster } abstract_socket_matrix_row;
241a72f6754SMarkus Armbruster 
2424d3a329aSxiaoqiang zhao static gpointer unix_client_thread_func(gpointer user_data)
2434d3a329aSxiaoqiang zhao {
244a72f6754SMarkus Armbruster     abstract_socket_matrix_row *row = user_data;
245a72f6754SMarkus Armbruster     Error *err = NULL;
246a72f6754SMarkus Armbruster     int i, fd;
2474d3a329aSxiaoqiang zhao 
248a72f6754SMarkus Armbruster     for (i = 0; i < ABSTRACT_SOCKET_VARIANTS; i++) {
249a72f6754SMarkus Armbruster         if (row->expect_connect[i]) {
250a72f6754SMarkus Armbruster             fd = socket_connect(row->client[i], &error_abort);
2514d3a329aSxiaoqiang zhao             g_assert_cmpint(fd, >=, 0);
252a72f6754SMarkus Armbruster         } else {
253a72f6754SMarkus Armbruster             fd = socket_connect(row->client[i], &err);
254a72f6754SMarkus Armbruster             g_assert_cmpint(fd, ==, -1);
255a72f6754SMarkus Armbruster             error_free_or_abort(&err);
256a72f6754SMarkus Armbruster         }
2574d3a329aSxiaoqiang zhao         close(fd);
258a72f6754SMarkus Armbruster     }
2594d3a329aSxiaoqiang zhao     return NULL;
2604d3a329aSxiaoqiang zhao }
2614d3a329aSxiaoqiang zhao 
262a72f6754SMarkus Armbruster static void test_socket_unix_abstract_row(abstract_socket_matrix_row *test)
26389cb0bb5SMarkus Armbruster {
264a72f6754SMarkus Armbruster     int fd, connfd, i;
26539458d4eSMarkus Armbruster     GThread *cli;
26639458d4eSMarkus Armbruster     struct sockaddr_un un;
26739458d4eSMarkus Armbruster     socklen_t len = sizeof(un);
26889cb0bb5SMarkus Armbruster 
269a72f6754SMarkus Armbruster     /* Last one must connect, or else accept() below hangs */
270a72f6754SMarkus Armbruster     assert(test->expect_connect[ABSTRACT_SOCKET_VARIANTS - 1]);
271a72f6754SMarkus Armbruster 
272a72f6754SMarkus Armbruster     fd = socket_listen(test->server, 1, &error_abort);
27339458d4eSMarkus Armbruster     g_assert_cmpint(fd, >=, 0);
27439458d4eSMarkus Armbruster     g_assert(fd_is_socket(fd));
27589cb0bb5SMarkus Armbruster 
27689cb0bb5SMarkus Armbruster     cli = g_thread_new("abstract_unix_client",
27789cb0bb5SMarkus Armbruster                        unix_client_thread_func,
278a72f6754SMarkus Armbruster                        test);
27989cb0bb5SMarkus Armbruster 
280a72f6754SMarkus Armbruster     for (i = 0; i < ABSTRACT_SOCKET_VARIANTS; i++) {
281a72f6754SMarkus Armbruster         if (test->expect_connect[i]) {
28239458d4eSMarkus Armbruster             connfd = accept(fd, (struct sockaddr *)&un, &len);
28339458d4eSMarkus Armbruster             g_assert_cmpint(connfd, !=, -1);
28439458d4eSMarkus Armbruster             close(connfd);
285a72f6754SMarkus Armbruster         }
286a72f6754SMarkus Armbruster     }
28739458d4eSMarkus Armbruster 
28839458d4eSMarkus Armbruster     close(fd);
28989cb0bb5SMarkus Armbruster     g_thread_join(cli);
29089cb0bb5SMarkus Armbruster }
29189cb0bb5SMarkus Armbruster 
292a72f6754SMarkus Armbruster static void test_socket_unix_abstract(void)
2934d3a329aSxiaoqiang zhao {
294a72f6754SMarkus Armbruster     SocketAddress addr, addr_tight, addr_padded;
295a72f6754SMarkus Armbruster     abstract_socket_matrix_row matrix[ABSTRACT_SOCKET_VARIANTS] = {
296a72f6754SMarkus Armbruster         { &addr,
297a72f6754SMarkus Armbruster           { &addr_tight, &addr_padded, &addr },
298b08cc97dSMarkus Armbruster           { true, false, true } },
299a72f6754SMarkus Armbruster         { &addr_tight,
300a72f6754SMarkus Armbruster           { &addr_padded, &addr, &addr_tight },
301b08cc97dSMarkus Armbruster           { false, true, true } },
302a72f6754SMarkus Armbruster         { &addr_padded,
303a72f6754SMarkus Armbruster           { &addr, &addr_tight, &addr_padded },
304b08cc97dSMarkus Armbruster           { false, false, true } }
305a72f6754SMarkus Armbruster     };
306a72f6754SMarkus Armbruster     int i;
3074d3a329aSxiaoqiang zhao 
308718a9be0SMarkus Armbruster     addr.type = SOCKET_ADDRESS_TYPE_UNIX;
309718a9be0SMarkus Armbruster     addr.u.q_unix.path = g_strdup_printf("unix-%d-%u",
310718a9be0SMarkus Armbruster                                          getpid(), g_random_int());
311718a9be0SMarkus Armbruster     addr.u.q_unix.has_abstract = true;
312718a9be0SMarkus Armbruster     addr.u.q_unix.abstract = true;
313718a9be0SMarkus Armbruster     addr.u.q_unix.has_tight = false;
314718a9be0SMarkus Armbruster     addr.u.q_unix.tight = false;
3154d3a329aSxiaoqiang zhao 
316a72f6754SMarkus Armbruster     addr_tight = addr;
317a72f6754SMarkus Armbruster     addr_tight.u.q_unix.has_tight = true;
318a72f6754SMarkus Armbruster     addr_tight.u.q_unix.tight = true;
319a72f6754SMarkus Armbruster 
320a72f6754SMarkus Armbruster     addr_padded = addr;
321a72f6754SMarkus Armbruster     addr_padded.u.q_unix.has_tight = true;
322a72f6754SMarkus Armbruster     addr_padded.u.q_unix.tight = false;
323a72f6754SMarkus Armbruster 
324a72f6754SMarkus Armbruster     for (i = 0; i < ABSTRACT_SOCKET_VARIANTS; i++) {
325a72f6754SMarkus Armbruster         test_socket_unix_abstract_row(&matrix[i]);
326a72f6754SMarkus Armbruster     }
3274d3a329aSxiaoqiang zhao 
328718a9be0SMarkus Armbruster     g_free(addr.u.q_unix.path);
3294d3a329aSxiaoqiang zhao }
3308acefc79SMarkus Armbruster 
3318acefc79SMarkus Armbruster #endif  /* CONFIG_LINUX */
3321723d6b1SDaniel P. Berrange 
33358dc31f1SDaniel P. Berrange int main(int argc, char **argv)
33458dc31f1SDaniel P. Berrange {
33558dc31f1SDaniel P. Berrange     bool has_ipv4, has_ipv6;
33658dc31f1SDaniel P. Berrange 
3378330bd53SYonggang Luo     qemu_init_main_loop(&error_abort);
33858dc31f1SDaniel P. Berrange     socket_init();
33958dc31f1SDaniel P. Berrange 
34058dc31f1SDaniel P. Berrange     g_test_init(&argc, &argv, NULL);
34158dc31f1SDaniel P. Berrange 
34258dc31f1SDaniel P. Berrange     /* We're creating actual IPv4/6 sockets, so we should
34358dc31f1SDaniel P. Berrange      * check if the host running tests actually supports
34458dc31f1SDaniel P. Berrange      * each protocol to avoid breaking tests on machines
34558dc31f1SDaniel P. Berrange      * with either IPv4 or IPv6 disabled.
34658dc31f1SDaniel P. Berrange      */
34758dc31f1SDaniel P. Berrange     if (socket_check_protocol_support(&has_ipv4, &has_ipv6) < 0) {
348a4eb74a6SMarc-André Lureau         g_printerr("socket_check_protocol_support() failed\n");
349a4eb74a6SMarc-André Lureau         goto end;
35058dc31f1SDaniel P. Berrange     }
35158dc31f1SDaniel P. Berrange 
35258dc31f1SDaniel P. Berrange     if (has_ipv4) {
35358dc31f1SDaniel P. Berrange         g_test_add_func("/util/socket/is-socket/bad",
35458dc31f1SDaniel P. Berrange                         test_fd_is_socket_bad);
35558dc31f1SDaniel P. Berrange         g_test_add_func("/util/socket/is-socket/good",
35658dc31f1SDaniel P. Berrange                         test_fd_is_socket_good);
3578330bd53SYonggang Luo #ifndef _WIN32
3581723d6b1SDaniel P. Berrange         g_test_add_func("/socket/fd-pass/name/good",
3591723d6b1SDaniel P. Berrange                         test_socket_fd_pass_name_good);
3601723d6b1SDaniel P. Berrange         g_test_add_func("/socket/fd-pass/name/bad",
3611723d6b1SDaniel P. Berrange                         test_socket_fd_pass_name_bad);
3621723d6b1SDaniel P. Berrange         g_test_add_func("/socket/fd-pass/name/nomon",
3631723d6b1SDaniel P. Berrange                         test_socket_fd_pass_name_nomon);
3641723d6b1SDaniel P. Berrange         g_test_add_func("/socket/fd-pass/num/good",
3651723d6b1SDaniel P. Berrange                         test_socket_fd_pass_num_good);
3661723d6b1SDaniel P. Berrange         g_test_add_func("/socket/fd-pass/num/bad",
3671723d6b1SDaniel P. Berrange                         test_socket_fd_pass_num_bad);
3681723d6b1SDaniel P. Berrange         g_test_add_func("/socket/fd-pass/num/nocli",
3691723d6b1SDaniel P. Berrange                         test_socket_fd_pass_num_nocli);
3708330bd53SYonggang Luo #endif
37158dc31f1SDaniel P. Berrange     }
37258dc31f1SDaniel P. Berrange 
3738acefc79SMarkus Armbruster #ifdef CONFIG_LINUX
374a72f6754SMarkus Armbruster     g_test_add_func("/util/socket/unix-abstract",
375a72f6754SMarkus Armbruster                     test_socket_unix_abstract);
3764d3a329aSxiaoqiang zhao #endif
3774d3a329aSxiaoqiang zhao 
378a4eb74a6SMarc-André Lureau end:
37958dc31f1SDaniel P. Berrange     return g_test_run();
38058dc31f1SDaniel P. Berrange }
381