Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2019 Intel Corporation.
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include "spdk/stdinc.h"
7 : :
8 : : #include "spdk_internal/cunit.h"
9 : :
10 : : #include "util/iov.c"
11 : :
12 : : static int
13 : 48 : _check_val(void *buf, size_t len, uint8_t val)
14 : : {
15 : : size_t i;
16 : 48 : uint8_t *data = buf;
17 : :
18 [ + + ]: 2352 : for (i = 0; i < len; i++) {
19 [ - + ]: 2304 : if (data[i] != val) {
20 : 0 : return -1;
21 : : }
22 : : }
23 : :
24 : 48 : return 0;
25 : : }
26 : :
27 : : static void
28 : 3 : test_single_iov(void)
29 : : {
30 : 3 : struct iovec siov[1];
31 : 3 : struct iovec diov[1];
32 : 3 : uint8_t sdata[64];
33 : 3 : uint8_t ddata[64];
34 : : ssize_t rc;
35 : :
36 : : /* Simplest cases- 1 element in each iovec. */
37 : :
38 : : /* Same size. */
39 [ - + ]: 3 : memset(sdata, 1, sizeof(sdata));
40 [ - + ]: 3 : memset(ddata, 0, sizeof(ddata));
41 : 3 : siov[0].iov_base = sdata;
42 : 3 : siov[0].iov_len = sizeof(sdata);
43 : 3 : diov[0].iov_base = ddata;
44 : 3 : diov[0].iov_len = sizeof(ddata);
45 : :
46 : 3 : rc = spdk_iovcpy(siov, 1, diov, 1);
47 : 3 : CU_ASSERT(rc == sizeof(sdata));
48 : 3 : CU_ASSERT(_check_val(ddata, 64, 1) == 0);
49 : :
50 : : /* Source smaller than dest */
51 [ - + ]: 3 : memset(sdata, 1, sizeof(sdata));
52 [ - + ]: 3 : memset(ddata, 0, sizeof(ddata));
53 : 3 : siov[0].iov_base = sdata;
54 : 3 : siov[0].iov_len = 48;
55 : 3 : diov[0].iov_base = ddata;
56 : 3 : diov[0].iov_len = sizeof(ddata);
57 : :
58 : 3 : rc = spdk_iovcpy(siov, 1, diov, 1);
59 : 3 : CU_ASSERT(rc == 48);
60 : 3 : CU_ASSERT(_check_val(ddata, 48, 1) == 0);
61 : 3 : CU_ASSERT(_check_val(&ddata[48], 16, 0) == 0);
62 : :
63 : : /* Dest smaller than source */
64 [ - + ]: 3 : memset(sdata, 1, sizeof(sdata));
65 [ - + ]: 3 : memset(ddata, 0, sizeof(ddata));
66 : 3 : siov[0].iov_base = sdata;
67 : 3 : siov[0].iov_len = sizeof(sdata);
68 : 3 : diov[0].iov_base = ddata;
69 : 3 : diov[0].iov_len = 48;
70 : :
71 : 3 : rc = spdk_iovcpy(siov, 1, diov, 1);
72 : 3 : CU_ASSERT(rc == 48);
73 : 3 : CU_ASSERT(_check_val(ddata, 48, 1) == 0);
74 : 3 : CU_ASSERT(_check_val(&ddata[48], 16, 0) == 0);
75 : 3 : }
76 : :
77 : : static void
78 : 3 : test_simple_iov(void)
79 : : {
80 : 3 : struct iovec siov[4];
81 : 3 : struct iovec diov[4];
82 : 3 : uint8_t sdata[64];
83 : 3 : uint8_t ddata[64];
84 : : ssize_t rc;
85 : : int i;
86 : :
87 : : /* Simple cases with 4 iov elements */
88 : :
89 : : /* Same size. */
90 [ - + ]: 3 : memset(sdata, 1, sizeof(sdata));
91 [ - + ]: 3 : memset(ddata, 0, sizeof(ddata));
92 [ + + ]: 15 : for (i = 0; i < 4; i++) {
93 : 12 : siov[i].iov_base = sdata + (16 * i);
94 : 12 : siov[i].iov_len = 16;
95 : 12 : diov[i].iov_base = ddata + (16 * i);
96 : 12 : diov[i].iov_len = 16;
97 : : }
98 : :
99 : 3 : rc = spdk_iovcpy(siov, 4, diov, 4);
100 : 3 : CU_ASSERT(rc == sizeof(sdata));
101 : 3 : CU_ASSERT(_check_val(ddata, 64, 1) == 0);
102 : :
103 : : /* Source smaller than dest */
104 [ - + ]: 3 : memset(sdata, 1, sizeof(sdata));
105 [ - + ]: 3 : memset(ddata, 0, sizeof(ddata));
106 [ + + ]: 15 : for (i = 0; i < 4; i++) {
107 : 12 : siov[i].iov_base = sdata + (8 * i);
108 : 12 : siov[i].iov_len = 8;
109 : 12 : diov[i].iov_base = ddata + (16 * i);
110 : 12 : diov[i].iov_len = 16;
111 : : }
112 : :
113 : 3 : rc = spdk_iovcpy(siov, 4, diov, 4);
114 : 3 : CU_ASSERT(rc == 32);
115 : 3 : CU_ASSERT(_check_val(ddata, 32, 1) == 0);
116 : 3 : CU_ASSERT(_check_val(&ddata[32], 32, 0) == 0);
117 : :
118 : : /* Dest smaller than source */
119 [ - + ]: 3 : memset(sdata, 1, sizeof(sdata));
120 [ - + ]: 3 : memset(ddata, 0, sizeof(ddata));
121 [ + + ]: 15 : for (i = 0; i < 4; i++) {
122 : 12 : siov[i].iov_base = sdata + (16 * i);
123 : 12 : siov[i].iov_len = 16;
124 : 12 : diov[i].iov_base = ddata + (8 * i);
125 : 12 : diov[i].iov_len = 8;
126 : : }
127 : :
128 : 3 : rc = spdk_iovcpy(siov, 4, diov, 4);
129 : 3 : CU_ASSERT(rc == 32);
130 : 3 : CU_ASSERT(_check_val(ddata, 32, 1) == 0);
131 : 3 : CU_ASSERT(_check_val(&ddata[32], 32, 0) == 0);
132 : 3 : }
133 : :
134 : : static void
135 : 3 : test_complex_iov(void)
136 : : {
137 : 3 : struct iovec siov[4];
138 : 3 : struct iovec diov[4];
139 : 3 : uint8_t sdata[64];
140 : 3 : uint8_t ddata[64];
141 : : ssize_t rc;
142 : : int i;
143 : :
144 : : /* More source elements */
145 [ - + ]: 3 : memset(sdata, 1, sizeof(sdata));
146 [ - + ]: 3 : memset(ddata, 0, sizeof(ddata));
147 [ + + ]: 15 : for (i = 0; i < 4; i++) {
148 : 12 : siov[i].iov_base = sdata + (16 * i);
149 : 12 : siov[i].iov_len = 16;
150 : : }
151 : 3 : diov[0].iov_base = ddata;
152 : 3 : diov[0].iov_len = sizeof(ddata);
153 : :
154 : 3 : rc = spdk_iovcpy(siov, 4, diov, 1);
155 : 3 : CU_ASSERT(rc == sizeof(sdata));
156 : 3 : CU_ASSERT(_check_val(ddata, 64, 1) == 0);
157 : :
158 : : /* More dest elements */
159 [ - + ]: 3 : memset(sdata, 1, sizeof(sdata));
160 [ - + ]: 3 : memset(ddata, 0, sizeof(ddata));
161 [ + + ]: 15 : for (i = 0; i < 4; i++) {
162 : 12 : diov[i].iov_base = ddata + (16 * i);
163 : 12 : diov[i].iov_len = 16;
164 : : }
165 : 3 : siov[0].iov_base = sdata;
166 : 3 : siov[0].iov_len = sizeof(sdata);
167 : :
168 : 3 : rc = spdk_iovcpy(siov, 1, diov, 4);
169 : 3 : CU_ASSERT(rc == sizeof(sdata));
170 : 3 : CU_ASSERT(_check_val(ddata, 64, 1) == 0);
171 : :
172 : : /* Build one by hand that's really terrible */
173 [ - + ]: 3 : memset(sdata, 1, sizeof(sdata));
174 [ - + ]: 3 : memset(ddata, 0, sizeof(ddata));
175 : 3 : siov[0].iov_base = sdata;
176 : 3 : siov[0].iov_len = 1;
177 : 3 : siov[1].iov_base = siov[0].iov_base + siov[0].iov_len;
178 : 3 : siov[1].iov_len = 13;
179 : 3 : siov[2].iov_base = siov[1].iov_base + siov[1].iov_len;
180 : 3 : siov[2].iov_len = 6;
181 : 3 : siov[3].iov_base = siov[2].iov_base + siov[2].iov_len;
182 : 3 : siov[3].iov_len = 44;
183 : :
184 : 3 : diov[0].iov_base = ddata;
185 : 3 : diov[0].iov_len = 31;
186 : 3 : diov[1].iov_base = diov[0].iov_base + diov[0].iov_len;
187 : 3 : diov[1].iov_len = 9;
188 : 3 : diov[2].iov_base = diov[1].iov_base + diov[1].iov_len;
189 : 3 : diov[2].iov_len = 1;
190 : 3 : diov[3].iov_base = diov[2].iov_base + diov[2].iov_len;
191 : 3 : diov[3].iov_len = 23;
192 : :
193 : 3 : rc = spdk_iovcpy(siov, 4, diov, 4);
194 : 3 : CU_ASSERT(rc == 64);
195 : 3 : CU_ASSERT(_check_val(ddata, 64, 1) == 0);
196 : 3 : }
197 : :
198 : : static void
199 : 3 : test_iovs_to_buf(void)
200 : : {
201 : 3 : struct iovec iov[4];
202 : 3 : uint8_t sdata[64];
203 : 3 : uint8_t ddata[64];
204 : :
205 [ - + ]: 3 : memset(&sdata, 1, sizeof(sdata));
206 [ - + ]: 3 : memset(&ddata, 6, sizeof(ddata));
207 : :
208 : 3 : iov[0].iov_base = sdata;
209 : 3 : iov[0].iov_len = 3;
210 : 3 : iov[1].iov_base = iov[0].iov_base + iov[0].iov_len;
211 : 3 : iov[1].iov_len = 11;
212 : 3 : iov[2].iov_base = iov[1].iov_base + iov[1].iov_len;
213 : 3 : iov[2].iov_len = 21;
214 : 3 : iov[3].iov_base = iov[2].iov_base + iov[2].iov_len;
215 : 3 : iov[3].iov_len = 29;
216 : :
217 : 3 : spdk_copy_iovs_to_buf(ddata, 64, iov, 4);
218 : 3 : CU_ASSERT(_check_val(ddata, 64, 1) == 0);
219 : 3 : }
220 : :
221 : : static void
222 : 3 : test_buf_to_iovs(void)
223 : : {
224 : 3 : struct iovec iov[4];
225 : 3 : uint8_t sdata[64];
226 : 3 : uint8_t ddata[64];
227 : 3 : uint8_t iov_buffer[64];
228 : :
229 [ - + ]: 3 : memset(&sdata, 7, sizeof(sdata));
230 [ - + ]: 3 : memset(&ddata, 4, sizeof(ddata));
231 [ - + ]: 3 : memset(&iov_buffer, 1, sizeof(iov_buffer));
232 : :
233 : 3 : iov[0].iov_base = iov_buffer;
234 : 3 : iov[0].iov_len = 5;
235 : 3 : iov[1].iov_base = iov[0].iov_base + iov[0].iov_len;
236 : 3 : iov[1].iov_len = 15;
237 : 3 : iov[2].iov_base = iov[1].iov_base + iov[1].iov_len;
238 : 3 : iov[2].iov_len = 21;
239 : 3 : iov[3].iov_base = iov[2].iov_base + iov[2].iov_len;
240 : 3 : iov[3].iov_len = 23;
241 : :
242 : 3 : spdk_copy_buf_to_iovs(iov, 4, sdata, 64);
243 : 3 : spdk_copy_iovs_to_buf(ddata, 64, iov, 4);
244 : :
245 : 3 : CU_ASSERT(_check_val(ddata, 64, 7) == 0);
246 : 3 : }
247 : :
248 : : static void
249 : 3 : test_memset(void)
250 : : {
251 : 3 : struct iovec iov[4];
252 : 3 : uint8_t iov_buffer[64];
253 : :
254 [ - + ]: 3 : memset(&iov_buffer, 1, sizeof(iov_buffer));
255 : :
256 : 3 : iov[0].iov_base = iov_buffer;
257 : 3 : iov[0].iov_len = 5;
258 : 3 : iov[1].iov_base = iov[0].iov_base + iov[0].iov_len;
259 : 3 : iov[1].iov_len = 15;
260 : 3 : iov[2].iov_base = iov[1].iov_base + iov[1].iov_len;
261 : 3 : iov[2].iov_len = 21;
262 : 3 : iov[3].iov_base = iov[2].iov_base + iov[2].iov_len;
263 : 3 : iov[3].iov_len = 23;
264 : :
265 : 3 : spdk_iov_memset(iov, 4, 0);
266 : :
267 : 3 : CU_ASSERT(_check_val(iov_buffer, 64, 0) == 0);
268 : 3 : }
269 : :
270 : : static void
271 : 3 : test_iov_one(void)
272 : : {
273 : 3 : struct iovec iov = { 0 };
274 : 3 : int iovcnt;
275 : 3 : char buf[4];
276 : :
277 : 3 : SPDK_IOV_ONE(&iov, &iovcnt, buf, sizeof(buf));
278 : :
279 : 3 : CU_ASSERT(iov.iov_base == buf);
280 : 3 : CU_ASSERT(iov.iov_len == sizeof(buf));
281 : 3 : CU_ASSERT(iovcnt == 1);
282 : 3 : }
283 : :
284 : : static void
285 : 3 : test_iov_xfer(void)
286 : : {
287 : 3 : struct spdk_iov_xfer ix;
288 : 3 : uint8_t data[64] = { 0 };
289 : 3 : uint8_t iov_buffer[64];
290 : 3 : struct iovec iov[4];
291 : : size_t i;
292 : :
293 [ + + ]: 195 : for (i = 0; i < sizeof(iov_buffer); i++) {
294 : 192 : iov_buffer[i] = i;
295 : : }
296 : :
297 : 3 : iov[0].iov_base = iov_buffer;
298 : 3 : iov[0].iov_len = 5;
299 : 3 : iov[1].iov_base = iov[0].iov_base + iov[0].iov_len;
300 : 3 : iov[1].iov_len = 15;
301 : 3 : iov[2].iov_base = iov[1].iov_base + iov[1].iov_len;
302 : 3 : iov[2].iov_len = 21;
303 : 3 : iov[3].iov_base = iov[2].iov_base + iov[2].iov_len;
304 : 3 : iov[3].iov_len = 23;
305 : :
306 : 3 : spdk_iov_xfer_init(&ix, iov, 4);
307 : :
308 : 3 : spdk_iov_xfer_to_buf(&ix, data, 8);
309 : 3 : spdk_iov_xfer_to_buf(&ix, data + 8, 56);
310 : :
311 [ + + ]: 195 : for (i = 0; i < sizeof(data); i++) {
312 : 192 : CU_ASSERT(data[i] == i);
313 : : }
314 : :
315 [ + + ]: 195 : for (i = 0; i < sizeof(data); i++) {
316 : 192 : data[i] = sizeof(data) - i;
317 : : }
318 : :
319 : 3 : spdk_iov_xfer_init(&ix, iov, 4);
320 : :
321 : 3 : spdk_iov_xfer_from_buf(&ix, data, 5);
322 : 3 : spdk_iov_xfer_from_buf(&ix, data + 5, 3);
323 : 3 : spdk_iov_xfer_from_buf(&ix, data + 8, 56);
324 : :
325 [ + + ]: 195 : for (i = 0; i < sizeof(iov_buffer); i++) {
326 : 192 : CU_ASSERT(iov_buffer[i] == sizeof(iov_buffer) - i);
327 : : }
328 : 3 : }
329 : :
330 : : int
331 : 3 : main(int argc, char **argv)
332 : : {
333 : 3 : CU_pSuite suite = NULL;
334 : : unsigned int num_failures;
335 : :
336 : 3 : CU_initialize_registry();
337 : :
338 : 3 : suite = CU_add_suite("iov", NULL, NULL);
339 : :
340 : 3 : CU_ADD_TEST(suite, test_single_iov);
341 : 3 : CU_ADD_TEST(suite, test_simple_iov);
342 : 3 : CU_ADD_TEST(suite, test_complex_iov);
343 : 3 : CU_ADD_TEST(suite, test_iovs_to_buf);
344 : 3 : CU_ADD_TEST(suite, test_buf_to_iovs);
345 : 3 : CU_ADD_TEST(suite, test_memset);
346 : 3 : CU_ADD_TEST(suite, test_iov_one);
347 : 3 : CU_ADD_TEST(suite, test_iov_xfer);
348 : :
349 : :
350 : 3 : num_failures = spdk_ut_run_tests(argc, argv, NULL);
351 : :
352 : 3 : CU_cleanup_registry();
353 : :
354 : 3 : return num_failures;
355 : : }
|