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);
ATF_TEST_CASE_BODY(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);
ATF_TEST_CASE_BODY(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);
ATF_TEST_CASE_BODY(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);
ATF_TEST_CASE_BODY(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);
ATF_TEST_CASE_BODY(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);
ATF_TEST_CASE_BODY(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);
ATF_TEST_CASE_BODY(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);
ATF_TEST_CASE_BODY(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);
ATF_TEST_CASE_BODY(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);
ATF_TEST_CASE_BODY(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);
ATF_TEST_CASE_BODY(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);
ATF_TEST_CASE_BODY(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);
ATF_TEST_CASE_BODY(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);
ATF_TEST_CASE_BODY(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);
ATF_TEST_CASE_BODY(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);
ATF_TEST_CASE_BODY(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);
ATF_TEST_CASE_BODY(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);
ATF_TEST_CASE_BODY(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);
ATF_TEST_CASE_BODY(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);
ATF_TEST_CASE_BODY(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);
ATF_TEST_CASE_BODY(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
ATF_INIT_TEST_CASES(tp)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