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