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