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