1/*-
2 * Copyright (c) 2016 Adam Starak <starak.adam@gmail.com>
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 AUTHORS 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 AUTHORS OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28#include <sys/cnv.h>
29#include <sys/nv.h>
30#include <sys/types.h>
31
32#include <atf-c++.hpp>
33#include <fcntl.h>
34#include <errno.h>
35
36#define	fd_is_valid(fd)	(fcntl((fd), F_GETFL) != -1 || errno != EBADF)
37
38/* ATF cnvlist_get tests. */
39
40ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_get_bool);
41ATF_TEST_CASE_BODY(cnvlist_get_bool)
42{
43	nvlist_t *nvl;
44	const char *key;
45	bool value;
46	void *cookie;
47	int type;
48
49	nvl = nvlist_create(0);
50	ATF_REQUIRE(nvl != NULL);
51	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
52	ATF_REQUIRE(nvlist_empty(nvl));
53
54	cookie = NULL;
55	key = "name";
56	value = true;
57
58	nvlist_add_bool(nvl, key, value);
59	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
60	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
61	ATF_REQUIRE_EQ(type, NV_TYPE_BOOL);
62	ATF_REQUIRE(!nvlist_empty(nvl));
63	ATF_REQUIRE(nvlist_exists(nvl, key));
64	ATF_REQUIRE(nvlist_exists_bool(nvl, key));
65
66	ATF_REQUIRE_EQ(cnvlist_get_bool(cookie), value);
67
68	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
69	    static_cast<const char *>(NULL));
70
71	nvlist_destroy(nvl);
72}
73
74ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_get_number);
75ATF_TEST_CASE_BODY(cnvlist_get_number)
76{
77	nvlist_t *nvl;
78	const char *key;
79	uint64_t value;
80	void *cookie;
81	int type;
82
83	nvl = nvlist_create(0);
84	ATF_REQUIRE(nvl != NULL);
85	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
86	ATF_REQUIRE(nvlist_empty(nvl));
87
88	cookie = NULL;
89	key = "name";
90	value = 420;
91
92	nvlist_add_number(nvl, key, value);
93	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
94	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
95	ATF_REQUIRE_EQ(type, NV_TYPE_NUMBER);
96	ATF_REQUIRE(!nvlist_empty(nvl));
97	ATF_REQUIRE(nvlist_exists(nvl, key));
98	ATF_REQUIRE(nvlist_exists_number(nvl, key));
99
100	ATF_REQUIRE_EQ(cnvlist_get_number(cookie), value);
101
102	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
103	    static_cast<const char *>(NULL));
104
105	nvlist_destroy(nvl);
106}
107
108
109ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_get_string);
110ATF_TEST_CASE_BODY(cnvlist_get_string)
111{
112	nvlist_t *nvl;
113	const char *key;
114	const char *value;
115	void *cookie;
116	int type;
117
118	nvl = nvlist_create(0);
119	ATF_REQUIRE(nvl != NULL);
120	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
121	ATF_REQUIRE(nvlist_empty(nvl));
122
123	cookie = NULL;
124	key = "name";
125	value = "text";
126
127	nvlist_add_string(nvl, key, value);
128	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
129	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
130	ATF_REQUIRE_EQ(type, NV_TYPE_STRING);
131	ATF_REQUIRE(!nvlist_empty(nvl));
132	ATF_REQUIRE(nvlist_exists(nvl, key));
133	ATF_REQUIRE(nvlist_exists_string(nvl, key));
134
135	ATF_REQUIRE_EQ(strcmp(cnvlist_get_string(cookie), value), 0);
136
137	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
138	    static_cast<const char *>(NULL));
139
140	nvlist_destroy(nvl);
141}
142
143ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_get_nvlist);
144ATF_TEST_CASE_BODY(cnvlist_get_nvlist)
145{
146	nvlist_t *nvl, *value;
147	const nvlist_t *result;
148	const char *key, *subkey;
149	void *cookie;
150	int type;
151
152	nvl = nvlist_create(0);
153	ATF_REQUIRE(nvl != NULL);
154	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
155	ATF_REQUIRE(nvlist_empty(nvl));
156
157	value = nvlist_create(0);
158	ATF_REQUIRE(nvl != NULL);
159	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
160	ATF_REQUIRE(nvlist_empty(nvl));
161
162	key = "name";
163	subkey = "subname";
164	cookie = NULL;
165
166	/* Add null to 'value' nvlist. */
167	nvlist_add_null(value, subkey);
168	ATF_REQUIRE_EQ(strcmp(subkey, nvlist_next(value, &type, &cookie)), 0);
169	ATF_REQUIRE_EQ(nvlist_error(value), 0);
170	ATF_REQUIRE_EQ(type, NV_TYPE_NULL);
171	ATF_REQUIRE(!nvlist_empty(value));
172	ATF_REQUIRE(nvlist_exists(value, subkey));
173	ATF_REQUIRE(nvlist_exists_null(value, subkey));
174	ATF_REQUIRE_EQ(nvlist_next(value, &type, &cookie),
175		       static_cast<const char *>(NULL));
176
177	/* Add 'value' nvlist. */
178	cookie = NULL;
179	nvlist_add_nvlist(nvl, key, value);
180	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
181	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
182	ATF_REQUIRE_EQ(type, NV_TYPE_NVLIST);
183	ATF_REQUIRE(!nvlist_empty(nvl));
184	ATF_REQUIRE(nvlist_exists(nvl, key));
185	ATF_REQUIRE(nvlist_exists_nvlist(nvl, key));
186
187	/*
188	 * Assuming nvlist_get_nvlist() is correct check if cnvlist returns
189	 * the same pointer.
190	 */
191	result = cnvlist_get_nvlist(cookie);
192	ATF_REQUIRE_EQ(result, nvlist_get_nvlist(nvl, key));
193	ATF_REQUIRE(result != value);
194	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
195		       static_cast<const char *>(NULL));
196
197	/* Validate data inside nvlist. */
198	cookie = NULL;
199	ATF_REQUIRE_EQ(strcmp(subkey, nvlist_next(result, &type, &cookie)), 0);
200	ATF_REQUIRE_EQ(nvlist_error(result), 0);
201	ATF_REQUIRE_EQ(type, NV_TYPE_NULL);
202	ATF_REQUIRE(!nvlist_empty(result));
203	ATF_REQUIRE(nvlist_exists(result, subkey));
204	ATF_REQUIRE(nvlist_exists_null(result, subkey));
205	ATF_REQUIRE_EQ(nvlist_next(result, &type, &cookie),
206		       static_cast<const char *>(NULL));
207
208	nvlist_destroy(nvl);
209	nvlist_destroy(value);
210}
211
212ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_get_descriptor);
213ATF_TEST_CASE_BODY(cnvlist_get_descriptor)
214{
215	nvlist_t *nvl;
216	const char *key;
217	void *cookie;
218	int type;
219
220	nvl = nvlist_create(0);
221	ATF_REQUIRE(nvl != NULL);
222	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
223	ATF_REQUIRE(nvlist_empty(nvl));
224
225	cookie = NULL;
226	key = "name";
227
228	nvlist_add_descriptor(nvl, key, STDERR_FILENO);
229	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
230	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
231	ATF_REQUIRE_EQ(type, NV_TYPE_DESCRIPTOR);
232	ATF_REQUIRE(!nvlist_empty(nvl));
233	ATF_REQUIRE(nvlist_exists(nvl, key));
234	ATF_REQUIRE(nvlist_exists_descriptor(nvl, key));
235
236	ATF_REQUIRE_EQ(fd_is_valid(cnvlist_get_descriptor(cookie)), 1);
237
238	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
239	    static_cast<const char *>(NULL));
240
241	nvlist_destroy(nvl);
242}
243
244ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_get_binary);
245ATF_TEST_CASE_BODY(cnvlist_get_binary)
246{
247	nvlist_t *nvl;
248	const char *key;
249	void *in_binary;
250	const void *out_binary;
251	void *cookie;
252	int type;
253	size_t in_size, out_size;
254
255	nvl = nvlist_create(0);
256	ATF_REQUIRE(nvl != NULL);
257	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
258	ATF_REQUIRE(nvlist_empty(nvl));
259
260	cookie = NULL;
261	key = "name";
262	in_size = 13;
263
264	in_binary = malloc(in_size);
265	ATF_REQUIRE(in_binary != NULL);
266	memset(in_binary, 0xa5, in_size);
267
268	nvlist_add_binary(nvl, key, in_binary, in_size);
269	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
270	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
271	ATF_REQUIRE_EQ(type, NV_TYPE_BINARY);
272	ATF_REQUIRE(!nvlist_empty(nvl));
273	ATF_REQUIRE(nvlist_exists(nvl, key));
274	ATF_REQUIRE(nvlist_exists_binary(nvl, key));
275
276	out_binary = cnvlist_get_binary(cookie, &out_size);
277	ATF_REQUIRE_EQ(out_size, in_size);
278	ATF_REQUIRE_EQ(memcmp(in_binary, out_binary, out_size), 0);
279
280	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
281	    static_cast<const char *>(NULL));
282
283	nvlist_destroy(nvl);
284}
285
286/* ATF cnvlist_get array tests. */
287
288ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_get_bool_array);
289ATF_TEST_CASE_BODY(cnvlist_get_bool_array)
290{
291	nvlist_t *nvl;
292	bool in_array[16];
293	const bool *out_array;
294	const char *key;
295	void *cookie;
296	int type, i;
297	size_t nitems;
298
299	for (i = 0; i < 16; i++)
300		in_array[i] = (i % 2 == 0);
301
302	nvl = nvlist_create(0);
303	ATF_REQUIRE(nvl != NULL);
304	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
305	ATF_REQUIRE(nvlist_empty(nvl));
306
307	cookie = NULL;
308	key = "name";
309
310	nvlist_add_bool_array(nvl, key, in_array, 16);
311	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
312	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
313	ATF_REQUIRE_EQ(type, NV_TYPE_BOOL_ARRAY);
314	ATF_REQUIRE(!nvlist_empty(nvl));
315	ATF_REQUIRE(nvlist_exists(nvl, key));
316	ATF_REQUIRE(nvlist_exists_bool_array(nvl, key));
317
318	out_array = cnvlist_get_bool_array(cookie, &nitems);
319	ATF_REQUIRE_EQ(nitems, 16);
320	ATF_REQUIRE(out_array != NULL);
321	for (i = 0; i < 16; i++)
322		ATF_REQUIRE_EQ(out_array[i], in_array[i]);
323
324	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
325	    static_cast<const char *>(NULL));
326
327	nvlist_destroy(nvl);
328}
329
330ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_get_number_array);
331ATF_TEST_CASE_BODY(cnvlist_get_number_array)
332{
333	nvlist_t *nvl;
334	uint64_t in_array[16];
335	const uint64_t *out_array;
336	const char *key;
337	void *cookie;
338	int type, i;
339	size_t nitems;
340
341	for (i = 0; i < 16; i++)
342		in_array[i] = i;
343
344	nvl = nvlist_create(0);
345	ATF_REQUIRE(nvl != NULL);
346	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
347	ATF_REQUIRE(nvlist_empty(nvl));
348
349	cookie = NULL;
350	key = "name";
351
352	nvlist_add_number_array(nvl, key, in_array, 16);
353	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
354	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
355	ATF_REQUIRE_EQ(type, NV_TYPE_NUMBER_ARRAY);
356	ATF_REQUIRE(!nvlist_empty(nvl));
357	ATF_REQUIRE(nvlist_exists(nvl, key));
358	ATF_REQUIRE(nvlist_exists_number_array(nvl, key));
359
360	out_array = cnvlist_get_number_array(cookie, &nitems);
361	ATF_REQUIRE(out_array != NULL);
362	ATF_REQUIRE_EQ(nitems, 16);
363	for (i = 0; i < 16; i++)
364		ATF_REQUIRE_EQ(out_array[i], in_array[i]);
365
366	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
367	    static_cast<const char *>(NULL));
368
369	nvlist_destroy(nvl);
370}
371
372ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_get_string_array);
373ATF_TEST_CASE_BODY(cnvlist_get_string_array)
374{
375	nvlist_t *nvl;
376	const char *in_array[4] = {"inequality", "sucks", ".", ""};
377	const char * const *out_array;
378	const char *key;
379	void *cookie;
380	int type, i;
381	size_t nitems;
382
383	nvl = nvlist_create(0);
384	ATF_REQUIRE(nvl != NULL);
385	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
386	ATF_REQUIRE(nvlist_empty(nvl));
387
388	cookie = NULL;
389	key = "name";
390
391	nvlist_add_string_array(nvl, key, in_array, 4);
392	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
393	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
394	ATF_REQUIRE_EQ(type, NV_TYPE_STRING_ARRAY);
395	ATF_REQUIRE(!nvlist_empty(nvl));
396	ATF_REQUIRE(nvlist_exists(nvl, key));
397	ATF_REQUIRE(nvlist_exists_string_array(nvl, key));
398
399	out_array = cnvlist_get_string_array(cookie, &nitems);
400	ATF_REQUIRE_EQ(nitems, 4);
401	ATF_REQUIRE(out_array != NULL);
402	for (i = 0; i < 4; i++) {
403		ATF_REQUIRE(out_array[i] != NULL);
404		ATF_REQUIRE_EQ(strcmp(out_array[i], in_array[i]), 0);
405	}
406
407	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
408	    static_cast<const char *>(NULL));
409
410	nvlist_destroy(nvl);
411}
412
413ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_get_nvlist_array);
414ATF_TEST_CASE_BODY(cnvlist_get_nvlist_array)
415{
416	nvlist_t *nvl;
417	nvlist_t *in_array[6];
418	const nvlist_t * const *out_array;
419	const nvlist_t * const *out_result;
420	void *cookie;
421	const char *key;
422	const char *subkeys;
423	int type, i;
424	size_t nitems;
425
426	nvl = nvlist_create(0);
427	ATF_REQUIRE(nvl != NULL);
428	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
429	ATF_REQUIRE(nvlist_empty(nvl));
430
431	subkeys = "123456";
432	for (i = 0; i < 6; i++) {
433		in_array[i] = nvlist_create(0);
434		ATF_REQUIRE(in_array[i] != NULL);
435		ATF_REQUIRE_EQ(nvlist_error(in_array[i]), 0);
436		ATF_REQUIRE(nvlist_empty(in_array[i]));
437
438		cookie = NULL;
439
440		nvlist_add_null(in_array[i], subkeys+i);
441		ATF_REQUIRE_EQ(strcmp(subkeys+i, nvlist_next(in_array[i],
442		    &type, &cookie)),0);
443		ATF_REQUIRE_EQ(nvlist_error(in_array[i]), 0);
444		ATF_REQUIRE_EQ(type, NV_TYPE_NULL);
445		ATF_REQUIRE(!nvlist_empty(in_array[i]));
446		ATF_REQUIRE(nvlist_exists(in_array[i], subkeys+i));
447		ATF_REQUIRE(nvlist_exists_null(in_array[i], subkeys+i));
448		ATF_REQUIRE_EQ(nvlist_next(in_array[i], &type, &cookie),
449		    static_cast<const char *>(NULL));
450	}
451
452	cookie = NULL;
453	key = "name";
454
455	nvlist_add_nvlist_array(nvl, key, in_array, 6);
456	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
457	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
458	ATF_REQUIRE_EQ(type, NV_TYPE_NVLIST_ARRAY);
459	ATF_REQUIRE(!nvlist_empty(nvl));
460	ATF_REQUIRE(nvlist_exists(nvl, key));
461	ATF_REQUIRE(nvlist_exists_nvlist_array(nvl, key));
462
463	/* Get nvlist array by cnvlist function. */
464	out_array = cnvlist_get_nvlist_array(cookie, &nitems);
465	ATF_REQUIRE(out_array != NULL);
466	ATF_REQUIRE_EQ(nitems, 6);
467	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
468	    static_cast<const char *>(NULL));
469
470	/* Get nvlist array by nvlist function. */
471	out_result = nvlist_get_nvlist_array(nvl, key, &nitems);
472	ATF_REQUIRE(out_result != NULL);
473	ATF_REQUIRE_EQ(nitems, 6);
474
475	/* Validate assuming that nvlist returned a proper pointer */
476	for (i = 0; i < 6; i++) {
477		ATF_REQUIRE_EQ(out_result[i], out_array[i]);
478		ATF_REQUIRE(out_array[i] != in_array[i]);
479
480		/* Validate data inside nvlist. */
481		cookie = NULL;
482		ATF_REQUIRE_EQ(strcmp(subkeys+i, nvlist_next(out_array[i],
483		    &type, &cookie)), 0);
484		ATF_REQUIRE_EQ(nvlist_error(out_array[i]), 0);
485		ATF_REQUIRE_EQ(type, NV_TYPE_NULL);
486		ATF_REQUIRE(!nvlist_empty(out_array[i]));
487		ATF_REQUIRE(nvlist_exists(out_array[i], subkeys+i));
488		ATF_REQUIRE(nvlist_exists_null(out_array[i], subkeys+i));
489		ATF_REQUIRE_EQ(nvlist_next(out_array[i], &type, &cookie),
490		    static_cast<const char *>(NULL));
491	}
492
493	nvlist_destroy(nvl);
494}
495
496ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_get_descriptor_array);
497ATF_TEST_CASE_BODY(cnvlist_get_descriptor_array)
498{
499	nvlist_t *nvl;
500	size_t count, i, nitems;
501	const int *out_array;
502	int *in_array, type;
503	const char *key;
504	void *cookie;
505
506	nvl = nvlist_create(0);
507	ATF_REQUIRE(nvl != NULL);
508	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
509	ATF_REQUIRE(nvlist_empty(nvl));
510
511	cookie = NULL;
512	key = "name";
513	count = 50;
514
515	in_array = static_cast<int *>(malloc(sizeof(*in_array)*count));
516	ATF_REQUIRE(in_array != NULL);
517	for (i = 0; i < count; i++) {
518		in_array[i] = dup(STDERR_FILENO);
519		ATF_REQUIRE(fd_is_valid(in_array[i]));
520	}
521
522	nvlist_add_descriptor_array(nvl, key, in_array, count);
523	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
524	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
525	ATF_REQUIRE_EQ(type, NV_TYPE_DESCRIPTOR_ARRAY);
526	ATF_REQUIRE(!nvlist_empty(nvl));
527	ATF_REQUIRE(nvlist_exists(nvl, key));
528	ATF_REQUIRE(nvlist_exists_descriptor_array(nvl, key));
529
530	out_array = cnvlist_get_descriptor_array(cookie, &nitems);
531	ATF_REQUIRE_EQ(nitems, count);
532	ATF_REQUIRE(out_array != NULL);
533	for (i = 0; i < count; i++)
534		ATF_REQUIRE_EQ(fd_is_valid(out_array[i]), 1);
535
536	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
537	    static_cast<const char *>(NULL));
538
539	nvlist_destroy(nvl);
540}
541
542/* ATF cnvlist_take tests. */
543
544ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_take_bool);
545ATF_TEST_CASE_BODY(cnvlist_take_bool)
546{
547	nvlist_t *nvl;
548	const char *key;
549	bool value;
550	void *cookie;
551	int type;
552
553	nvl = nvlist_create(0);
554	ATF_REQUIRE(nvl != NULL);
555	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
556	ATF_REQUIRE(nvlist_empty(nvl));
557
558	cookie = NULL;
559	key = "name";
560	value = true;
561
562	nvlist_add_bool(nvl, key, value);
563	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
564	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
565	ATF_REQUIRE_EQ(type, NV_TYPE_BOOL);
566	ATF_REQUIRE(!nvlist_empty(nvl));
567	ATF_REQUIRE(nvlist_exists(nvl, key));
568	ATF_REQUIRE(nvlist_exists_bool(nvl, key));
569	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
570	    static_cast<const char *>(NULL));
571
572	cookie = NULL;
573	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
574	ATF_REQUIRE_EQ(cnvlist_take_bool(cookie), value);
575
576	cookie = NULL;
577	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
578	ATF_REQUIRE(nvlist_empty(nvl));
579	ATF_REQUIRE(!nvlist_exists(nvl, key));
580	ATF_REQUIRE(!nvlist_exists_bool(nvl, key));
581	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
582	    static_cast<const char *>(NULL));
583
584	nvlist_destroy(nvl);
585}
586
587ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_take_number);
588ATF_TEST_CASE_BODY(cnvlist_take_number)
589{
590	nvlist_t *nvl;
591	const char *key;
592	uint64_t value;
593	void *cookie;
594	int type;
595
596	nvl = nvlist_create(0);
597	ATF_REQUIRE(nvl != NULL);
598	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
599	ATF_REQUIRE(nvlist_empty(nvl));
600
601	cookie = NULL;
602	key = "name";
603	value = 69;
604
605	nvlist_add_number(nvl, key, value);
606	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
607	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
608	ATF_REQUIRE_EQ(type, NV_TYPE_NUMBER);
609	ATF_REQUIRE(!nvlist_empty(nvl));
610	ATF_REQUIRE(nvlist_exists(nvl, key));
611	ATF_REQUIRE(nvlist_exists_number(nvl, key));
612	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
613	    static_cast<const char *>(NULL));
614
615	cookie = NULL;
616	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
617	ATF_REQUIRE_EQ(cnvlist_take_number(cookie), value);
618
619	cookie = NULL;
620	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
621	ATF_REQUIRE(nvlist_empty(nvl));
622	ATF_REQUIRE(!nvlist_exists(nvl, key));
623	ATF_REQUIRE(!nvlist_exists_number(nvl, key));
624	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
625	    static_cast<const char *>(NULL));
626
627	nvlist_destroy(nvl);
628}
629
630ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_take_string);
631ATF_TEST_CASE_BODY(cnvlist_take_string)
632{
633	nvlist_t *nvl;
634	const char *key;
635	const char *value;
636	char *out_string;
637	void *cookie;
638	int type;
639
640	nvl = nvlist_create(0);
641	ATF_REQUIRE(nvl != NULL);
642	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
643	ATF_REQUIRE(nvlist_empty(nvl));
644
645	cookie = NULL;
646	key = "name";
647	value = "text";
648
649	nvlist_add_string(nvl, key, value);
650	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
651	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
652	ATF_REQUIRE_EQ(type, NV_TYPE_STRING);
653	ATF_REQUIRE(!nvlist_empty(nvl));
654	ATF_REQUIRE(nvlist_exists(nvl, key));
655	ATF_REQUIRE(nvlist_exists_string(nvl, key));
656	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
657	    static_cast<const char *>(NULL));
658
659	cookie = NULL;
660	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
661	out_string = cnvlist_take_string(cookie);
662	ATF_REQUIRE(out_string != NULL);
663	ATF_REQUIRE_EQ(strcmp(out_string, value), 0);
664
665	cookie = NULL;
666	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
667	ATF_REQUIRE(nvlist_empty(nvl));
668	ATF_REQUIRE(!nvlist_exists(nvl, key));
669	ATF_REQUIRE(!nvlist_exists_string(nvl, key));
670	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
671	    static_cast<const char *>(NULL));
672
673	free(out_string);
674	nvlist_destroy(nvl);
675}
676
677ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_take_nvlist);
678ATF_TEST_CASE_BODY(cnvlist_take_nvlist)
679{
680	nvlist_t *nvl, *value, *result;
681	const char *key, *subkey;
682	void *cookie;
683	int type;
684
685	nvl = nvlist_create(0);
686	ATF_REQUIRE(nvl != NULL);
687	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
688	ATF_REQUIRE(nvlist_empty(nvl));
689
690	value = nvlist_create(0);
691	ATF_REQUIRE(value != NULL);
692	ATF_REQUIRE_EQ(nvlist_error(value), 0);
693	ATF_REQUIRE(nvlist_empty(value));
694
695	key = "name";
696	subkey = "subname";
697	cookie = NULL;
698
699	/* Add null to 'value' nvlist. */
700	nvlist_add_null(value, subkey);
701	ATF_REQUIRE_EQ(strcmp(subkey, nvlist_next(value, &type, &cookie)), 0);
702	ATF_REQUIRE_EQ(nvlist_error(value), 0);
703	ATF_REQUIRE_EQ(type, NV_TYPE_NULL);
704	ATF_REQUIRE(!nvlist_empty(value));
705	ATF_REQUIRE(nvlist_exists(value, subkey));
706	ATF_REQUIRE(nvlist_exists_null(value, subkey));
707	ATF_REQUIRE_EQ(nvlist_next(value, &type, &cookie),
708	    static_cast<const char *>(NULL));
709
710	/* Add 'value' nvlist. */
711	cookie = NULL;
712	nvlist_move_nvlist(nvl, key, value);
713	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
714	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
715	ATF_REQUIRE_EQ(type, NV_TYPE_NVLIST);
716	ATF_REQUIRE(!nvlist_empty(nvl));
717	ATF_REQUIRE(nvlist_exists(nvl, key));
718	ATF_REQUIRE(nvlist_exists_nvlist(nvl, key));
719	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
720	    static_cast<const char *>(NULL));
721
722	cookie = NULL;
723	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
724	result = cnvlist_take_nvlist(cookie);
725	ATF_REQUIRE(!nvlist_exists_nvlist(nvl, key));
726	ATF_REQUIRE(result == value);
727
728	/* Validate data inside nvlist. */
729	cookie = NULL;
730	ATF_REQUIRE_EQ(strcmp(subkey, nvlist_next(result, &type, &cookie)), 0);
731	ATF_REQUIRE_EQ(nvlist_error(value), 0);
732	ATF_REQUIRE_EQ(type, NV_TYPE_NULL);
733	ATF_REQUIRE(!nvlist_empty(value));
734	ATF_REQUIRE(nvlist_exists(value, subkey));
735	ATF_REQUIRE(nvlist_exists_null(value, subkey));
736	ATF_REQUIRE_EQ(nvlist_next(value, &type, &cookie),
737	    static_cast<const char *>(NULL));
738
739	cookie = NULL;
740	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
741	    static_cast<const char *>(NULL));
742
743	nvlist_destroy(nvl);
744	nvlist_destroy(value);
745}
746
747/* ATF cnvlist_take array tests */
748
749ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_take_bool_array);
750ATF_TEST_CASE_BODY(cnvlist_take_bool_array)
751{
752	nvlist_t *nvl;
753	bool in_array[16];
754	const bool *out_array;
755	const char *key;
756	void *cookie;
757	int type, i;
758	size_t nitems;
759
760	for (i = 0; i < 16; i++)
761		in_array[i] = (i % 2 == 0);
762
763	nvl = nvlist_create(0);
764	ATF_REQUIRE(nvl != NULL);
765	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
766	ATF_REQUIRE(nvlist_empty(nvl));
767
768	cookie = NULL;
769	key = "name";
770
771	nvlist_add_bool_array(nvl, key, in_array, 16);
772	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
773	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
774	ATF_REQUIRE_EQ(type, NV_TYPE_BOOL_ARRAY);
775	ATF_REQUIRE(!nvlist_empty(nvl));
776	ATF_REQUIRE(nvlist_exists(nvl, key));
777	ATF_REQUIRE(nvlist_exists_bool_array(nvl, key));
778	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
779	    static_cast<const char *>(NULL));
780
781	cookie = NULL;
782	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
783	out_array = cnvlist_take_bool_array(cookie, &nitems);
784	ATF_REQUIRE_EQ(nitems, 16);
785	ATF_REQUIRE(out_array != NULL);
786	for (i = 0; i < 16; i++)
787		ATF_REQUIRE_EQ(out_array[i], in_array[i]);
788
789	cookie = NULL;
790	ATF_REQUIRE(!nvlist_exists_bool_array(nvl, key));
791	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
792	ATF_REQUIRE(nvlist_empty(nvl));
793	ATF_REQUIRE(!nvlist_exists(nvl, key));
794	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
795	    static_cast<const char *>(NULL));
796
797
798	nvlist_destroy(nvl);
799}
800
801ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_take_number_array);
802ATF_TEST_CASE_BODY(cnvlist_take_number_array)
803{
804	nvlist_t *nvl;
805	uint64_t in_array[16];
806	const uint64_t *out_array;
807	const char *key;
808	void *cookie;
809	int type, i;
810	size_t nitems;
811
812	for (i = 0; i < 16; i++)
813		in_array[i] = i;
814
815	nvl = nvlist_create(0);
816	ATF_REQUIRE(nvl != NULL);
817	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
818	ATF_REQUIRE(nvlist_empty(nvl));
819
820	cookie = NULL;
821	key = "name";
822
823	nvlist_add_number_array(nvl, key, in_array, 16);
824	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
825	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
826	ATF_REQUIRE_EQ(type, NV_TYPE_NUMBER_ARRAY);
827	ATF_REQUIRE(!nvlist_empty(nvl));
828	ATF_REQUIRE(nvlist_exists(nvl, key));
829	ATF_REQUIRE(nvlist_exists_number_array(nvl, key));
830	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
831	    static_cast<const char *>(NULL));
832
833	cookie = NULL;
834	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
835	out_array = cnvlist_take_number_array(cookie, &nitems);
836
837	ATF_REQUIRE(out_array != NULL);
838	ATF_REQUIRE_EQ(nitems, 16);
839	for (i = 0; i < 16; i++)
840		ATF_REQUIRE_EQ(out_array[i], in_array[i]);
841
842	cookie = NULL;
843	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
844	ATF_REQUIRE(nvlist_empty(nvl));
845	ATF_REQUIRE(!nvlist_exists(nvl, key));
846	ATF_REQUIRE(!nvlist_exists_number_array(nvl, key));
847	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
848	    static_cast<const char *>(NULL));
849
850	nvlist_destroy(nvl);
851}
852
853ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_take_string_array);
854ATF_TEST_CASE_BODY(cnvlist_take_string_array)
855{
856	nvlist_t *nvl;
857	const char *in_array[4] = {"inequality", "sks", ".", ""};
858	char **out_array;
859	const char *key;
860	void *cookie;
861	int type, i;
862	size_t nitems;
863
864	nvl = nvlist_create(0);
865	ATF_REQUIRE(nvl != NULL);
866	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
867	ATF_REQUIRE(nvlist_empty(nvl));
868
869	cookie = NULL;
870	key = "name";
871
872	nvlist_add_string_array(nvl, key, in_array, 4);
873	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
874	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
875	ATF_REQUIRE_EQ(type, NV_TYPE_STRING_ARRAY);
876	ATF_REQUIRE(!nvlist_empty(nvl));
877	ATF_REQUIRE(nvlist_exists(nvl, key));
878	ATF_REQUIRE(nvlist_exists_string_array(nvl, key));
879	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
880	    static_cast<const char *>(NULL));
881
882	cookie = NULL;
883	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
884	out_array = cnvlist_take_string_array(cookie, &nitems);
885	ATF_REQUIRE_EQ(nitems, 4);
886	for (i = 0; i < 4; i++) {
887		ATF_REQUIRE(out_array[i] != NULL);
888		ATF_REQUIRE_EQ(strcmp(out_array[i], in_array[i]), 0);
889	}
890	ATF_REQUIRE(nvlist_empty(nvl));
891
892	cookie = NULL;
893	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
894	ATF_REQUIRE(nvlist_empty(nvl));
895	ATF_REQUIRE(!nvlist_exists(nvl, key));
896	ATF_REQUIRE(!nvlist_exists_number_array(nvl, key));
897	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
898	    static_cast<const char *>(NULL));
899
900	free(out_array);
901	nvlist_destroy(nvl);
902}
903
904ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_take_nvlist_array);
905ATF_TEST_CASE_BODY(cnvlist_take_nvlist_array)
906{
907	nvlist_t *testnvl[8];
908	nvlist_t **result;
909	nvlist_t *nvl;
910	void *cookie;
911	size_t num_items;
912	unsigned int i;
913	int type;
914	const char *somestr[8] = { "a", "b", "c", "d", "e", "f", "g", "h" };
915	const char *key;
916
917	for (i = 0; i < 8; i++) {
918		testnvl[i] = nvlist_create(0);
919		ATF_REQUIRE(testnvl[i] != NULL);
920		ATF_REQUIRE_EQ(nvlist_error(testnvl[i]), 0);
921		ATF_REQUIRE(nvlist_empty(testnvl[i]));
922		nvlist_add_string(testnvl[i], "nvl/string", somestr[i]);
923
924		cookie = NULL;
925		ATF_REQUIRE_EQ(strcmp("nvl/string", nvlist_next(testnvl[i],
926		    &type, &cookie)), 0);
927		ATF_REQUIRE_EQ(nvlist_error(testnvl[i]), 0);
928		ATF_REQUIRE_EQ(type, NV_TYPE_STRING);
929		ATF_REQUIRE(!nvlist_empty(testnvl[i]));
930		ATF_REQUIRE(nvlist_exists(testnvl[i], "nvl/string"));
931		ATF_REQUIRE(nvlist_exists_string(testnvl[i], "nvl/string"));
932		ATF_REQUIRE_EQ(nvlist_next(testnvl[i], &type, &cookie),
933		    static_cast<const char *>(NULL));
934	}
935
936	nvl = nvlist_create(0);
937	ATF_REQUIRE(nvl != NULL);
938	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
939	ATF_REQUIRE(nvlist_empty(nvl));
940
941	key = "nvl/nvlist";
942	cookie = NULL;
943
944	nvlist_add_nvlist_array(nvl, key, (const nvlist_t * const *)testnvl, 8);
945	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
946	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
947	ATF_REQUIRE_EQ(type, NV_TYPE_NVLIST_ARRAY);
948	ATF_REQUIRE(!nvlist_empty(nvl));
949	ATF_REQUIRE(nvlist_exists(nvl, key));
950	ATF_REQUIRE(nvlist_exists_nvlist_array(nvl, key));
951	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
952	    static_cast<const char *>(NULL));
953
954	cookie = NULL;
955	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
956	result = cnvlist_take_nvlist_array(cookie, &num_items);
957
958	ATF_REQUIRE(result != NULL);
959	ATF_REQUIRE_EQ(num_items, 8);
960	for (i = 0; i < num_items; i++) {
961		ATF_REQUIRE_EQ(nvlist_error(result[i]), 0);
962		ATF_REQUIRE(nvlist_get_array_next(result[i]) == NULL);
963	}
964
965	ATF_REQUIRE(!nvlist_exists_string_array(nvl, key));
966	ATF_REQUIRE(nvlist_empty(nvl));
967	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
968
969	cookie = NULL;
970	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
971	ATF_REQUIRE(nvlist_empty(nvl));
972	ATF_REQUIRE(!nvlist_exists(nvl, key));
973	ATF_REQUIRE(!nvlist_exists_nvlist_array(nvl, key));
974	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
975	    static_cast<const char *>(NULL));
976
977	for (i = 0; i < 8; i++) {
978		nvlist_destroy(result[i]);
979		nvlist_destroy(testnvl[i]);
980	}
981
982	free(result);
983	nvlist_destroy(nvl);
984}
985
986ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_take_binary);
987ATF_TEST_CASE_BODY(cnvlist_take_binary)
988{
989	nvlist_t *nvl;
990	const char *key;
991	void *in_binary;
992	const void *out_binary;
993	void *cookie;
994	int type;
995	size_t in_size, out_size;
996
997	nvl = nvlist_create(0);
998	ATF_REQUIRE(nvl != NULL);
999	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1000	ATF_REQUIRE(nvlist_empty(nvl));
1001
1002	cookie = NULL;
1003	key = "name";
1004	in_size = 13;
1005	in_binary = malloc(in_size);
1006	ATF_REQUIRE(in_binary != NULL);
1007	memset(in_binary, 0xa5, in_size);
1008
1009	nvlist_add_binary(nvl, key, in_binary, in_size);
1010	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
1011	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1012	ATF_REQUIRE_EQ(type, NV_TYPE_BINARY);
1013	ATF_REQUIRE(!nvlist_empty(nvl));
1014	ATF_REQUIRE(nvlist_exists(nvl, key));
1015	ATF_REQUIRE(nvlist_exists_binary(nvl, key));
1016	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
1017	    static_cast<const char *>(NULL));
1018
1019	cookie = NULL;
1020	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
1021	out_binary = cnvlist_take_binary(cookie, &out_size);
1022	ATF_REQUIRE_EQ(out_size, in_size);
1023	ATF_REQUIRE_EQ(memcmp(in_binary, out_binary, out_size), 0);
1024
1025	cookie = NULL;
1026	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1027	ATF_REQUIRE(nvlist_empty(nvl));
1028	ATF_REQUIRE(!nvlist_exists(nvl, key));
1029	ATF_REQUIRE(!nvlist_exists_binary(nvl, key));
1030	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
1031	    static_cast<const char *>(NULL));
1032
1033	nvlist_destroy(nvl);
1034}
1035
1036/* ATF cnvlist_free tests. */
1037
1038ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_free_bool);
1039ATF_TEST_CASE_BODY(cnvlist_free_bool)
1040{
1041	nvlist_t *nvl;
1042	const char *key;
1043	bool value;
1044	void *cookie;
1045	int type;
1046
1047	nvl = nvlist_create(0);
1048	ATF_REQUIRE(nvl != NULL);
1049	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1050	ATF_REQUIRE(nvlist_empty(nvl));
1051
1052	cookie = NULL;
1053	key = "name";
1054	value = true;
1055
1056	nvlist_add_bool(nvl, key, value);
1057	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
1058	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1059	ATF_REQUIRE_EQ(type, NV_TYPE_BOOL);
1060	ATF_REQUIRE(!nvlist_empty(nvl));
1061	ATF_REQUIRE(nvlist_exists(nvl, key));
1062	ATF_REQUIRE(nvlist_exists_bool(nvl, key));
1063	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
1064	    static_cast<const char *>(NULL));
1065
1066	cookie = NULL;
1067	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
1068	cnvlist_free_bool(cookie);
1069
1070	cookie = NULL;
1071	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1072	ATF_REQUIRE(nvlist_empty(nvl));
1073	ATF_REQUIRE(!nvlist_exists(nvl, key));
1074	ATF_REQUIRE(!nvlist_exists_bool(nvl, key));
1075	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
1076	    static_cast<const char *>(NULL));
1077
1078	nvlist_destroy(nvl);
1079}
1080
1081ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_free_number);
1082ATF_TEST_CASE_BODY(cnvlist_free_number)
1083{
1084	nvlist_t *nvl;
1085	const char *key;
1086	uint64_t value;
1087	void *cookie;
1088	int type;
1089
1090	nvl = nvlist_create(0);
1091	ATF_REQUIRE(nvl != NULL);
1092	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1093	ATF_REQUIRE(nvlist_empty(nvl));
1094
1095	cookie = NULL;
1096	key = "name";
1097	value = 69;
1098
1099	nvlist_add_number(nvl, key, value);
1100	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
1101	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1102	ATF_REQUIRE_EQ(type, NV_TYPE_NUMBER);
1103	ATF_REQUIRE(!nvlist_empty(nvl));
1104	ATF_REQUIRE(nvlist_exists(nvl, key));
1105	ATF_REQUIRE(nvlist_exists_number(nvl, key));
1106	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
1107	    static_cast<const char *>(NULL));
1108
1109	cookie = NULL;
1110	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
1111	cnvlist_free_number(cookie);
1112
1113	cookie = NULL;
1114	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1115	ATF_REQUIRE(nvlist_empty(nvl));
1116	ATF_REQUIRE(!nvlist_exists(nvl, key));
1117	ATF_REQUIRE(!nvlist_exists_number(nvl, key));
1118	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
1119	    static_cast<const char *>(NULL));
1120
1121	nvlist_destroy(nvl);
1122}
1123
1124ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_free_string);
1125ATF_TEST_CASE_BODY(cnvlist_free_string)
1126{
1127	nvlist_t *nvl;
1128	const char *key;
1129	const char *value;
1130	void *cookie;
1131	int type;
1132
1133	nvl = nvlist_create(0);
1134	ATF_REQUIRE(nvl != NULL);
1135	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1136	ATF_REQUIRE(nvlist_empty(nvl));
1137
1138	cookie = NULL;
1139	key = "name";
1140	value = "text";
1141
1142	nvlist_add_string(nvl, key, value);
1143	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
1144	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1145	ATF_REQUIRE_EQ(type, NV_TYPE_STRING);
1146	ATF_REQUIRE(!nvlist_empty(nvl));
1147	ATF_REQUIRE(nvlist_exists(nvl, key));
1148	ATF_REQUIRE(nvlist_exists_string(nvl, key));
1149	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
1150	    static_cast<const char *>(NULL));
1151
1152	cookie = NULL;
1153	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
1154	cnvlist_free_string(cookie);
1155
1156	cookie = NULL;
1157	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1158	ATF_REQUIRE(nvlist_empty(nvl));
1159	ATF_REQUIRE(!nvlist_exists(nvl, key));
1160	ATF_REQUIRE(!nvlist_exists_string(nvl, key));
1161	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
1162	    static_cast<const char *>(NULL));
1163
1164	nvlist_destroy(nvl);
1165}
1166
1167ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_free_nvlist);
1168ATF_TEST_CASE_BODY(cnvlist_free_nvlist)
1169{
1170	nvlist_t *nvl, *value;
1171	const char *key, *subkey;
1172	void *cookie;
1173	int type;
1174
1175	nvl = nvlist_create(0);
1176	ATF_REQUIRE(nvl != NULL);
1177	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1178	ATF_REQUIRE(nvlist_empty(nvl));
1179
1180	value = nvlist_create(0);
1181	ATF_REQUIRE(nvl != NULL);
1182	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1183	ATF_REQUIRE(nvlist_empty(nvl));
1184
1185	key = "name";
1186	subkey = "subname";
1187	cookie = NULL;
1188
1189	/* Add null to 'value' nvlist. */
1190	nvlist_add_null(value, subkey);
1191	ATF_REQUIRE_EQ(strcmp(subkey, nvlist_next(value, &type, &cookie)), 0);
1192	ATF_REQUIRE_EQ(nvlist_error(value), 0);
1193	ATF_REQUIRE_EQ(type, NV_TYPE_NULL);
1194	ATF_REQUIRE(!nvlist_empty(value));
1195	ATF_REQUIRE(nvlist_exists(value, subkey));
1196	ATF_REQUIRE(nvlist_exists_null(value, subkey));
1197	ATF_REQUIRE_EQ(nvlist_next(value, &type, &cookie),
1198	    static_cast<const char *>(NULL));
1199
1200	/* Add 'value' nvlist. */
1201	cookie = NULL;
1202	nvlist_move_nvlist(nvl, key, value);
1203	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
1204	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1205	ATF_REQUIRE_EQ(type, NV_TYPE_NVLIST);
1206	ATF_REQUIRE(!nvlist_empty(nvl));
1207	ATF_REQUIRE(nvlist_exists(nvl, key));
1208	ATF_REQUIRE(nvlist_exists_nvlist(nvl, key));
1209	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
1210	    static_cast<const char *>(NULL));
1211
1212	cookie = NULL;
1213	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
1214	cnvlist_free_nvlist(cookie);
1215
1216	cookie = NULL;
1217	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1218	ATF_REQUIRE(nvlist_empty(nvl));
1219	ATF_REQUIRE(!nvlist_exists(nvl, key));
1220	ATF_REQUIRE(!nvlist_exists_nvlist(nvl, key));
1221	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
1222	    static_cast<const char *>(NULL));
1223
1224	nvlist_destroy(nvl);
1225}
1226
1227ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_free_binary);
1228ATF_TEST_CASE_BODY(cnvlist_free_binary)
1229{
1230	nvlist_t *nvl;
1231	const char *key;
1232	void *in_binary;
1233	void *cookie;
1234	int type;
1235	size_t in_size;
1236
1237	nvl = nvlist_create(0);
1238	ATF_REQUIRE(nvl != NULL);
1239	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1240	ATF_REQUIRE(nvlist_empty(nvl));
1241
1242	cookie = NULL;
1243	key = "name";
1244	in_size = 13;
1245	in_binary = malloc(in_size);
1246	ATF_REQUIRE(in_binary != NULL);
1247	memset(in_binary, 0xa5, in_size);
1248
1249	nvlist_add_binary(nvl, key, in_binary, in_size);
1250	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
1251	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1252	ATF_REQUIRE_EQ(type, NV_TYPE_BINARY);
1253	ATF_REQUIRE(!nvlist_empty(nvl));
1254	ATF_REQUIRE(nvlist_exists(nvl, key));
1255	ATF_REQUIRE(nvlist_exists_binary(nvl, key));
1256	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
1257	    static_cast<const char *>(NULL));
1258
1259	cookie = NULL;
1260	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
1261	cnvlist_free_binary(cookie);
1262
1263	cookie = NULL;
1264	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1265	ATF_REQUIRE(nvlist_empty(nvl));
1266	ATF_REQUIRE(!nvlist_exists(nvl, key));
1267	ATF_REQUIRE(!nvlist_exists_nvlist(nvl, key));
1268	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
1269	    static_cast<const char *>(NULL));
1270
1271	nvlist_destroy(nvl);
1272}
1273
1274/* ATF cnvlist_free array tests. */
1275
1276ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_free_bool_array);
1277ATF_TEST_CASE_BODY(cnvlist_free_bool_array)
1278{
1279	nvlist_t *nvl;
1280	bool in_array[16];
1281	const char *key;
1282	void *cookie;
1283	int type, i;
1284
1285	for (i = 0; i < 16; i++)
1286		in_array[i] = (i % 2 == 0);
1287
1288	nvl = nvlist_create(0);
1289	ATF_REQUIRE(nvl != NULL);
1290	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1291	ATF_REQUIRE(nvlist_empty(nvl));
1292
1293	cookie = NULL;
1294	key = "name";
1295
1296	nvlist_add_bool_array(nvl, key, in_array, 16);
1297	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
1298	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1299	ATF_REQUIRE_EQ(type, NV_TYPE_BOOL_ARRAY);
1300	ATF_REQUIRE(!nvlist_empty(nvl));
1301	ATF_REQUIRE(nvlist_exists(nvl, key));
1302	ATF_REQUIRE(nvlist_exists_bool_array(nvl, key));
1303	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
1304	    static_cast<const char *>(NULL));
1305
1306	cookie = NULL;
1307	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
1308	cnvlist_free_bool_array(cookie);
1309
1310	cookie = NULL;
1311	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1312	ATF_REQUIRE(nvlist_empty(nvl));
1313	ATF_REQUIRE(!nvlist_exists(nvl, key));
1314	ATF_REQUIRE(!nvlist_exists_bool(nvl, key));
1315	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
1316	    static_cast<const char *>(NULL));
1317
1318	nvlist_destroy(nvl);
1319}
1320
1321ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_free_number_array);
1322ATF_TEST_CASE_BODY(cnvlist_free_number_array)
1323{
1324	nvlist_t *nvl;
1325	uint64_t in_array[16];
1326	const char *key;
1327	void *cookie;
1328	int type, i;
1329
1330	for (i = 0; i < 16; i++)
1331		in_array[i] = i;
1332
1333	nvl = nvlist_create(0);
1334	ATF_REQUIRE(nvl != NULL);
1335	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1336	ATF_REQUIRE(nvlist_empty(nvl));
1337
1338	cookie = NULL;
1339	key = "name";
1340
1341	nvlist_add_number_array(nvl, key, in_array, 16);
1342	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
1343	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1344	ATF_REQUIRE_EQ(type, NV_TYPE_NUMBER_ARRAY);
1345	ATF_REQUIRE(!nvlist_empty(nvl));
1346	ATF_REQUIRE(nvlist_exists(nvl, key));
1347	ATF_REQUIRE(nvlist_exists_number_array(nvl, key));
1348	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
1349	    static_cast<const char *>(NULL));
1350
1351	cookie = NULL;
1352	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
1353	cnvlist_free_number_array(cookie);
1354
1355	cookie = NULL;
1356	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1357	ATF_REQUIRE(nvlist_empty(nvl));
1358	ATF_REQUIRE(!nvlist_exists(nvl, key));
1359	ATF_REQUIRE(!nvlist_exists_number_array(nvl, key));
1360	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
1361	    static_cast<const char *>(NULL));
1362
1363	nvlist_destroy(nvl);
1364}
1365
1366ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_free_string_array);
1367ATF_TEST_CASE_BODY(cnvlist_free_string_array)
1368{
1369	nvlist_t *nvl;
1370	const char *in_array[4] = {"inequality", "sucks", ".", ""};
1371	const char *key;
1372	void *cookie;
1373	int type;
1374
1375	nvl = nvlist_create(0);
1376	ATF_REQUIRE(nvl != NULL);
1377	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1378	ATF_REQUIRE(nvlist_empty(nvl));
1379
1380	cookie = NULL;
1381	key = "name";
1382
1383	nvlist_add_string_array(nvl, key, in_array, 4);
1384	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
1385	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1386	ATF_REQUIRE_EQ(type, NV_TYPE_STRING_ARRAY);
1387	ATF_REQUIRE(!nvlist_empty(nvl));
1388	ATF_REQUIRE(nvlist_exists(nvl, key));
1389	ATF_REQUIRE(nvlist_exists_string_array(nvl, key));
1390	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
1391	    static_cast<const char *>(NULL));
1392
1393	cookie = NULL;
1394	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
1395	cnvlist_free_string_array(cookie);
1396
1397	cookie = NULL;
1398	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1399	ATF_REQUIRE(nvlist_empty(nvl));
1400	ATF_REQUIRE(!nvlist_exists(nvl, key));
1401	ATF_REQUIRE(!nvlist_exists_string_array(nvl, key));
1402	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
1403	    static_cast<const char *>(NULL));
1404
1405	nvlist_destroy(nvl);
1406}
1407
1408ATF_TEST_CASE_WITHOUT_HEAD(cnvlist_free_nvlist_array);
1409ATF_TEST_CASE_BODY(cnvlist_free_nvlist_array)
1410{
1411	nvlist_t *testnvl[8];
1412	nvlist_t *nvl;
1413	void *cookie;
1414	unsigned int i;
1415	int type;
1416	const char *somestr[8] = { "a", "b", "c", "d", "e", "f", "g", "h" };
1417	const char *key;
1418
1419	for (i = 0; i < 8; i++) {
1420		testnvl[i] = nvlist_create(0);
1421		ATF_REQUIRE(testnvl[i] != NULL);
1422		ATF_REQUIRE_EQ(nvlist_error(testnvl[i]), 0);
1423		ATF_REQUIRE(nvlist_empty(testnvl[i]));
1424		nvlist_add_string(testnvl[i], "nvl/string", somestr[i]);
1425
1426		cookie = NULL;
1427		ATF_REQUIRE_EQ(strcmp("nvl/string", nvlist_next(testnvl[i],
1428		    &type, &cookie)), 0);
1429		ATF_REQUIRE_EQ(nvlist_error(testnvl[i]), 0);
1430		ATF_REQUIRE_EQ(type, NV_TYPE_STRING);
1431		ATF_REQUIRE(!nvlist_empty(testnvl[i]));
1432		ATF_REQUIRE(nvlist_exists(testnvl[i], "nvl/string"));
1433		ATF_REQUIRE(nvlist_exists_string(testnvl[i], "nvl/string"));
1434		ATF_REQUIRE_EQ(nvlist_next(testnvl[i], &type, &cookie),
1435		    static_cast<const char *>(NULL));
1436	}
1437
1438	nvl = nvlist_create(0);
1439	ATF_REQUIRE(nvl != NULL);
1440	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1441	ATF_REQUIRE(nvlist_empty(nvl));
1442
1443	key = "nvl/nvlist";
1444	cookie = NULL;
1445
1446	nvlist_add_nvlist_array(nvl, key, (const nvlist_t * const *)testnvl, 8);
1447	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
1448	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1449	ATF_REQUIRE_EQ(type, NV_TYPE_NVLIST_ARRAY);
1450	ATF_REQUIRE(!nvlist_empty(nvl));
1451	ATF_REQUIRE(nvlist_exists(nvl, key));
1452	ATF_REQUIRE(nvlist_exists_nvlist_array(nvl, key));
1453	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
1454	    static_cast<const char *>(NULL));
1455
1456	cookie = NULL;
1457	ATF_REQUIRE_EQ(strcmp(key, nvlist_next(nvl, &type, &cookie)), 0);
1458	cnvlist_free_nvlist_array(cookie);
1459
1460	cookie = NULL;
1461	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
1462	ATF_REQUIRE(nvlist_empty(nvl));
1463	ATF_REQUIRE(!nvlist_exists(nvl, key));
1464	ATF_REQUIRE(!nvlist_exists_nvlist_array(nvl, key));
1465	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &cookie),
1466	    static_cast<const char *>(NULL));
1467
1468	for (i = 0; i < 8; i++)
1469		nvlist_destroy(testnvl[i]);
1470	nvlist_destroy(nvl);
1471}
1472
1473ATF_INIT_TEST_CASES(tp)
1474{
1475	ATF_ADD_TEST_CASE(tp, cnvlist_get_bool);
1476	ATF_ADD_TEST_CASE(tp, cnvlist_get_bool_array);
1477	ATF_ADD_TEST_CASE(tp, cnvlist_get_number);
1478	ATF_ADD_TEST_CASE(tp, cnvlist_get_string);
1479	ATF_ADD_TEST_CASE(tp, cnvlist_get_nvlist);
1480	ATF_ADD_TEST_CASE(tp, cnvlist_get_descriptor);
1481	ATF_ADD_TEST_CASE(tp, cnvlist_get_binary);
1482	ATF_ADD_TEST_CASE(tp, cnvlist_get_number_array);
1483	ATF_ADD_TEST_CASE(tp, cnvlist_get_string_array);
1484	ATF_ADD_TEST_CASE(tp, cnvlist_get_nvlist_array);
1485	ATF_ADD_TEST_CASE(tp, cnvlist_get_descriptor_array);
1486	ATF_ADD_TEST_CASE(tp, cnvlist_take_bool);
1487	ATF_ADD_TEST_CASE(tp, cnvlist_take_number);
1488	ATF_ADD_TEST_CASE(tp, cnvlist_take_string);
1489	ATF_ADD_TEST_CASE(tp, cnvlist_take_nvlist);
1490	ATF_ADD_TEST_CASE(tp, cnvlist_take_binary);
1491	ATF_ADD_TEST_CASE(tp, cnvlist_take_bool_array);
1492	ATF_ADD_TEST_CASE(tp, cnvlist_take_number_array);
1493	ATF_ADD_TEST_CASE(tp, cnvlist_take_string_array);
1494	ATF_ADD_TEST_CASE(tp, cnvlist_take_nvlist_array);
1495	ATF_ADD_TEST_CASE(tp, cnvlist_free_bool);
1496	ATF_ADD_TEST_CASE(tp, cnvlist_free_number);
1497	ATF_ADD_TEST_CASE(tp, cnvlist_free_string);
1498	ATF_ADD_TEST_CASE(tp, cnvlist_free_nvlist);
1499	ATF_ADD_TEST_CASE(tp, cnvlist_free_binary);
1500	ATF_ADD_TEST_CASE(tp, cnvlist_free_bool_array);
1501	ATF_ADD_TEST_CASE(tp, cnvlist_free_number_array);
1502	ATF_ADD_TEST_CASE(tp, cnvlist_free_string_array);
1503	ATF_ADD_TEST_CASE(tp, cnvlist_free_nvlist_array);
1504}
1505