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