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