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