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