Statistics
| Branch: | Revision:

root / tests / test-iov.c @ 164a101f

History | View | Annotate | Download (11.8 kB)

1 2278a69e Michael Tokarev
#include <glib.h>
2 2278a69e Michael Tokarev
#include "qemu-common.h"
3 1de7afc9 Paolo Bonzini
#include "qemu/iov.h"
4 1de7afc9 Paolo Bonzini
#include "qemu/sockets.h"
5 2278a69e Michael Tokarev
6 2278a69e Michael Tokarev
/* create a randomly-sized iovec with random vectors */
7 2278a69e Michael Tokarev
static void iov_random(struct iovec **iovp, unsigned *iov_cntp)
8 2278a69e Michael Tokarev
{
9 2278a69e Michael Tokarev
     unsigned niov = g_test_rand_int_range(3,8);
10 2278a69e Michael Tokarev
     struct iovec *iov = g_malloc(niov * sizeof(*iov));
11 2278a69e Michael Tokarev
     unsigned i;
12 2278a69e Michael Tokarev
     for (i = 0; i < niov; ++i) {
13 2278a69e Michael Tokarev
         iov[i].iov_len = g_test_rand_int_range(5,20);
14 2278a69e Michael Tokarev
         iov[i].iov_base = g_malloc(iov[i].iov_len);
15 2278a69e Michael Tokarev
     }
16 2278a69e Michael Tokarev
     *iovp = iov;
17 2278a69e Michael Tokarev
     *iov_cntp = niov;
18 2278a69e Michael Tokarev
}
19 2278a69e Michael Tokarev
20 2278a69e Michael Tokarev
static void iov_free(struct iovec *iov, unsigned niov)
21 2278a69e Michael Tokarev
{
22 2278a69e Michael Tokarev
    unsigned i;
23 2278a69e Michael Tokarev
    for (i = 0; i < niov; ++i) {
24 2278a69e Michael Tokarev
        g_free(iov[i].iov_base);
25 2278a69e Michael Tokarev
    }
26 2278a69e Michael Tokarev
    g_free(iov);
27 2278a69e Michael Tokarev
}
28 2278a69e Michael Tokarev
29 2278a69e Michael Tokarev
static void test_iov_bytes(struct iovec *iov, unsigned niov,
30 2278a69e Michael Tokarev
                           size_t offset, size_t bytes)
