1 /*- 2 * Copyright (c) 2015-2024 Mariusz Zaborski <oshogbo@FreeBSD.org> 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26 #include <sys/param.h> 27 #include <sys/types.h> 28 #include <sys/nv.h> 29 #include <sys/mman.h> 30 #include <sys/socket.h> 31 32 #include <atf-c++.hpp> 33 34 #include <cstdio> 35 #include <errno.h> 36 #include <fcntl.h> 37 #include <limits> 38 #include <set> 39 #include <sstream> 40 #include <string> 41 42 #define fd_is_valid(fd) (fcntl((fd), F_GETFL) != -1 || errno != EBADF) 43 44 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_bool_array__basic); 45 ATF_TEST_CASE_BODY(nvlist_bool_array__basic) 46 { 47 bool testbool[16]; 48 const bool *const_result; 49 bool *result; 50 nvlist_t *nvl; 51 size_t num_items; 52 unsigned int i; 53 const char *key; 54 55 key = "nvl/bool"; 56 nvl = nvlist_create(0); 57 ATF_REQUIRE(nvl != NULL); 58 ATF_REQUIRE(nvlist_empty(nvl)); 59 ATF_REQUIRE(!nvlist_exists_string_array(nvl, key)); 60 61 for (i = 0; i < 16; i++) 62 testbool[i] = (i % 2 == 0); 63 64 nvlist_add_bool_array(nvl, key, testbool, 16); 65 ATF_REQUIRE_EQ(nvlist_error(nvl), 0); 66 ATF_REQUIRE(!nvlist_empty(nvl)); 67 ATF_REQUIRE(nvlist_exists_bool_array(nvl, key)); 68 ATF_REQUIRE(nvlist_exists_bool_array(nvl, "nvl/bool")); 69 70 const_result = nvlist_get_bool_array(nvl, key, &num_items); 71 ATF_REQUIRE_EQ(num_items, 16); 72 ATF_REQUIRE(const_result != NULL); 73 for (i = 0; i < num_items; i++) 74 ATF_REQUIRE_EQ(const_result[i], testbool[i]); 75 76 result = nvlist_take_bool_array(nvl, key, &num_items); 77 ATF_REQUIRE_EQ(num_items, 16); 78 ATF_REQUIRE(const_result != NULL); 79 for (i = 0; i < num_items; i++) 80 ATF_REQUIRE_EQ(result[i], testbool[i]); 81 82 ATF_REQUIRE(!nvlist_exists_bool_array(nvl, key)); 83 ATF_REQUIRE(nvlist_empty(nvl)); 84 ATF_REQUIRE_EQ(nvlist_error(nvl), 0); 85 86 free(result); 87 nvlist_destroy(nvl); 88 } 89 90 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_string_array__basic); 91 ATF_TEST_CASE_BODY(nvlist_string_array__basic) 92 { 93 const char * const *const_result; 94 char **result; 95 nvlist_t *nvl; 96 size_t num_items; 97 unsigned int i; 98 const char *key; 99 const char *string_arr[8] = { "a", "b", "kot", "foo", 100 "tests", "nice test", "", "abcdef" }; 101 102 key = "nvl/string"; 103 nvl = nvlist_create(0); 104 ATF_REQUIRE(nvl != NULL); 105 ATF_REQUIRE(nvlist_empty(nvl)); 106 ATF_REQUIRE(!nvlist_exists_string_array(nvl, key)); 107 108 nvlist_add_string_array(nvl, key, string_arr, nitems(string_arr)); 109 ATF_REQUIRE_EQ(nvlist_error(nvl), 0); 110 ATF_REQUIRE(!nvlist_empty(nvl)); 111 ATF_REQUIRE(nvlist_exists_string_array(nvl, key)); 112 ATF_REQUIRE(nvlist_exists_string_array(nvl, "nvl/string")); 113 114 const_result = nvlist_get_string_array(nvl, key, &num_items); 115 ATF_REQUIRE(!nvlist_empty(nvl)); 116 ATF_REQUIRE(const_result != NULL); 117 ATF_REQUIRE(num_items == nitems(string_arr)); 118 for (i = 0; i < num_items; i++) { 119 if (string_arr[i] != NULL) { 120 ATF_REQUIRE(strcmp(const_result[i], 121 string_arr[i]) == 0); 122 } else { 123 ATF_REQUIRE(const_result[i] == string_arr[i]); 124 } 125 } 126 127 result = nvlist_take_string_array(nvl, key, &num_items); 128 ATF_REQUIRE(result != NULL); 129 ATF_REQUIRE_EQ(num_items, nitems(string_arr)); 130 for (i = 0; i < num_items; i++) { 131 if (string_arr[i] != NULL) { 132 ATF_REQUIRE_EQ(strcmp(result[i], string_arr[i]), 0); 133 } else { 134 ATF_REQUIRE_EQ(result[i], string_arr[i]); 135 } 136 } 137 138 ATF_REQUIRE(!nvlist_exists_string_array(nvl, key)); 139 ATF_REQUIRE(nvlist_empty(nvl)); 140 ATF_REQUIRE_EQ(nvlist_error(nvl), 0); 141 142 for (i = 0; i < num_items; i++) 143 free(result[i]); 144 free(result); 145 nvlist_destroy(nvl); 146 } 147 148 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_descriptor_array__basic); 149 ATF_TEST_CASE_BODY(nvlist_descriptor_array__basic) 150 { 151 int fd[32], *result; 152 const int *const_result; 153 nvlist_t *nvl; 154 size_t num_items; 155 unsigned int i; 156 const char *key; 157 158 for (i = 0; i < nitems(fd); i++) { 159 fd[i] = dup(STDERR_FILENO); 160 ATF_REQUIRE(fd_is_valid(fd[i])); 161 } 162 163 key = "nvl/descriptor"; 164 nvl = nvlist_create(0); 165 ATF_REQUIRE(nvl != NULL); 166 ATF_REQUIRE(nvlist_empty(nvl)); 167 ATF_REQUIRE(!nvlist_exists_descriptor_array(nvl, key)); 168 169 nvlist_add_descriptor_array(nvl, key, fd, nitems(fd)); 170 ATF_REQUIRE_EQ(nvlist_error(nvl), 0); 171 ATF_REQUIRE(!nvlist_empty(nvl)); 172 ATF_REQUIRE(nvlist_exists_descriptor_array(nvl, key)); 173 ATF_REQUIRE(nvlist_exists_descriptor_array(nvl, "nvl/descriptor")); 174 175 const_result = nvlist_get_descriptor_array(nvl, key, &num_items); 176 ATF_REQUIRE(!nvlist_empty(nvl)); 177 ATF_REQUIRE(const_result != NULL); 178 ATF_REQUIRE(num_items == nitems(fd)); 179 for (i = 0; i < num_items; i++) { 180 ATF_REQUIRE(fd_is_valid(const_result[i])); 181 if (i > 0) 182 ATF_REQUIRE(const_result[i] != const_result[i - 1]); 183 } 184 185 result = nvlist_take_descriptor_array(nvl, key, &num_items); 186 ATF_REQUIRE(result != NULL); 187 ATF_REQUIRE_EQ(num_items, nitems(fd)); 188 for (i = 0; i < num_items; i++) { 189 ATF_REQUIRE(fd_is_valid(result[i])); 190 if (i > 0) 191 ATF_REQUIRE(const_result[i] != const_result[i - 1]); 192 } 193 194 ATF_REQUIRE(!nvlist_exists_string_array(nvl, key)); 195 ATF_REQUIRE(nvlist_empty(nvl)); 196 ATF_REQUIRE_EQ(nvlist_error(nvl), 0); 197 198 for (i = 0; i < num_items; i++) { 199 close(result[i]); 200 close(fd[i]); 201 } 202 free(result); 203 nvlist_destroy(nvl); 204 } 205 206 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_number_array__basic); 207 ATF_TEST_CASE_BODY(nvlist_number_array__basic) 208 { 209 const uint64_t *const_result; 210 uint64_t *result; 211 nvlist_t *nvl; 212 size_t num_items; 213 unsigned int i; 214 const char *key; 215 const uint64_t number[8] = { 0, UINT_MAX, 7, 123, 90, 216 100000, 8, 1 }; 217 218 key = "nvl/number"; 219 nvl = nvlist_create(0); 220 ATF_REQUIRE(nvl != NULL); 221 ATF_REQUIRE(nvlist_empty(nvl)); 222 ATF_REQUIRE(!nvlist_exists_string_array(nvl, key)); 223 224 nvlist_add_number_array(nvl, key, number, nitems(number)); 225 ATF_REQUIRE_EQ(nvlist_error(nvl), 0); 226 ATF_REQUIRE(!nvlist_empty(nvl)); 227 ATF_REQUIRE(nvlist_exists_number_array(nvl, key)); 228 ATF_REQUIRE(nvlist_exists_number_array(nvl, "nvl/number")); 229 230 const_result = nvlist_get_number_array(nvl, key, &num_items); 231 ATF_REQUIRE(!nvlist_empty(nvl)); 232 ATF_REQUIRE(const_result != NULL); 233 ATF_REQUIRE(num_items == nitems(number)); 234 for (i = 0; i < num_items; i++) 235 ATF_REQUIRE_EQ(const_result[i], number[i]); 236 237 result = nvlist_take_number_array(nvl, key, &num_items); 238 ATF_REQUIRE(result != NULL); 239 ATF_REQUIRE_EQ(num_items, nitems(number)); 240 for (i = 0; i < num_items; i++) 241 ATF_REQUIRE_EQ(result[i], number[i]); 242 243 ATF_REQUIRE(!nvlist_exists_string_array(nvl, key)); 244 ATF_REQUIRE(nvlist_empty(nvl)); 245 ATF_REQUIRE_EQ(nvlist_error(nvl), 0); 246 247 free(result); 248 nvlist_destroy(nvl); 249 } 250 251 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_nvlist_array__basic); 252 ATF_TEST_CASE_BODY(nvlist_nvlist_array__basic) 253 { 254 nvlist_t *testnvl[8]; 255 const nvlist_t * const *const_result; 256 nvlist_t **result; 257 nvlist_t *nvl; 258 size_t num_items; 259 unsigned int i; 260 const char *somestr[8] = { "a", "b", "c", "d", "e", "f", "g", "h" }; 261 const char *key; 262 263 for (i = 0; i < 8; i++) { 264 testnvl[i] = nvlist_create(0); 265 ATF_REQUIRE(testnvl[i] != NULL); 266 ATF_REQUIRE_EQ(nvlist_error(testnvl[i]), 0); 267 nvlist_add_string(testnvl[i], "nvl/string", somestr[i]); 268 ATF_REQUIRE_EQ(nvlist_error(testnvl[i]), 0); 269 ATF_REQUIRE(nvlist_exists_string(testnvl[i], "nvl/string")); 270 } 271 272 key = "nvl/nvlist"; 273 nvl = nvlist_create(0); 274 ATF_REQUIRE(nvl != NULL); 275 ATF_REQUIRE(nvlist_empty(nvl)); 276 ATF_REQUIRE(!nvlist_exists_string_array(nvl, key)); 277 278 nvlist_add_nvlist_array(nvl, key, (const nvlist_t * const *)testnvl, 8); 279 ATF_REQUIRE_EQ(nvlist_error(nvl), 0); 280 ATF_REQUIRE(!nvlist_empty(nvl)); 281 ATF_REQUIRE(nvlist_exists_nvlist_array(nvl, key)); 282 ATF_REQUIRE(nvlist_exists_nvlist_array(nvl, "nvl/nvlist")); 283 284 const_result = nvlist_get_nvlist_array(nvl, key, &num_items); 285 ATF_REQUIRE(!nvlist_empty(nvl)); 286 ATF_REQUIRE(const_result != NULL); 287 ATF_REQUIRE(num_items == nitems(testnvl)); 288 289 for (i = 0; i < num_items; i++) { 290 ATF_REQUIRE_EQ(nvlist_error(const_result[i]), 0); 291 if (i < num_items - 1) { 292 ATF_REQUIRE(nvlist_get_array_next(const_result[i]) == 293 const_result[i + 1]); 294 } else { 295 ATF_REQUIRE(nvlist_get_array_next(const_result[i]) == 296 NULL); 297 } 298 ATF_REQUIRE(nvlist_get_parent(const_result[i], NULL) == nvl); 299 ATF_REQUIRE(nvlist_in_array(const_result[i])); 300 ATF_REQUIRE(nvlist_exists_string(const_result[i], 301 "nvl/string")); 302 ATF_REQUIRE(strcmp(nvlist_get_string(const_result[i], 303 "nvl/string"), somestr[i]) == 0); 304 } 305 306 result = nvlist_take_nvlist_array(nvl, key, &num_items); 307 ATF_REQUIRE(result != NULL); 308 ATF_REQUIRE_EQ(num_items, 8); 309 for (i = 0; i < num_items; i++) { 310 ATF_REQUIRE_EQ(nvlist_error(result[i]), 0); 311 ATF_REQUIRE(nvlist_get_array_next(result[i]) == NULL); 312 ATF_REQUIRE(nvlist_get_parent(result[i], NULL) == NULL); 313 ATF_REQUIRE(nvlist_get_array_next(const_result[i]) == NULL); 314 ATF_REQUIRE(!nvlist_in_array(const_result[i])); 315 } 316 317 ATF_REQUIRE(!nvlist_exists_string_array(nvl, key)); 318 ATF_REQUIRE(nvlist_empty(nvl)); 319 ATF_REQUIRE_EQ(nvlist_error(nvl), 0); 320 321 for (i = 0; i < 8; i++) { 322 nvlist_destroy(result[i]); 323 nvlist_destroy(testnvl[i]); 324 } 325 326 free(result); 327 nvlist_destroy(nvl); 328 } 329 330 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_clone_array); 331 ATF_TEST_CASE_BODY(nvlist_clone_array) 332 { 333 nvlist_t *testnvl[8]; 334 nvlist_t *src, *dst; 335 const nvlist_t *nvl; 336 bool testbool[16]; 337 int testfd[16]; 338 size_t i, num_items; 339 const char *string_arr[8] = { "a", "b", "kot", "foo", 340 "tests", "nice test", "", "abcdef" }; 341 const char *somestr[8] = { "a", "b", "c", "d", "e", "f", "g", "h" }; 342 const uint64_t number[8] = { 0, UINT_MAX, 7, 123, 90, 343 100000, 8, 1 }; 344 345 for (i = 0; i < nitems(testfd); i++) { 346 testbool[i] = (i % 2 == 0); 347 testfd[i] = dup(STDERR_FILENO); 348 ATF_REQUIRE(fd_is_valid(testfd[i])); 349 } 350 for (i = 0; i < nitems(testnvl); i++) { 351 testnvl[i] = nvlist_create(0); 352 ATF_REQUIRE(nvlist_error(testnvl[i]) == 0); 353 nvlist_add_string(testnvl[i], "nvl/nvl/teststr", somestr[i]); 354 ATF_REQUIRE(nvlist_error(testnvl[i]) == 0); 355 } 356 357 src = nvlist_create(0); 358 ATF_REQUIRE(nvlist_error(src) == 0); 359 360 ATF_REQUIRE(!nvlist_exists_bool_array(src, "nvl/bool")); 361 nvlist_add_bool_array(src, "nvl/bool", testbool, nitems(testbool)); 362 ATF_REQUIRE_EQ(nvlist_error(src), 0); 363 ATF_REQUIRE(nvlist_exists_bool_array(src, "nvl/bool")); 364 365 ATF_REQUIRE(!nvlist_exists_string_array(src, "nvl/string")); 366 nvlist_add_string_array(src, "nvl/string", string_arr, 367 nitems(string_arr)); 368 ATF_REQUIRE_EQ(nvlist_error(src), 0); 369 ATF_REQUIRE(nvlist_exists_string_array(src, "nvl/string")); 370 371 ATF_REQUIRE(!nvlist_exists_descriptor_array(src, "nvl/fd")); 372 nvlist_add_descriptor_array(src, "nvl/fd", testfd, nitems(testfd)); 373 ATF_REQUIRE_EQ(nvlist_error(src), 0); 374 ATF_REQUIRE(nvlist_exists_descriptor_array(src, "nvl/fd")); 375 376 ATF_REQUIRE(!nvlist_exists_number_array(src, "nvl/number")); 377 nvlist_add_number_array(src, "nvl/number", number, 378 nitems(number)); 379 ATF_REQUIRE_EQ(nvlist_error(src), 0); 380 ATF_REQUIRE(nvlist_exists_number_array(src, "nvl/number")); 381 382 ATF_REQUIRE(!nvlist_exists_nvlist_array(src, "nvl/array")); 383 nvlist_add_nvlist_array(src, "nvl/array", 384 (const nvlist_t * const *)testnvl, nitems(testnvl)); 385 ATF_REQUIRE_EQ(nvlist_error(src), 0); 386 ATF_REQUIRE(nvlist_exists_nvlist_array(src, "nvl/array")); 387 388 dst = nvlist_clone(src); 389 ATF_REQUIRE(dst != NULL); 390 391 ATF_REQUIRE(nvlist_exists_bool_array(dst, "nvl/bool")); 392 (void) nvlist_get_bool_array(dst, "nvl/bool", &num_items); 393 ATF_REQUIRE_EQ(num_items, nitems(testbool)); 394 for (i = 0; i < num_items; i++) { 395 ATF_REQUIRE( 396 nvlist_get_bool_array(dst, "nvl/bool", &num_items)[i] == 397 nvlist_get_bool_array(src, "nvl/bool", &num_items)[i]); 398 } 399 400 ATF_REQUIRE(nvlist_exists_string_array(dst, "nvl/string")); 401 (void) nvlist_get_string_array(dst, "nvl/string", &num_items); 402 ATF_REQUIRE_EQ(num_items, nitems(string_arr)); 403 for (i = 0; i < num_items; i++) { 404 if (nvlist_get_string_array(dst, "nvl/string", 405 &num_items)[i] == NULL) { 406 ATF_REQUIRE(nvlist_get_string_array(dst, "nvl/string", 407 &num_items)[i] == nvlist_get_string_array(src, 408 "nvl/string", &num_items)[i]); 409 } else { 410 ATF_REQUIRE(strcmp(nvlist_get_string_array(dst, 411 "nvl/string", &num_items)[i], nvlist_get_string_array( 412 src, "nvl/string", &num_items)[i]) == 0); 413 } 414 } 415 416 ATF_REQUIRE(nvlist_exists_descriptor_array(dst, "nvl/fd")); 417 (void) nvlist_get_descriptor_array(dst, "nvl/fd", &num_items); 418 ATF_REQUIRE_EQ(num_items, nitems(testfd)); 419 for (i = 0; i < num_items; i++) { 420 ATF_REQUIRE(fd_is_valid( 421 nvlist_get_descriptor_array(dst, "nvl/fd", &num_items)[i])); 422 } 423 ATF_REQUIRE(nvlist_exists_number_array(dst, "nvl/number")); 424 (void) nvlist_get_number_array(dst, "nvl/number", &num_items); 425 ATF_REQUIRE_EQ(num_items, nitems(number)); 426 427 for (i = 0; i < num_items; i++) { 428 ATF_REQUIRE( 429 nvlist_get_number_array(dst, "nvl/number", &num_items)[i] == 430 nvlist_get_number_array(src, "nvl/number", &num_items)[i]); 431 } 432 433 ATF_REQUIRE(nvlist_exists_nvlist_array(dst, "nvl/array")); 434 (void) nvlist_get_nvlist_array(dst, "nvl/array", &num_items); 435 ATF_REQUIRE_EQ(num_items, nitems(testnvl)); 436 for (i = 0; i < num_items; i++) { 437 nvl = nvlist_get_nvlist_array(dst, "nvl/array", &num_items)[i]; 438 ATF_REQUIRE(nvlist_exists_string(nvl, "nvl/nvl/teststr")); 439 ATF_REQUIRE(strcmp(nvlist_get_string(nvl, "nvl/nvl/teststr"), 440 somestr[i]) == 0); 441 } 442 443 for (i = 0; i < nitems(testfd); i++) { 444 close(testfd[i]); 445 } 446 for (i = 0; i < nitems(testnvl); i++) { 447 nvlist_destroy(testnvl[i]); 448 } 449 nvlist_destroy(src); 450 nvlist_destroy(dst); 451 } 452 453 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_bool_array__move); 454 ATF_TEST_CASE_BODY(nvlist_bool_array__move) 455 { 456 bool *testbool; 457 const bool *const_result; 458 nvlist_t *nvl; 459 size_t num_items, count; 460 unsigned int i; 461 const char *key; 462 463 key = "nvl/bool"; 464 nvl = nvlist_create(0); 465 ATF_REQUIRE(nvl != NULL); 466 ATF_REQUIRE(nvlist_empty(nvl)); 467 ATF_REQUIRE(!nvlist_exists_string_array(nvl, key)); 468 469 count = 16; 470 testbool = (bool*)malloc(sizeof(*testbool) * count); 471 ATF_REQUIRE(testbool != NULL); 472 for (i = 0; i < count; i++) 473 testbool[i] = (i % 2 == 0); 474 475 nvlist_move_bool_array(nvl, key, testbool, count); 476 ATF_REQUIRE_EQ(nvlist_error(nvl), 0); 477 ATF_REQUIRE(!nvlist_empty(nvl)); 478 ATF_REQUIRE(nvlist_exists_bool_array(nvl, key)); 479 480 const_result = nvlist_get_bool_array(nvl, key, &num_items); 481 ATF_REQUIRE_EQ(num_items, count); 482 ATF_REQUIRE(const_result != NULL); 483 ATF_REQUIRE(const_result == testbool); 484 for (i = 0; i < num_items; i++) 485 ATF_REQUIRE_EQ(const_result[i], (i % 2 == 0)); 486 487 nvlist_destroy(nvl); 488 } 489 490 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_string_array__move); 491 ATF_TEST_CASE_BODY(nvlist_string_array__move) 492 { 493 char **teststr; 494 const char * const *const_result; 495 nvlist_t *nvl; 496 size_t num_items, count; 497 unsigned int i; 498 const char *key; 499 500 key = "nvl/string"; 501 nvl = nvlist_create(0); 502 ATF_REQUIRE(nvl != NULL); 503 ATF_REQUIRE(nvlist_empty(nvl)); 504 ATF_REQUIRE(!nvlist_exists_string_array(nvl, key)); 505 506 count = 26; 507 teststr = (char**)malloc(sizeof(*teststr) * count); 508 ATF_REQUIRE(teststr != NULL); 509 for (i = 0; i < count; i++) { 510 teststr[i] = (char*)malloc(sizeof(**teststr) * 2); 511 ATF_REQUIRE(teststr[i] != NULL); 512 teststr[i][0] = 'a' + i; 513 teststr[i][1] = '\0'; 514 } 515 516 nvlist_move_string_array(nvl, key, teststr, count); 517 ATF_REQUIRE_EQ(nvlist_error(nvl), 0); 518 ATF_REQUIRE(!nvlist_empty(nvl)); 519 ATF_REQUIRE(nvlist_exists_string_array(nvl, key)); 520 521 const_result = nvlist_get_string_array(nvl, key, &num_items); 522 ATF_REQUIRE_EQ(num_items, count); 523 ATF_REQUIRE(const_result != NULL); 524 ATF_REQUIRE((intptr_t)const_result == (intptr_t)teststr); 525 for (i = 0; i < num_items; i++) { 526 ATF_REQUIRE_EQ(const_result[i][0], (char)('a' + i)); 527 ATF_REQUIRE_EQ(const_result[i][1], '\0'); 528 } 529 530 nvlist_destroy(nvl); 531 } 532 533 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_nvlist_array__move); 534 ATF_TEST_CASE_BODY(nvlist_nvlist_array__move) 535 { 536 nvlist **testnv; 537 const nvlist * const *const_result; 538 nvlist_t *nvl; 539 size_t num_items, count; 540 unsigned int i; 541 const char *key; 542 543 key = "nvl/nvlist"; 544 nvl = nvlist_create(0); 545 ATF_REQUIRE(nvl != NULL); 546 ATF_REQUIRE(nvlist_empty(nvl)); 547 ATF_REQUIRE(!nvlist_exists_nvlist_array(nvl, key)); 548 549 count = 26; 550 testnv = (nvlist**)malloc(sizeof(*testnv) * count); 551 ATF_REQUIRE(testnv != NULL); 552 for (i = 0; i < count; i++) { 553 testnv[i] = nvlist_create(0); 554 ATF_REQUIRE(testnv[i] != NULL); 555 } 556 557 nvlist_move_nvlist_array(nvl, key, testnv, count); 558 ATF_REQUIRE_EQ(nvlist_error(nvl), 0); 559 ATF_REQUIRE(!nvlist_empty(nvl)); 560 ATF_REQUIRE(nvlist_exists_nvlist_array(nvl, key)); 561 562 const_result = nvlist_get_nvlist_array(nvl, key, &num_items); 563 ATF_REQUIRE_EQ(num_items, count); 564 ATF_REQUIRE(const_result != NULL); 565 ATF_REQUIRE((intptr_t)const_result == (intptr_t)testnv); 566 for (i = 0; i < num_items; i++) { 567 ATF_REQUIRE_EQ(nvlist_error(const_result[i]), 0); 568 ATF_REQUIRE(nvlist_empty(const_result[i])); 569 if (i < num_items - 1) { 570 ATF_REQUIRE(nvlist_get_array_next(const_result[i]) == 571 const_result[i + 1]); 572 } else { 573 ATF_REQUIRE(nvlist_get_array_next(const_result[i]) == 574 NULL); 575 } 576 ATF_REQUIRE(nvlist_get_parent(const_result[i], NULL) == nvl); 577 ATF_REQUIRE(nvlist_in_array(const_result[i])); 578 } 579 580 nvlist_destroy(nvl); 581 } 582 583 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_number_array__move); 584 ATF_TEST_CASE_BODY(nvlist_number_array__move) 585 { 586 uint64_t *testnumber; 587 const uint64_t *const_result; 588 nvlist_t *nvl; 589 size_t num_items, count; 590 unsigned int i; 591 const char *key; 592 593 key = "nvl/number"; 594 nvl = nvlist_create(0); 595 ATF_REQUIRE(nvl != NULL); 596 ATF_REQUIRE(nvlist_empty(nvl)); 597 ATF_REQUIRE(!nvlist_exists_string_array(nvl, key)); 598 599 count = 1000; 600 testnumber = (uint64_t*)malloc(sizeof(*testnumber) * count); 601 ATF_REQUIRE(testnumber != NULL); 602 for (i = 0; i < count; i++) 603 testnumber[i] = i; 604 605 nvlist_move_number_array(nvl, key, testnumber, count); 606 ATF_REQUIRE_EQ(nvlist_error(nvl), 0); 607 ATF_REQUIRE(!nvlist_empty(nvl)); 608 ATF_REQUIRE(nvlist_exists_number_array(nvl, key)); 609 610 const_result = nvlist_get_number_array(nvl, key, &num_items); 611 ATF_REQUIRE_EQ(num_items, count); 612 ATF_REQUIRE(const_result != NULL); 613 ATF_REQUIRE(const_result == testnumber); 614 for (i = 0; i < num_items; i++) 615 ATF_REQUIRE_EQ(const_result[i], i); 616 617 nvlist_destroy(nvl); 618 } 619 620 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_descriptor_array__move); 621 ATF_TEST_CASE_BODY(nvlist_descriptor_array__move) 622 { 623 int *testfd; 624 const int *const_result; 625 nvlist_t *nvl; 626 size_t num_items, count; 627 unsigned int i; 628 const char *key; 629 630 key = "nvl/fd"; 631 nvl = nvlist_create(0); 632 ATF_REQUIRE(nvl != NULL); 633 ATF_REQUIRE(nvlist_empty(nvl)); 634 ATF_REQUIRE(!nvlist_exists_string_array(nvl, key)); 635 636 count = 50; 637 testfd = (int*)malloc(sizeof(*testfd) * count); 638 ATF_REQUIRE(testfd != NULL); 639 for (i = 0; i < count; i++) { 640 testfd[i] = dup(STDERR_FILENO); 641 ATF_REQUIRE(fd_is_valid(testfd[i])); 642 } 643 644 nvlist_move_descriptor_array(nvl, key, testfd, count); 645 ATF_REQUIRE_EQ(nvlist_error(nvl), 0); 646 ATF_REQUIRE(!nvlist_empty(nvl)); 647 ATF_REQUIRE(nvlist_exists_descriptor_array(nvl, key)); 648 649 const_result = nvlist_get_descriptor_array(nvl, key, &num_items); 650 ATF_REQUIRE_EQ(num_items, count); 651 ATF_REQUIRE(const_result != NULL); 652 ATF_REQUIRE(const_result == testfd); 653 for (i = 0; i < num_items; i++) 654 ATF_REQUIRE(fd_is_valid(const_result[i])); 655 656 nvlist_destroy(nvl); 657 } 658 659 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_arrays__error_null); 660 ATF_TEST_CASE_BODY(nvlist_arrays__error_null) 661 { 662 nvlist_t *nvl; 663 664 nvl = nvlist_create(0); 665 ATF_REQUIRE(nvl != NULL); 666 nvlist_add_number_array(nvl, "nvl/number", NULL, 0); 667 ATF_REQUIRE(nvlist_error(nvl) != 0); 668 nvlist_destroy(nvl); 669 670 nvl = nvlist_create(0); 671 ATF_REQUIRE(nvl != NULL); 672 nvlist_move_number_array(nvl, "nvl/number", NULL, 0); 673 ATF_REQUIRE(nvlist_error(nvl) != 0); 674 nvlist_destroy(nvl); 675 676 nvl = nvlist_create(0); 677 ATF_REQUIRE(nvl != NULL); 678 nvlist_add_descriptor_array(nvl, "nvl/fd", NULL, 0); 679 ATF_REQUIRE(nvlist_error(nvl) != 0); 680 nvlist_destroy(nvl); 681 682 nvl = nvlist_create(0); 683 ATF_REQUIRE(nvl != NULL); 684 nvlist_move_descriptor_array(nvl, "nvl/fd", NULL, 0); 685 ATF_REQUIRE(nvlist_error(nvl) != 0); 686 nvlist_destroy(nvl); 687 688 nvl = nvlist_create(0); 689 ATF_REQUIRE(nvl != NULL); 690 nvlist_add_string_array(nvl, "nvl/string", NULL, 0); 691 ATF_REQUIRE(nvlist_error(nvl) != 0); 692 nvlist_destroy(nvl); 693 694 nvl = nvlist_create(0); 695 ATF_REQUIRE(nvl != NULL); 696 nvlist_move_string_array(nvl, "nvl/string", NULL, 0); 697 ATF_REQUIRE(nvlist_error(nvl) != 0); 698 nvlist_destroy(nvl); 699 700 nvl = nvlist_create(0); 701 ATF_REQUIRE(nvl != NULL); 702 nvlist_add_nvlist_array(nvl, "nvl/nvlist", NULL, 0); 703 ATF_REQUIRE(nvlist_error(nvl) != 0); 704 nvlist_destroy(nvl); 705 706 nvl = nvlist_create(0); 707 ATF_REQUIRE(nvl != NULL); 708 nvlist_move_nvlist_array(nvl, "nvl/nvlist", NULL, 0); 709 ATF_REQUIRE(nvlist_error(nvl) != 0); 710 nvlist_destroy(nvl); 711 712 nvl = nvlist_create(0); 713 ATF_REQUIRE(nvl != NULL); 714 nvlist_add_bool_array(nvl, "nvl/bool", NULL, 0); 715 ATF_REQUIRE(nvlist_error(nvl) != 0); 716 nvlist_destroy(nvl); 717 718 nvl = nvlist_create(0); 719 ATF_REQUIRE(nvl != NULL); 720 nvlist_move_bool_array(nvl, "nvl/bool", NULL, 0); 721 ATF_REQUIRE(nvlist_error(nvl) != 0); 722 nvlist_destroy(nvl); 723 } 724 725 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_arrays__bad_value); 726 ATF_TEST_CASE_BODY(nvlist_arrays__bad_value) 727 { 728 nvlist_t *nvl, *nvladd[1], **nvlmove; 729 int fdadd[1], *fdmove; 730 731 nvladd[0] = NULL; 732 nvl = nvlist_create(0); 733 ATF_REQUIRE(nvl != NULL); 734 nvlist_add_nvlist_array(nvl, "nvl/nvlist", nvladd, 1); 735 ATF_REQUIRE(nvlist_error(nvl) != 0); 736 nvlist_destroy(nvl); 737 738 nvlmove = (nvlist_t**)malloc(sizeof(*nvlmove)); 739 ATF_REQUIRE(nvlmove != NULL); 740 nvlmove[0] = NULL; 741 nvl = nvlist_create(0); 742 ATF_REQUIRE(nvl != NULL); 743 nvlist_move_nvlist_array(nvl, "nvl/nvlist", nvlmove, 1); 744 ATF_REQUIRE(nvlist_error(nvl) != 0); 745 nvlist_destroy(nvl); 746 747 fdadd[0] = -2; 748 nvl = nvlist_create(0); 749 ATF_REQUIRE(nvl != NULL); 750 nvlist_add_descriptor_array(nvl, "nvl/fd", fdadd, 1); 751 ATF_REQUIRE(nvlist_error(nvl) != 0); 752 nvlist_destroy(nvl); 753 754 fdmove = (int*)malloc(sizeof(*fdmove)); 755 ATF_REQUIRE(fdmove != NULL); 756 fdmove[0] = -2; 757 nvl = nvlist_create(0); 758 ATF_REQUIRE(nvl != NULL); 759 nvlist_move_descriptor_array(nvl, "nvl/fd", fdmove, 1); 760 ATF_REQUIRE(nvlist_error(nvl) != 0); 761 nvlist_destroy(nvl); 762 } 763 764 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_nvlist_array__travel); 765 ATF_TEST_CASE_BODY(nvlist_nvlist_array__travel) 766 { 767 nvlist_t *nvl, *test[5], *nasted; 768 const nvlist_t *travel; 769 const char *name; 770 void *cookie; 771 int type; 772 unsigned int i, index; 773 774 for (i = 0; i < nitems(test); i++) { 775 test[i] = nvlist_create(0); 776 ATF_REQUIRE(test[i] != NULL); 777 nvlist_add_number(test[i], "nvl/number", i); 778 ATF_REQUIRE(nvlist_error(test[i]) == 0); 779 } 780 nvl = nvlist_create(0); 781 ATF_REQUIRE(nvl != NULL); 782 nvlist_add_nvlist_array(nvl, "nvl/nvlist_array", test, nitems(test)); 783 ATF_REQUIRE(nvlist_error(nvl) == 0); 784 nasted = nvlist_create(0); 785 ATF_REQUIRE(nasted != NULL); 786 nvlist_add_nvlist_array(nasted, "nvl/nvl/nvlist_array", test, 787 nitems(test)); 788 ATF_REQUIRE(nvlist_error(nasted) == 0); 789 nvlist_move_nvlist(nvl, "nvl/nvl", nasted); 790 ATF_REQUIRE(nvlist_error(nvl) == 0); 791 nvlist_add_string(nvl, "nvl/string", "END"); 792 ATF_REQUIRE(nvlist_error(nvl) == 0); 793 794 cookie = NULL; 795 index = 0; 796 travel = nvl; 797 do { 798 while ((name = nvlist_next(travel, &type, &cookie)) != NULL) { 799 if (index == 0) { 800 ATF_REQUIRE(type == NV_TYPE_NVLIST_ARRAY); 801 } else if (index >= 1 && index <= nitems(test)) { 802 ATF_REQUIRE(type == NV_TYPE_NUMBER); 803 } else if (index == nitems(test) + 1) { 804 ATF_REQUIRE(type == NV_TYPE_NVLIST); 805 } else if (index == nitems(test) + 2) { 806 ATF_REQUIRE(type == NV_TYPE_NVLIST_ARRAY); 807 } else if (index >= nitems(test) + 3 && 808 index <= 2 * nitems(test) + 2) { 809 ATF_REQUIRE(type == NV_TYPE_NUMBER); 810 } else if (index == 2 * nitems(test) + 3) { 811 ATF_REQUIRE(type == NV_TYPE_STRING); 812 } 813 814 if (type == NV_TYPE_NVLIST) { 815 travel = nvlist_get_nvlist(travel, name); 816 cookie = NULL; 817 } else if (type == NV_TYPE_NVLIST_ARRAY) { 818 travel = nvlist_get_nvlist_array(travel, name, 819 NULL)[0]; 820 cookie = NULL; 821 } 822 index ++; 823 } 824 } while ((travel = nvlist_get_pararr(travel, &cookie)) != NULL); 825 826 for (i = 0; i < nitems(test); i++) 827 nvlist_destroy(test[i]); 828 829 nvlist_destroy(nvl); 830 } 831 832 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_nvlist_array__travel_alternative); 833 ATF_TEST_CASE_BODY(nvlist_nvlist_array__travel_alternative) 834 { 835 nvlist_t *nvl, *test[5], *nasted; 836 const nvlist_t *travel, *tmp; 837 void *cookie; 838 int index, i, type; 839 const char *name; 840 841 for (i = 0; i < 5; i++) { 842 test[i] = nvlist_create(0); 843 ATF_REQUIRE(test[i] != NULL); 844 nvlist_add_number(test[i], "nvl/number", i); 845 ATF_REQUIRE(nvlist_error(test[i]) == 0); 846 } 847 nvl = nvlist_create(0); 848 ATF_REQUIRE(nvl != NULL); 849 nvlist_add_nvlist_array(nvl, "nvl/nvlist_array", test, 5); 850 ATF_REQUIRE(nvlist_error(nvl) == 0); 851 nasted = nvlist_create(0); 852 ATF_REQUIRE(nasted != NULL); 853 nvlist_add_nvlist_array(nasted, "nvl/nvl/nvlist_array", test, 5); 854 ATF_REQUIRE(nvlist_error(nasted) == 0); 855 nvlist_move_nvlist(nvl, "nvl/nvl", nasted); 856 ATF_REQUIRE(nvlist_error(nvl) == 0); 857 nvlist_add_string(nvl, "nvl/string", "END"); 858 ATF_REQUIRE(nvlist_error(nvl) == 0); 859 860 cookie = NULL; 861 index = 0; 862 tmp = travel = nvl; 863 do { 864 do { 865 travel = tmp; 866 while ((name = nvlist_next(travel, &type, &cookie)) != 867 NULL) { 868 if (index == 0) { 869 ATF_REQUIRE(type == 870 NV_TYPE_NVLIST_ARRAY); 871 } else if (index >= 1 && index <= 5) { 872 ATF_REQUIRE(type == NV_TYPE_NUMBER); 873 } else if (index == 6) { 874 ATF_REQUIRE(type == NV_TYPE_NVLIST); 875 } else if (index == 7) { 876 ATF_REQUIRE(type == 877 NV_TYPE_NVLIST_ARRAY); 878 } else if (index >= 8 && index <= 12) { 879 ATF_REQUIRE(type == NV_TYPE_NUMBER); 880 } else if (index == 13) { 881 ATF_REQUIRE(type == NV_TYPE_STRING); 882 } 883 884 if (type == NV_TYPE_NVLIST) { 885 travel = nvlist_get_nvlist(travel, 886 name); 887 cookie = NULL; 888 } else if (type == NV_TYPE_NVLIST_ARRAY) { 889 travel = nvlist_get_nvlist_array(travel, 890 name, NULL)[0]; 891 cookie = NULL; 892 } 893 index ++; 894 } 895 cookie = NULL; 896 } while ((tmp = nvlist_get_array_next(travel)) != NULL); 897 } while ((tmp = nvlist_get_parent(travel, &cookie)) != NULL); 898 899 for (i = 0; i < 5; i++) 900 nvlist_destroy(test[i]); 901 902 nvlist_destroy(nvl); 903 } 904 905 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_bool_array__pack); 906 ATF_TEST_CASE_BODY(nvlist_bool_array__pack) 907 { 908 nvlist_t *nvl, *unpacked; 909 const char *key; 910 size_t packed_size, count; 911 void *packed; 912 unsigned int i; 913 const bool *const_result; 914 bool testbool[16]; 915 916 for (i = 0; i < nitems(testbool); i++) 917 testbool[i] = (i % 2 == 0); 918 919 key = "nvl/bool"; 920 nvl = nvlist_create(0); 921 ATF_REQUIRE(nvl != NULL); 922 ATF_REQUIRE(nvlist_empty(nvl)); 923 ATF_REQUIRE(!nvlist_exists_string_array(nvl, key)); 924 925 nvlist_add_bool_array(nvl, key, testbool, nitems(testbool)); 926 ATF_REQUIRE_EQ(nvlist_error(nvl), 0); 927 ATF_REQUIRE(!nvlist_empty(nvl)); 928 ATF_REQUIRE(nvlist_exists_bool_array(nvl, key)); 929 930 packed = nvlist_pack(nvl, &packed_size); 931 ATF_REQUIRE(packed != NULL); 932 933 unpacked = nvlist_unpack(packed, packed_size, 0); 934 ATF_REQUIRE(unpacked != NULL); 935 ATF_REQUIRE_EQ(nvlist_error(unpacked), 0); 936 ATF_REQUIRE(nvlist_exists_bool_array(unpacked, key)); 937 938 const_result = nvlist_get_bool_array(unpacked, key, &count); 939 ATF_REQUIRE_EQ(count, nitems(testbool)); 940 for (i = 0; i < count; i++) { 941 ATF_REQUIRE_EQ(testbool[i], const_result[i]); 942 } 943 944 nvlist_destroy(nvl); 945 nvlist_destroy(unpacked); 946 free(packed); 947 } 948 949 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_number_array__pack); 950 ATF_TEST_CASE_BODY(nvlist_number_array__pack) 951 { 952 nvlist_t *nvl, *unpacked; 953 const char *key; 954 size_t packed_size, count; 955 void *packed; 956 unsigned int i; 957 const uint64_t *const_result; 958 const uint64_t number[8] = { 0, UINT_MAX, 7, 123, 90, 959 100000, 8, 1 }; 960 961 key = "nvl/number"; 962 nvl = nvlist_create(0); 963 ATF_REQUIRE(nvl != NULL); 964 ATF_REQUIRE(nvlist_empty(nvl)); 965 ATF_REQUIRE(!nvlist_exists_string_array(nvl, key)); 966 967 nvlist_add_number_array(nvl, key, number, 8); 968 ATF_REQUIRE_EQ(nvlist_error(nvl), 0); 969 ATF_REQUIRE(!nvlist_empty(nvl)); 970 ATF_REQUIRE(nvlist_exists_number_array(nvl, key)); 971 972 packed = nvlist_pack(nvl, &packed_size); 973 ATF_REQUIRE(packed != NULL); 974 975 unpacked = nvlist_unpack(packed, packed_size, 0); 976 ATF_REQUIRE(unpacked != NULL); 977 ATF_REQUIRE_EQ(nvlist_error(unpacked), 0); 978 ATF_REQUIRE(nvlist_exists_number_array(unpacked, key)); 979 980 const_result = nvlist_get_number_array(unpacked, key, &count); 981 ATF_REQUIRE_EQ(count, nitems(number)); 982 for (i = 0; i < count; i++) { 983 ATF_REQUIRE_EQ(number[i], const_result[i]); 984 } 985 986 nvlist_destroy(nvl); 987 nvlist_destroy(unpacked); 988 free(packed); 989 } 990 991 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_descriptor_array__pack); 992 ATF_TEST_CASE_BODY(nvlist_descriptor_array__pack) 993 { 994 nvlist_t *nvl; 995 const char *key; 996 size_t num_items; 997 unsigned int i; 998 const int *const_result; 999 int desc[32], fd, socks[2]; 1000 pid_t pid; 1001 1002 key = "nvl/descriptor"; 1003 1004 ATF_REQUIRE_EQ(socketpair(PF_UNIX, SOCK_STREAM, 0, socks), 0); 1005 1006 pid = atf::utils::fork(); 1007 ATF_REQUIRE(pid >= 0); 1008 if (pid == 0) { 1009 /* Child. */ 1010 fd = socks[0]; 1011 close(socks[1]); 1012 for (i = 0; i < nitems(desc); i++) { 1013 desc[i] = dup(STDERR_FILENO); 1014 ATF_REQUIRE(fd_is_valid(desc[i])); 1015 } 1016 1017 nvl = nvlist_create(0); 1018 ATF_REQUIRE(nvl != NULL); 1019 ATF_REQUIRE(nvlist_empty(nvl)); 1020 ATF_REQUIRE(!nvlist_exists_descriptor_array(nvl, key)); 1021 1022 nvlist_add_descriptor_array(nvl, key, desc, nitems(desc)); 1023 ATF_REQUIRE_EQ(nvlist_error(nvl), 0); 1024 ATF_REQUIRE(!nvlist_empty(nvl)); 1025 ATF_REQUIRE(nvlist_exists_descriptor_array(nvl, key)); 1026 1027 ATF_REQUIRE(nvlist_send(fd, nvl) >= 0); 1028 1029 for (i = 0; i < nitems(desc); i++) 1030 close(desc[i]); 1031 } else { 1032 /* Parent */ 1033 fd = socks[1]; 1034 close(socks[0]); 1035 1036 errno = 0; 1037 nvl = nvlist_recv(fd, 0); 1038 ATF_REQUIRE(nvl != NULL); 1039 ATF_REQUIRE_EQ(nvlist_error(nvl), 0); 1040 ATF_REQUIRE(nvlist_exists_descriptor_array(nvl, key)); 1041 1042 const_result = nvlist_get_descriptor_array(nvl, key, &num_items); 1043 ATF_REQUIRE(const_result != NULL); 1044 ATF_REQUIRE_EQ(num_items, nitems(desc)); 1045 for (i = 0; i < num_items; i++) 1046 ATF_REQUIRE(fd_is_valid(const_result[i])); 1047 1048 atf::utils::wait(pid, 0, "", ""); 1049 } 1050 1051 nvlist_destroy(nvl); 1052 close(fd); 1053 } 1054 1055 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_string_array__pack); 1056 ATF_TEST_CASE_BODY(nvlist_string_array__pack) 1057 { 1058 nvlist_t *nvl, *unpacked; 1059 const char *key; 1060 size_t packed_size, count; 1061 void *packed; 1062 unsigned int i; 1063 const char * const *const_result; 1064 const char *string_arr[8] = { "a", "b", "kot", "foo", 1065 "tests", "nice test", "", "abcdef" }; 1066 1067 key = "nvl/string"; 1068 nvl = nvlist_create(0); 1069 ATF_REQUIRE(nvl != NULL); 1070 ATF_REQUIRE(nvlist_empty(nvl)); 1071 ATF_REQUIRE(!nvlist_exists_string_array(nvl, key)); 1072 1073 nvlist_add_string_array(nvl, key, string_arr, nitems(string_arr)); 1074 ATF_REQUIRE_EQ(nvlist_error(nvl), 0); 1075 ATF_REQUIRE(!nvlist_empty(nvl)); 1076 ATF_REQUIRE(nvlist_exists_string_array(nvl, key)); 1077 1078 packed = nvlist_pack(nvl, &packed_size); 1079 ATF_REQUIRE(packed != NULL); 1080 1081 unpacked = nvlist_unpack(packed, packed_size, 0); 1082 ATF_REQUIRE(unpacked != NULL); 1083 ATF_REQUIRE_EQ(nvlist_error(unpacked), 0); 1084 ATF_REQUIRE(nvlist_exists_string_array(unpacked, key)); 1085 1086 const_result = nvlist_get_string_array(unpacked, key, &count); 1087 ATF_REQUIRE_EQ(count, nitems(string_arr)); 1088 for (i = 0; i < count; i++) { 1089 ATF_REQUIRE_EQ(strcmp(string_arr[i], const_result[i]), 0); 1090 } 1091 1092 nvlist_destroy(nvl); 1093 nvlist_destroy(unpacked); 1094 free(packed); 1095 } 1096 1097 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_nvlist_array__pack); 1098 ATF_TEST_CASE_BODY(nvlist_nvlist_array__pack) 1099 { 1100 nvlist_t *testnvl[8], *unpacked; 1101 const nvlist_t * const *const_result; 1102 nvlist_t *nvl; 1103 size_t num_items, packed_size; 1104 unsigned int i; 1105 void *packed; 1106 const char *somestr[8] = { "a", "b", "c", "d", "e", "f", "g", "h" }; 1107 const char *key; 1108 1109 for (i = 0; i < nitems(testnvl); i++) { 1110 testnvl[i] = nvlist_create(0); 1111 ATF_REQUIRE(testnvl[i] != NULL); 1112 ATF_REQUIRE_EQ(nvlist_error(testnvl[i]), 0); 1113 nvlist_add_string(testnvl[i], "nvl/string", somestr[i]); 1114 ATF_REQUIRE_EQ(nvlist_error(testnvl[i]), 0); 1115 ATF_REQUIRE(nvlist_exists_string(testnvl[i], "nvl/string")); 1116 } 1117 1118 key = "nvl/nvlist"; 1119 nvl = nvlist_create(0); 1120 ATF_REQUIRE(nvl != NULL); 1121 ATF_REQUIRE(nvlist_empty(nvl)); 1122 ATF_REQUIRE(!nvlist_exists_string_array(nvl, key)); 1123 1124 nvlist_add_nvlist_array(nvl, key, (const nvlist_t * const *)testnvl, 8); 1125 ATF_REQUIRE_EQ(nvlist_error(nvl), 0); 1126 ATF_REQUIRE(!nvlist_empty(nvl)); 1127 ATF_REQUIRE(nvlist_exists_nvlist_array(nvl, key)); 1128 ATF_REQUIRE(nvlist_exists_nvlist_array(nvl, "nvl/nvlist")); 1129 packed = nvlist_pack(nvl, &packed_size); 1130 ATF_REQUIRE(packed != NULL); 1131 1132 unpacked = nvlist_unpack(packed, packed_size, 0); 1133 ATF_REQUIRE(unpacked != NULL); 1134 ATF_REQUIRE_EQ(nvlist_error(unpacked), 0); 1135 ATF_REQUIRE(nvlist_exists_nvlist_array(unpacked, key)); 1136 1137 const_result = nvlist_get_nvlist_array(unpacked, key, &num_items); 1138 ATF_REQUIRE(const_result != NULL); 1139 ATF_REQUIRE_EQ(num_items, nitems(testnvl)); 1140 for (i = 0; i < num_items; i++) { 1141 ATF_REQUIRE_EQ(nvlist_error(const_result[i]), 0); 1142 if (i < num_items - 1) { 1143 ATF_REQUIRE(nvlist_get_array_next(const_result[i]) == 1144 const_result[i + 1]); 1145 } else { 1146 ATF_REQUIRE(nvlist_get_array_next(const_result[i]) == 1147 NULL); 1148 } 1149 ATF_REQUIRE(nvlist_get_parent(const_result[i], NULL) == unpacked); 1150 ATF_REQUIRE(nvlist_in_array(const_result[i])); 1151 ATF_REQUIRE(nvlist_exists_string(const_result[i], 1152 "nvl/string")); 1153 ATF_REQUIRE(strcmp(nvlist_get_string(const_result[i], 1154 "nvl/string"), somestr[i]) == 0); 1155 } 1156 1157 for (i = 0; i < nitems(testnvl); i++) 1158 nvlist_destroy(testnvl[i]); 1159 nvlist_destroy(nvl); 1160 nvlist_destroy(unpacked); 1161 free(packed); 1162 } 1163 1164 1165 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_string_array_nonull__pack); 1166 ATF_TEST_CASE_BODY(nvlist_string_array_nonull__pack) 1167 { 1168 nvlist_t *testnvl, *unpacked; 1169 const char *somestr[3] = { "a", "b", "XXX" }; 1170 uint8_t *packed, *twopages, *dataptr, *secondpage; 1171 size_t packed_size, page_size; 1172 bool found; 1173 1174 page_size = sysconf(_SC_PAGESIZE); 1175 testnvl = nvlist_create(0); 1176 ATF_REQUIRE(testnvl != NULL); 1177 ATF_REQUIRE_EQ(nvlist_error(testnvl), 0); 1178 nvlist_add_string_array(testnvl, "nvl/string", somestr, 1179 nitems(somestr)); 1180 ATF_REQUIRE_EQ(nvlist_error(testnvl), 0); 1181 1182 packed = (uint8_t *)nvlist_pack(testnvl, &packed_size); 1183 ATF_REQUIRE(packed != NULL); 1184 1185 twopages = (uint8_t *)mmap(NULL, page_size * 2, PROT_READ | PROT_WRITE, 1186 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 1187 ATF_REQUIRE(twopages != MAP_FAILED); 1188 dataptr = &twopages[page_size - packed_size]; 1189 secondpage = &twopages[page_size]; 1190 1191 memset(twopages, 'A', page_size * 2); 1192 1193 mprotect(secondpage, page_size, PROT_NONE); 1194 memcpy(dataptr, packed, packed_size); 1195 1196 found = false; 1197 for (size_t i = 0; i < packed_size - 3; i++) { 1198 if (dataptr[i] == 'X' && dataptr[i + 1] == 'X' && 1199 dataptr[i + 2] == 'X' && dataptr[i + 3] == '\0') { 1200 dataptr[i + 3] = 'X'; 1201 found = true; 1202 break; 1203 } 1204 } 1205 ATF_REQUIRE(found == true); 1206 1207 unpacked = nvlist_unpack(dataptr, packed_size, 0); 1208 ATF_REQUIRE(unpacked == NULL); 1209 1210 nvlist_destroy(testnvl); 1211 free(packed); 1212 munmap(twopages, page_size * 2); 1213 } 1214 1215 1216 ATF_INIT_TEST_CASES(tp) 1217 { 1218 1219 ATF_ADD_TEST_CASE(tp, nvlist_bool_array__basic); 1220 ATF_ADD_TEST_CASE(tp, nvlist_string_array__basic); 1221 ATF_ADD_TEST_CASE(tp, nvlist_descriptor_array__basic); 1222 ATF_ADD_TEST_CASE(tp, nvlist_number_array__basic); 1223 ATF_ADD_TEST_CASE(tp, nvlist_nvlist_array__basic) 1224 1225 ATF_ADD_TEST_CASE(tp, nvlist_clone_array) 1226 1227 ATF_ADD_TEST_CASE(tp, nvlist_bool_array__move); 1228 ATF_ADD_TEST_CASE(tp, nvlist_string_array__move); 1229 ATF_ADD_TEST_CASE(tp, nvlist_nvlist_array__move); 1230 ATF_ADD_TEST_CASE(tp, nvlist_number_array__move); 1231 ATF_ADD_TEST_CASE(tp, nvlist_descriptor_array__move); 1232 1233 ATF_ADD_TEST_CASE(tp, nvlist_arrays__error_null); 1234 1235 ATF_ADD_TEST_CASE(tp, nvlist_arrays__bad_value) 1236 1237 ATF_ADD_TEST_CASE(tp, nvlist_nvlist_array__travel) 1238 ATF_ADD_TEST_CASE(tp, nvlist_nvlist_array__travel_alternative) 1239 1240 ATF_ADD_TEST_CASE(tp, nvlist_bool_array__pack) 1241 ATF_ADD_TEST_CASE(tp, nvlist_number_array__pack) 1242 ATF_ADD_TEST_CASE(tp, nvlist_descriptor_array__pack) 1243 ATF_ADD_TEST_CASE(tp, nvlist_string_array__pack) 1244 ATF_ADD_TEST_CASE(tp, nvlist_nvlist_array__pack) 1245 1246 ATF_ADD_TEST_CASE(tp, nvlist_string_array_nonull__pack) 1247 } 1248 1249