]> git.proxmox.com Git - qemu.git/blob - tests/test-iov.c
rewrite iov_* functions
[qemu.git] / tests / test-iov.c
1 #include <glib.h>
2 #include "qemu-common.h"
3 #include "iov.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 void test_iov_bytes(struct iovec *iov, unsigned niov,
29 size_t offset, size_t bytes)
30 {
31 unsigned i;
32 size_t j, o;
33 unsigned char *b;
34 o = 0;
35
36 /* we walk over all elements, */
37 for (i = 0; i < niov; ++i) {
38 b = iov[i].iov_base;
39 /* over each char of each element, */
40 for (j = 0; j < iov[i].iov_len; ++j) {
41 /* counting each of them and
42 * verifying that the ones within [offset,offset+bytes)
43 * range are equal to the position number (o) */
44 if (o >= offset && o < offset + bytes) {
45 g_assert(b[j] == (o & 255));
46 } else {
47 g_assert(b[j] == 0xff);
48 }
49 ++o;
50 }
51 }
52 }
53
54 static void test_to_from_buf_1(void)
55 {
56 unsigned niov;
57 struct iovec *iov;
58 size_t sz;
59 unsigned char *ibuf, *obuf;
60 unsigned i, j, n;
61
62 iov_random(&iov, &niov);
63
64 sz = iov_size(iov, niov);
65
66 ibuf = g_malloc(sz + 8) + 4;
67 memcpy(ibuf-4, "aaaa", 4); memcpy(ibuf + sz, "bbbb", 4);
68 obuf = g_malloc(sz + 8) + 4;
69 memcpy(obuf-4, "xxxx", 4); memcpy(obuf + sz, "yyyy", 4);
70
71 /* fill in ibuf with 0123456... */
72 for (i = 0; i < sz; ++i) {
73 ibuf[i] = i & 255;
74 }
75
76 for (i = 0; i <= sz; ++i) {
77
78 /* Test from/to buf for offset(i) in [0..sz] up to the end of buffer.
79 * For last iteration with offset == sz, the procedure should
80 * skip whole vector and process exactly 0 bytes */
81
82 /* first set bytes [i..sz) to some "random" value */
83 n = iov_memset(iov, niov, 0, 0xff, -1);
84 g_assert(n == sz);
85
86 /* next copy bytes [i..sz) from ibuf to iovec */
87 n = iov_from_buf(iov, niov, i, ibuf + i, -1);
88 g_assert(n == sz - i);
89
90 /* clear part of obuf */
91 memset(obuf + i, 0, sz - i);
92 /* and set this part of obuf to values from iovec */
93 n = iov_to_buf(iov, niov, i, obuf + i, -1);
94 g_assert(n == sz - i);
95
96 /* now compare resulting buffers */
97 g_assert(memcmp(ibuf, obuf, sz) == 0);
98
99 /* test just one char */
100 n = iov_to_buf(iov, niov, i, obuf + i, 1);
101 g_assert(n == (i < sz));
102 if (n) {
103 g_assert(obuf[i] == (i & 255));
104 }
105
106 for (j = i; j <= sz; ++j) {
107 /* now test num of bytes cap up to byte no. j,
108 * with j in [i..sz]. */
109
110 /* clear iovec */
111 n = iov_memset(iov, niov, 0, 0xff, -1);
112 g_assert(n == sz);
113
114 /* copy bytes [i..j) from ibuf to iovec */
115 n = iov_from_buf(iov, niov, i, ibuf + i, j - i);
116 g_assert(n == j - i);
117
118 /* clear part of obuf */
119 memset(obuf + i, 0, j - i);
120
121 /* copy bytes [i..j) from iovec to obuf */
122 n = iov_to_buf(iov, niov, i, obuf + i, j - i);
123 g_assert(n == j - i);
124
125 /* verify result */
126 g_assert(memcmp(ibuf, obuf, sz) == 0);
127
128 /* now actually check if the iovec contains the right data */
129 test_iov_bytes(iov, niov, i, j - i);
130 }
131 }
132 g_assert(!memcmp(ibuf-4, "aaaa", 4) && !memcmp(ibuf+sz, "bbbb", 4));
133 g_free(ibuf-4);
134 g_assert(!memcmp(obuf-4, "xxxx", 4) && !memcmp(obuf+sz, "yyyy", 4));
135 g_free(obuf-4);
136 iov_free(iov, niov);
137 }
138
139 static void test_to_from_buf(void)
140 {
141 int x;
142 for (x = 0; x < 4; ++x) {
143 test_to_from_buf_1();
144 }
145 }
146
147 int main(int argc, char **argv)
148 {
149 g_test_init(&argc, &argv, NULL);
150 g_test_rand_int();
151 g_test_add_func("/basic/iov/from-to-buf", test_to_from_buf);
152 return g_test_run();
153 }