1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "spdk/stdinc.h" 7 8 #include "spdk_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 228 memset(&sdata, 7, sizeof(sdata)); 229 memset(&ddata, 4, sizeof(ddata)); 230 231 iov[0].iov_base = sdata; 232 iov[0].iov_len = 5; 233 iov[1].iov_base = iov[0].iov_base + iov[0].iov_len; 234 iov[1].iov_len = 15; 235 iov[2].iov_base = iov[1].iov_base + iov[1].iov_len; 236 iov[2].iov_len = 21; 237 iov[3].iov_base = iov[2].iov_base + iov[2].iov_len; 238 iov[3].iov_len = 23; 239 240 spdk_copy_buf_to_iovs(iov, 4, sdata, 64); 241 spdk_copy_iovs_to_buf(ddata, 64, iov, 4); 242 243 CU_ASSERT(_check_val(ddata, 64, 7) == 0); 244 } 245 246 int 247 main(int argc, char **argv) 248 { 249 CU_pSuite suite = NULL; 250 unsigned int num_failures; 251 252 CU_set_error_action(CUEA_ABORT); 253 CU_initialize_registry(); 254 255 suite = CU_add_suite("iov", NULL, NULL); 256 257 CU_ADD_TEST(suite, test_single_iov); 258 CU_ADD_TEST(suite, test_simple_iov); 259 CU_ADD_TEST(suite, test_complex_iov); 260 CU_ADD_TEST(suite, test_iovs_to_buf); 261 CU_ADD_TEST(suite, test_buf_to_iovs); 262 263 CU_basic_set_mode(CU_BRM_VERBOSE); 264 265 CU_basic_run_tests(); 266 267 num_failures = CU_get_number_of_failures(); 268 CU_cleanup_registry(); 269 270 return num_failures; 271 } 272