xref: /freebsd/lib/libnv/tests/nv_array_tests.cc (revision 49b49cda41feabe3439f7318e8bf40e3896c7bf4)
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_array_next(const_result[i]) == NULL);
316 		ATF_REQUIRE(!nvlist_in_array(const_result[i]));
317 	}
318 
319 	ATF_REQUIRE(!nvlist_exists_string_array(nvl, key));
320 	ATF_REQUIRE(nvlist_empty(nvl));
321 	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
322 
323 	for (i = 0; i < 8; i++) {
324 		nvlist_destroy(result[i]);
325 		nvlist_destroy(testnvl[i]);
326 	}
327 
328 	free(result);
329 	nvlist_destroy(nvl);
330 }
331 
332 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_clone_array);
333 ATF_TEST_CASE_BODY(nvlist_clone_array)
334 {
335 	nvlist_t *testnvl[8];
336 	nvlist_t *src, *dst;
337 	const nvlist_t *nvl;
338 	bool testbool[16];
339 	int testfd[16];
340 	size_t i, num_items;
341 	const char *string_arr[8] = { "a", "b", "kot", "foo",
342 	    "tests", "nice test", "", "abcdef" };
343 	const char *somestr[8] = { "a", "b", "c", "d", "e", "f", "g", "h" };
344 	const uint64_t number[8] = { 0, UINT_MAX, 7, 123, 90,
345 	    100000, 8, 1 };
346 
347 	for (i = 0; i < nitems(testfd); i++) {
348 		testbool[i] = (i % 2 == 0);
349 		testfd[i] = dup(STDERR_FILENO);
350 		ATF_REQUIRE(fd_is_valid(testfd[i]));
351 	}
352 	for (i = 0; i < nitems(testnvl); i++) {
353 		testnvl[i] = nvlist_create(0);
354 		ATF_REQUIRE(nvlist_error(testnvl[i]) == 0);
355 		nvlist_add_string(testnvl[i], "nvl/nvl/teststr", somestr[i]);
356 		ATF_REQUIRE(nvlist_error(testnvl[i]) == 0);
357 	}
358 
359 	src = nvlist_create(0);
360 	ATF_REQUIRE(nvlist_error(src) == 0);
361 
362 	ATF_REQUIRE(!nvlist_exists_bool_array(src, "nvl/bool"));
363 	nvlist_add_bool_array(src, "nvl/bool", testbool, nitems(testbool));
364 	ATF_REQUIRE_EQ(nvlist_error(src), 0);
365 	ATF_REQUIRE(nvlist_exists_bool_array(src, "nvl/bool"));
366 
367 	ATF_REQUIRE(!nvlist_exists_string_array(src, "nvl/string"));
368 	nvlist_add_string_array(src, "nvl/string", string_arr,
369 	    nitems(string_arr));
370 	ATF_REQUIRE_EQ(nvlist_error(src), 0);
371 	ATF_REQUIRE(nvlist_exists_string_array(src, "nvl/string"));
372 
373 	ATF_REQUIRE(!nvlist_exists_descriptor_array(src, "nvl/fd"));
374 	nvlist_add_descriptor_array(src, "nvl/fd", testfd, nitems(testfd));
375 	ATF_REQUIRE_EQ(nvlist_error(src), 0);
376 	ATF_REQUIRE(nvlist_exists_descriptor_array(src, "nvl/fd"));
377 
378 	ATF_REQUIRE(!nvlist_exists_number_array(src, "nvl/number"));
379 	nvlist_add_number_array(src, "nvl/number", number,
380 	    nitems(number));
381 	ATF_REQUIRE_EQ(nvlist_error(src), 0);
382 	ATF_REQUIRE(nvlist_exists_number_array(src, "nvl/number"));
383 
384 	ATF_REQUIRE(!nvlist_exists_nvlist_array(src, "nvl/array"));
385 	nvlist_add_nvlist_array(src, "nvl/array",
386 	    (const nvlist_t * const *)testnvl, nitems(testnvl));
387 	ATF_REQUIRE_EQ(nvlist_error(src), 0);
388 	ATF_REQUIRE(nvlist_exists_nvlist_array(src, "nvl/array"));
389 
390 	dst = nvlist_clone(src);
391 	ATF_REQUIRE(dst != NULL);
392 
393 	ATF_REQUIRE(nvlist_exists_bool_array(dst, "nvl/bool"));
394 	(void) nvlist_get_bool_array(dst, "nvl/bool", &num_items);
395 	ATF_REQUIRE_EQ(num_items, nitems(testbool));
396 	for (i = 0; i < num_items; i++) {
397 		ATF_REQUIRE(
398 		    nvlist_get_bool_array(dst, "nvl/bool", &num_items)[i] ==
399 		    nvlist_get_bool_array(src, "nvl/bool", &num_items)[i]);
400 	}
401 
402 	ATF_REQUIRE(nvlist_exists_string_array(dst, "nvl/string"));
403 	(void) nvlist_get_string_array(dst, "nvl/string", &num_items);
404 	ATF_REQUIRE_EQ(num_items, nitems(string_arr));
405 	for (i = 0; i < num_items; i++) {
406 		if (nvlist_get_string_array(dst, "nvl/string",
407 		    &num_items)[i] == NULL) {
408 			ATF_REQUIRE(nvlist_get_string_array(dst, "nvl/string",
409 			    &num_items)[i] == nvlist_get_string_array(src,
410 			    "nvl/string", &num_items)[i]);
411 		} else {
412 			ATF_REQUIRE(strcmp(nvlist_get_string_array(dst,
413 			    "nvl/string", &num_items)[i], nvlist_get_string_array(
414 			    src, "nvl/string", &num_items)[i]) == 0);
415 		}
416 	}
417 
418 	ATF_REQUIRE(nvlist_exists_descriptor_array(dst, "nvl/fd"));
419 	(void) nvlist_get_descriptor_array(dst, "nvl/fd", &num_items);
420 	ATF_REQUIRE_EQ(num_items, nitems(testfd));
421 	for (i = 0; i < num_items; i++) {
422 		ATF_REQUIRE(fd_is_valid(
423 		    nvlist_get_descriptor_array(dst, "nvl/fd", &num_items)[i]));
424 	}
425 	ATF_REQUIRE(nvlist_exists_number_array(dst, "nvl/number"));
426 	(void) nvlist_get_number_array(dst, "nvl/number", &num_items);
427 	ATF_REQUIRE_EQ(num_items, nitems(number));
428 
429 	for (i = 0; i < num_items; i++) {
430 		ATF_REQUIRE(
431 		    nvlist_get_number_array(dst, "nvl/number", &num_items)[i] ==
432 		    nvlist_get_number_array(src, "nvl/number", &num_items)[i]);
433 	}
434 
435 	ATF_REQUIRE(nvlist_exists_nvlist_array(dst, "nvl/array"));
436 	(void) nvlist_get_nvlist_array(dst, "nvl/array", &num_items);
437 	ATF_REQUIRE_EQ(num_items, nitems(testnvl));
438 	for (i = 0; i < num_items; i++) {
439 		nvl = nvlist_get_nvlist_array(dst, "nvl/array", &num_items)[i];
440 		ATF_REQUIRE(nvlist_exists_string(nvl, "nvl/nvl/teststr"));
441 		ATF_REQUIRE(strcmp(nvlist_get_string(nvl, "nvl/nvl/teststr"),
442 		    somestr[i]) == 0);
443 	}
444 
445 	for (i = 0; i < nitems(testfd); i++) {
446 		close(testfd[i]);
447 	}
448 	for (i = 0; i < nitems(testnvl); i++) {
449 		nvlist_destroy(testnvl[i]);
450 	}
451 	nvlist_destroy(src);
452 	nvlist_destroy(dst);
453 }
454 
455 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_bool_array__move);
456 ATF_TEST_CASE_BODY(nvlist_bool_array__move)
457 {
458 	bool *testbool;
459 	const bool *const_result;
460 	nvlist_t *nvl;
461 	size_t num_items, count;
462 	unsigned int i;
463 	const char *key;
464 
465 	key = "nvl/bool";
466 	nvl = nvlist_create(0);
467 	ATF_REQUIRE(nvl != NULL);
468 	ATF_REQUIRE(nvlist_empty(nvl));
469 	ATF_REQUIRE(!nvlist_exists_string_array(nvl, key));
470 
471 	count = 16;
472 	testbool = (bool*)malloc(sizeof(*testbool) * count);
473 	ATF_REQUIRE(testbool != NULL);
474 	for (i = 0; i < count; i++)
475 		testbool[i] = (i % 2 == 0);
476 
477 	nvlist_move_bool_array(nvl, key, testbool, count);
478 	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
479 	ATF_REQUIRE(!nvlist_empty(nvl));
480 	ATF_REQUIRE(nvlist_exists_bool_array(nvl, key));
481 
482 	const_result = nvlist_get_bool_array(nvl, key, &num_items);
483 	ATF_REQUIRE_EQ(num_items, count);
484 	ATF_REQUIRE(const_result != NULL);
485 	ATF_REQUIRE(const_result == testbool);
486 	for (i = 0; i < num_items; i++)
487 		ATF_REQUIRE_EQ(const_result[i], (i % 2 == 0));
488 
489 	nvlist_destroy(nvl);
490 }
491 
492 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_string_array__move);
493 ATF_TEST_CASE_BODY(nvlist_string_array__move)
494 {
495 	char **teststr;
496 	const char * const *const_result;
497 	nvlist_t *nvl;
498 	size_t num_items, count;
499 	unsigned int i;
500 	const char *key;
501 
502 	key = "nvl/string";
503 	nvl = nvlist_create(0);
504 	ATF_REQUIRE(nvl != NULL);
505 	ATF_REQUIRE(nvlist_empty(nvl));
506 	ATF_REQUIRE(!nvlist_exists_string_array(nvl, key));
507 
508 	count = 26;
509 	teststr = (char**)malloc(sizeof(*teststr) * count);
510 	ATF_REQUIRE(teststr != NULL);
511 	for (i = 0; i < count; i++) {
512 		teststr[i] = (char*)malloc(sizeof(**teststr) * 2);
513 		ATF_REQUIRE(teststr[i] != NULL);
514 		teststr[i][0] = 'a' + i;
515 		teststr[i][1] = '\0';
516 	}
517 
518 	nvlist_move_string_array(nvl, key, teststr, count);
519 	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
520 	ATF_REQUIRE(!nvlist_empty(nvl));
521 	ATF_REQUIRE(nvlist_exists_string_array(nvl, key));
522 
523 	const_result = nvlist_get_string_array(nvl, key, &num_items);
524 	ATF_REQUIRE_EQ(num_items, count);
525 	ATF_REQUIRE(const_result != NULL);
526 	ATF_REQUIRE((intptr_t)const_result == (intptr_t)teststr);
527 	for (i = 0; i < num_items; i++) {
528 		ATF_REQUIRE_EQ(const_result[i][0], (char)('a' + i));
529 		ATF_REQUIRE_EQ(const_result[i][1], '\0');
530 	}
531 
532 	nvlist_destroy(nvl);
533 }
534 
535 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_nvlist_array__move);
536 ATF_TEST_CASE_BODY(nvlist_nvlist_array__move)
537 {
538 	nvlist **testnv;
539 	const nvlist * const *const_result;
540 	nvlist_t *nvl;
541 	size_t num_items, count;
542 	unsigned int i;
543 	const char *key;
544 
545 	key = "nvl/nvlist";
546 	nvl = nvlist_create(0);
547 	ATF_REQUIRE(nvl != NULL);
548 	ATF_REQUIRE(nvlist_empty(nvl));
549 	ATF_REQUIRE(!nvlist_exists_nvlist_array(nvl, key));
550 
551 	count = 26;
552 	testnv = (nvlist**)malloc(sizeof(*testnv) * count);
553 	ATF_REQUIRE(testnv != NULL);
554 	for (i = 0; i < count; i++) {
555 		testnv[i] = nvlist_create(0);
556 		ATF_REQUIRE(testnv[i] != NULL);
557 	}
558 
559 	nvlist_move_nvlist_array(nvl, key, testnv, count);
560 	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
561 	ATF_REQUIRE(!nvlist_empty(nvl));
562 	ATF_REQUIRE(nvlist_exists_nvlist_array(nvl, key));
563 
564 	const_result = nvlist_get_nvlist_array(nvl, key, &num_items);
565 	ATF_REQUIRE_EQ(num_items, count);
566 	ATF_REQUIRE(const_result != NULL);
567 	ATF_REQUIRE((intptr_t)const_result == (intptr_t)testnv);
568 	for (i = 0; i < num_items; i++) {
569 		ATF_REQUIRE_EQ(nvlist_error(const_result[i]), 0);
570 		ATF_REQUIRE(nvlist_empty(const_result[i]));
571 		if (i < num_items - 1) {
572 			ATF_REQUIRE(nvlist_get_array_next(const_result[i]) ==
573 			    const_result[i + 1]);
574 		} else {
575 			ATF_REQUIRE(nvlist_get_array_next(const_result[i]) ==
576 			    NULL);
577 		}
578 		ATF_REQUIRE(nvlist_get_parent(const_result[i], NULL) == nvl);
579 		ATF_REQUIRE(nvlist_in_array(const_result[i]));
580 	}
581 
582 	nvlist_destroy(nvl);
583 }
584 
585 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_number_array__move);
586 ATF_TEST_CASE_BODY(nvlist_number_array__move)
587 {
588 	uint64_t *testnumber;
589 	const uint64_t *const_result;
590 	nvlist_t *nvl;
591 	size_t num_items, count;
592 	unsigned int i;
593 	const char *key;
594 
595 	key = "nvl/number";
596 	nvl = nvlist_create(0);
597 	ATF_REQUIRE(nvl != NULL);
598 	ATF_REQUIRE(nvlist_empty(nvl));
599 	ATF_REQUIRE(!nvlist_exists_string_array(nvl, key));
600 
601 	count = 1000;
602 	testnumber = (uint64_t*)malloc(sizeof(*testnumber) * count);
603 	ATF_REQUIRE(testnumber != NULL);
604 	for (i = 0; i < count; i++)
605 		testnumber[i] = i;
606 
607 	nvlist_move_number_array(nvl, key, testnumber, count);
608 	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
609 	ATF_REQUIRE(!nvlist_empty(nvl));
610 	ATF_REQUIRE(nvlist_exists_number_array(nvl, key));
611 
612 	const_result = nvlist_get_number_array(nvl, key, &num_items);
613 	ATF_REQUIRE_EQ(num_items, count);
614 	ATF_REQUIRE(const_result != NULL);
615 	ATF_REQUIRE(const_result == testnumber);
616 	for (i = 0; i < num_items; i++)
617 		ATF_REQUIRE_EQ(const_result[i], i);
618 
619 	nvlist_destroy(nvl);
620 }
621 
622 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_descriptor_array__move);
623 ATF_TEST_CASE_BODY(nvlist_descriptor_array__move)
624 {
625 	int *testfd;
626 	const int *const_result;
627 	nvlist_t *nvl;
628 	size_t num_items, count;
629 	unsigned int i;
630 	const char *key;
631 
632 	key = "nvl/fd";
633 	nvl = nvlist_create(0);
634 	ATF_REQUIRE(nvl != NULL);
635 	ATF_REQUIRE(nvlist_empty(nvl));
636 	ATF_REQUIRE(!nvlist_exists_string_array(nvl, key));
637 
638 	count = 50;
639 	testfd = (int*)malloc(sizeof(*testfd) * count);
640 	ATF_REQUIRE(testfd != NULL);
641 	for (i = 0; i < count; i++) {
642 		testfd[i] = dup(STDERR_FILENO);
643 		ATF_REQUIRE(fd_is_valid(testfd[i]));
644 	}
645 
646 	nvlist_move_descriptor_array(nvl, key, testfd, count);
647 	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
648 	ATF_REQUIRE(!nvlist_empty(nvl));
649 	ATF_REQUIRE(nvlist_exists_descriptor_array(nvl, key));
650 
651 	const_result = nvlist_get_descriptor_array(nvl, key, &num_items);
652 	ATF_REQUIRE_EQ(num_items, count);
653 	ATF_REQUIRE(const_result != NULL);
654 	ATF_REQUIRE(const_result == testfd);
655 	for (i = 0; i < num_items; i++)
656 		ATF_REQUIRE(fd_is_valid(const_result[i]));
657 
658 	nvlist_destroy(nvl);
659 }
660 
661 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_arrays__error_null);
662 ATF_TEST_CASE_BODY(nvlist_arrays__error_null)
663 {
664 	nvlist_t *nvl;
665 
666 	nvl = nvlist_create(0);
667 	ATF_REQUIRE(nvl != NULL);
668 	nvlist_add_number_array(nvl, "nvl/number", NULL, 0);
669 	ATF_REQUIRE(nvlist_error(nvl) != 0);
670 	nvlist_destroy(nvl);
671 
672 	nvl = nvlist_create(0);
673 	ATF_REQUIRE(nvl != NULL);
674 	nvlist_move_number_array(nvl, "nvl/number", NULL, 0);
675 	ATF_REQUIRE(nvlist_error(nvl) != 0);
676 	nvlist_destroy(nvl);
677 
678 	nvl = nvlist_create(0);
679 	ATF_REQUIRE(nvl != NULL);
680 	nvlist_add_descriptor_array(nvl, "nvl/fd", NULL, 0);
681 	ATF_REQUIRE(nvlist_error(nvl) != 0);
682 	nvlist_destroy(nvl);
683 
684 	nvl = nvlist_create(0);
685 	ATF_REQUIRE(nvl != NULL);
686 	nvlist_move_descriptor_array(nvl, "nvl/fd", NULL, 0);
687 	ATF_REQUIRE(nvlist_error(nvl) != 0);
688 	nvlist_destroy(nvl);
689 
690 	nvl = nvlist_create(0);
691 	ATF_REQUIRE(nvl != NULL);
692 	nvlist_add_string_array(nvl, "nvl/string", NULL, 0);
693 	ATF_REQUIRE(nvlist_error(nvl) != 0);
694 	nvlist_destroy(nvl);
695 
696 	nvl = nvlist_create(0);
697 	ATF_REQUIRE(nvl != NULL);
698 	nvlist_move_string_array(nvl, "nvl/string", NULL, 0);
699 	ATF_REQUIRE(nvlist_error(nvl) != 0);
700 	nvlist_destroy(nvl);
701 
702 	nvl = nvlist_create(0);
703 	ATF_REQUIRE(nvl != NULL);
704 	nvlist_add_nvlist_array(nvl, "nvl/nvlist", NULL, 0);
705 	ATF_REQUIRE(nvlist_error(nvl) != 0);
706 	nvlist_destroy(nvl);
707 
708 	nvl = nvlist_create(0);
709 	ATF_REQUIRE(nvl != NULL);
710 	nvlist_move_nvlist_array(nvl, "nvl/nvlist", NULL, 0);
711 	ATF_REQUIRE(nvlist_error(nvl) != 0);
712 	nvlist_destroy(nvl);
713 
714 	nvl = nvlist_create(0);
715 	ATF_REQUIRE(nvl != NULL);
716 	nvlist_add_bool_array(nvl, "nvl/bool", NULL, 0);
717 	ATF_REQUIRE(nvlist_error(nvl) != 0);
718 	nvlist_destroy(nvl);
719 
720 	nvl = nvlist_create(0);
721 	ATF_REQUIRE(nvl != NULL);
722 	nvlist_move_bool_array(nvl, "nvl/bool", NULL, 0);
723 	ATF_REQUIRE(nvlist_error(nvl) != 0);
724 	nvlist_destroy(nvl);
725 }
726 
727 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_arrays__bad_value);
728 ATF_TEST_CASE_BODY(nvlist_arrays__bad_value)
729 {
730 	nvlist_t *nvl, *nvladd[1], **nvlmove;
731 	int fdadd[1], *fdmove;
732 
733 	nvladd[0] = NULL;
734 	nvl = nvlist_create(0);
735 	ATF_REQUIRE(nvl != NULL);
736 	nvlist_add_nvlist_array(nvl, "nvl/nvlist", nvladd, 1);
737 	ATF_REQUIRE(nvlist_error(nvl) != 0);
738 	nvlist_destroy(nvl);
739 
740 	nvlmove = (nvlist_t**)malloc(sizeof(*nvlmove));
741 	ATF_REQUIRE(nvlmove != NULL);
742 	nvlmove[0] = NULL;
743 	nvl = nvlist_create(0);
744 	ATF_REQUIRE(nvl != NULL);
745 	nvlist_move_nvlist_array(nvl, "nvl/nvlist", nvlmove, 1);
746 	ATF_REQUIRE(nvlist_error(nvl) != 0);
747 	nvlist_destroy(nvl);
748 
749 	fdadd[0] = -2;
750 	nvl = nvlist_create(0);
751 	ATF_REQUIRE(nvl != NULL);
752 	nvlist_add_descriptor_array(nvl, "nvl/fd", fdadd, 1);
753 	ATF_REQUIRE(nvlist_error(nvl) != 0);
754 	nvlist_destroy(nvl);
755 
756 	fdmove = (int*)malloc(sizeof(*fdmove));
757 	ATF_REQUIRE(fdmove != NULL);
758 	fdmove[0] = -2;
759 	nvl = nvlist_create(0);
760 	ATF_REQUIRE(nvl != NULL);
761 	nvlist_move_descriptor_array(nvl, "nvl/fd", fdmove, 1);
762 	ATF_REQUIRE(nvlist_error(nvl) != 0);
763 	nvlist_destroy(nvl);
764 }
765 
766 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_nvlist_array__travel);
767 ATF_TEST_CASE_BODY(nvlist_nvlist_array__travel)
768 {
769 	nvlist_t *nvl, *test[5], *nasted;
770 	const nvlist_t *travel;
771 	const char *name;
772 	void *cookie;
773 	int type;
774 	unsigned int i, index;
775 
776 	for (i = 0; i < nitems(test); i++) {
777 		test[i] = nvlist_create(0);
778 		ATF_REQUIRE(test[i] != NULL);
779 		nvlist_add_number(test[i], "nvl/number", i);
780 		ATF_REQUIRE(nvlist_error(test[i]) == 0);
781 	}
782 	nvl = nvlist_create(0);
783 	ATF_REQUIRE(nvl != NULL);
784 	nvlist_add_nvlist_array(nvl, "nvl/nvlist_array", test, nitems(test));
785 	ATF_REQUIRE(nvlist_error(nvl) == 0);
786 	nasted = nvlist_create(0);
787 	ATF_REQUIRE(nasted != NULL);
788 	nvlist_add_nvlist_array(nasted, "nvl/nvl/nvlist_array", test,
789 	    nitems(test));
790 	ATF_REQUIRE(nvlist_error(nasted) == 0);
791 	nvlist_move_nvlist(nvl, "nvl/nvl", nasted);
792 	ATF_REQUIRE(nvlist_error(nvl) == 0);
793 	nvlist_add_string(nvl, "nvl/string", "END");
794 	ATF_REQUIRE(nvlist_error(nvl) == 0);
795 
796 	cookie = NULL;
797 	index = 0;
798 	travel = nvl;
799 	do {
800 		while ((name = nvlist_next(travel, &type, &cookie)) != NULL) {
801 			if (index == 0) {
802 				ATF_REQUIRE(type == NV_TYPE_NVLIST_ARRAY);
803 			} else if (index >= 1 && index <= nitems(test)) {
804 				ATF_REQUIRE(type == NV_TYPE_NUMBER);
805 			} else if (index == nitems(test) + 1) {
806 				ATF_REQUIRE(type == NV_TYPE_NVLIST);
807 			} else if (index == nitems(test) + 2) {
808 				ATF_REQUIRE(type == NV_TYPE_NVLIST_ARRAY);
809 			} else if (index >= nitems(test) + 3 &&
810 				   index <= 2 * nitems(test) + 2) {
811 				ATF_REQUIRE(type == NV_TYPE_NUMBER);
812 			} else if (index == 2 * nitems(test) + 3) {
813 				ATF_REQUIRE(type == NV_TYPE_STRING);
814 			}
815 
816 			if (type == NV_TYPE_NVLIST) {
817 				travel = nvlist_get_nvlist(travel, name);
818 				cookie = NULL;
819 			} else if (type == NV_TYPE_NVLIST_ARRAY) {
820 				travel = nvlist_get_nvlist_array(travel, name,
821 				    NULL)[0];
822 				cookie = NULL;
823 			}
824 			index ++;
825 		}
826 	} while ((travel = nvlist_get_pararr(travel, &cookie)) != NULL);
827 
828 	for (i = 0; i < nitems(test); i++)
829 		nvlist_destroy(test[i]);
830 
831 	nvlist_destroy(nvl);
832 }
833 
834 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_nvlist_array__travel_alternative);
835 ATF_TEST_CASE_BODY(nvlist_nvlist_array__travel_alternative)
836 {
837 	nvlist_t *nvl, *test[5], *nasted;
838 	const nvlist_t *travel, *tmp;
839 	void *cookie;
840 	int index, i, type;
841 	const char *name;
842 
843 	for (i = 0; i < 5; i++) {
844 		test[i] = nvlist_create(0);
845 		ATF_REQUIRE(test[i] != NULL);
846 		nvlist_add_number(test[i], "nvl/number", i);
847 		ATF_REQUIRE(nvlist_error(test[i]) == 0);
848 	}
849 	nvl = nvlist_create(0);
850 	ATF_REQUIRE(nvl != NULL);
851 	nvlist_add_nvlist_array(nvl, "nvl/nvlist_array", test, 5);
852 	ATF_REQUIRE(nvlist_error(nvl) == 0);
853 	nasted = nvlist_create(0);
854 	ATF_REQUIRE(nasted != NULL);
855 	nvlist_add_nvlist_array(nasted, "nvl/nvl/nvlist_array", test, 5);
856 	ATF_REQUIRE(nvlist_error(nasted) == 0);
857 	nvlist_move_nvlist(nvl, "nvl/nvl", nasted);
858 	ATF_REQUIRE(nvlist_error(nvl) == 0);
859 	nvlist_add_string(nvl, "nvl/string", "END");
860 	ATF_REQUIRE(nvlist_error(nvl) == 0);
861 
862 	cookie = NULL;
863 	index = 0;
864 	tmp = travel = nvl;
865 	do {
866 		do {
867 			travel = tmp;
868 			while ((name = nvlist_next(travel, &type, &cookie)) !=
869 			    NULL) {
870 				if (index == 0) {
871 					ATF_REQUIRE(type ==
872 					    NV_TYPE_NVLIST_ARRAY);
873 				} else if (index >= 1 && index <= 5) {
874 					ATF_REQUIRE(type == NV_TYPE_NUMBER);
875 				} else if (index == 6) {
876 					ATF_REQUIRE(type == NV_TYPE_NVLIST);
877 				} else if (index == 7) {
878 					ATF_REQUIRE(type ==
879 					    NV_TYPE_NVLIST_ARRAY);
880 				} else if (index >= 8 && index <= 12) {
881 					ATF_REQUIRE(type == NV_TYPE_NUMBER);
882 				} else if (index == 13) {
883 					ATF_REQUIRE(type == NV_TYPE_STRING);
884 				}
885 
886 				if (type == NV_TYPE_NVLIST) {
887 					travel = nvlist_get_nvlist(travel,
888 					    name);
889 					cookie = NULL;
890 				} else if (type == NV_TYPE_NVLIST_ARRAY) {
891 					travel = nvlist_get_nvlist_array(travel,
892 					    name, NULL)[0];
893 					cookie = NULL;
894 				}
895 				index ++;
896 			}
897 			cookie = NULL;
898 		} while ((tmp = nvlist_get_array_next(travel)) != NULL);
899 	} while ((tmp = nvlist_get_parent(travel, &cookie)) != NULL);
900 
901 	for (i = 0; i < 5; i++)
902 		nvlist_destroy(test[i]);
903 
904 	nvlist_destroy(nvl);
905 }
906 
907 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_bool_array__pack);
908 ATF_TEST_CASE_BODY(nvlist_bool_array__pack)
909 {
910 	nvlist_t *nvl, *unpacked;
911 	const char *key;
912 	size_t packed_size, count;
913 	void *packed;
914 	unsigned int i;
915 	const bool *const_result;
916 	bool testbool[16];
917 
918 	for (i = 0; i < nitems(testbool); i++)
919 		testbool[i] = (i % 2 == 0);
920 
921 	key = "nvl/bool";
922 	nvl = nvlist_create(0);
923 	ATF_REQUIRE(nvl != NULL);
924 	ATF_REQUIRE(nvlist_empty(nvl));
925 	ATF_REQUIRE(!nvlist_exists_string_array(nvl, key));
926 
927 	nvlist_add_bool_array(nvl, key, testbool, nitems(testbool));
928 	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
929 	ATF_REQUIRE(!nvlist_empty(nvl));
930 	ATF_REQUIRE(nvlist_exists_bool_array(nvl, key));
931 
932 	packed = nvlist_pack(nvl, &packed_size);
933 	ATF_REQUIRE(packed != NULL);
934 
935 	unpacked = nvlist_unpack(packed, packed_size, 0);
936 	ATF_REQUIRE(unpacked != NULL);
937 	ATF_REQUIRE_EQ(nvlist_error(unpacked), 0);
938 	ATF_REQUIRE(nvlist_exists_bool_array(unpacked, key));
939 
940 	const_result = nvlist_get_bool_array(unpacked, key, &count);
941 	ATF_REQUIRE_EQ(count, nitems(testbool));
942 	for (i = 0; i < count; i++) {
943 		ATF_REQUIRE_EQ(testbool[i], const_result[i]);
944 	}
945 
946 	nvlist_destroy(nvl);
947 	nvlist_destroy(unpacked);
948 	free(packed);
949 }
950 
951 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_number_array__pack);
952 ATF_TEST_CASE_BODY(nvlist_number_array__pack)
953 {
954 	nvlist_t *nvl, *unpacked;
955 	const char *key;
956 	size_t packed_size, count;
957 	void *packed;
958 	unsigned int i;
959 	const uint64_t *const_result;
960 	const uint64_t number[8] = { 0, UINT_MAX, 7, 123, 90,
961 	    100000, 8, 1 };
962 
963 	key = "nvl/number";
964 	nvl = nvlist_create(0);
965 	ATF_REQUIRE(nvl != NULL);
966 	ATF_REQUIRE(nvlist_empty(nvl));
967 	ATF_REQUIRE(!nvlist_exists_string_array(nvl, key));
968 
969 	nvlist_add_number_array(nvl, key, number, 8);
970 	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
971 	ATF_REQUIRE(!nvlist_empty(nvl));
972 	ATF_REQUIRE(nvlist_exists_number_array(nvl, key));
973 
974 	packed = nvlist_pack(nvl, &packed_size);
975 	ATF_REQUIRE(packed != NULL);
976 
977 	unpacked = nvlist_unpack(packed, packed_size, 0);
978 	ATF_REQUIRE(unpacked != NULL);
979 	ATF_REQUIRE_EQ(nvlist_error(unpacked), 0);
980 	ATF_REQUIRE(nvlist_exists_number_array(unpacked, key));
981 
982 	const_result = nvlist_get_number_array(unpacked, key, &count);
983 	ATF_REQUIRE_EQ(count, nitems(number));
984 	for (i = 0; i < count; i++) {
985 		ATF_REQUIRE_EQ(number[i], const_result[i]);
986 	}
987 
988 	nvlist_destroy(nvl);
989 	nvlist_destroy(unpacked);
990 	free(packed);
991 }
992 
993 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_descriptor_array__pack);
994 ATF_TEST_CASE_BODY(nvlist_descriptor_array__pack)
995 {
996 	nvlist_t *nvl;
997 	const char *key;
998 	size_t num_items;
999 	unsigned int i;
1000 	const int *const_result;
1001 	int desc[32], fd, socks[2];
1002 	pid_t pid;
1003 
1004 	key = "nvl/descriptor";
1005 
1006 	ATF_REQUIRE_EQ(socketpair(PF_UNIX, SOCK_STREAM, 0, socks), 0);
1007 
1008 	pid = atf::utils::fork();
1009 	ATF_REQUIRE(pid >= 0);
1010 	if (pid == 0) {
1011 		/* Child. */
1012 		fd = socks[0];
1013 		close(socks[1]);
1014 		for (i = 0; i < nitems(desc); i++) {
1015 			desc[i] = dup(STDERR_FILENO);
1016 			ATF_REQUIRE(fd_is_valid(desc[i]));
1017 		}
1018 
1019 		nvl = nvlist_create(0);
1020 		ATF_REQUIRE(nvl != NULL);
1021 		ATF_REQUIRE(nvlist_empty(nvl));
1022 		ATF_REQUIRE(!nvlist_exists_descriptor_array(nvl, key));
1023 
1024 		nvlist_add_descriptor_array(nvl, key, desc, nitems(desc));
1025 		ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1026 		ATF_REQUIRE(!nvlist_empty(nvl));
1027 		ATF_REQUIRE(nvlist_exists_descriptor_array(nvl, key));
1028 
1029 		ATF_REQUIRE(nvlist_send(fd, nvl) >= 0);
1030 
1031 		for (i = 0; i < nitems(desc); i++)
1032 			close(desc[i]);
1033 	} else {
1034 		/* Parent */
1035 		fd = socks[1];
1036 		close(socks[0]);
1037 
1038 		errno = 0;
1039 		nvl = nvlist_recv(fd, 0);
1040 		ATF_REQUIRE(nvl != NULL);
1041 		ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1042 		ATF_REQUIRE(nvlist_exists_descriptor_array(nvl, key));
1043 
1044 		const_result = nvlist_get_descriptor_array(nvl, key, &num_items);
1045 		ATF_REQUIRE(const_result != NULL);
1046 		ATF_REQUIRE_EQ(num_items, nitems(desc));
1047 		for (i = 0; i < num_items; i++)
1048 			ATF_REQUIRE(fd_is_valid(const_result[i]));
1049 
1050 		atf::utils::wait(pid, 0, "", "");
1051 	}
1052 
1053 	nvlist_destroy(nvl);
1054 	close(fd);
1055 }
1056 
1057 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_string_array__pack);
1058 ATF_TEST_CASE_BODY(nvlist_string_array__pack)
1059 {
1060 	nvlist_t *nvl, *unpacked;
1061 	const char *key;
1062 	size_t packed_size, count;
1063 	void *packed;
1064 	unsigned int i;
1065 	const char * const *const_result;
1066 	const char *string_arr[8] = { "a", "b", "kot", "foo",
1067 	    "tests", "nice test", "", "abcdef" };
1068 
1069 	key = "nvl/string";
1070 	nvl = nvlist_create(0);
1071 	ATF_REQUIRE(nvl != NULL);
1072 	ATF_REQUIRE(nvlist_empty(nvl));
1073 	ATF_REQUIRE(!nvlist_exists_string_array(nvl, key));
1074 
1075 	nvlist_add_string_array(nvl, key, string_arr, nitems(string_arr));
1076 	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1077 	ATF_REQUIRE(!nvlist_empty(nvl));
1078 	ATF_REQUIRE(nvlist_exists_string_array(nvl, key));
1079 
1080 	packed = nvlist_pack(nvl, &packed_size);
1081 	ATF_REQUIRE(packed != NULL);
1082 
1083 	unpacked = nvlist_unpack(packed, packed_size, 0);
1084 	ATF_REQUIRE(unpacked != NULL);
1085 	ATF_REQUIRE_EQ(nvlist_error(unpacked), 0);
1086 	ATF_REQUIRE(nvlist_exists_string_array(unpacked, key));
1087 
1088 	const_result = nvlist_get_string_array(unpacked, key, &count);
1089 	ATF_REQUIRE_EQ(count, nitems(string_arr));
1090 	for (i = 0; i < count; i++) {
1091 		ATF_REQUIRE_EQ(strcmp(string_arr[i], const_result[i]), 0);
1092 	}
1093 
1094 	nvlist_destroy(nvl);
1095 	nvlist_destroy(unpacked);
1096 	free(packed);
1097 }
1098 
1099 ATF_TEST_CASE_WITHOUT_HEAD(nvlist_nvlist_array__pack);
1100 ATF_TEST_CASE_BODY(nvlist_nvlist_array__pack)
1101 {
1102 	nvlist_t *testnvl[8], *unpacked;
1103 	const nvlist_t * const *const_result;
1104 	nvlist_t *nvl;
1105 	size_t num_items, packed_size;
1106 	unsigned int i;
1107 	void *packed;
1108 	const char *somestr[8] = { "a", "b", "c", "d", "e", "f", "g", "h" };
1109 	const char *key;
1110 
1111 	for (i = 0; i < nitems(testnvl); i++) {
1112 		testnvl[i] = nvlist_create(0);
1113 		ATF_REQUIRE(testnvl[i] != NULL);
1114 		ATF_REQUIRE_EQ(nvlist_error(testnvl[i]), 0);
1115 		nvlist_add_string(testnvl[i], "nvl/string", somestr[i]);
1116 		ATF_REQUIRE_EQ(nvlist_error(testnvl[i]), 0);
1117 		ATF_REQUIRE(nvlist_exists_string(testnvl[i], "nvl/string"));
1118 	}
1119 
1120 	key = "nvl/nvlist";
1121 	nvl = nvlist_create(0);
1122 	ATF_REQUIRE(nvl != NULL);
1123 	ATF_REQUIRE(nvlist_empty(nvl));
1124 	ATF_REQUIRE(!nvlist_exists_string_array(nvl, key));
1125 
1126 	nvlist_add_nvlist_array(nvl, key, (const nvlist_t * const *)testnvl, 8);
1127 	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1128 	ATF_REQUIRE(!nvlist_empty(nvl));
1129 	ATF_REQUIRE(nvlist_exists_nvlist_array(nvl, key));
1130 	ATF_REQUIRE(nvlist_exists_nvlist_array(nvl, "nvl/nvlist"));
1131 	packed = nvlist_pack(nvl, &packed_size);
1132 	ATF_REQUIRE(packed != NULL);
1133 
1134 	unpacked = nvlist_unpack(packed, packed_size, 0);
1135 	ATF_REQUIRE(unpacked != NULL);
1136 	ATF_REQUIRE_EQ(nvlist_error(unpacked), 0);
1137 	ATF_REQUIRE(nvlist_exists_nvlist_array(unpacked, key));
1138 
1139 	const_result = nvlist_get_nvlist_array(unpacked, key, &num_items);
1140 	ATF_REQUIRE(const_result != NULL);
1141 	ATF_REQUIRE_EQ(num_items, nitems(testnvl));
1142 	for (i = 0; i < num_items; i++) {
1143 		ATF_REQUIRE_EQ(nvlist_error(const_result[i]), 0);
1144 		if (i < num_items - 1) {
1145 			ATF_REQUIRE(nvlist_get_array_next(const_result[i]) ==
1146 			    const_result[i + 1]);
1147 		} else {
1148 			ATF_REQUIRE(nvlist_get_array_next(const_result[i]) ==
1149 			    NULL);
1150 		}
1151 		ATF_REQUIRE(nvlist_get_parent(const_result[i], NULL) == unpacked);
1152 		ATF_REQUIRE(nvlist_in_array(const_result[i]));
1153 		ATF_REQUIRE(nvlist_exists_string(const_result[i],
1154 		    "nvl/string"));
1155 		ATF_REQUIRE(strcmp(nvlist_get_string(const_result[i],
1156 		    "nvl/string"), somestr[i]) == 0);
1157 	}
1158 
1159 	for (i = 0; i < nitems(testnvl); i++)
1160 		nvlist_destroy(testnvl[i]);
1161 	nvlist_destroy(nvl);
1162 	nvlist_destroy(unpacked);
1163 	free(packed);
1164 }
1165 
1166 ATF_INIT_TEST_CASES(tp)
1167 {
1168 
1169 	ATF_ADD_TEST_CASE(tp, nvlist_bool_array__basic);
1170 	ATF_ADD_TEST_CASE(tp, nvlist_string_array__basic);
1171 	ATF_ADD_TEST_CASE(tp, nvlist_descriptor_array__basic);
1172 	ATF_ADD_TEST_CASE(tp, nvlist_number_array__basic);
1173 	ATF_ADD_TEST_CASE(tp, nvlist_nvlist_array__basic)
1174 
1175 	ATF_ADD_TEST_CASE(tp, nvlist_clone_array)
1176 
1177 	ATF_ADD_TEST_CASE(tp, nvlist_bool_array__move);
1178 	ATF_ADD_TEST_CASE(tp, nvlist_string_array__move);
1179 	ATF_ADD_TEST_CASE(tp, nvlist_nvlist_array__move);
1180 	ATF_ADD_TEST_CASE(tp, nvlist_number_array__move);
1181 	ATF_ADD_TEST_CASE(tp, nvlist_descriptor_array__move);
1182 
1183 	ATF_ADD_TEST_CASE(tp, nvlist_arrays__error_null);
1184 
1185 	ATF_ADD_TEST_CASE(tp, nvlist_arrays__bad_value)
1186 
1187 	ATF_ADD_TEST_CASE(tp, nvlist_nvlist_array__travel)
1188 	ATF_ADD_TEST_CASE(tp, nvlist_nvlist_array__travel_alternative)
1189 
1190 	ATF_ADD_TEST_CASE(tp, nvlist_bool_array__pack)
1191 	ATF_ADD_TEST_CASE(tp, nvlist_number_array__pack)
1192 	ATF_ADD_TEST_CASE(tp, nvlist_descriptor_array__pack)
1193 	ATF_ADD_TEST_CASE(tp, nvlist_string_array__pack)
1194 	ATF_ADD_TEST_CASE(tp, nvlist_nvlist_array__pack)
1195 }
1196 
1197