31 2278a69e Michael Tokarev
{
32 2278a69e Michael Tokarev
    unsigned i;
33 2278a69e Michael Tokarev
    size_t j, o;
34 2278a69e Michael Tokarev
    unsigned char *b;
35 2278a69e Michael Tokarev
    o = 0;
36 2278a69e Michael Tokarev
37 2278a69e Michael Tokarev
    /* we walk over all elements, */
38 2278a69e Michael Tokarev
    for (i = 0; i < niov; ++i) {
39 2278a69e Michael Tokarev
        b = iov[i].iov_base;
40 2278a69e Michael Tokarev
        /* over each char of each element, */
41 2278a69e Michael Tokarev
        for (j = 0; j < iov[i].iov_len; ++j) {
42 2278a69e Michael Tokarev
            /* counting each of them and
43 2278a69e Michael Tokarev
             * verifying that the ones within [offset,offset+bytes)
44 2278a69e Michael Tokarev
             * range are equal to the position number (o) */
45 2278a69e Michael Tokarev
            if (o >= offset && o < offset + bytes) {
46 2278a69e Michael Tokarev
                g_assert(b[j] == (o & 255));
47 2278a69e Michael Tokarev
            } else {
48 2278a69e Michael Tokarev
                g_assert(b[j] == 0xff);
49 2278a69e Michael Tokarev
            }
50 2278a69e Michael Tokarev
            ++o;
51 2278a69e Michael Tokarev
        }
52 2278a69e Michael Tokarev
    }
53 2278a69e Michael Tokarev
}
54 2278a69e Michael Tokarev
55 2278a69e Michael Tokarev
static void test_to_from_buf_1(void)
56 2278a69e Michael Tokarev
{
57 2278a69e Michael Tokarev
     unsigned niov;
58 2278a69e Michael Tokarev
     struct iovec *iov;
59 2278a69e Michael Tokarev
     size_t sz;
60 2278a69e Michael Tokarev
     unsigned char *ibuf, *obuf;
61 2278a69e Michael Tokarev
     unsigned i, j, n;
62 2278a69e Michael Tokarev
63 2278a69e Michael Tokarev
     iov_random(&iov, &niov);
64 2278a69e Michael Tokarev
65 2278a69e Michael Tokarev
     sz = iov_size(iov, niov);
66 2278a69e Michael Tokarev
67 2278a69e Michael Tokarev
     ibuf = g_malloc(sz + 8) + 4;
68 2278a69e Michael Tokarev
     memcpy(ibuf-4, "aaaa", 4); memcpy(ibuf + sz, "bbbb", 4);
69 2278a69e Michael Tokarev
     obuf = g_malloc(sz + 8) + 4;
70 2278a69e Michael Tokarev
     memcpy(obuf-4, "xxxx", 4); memcpy(obuf + sz, "yyyy", 4);
71 2278a69e Michael Tokarev
72 2278a69e Michael Tokarev
     /* fill in ibuf with 0123456... */
73 2278a69e Michael Tokarev
     for (i = 0; i < sz; ++i) {
74 2278a69e Michael Tokarev
         ibuf[i] = i & 255;
75 2278a69e Michael Tokarev
     }
76 2278a69e Michael Tokarev
77 2278a69e Michael Tokarev
     for (i = 0; i <= sz; ++i) {
78 2278a69e Michael Tokarev
79 2278a69e Michael Tokarev
         /* Test from/to buf for offset(i) in [0..sz] up to the end of buffer.
80 2278a69e Michael Tokarev
          * For last iteration with offset == sz, the procedure should
81 2278a69e Michael Tokarev
          * skip whole vector and process exactly 0 bytes */
82 2278a69e Michael Tokarev
83 2278a69e Michael Tokarev
         /* first set bytes [i..sz) to some "random" value */
84 2278a69e Michael Tokarev
         n = iov_memset(iov, niov, 0, 0xff, -1);
85 2278a69e Michael Tokarev
         g_assert(n == sz);
86 2278a69e Michael Tokarev
87 2278a69e Michael Tokarev
         /* next copy bytes [i..sz) from ibuf to iovec */
88 2278a69e Michael Tokarev
         n = iov_from_buf(iov, niov, i, ibuf + i, -1);
89 2278a69e Michael Tokarev
         g_assert(n == sz - i);
90 2278a69e Michael Tokarev
91 2278a69e Michael Tokarev
         /* clear part of obuf */
92 2278a69e Michael Tokarev
         memset(obuf + i, 0, sz - i);
93 2278a69e Michael Tokarev
         /* and set this part of obuf to values from iovec */
94 2278a69e Michael Tokarev
         n = iov_to_buf(iov, niov, i, obuf + i, -1);
95 2278a69e Michael Tokarev
         g_assert(n == sz - i);
96 2278a69e Michael Tokarev
97 2278a69e Michael Tokarev
         /* now compare resulting buffers */
98 2278a69e Michael Tokarev
         g_assert(memcmp(ibuf, obuf, sz) == 0);
99 2278a69e Michael Tokarev
100 2278a69e Michael Tokarev
         /* test just one char */
101 2278a69e Michael Tokarev
         n = iov_to_buf(iov, niov, i, obuf + i, 1);
102 2278a69e Michael Tokarev
         g_assert(n == (i < sz));
103 2278a69e Michael Tokarev
         if (n) {
104 2278a69e Michael Tokarev
             g_assert(obuf[i] == (i & 255));
105 2278a69e Michael Tokarev
         }
106 2278a69e Michael Tokarev
107 2278a69e Michael Tokarev
         for (j = i; j <= sz; ++j) {
108 2278a69e Michael Tokarev
             /* now test num of bytes cap up to byte no. j,
109 2278a69e Michael Tokarev
              * with j in [i..sz]. */
110 2278a69e Michael Tokarev
111 2278a69e Michael Tokarev
             /* clear iovec */
112 2278a69e Michael Tokarev
             n = iov_memset(iov, niov, 0, 0xff, -1);
113 2278a69e Michael Tokarev
             g_assert(n == sz);
114 2278a69e Michael Tokarev
115 2278a69e Michael Tokarev
             /* copy bytes [i..j) from ibuf to iovec */
116 2278a69e Michael Tokarev
             n = iov_from_buf(iov, niov, i, ibuf + i, j - i);
117 2278a69e Michael Tokarev
             g_assert(n == j - i);
118 2278a69e Michael Tokarev
119 2278a69e Michael Tokarev
             /* clear part of obuf */
120 2278a69e Michael Tokarev
             memset(obuf + i, 0, j - i);
121 2278a69e Michael Tokarev
122 2278a69e Michael Tokarev
             /* copy bytes [i..j) from iovec to obuf */
123 2278a69e Michael Tokarev
             n = iov_to_buf(iov, niov, i, obuf + i, j - i);
124 2278a69e Michael Tokarev
             g_assert(n == j - i);
125 2278a69e Michael Tokarev
126 2278a69e Michael Tokarev
             /* verify result */
127 2278a69e Michael Tokarev
             g_assert(memcmp(ibuf, obuf, sz) == 0);
128 2278a69e Michael Tokarev
129 2278a69e Michael Tokarev
             /* now actually check if the iovec contains the right data */
130 2278a69e Michael Tokarev
             test_iov_bytes(iov, niov, i, j - i);
131 2278a69e Michael Tokarev
         }
132 2278a69e Michael Tokarev
    }
133 2278a69e Michael Tokarev
    g_assert(!memcmp(ibuf-4, "aaaa", 4) && !memcmp(ibuf+sz, "bbbb", 4));
134 2278a69e Michael Tokarev
    g_free(ibuf-4);
135 2278a69e Michael Tokarev
    g_assert(!memcmp(obuf-4, "xxxx", 4) && !memcmp(obuf+sz, "yyyy", 4));
136 2278a69e Michael Tokarev
    g_free(obuf-4);
137 2278a69e Michael Tokarev
    iov_free(iov, niov);
138 2278a69e Michael Tokarev
}
139 2278a69e Michael Tokarev
140 2278a69e Michael Tokarev
static void test_to_from_buf(void)
141 2278a69e Michael Tokarev
{
142 2278a69e Michael Tokarev
    int x;
143 2278a69e Michael Tokarev
    for (x = 0; x < 4; ++x) {
144 2278a69e Michael Tokarev
        test_to_from_buf_1();
145 2278a69e Michael Tokarev
    }
146 2278a69e Michael Tokarev
}
147 2278a69e Michael Tokarev
148 25e5e4c7 Michael Tokarev
static void test_io(void)
149 25e5e4c7 Michael Tokarev
{
150 25e5e4c7 Michael Tokarev
#ifndef _WIN32
151 25e5e4c7 Michael Tokarev
/* socketpair(PF_UNIX) which does not exist on windows */
152 25e5e4c7 Michael Tokarev
153 25e5e4c7 Michael Tokarev
    int sv[2];
154 25e5e4c7 Michael Tokarev
    int r;
155 25e5e4c7 Michael Tokarev
    unsigned i, j, k, s, t;
156 25e5e4c7 Michael Tokarev
    fd_set fds;
157 25e5e4c7 Michael Tokarev
    unsigned niov;
158 25e5e4c7 Michael Tokarev
    struct iovec *iov, *siov;
159 25e5e4c7 Michael Tokarev
    unsigned char *buf;
160 25e5e4c7 Michael Tokarev
    size_t sz;
161 25e5e4c7 Michael Tokarev
162 25e5e4c7 Michael Tokarev
    iov_random(&iov, &niov);
163 25e5e4c7 Michael Tokarev
    sz = iov_size(iov, niov);
164 25e5e4c7 Michael Tokarev
    buf = g_malloc(sz);
165 25e5e4c7 Michael Tokarev
    for (i = 0; i < sz; ++i) {
166 25e5e4c7 Michael Tokarev
        buf[i] = i & 255;
167 25e5e4c7 Michael Tokarev
    }
168 25e5e4c7 Michael Tokarev
    iov_from_buf(iov, niov, 0, buf, sz);
169 25e5e4c7 Michael Tokarev
170 25e5e4c7 Michael Tokarev
    siov = g_malloc(sizeof(*iov) * niov);
171 25e5e4c7 Michael Tokarev
    memcpy(siov, iov, sizeof(*iov) * niov);
172 25e5e4c7 Michael Tokarev
173 25e5e4c7 Michael Tokarev
    if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) < 0) {
174 25e5e4c7 Michael Tokarev
       perror("socketpair");
175 25e5e4c7 Michael Tokarev
       exit(1);
176 25e5e4c7 Michael Tokarev
    }
