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