qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

test-io-channel-socket.c (19054B)


      1 /*
      2  * QEMU I/O channel sockets test
      3  *
      4  * Copyright (c) 2015-2016 Red Hat, Inc.
      5  *
      6  * This library is free software; you can redistribute it and/or
      7  * modify it under the terms of the GNU Lesser General Public
      8  * License as published by the Free Software Foundation; either
      9  * version 2.1 of the License, or (at your option) any later version.
     10  *
     11  * This library is distributed in the hope that it will be useful,
     12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14  * Lesser General Public License for more details.
     15  *
     16  * You should have received a copy of the GNU Lesser General Public
     17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
     18  *
     19  */
     20 
     21 #include "qemu/osdep.h"
     22 #include "io/channel-socket.h"
     23 #include "io/channel-util.h"
     24 #include "io-channel-helpers.h"
     25 #include "socket-helpers.h"
     26 #include "qapi/error.h"
     27 #include "qemu/module.h"
     28 #include "qemu/main-loop.h"
     29 
     30 
     31 static void test_io_channel_set_socket_bufs(QIOChannel *src,
     32                                             QIOChannel *dst)
     33 {
     34     int buflen = 64 * 1024;
     35 
     36     /*
     37      * Make the socket buffers small so that we see
     38      * the effects of partial reads/writes
     39      */
     40     setsockopt(((QIOChannelSocket *)src)->fd,
     41                SOL_SOCKET, SO_SNDBUF,
     42                (char *)&buflen,
     43                sizeof(buflen));
     44 
     45     setsockopt(((QIOChannelSocket *)dst)->fd,
     46                SOL_SOCKET, SO_SNDBUF,
     47                (char *)&buflen,
     48                sizeof(buflen));
     49 }
     50 
     51 
     52 static void test_io_channel_setup_sync(SocketAddress *listen_addr,
     53                                        SocketAddress *connect_addr,
     54                                        QIOChannel **srv,
     55                                        QIOChannel **src,
     56                                        QIOChannel **dst)
     57 {
     58     QIOChannelSocket *lioc;
     59 
     60     lioc = qio_channel_socket_new();
     61     qio_channel_socket_listen_sync(lioc, listen_addr, 1, &error_abort);
     62 
     63     if (listen_addr->type == SOCKET_ADDRESS_TYPE_INET) {
     64         SocketAddress *laddr = qio_channel_socket_get_local_address(
     65             lioc, &error_abort);
     66 
     67         g_free(connect_addr->u.inet.port);
     68         connect_addr->u.inet.port = g_strdup(laddr->u.inet.port);
     69 
     70         qapi_free_SocketAddress(laddr);
     71     }
     72 
     73     *src = QIO_CHANNEL(qio_channel_socket_new());
     74     qio_channel_socket_connect_sync(
     75         QIO_CHANNEL_SOCKET(*src), connect_addr, &error_abort);
     76     qio_channel_set_delay(*src, false);
     77 
     78     qio_channel_wait(QIO_CHANNEL(lioc), G_IO_IN);
     79     *dst = QIO_CHANNEL(qio_channel_socket_accept(lioc, &error_abort));
     80     g_assert(*dst);
     81 
     82     test_io_channel_set_socket_bufs(*src, *dst);
     83 
     84     *srv = QIO_CHANNEL(lioc);
     85 }
     86 
     87 
     88 struct TestIOChannelData {
     89     bool err;
     90     GMainLoop *loop;
     91 };
     92 
     93 
     94 static void test_io_channel_complete(QIOTask *task,
     95                                      gpointer opaque)
     96 {
     97     struct TestIOChannelData *data = opaque;
     98     data->err = qio_task_propagate_error(task, NULL);
     99     g_main_loop_quit(data->loop);
    100 }
    101 
    102 
    103 static void test_io_channel_setup_async(SocketAddress *listen_addr,
    104                                         SocketAddress *connect_addr,
    105                                         QIOChannel **srv,
    106                                         QIOChannel **src,
    107                                         QIOChannel **dst)
    108 {
    109     QIOChannelSocket *lioc;
    110     struct TestIOChannelData data;
    111 
    112     data.loop = g_main_loop_new(g_main_context_default(),
    113                                 TRUE);
    114 
    115     lioc = qio_channel_socket_new();
    116     qio_channel_socket_listen_async(
    117         lioc, listen_addr, 1,
    118         test_io_channel_complete, &data, NULL, NULL);
    119 
    120     g_main_loop_run(data.loop);
    121     g_main_context_iteration(g_main_context_default(), FALSE);
    122 
    123     g_assert(!data.err);
    124 
    125     if (listen_addr->type == SOCKET_ADDRESS_TYPE_INET) {
    126         SocketAddress *laddr = qio_channel_socket_get_local_address(
    127             lioc, &error_abort);
    128 
    129         g_free(connect_addr->u.inet.port);
    130         connect_addr->u.inet.port = g_strdup(laddr->u.inet.port);
    131 
    132         qapi_free_SocketAddress(laddr);
    133     }
    134 
    135     *src = QIO_CHANNEL(qio_channel_socket_new());
    136 
    137     qio_channel_socket_connect_async(
    138         QIO_CHANNEL_SOCKET(*src), connect_addr,
    139         test_io_channel_complete, &data, NULL, NULL);
    140 
    141     g_main_loop_run(data.loop);
    142     g_main_context_iteration(g_main_context_default(), FALSE);
    143 
    144     g_assert(!data.err);
    145 
    146     qio_channel_wait(QIO_CHANNEL(lioc), G_IO_IN);
    147     *dst = QIO_CHANNEL(qio_channel_socket_accept(lioc, &error_abort));
    148     g_assert(*dst);
    149 
    150     qio_channel_set_delay(*src, false);
    151     test_io_channel_set_socket_bufs(*src, *dst);
    152 
    153     *srv = QIO_CHANNEL(lioc);
    154 
    155     g_main_loop_unref(data.loop);
    156 }
    157 
    158 
    159 static void test_io_channel_socket_path_exists(SocketAddress *addr,
    160                                                bool expectExists)
    161 {
    162     if (addr->type != SOCKET_ADDRESS_TYPE_UNIX) {
    163         return;
    164     }
    165 
    166     g_assert(g_file_test(addr->u.q_unix.path,
    167                          G_FILE_TEST_EXISTS) == expectExists);
    168 }
    169 
    170 
    171 static void test_io_channel(bool async,
    172                             SocketAddress *listen_addr,
    173                             SocketAddress *connect_addr,
    174                             bool passFD)
    175 {
    176     QIOChannel *src, *dst, *srv;
    177     QIOChannelTest *test;
    178     if (async) {
    179         test_io_channel_setup_async(listen_addr, connect_addr,
    180                                     &srv, &src, &dst);
    181 
    182 #ifndef _WIN32
    183         g_assert(!passFD ||
    184                  qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
    185         g_assert(!passFD ||
    186                  qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_FD_PASS));
    187 #endif
    188         g_assert(qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_SHUTDOWN));
    189         g_assert(qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_SHUTDOWN));
    190 
    191         test_io_channel_socket_path_exists(listen_addr, true);
    192 
    193         test = qio_channel_test_new();
    194         qio_channel_test_run_threads(test, true, src, dst);
    195         qio_channel_test_validate(test);
    196 
    197         test_io_channel_socket_path_exists(listen_addr, true);
    198 
    199         /* unref without close, to ensure finalize() cleans up */
    200 
    201         object_unref(OBJECT(src));
    202         object_unref(OBJECT(dst));
    203         test_io_channel_socket_path_exists(listen_addr, true);
    204 
    205         object_unref(OBJECT(srv));
    206         test_io_channel_socket_path_exists(listen_addr, false);
    207 
    208         test_io_channel_setup_async(listen_addr, connect_addr,
    209                                     &srv, &src, &dst);
    210 
    211 #ifndef _WIN32
    212         g_assert(!passFD ||
    213                  qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
    214         g_assert(!passFD ||
    215                  qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_FD_PASS));
    216 #endif
    217         g_assert(qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_SHUTDOWN));
    218         g_assert(qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_SHUTDOWN));
    219 
    220         test = qio_channel_test_new();
    221         qio_channel_test_run_threads(test, false, src, dst);
    222         qio_channel_test_validate(test);
    223 
    224         /* close before unref, to ensure finalize copes with already closed */
    225 
    226         qio_channel_close(src, &error_abort);
    227         qio_channel_close(dst, &error_abort);
    228         test_io_channel_socket_path_exists(listen_addr, true);
    229 
    230         object_unref(OBJECT(src));
    231         object_unref(OBJECT(dst));
    232         test_io_channel_socket_path_exists(listen_addr, true);
    233 
    234         qio_channel_close(srv, &error_abort);
    235         test_io_channel_socket_path_exists(listen_addr, false);
    236 
    237         object_unref(OBJECT(srv));
    238         test_io_channel_socket_path_exists(listen_addr, false);
    239     } else {
    240         test_io_channel_setup_sync(listen_addr, connect_addr,
    241                                    &srv, &src, &dst);
    242 
    243 #ifndef _WIN32
    244         g_assert(!passFD ||
    245                  qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
    246         g_assert(!passFD ||
    247                  qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_FD_PASS));
    248 #endif
    249         g_assert(qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_SHUTDOWN));
    250         g_assert(qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_SHUTDOWN));
    251 
    252         test_io_channel_socket_path_exists(listen_addr, true);
    253 
    254         test = qio_channel_test_new();
    255         qio_channel_test_run_threads(test, true, src, dst);
    256         qio_channel_test_validate(test);
    257 
    258         test_io_channel_socket_path_exists(listen_addr, true);
    259 
    260         /* unref without close, to ensure finalize() cleans up */
    261 
    262         object_unref(OBJECT(src));
    263         object_unref(OBJECT(dst));
    264         test_io_channel_socket_path_exists(listen_addr, true);
    265 
    266         object_unref(OBJECT(srv));
    267         test_io_channel_socket_path_exists(listen_addr, false);
    268 
    269         test_io_channel_setup_sync(listen_addr, connect_addr,
    270                                    &srv, &src, &dst);
    271 
    272 #ifndef _WIN32
    273         g_assert(!passFD ||
    274                  qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
    275         g_assert(!passFD ||
    276                  qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_FD_PASS));
    277 #endif
    278         g_assert(qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_SHUTDOWN));
    279         g_assert(qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_SHUTDOWN));
    280 
    281         test = qio_channel_test_new();
    282         qio_channel_test_run_threads(test, false, src, dst);
    283         qio_channel_test_validate(test);
    284 
    285         test_io_channel_socket_path_exists(listen_addr, true);
    286 
    287         /* close before unref, to ensure finalize copes with already closed */
    288 
    289         qio_channel_close(src, &error_abort);
    290         qio_channel_close(dst, &error_abort);
    291         test_io_channel_socket_path_exists(listen_addr, true);
    292 
    293         object_unref(OBJECT(src));
    294         object_unref(OBJECT(dst));
    295         test_io_channel_socket_path_exists(listen_addr, true);
    296 
    297         qio_channel_close(srv, &error_abort);
    298         test_io_channel_socket_path_exists(listen_addr, false);
    299 
    300         object_unref(OBJECT(srv));
    301         test_io_channel_socket_path_exists(listen_addr, false);
    302     }
    303 }
    304 
    305 
    306 static void test_io_channel_ipv4(bool async)
    307 {
    308     SocketAddress *listen_addr = g_new0(SocketAddress, 1);
    309     SocketAddress *connect_addr = g_new0(SocketAddress, 1);
    310 
    311     listen_addr->type = SOCKET_ADDRESS_TYPE_INET;
    312     listen_addr->u.inet = (InetSocketAddress) {
    313         .host = g_strdup("127.0.0.1"),
    314         .port = NULL, /* Auto-select */
    315     };
    316 
    317     connect_addr->type = SOCKET_ADDRESS_TYPE_INET;
    318     connect_addr->u.inet = (InetSocketAddress) {
    319         .host = g_strdup("127.0.0.1"),
    320         .port = NULL, /* Filled in later */
    321     };
    322 
    323     test_io_channel(async, listen_addr, connect_addr, false);
    324 
    325     qapi_free_SocketAddress(listen_addr);
    326     qapi_free_SocketAddress(connect_addr);
    327 }
    328 
    329 
    330 static void test_io_channel_ipv4_sync(void)
    331 {
    332     return test_io_channel_ipv4(false);
    333 }
    334 
    335 
    336 static void test_io_channel_ipv4_async(void)
    337 {
    338     return test_io_channel_ipv4(true);
    339 }
    340 
    341 
    342 static void test_io_channel_ipv6(bool async)
    343 {
    344     SocketAddress *listen_addr = g_new0(SocketAddress, 1);
    345     SocketAddress *connect_addr = g_new0(SocketAddress, 1);
    346 
    347     listen_addr->type = SOCKET_ADDRESS_TYPE_INET;
    348     listen_addr->u.inet = (InetSocketAddress) {
    349         .host = g_strdup("::1"),
    350         .port = NULL, /* Auto-select */
    351     };
    352 
    353     connect_addr->type = SOCKET_ADDRESS_TYPE_INET;
    354     connect_addr->u.inet = (InetSocketAddress) {
    355         .host = g_strdup("::1"),
    356         .port = NULL, /* Filled in later */
    357     };
    358 
    359     test_io_channel(async, listen_addr, connect_addr, false);
    360 
    361     qapi_free_SocketAddress(listen_addr);
    362     qapi_free_SocketAddress(connect_addr);
    363 }
    364 
    365 
    366 static void test_io_channel_ipv6_sync(void)
    367 {
    368     return test_io_channel_ipv6(false);
    369 }
    370 
    371 
    372 static void test_io_channel_ipv6_async(void)
    373 {
    374     return test_io_channel_ipv6(true);
    375 }
    376 
    377 
    378 static void test_io_channel_unix(bool async)
    379 {
    380     SocketAddress *listen_addr = g_new0(SocketAddress, 1);
    381     SocketAddress *connect_addr = g_new0(SocketAddress, 1);
    382 
    383 #define TEST_SOCKET "test-io-channel-socket.sock"
    384     listen_addr->type = SOCKET_ADDRESS_TYPE_UNIX;
    385     listen_addr->u.q_unix.path = g_strdup(TEST_SOCKET);
    386 
    387     connect_addr->type = SOCKET_ADDRESS_TYPE_UNIX;
    388     connect_addr->u.q_unix.path = g_strdup(TEST_SOCKET);
    389 
    390     test_io_channel(async, listen_addr, connect_addr, true);
    391 
    392     qapi_free_SocketAddress(listen_addr);
    393     qapi_free_SocketAddress(connect_addr);
    394 }
    395 
    396 
    397 static void test_io_channel_unix_sync(void)
    398 {
    399     return test_io_channel_unix(false);
    400 }
    401 
    402 
    403 static void test_io_channel_unix_async(void)
    404 {
    405     return test_io_channel_unix(true);
    406 }
    407 
    408 #ifndef _WIN32
    409 static void test_io_channel_unix_fd_pass(void)
    410 {
    411     SocketAddress *listen_addr = g_new0(SocketAddress, 1);
    412     SocketAddress *connect_addr = g_new0(SocketAddress, 1);
    413     QIOChannel *src, *dst, *srv;
    414     int testfd;
    415     int fdsend[3];
    416     int *fdrecv = NULL;
    417     size_t nfdrecv = 0;
    418     size_t i;
    419     char bufsend[12], bufrecv[12];
    420     struct iovec iosend[1], iorecv[1];
    421 
    422 #define TEST_SOCKET "test-io-channel-socket.sock"
    423 #define TEST_FILE "test-io-channel-socket.txt"
    424 
    425     testfd = open(TEST_FILE, O_RDWR|O_TRUNC|O_CREAT, 0700);
    426     g_assert(testfd != -1);
    427     fdsend[0] = testfd;
    428     fdsend[1] = testfd;
    429     fdsend[2] = testfd;
    430 
    431     listen_addr->type = SOCKET_ADDRESS_TYPE_UNIX;
    432     listen_addr->u.q_unix.path = g_strdup(TEST_SOCKET);
    433 
    434     connect_addr->type = SOCKET_ADDRESS_TYPE_UNIX;
    435     connect_addr->u.q_unix.path = g_strdup(TEST_SOCKET);
    436 
    437     test_io_channel_setup_sync(listen_addr, connect_addr, &srv, &src, &dst);
    438 
    439     memcpy(bufsend, "Hello World", G_N_ELEMENTS(bufsend));
    440 
    441     iosend[0].iov_base = bufsend;
    442     iosend[0].iov_len = G_N_ELEMENTS(bufsend);
    443 
    444     iorecv[0].iov_base = bufrecv;
    445     iorecv[0].iov_len = G_N_ELEMENTS(bufrecv);
    446 
    447     g_assert(qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
    448     g_assert(qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_FD_PASS));
    449 
    450     qio_channel_writev_full(src,
    451                             iosend,
    452                             G_N_ELEMENTS(iosend),
    453                             fdsend,
    454                             G_N_ELEMENTS(fdsend),
    455                             0,
    456                             &error_abort);
    457 
    458     qio_channel_readv_full(dst,
    459                            iorecv,
    460                            G_N_ELEMENTS(iorecv),
    461                            &fdrecv,
    462                            &nfdrecv,
    463                            &error_abort);
    464 
    465     g_assert(nfdrecv == G_N_ELEMENTS(fdsend));
    466     /* Each recvd FD should be different from sent FD */
    467     for (i = 0; i < nfdrecv; i++) {
    468         g_assert_cmpint(fdrecv[i], !=, testfd);
    469     }
    470     /* Each recvd FD should be different from each other */
    471     g_assert_cmpint(fdrecv[0], !=, fdrecv[1]);
    472     g_assert_cmpint(fdrecv[0], !=, fdrecv[2]);
    473     g_assert_cmpint(fdrecv[1], !=, fdrecv[2]);
    474 
    475     /* Check the I/O buf we sent at the same time matches */
    476     g_assert(memcmp(bufsend, bufrecv, G_N_ELEMENTS(bufsend)) == 0);
    477 
    478     /* Write some data into the FD we received */
    479     g_assert(write(fdrecv[0], bufsend, G_N_ELEMENTS(bufsend)) ==
    480              G_N_ELEMENTS(bufsend));
    481 
    482     /* Read data from the original FD and make sure it matches */
    483     memset(bufrecv, 0, G_N_ELEMENTS(bufrecv));
    484     g_assert(lseek(testfd, 0, SEEK_SET) == 0);
    485     g_assert(read(testfd, bufrecv, G_N_ELEMENTS(bufrecv)) ==
    486              G_N_ELEMENTS(bufrecv));
    487     g_assert(memcmp(bufsend, bufrecv, G_N_ELEMENTS(bufsend)) == 0);
    488 
    489     object_unref(OBJECT(src));
    490     object_unref(OBJECT(dst));
    491     object_unref(OBJECT(srv));
    492     qapi_free_SocketAddress(listen_addr);
    493     qapi_free_SocketAddress(connect_addr);
    494     unlink(TEST_SOCKET);
    495     unlink(TEST_FILE);
    496     close(testfd);
    497     for (i = 0; i < nfdrecv; i++) {
    498         close(fdrecv[i]);
    499     }
    500     g_free(fdrecv);
    501 }
    502 #endif /* _WIN32 */
    503 
    504 static void test_io_channel_unix_listen_cleanup(void)
    505 {
    506     QIOChannelSocket *ioc;
    507     struct sockaddr_un un;
    508     int sock;
    509 
    510 #define TEST_SOCKET "test-io-channel-socket.sock"
    511 
    512     ioc = qio_channel_socket_new();
    513 
    514     /* Manually bind ioc without calling the qio api to avoid setting
    515      * the LISTEN feature */
    516     sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0);
    517     memset(&un, 0, sizeof(un));
    518     un.sun_family = AF_UNIX;
    519     snprintf(un.sun_path, sizeof(un.sun_path), "%s", TEST_SOCKET);
    520     unlink(TEST_SOCKET);
    521     bind(sock, (struct sockaddr *)&un, sizeof(un));
    522     ioc->fd = sock;
    523     ioc->localAddrLen = sizeof(ioc->localAddr);
    524     getsockname(sock, (struct sockaddr *)&ioc->localAddr,
    525                 &ioc->localAddrLen);
    526 
    527     g_assert(g_file_test(TEST_SOCKET, G_FILE_TEST_EXISTS));
    528     object_unref(OBJECT(ioc));
    529     g_assert(g_file_test(TEST_SOCKET, G_FILE_TEST_EXISTS));
    530 
    531     unlink(TEST_SOCKET);
    532 }
    533 
    534 static void test_io_channel_ipv4_fd(void)
    535 {
    536     QIOChannel *ioc;
    537     int fd = -1;
    538     struct sockaddr_in sa = {
    539         .sin_family = AF_INET,
    540         .sin_addr = {
    541             .s_addr =  htonl(INADDR_LOOPBACK),
    542         }
    543         /* Leave port unset for auto-assign */
    544     };
    545     socklen_t salen = sizeof(sa);
    546 
    547     fd = socket(AF_INET, SOCK_STREAM, 0);
    548     g_assert_cmpint(fd, >, -1);
    549 
    550     g_assert_cmpint(bind(fd, (struct sockaddr *)&sa, salen), ==, 0);
    551 
    552     ioc = qio_channel_new_fd(fd, &error_abort);
    553 
    554     g_assert_cmpstr(object_get_typename(OBJECT(ioc)),
    555                     ==,
    556                     TYPE_QIO_CHANNEL_SOCKET);
    557 
    558     object_unref(OBJECT(ioc));
    559 }
    560 
    561 
    562 int main(int argc, char **argv)
    563 {
    564     bool has_ipv4, has_ipv6, has_afunix;
    565 
    566     module_call_init(MODULE_INIT_QOM);
    567     qemu_init_main_loop(&error_abort);
    568     socket_init();
    569 
    570     g_test_init(&argc, &argv, NULL);
    571 
    572     /* We're creating actual IPv4/6 sockets, so we should
    573      * check if the host running tests actually supports
    574      * each protocol to avoid breaking tests on machines
    575      * with either IPv4 or IPv6 disabled.
    576      */
    577     if (socket_check_protocol_support(&has_ipv4, &has_ipv6) < 0) {
    578         g_printerr("socket_check_protocol_support() failed\n");
    579         goto end;
    580     }
    581 
    582     if (has_ipv4) {
    583         g_test_add_func("/io/channel/socket/ipv4-sync",
    584                         test_io_channel_ipv4_sync);
    585         g_test_add_func("/io/channel/socket/ipv4-async",
    586                         test_io_channel_ipv4_async);
    587         g_test_add_func("/io/channel/socket/ipv4-fd",
    588                         test_io_channel_ipv4_fd);
    589     }
    590     if (has_ipv6) {
    591         g_test_add_func("/io/channel/socket/ipv6-sync",
    592                         test_io_channel_ipv6_sync);
    593         g_test_add_func("/io/channel/socket/ipv6-async",
    594                         test_io_channel_ipv6_async);
    595     }
    596 
    597     socket_check_afunix_support(&has_afunix);
    598     if (has_afunix) {
    599         g_test_add_func("/io/channel/socket/unix-sync",
    600                         test_io_channel_unix_sync);
    601         g_test_add_func("/io/channel/socket/unix-async",
    602                         test_io_channel_unix_async);
    603 #ifndef _WIN32
    604         g_test_add_func("/io/channel/socket/unix-fd-pass",
    605                         test_io_channel_unix_fd_pass);
    606 #endif
    607         g_test_add_func("/io/channel/socket/unix-listen-cleanup",
    608                         test_io_channel_unix_listen_cleanup);
    609     }
    610 
    611 end:
    612     return g_test_run();
    613 }