177 25e5e4c7 Michael Tokarev
178 25e5e4c7 Michael Tokarev
    FD_ZERO(&fds);
179 25e5e4c7 Michael Tokarev
180 25e5e4c7 Michael Tokarev
    t = 0;
181 25e5e4c7 Michael Tokarev
    if (fork() == 0) {
182 25e5e4c7 Michael Tokarev
       /* writer */
183 25e5e4c7 Michael Tokarev
184 25e5e4c7 Michael Tokarev
       close(sv[0]);
185 25e5e4c7 Michael Tokarev
       FD_SET(sv[1], &fds);
186 25e5e4c7 Michael Tokarev
       fcntl(sv[1], F_SETFL, O_RDWR|O_NONBLOCK);
187 25e5e4c7 Michael Tokarev
       r = g_test_rand_int_range(sz / 2, sz);
188 25e5e4c7 Michael Tokarev
       setsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &r, sizeof(r));
189 25e5e4c7 Michael Tokarev
190 25e5e4c7 Michael Tokarev
       for (i = 0; i <= sz; ++i) {
191 25e5e4c7 Michael Tokarev
           for (j = i; j <= sz; ++j) {
192 25e5e4c7 Michael Tokarev
               k = i;
193 25e5e4c7 Michael Tokarev
               do {
194 25e5e4c7 Michael Tokarev
                   s = g_test_rand_int_range(0, j - k + 1);
195 25e5e4c7 Michael Tokarev
                   r = iov_send(sv[1], iov, niov, k, s);
196 25e5e4c7 Michael Tokarev
                   g_assert(memcmp(iov, siov, sizeof(*iov)*niov) == 0);
197 25e5e4c7 Michael Tokarev
                   if (r >= 0) {
198 25e5e4c7 Michael Tokarev
                       k += r;
199 25e5e4c7 Michael Tokarev
                       t += r;
200 25e5e4c7 Michael Tokarev
                       usleep(g_test_rand_int_range(0, 30));
201 25e5e4c7 Michael Tokarev
                   } else if (errno == EAGAIN) {
202 25e5e4c7 Michael Tokarev
                       select(sv[1]+1, NULL, &fds, NULL, NULL);
203 25e5e4c7 Michael Tokarev
                       continue;
204 25e5e4c7 Michael Tokarev
                   } else {
205 25e5e4c7 Michael Tokarev
                       perror("send");
206 25e5e4c7 Michael Tokarev
                       exit(1);
207 25e5e4c7 Michael Tokarev
                   }
208 25e5e4c7 Michael Tokarev
               } while(k < j);
209 25e5e4c7 Michael Tokarev
           }
210 25e5e4c7 Michael Tokarev
       }
