~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to tests/test-iov.c

  • Committer: Phil Dennis-Jordan
  • Author(s): Michael Tokarev
  • Date: 2017-05-23 06:58:03 UTC
  • Revision ID: phil@philjordan.eu-20170523065803-3subwvf3y8kzkjry
Tags: upstream-2.8+dfsg
ImportĀ upstreamĀ versionĀ 2.8+dfsg

Show diffs side-by-side

added added

removed removed

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