1279424Srstone/*-
2279424Srstone * Copyright (c) 2014-2015 Sandvine Inc.  All rights reserved.
3279424Srstone * All rights reserved.
4279424Srstone *
5279424Srstone * Redistribution and use in source and binary forms, with or without
6279424Srstone * modification, are permitted provided that the following conditions
7279424Srstone * are met:
8279424Srstone * 1. Redistributions of source code must retain the above copyright
9279424Srstone *    notice, this list of conditions and the following disclaimer.
10279424Srstone * 2. Redistributions in binary form must reproduce the above copyright
11279424Srstone *    notice, this list of conditions and the following disclaimer in the
12279424Srstone *    documentation and/or other materials provided with the distribution.
13279424Srstone *
14279424Srstone * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15279424Srstone * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16279424Srstone * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17279424Srstone * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18279424Srstone * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19279424Srstone * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20279424Srstone * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21279424Srstone * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22279424Srstone * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23279424Srstone * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24279424Srstone * SUCH DAMAGE.
25279424Srstone */
26279424Srstone
27279424Srstone#include <sys/cdefs.h>
28279424Srstone__FBSDID("$FreeBSD: releng/10.3/lib/libnv/tests/nv_tests.cc 292637 2015-12-22 23:21:06Z ngie $");
29279424Srstone
30279424Srstone#include <atf-c++.hpp>
31279424Srstone#include <nv.h>
32279424Srstone
33279424Srstone#include <errno.h>
34292634Sngie#include <limits>
35292634Sngie#include <set>
36292634Sngie#include <sstream>
37292634Sngie#include <string>
38292634Sngie
39279424Srstone/*
40279424Srstone * Test that a newly created nvlist has no errors, and is empty.
41279424Srstone */
42279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_create__is_empty);
43279424SrstoneATF_TEST_CASE_BODY(nvlist_create__is_empty)
44279424Srstone{
45279424Srstone	nvlist_t *nvl;
46279424Srstone	int type;
47279424Srstone	void *it;
48279424Srstone
49279424Srstone	nvl = nvlist_create(0);
50279424Srstone
51279424Srstone	ATF_REQUIRE(nvl != NULL);
52279424Srstone
53279424Srstone	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
54279424Srstone	ATF_REQUIRE(nvlist_empty(nvl));
55279424Srstone
56279424Srstone	it = NULL;
57292637Sngie	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &it), static_cast<const char *>(NULL));
58279424Srstone
59279424Srstone	nvlist_destroy(nvl);
60279424Srstone}
61279424Srstone
62279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_add_null__single_insert);
63279424SrstoneATF_TEST_CASE_BODY(nvlist_add_null__single_insert)
64279424Srstone{
65279424Srstone	nvlist_t *nvl;
66279424Srstone	void *it;
67279424Srstone	const char *key;
68279424Srstone	int type;
69279424Srstone
70279424Srstone	key = "key";
71279424Srstone	nvl = nvlist_create(0);
72279424Srstone
73279424Srstone	ATF_REQUIRE(nvl != NULL);
74279424Srstone	ATF_REQUIRE(!nvlist_exists(nvl, key));
75279424Srstone
76279424Srstone	nvlist_add_null(nvl, key);
77279424Srstone
78279424Srstone	ATF_REQUIRE(!nvlist_empty(nvl));
79279424Srstone	ATF_REQUIRE(nvlist_exists(nvl, key));
80279424Srstone	ATF_REQUIRE(nvlist_exists_null(nvl, key));
81292637Sngie	ATF_REQUIRE(nvlist_exists_null(nvl, "key"));
82279424Srstone
83279424Srstone	/* Iterate over the nvlist; ensure that it has only our one key. */
84279424Srstone	it = NULL;
85279424Srstone	ATF_REQUIRE_EQ(strcmp(nvlist_next(nvl, &type, &it), key), 0);
86279424Srstone	ATF_REQUIRE_EQ(type, NV_TYPE_NULL);
87292637Sngie	ATF_REQUIRE_EQ(nvlist_next(nvl, &type,&it), static_cast<const char *>(NULL));
88279424Srstone
89279424Srstone	nvlist_destroy(nvl);
90279424Srstone}
91279424Srstone
92279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_add_bool__single_insert);
93279424SrstoneATF_TEST_CASE_BODY(nvlist_add_bool__single_insert)
94279424Srstone{
95279424Srstone	nvlist_t *nvl;
96279424Srstone	void *it;
97279424Srstone	const char *key;
98279424Srstone	int type;
99279424Srstone
100279424Srstone	key = "name";
101279424Srstone	nvl = nvlist_create(0);
102279424Srstone
103279424Srstone	ATF_REQUIRE(nvl != NULL);
104279424Srstone	ATF_REQUIRE(!nvlist_exists(nvl, key));
105279424Srstone
106279424Srstone	nvlist_add_bool(nvl, key, true);
107279424Srstone
108279424Srstone	ATF_REQUIRE(!nvlist_empty(nvl));
109279424Srstone	ATF_REQUIRE(nvlist_exists(nvl, key));
110292637Sngie	ATF_REQUIRE(nvlist_exists(nvl, "name"));
111279424Srstone	ATF_REQUIRE(nvlist_exists_bool(nvl, key));
112292637Sngie	ATF_REQUIRE(nvlist_exists_bool(nvl, "name"));
113279424Srstone	ATF_REQUIRE_EQ(nvlist_get_bool(nvl, key), true);
114279424Srstone
115279424Srstone	/* Iterate over the nvlist; ensure that it has only our one key. */
116279424Srstone	it = NULL;
117279424Srstone	ATF_REQUIRE_EQ(strcmp(nvlist_next(nvl, &type, &it), key), 0);
118279424Srstone	ATF_REQUIRE_EQ(type, NV_TYPE_BOOL);
119292637Sngie	ATF_REQUIRE_EQ(nvlist_next(nvl, &type,&it), static_cast<const char *>(NULL));
120279424Srstone
121279424Srstone	nvlist_destroy(nvl);
122279424Srstone}
123279424Srstone
124279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_add_number__single_insert);
125279424SrstoneATF_TEST_CASE_BODY(nvlist_add_number__single_insert)
126279424Srstone{
127279424Srstone	nvlist_t *nvl;
128279424Srstone	void *it;
129279424Srstone	const char *key;
130279424Srstone	uint64_t value;
131279424Srstone	int type;
132279424Srstone
133279424Srstone	key = "foo123";
134279424Srstone	value = 71965;
135279424Srstone	nvl = nvlist_create(0);
136279424Srstone
137279424Srstone	ATF_REQUIRE(nvl != NULL);
138279424Srstone	ATF_REQUIRE(!nvlist_exists(nvl, key));
139279424Srstone
140279424Srstone	nvlist_add_number(nvl, key, value);
141279424Srstone
142279424Srstone	ATF_REQUIRE(!nvlist_empty(nvl));
143279424Srstone	ATF_REQUIRE(nvlist_exists(nvl, key));
144292637Sngie	ATF_REQUIRE(nvlist_exists(nvl, "foo123"));
145279424Srstone	ATF_REQUIRE(nvlist_exists_number(nvl, key));
146279424Srstone	ATF_REQUIRE_EQ(nvlist_get_number(nvl, key), value);
147279424Srstone
148279424Srstone	/* Iterate over the nvlist; ensure that it has only our one key. */
149279424Srstone	it = NULL;
150279424Srstone	ATF_REQUIRE_EQ(strcmp(nvlist_next(nvl, &type, &it), key), 0);
151279424Srstone	ATF_REQUIRE_EQ(type, NV_TYPE_NUMBER);
152292637Sngie	ATF_REQUIRE_EQ(nvlist_next(nvl, &type,&it), static_cast<const char *>(NULL));
153279424Srstone
154279424Srstone	nvlist_destroy(nvl);
155279424Srstone}
156279424Srstone
157279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_add_string__single_insert);
158279424SrstoneATF_TEST_CASE_BODY(nvlist_add_string__single_insert)
159279424Srstone{
160279424Srstone	nvlist_t *nvl;
161279424Srstone	void *it;
162279424Srstone	const char *key;
163279424Srstone	const char *value;
164279424Srstone	int type;
165279424Srstone
166279424Srstone	key = "test";
167279424Srstone	value = "fgjdkgjdk";
168279424Srstone	nvl = nvlist_create(0);
169279424Srstone
170279424Srstone	ATF_REQUIRE(nvl != NULL);
171279424Srstone	ATF_REQUIRE(!nvlist_exists(nvl, key));
172279424Srstone
173279424Srstone	nvlist_add_string(nvl, key, value);
174279424Srstone
175279424Srstone	ATF_REQUIRE(!nvlist_empty(nvl));
176279424Srstone	ATF_REQUIRE(nvlist_exists(nvl, key));
177292637Sngie	ATF_REQUIRE(nvlist_exists(nvl, "test"));
178279424Srstone	ATF_REQUIRE(nvlist_exists_string(nvl, key));
179292637Sngie	ATF_REQUIRE(nvlist_exists_string(nvl, "test"));
180279424Srstone	ATF_REQUIRE_EQ(strcmp(nvlist_get_string(nvl, key), value), 0);
181279424Srstone
182279424Srstone	/* nvlist_add_* is required to clone the value, so check for that. */
183279424Srstone	ATF_REQUIRE(nvlist_get_string(nvl, key) != value);
184279424Srstone
185279424Srstone	/* Iterate over the nvlist; ensure that it has only our one key. */
186279424Srstone	it = NULL;
187279424Srstone	ATF_REQUIRE_EQ(strcmp(nvlist_next(nvl, &type, &it), key), 0);
188279424Srstone	ATF_REQUIRE_EQ(type, NV_TYPE_STRING);
189292637Sngie	ATF_REQUIRE_EQ(nvlist_next(nvl, &type,&it), static_cast<const char *>(NULL));
190279424Srstone
191279424Srstone	nvlist_destroy(nvl);
192279424Srstone}
193279424Srstone
194279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_add_nvlist__single_insert);
195279424SrstoneATF_TEST_CASE_BODY(nvlist_add_nvlist__single_insert)
196279424Srstone{
197279424Srstone	nvlist_t *nvl;
198279424Srstone	void *it;
199279424Srstone	const char *key, *subkey;
200279424Srstone	nvlist_t *sublist;
201279424Srstone	const nvlist_t *value;
202279424Srstone	int type;
203279424Srstone
204279424Srstone	key = "test";
205279424Srstone	subkey = "subkey";
206279424Srstone	sublist = nvlist_create(0);
207279424Srstone	nvl = nvlist_create(0);
208279424Srstone
209279424Srstone	ATF_REQUIRE(nvl != NULL);
210279424Srstone	ATF_REQUIRE(!nvlist_exists(nvl, key));
211279424Srstone
212279424Srstone	nvlist_add_null(sublist, subkey);
213279424Srstone	nvlist_add_nvlist(nvl, key, sublist);
214279424Srstone
215279424Srstone	ATF_REQUIRE(!nvlist_empty(nvl));
216279424Srstone	ATF_REQUIRE(nvlist_exists(nvl, key));
217292637Sngie	ATF_REQUIRE(nvlist_exists(nvl, "test"));
218279424Srstone	ATF_REQUIRE(nvlist_exists_nvlist(nvl, key));
219292637Sngie	ATF_REQUIRE(nvlist_exists_nvlist(nvl, "test"));
220279424Srstone
221279424Srstone	value = nvlist_get_nvlist(nvl, key);
222279424Srstone	ATF_REQUIRE(nvlist_exists_null(value, subkey));
223279424Srstone
224279424Srstone	/* nvlist_add_* is required to clone the value, so check for that. */
225279424Srstone	ATF_REQUIRE(sublist != value);
226279424Srstone
227279424Srstone	/* Iterate over the nvlist; ensure that it has only our one key. */
228279424Srstone	it = NULL;
229279424Srstone	ATF_REQUIRE_EQ(strcmp(nvlist_next(nvl, &type, &it), key), 0);
230279424Srstone	ATF_REQUIRE_EQ(type, NV_TYPE_NVLIST);
231292637Sngie	ATF_REQUIRE_EQ(nvlist_next(nvl, &type,&it), static_cast<const char *>(NULL));
232279424Srstone
233279424Srstone	nvlist_destroy(sublist);
234279424Srstone	nvlist_destroy(nvl);
235279424Srstone}
236279424Srstone
237292637SngieATF_TEST_CASE_WITHOUT_HEAD(nvlist_add_nvlist__child_with_error);
238292637SngieATF_TEST_CASE_BODY(nvlist_add_nvlist__child_with_error)
239292637Sngie{
240292637Sngie	nvlist_t *nvl, *parent;
241292637Sngie
242292637Sngie	nvl = nvlist_create(0);
243292637Sngie	parent = nvlist_create(0);
244292637Sngie
245292637Sngie	nvlist_set_error(nvl, EBADF);
246292637Sngie	nvlist_add_nvlist(parent, "test", nvl);
247292637Sngie	ATF_REQUIRE_EQ(nvlist_error(parent), EBADF);
248292637Sngie
249292637Sngie	nvlist_destroy(nvl);
250292637Sngie	nvlist_destroy(parent);
251292637Sngie}
252292637Sngie
253279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_add_binary__single_insert);
254279424SrstoneATF_TEST_CASE_BODY(nvlist_add_binary__single_insert)
255279424Srstone{
256279424Srstone	nvlist_t *nvl;
257279424Srstone	void *it;
258279424Srstone	const char *key;
259279424Srstone	void *value;
260279424Srstone	const void *ret_value;
261279424Srstone	size_t value_size, ret_size;
262279424Srstone	int type;
263279424Srstone
264279424Srstone	key = "binary";
265279424Srstone	value_size = 13;
266279424Srstone	value = malloc(value_size);
267279424Srstone	memset(value, 0xa5, value_size);
268279424Srstone	nvl = nvlist_create(0);
269279424Srstone
270279424Srstone	ATF_REQUIRE(nvl != NULL);
271279424Srstone	ATF_REQUIRE(!nvlist_exists(nvl, key));
272279424Srstone
273279424Srstone	nvlist_add_binary(nvl, key, value, value_size);
274279424Srstone
275279424Srstone	ATF_REQUIRE(!nvlist_empty(nvl));
276279424Srstone	ATF_REQUIRE(nvlist_exists(nvl, key));
277292637Sngie	ATF_REQUIRE(nvlist_exists(nvl, "binary"));
278279424Srstone	ATF_REQUIRE(nvlist_exists_binary(nvl, key));
279292637Sngie	ATF_REQUIRE(nvlist_exists_binary(nvl, "binary"));
280279424Srstone
281279424Srstone	ret_value = nvlist_get_binary(nvl, key, &ret_size);
282279424Srstone	ATF_REQUIRE_EQ(value_size, ret_size);
283279424Srstone	ATF_REQUIRE_EQ(memcmp(value, ret_value, ret_size), 0);
284279424Srstone
285279424Srstone	/* nvlist_add_* is required to clone the value, so check for that. */
286279424Srstone	ATF_REQUIRE(value != ret_value);
287279424Srstone
288279424Srstone	/* Iterate over the nvlist; ensure that it has only our one key. */
289279424Srstone	it = NULL;
290279424Srstone	ATF_REQUIRE_EQ(strcmp(nvlist_next(nvl, &type, &it), key), 0);
291279424Srstone	ATF_REQUIRE_EQ(type, NV_TYPE_BINARY);
292292637Sngie	ATF_REQUIRE_EQ(nvlist_next(nvl, &type,&it), static_cast<const char *>(NULL));
293279424Srstone
294279424Srstone	nvlist_destroy(nvl);
295279424Srstone	free(value);
296279424Srstone}
297279424Srstone
298292634SngieATF_TEST_CASE_WITHOUT_HEAD(nvlist_clone__empty_nvlist);
299292634SngieATF_TEST_CASE_BODY(nvlist_clone__empty_nvlist)
300292634Sngie{
301292634Sngie	nvlist_t *nvl, *clone;
302292634Sngie
303292634Sngie	nvl = nvlist_create(0);
304292634Sngie	ATF_REQUIRE(nvl != NULL);
305292634Sngie
306292634Sngie	clone = nvlist_clone(nvl);
307292634Sngie	ATF_REQUIRE(clone != NULL);
308292634Sngie	ATF_REQUIRE(clone != nvl);
309292634Sngie	ATF_REQUIRE(nvlist_empty(clone));
310292634Sngie
311292634Sngie	nvlist_destroy(clone);
312292634Sngie	nvlist_destroy(nvl);
313292634Sngie}
314292634Sngie
315292634SngieATF_TEST_CASE_WITHOUT_HEAD(nvlist_clone__nonempty_nvlist);
316292634SngieATF_TEST_CASE_BODY(nvlist_clone__nonempty_nvlist)
317292634Sngie{
318292634Sngie	nvlist_t *nvl, *clone;
319292634Sngie	const char *key;
320292634Sngie	void *it;
321292634Sngie	uint64_t value;
322292634Sngie	int type;
323292634Sngie
324292634Sngie	nvl = nvlist_create(0);
325292634Sngie	ATF_REQUIRE(nvl != NULL);
326292634Sngie
327292634Sngie	key = "testkey";
328292634Sngie	value = 684874;
329292634Sngie	nvlist_add_number(nvl, key, value);
330292634Sngie
331292634Sngie	clone = nvlist_clone(nvl);
332292634Sngie	ATF_REQUIRE(clone != NULL);
333292634Sngie	ATF_REQUIRE(clone != nvl);
334292634Sngie	ATF_REQUIRE(nvlist_exists_number(clone, key));
335292634Sngie	ATF_REQUIRE_EQ(nvlist_get_number(clone, key), value);
336292634Sngie
337292634Sngie	/* Iterate over the nvlist; ensure that it has only our one key. */
338292634Sngie	it = NULL;
339292634Sngie	ATF_REQUIRE_EQ(strcmp(nvlist_next(clone, &type, &it), key), 0);
340292634Sngie	ATF_REQUIRE_EQ(type, NV_TYPE_NUMBER);
341292637Sngie	ATF_REQUIRE_EQ(nvlist_next(clone, &type, &it), static_cast<const char *>(NULL));
342292634Sngie
343292634Sngie	nvlist_destroy(clone);
344292634Sngie	nvlist_destroy(nvl);
345292634Sngie}
346292634Sngie
347292634Sngiestatic const char * const test_subnvlist_key = "nvlist";
348292634Sngie
349292634Sngiestatic const char * const test_string_key = "string";
350292634Sngiestatic const char * const test_string_val = "59525";
351292634Sngie
352292634Sngiestatic nvlist_t*
353292634Sngiecreate_test_nvlist(void)
354292634Sngie{
355292634Sngie	nvlist_t *nvl, *sublist;
356292634Sngie
357292634Sngie	nvl = nvlist_create(0);
358292634Sngie	ATF_REQUIRE(nvl != NULL);
359292634Sngie
360292634Sngie	sublist = nvlist_create(0);
361292634Sngie	ATF_REQUIRE(sublist != NULL);
362292634Sngie
363292634Sngie	nvlist_add_string(sublist, test_string_key, test_string_val);
364292634Sngie	nvlist_move_nvlist(nvl, test_subnvlist_key, sublist);
365292634Sngie
366292634Sngie	return (nvl);
367292634Sngie}
368292634Sngie
369292634Sngiestatic void
370292634Sngieverify_test_nvlist(const nvlist_t *nvl)
371292634Sngie{
372292634Sngie	void *it;
373292634Sngie	const nvlist_t *value;
374292634Sngie	int type;
375292634Sngie
376292634Sngie	ATF_REQUIRE(nvlist_exists_nvlist(nvl, test_subnvlist_key));
377292634Sngie
378292634Sngie	value = nvlist_get_nvlist(nvl, test_subnvlist_key);
379292634Sngie
380292634Sngie	ATF_REQUIRE(nvlist_exists_string(value, test_string_key));
381292634Sngie	ATF_REQUIRE_EQ(strcmp(nvlist_get_string(value, test_string_key), test_string_val), 0);
382292634Sngie	ATF_REQUIRE(nvlist_get_string(value, test_string_key) != test_string_val);
383292634Sngie
384292634Sngie	/* Iterate over both nvlists; ensure that each has only the one key. */
385292634Sngie	it = NULL;
386292634Sngie	ATF_REQUIRE_EQ(strcmp(nvlist_next(value, &type, &it),
387292634Sngie	    test_string_key), 0);
388292634Sngie	ATF_REQUIRE_EQ(type, NV_TYPE_STRING);
389292637Sngie	ATF_REQUIRE_EQ(nvlist_next(value, &type, &it), static_cast<const char *>(NULL));
390292634Sngie
391292634Sngie	it = NULL;
392292634Sngie	ATF_REQUIRE_EQ(strcmp(nvlist_next(nvl, &type, &it),
393292634Sngie	    test_subnvlist_key), 0);
394292634Sngie	ATF_REQUIRE_EQ(type, NV_TYPE_NVLIST);
395292637Sngie	ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &it), static_cast<const char *>(NULL));
396292634Sngie}
397292634Sngie
398292634SngieATF_TEST_CASE_WITHOUT_HEAD(nvlist_clone__nested_nvlist);
399292634SngieATF_TEST_CASE_BODY(nvlist_clone__nested_nvlist)
400292634Sngie{
401292634Sngie	nvlist_t *nvl, *clone;
402292634Sngie
403292634Sngie	nvl = create_test_nvlist();
404292634Sngie	clone = nvlist_clone(nvl);
405292634Sngie
406292634Sngie	ATF_REQUIRE(clone != NULL);
407292634Sngie	ATF_REQUIRE(clone != nvl);
408292634Sngie	verify_test_nvlist(clone);
409292634Sngie
410292634Sngie	nvlist_destroy(clone);
411292634Sngie	nvlist_destroy(nvl);
412292634Sngie}
413292634Sngie
414292637SngieATF_TEST_CASE_WITHOUT_HEAD(nvlist_clone__error_nvlist);
415292637SngieATF_TEST_CASE_BODY(nvlist_clone__error_nvlist)
416292637Sngie{
417292637Sngie	nvlist_t *nvl, *clone;
418292637Sngie
419292637Sngie	nvl = nvlist_create(0);
420292637Sngie	ATF_REQUIRE(nvl != NULL);
421292637Sngie
422292637Sngie	nvlist_set_error(nvl, ENOMEM);
423292637Sngie
424292637Sngie	clone = nvlist_clone(nvl);
425292637Sngie	ATF_REQUIRE(clone == NULL);
426292637Sngie
427292637Sngie	nvlist_destroy(nvl);
428292637Sngie}
429292637Sngie
430292634SngieATF_TEST_CASE_WITHOUT_HEAD(nvlist_pack__empty_nvlist);
431292634SngieATF_TEST_CASE_BODY(nvlist_pack__empty_nvlist)
432292634Sngie{
433292634Sngie	nvlist_t *nvl, *unpacked;
434292634Sngie	void *packed;
435292634Sngie	size_t packed_size;
436292634Sngie
437292634Sngie	nvl = nvlist_create(0);
438292634Sngie	ATF_REQUIRE(nvl != NULL);
439292634Sngie
440292634Sngie	packed = nvlist_pack(nvl, &packed_size);
441292634Sngie	ATF_REQUIRE(packed != NULL);
442292634Sngie
443292634Sngie	unpacked = nvlist_unpack(packed, packed_size);
444292634Sngie	ATF_REQUIRE(unpacked != NULL);
445292634Sngie	ATF_REQUIRE(unpacked != nvl);
446292634Sngie	ATF_REQUIRE(nvlist_empty(unpacked));
447292634Sngie
448292634Sngie	nvlist_destroy(unpacked);
449292634Sngie	nvlist_destroy(nvl);
450292634Sngie	free(packed);
451292634Sngie}
452292634Sngie
453292634Sngiestatic void
454292634Sngieverify_null(const nvlist_t *nvl, int type)
455292634Sngie{
456292634Sngie
457292634Sngie	ATF_REQUIRE_EQ(type, NV_TYPE_NULL);
458292634Sngie}
459292634Sngie
460292634Sngiestatic void
461292634Sngieverify_number(const nvlist_t *nvl, const char *name, int type, uint64_t value)
462292634Sngie{
463292634Sngie
464292634Sngie	ATF_REQUIRE_EQ(type, NV_TYPE_NUMBER);
465292634Sngie	ATF_REQUIRE_EQ(nvlist_get_number(nvl, name), value);
466292634Sngie}
467292634Sngie
468292634Sngiestatic void
469292634Sngieverify_string(const nvlist_t *nvl, const char *name, int type,
470292634Sngie    const char * value)
471292634Sngie{
472292634Sngie
473292634Sngie	ATF_REQUIRE_EQ(type, NV_TYPE_STRING);
474292634Sngie	ATF_REQUIRE_EQ(strcmp(nvlist_get_string(nvl, name), value), 0);
475292634Sngie}
476292634Sngie
477292634Sngiestatic void
478292634Sngieverify_nvlist(const nvlist_t *nvl, const char *name, int type)
479292634Sngie{
480292634Sngie
481292634Sngie	ATF_REQUIRE_EQ(type, NV_TYPE_NVLIST);
482292634Sngie	verify_test_nvlist(nvlist_get_nvlist(nvl, name));
483292634Sngie}
484292634Sngie
485292634Sngiestatic void
486292634Sngieverify_binary(const nvlist_t *nvl, const char *name, int type,
487292634Sngie    const void * value, size_t size)
488292634Sngie{
489292634Sngie	const void *actual_value;
490292634Sngie	size_t actual_size;
491292634Sngie
492292634Sngie	ATF_REQUIRE_EQ(type, NV_TYPE_BINARY);
493292634Sngie	actual_value = nvlist_get_binary(nvl, name, &actual_size);
494292634Sngie	ATF_REQUIRE_EQ(size, actual_size);
495292634Sngie	ATF_REQUIRE_EQ(memcmp(value, actual_value, size), 0);
496292634Sngie}
497292634Sngie
498292634SngieATF_TEST_CASE_WITHOUT_HEAD(nvlist_pack__multiple_values);
499292634SngieATF_TEST_CASE_BODY(nvlist_pack__multiple_values)
500292634Sngie{
501292634Sngie	std::ostringstream msg;
502292634Sngie	std::set<std::string> keys_seen;
503292634Sngie	nvlist_t *nvl, *unpacked, *nvvalue;
504292634Sngie	const char *nullkey, *numkey, *strkey, *nvkey, *binkey, *name;
505292634Sngie	int numvalue;
506292634Sngie	const char * strvalue;
507292634Sngie	void *binvalue, *packed, *it;
508292634Sngie	size_t binsize, packed_size;
509292634Sngie	int type;
510292634Sngie
511292634Sngie	nvl = nvlist_create(0);
512292634Sngie
513292634Sngie	nullkey = "null";
514292634Sngie	nvlist_add_null(nvl, nullkey);
515292634Sngie
516292634Sngie	numkey = "number";
517292634Sngie	numvalue = 939853984;
518292634Sngie	nvlist_add_number(nvl, numkey, numvalue);
519292634Sngie
520292634Sngie	strkey = "string";
521292634Sngie	strvalue = "jfieutijf";
522292634Sngie	nvlist_add_string(nvl, strkey, strvalue);
523292634Sngie
524292634Sngie	nvkey = "nvlist";
525292634Sngie	nvvalue = create_test_nvlist();
526292634Sngie	nvlist_move_nvlist(nvl, nvkey, nvvalue);
527292634Sngie
528292634Sngie	binkey = "binary";
529292634Sngie	binsize = 4;
530292634Sngie	binvalue = malloc(binsize);
531292634Sngie	memset(binvalue, 'b', binsize);
532292634Sngie	nvlist_move_binary(nvl, binkey, binvalue, binsize);
533292634Sngie
534292634Sngie	packed = nvlist_pack(nvl, &packed_size);
535292634Sngie	ATF_REQUIRE(packed != NULL);
536292634Sngie
537292634Sngie	unpacked = nvlist_unpack(packed, packed_size);
538292634Sngie	ATF_REQUIRE(unpacked != 0);
539292634Sngie
540292634Sngie	it = NULL;
541292634Sngie	while ((name = nvlist_next(unpacked, &type, &it)) != NULL) {
542292634Sngie		/* Ensure that we see every key only once. */
543292634Sngie		ATF_REQUIRE_EQ(keys_seen.count(name), 0);
544292634Sngie
545292634Sngie		if (strcmp(name, nullkey) == 0)
546292634Sngie			verify_null(unpacked, type);
547292634Sngie		else if (strcmp(name, numkey) == 0)
548292634Sngie			verify_number(unpacked, name, type, numvalue);
549292634Sngie		else if (strcmp(name, strkey) == 0)
550292634Sngie			verify_string(unpacked, name, type, strvalue);
551292634Sngie		else if (strcmp(name, nvkey) == 0)
552292634Sngie			verify_nvlist(unpacked, name, type);
553292634Sngie		else if (strcmp(name, binkey) == 0)
554292634Sngie			verify_binary(unpacked, name, type, binvalue, binsize);
555292634Sngie		else {
556292634Sngie			msg << "Unexpected key :'" << name << "'";
557292634Sngie			ATF_FAIL(msg.str().c_str());
558292634Sngie		}
559292634Sngie
560292634Sngie		keys_seen.insert(name);
561292634Sngie	}
562292634Sngie
563292634Sngie	/* Ensure that we saw every key. */
564292634Sngie	ATF_REQUIRE_EQ(keys_seen.size(), 5);
565292634Sngie
566292634Sngie	nvlist_destroy(nvl);
567292634Sngie	nvlist_destroy(unpacked);
568292634Sngie	free(packed);
569292634Sngie}
570292634Sngie
571292637SngieATF_TEST_CASE_WITHOUT_HEAD(nvlist_pack__error_nvlist);
572292637SngieATF_TEST_CASE_BODY(nvlist_pack__error_nvlist)
573292634Sngie{
574292634Sngie	nvlist_t *nvl;
575279424Srstone	void *packed;
576292637Sngie	size_t size;
577279424Srstone
578279424Srstone	nvl = nvlist_create(0);
579279424Srstone	ATF_REQUIRE(nvl != NULL);
580279424Srstone
581292637Sngie	nvlist_set_error(nvl, ENOMEM);
582279424Srstone
583292637Sngie	packed = nvlist_pack(nvl, &size);
584292637Sngie	ATF_REQUIRE(packed == NULL);
585279424Srstone
586279424Srstone	nvlist_destroy(nvl);
587279424Srstone}
588279424Srstone
589279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_unpack__duplicate_key);
590279424SrstoneATF_TEST_CASE_BODY(nvlist_unpack__duplicate_key)
591279424Srstone{
592279424Srstone	nvlist_t *nvl, *unpacked;
593279424Srstone	const char *key1, *key2;
594279424Srstone	void *packed, *keypos;
595279424Srstone	size_t size, keylen;
596279424Srstone
597279424Srstone	nvl = nvlist_create(0);
598279424Srstone
599279424Srstone	key1 = "key1";
600279424Srstone	keylen = strlen(key1);
601279424Srstone	nvlist_add_number(nvl, key1, 5);
602279424Srstone
603279424Srstone	key2 = "key2";
604279424Srstone	ATF_REQUIRE_EQ(keylen, strlen(key2));
605279424Srstone	nvlist_add_number(nvl, key2, 10);
606279424Srstone
607279424Srstone	packed = nvlist_pack(nvl, &size);
608279424Srstone
609279424Srstone	/*
610279424Srstone	 * Mangle the packed nvlist by replacing key1 with key2, creating a
611279424Srstone	 * packed nvlist with a duplicate key.
612279424Srstone	 */
613279424Srstone	keypos = memmem(packed, size, key1, keylen);
614279424Srstone	ATF_REQUIRE(keypos != NULL);
615279424Srstone	memcpy(keypos, key2, keylen);
616279424Srstone
617279424Srstone	unpacked = nvlist_unpack(packed, size);
618279424Srstone	ATF_REQUIRE(nvlist_error(unpacked) != 0);
619279424Srstone
620279424Srstone	free(packed);
621279424Srstone	nvlist_destroy(nvl);
622279424Srstone	nvlist_destroy(unpacked);
623279424Srstone}
624279424Srstone
625279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_move_string__single_insert);
626279424SrstoneATF_TEST_CASE_BODY(nvlist_move_string__single_insert)
627279424Srstone{
628279424Srstone	nvlist_t *nvl;
629279424Srstone	const char *key;
630279424Srstone	char *value;
631279424Srstone
632279424Srstone	nvl = nvlist_create(0);
633279424Srstone	ATF_REQUIRE(nvl != NULL);
634279424Srstone
635279424Srstone	key = "testkey";
636279424Srstone	value = strdup("testval");
637279424Srstone	ATF_REQUIRE(value != NULL);
638279424Srstone
639279424Srstone	nvlist_move_string(nvl, key, value);
640279424Srstone	ATF_REQUIRE_EQ(nvlist_get_string(nvl, key), value);
641279424Srstone
642279424Srstone	nvlist_destroy(nvl);
643279424Srstone}
644279424Srstone
645279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_move_nvlist__null_child);
646279424SrstoneATF_TEST_CASE_BODY(nvlist_move_nvlist__null_child)
647279424Srstone{
648279424Srstone	nvlist_t *parent;
649279424Srstone
650279424Srstone	parent = nvlist_create(0);
651279424Srstone
652279424Srstone	nvlist_move_nvlist(parent, "test", NULL);
653279424Srstone
654279424Srstone	ATF_REQUIRE(nvlist_error(parent) != 0);
655279424Srstone
656279424Srstone	nvlist_destroy(parent);
657279424Srstone}
658279424Srstone
659292637SngieATF_TEST_CASE_WITHOUT_HEAD(nvlist_move_nvlist__child_with_error);
660292637SngieATF_TEST_CASE_BODY(nvlist_move_nvlist__child_with_error)
661292637Sngie{
662292637Sngie	nvlist_t *nvl, *parent;
663292637Sngie
664292637Sngie	nvl = nvlist_create(0);
665292637Sngie	parent = nvlist_create(0);
666292637Sngie
667292637Sngie	nvlist_set_error(nvl, EBADF);
668292637Sngie	nvlist_move_nvlist(parent, "test", nvl);
669292637Sngie	ATF_REQUIRE_EQ(nvlist_error(parent), EBADF);
670292637Sngie
671292637Sngie	nvlist_destroy(parent);
672292637Sngie}
673292637Sngie
674279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_move_nvlist__single_insert);
675279424SrstoneATF_TEST_CASE_BODY(nvlist_move_nvlist__single_insert)
676279424Srstone{
677279424Srstone	nvlist_t *nvl;
678279424Srstone	const char *key;
679279424Srstone	nvlist_t *value;
680279424Srstone
681279424Srstone	nvl = nvlist_create(0);
682279424Srstone	ATF_REQUIRE(nvl != NULL);
683279424Srstone
684279424Srstone	key = "testkey";
685279424Srstone	value = nvlist_create(0);
686279424Srstone	ATF_REQUIRE(value != NULL);
687279424Srstone
688279424Srstone	nvlist_move_nvlist(nvl, key, value);
689279424Srstone	ATF_REQUIRE_EQ(nvlist_get_nvlist(nvl, key), value);
690279424Srstone
691279424Srstone	nvlist_destroy(nvl);
692279424Srstone}
693279424Srstone
694279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_move_binary__single_insert);
695279424SrstoneATF_TEST_CASE_BODY(nvlist_move_binary__single_insert)
696279424Srstone{
697279424Srstone	nvlist_t *nvl;
698279424Srstone	const char *key;
699279424Srstone	void *value;
700279424Srstone	size_t size, actual_size;
701279424Srstone
702279424Srstone	nvl = nvlist_create(0);
703279424Srstone	ATF_REQUIRE(nvl != NULL);
704279424Srstone
705279424Srstone	key = "testkey";
706279424Srstone	size = 73;
707279424Srstone	value = malloc(size);
708279424Srstone	ATF_REQUIRE(value != NULL);
709279424Srstone
710279424Srstone	nvlist_move_binary(nvl, key, value, size);
711279424Srstone	ATF_REQUIRE_EQ(nvlist_get_binary(nvl, key, &actual_size), value);
712279424Srstone	ATF_REQUIRE_EQ(size, actual_size);
713279424Srstone
714279424Srstone	nvlist_destroy(nvl);
715279424Srstone}
716279424Srstone
717279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_take_bool__single_remove);
718279424SrstoneATF_TEST_CASE_BODY(nvlist_take_bool__single_remove)
719279424Srstone{
720279424Srstone	nvlist_t *nvl;
721279424Srstone	const char *testkey;
722279424Srstone	bool testval;
723279424Srstone
724279424Srstone	nvl = nvlist_create(0);
725279424Srstone	ATF_REQUIRE(nvl != NULL);
726279424Srstone
727279424Srstone	testkey = "boolkey";
728279424Srstone	testval = false;
729279424Srstone	nvlist_add_bool(nvl, testkey, testval);
730279424Srstone
731279424Srstone	ATF_REQUIRE_EQ(nvlist_take_bool(nvl, testkey), testval);
732279424Srstone	ATF_REQUIRE(nvlist_empty(nvl));
733279424Srstone
734279424Srstone	nvlist_destroy(nvl);
735279424Srstone}
736279424Srstone
737279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_take_bool__other_keys_unchanged);
738279424SrstoneATF_TEST_CASE_BODY(nvlist_take_bool__other_keys_unchanged)
739279424Srstone{
740279424Srstone	nvlist_t *nvl;
741279424Srstone	const char *testkey, *otherkey1, *otherkey2;
742279424Srstone	bool testval, otherval1;
743279424Srstone	nvlist_t *otherval2;
744279424Srstone
745279424Srstone	nvl = nvlist_create(0);
746279424Srstone	ATF_REQUIRE(nvl != NULL);
747279424Srstone
748279424Srstone	testkey = "boolkey";
749279424Srstone	testval = true;
750279424Srstone	nvlist_add_bool(nvl, testkey, testval);
751279424Srstone
752279424Srstone	otherkey1 = "key1";
753279424Srstone	otherval1 = false;
754279424Srstone	nvlist_add_bool(nvl, otherkey1, otherval1);
755279424Srstone
756279424Srstone	otherkey2 = "key2";
757279424Srstone	otherval2 = create_test_nvlist();
758279424Srstone	nvlist_move_nvlist(nvl, otherkey2, otherval2);
759279424Srstone
760279424Srstone	ATF_REQUIRE_EQ(nvlist_take_bool(nvl, testkey), testval);
761279424Srstone
762279424Srstone	ATF_REQUIRE(nvlist_exists_bool(nvl, otherkey1));
763279424Srstone	ATF_REQUIRE_EQ(nvlist_get_bool(nvl, otherkey1), otherval1);
764279424Srstone
765279424Srstone	ATF_REQUIRE(nvlist_exists_nvlist(nvl, otherkey2));
766279424Srstone	verify_test_nvlist(nvlist_get_nvlist(nvl, otherkey2));
767279424Srstone
768279424Srstone	nvlist_destroy(nvl);
769279424Srstone}
770279424Srstone
771279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_take_number__single_remove);
772279424SrstoneATF_TEST_CASE_BODY(nvlist_take_number__single_remove)
773279424Srstone{
774279424Srstone	nvlist_t *nvl;
775279424Srstone	const char *testkey;
776279424Srstone	uint64_t testval;
777279424Srstone
778279424Srstone	nvl = nvlist_create(0);
779279424Srstone	ATF_REQUIRE(nvl != NULL);
780279424Srstone
781279424Srstone	testkey = "numkey";
782279424Srstone	testval = std::numeric_limits<uint64_t>::max();
783279424Srstone	nvlist_add_number(nvl, testkey, testval);
784279424Srstone
785279424Srstone	ATF_REQUIRE_EQ(nvlist_take_number(nvl, testkey), testval);
786279424Srstone	ATF_REQUIRE(nvlist_empty(nvl));
787279424Srstone
788279424Srstone	nvlist_destroy(nvl);
789279424Srstone}
790279424Srstone
791279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_take_number__other_keys_unchanged);
792279424SrstoneATF_TEST_CASE_BODY(nvlist_take_number__other_keys_unchanged)
793279424Srstone{
794279424Srstone	nvlist_t *nvl;
795279424Srstone	const char *testkey, *otherkey1, *otherkey2;
796279424Srstone	uint64_t testval, otherval1;
797279424Srstone	const char *otherval2;
798279424Srstone
799279424Srstone	nvl = nvlist_create(0);
800279424Srstone	ATF_REQUIRE(nvl != NULL);
801279424Srstone
802279424Srstone	otherkey1 = "key1";
803279424Srstone	otherval1 = 5;
804279424Srstone	nvlist_add_number(nvl, otherkey1, otherval1);
805279424Srstone
806279424Srstone	testkey = "numkey";
807279424Srstone	testval = 1654;
808279424Srstone	nvlist_add_number(nvl, testkey, testval);
809279424Srstone
810279424Srstone	otherkey2 = "key2";
811279424Srstone	otherval2 = "string";
812279424Srstone	nvlist_add_string(nvl, otherkey2, otherval2);
813279424Srstone
814279424Srstone	ATF_REQUIRE_EQ(nvlist_take_number(nvl, testkey), testval);
815279424Srstone
816279424Srstone	ATF_REQUIRE(nvlist_exists_number(nvl, otherkey1));
817279424Srstone	ATF_REQUIRE_EQ(nvlist_get_number(nvl, otherkey1), otherval1);
818279424Srstone
819279424Srstone	ATF_REQUIRE(nvlist_exists_string(nvl, otherkey2));
820279424Srstone	ATF_REQUIRE_EQ(strcmp(nvlist_get_string(nvl, otherkey2), otherval2), 0);
821279424Srstone
822279424Srstone	nvlist_destroy(nvl);
823279424Srstone}
824279424Srstone
825279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_take_string__single_remove);
826279424SrstoneATF_TEST_CASE_BODY(nvlist_take_string__single_remove)
827279424Srstone{
828279424Srstone	nvlist_t *nvl;
829279424Srstone	const char *testkey;
830279424Srstone	const char *testval;
831279424Srstone
832279424Srstone	nvl = nvlist_create(0);
833279424Srstone	ATF_REQUIRE(nvl != NULL);
834279424Srstone
835279424Srstone	testkey = "numkey";
836279424Srstone	testval = "nvlist";
837279424Srstone	nvlist_add_string(nvl, testkey, testval);
838279424Srstone
839279424Srstone	ATF_REQUIRE_EQ(strcmp(nvlist_take_string(nvl, testkey), testval), 0);
840279424Srstone	ATF_REQUIRE(nvlist_empty(nvl));
841279424Srstone
842279424Srstone	nvlist_destroy(nvl);
843279424Srstone}
844279424Srstone
845279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_take_string__other_keys_unchanged);
846279424SrstoneATF_TEST_CASE_BODY(nvlist_take_string__other_keys_unchanged)
847279424Srstone{
848279424Srstone	nvlist_t *nvl;
849279424Srstone	const char *testkey, *otherkey1, *otherkey2;
850279424Srstone	const char *testval, *otherval1;
851279424Srstone	bool otherval2;
852279424Srstone
853279424Srstone	nvl = nvlist_create(0);
854279424Srstone	ATF_REQUIRE(nvl != NULL);
855279424Srstone
856279424Srstone	otherkey1 = "key1";
857279424Srstone	otherval1 = "fjdifjdk";
858279424Srstone	nvlist_add_string(nvl, otherkey1, otherval1);
859279424Srstone
860279424Srstone	otherkey2 = "key2";
861279424Srstone	otherval2 = true;
862279424Srstone	nvlist_add_bool(nvl, otherkey2, otherval2);
863279424Srstone
864279424Srstone	testkey = "strkey";
865279424Srstone	testval = "1654";
866279424Srstone	nvlist_add_string(nvl, testkey, testval);
867279424Srstone
868279424Srstone	ATF_REQUIRE_EQ(strcmp(nvlist_take_string(nvl, testkey), testval), 0);
869279424Srstone
870279424Srstone	ATF_REQUIRE(nvlist_exists_string(nvl, otherkey1));
871279424Srstone	ATF_REQUIRE_EQ(strcmp(nvlist_get_string(nvl, otherkey1), otherval1), 0);
872279424Srstone
873279424Srstone	ATF_REQUIRE(nvlist_exists_bool(nvl, otherkey2));
874279424Srstone	ATF_REQUIRE_EQ(nvlist_get_bool(nvl, otherkey2), otherval2);
875279424Srstone
876279424Srstone	nvlist_destroy(nvl);
877279424Srstone}
878279424Srstone
879279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_take_nvlist__single_remove);
880279424SrstoneATF_TEST_CASE_BODY(nvlist_take_nvlist__single_remove)
881279424Srstone{
882279424Srstone	nvlist_t *nvl;
883279424Srstone	const char *testkey;
884279424Srstone	nvlist_t *testval;
885279424Srstone
886279424Srstone	nvl = nvlist_create(0);
887279424Srstone	ATF_REQUIRE(nvl != NULL);
888279424Srstone
889279424Srstone	testkey = "numkey";
890279424Srstone	testval = create_test_nvlist();
891279424Srstone	nvlist_move_nvlist(nvl, testkey, testval);
892279424Srstone
893279424Srstone	verify_test_nvlist(nvlist_take_nvlist(nvl, testkey));
894279424Srstone	ATF_REQUIRE(nvlist_empty(nvl));
895279424Srstone
896279424Srstone	nvlist_destroy(nvl);
897279424Srstone}
898279424Srstone
899279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_take_nvlist__other_keys_unchanged);
900279424SrstoneATF_TEST_CASE_BODY(nvlist_take_nvlist__other_keys_unchanged)
901279424Srstone{
902279424Srstone	nvlist_t *nvl;
903279424Srstone	const char *testkey, *otherkey1, *otherkey2;
904279424Srstone	nvlist_t *testval, *otherval1;
905279424Srstone
906279424Srstone	nvl = nvlist_create(0);
907279424Srstone	ATF_REQUIRE(nvl != NULL);
908279424Srstone
909279424Srstone	testkey = "strkey";
910279424Srstone	testval = create_test_nvlist();
911279424Srstone	nvlist_move_nvlist(nvl, testkey, testval);
912279424Srstone
913279424Srstone	otherkey1 = "key1";
914279424Srstone	otherval1 = nvlist_create(0);
915279424Srstone	nvlist_move_nvlist(nvl, otherkey1, otherval1);
916279424Srstone
917279424Srstone	otherkey2 = "key2";
918279424Srstone	nvlist_add_null(nvl, otherkey2);
919279424Srstone
920279424Srstone	verify_test_nvlist(nvlist_take_nvlist(nvl, testkey));
921279424Srstone
922279424Srstone	ATF_REQUIRE(nvlist_exists_nvlist(nvl, otherkey1));
923279424Srstone	ATF_REQUIRE(nvlist_empty(nvlist_get_nvlist(nvl, otherkey1)));
924279424Srstone
925279424Srstone	ATF_REQUIRE(nvlist_exists_null(nvl, otherkey2));
926279424Srstone
927279424Srstone	nvlist_destroy(nvl);
928279424Srstone}
929279424Srstone
930279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_take_binary__single_remove);
931279424SrstoneATF_TEST_CASE_BODY(nvlist_take_binary__single_remove)
932279424Srstone{
933279424Srstone	nvlist_t *nvl;
934279424Srstone	const char *testkey;
935279424Srstone	void *testval;
936279424Srstone	const void *actual_val;
937279424Srstone	size_t testsize, actual_size;
938279424Srstone
939279424Srstone	nvl = nvlist_create(0);
940279424Srstone	ATF_REQUIRE(nvl != NULL);
941279424Srstone
942279424Srstone	testkey = "numkey";
943279424Srstone	testsize = 457;
944279424Srstone	testval = malloc(testsize);
945279424Srstone	memset(testval, '5', testsize);
946279424Srstone	nvlist_move_binary(nvl, testkey, testval, testsize);
947279424Srstone
948279424Srstone	actual_val = nvlist_take_binary(nvl, testkey, &actual_size);
949279424Srstone	ATF_REQUIRE_EQ(testsize, actual_size);
950279424Srstone	ATF_REQUIRE_EQ(memcmp(actual_val, testval, testsize), 0);
951279424Srstone	ATF_REQUIRE(nvlist_empty(nvl));
952279424Srstone
953279424Srstone	nvlist_destroy(nvl);
954279424Srstone}
955279424Srstone
956279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_take_binary__other_keys_unchanged);
957279424SrstoneATF_TEST_CASE_BODY(nvlist_take_binary__other_keys_unchanged)
958279424Srstone{
959279424Srstone	nvlist_t *nvl;
960279424Srstone	const char *testkey, *otherkey1, *otherkey2;
961279424Srstone	const void *actual_value;
962279424Srstone	char testval[] = "gjiertj";
963279424Srstone	char otherval1[] = "fdreg";
964279424Srstone	size_t testsize, othersize, actual_size;
965279424Srstone	bool otherval2;
966279424Srstone
967279424Srstone	nvl = nvlist_create(0);
968279424Srstone	ATF_REQUIRE(nvl != NULL);
969279424Srstone
970279424Srstone	otherkey1 = "key1";
971279424Srstone	othersize = sizeof(otherval1);
972279424Srstone	nvlist_add_binary(nvl, otherkey1, otherval1, othersize);
973279424Srstone
974279424Srstone	otherkey2 = "key2";
975279424Srstone	otherval2 = true;
976279424Srstone	nvlist_add_bool(nvl, otherkey2, otherval2);
977279424Srstone
978279424Srstone	testkey = "strkey";
979279424Srstone	testsize = sizeof(testval);
980279424Srstone	nvlist_add_binary(nvl, testkey, testval, testsize);
981279424Srstone
982279424Srstone	actual_value = nvlist_take_binary(nvl, testkey, &actual_size);
983279424Srstone	ATF_REQUIRE_EQ(testsize, actual_size);
984279424Srstone	ATF_REQUIRE_EQ(memcmp(actual_value, testval, testsize), 0);
985279424Srstone
986279424Srstone	ATF_REQUIRE(nvlist_exists_binary(nvl, otherkey1));
987279424Srstone	actual_value = nvlist_get_binary(nvl, otherkey1, &actual_size);
988279424Srstone	ATF_REQUIRE_EQ(othersize, actual_size);
989279424Srstone	ATF_REQUIRE_EQ(memcmp(actual_value, otherval1, othersize), 0);
990279424Srstone
991279424Srstone	ATF_REQUIRE(nvlist_exists_bool(nvl, otherkey2));
992279424Srstone	ATF_REQUIRE_EQ(nvlist_get_bool(nvl, otherkey2), otherval2);
993279424Srstone
994279424Srstone	nvlist_destroy(nvl);
995279424Srstone}
996279424Srstone
997279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_free__single_null);
998279424SrstoneATF_TEST_CASE_BODY(nvlist_free__single_null)
999279424Srstone{
1000279424Srstone	nvlist_t *nvl;
1001279424Srstone	const char *key;
1002279424Srstone
1003279424Srstone	nvl = nvlist_create(0);
1004279424Srstone	key = "test";
1005279424Srstone	nvlist_add_null(nvl, key);
1006279424Srstone
1007279424Srstone	nvlist_free(nvl, key);
1008279424Srstone	ATF_REQUIRE(nvlist_empty(nvl));
1009279424Srstone
1010279424Srstone	nvlist_destroy(nvl);
1011279424Srstone}
1012279424Srstone
1013279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_free__single_bool);
1014279424SrstoneATF_TEST_CASE_BODY(nvlist_free__single_bool)
1015279424Srstone{
1016279424Srstone	nvlist_t *nvl;
1017279424Srstone	const char *key;
1018279424Srstone
1019279424Srstone	nvl = nvlist_create(0);
1020279424Srstone	key = "test";
1021279424Srstone	nvlist_add_bool(nvl, key, true);
1022279424Srstone
1023279424Srstone	nvlist_free(nvl, key);
1024279424Srstone	ATF_REQUIRE(nvlist_empty(nvl));
1025279424Srstone
1026279424Srstone	nvlist_destroy(nvl);
1027279424Srstone}
1028279424Srstone
1029279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_free__single_number);
1030279424SrstoneATF_TEST_CASE_BODY(nvlist_free__single_number)
1031279424Srstone{
1032279424Srstone	nvlist_t *nvl;
1033279424Srstone	const char *key;
1034279424Srstone
1035279424Srstone	nvl = nvlist_create(0);
1036279424Srstone	key = "test";
1037279424Srstone	nvlist_add_number(nvl, key, 584);
1038279424Srstone
1039279424Srstone	nvlist_free(nvl, key);
1040279424Srstone	ATF_REQUIRE(nvlist_empty(nvl));
1041279424Srstone
1042279424Srstone	nvlist_destroy(nvl);
1043279424Srstone}
1044279424Srstone
1045279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_free__single_string);
1046279424SrstoneATF_TEST_CASE_BODY(nvlist_free__single_string)
1047279424Srstone{
1048279424Srstone	nvlist_t *nvl;
1049279424Srstone	const char *key;
1050279424Srstone
1051279424Srstone	nvl = nvlist_create(0);
1052279424Srstone	key = "test";
1053279424Srstone	nvlist_add_string(nvl, key, "gjkfkjd");
1054279424Srstone
1055279424Srstone	nvlist_free(nvl, key);
1056279424Srstone	ATF_REQUIRE(nvlist_empty(nvl));
1057279424Srstone
1058279424Srstone	nvlist_destroy(nvl);
1059279424Srstone}
1060279424Srstone
1061279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_free__single_nvlist);
1062279424SrstoneATF_TEST_CASE_BODY(nvlist_free__single_nvlist)
1063279424Srstone{
1064279424Srstone	nvlist_t *nvl;
1065279424Srstone	const char *key;
1066279424Srstone
1067279424Srstone	nvl = nvlist_create(0);
1068279424Srstone	key = "test";
1069279424Srstone	nvlist_add_nvlist(nvl, key, nvlist_create(0));
1070279424Srstone
1071279424Srstone	nvlist_free(nvl, key);
1072279424Srstone	ATF_REQUIRE(nvlist_empty(nvl));
1073279424Srstone
1074279424Srstone	nvlist_destroy(nvl);
1075279424Srstone}
1076279424Srstone
1077279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_free__single_binary);
1078279424SrstoneATF_TEST_CASE_BODY(nvlist_free__single_binary)
1079279424Srstone{
1080279424Srstone	nvlist_t *nvl;
1081279424Srstone	const char *key;
1082279424Srstone
1083279424Srstone	nvl = nvlist_create(0);
1084279424Srstone	key = "test";
1085279424Srstone	nvlist_add_binary(nvl, key, "jgjgfd", 6);
1086279424Srstone
1087279424Srstone	nvlist_free(nvl, key);
1088279424Srstone	ATF_REQUIRE(nvlist_empty(nvl));
1089279424Srstone
1090279424Srstone	nvlist_destroy(nvl);
1091279424Srstone}
1092279424Srstone
1093279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_free_null__single_null);
1094279424SrstoneATF_TEST_CASE_BODY(nvlist_free_null__single_null)
1095279424Srstone{
1096279424Srstone	nvlist_t *nvl;
1097279424Srstone	const char *key;
1098279424Srstone
1099279424Srstone	nvl = nvlist_create(0);
1100279424Srstone	key = "test";
1101279424Srstone	nvlist_add_null(nvl, key);
1102279424Srstone
1103279424Srstone	nvlist_free_null(nvl, key);
1104279424Srstone	ATF_REQUIRE(nvlist_empty(nvl));
1105279424Srstone
1106279424Srstone	nvlist_destroy(nvl);
1107279424Srstone}
1108279424Srstone
1109279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_free_bool__single_bool);
1110279424SrstoneATF_TEST_CASE_BODY(nvlist_free_bool__single_bool)
1111279424Srstone{
1112279424Srstone	nvlist_t *nvl;
1113279424Srstone	const char *key;
1114279424Srstone
1115279424Srstone	nvl = nvlist_create(0);
1116279424Srstone	key = "test";
1117279424Srstone	nvlist_add_bool(nvl, key, true);
1118279424Srstone
1119279424Srstone	nvlist_free_bool(nvl, key);
1120279424Srstone	ATF_REQUIRE(nvlist_empty(nvl));
1121279424Srstone
1122279424Srstone	nvlist_destroy(nvl);
1123279424Srstone}
1124279424Srstone
1125279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_free_number__single_number);
1126279424SrstoneATF_TEST_CASE_BODY(nvlist_free_number__single_number)
1127279424Srstone{
1128279424Srstone	nvlist_t *nvl;
1129279424Srstone	const char *key;
1130279424Srstone
1131279424Srstone	nvl = nvlist_create(0);
1132279424Srstone	key = "test";
1133279424Srstone	nvlist_add_number(nvl, key, 584);
1134279424Srstone
1135279424Srstone	nvlist_free_number(nvl, key);
1136279424Srstone	ATF_REQUIRE(nvlist_empty(nvl));
1137279424Srstone
1138279424Srstone	nvlist_destroy(nvl);
1139279424Srstone}
1140279424Srstone
1141279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_free_string__single_string);
1142279424SrstoneATF_TEST_CASE_BODY(nvlist_free_string__single_string)
1143279424Srstone{
1144279424Srstone	nvlist_t *nvl;
1145279424Srstone	const char *key;
1146279424Srstone
1147279424Srstone	nvl = nvlist_create(0);
1148279424Srstone	key = "test";
1149279424Srstone	nvlist_add_string(nvl, key, "gjkfkjd");
1150279424Srstone
1151279424Srstone	nvlist_free_string(nvl, key);
1152279424Srstone	ATF_REQUIRE(nvlist_empty(nvl));
1153279424Srstone
1154279424Srstone	nvlist_destroy(nvl);
1155279424Srstone}
1156279424Srstone
1157279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_free_nvlist__single_nvlist);
1158279424SrstoneATF_TEST_CASE_BODY(nvlist_free_nvlist__single_nvlist)
1159279424Srstone{
1160279424Srstone	nvlist_t *nvl;
1161279424Srstone	const char *key;
1162279424Srstone
1163279424Srstone	nvl = nvlist_create(0);
1164279424Srstone	key = "test";
1165279424Srstone	nvlist_add_nvlist(nvl, key, nvlist_create(0));
1166279424Srstone
1167279424Srstone	nvlist_free_nvlist(nvl, key);
1168279424Srstone	ATF_REQUIRE(nvlist_empty(nvl));
1169279424Srstone
1170279424Srstone	nvlist_destroy(nvl);
1171279424Srstone}
1172279424Srstone
1173279424SrstoneATF_TEST_CASE_WITHOUT_HEAD(nvlist_free_binary__single_binary);
1174279424SrstoneATF_TEST_CASE_BODY(nvlist_free_binary__single_binary)
1175279424Srstone{
1176279424Srstone	nvlist_t *nvl;
1177279424Srstone	const char *key;
1178279424Srstone
1179279424Srstone	nvl = nvlist_create(0);
1180279424Srstone	key = "test";
1181279424Srstone	nvlist_add_binary(nvl, key, "jgjgfd", 6);
1182279424Srstone
1183279424Srstone	nvlist_free_binary(nvl, key);
1184279424Srstone	ATF_REQUIRE(nvlist_empty(nvl));
1185279424Srstone
1186279424Srstone	nvlist_destroy(nvl);
1187279424Srstone}
1188279424Srstone
1189279424SrstoneATF_INIT_TEST_CASES(tp)
1190279424Srstone{
1191279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_create__is_empty);
1192279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_add_null__single_insert);
1193279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_add_bool__single_insert);
1194279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_add_number__single_insert);
1195279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_add_string__single_insert);
1196279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_add_nvlist__single_insert);
1197292637Sngie	ATF_ADD_TEST_CASE(tp, nvlist_add_nvlist__child_with_error);
1198279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_add_binary__single_insert);
1199279424Srstone
1200279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_clone__empty_nvlist);
1201279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_clone__nonempty_nvlist);
1202279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_clone__nested_nvlist);
1203292637Sngie	ATF_ADD_TEST_CASE(tp, nvlist_clone__error_nvlist);
1204279424Srstone
1205279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_pack__empty_nvlist);
1206279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_pack__multiple_values);
1207292637Sngie	ATF_ADD_TEST_CASE(tp, nvlist_pack__error_nvlist);
1208279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_unpack__duplicate_key);
1209279424Srstone
1210279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_move_string__single_insert);
1211279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_move_nvlist__single_insert);
1212279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_move_nvlist__null_child);
1213292637Sngie	ATF_ADD_TEST_CASE(tp, nvlist_move_nvlist__child_with_error);
1214279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_move_binary__single_insert);
1215279424Srstone
1216279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_take_bool__single_remove);
1217279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_take_bool__other_keys_unchanged);
1218279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_take_number__single_remove);
1219279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_take_number__other_keys_unchanged);
1220279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_take_string__single_remove);
1221279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_take_string__other_keys_unchanged);
1222279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_take_nvlist__single_remove);
1223279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_take_nvlist__other_keys_unchanged);
1224279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_take_binary__single_remove);
1225279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_take_binary__other_keys_unchanged);
1226279424Srstone
1227279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_free__single_null);
1228279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_free__single_bool);
1229279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_free__single_number);
1230279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_free__single_string);
1231279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_free__single_nvlist);
1232279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_free__single_binary);
1233279424Srstone
1234279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_free_null__single_null);
1235279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_free_bool__single_bool);
1236279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_free_number__single_number);
1237279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_free_string__single_string);
1238279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_free_nvlist__single_nvlist);
1239279424Srstone	ATF_ADD_TEST_CASE(tp, nvlist_free_binary__single_binary);
1240279424Srstone}
1241