211 25e5e4c7 Michael Tokarev
       exit(0);
212 25e5e4c7 Michael Tokarev
213 25e5e4c7 Michael Tokarev
    } else {
214 25e5e4c7 Michael Tokarev
       /* reader & verifier */
215 25e5e4c7 Michael Tokarev
216 25e5e4c7 Michael Tokarev
       close(sv[1]);
217 25e5e4c7 Michael Tokarev
       FD_SET(sv[0], &fds);
218 25e5e4c7 Michael Tokarev
       fcntl(sv[0], F_SETFL, O_RDWR|O_NONBLOCK);
219 25e5e4c7 Michael Tokarev
       r = g_test_rand_int_range(sz / 2, sz);
220 25e5e4c7 Michael Tokarev
       setsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &r, sizeof(r));
221 25e5e4c7 Michael Tokarev
       usleep(500000);
222 25e5e4c7 Michael Tokarev
223 25e5e4c7 Michael Tokarev
       for (i = 0; i <= sz; ++i) {
224 25e5e4c7 Michael Tokarev
           for (j = i; j <= sz; ++j) {
225 25e5e4c7 Michael Tokarev
               k = i;
226 25e5e4c7 Michael Tokarev
               iov_memset(iov, niov, 0, 0xff, -1);
227 25e5e4c7 Michael Tokarev
               do {
228 25e5e4c7 Michael Tokarev
                   s = g_test_rand_int_range(0, j - k + 1);
229 25e5e4c7 Michael Tokarev
                   r = iov_recv(sv[0], iov, niov, k, s);
230 25e5e4c7 Michael Tokarev
                   g_assert(memcmp(iov, siov, sizeof(*iov)*niov) == 0);
231 25e5e4c7 Michael Tokarev
                   if (r > 0) {
232 25e5e4c7 Michael Tokarev
                       k += r;
233 25e5e4c7 Michael Tokarev
                       t += r;
234 25e5e4c7 Michael Tokarev
                   } else if (!r) {
235 25e5e4c7 Michael Tokarev
                       if (s) {
236 25e5e4c7 Michael Tokarev
                           break;
237 25e5e4c7 Michael Tokarev
                       }
238 25e5e4c7 Michael Tokarev
                   } else if (errno == EAGAIN) {
239 25e5e4c7 Michael Tokarev
                       select(sv[0]+1, &fds, NULL, NULL, NULL);
240 25e5e4c7 Michael Tokarev
                       continue;
241 25e5e4c7 Michael Tokarev
                   } else {
242 25e5e4c7 Michael Tokarev
                       perror("recv");
243 25e5e4c7 Michael Tokarev
                       exit(1);
244 25e5e4c7 Michael Tokarev
                   }
245 25e5e4c7 Michael Tokarev
               } while(k < j);
246 25e5e4c7 Michael Tokarev
               test_iov_bytes(iov, niov, i, j - i);
247 25e5e4c7 Michael Tokarev
           }
248 25e5e4c7 Michael Tokarev
        }
