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