qemu

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

test-iov.c (17646B)


      1 #include "qemu/osdep.h"
      2 #include "qemu/iov.h"
      3 #include "qemu/sockets.h"
      4 
      5 /* create a randomly-sized iovec with random vectors */
      6 static void iov_random(struct iovec **iovp, unsigned *iov_cntp)
      7 {
      8      unsigned niov = g_test_rand_int_range(3,8);
      9      struct iovec *iov = g_malloc(niov * sizeof(*iov));
     10      unsigned i;
     11      for (i = 0; i < niov; ++i) {
     12          iov[i].iov_len = g_test_rand_int_range(5,20);
     13          iov[i].iov_base = g_malloc(iov[i].iov_len);
     14      }
     15      *iovp = iov;
     16      *iov_cntp = niov;
     17 }
     18 
     19 static void iov_free(struct iovec *iov, unsigned niov)
     20 {
     21     unsigned i;
     22     for (i = 0; i < niov; ++i) {
     23         g_free(iov[i].iov_base);
     24     }
     25     g_free(iov);
     26 }
     27 
     28 static bool iov_equals(const struct iovec *a, const struct iovec *b,
     29                        unsigned niov)
     30 {
     31     return memcmp(a, b, sizeof(a[0]) * niov) == 0;
     32 }
     33 
     34 static void test_iov_bytes(struct iovec *iov, unsigned niov,
     35                            size_t offset, size_t bytes)
     36 {
     37     unsigned i;
     38     size_t j, o;
     39     unsigned char *b;
     40     o = 0;
     41 
     42     /* we walk over all elements, */
     43     for (i = 0; i < niov; ++i) {
     44         b = iov[i].iov_base;
     45         /* over each char of each element, */
     46         for (j = 0; j < iov[i].iov_len; ++j) {
     47             /* counting each of them and
     48              * verifying that the ones within [offset,offset+bytes)
     49              * range are equal to the position number (o) */
     50             if (o >= offset && o < offset + bytes) {
     51                 g_assert(b[j] == (o & 255));
     52             } else {
     53                 g_assert(b[j] == 0xff);
     54             }
     55             ++o;
     56         }
     57     }
     58 }
     59 
     60 static void test_to_from_buf_1(void)
     61 {
     62      unsigned niov;
     63      struct iovec *iov;
     64      size_t sz;
     65      unsigned char *ibuf, *obuf;
     66      unsigned i, j, n;
     67 
     68      iov_random(&iov, &niov);
     69 
     70      sz = iov_size(iov, niov);
     71 
     72      ibuf = g_malloc(sz + 8) + 4;
     73      memcpy(ibuf-4, "aaaa", 4); memcpy(ibuf + sz, "bbbb", 4);
     74      obuf = g_malloc(sz + 8) + 4;
     75      memcpy(obuf-4, "xxxx", 4); memcpy(obuf + sz, "yyyy", 4);
     76 
     77      /* fill in ibuf with 0123456... */
     78      for (i = 0; i < sz; ++i) {
     79          ibuf[i] = i & 255;
     80      }
     81 
     82      for (i = 0; i <= sz; ++i) {
     83 
     84          /* Test from/to buf for offset(i) in [0..sz] up to the end of buffer.
     85           * For last iteration with offset == sz, the procedure should
     86           * skip whole vector and process exactly 0 bytes */
     87 
     88          /* first set bytes [i..sz) to some "random" value */
     89          n = iov_memset(iov, niov, 0, 0xff, sz);
     90          g_assert(n == sz);
     91 
     92          /* next copy bytes [i..sz) from ibuf to iovec */
     93          n = iov_from_buf(iov, niov, i, ibuf + i, sz - i);
     94          g_assert(n == sz - i);
     95 
     96          /* clear part of obuf */
     97          memset(obuf + i, 0, sz - i);
     98          /* and set this part of obuf to values from iovec */
     99          n = iov_to_buf(iov, niov, i, obuf + i, sz - i);
    100          g_assert(n == sz - i);
    101 
    102          /* now compare resulting buffers */
    103          g_assert(memcmp(ibuf, obuf, sz) == 0);
    104 
    105          /* test just one char */
    106          n = iov_to_buf(iov, niov, i, obuf + i, 1);
    107          g_assert(n == (i < sz));
    108          if (n) {
    109              g_assert(obuf[i] == (i & 255));
    110          }
    111 
    112          for (j = i; j <= sz; ++j) {
    113              /* now test num of bytes cap up to byte no. j,
    114               * with j in [i..sz]. */
    115 
    116              /* clear iovec */
    117              n = iov_memset(iov, niov, 0, 0xff, sz);
    118              g_assert(n == sz);
    119 
    120              /* copy bytes [i..j) from ibuf to iovec */
    121              n = iov_from_buf(iov, niov, i, ibuf + i, j - i);
    122              g_assert(n == j - i);
    123 
    124              /* clear part of obuf */
    125              memset(obuf + i, 0, j - i);
    126 
    127              /* copy bytes [i..j) from iovec to obuf */
    128              n = iov_to_buf(iov, niov, i, obuf + i, j - i);
    129              g_assert(n == j - i);
    130 
    131              /* verify result */
    132              g_assert(memcmp(ibuf, obuf, sz) == 0);
    133 
    134              /* now actually check if the iovec contains the right data */
    135              test_iov_bytes(iov, niov, i, j - i);
    136          }
    137     }
    138     g_assert(!memcmp(ibuf-4, "aaaa", 4) && !memcmp(ibuf+sz, "bbbb", 4));
    139     g_free(ibuf-4);
    140     g_assert(!memcmp(obuf-4, "xxxx", 4) && !memcmp(obuf+sz, "yyyy", 4));
    141     g_free(obuf-4);
    142     iov_free(iov, niov);
    143 }
    144 
    145 static void test_to_from_buf(void)
    146 {
    147     int x;
    148     for (x = 0; x < 4; ++x) {
    149         test_to_from_buf_1();
    150     }
    151 }
    152 
    153 static void test_io(void)
    154 {
    155 #ifndef _WIN32
    156 /* socketpair(PF_UNIX) which does not exist on windows */
    157 
    158     int sv[2];
    159     int r;
    160     unsigned i, j, k, s;
    161     fd_set fds;
    162     unsigned niov;
    163     struct iovec *iov, *siov;
    164     unsigned char *buf;
    165     size_t sz;
    166 
    167     iov_random(&iov, &niov);
    168     sz = iov_size(iov, niov);
    169     buf = g_malloc(sz);
    170     for (i = 0; i < sz; ++i) {
    171         buf[i] = i & 255;
    172     }
    173     iov_from_buf(iov, niov, 0, buf, sz);
    174 
    175     siov = g_memdup2(iov, sizeof(*iov) * niov);
    176 
    177     if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) < 0) {
    178        perror("socketpair");
    179        exit(1);
    180     }
    181 
    182     FD_ZERO(&fds);
    183 
    184     if (fork() == 0) {
    185        /* writer */
    186 
    187        close(sv[0]);
    188        FD_SET(sv[1], &fds);
    189        g_unix_set_fd_nonblocking(sv[1], true, NULL);
    190        r = g_test_rand_int_range(sz / 2, sz);
    191        setsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &r, sizeof(r));
    192 
    193        for (i = 0; i <= sz; ++i) {
    194            for (j = i; j <= sz; ++j) {
    195                k = i;
    196                do {
    197                    s = g_test_rand_int_range(0, j - k + 1);
    198                    r = iov_send(sv[1], iov, niov, k, s);
    199                    g_assert(memcmp(iov, siov, sizeof(*iov)*niov) == 0);
    200                    if (r >= 0) {
    201                        k += r;
    202                        usleep(g_test_rand_int_range(0, 30));
    203                    } else if (errno == EAGAIN) {
    204                        select(sv[1]+1, NULL, &fds, NULL, NULL);
    205                        continue;
    206                    } else {
    207                        perror("send");
    208                        exit(1);
    209                    }
    210                } while(k < j);
    211            }
    212        }
    213        iov_free(iov, niov);
    214        g_free(buf);
    215        g_free(siov);
    216        exit(0);
    217 
    218     } else {
    219        /* reader & verifier */
    220 
    221        close(sv[1]);
    222        FD_SET(sv[0], &fds);
    223        g_unix_set_fd_nonblocking(sv[0], true, NULL);
    224        r = g_test_rand_int_range(sz / 2, sz);
    225        setsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &r, sizeof(r));
    226        usleep(500000);
    227 
    228        for (i = 0; i <= sz; ++i) {
    229            for (j = i; j <= sz; ++j) {
    230                k = i;
    231                iov_memset(iov, niov, 0, 0xff, sz);
    232                do {
    233                    s = g_test_rand_int_range(0, j - k + 1);
    234                    r = iov_recv(sv[0], iov, niov, k, s);
    235                    g_assert(memcmp(iov, siov, sizeof(*iov)*niov) == 0);
    236                    if (r > 0) {
    237                        k += r;
    238                    } else if (!r) {
    239                        if (s) {
    240                            break;
    241                        }
    242                    } else if (errno == EAGAIN) {
    243                        select(sv[0]+1, &fds, NULL, NULL, NULL);
    244                        continue;
    245                    } else {
    246                        perror("recv");
    247                        exit(1);
    248                    }
    249                } while(k < j);
    250                test_iov_bytes(iov, niov, i, j - i);
    251            }
    252         }
    253 
    254        iov_free(iov, niov);
    255        g_free(buf);
    256        g_free(siov);
    257      }
    258 #endif
    259 }
    260 
    261 static void test_discard_front(void)
    262 {
    263     struct iovec *iov;
    264     struct iovec *iov_tmp;
    265     unsigned int iov_cnt;
    266     unsigned int iov_cnt_tmp;
    267     void *old_base;
    268     size_t size;
    269     size_t ret;
    270 
    271     /* Discard zero bytes */
    272     iov_random(&iov, &iov_cnt);
    273     iov_tmp = iov;
    274     iov_cnt_tmp = iov_cnt;
    275     ret = iov_discard_front(&iov_tmp, &iov_cnt_tmp, 0);
    276     g_assert(ret == 0);
    277     g_assert(iov_tmp == iov);
    278     g_assert(iov_cnt_tmp == iov_cnt);
    279     iov_free(iov, iov_cnt);
    280 
    281     /* Discard more bytes than vector size */
    282     iov_random(&iov, &iov_cnt);
    283     iov_tmp = iov;
    284     iov_cnt_tmp = iov_cnt;
    285     size = iov_size(iov, iov_cnt);
    286     ret = iov_discard_front(&iov_tmp, &iov_cnt_tmp, size + 1);
    287     g_assert(ret == size);
    288     g_assert(iov_cnt_tmp == 0);
    289     iov_free(iov, iov_cnt);
    290 
    291     /* Discard entire vector */
    292     iov_random(&iov, &iov_cnt);
    293     iov_tmp = iov;
    294     iov_cnt_tmp = iov_cnt;
    295     size = iov_size(iov, iov_cnt);
    296     ret = iov_discard_front(&iov_tmp, &iov_cnt_tmp, size);
    297     g_assert(ret == size);
    298     g_assert(iov_cnt_tmp == 0);
    299     iov_free(iov, iov_cnt);
    300 
    301     /* Discard within first element */
    302     iov_random(&iov, &iov_cnt);
    303     iov_tmp = iov;
    304     iov_cnt_tmp = iov_cnt;
    305     old_base = iov->iov_base;
    306     size = g_test_rand_int_range(1, iov->iov_len);
    307     ret = iov_discard_front(&iov_tmp, &iov_cnt_tmp, size);
    308     g_assert(ret == size);
    309     g_assert(iov_tmp == iov);
    310     g_assert(iov_cnt_tmp == iov_cnt);
    311     g_assert(iov_tmp->iov_base == old_base + size);
    312     iov_tmp->iov_base = old_base; /* undo before g_free() */
    313     iov_free(iov, iov_cnt);
    314 
    315     /* Discard entire first element */
    316     iov_random(&iov, &iov_cnt);
    317     iov_tmp = iov;
    318     iov_cnt_tmp = iov_cnt;
    319     ret = iov_discard_front(&iov_tmp, &iov_cnt_tmp, iov->iov_len);
    320     g_assert(ret == iov->iov_len);
    321     g_assert(iov_tmp == iov + 1);
    322     g_assert(iov_cnt_tmp == iov_cnt - 1);
    323     iov_free(iov, iov_cnt);
    324 
    325     /* Discard within second element */
    326     iov_random(&iov, &iov_cnt);
    327     iov_tmp = iov;
    328     iov_cnt_tmp = iov_cnt;
    329     old_base = iov[1].iov_base;
    330     size = iov->iov_len + g_test_rand_int_range(1, iov[1].iov_len);
    331     ret = iov_discard_front(&iov_tmp, &iov_cnt_tmp, size);
    332     g_assert(ret == size);
    333     g_assert(iov_tmp == iov + 1);
    334     g_assert(iov_cnt_tmp == iov_cnt - 1);
    335     g_assert(iov_tmp->iov_base == old_base + (size - iov->iov_len));
    336     iov_tmp->iov_base = old_base; /* undo before g_free() */
    337     iov_free(iov, iov_cnt);
    338 }
    339 
    340 static void test_discard_front_undo(void)
    341 {
    342     IOVDiscardUndo undo;
    343     struct iovec *iov;
    344     struct iovec *iov_tmp;
    345     struct iovec *iov_orig;
    346     unsigned int iov_cnt;
    347     unsigned int iov_cnt_tmp;
    348     size_t size;
    349 
    350     /* Discard zero bytes */
    351     iov_random(&iov, &iov_cnt);
    352     iov_orig = g_memdup2(iov, sizeof(iov[0]) * iov_cnt);
    353     iov_tmp = iov;
    354     iov_cnt_tmp = iov_cnt;
    355     iov_discard_front_undoable(&iov_tmp, &iov_cnt_tmp, 0, &undo);
    356     iov_discard_undo(&undo);
    357     assert(iov_equals(iov, iov_orig, iov_cnt));
    358     g_free(iov_orig);
    359     iov_free(iov, iov_cnt);
    360 
    361     /* Discard more bytes than vector size */
    362     iov_random(&iov, &iov_cnt);
    363     iov_orig = g_memdup2(iov, sizeof(iov[0]) * iov_cnt);
    364     iov_tmp = iov;
    365     iov_cnt_tmp = iov_cnt;
    366     size = iov_size(iov, iov_cnt);
    367     iov_discard_front_undoable(&iov_tmp, &iov_cnt_tmp, size + 1, &undo);
    368     iov_discard_undo(&undo);
    369     assert(iov_equals(iov, iov_orig, iov_cnt));
    370     g_free(iov_orig);
    371     iov_free(iov, iov_cnt);
    372 
    373     /* Discard entire vector */
    374     iov_random(&iov, &iov_cnt);
    375     iov_orig = g_memdup2(iov, sizeof(iov[0]) * iov_cnt);
    376     iov_tmp = iov;
    377     iov_cnt_tmp = iov_cnt;
    378     size = iov_size(iov, iov_cnt);
    379     iov_discard_front_undoable(&iov_tmp, &iov_cnt_tmp, size, &undo);
    380     iov_discard_undo(&undo);
    381     assert(iov_equals(iov, iov_orig, iov_cnt));
    382     g_free(iov_orig);
    383     iov_free(iov, iov_cnt);
    384 
    385     /* Discard within first element */
    386     iov_random(&iov, &iov_cnt);
    387     iov_orig = g_memdup2(iov, sizeof(iov[0]) * iov_cnt);
    388     iov_tmp = iov;
    389     iov_cnt_tmp = iov_cnt;
    390     size = g_test_rand_int_range(1, iov->iov_len);
    391     iov_discard_front_undoable(&iov_tmp, &iov_cnt_tmp, size, &undo);
    392     iov_discard_undo(&undo);
    393     assert(iov_equals(iov, iov_orig, iov_cnt));
    394     g_free(iov_orig);
    395     iov_free(iov, iov_cnt);
    396 
    397     /* Discard entire first element */
    398     iov_random(&iov, &iov_cnt);
    399     iov_orig = g_memdup2(iov, sizeof(iov[0]) * iov_cnt);
    400     iov_tmp = iov;
    401     iov_cnt_tmp = iov_cnt;
    402     iov_discard_front_undoable(&iov_tmp, &iov_cnt_tmp, iov->iov_len, &undo);
    403     iov_discard_undo(&undo);
    404     assert(iov_equals(iov, iov_orig, iov_cnt));
    405     g_free(iov_orig);
    406     iov_free(iov, iov_cnt);
    407 
    408     /* Discard within second element */
    409     iov_random(&iov, &iov_cnt);
    410     iov_orig = g_memdup2(iov, sizeof(iov[0]) * iov_cnt);
    411     iov_tmp = iov;
    412     iov_cnt_tmp = iov_cnt;
    413     size = iov->iov_len + g_test_rand_int_range(1, iov[1].iov_len);
    414     iov_discard_front_undoable(&iov_tmp, &iov_cnt_tmp, size, &undo);
    415     iov_discard_undo(&undo);
    416     assert(iov_equals(iov, iov_orig, iov_cnt));
    417     g_free(iov_orig);
    418     iov_free(iov, iov_cnt);
    419 }
    420 
    421 static void test_discard_back(void)
    422 {
    423     struct iovec *iov;
    424     unsigned int iov_cnt;
    425     unsigned int iov_cnt_tmp;
    426     void *old_base;
    427     size_t size;
    428     size_t ret;
    429 
    430     /* Discard zero bytes */
    431     iov_random(&iov, &iov_cnt);
    432     iov_cnt_tmp = iov_cnt;
    433     ret = iov_discard_back(iov, &iov_cnt_tmp, 0);
    434     g_assert(ret == 0);
    435     g_assert(iov_cnt_tmp == iov_cnt);
    436     iov_free(iov, iov_cnt);
    437 
    438     /* Discard more bytes than vector size */
    439     iov_random(&iov, &iov_cnt);
    440     iov_cnt_tmp = iov_cnt;
    441     size = iov_size(iov, iov_cnt);
    442     ret = iov_discard_back(iov, &iov_cnt_tmp, size + 1);
    443     g_assert(ret == size);
    444     g_assert(iov_cnt_tmp == 0);
    445     iov_free(iov, iov_cnt);
    446 
    447     /* Discard entire vector */
    448     iov_random(&iov, &iov_cnt);
    449     iov_cnt_tmp = iov_cnt;
    450     size = iov_size(iov, iov_cnt);
    451     ret = iov_discard_back(iov, &iov_cnt_tmp, size);
    452     g_assert(ret == size);
    453     g_assert(iov_cnt_tmp == 0);
    454     iov_free(iov, iov_cnt);
    455 
    456     /* Discard within last element */
    457     iov_random(&iov, &iov_cnt);
    458     iov_cnt_tmp = iov_cnt;
    459     old_base = iov[iov_cnt - 1].iov_base;
    460     size = g_test_rand_int_range(1, iov[iov_cnt - 1].iov_len);
    461     ret = iov_discard_back(iov, &iov_cnt_tmp, size);
    462     g_assert(ret == size);
    463     g_assert(iov_cnt_tmp == iov_cnt);
    464     g_assert(iov[iov_cnt - 1].iov_base == old_base);
    465     iov_free(iov, iov_cnt);
    466 
    467     /* Discard entire last element */
    468     iov_random(&iov, &iov_cnt);
    469     iov_cnt_tmp = iov_cnt;
    470     old_base = iov[iov_cnt - 1].iov_base;
    471     size = iov[iov_cnt - 1].iov_len;
    472     ret = iov_discard_back(iov, &iov_cnt_tmp, size);
    473     g_assert(ret == size);
    474     g_assert(iov_cnt_tmp == iov_cnt - 1);
    475     iov_free(iov, iov_cnt);
    476 
    477     /* Discard within second-to-last element */
    478     iov_random(&iov, &iov_cnt);
    479     iov_cnt_tmp = iov_cnt;
    480     old_base = iov[iov_cnt - 2].iov_base;
    481     size = iov[iov_cnt - 1].iov_len +
    482            g_test_rand_int_range(1, iov[iov_cnt - 2].iov_len);
    483     ret = iov_discard_back(iov, &iov_cnt_tmp, size);
    484     g_assert(ret == size);
    485     g_assert(iov_cnt_tmp == iov_cnt - 1);
    486     g_assert(iov[iov_cnt - 2].iov_base == old_base);
    487     iov_free(iov, iov_cnt);
    488 }
    489 
    490 static void test_discard_back_undo(void)
    491 {
    492     IOVDiscardUndo undo;
    493     struct iovec *iov;
    494     struct iovec *iov_orig;
    495     unsigned int iov_cnt;
    496     unsigned int iov_cnt_tmp;
    497     size_t size;
    498 
    499     /* Discard zero bytes */
    500     iov_random(&iov, &iov_cnt);
    501     iov_orig = g_memdup2(iov, sizeof(iov[0]) * iov_cnt);
    502     iov_cnt_tmp = iov_cnt;
    503     iov_discard_back_undoable(iov, &iov_cnt_tmp, 0, &undo);
    504     iov_discard_undo(&undo);
    505     assert(iov_equals(iov, iov_orig, iov_cnt));
    506     g_free(iov_orig);
    507     iov_free(iov, iov_cnt);
    508 
    509     /* Discard more bytes than vector size */
    510     iov_random(&iov, &iov_cnt);
    511     iov_orig = g_memdup2(iov, sizeof(iov[0]) * iov_cnt);
    512     iov_cnt_tmp = iov_cnt;
    513     size = iov_size(iov, iov_cnt);
    514     iov_discard_back_undoable(iov, &iov_cnt_tmp, size + 1, &undo);
    515     iov_discard_undo(&undo);
    516     assert(iov_equals(iov, iov_orig, iov_cnt));
    517     g_free(iov_orig);
    518     iov_free(iov, iov_cnt);
    519 
    520     /* Discard entire vector */
    521     iov_random(&iov, &iov_cnt);
    522     iov_orig = g_memdup2(iov, sizeof(iov[0]) * iov_cnt);
    523     iov_cnt_tmp = iov_cnt;
    524     size = iov_size(iov, iov_cnt);
    525     iov_discard_back_undoable(iov, &iov_cnt_tmp, size, &undo);
    526     iov_discard_undo(&undo);
    527     assert(iov_equals(iov, iov_orig, iov_cnt));
    528     g_free(iov_orig);
    529     iov_free(iov, iov_cnt);
    530 
    531     /* Discard within last element */
    532     iov_random(&iov, &iov_cnt);
    533     iov_orig = g_memdup2(iov, sizeof(iov[0]) * iov_cnt);
    534     iov_cnt_tmp = iov_cnt;
    535     size = g_test_rand_int_range(1, iov[iov_cnt - 1].iov_len);
    536     iov_discard_back_undoable(iov, &iov_cnt_tmp, size, &undo);
    537     iov_discard_undo(&undo);
    538     assert(iov_equals(iov, iov_orig, iov_cnt));
    539     g_free(iov_orig);
    540     iov_free(iov, iov_cnt);
    541 
    542     /* Discard entire last element */
    543     iov_random(&iov, &iov_cnt);
    544     iov_orig = g_memdup2(iov, sizeof(iov[0]) * iov_cnt);
    545     iov_cnt_tmp = iov_cnt;
    546     size = iov[iov_cnt - 1].iov_len;
    547     iov_discard_back_undoable(iov, &iov_cnt_tmp, size, &undo);
    548     iov_discard_undo(&undo);
    549     assert(iov_equals(iov, iov_orig, iov_cnt));
    550     g_free(iov_orig);
    551     iov_free(iov, iov_cnt);
    552 
    553     /* Discard within second-to-last element */
    554     iov_random(&iov, &iov_cnt);
    555     iov_orig = g_memdup2(iov, sizeof(iov[0]) * iov_cnt);
    556     iov_cnt_tmp = iov_cnt;
    557     size = iov[iov_cnt - 1].iov_len +
    558            g_test_rand_int_range(1, iov[iov_cnt - 2].iov_len);
    559     iov_discard_back_undoable(iov, &iov_cnt_tmp, size, &undo);
    560     iov_discard_undo(&undo);
    561     assert(iov_equals(iov, iov_orig, iov_cnt));
    562     g_free(iov_orig);
    563     iov_free(iov, iov_cnt);
    564 }
    565 
    566 int main(int argc, char **argv)
    567 {
    568     g_test_init(&argc, &argv, NULL);
    569     g_test_rand_int();
    570     g_test_add_func("/basic/iov/from-to-buf", test_to_from_buf);
    571     g_test_add_func("/basic/iov/io", test_io);
    572     g_test_add_func("/basic/iov/discard-front", test_discard_front);
    573     g_test_add_func("/basic/iov/discard-back", test_discard_back);
    574     g_test_add_func("/basic/iov/discard-front-undo", test_discard_front_undo);
    575     g_test_add_func("/basic/iov/discard-back-undo", test_discard_back_undo);
    576     return g_test_run();
    577 }