249 25e5e4c7 Michael Tokarev
     }
250 25e5e4c7 Michael Tokarev
#endif
251 25e5e4c7 Michael Tokarev
}
252 25e5e4c7 Michael Tokarev
253 8962e44f Stefan Hajnoczi
static void test_discard_front(void)
254 8962e44f Stefan Hajnoczi
{
255 8962e44f Stefan Hajnoczi
    struct iovec *iov;
256 8962e44f Stefan Hajnoczi
    struct iovec *iov_tmp;
257 8962e44f Stefan Hajnoczi
    unsigned int iov_cnt;
258 8962e44f Stefan Hajnoczi
    unsigned int iov_cnt_tmp;
259 8962e44f Stefan Hajnoczi
    void *old_base;
260 8962e44f Stefan Hajnoczi
    size_t size;
261 8962e44f Stefan Hajnoczi
    size_t ret;
262 8962e44f Stefan Hajnoczi
263 8962e44f Stefan Hajnoczi
    /* Discard zero bytes */
264 8962e44f Stefan Hajnoczi
    iov_random(&iov, &iov_cnt);
265 8962e44f Stefan Hajnoczi
    iov_tmp = iov;
266 8962e44f Stefan Hajnoczi
    iov_cnt_tmp = iov_cnt;
267 8962e44f Stefan Hajnoczi
    ret = iov_discard_front(&iov_tmp, &iov_cnt_tmp, 0);
268 8962e44f Stefan Hajnoczi
    g_assert(ret == 0);
269 8962e44f Stefan Hajnoczi
    g_assert(iov_tmp == iov);
270 8962e44f Stefan Hajnoczi
    g_assert(iov_cnt_tmp == iov_cnt);
271 8962e44f Stefan Hajnoczi
    iov_free(iov, iov_cnt);
272 8962e44f Stefan Hajnoczi
273 8962e44f Stefan Hajnoczi
    /* Discard more bytes than vector size */
274 8962e44f Stefan Hajnoczi
    iov_random(&iov, &iov_cnt);
275 8962e44f Stefan Hajnoczi
    iov_tmp = iov;
276 8962e44f Stefan Hajnoczi
    iov_cnt_tmp = iov_cnt;
277 8962e44f Stefan Hajnoczi
    size = iov_size(iov, iov_cnt);
278 8962e44f Stefan Hajnoczi
    ret = iov_discard_front(&iov_tmp, &iov_cnt_tmp, size + 1);
279 8962e44f Stefan Hajnoczi
    g_assert(ret == size);
280 8962e44f Stefan Hajnoczi
    g_assert(iov_cnt_tmp == 0);
281 8962e44f Stefan Hajnoczi
    iov_free(iov, iov_cnt);
282 8962e44f Stefan Hajnoczi
283 8962e44f Stefan Hajnoczi
    /* Discard entire vector */
284 8962e44f Stefan Hajnoczi
    iov_random(&iov, &iov_cnt);
285 8962e44f Stefan Hajnoczi
    iov_tmp = iov;
286 8962e44f Stefan Hajnoczi
    iov_cnt_tmp = iov_cnt;
287 8962e44f Stefan Hajnoczi
    size = iov_size(iov, iov_cnt);
288 8962e44f Stefan Hajnoczi
    ret = iov_discard_front(&iov_tmp, &iov_cnt_tmp, size);
289 8962e44f Stefan Hajnoczi
    g_assert(ret == size);
290 8962e44f Stefan Hajnoczi
    g_assert(iov_cnt_tmp == 0);
291 8962e44f Stefan Hajnoczi
    iov_free(iov, iov_cnt);
292 8962e44f Stefan Hajnoczi
293 8962e44f Stefan Hajnoczi
    /* Discard within first element */
294 8962e44f Stefan Hajnoczi
    iov_random(&iov, &iov_cnt);
295 8962e44f Stefan Hajnoczi
    iov_tmp = iov;
296 8962e44f Stefan Hajnoczi
    iov_cnt_tmp = iov_cnt;
297 8962e44f Stefan Hajnoczi
    old_base = iov->iov_base;
298 8962e44f Stefan Hajnoczi
    size = g_test_rand_int_range(1, iov->iov_len);
299 8962e44f Stefan Hajnoczi
    ret = iov_discard_front(&iov_tmp, &iov_cnt_tmp, size);
300 8962e44f Stefan Hajnoczi
    g_assert(ret == size);
301 8962e44f Stefan Hajnoczi
    g_assert(iov_tmp == iov);
302 8962e44f Stefan Hajnoczi
    g_assert(iov_cnt_tmp == iov_cnt);
303 8962e44f Stefan Hajnoczi
    g_assert(iov_tmp->iov_base == old_base + size);
304 8962e44f Stefan Hajnoczi
    iov_tmp->iov_base = old_base; /* undo before g_free() */
305 8962e44f Stefan Hajnoczi
    iov_free(iov, iov_cnt);
306 8962e44f Stefan Hajnoczi
307 8962e44f Stefan Hajnoczi
    /* Discard entire first element */
308 8962e44f Stefan Hajnoczi
    iov_random(&iov, &iov_cnt);
309 8962e44f Stefan Hajnoczi
    iov_tmp = iov;
310 8962e44f Stefan Hajnoczi
    iov_cnt_tmp = iov_cnt;
311 8962e44f Stefan Hajnoczi
    ret = iov_discard_front(&iov_tmp, &iov_cnt_tmp, iov->iov_len);
312 8962e44f Stefan Hajnoczi
    g_assert(ret == iov->iov_len);
313 8962e44f Stefan Hajnoczi
    g_assert(iov_tmp == iov + 1);
314 8962e44f Stefan Hajnoczi
    g_assert(iov_cnt_tmp == iov_cnt - 1);
315 8962e44f Stefan Hajnoczi
    iov_free(iov, iov_cnt);
316 8962e44f Stefan Hajnoczi
317 8962e44f Stefan Hajnoczi
    /* Discard within second element */
318 8962e44f Stefan Hajnoczi
    iov_random(&iov, &iov_cnt);
319 8962e44f Stefan Hajnoczi
    iov_tmp = iov;
320 8962e44f Stefan Hajnoczi
    iov_cnt_tmp = iov_cnt;
321 8962e44f Stefan Hajnoczi
    old_base = iov[1].iov_base;
322 8962e44f Stefan Hajnoczi
    size = iov->iov_len + g_test_rand_int_range(1, iov[1].iov_len);
323 8962e44f Stefan Hajnoczi
    ret = iov_discard_front(&iov_tmp, &iov_cnt_tmp, size);
324 8962e44f Stefan Hajnoczi
    g_assert(ret == size);
325 8962e44f Stefan Hajnoczi
    g_assert(iov_tmp == iov + 1);
326 8962e44f Stefan Hajnoczi
    g_assert(iov_cnt_tmp == iov_cnt - 1);
327 8962e44f Stefan Hajnoczi
    g_assert(iov_tmp->iov_base == old_base + (size - iov->iov_len));
328 8962e44f Stefan Hajnoczi
    iov_tmp->iov_base = old_base; /* undo before g_free() */
329 8962e44f Stefan Hajnoczi
    iov_free(iov, iov_cnt);
330 8962e44f Stefan Hajnoczi
}
331 8962e44f Stefan Hajnoczi
332 8962e44f Stefan Hajnoczi
static void test_discard_back(void)
333 8962e44f Stefan Hajnoczi
{
334 8962e44f Stefan Hajnoczi
    struct iovec *iov;
335 8962e44f Stefan Hajnoczi
    unsigned int iov_cnt;
336 8962e44f Stefan Hajnoczi
    unsigned int iov_cnt_tmp;
337 8962e44f Stefan Hajnoczi
    void *old_base;
338 8962e44f Stefan Hajnoczi
    size_t size;
339 8962e44f Stefan Hajnoczi
    size_t ret;
340 8962e44f Stefan Hajnoczi
341 8962e44f Stefan Hajnoczi
    /* Discard zero bytes */
342 8962e44f Stefan Hajnoczi
    iov_random(&iov, &iov_cnt);
343 8962e44f Stefan Hajnoczi
    iov_cnt_tmp = iov_cnt;
344 8962e44f Stefan Hajnoczi
    ret = iov_discard_back(iov, &iov_cnt_tmp, 0);
345 8962e44f Stefan Hajnoczi
    g_assert(ret == 0);
346 8962e44f Stefan Hajnoczi
    g_assert(iov_cnt_tmp == iov_cnt);
347 8962e44f Stefan Hajnoczi
    iov_free(iov, iov_cnt);
348 8962e44f Stefan Hajnoczi
349 8962e44f Stefan Hajnoczi
    /* Discard more bytes than vector size */
350 8962e44f Stefan Hajnoczi
    iov_random(&iov, &iov_cnt);
351 8962e44f Stefan Hajnoczi
    iov_cnt_tmp = iov_cnt;
352 8962e44f Stefan Hajnoczi
    size = iov_size(iov, iov_cnt);
353 8962e44f Stefan Hajnoczi
    ret = iov_discard_back(iov, &iov_cnt_tmp, size + 1);
354 8962e44f Stefan Hajnoczi
    g_assert(ret == size);
355 8962e44f Stefan Hajnoczi
    g_assert(iov_cnt_tmp == 0);
356 8962e44f Stefan Hajnoczi
    iov_free(iov, iov_cnt);
357 8962e44f Stefan Hajnoczi
358 8962e44f Stefan Hajnoczi
    /* Discard entire vector */
359 8962e44f Stefan Hajnoczi
    iov_random(&iov, &iov_cnt);
360 8962e44f Stefan Hajnoczi
    iov_cnt_tmp = iov_cnt;
361 8962e44f Stefan Hajnoczi
    size = iov_size(iov, iov_cnt);
362 8962e44f Stefan Hajnoczi
    ret = iov_discard_back(iov, &iov_cnt_tmp, size);
363 8962e44f Stefan Hajnoczi
    g_assert(ret == size);
364 8962e44f Stefan Hajnoczi
    g_assert(iov_cnt_tmp == 0);
365 8962e44f Stefan Hajnoczi
    iov_free(iov, iov_cnt);
366 8962e44f Stefan Hajnoczi
367 8962e44f Stefan Hajnoczi
    /* Discard within last element */
368 8962e44f Stefan Hajnoczi
    iov_random(&iov, &iov_cnt);
369 8962e44f Stefan Hajnoczi
    iov_cnt_tmp = iov_cnt;
370 8962e44f Stefan Hajnoczi
    old_base = iov[iov_cnt - 1].iov_base;
371 8962e44f Stefan Hajnoczi
    size = g_test_rand_int_range(1, iov[iov_cnt - 1].iov_len);
372 8962e44f Stefan Hajnoczi
    ret = iov_discard_back(iov, &iov_cnt_tmp, size);
373 8962e44f Stefan Hajnoczi
    g_assert(ret == size);
374 8962e44f Stefan Hajnoczi
    g_assert(iov_cnt_tmp == iov_cnt);
375 8962e44f Stefan Hajnoczi
    g_assert(iov[iov_cnt - 1].iov_base == old_base);
376 8962e44f Stefan Hajnoczi
    iov_free(iov, iov_cnt);
377 8962e44f Stefan Hajnoczi
378 8962e44f Stefan Hajnoczi
    /* Discard entire last element */
379 8962e44f Stefan Hajnoczi
    iov_random(&iov, &iov_cnt);
380 8962e44f Stefan Hajnoczi
    iov_cnt_tmp = iov_cnt;
381 8962e44f Stefan Hajnoczi
    old_base = iov[iov_cnt - 1].iov_base;
382 8962e44f Stefan Hajnoczi
    size = iov[iov_cnt - 1].iov_len;
383 8962e44f Stefan Hajnoczi
    ret = iov_discard_back(iov, &iov_cnt_tmp, size);
384 8962e44f Stefan Hajnoczi
    g_assert(ret == size);
385 8962e44f Stefan Hajnoczi
    g_assert(iov_cnt_tmp == iov_cnt - 1);
386 8962e44f Stefan Hajnoczi
    iov_free(iov, iov_cnt);
387 8962e44f Stefan Hajnoczi
388 8962e44f Stefan Hajnoczi
    /* Discard within second-to-last element */
389 8962e44f Stefan Hajnoczi
    iov_random(&iov, &iov_cnt);
390 8962e44f Stefan Hajnoczi
    iov_cnt_tmp = iov_cnt;
391 8962e44f Stefan Hajnoczi
    old_base = iov[iov_cnt - 2].iov_base;
392 8962e44f Stefan Hajnoczi
    size = iov[iov_cnt - 1].iov_len +
393 8962e44f Stefan Hajnoczi
           g_test_rand_int_range(1, iov[iov_cnt - 2].iov_len);
394 8962e44f Stefan Hajnoczi
    ret = iov_discard_back(iov, &iov_cnt_tmp, size);
395 8962e44f Stefan Hajnoczi
    g_assert(ret == size);
396 8962e44f Stefan Hajnoczi
    g_assert(iov_cnt_tmp == iov_cnt - 1);
397 8962e44f Stefan Hajnoczi
    g_assert(iov[iov_cnt - 2].iov_base == old_base);
398 8962e44f Stefan Hajnoczi
    iov_free(iov, iov_cnt);
399 8962e44f Stefan Hajnoczi
}
400 8962e44f Stefan Hajnoczi
401 2278a69e Michael Tokarev
int main(int argc, char **argv)
402 2278a69e Michael Tokarev
{
403 2278a69e Michael Tokarev
    g_test_init(&argc, &argv, NULL);
404 2278a69e Michael Tokarev
    g_test_rand_int();
405 2278a69e Michael Tokarev
    g_test_add_func("/basic/iov/from-to-buf", test_to_from_buf);
406 25e5e4c7 Michael Tokarev
    g_test_add_func("/basic/iov/io", test_io);
407 8962e44f Stefan Hajnoczi
    g_test_add_func("/basic/iov/discard-front", test_discard_front);
408 8962e44f Stefan Hajnoczi
    g_test_add_func("/basic/iov/discard-back", test_discard_back);
409 2278a69e Michael Tokarev
    return g_test_run();
410 2278a69e Michael Tokarev
}