Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 15 Aug 2015 06:34:50 +0000 (UTC)
From:      Mariusz Zaborski <oshogbo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r286796 - in head: lib/libnv/tests share/man/man9 sys/cddl/compat/opensolaris/sys sys/contrib/libnv sys/sys
Message-ID:  <201508150634.t7F6Yopc003939@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: oshogbo
Date: Sat Aug 15 06:34:49 2015
New Revision: 286796
URL: https://svnweb.freebsd.org/changeset/base/286796

Log:
  Add support for the arrays in nvlist library.
  
  - Add
    nvlist_{add,get,take,move,exists,free}_{number,bool,string,nvlist,
    descriptor} functions.
  - Add support for (un)packing arrays.
  - Add the nvl_array_next field to the nvlist structure.
    If an array is added by the nvlist_{move,add}_nvlist_array function
    this field will contains next element in the array.
  - Add the nitems field to the nvpair and nvpair_header structure.
    This field contains number of elements in the array.
  - Add special flag (NV_FLAG_IN_ARRAY) which is set if nvlist is a part of
    an array.
  - Add special type (NV_TYPE_NVLIST_ARRAY_NEXT).This type is used only
    on packing/unpacking.
  - Add new API for traversing arrays (nvlist_get_array_next).
  - Add the nvlist_get_pararr function which combines the
    nvlist_get_array_next and nvlist_get_parent functions. If nvlist is in
    the array it will return next element from array. If nvlist is last
    element in array or it isn't in array it will return his
    container (parent). This function should simplify traveling over nvlist.
  - Add tests for new features.
  - Add documentation for new functions.
  - Add my copyright.
  - Regenerate the sys/cddl/compat/opensolaris/sys/nvpair.h file.
  
  PR:		191083
  Reviewed by:	allanjude (doc)
  Approved by:	pjd (mentor)

Added:
  head/lib/libnv/tests/nv_array_tests.cc   (contents, props changed)
Modified:
  head/lib/libnv/tests/Makefile
  head/share/man/man9/nv.9
  head/sys/cddl/compat/opensolaris/sys/nvpair.h
  head/sys/contrib/libnv/nv_impl.h
  head/sys/contrib/libnv/nvlist.c
  head/sys/contrib/libnv/nvlist_impl.h
  head/sys/contrib/libnv/nvpair.c
  head/sys/contrib/libnv/nvpair_impl.h
  head/sys/sys/nv.h

Modified: head/lib/libnv/tests/Makefile
==============================================================================
--- head/lib/libnv/tests/Makefile	Sat Aug 15 00:42:33 2015	(r286795)
+++ head/lib/libnv/tests/Makefile	Sat Aug 15 06:34:49 2015	(r286796)
@@ -4,6 +4,7 @@ TESTSDIR=	${TESTSBASE}/lib/libnv
 
 ATF_TESTS_CXX=	\
 	dnv_tests \
+	nv_array_tests \
 	nv_tests \
 
 TAP_TESTS_C+=	nvlist_add_test

Added: head/lib/libnv/tests/nv_array_tests.cc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libnv/tests/nv_array_tests.cc	Sat Aug 15 06:34:49 2015	(r286796)
@@ -0,0 +1,1191 @@
+/*-
+ * Copyright (c) 2015 Mariusz Zaborski <oshogbo@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/nv.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <atf-c++.hpp>
+
+#include <cstdio>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits>
+#include <set>
+#include <sstream>
+#include <string>
+
+#define fd_is_valid(fd) (fcntl((fd), F_GETFL) != -1 || errno != EBADF)
+
+ATF_TEST_CASE_WITHOUT_HEAD(nvlist_bool_array__basic);
+ATF_TEST_CASE_BODY(nvlist_bool_array__basic)
+{
+	bool testbool[16];
+	const bool *const_result;
+	bool *result;
+	nvlist_t *nvl;
+	size_t nitems;
+	unsigned int i;
+	const char *key;
+
+	key = "nvl/bool";
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	ATF_REQUIRE(nvlist_empty(nvl));
+	ATF_REQUIRE(!nvlist_exists_string_array(nvl, key));
+
+	for (i = 0; i < 16; i++)
+		testbool[i] = (i % 2 == 0);
+
+	nvlist_add_bool_array(nvl, key, testbool, 16);
+	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
+	ATF_REQUIRE(!nvlist_empty(nvl));
+	ATF_REQUIRE(nvlist_exists_bool_array(nvl, key));
+	ATF_REQUIRE(nvlist_exists_bool_array(nvl, "nvl/bool"));
+
+	const_result = nvlist_get_bool_array(nvl, key, &nitems);
+	ATF_REQUIRE_EQ(nitems, 16);
+	ATF_REQUIRE(const_result != NULL);
+	for (i = 0; i < nitems; i++)
+		ATF_REQUIRE_EQ(const_result[i], testbool[i]);
+
+	result = nvlist_take_bool_array(nvl, key, &nitems);
+	ATF_REQUIRE_EQ(nitems, 16);
+	ATF_REQUIRE(const_result != NULL);
+	for (i = 0; i < nitems; i++)
+		ATF_REQUIRE_EQ(result[i], testbool[i]);
+
+	ATF_REQUIRE(!nvlist_exists_bool_array(nvl, key));
+	ATF_REQUIRE(nvlist_empty(nvl));
+	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
+
+	free(result);
+	nvlist_destroy(nvl);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(nvlist_string_array__basic);
+ATF_TEST_CASE_BODY(nvlist_string_array__basic)
+{
+	const char * const *const_result;
+	char **result;
+	nvlist_t *nvl;
+	size_t nitems;
+	unsigned int i;
+	const char *key;
+	const char *string[8] = { "a", "b", "kot", "foo",
+	    "tests", "nice test", "", "abcdef" };
+
+	key = "nvl/string";
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	ATF_REQUIRE(nvlist_empty(nvl));
+	ATF_REQUIRE(!nvlist_exists_string_array(nvl, key));
+
+	nvlist_add_string_array(nvl, key, string, 8);
+	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
+	ATF_REQUIRE(!nvlist_empty(nvl));
+	ATF_REQUIRE(nvlist_exists_string_array(nvl, key));
+	ATF_REQUIRE(nvlist_exists_string_array(nvl, "nvl/string"));
+
+	const_result = nvlist_get_string_array(nvl, key, &nitems);
+	ATF_REQUIRE(!nvlist_empty(nvl));
+	ATF_REQUIRE(const_result != NULL);
+	ATF_REQUIRE(nitems == 8);
+	for (i = 0; i < nitems; i++) {
+		if (string[i] != NULL) {
+			ATF_REQUIRE(strcmp(const_result[i], string[i]) == 0);
+		} else {
+			ATF_REQUIRE(const_result[i] == string[i]);
+		}
+	}
+
+	result = nvlist_take_string_array(nvl, key, &nitems);
+	ATF_REQUIRE(result != NULL);
+	ATF_REQUIRE_EQ(nitems, 8);
+	for (i = 0; i < nitems; i++) {
+		if (string[i] != NULL) {
+			ATF_REQUIRE_EQ(strcmp(result[i], string[i]), 0);
+		} else {
+			ATF_REQUIRE_EQ(result[i], string[i]);
+		}
+	}
+
+	ATF_REQUIRE(!nvlist_exists_string_array(nvl, key));
+	ATF_REQUIRE(nvlist_empty(nvl));
+	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
+
+	for (i = 0; i < 8; i++)
+		free(result[i]);
+	free(result);
+	nvlist_destroy(nvl);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(nvlist_descriptor_array__basic);
+ATF_TEST_CASE_BODY(nvlist_descriptor_array__basic)
+{
+	int fd[32], *result;
+	const int *const_result;
+	nvlist_t *nvl;
+	size_t nitems;
+	unsigned int i;
+	const char *key;
+
+	for (i = 0; i < 32; i++) {
+		fd[i] = dup(STDERR_FILENO);
+		ATF_REQUIRE(fd_is_valid(fd[i]));
+	}
+
+	key = "nvl/descriptor";
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	ATF_REQUIRE(nvlist_empty(nvl));
+	ATF_REQUIRE(!nvlist_exists_descriptor_array(nvl, key));
+
+	nvlist_add_descriptor_array(nvl, key, fd, 32);
+	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
+	ATF_REQUIRE(!nvlist_empty(nvl));
+	ATF_REQUIRE(nvlist_exists_descriptor_array(nvl, key));
+	ATF_REQUIRE(nvlist_exists_descriptor_array(nvl, "nvl/descriptor"));
+
+	const_result = nvlist_get_descriptor_array(nvl, key, &nitems);
+	ATF_REQUIRE(!nvlist_empty(nvl));
+	ATF_REQUIRE(const_result != NULL);
+	ATF_REQUIRE(nitems == 32);
+	for (i = 0; i < nitems; i++) {
+		ATF_REQUIRE(fd_is_valid(const_result[i]));
+		if (i > 0)
+			ATF_REQUIRE(const_result[i] != const_result[i - 1]);
+	}
+
+	result = nvlist_take_descriptor_array(nvl, key, &nitems);
+	ATF_REQUIRE(result != NULL);
+	ATF_REQUIRE_EQ(nitems, 32);
+	for (i = 0; i < nitems; i++) {
+		ATF_REQUIRE(fd_is_valid(result[i]));
+		if (i > 0)
+			ATF_REQUIRE(const_result[i] != const_result[i - 1]);
+	}
+
+	ATF_REQUIRE(!nvlist_exists_string_array(nvl, key));
+	ATF_REQUIRE(nvlist_empty(nvl));
+	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
+
+	for (i = 0; i < nitems; i++) {
+		close(result[i]);
+		close(fd[i]);
+	}
+	free(result);
+	nvlist_destroy(nvl);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(nvlist_number_array__basic);
+ATF_TEST_CASE_BODY(nvlist_number_array__basic)
+{
+	const uint64_t *const_result;
+	uint64_t *result;
+	nvlist_t *nvl;
+	size_t nitems;
+	unsigned int i;
+	const char *key;
+	const uint64_t number[8] = { 0, UINT_MAX, 7, 123, 90,
+	    100000, 8, 1 };
+
+	key = "nvl/number";
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	ATF_REQUIRE(nvlist_empty(nvl));
+	ATF_REQUIRE(!nvlist_exists_string_array(nvl, key));
+
+	nvlist_add_number_array(nvl, key, number, 8);
+	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
+	ATF_REQUIRE(!nvlist_empty(nvl));
+	ATF_REQUIRE(nvlist_exists_number_array(nvl, key));
+	ATF_REQUIRE(nvlist_exists_number_array(nvl, "nvl/number"));
+
+	const_result = nvlist_get_number_array(nvl, key, &nitems);
+	ATF_REQUIRE(!nvlist_empty(nvl));
+	ATF_REQUIRE(const_result != NULL);
+	ATF_REQUIRE(nitems == 8);
+	for (i = 0; i < nitems; i++)
+		ATF_REQUIRE_EQ(const_result[i], number[i]);
+
+	result = nvlist_take_number_array(nvl, key, &nitems);
+	ATF_REQUIRE(result != NULL);
+	ATF_REQUIRE_EQ(nitems, 8);
+	for (i = 0; i < nitems; i++)
+		ATF_REQUIRE_EQ(result[i], number[i]);
+
+	ATF_REQUIRE(!nvlist_exists_string_array(nvl, key));
+	ATF_REQUIRE(nvlist_empty(nvl));
+	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
+
+	free(result);
+	nvlist_destroy(nvl);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(nvlist_nvlist_array__basic);
+ATF_TEST_CASE_BODY(nvlist_nvlist_array__basic)
+{
+	nvlist_t *testnvl[8];
+	const nvlist_t * const *const_result;
+	nvlist_t **result;
+	nvlist_t *nvl;
+	size_t nitems;
+	unsigned int i;
+	const char *somestr[8] = { "a", "b", "c", "d", "e", "f", "g", "h" };
+	const char *key;
+
+	for (i = 0; i < 8; i++) {
+		testnvl[i] = nvlist_create(0);
+		ATF_REQUIRE(testnvl[i] != NULL);
+		ATF_REQUIRE_EQ(nvlist_error(testnvl[i]), 0);
+		nvlist_add_string(testnvl[i], "nvl/string", somestr[i]);
+		ATF_REQUIRE_EQ(nvlist_error(testnvl[i]), 0);
+		ATF_REQUIRE(nvlist_exists_string(testnvl[i], "nvl/string"));
+	}
+
+	key = "nvl/nvlist";
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	ATF_REQUIRE(nvlist_empty(nvl));
+	ATF_REQUIRE(!nvlist_exists_string_array(nvl, key));
+
+	nvlist_add_nvlist_array(nvl, key, (const nvlist_t * const *)testnvl, 8);
+	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
+	ATF_REQUIRE(!nvlist_empty(nvl));
+	ATF_REQUIRE(nvlist_exists_nvlist_array(nvl, key));
+	ATF_REQUIRE(nvlist_exists_nvlist_array(nvl, "nvl/nvlist"));
+
+	const_result = nvlist_get_nvlist_array(nvl, key, &nitems);
+	ATF_REQUIRE(!nvlist_empty(nvl));
+	ATF_REQUIRE(const_result != NULL);
+	ATF_REQUIRE(nitems == 8);
+
+	for (i = 0; i < nitems; i++) {
+		ATF_REQUIRE_EQ(nvlist_error(const_result[i]), 0);
+		if (i < nitems - 1) {
+			ATF_REQUIRE(nvlist_get_array_next(const_result[i]) ==
+			    const_result[i + 1]);
+		} else {
+			ATF_REQUIRE(nvlist_get_array_next(const_result[i]) ==
+			    NULL);
+		}
+		ATF_REQUIRE(nvlist_get_parent(const_result[i], NULL) == nvl);
+		ATF_REQUIRE(nvlist_in_array(const_result[i]));
+		ATF_REQUIRE(nvlist_exists_string(const_result[i],
+		    "nvl/string"));
+		ATF_REQUIRE(strcmp(nvlist_get_string(const_result[i],
+		    "nvl/string"), somestr[i]) == 0);
+	}
+
+	result = nvlist_take_nvlist_array(nvl, key, &nitems);
+	ATF_REQUIRE(result != NULL);
+	ATF_REQUIRE_EQ(nitems, 8);
+	for (i = 0; i < nitems; i++) {
+		ATF_REQUIRE_EQ(nvlist_error(result[i]), 0);
+		ATF_REQUIRE(nvlist_get_array_next(result[i]) == NULL);
+		ATF_REQUIRE(nvlist_get_array_next(const_result[i]) == NULL);
+		ATF_REQUIRE(!nvlist_in_array(const_result[i]));
+	}
+
+	ATF_REQUIRE(!nvlist_exists_string_array(nvl, key));
+	ATF_REQUIRE(nvlist_empty(nvl));
+	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
+
+	for (i = 0; i < 8; i++) {
+		nvlist_destroy(result[i]);
+		nvlist_destroy(testnvl[i]);
+	}
+
+	free(result);
+	nvlist_destroy(nvl);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(nvlist_clone_array);
+ATF_TEST_CASE_BODY(nvlist_clone_array)
+{
+	nvlist_t *testnvl[8];
+	nvlist_t *src, *dst;
+	const nvlist_t *nvl;
+	bool testbool[16];
+	int testfd[16];
+	size_t i, nitems;
+	const char *string[8] = { "a", "b", "kot", "foo",
+	    "tests", "nice test", "", "abcdef" };
+	const char *somestr[8] = { "a", "b", "c", "d", "e", "f", "g", "h" };
+	const uint64_t number[8] = { 0, UINT_MAX, 7, 123, 90,
+	    100000, 8, 1 };
+
+	for (i = 0; i < 16; i++) {
+		testbool[i] = (i % 2 == 0);
+		testfd[i] = dup(STDERR_FILENO);
+		ATF_REQUIRE(fd_is_valid(testfd[i]));
+	}
+	for (i = 0; i < 8; i++) {
+		testnvl[i] = nvlist_create(0);
+		ATF_REQUIRE(nvlist_error(testnvl[i]) == 0);
+		nvlist_add_string(testnvl[i], "nvl/nvl/teststr", somestr[i]);
+		ATF_REQUIRE(nvlist_error(testnvl[i]) == 0);
+	}
+
+	src = nvlist_create(0);
+	ATF_REQUIRE(nvlist_error(src) == 0);
+
+	ATF_REQUIRE(!nvlist_exists_bool_array(src, "nvl/bool"));
+	nvlist_add_bool_array(src, "nvl/bool", testbool, 16);
+	ATF_REQUIRE_EQ(nvlist_error(src), 0);
+	ATF_REQUIRE(nvlist_exists_bool_array(src, "nvl/bool"));
+
+	ATF_REQUIRE(!nvlist_exists_string_array(src, "nvl/string"));
+	nvlist_add_string_array(src, "nvl/string", string, 8);
+	ATF_REQUIRE_EQ(nvlist_error(src), 0);
+	ATF_REQUIRE(nvlist_exists_string_array(src, "nvl/string"));
+
+	ATF_REQUIRE(!nvlist_exists_descriptor_array(src, "nvl/fd"));
+	nvlist_add_descriptor_array(src, "nvl/fd", testfd, 16);
+	ATF_REQUIRE_EQ(nvlist_error(src), 0);
+	ATF_REQUIRE(nvlist_exists_descriptor_array(src, "nvl/fd"));
+
+	ATF_REQUIRE(!nvlist_exists_number_array(src, "nvl/number"));
+	nvlist_add_number_array(src, "nvl/number", number, 8);
+	ATF_REQUIRE_EQ(nvlist_error(src), 0);
+	ATF_REQUIRE(nvlist_exists_number_array(src, "nvl/number"));
+
+	ATF_REQUIRE(!nvlist_exists_nvlist_array(src, "nvl/array"));
+	nvlist_add_nvlist_array(src, "nvl/array",
+	    (const nvlist_t * const *)testnvl, 8);
+	ATF_REQUIRE_EQ(nvlist_error(src), 0);
+	ATF_REQUIRE(nvlist_exists_nvlist_array(src, "nvl/array"));
+
+	dst = nvlist_clone(src);
+	ATF_REQUIRE(dst != NULL);
+
+	ATF_REQUIRE(nvlist_exists_bool_array(dst, "nvl/bool"));
+	(void) nvlist_get_bool_array(dst, "nvl/bool", &nitems);
+	ATF_REQUIRE_EQ(nitems, 16);
+	for (i = 0; i < nitems; i++) {
+		ATF_REQUIRE(
+		    nvlist_get_bool_array(dst, "nvl/bool", &nitems)[i] ==
+		    nvlist_get_bool_array(src, "nvl/bool", &nitems)[i]);
+	}
+
+	ATF_REQUIRE(nvlist_exists_string_array(dst, "nvl/string"));
+	(void) nvlist_get_string_array(dst, "nvl/string", &nitems);
+	ATF_REQUIRE_EQ(nitems, 8);
+	for (i = 0; i < nitems; i++) {
+		if (nvlist_get_string_array(dst, "nvl/string",
+		    &nitems)[i] == NULL) {
+			ATF_REQUIRE(nvlist_get_string_array(dst, "nvl/string",
+			    &nitems)[i] == nvlist_get_string_array(src,
+			    "nvl/string", &nitems)[i]);
+		} else {
+			ATF_REQUIRE(strcmp(nvlist_get_string_array(dst,
+			    "nvl/string", &nitems)[i], nvlist_get_string_array(
+			    src, "nvl/string", &nitems)[i]) == 0);
+		}
+	}
+
+	ATF_REQUIRE(nvlist_exists_descriptor_array(dst, "nvl/fd"));
+	(void) nvlist_get_descriptor_array(dst, "nvl/fd", &nitems);
+	ATF_REQUIRE_EQ(nitems, 16);
+	for (i = 0; i < nitems; i++) {
+		ATF_REQUIRE(fd_is_valid(
+		    nvlist_get_descriptor_array(dst, "nvl/fd", &nitems)[i]));
+	}
+	ATF_REQUIRE(nvlist_exists_number_array(dst, "nvl/number"));
+	(void) nvlist_get_number_array(dst, "nvl/number", &nitems);
+	ATF_REQUIRE_EQ(nitems, 8);
+
+	for (i = 0; i < nitems; i++) {
+		ATF_REQUIRE(
+		    nvlist_get_number_array(dst, "nvl/number", &nitems)[i] ==
+		    nvlist_get_number_array(src, "nvl/number", &nitems)[i]);
+	}
+
+	ATF_REQUIRE(nvlist_exists_nvlist_array(dst, "nvl/array"));
+	(void) nvlist_get_nvlist_array(dst, "nvl/array", &nitems);
+	ATF_REQUIRE_EQ(nitems, 8);
+	for (i = 0; i < nitems; i++) {
+		nvl = nvlist_get_nvlist_array(dst, "nvl/array", &nitems)[i];
+		ATF_REQUIRE(nvlist_exists_string(nvl, "nvl/nvl/teststr"));
+		ATF_REQUIRE(strcmp(nvlist_get_string(nvl, "nvl/nvl/teststr"),
+		    somestr[i]) == 0);
+	}
+
+	for (i = 0; i < 16; i++) {
+		close(testfd[i]);
+		if (i < 8) {
+			nvlist_destroy(testnvl[i]);
+		}
+	}
+	nvlist_destroy(src);
+	nvlist_destroy(dst);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(nvlist_bool_array__move);
+ATF_TEST_CASE_BODY(nvlist_bool_array__move)
+{
+	bool *testbool;
+	const bool *const_result;
+	nvlist_t *nvl;
+	size_t nitems, count;
+	unsigned int i;
+	const char *key;
+
+	key = "nvl/bool";
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	ATF_REQUIRE(nvlist_empty(nvl));
+	ATF_REQUIRE(!nvlist_exists_string_array(nvl, key));
+
+	count = 16;
+	testbool = (bool*)malloc(sizeof(*testbool) * count);
+	ATF_REQUIRE(testbool != NULL);
+	for (i = 0; i < count; i++)
+		testbool[i] = (i % 2 == 0);
+
+	nvlist_move_bool_array(nvl, key, testbool, count);
+	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
+	ATF_REQUIRE(!nvlist_empty(nvl));
+	ATF_REQUIRE(nvlist_exists_bool_array(nvl, key));
+
+	const_result = nvlist_get_bool_array(nvl, key, &nitems);
+	ATF_REQUIRE_EQ(nitems, count);
+	ATF_REQUIRE(const_result != NULL);
+	ATF_REQUIRE(const_result == testbool);
+	for (i = 0; i < nitems; i++)
+		ATF_REQUIRE_EQ(const_result[i], (i % 2 == 0));
+
+	nvlist_destroy(nvl);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(nvlist_string_array__move);
+ATF_TEST_CASE_BODY(nvlist_string_array__move)
+{
+	char **teststr;
+	const char * const *const_result;
+	nvlist_t *nvl;
+	size_t nitems, count;
+	unsigned int i;
+	const char *key;
+
+	key = "nvl/string";
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	ATF_REQUIRE(nvlist_empty(nvl));
+	ATF_REQUIRE(!nvlist_exists_string_array(nvl, key));
+
+	count = 26;
+	teststr = (char**)malloc(sizeof(*teststr) * count);
+	ATF_REQUIRE(teststr != NULL);
+	for (i = 0; i < count; i++) {
+		teststr[i] = (char*)malloc(sizeof(**teststr) * 2);
+		ATF_REQUIRE(teststr[i] != NULL);
+		teststr[i][0] = 'a' + i;
+		teststr[i][1] = '\0';
+	}
+
+	nvlist_move_string_array(nvl, key, teststr, count);
+	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
+	ATF_REQUIRE(!nvlist_empty(nvl));
+	ATF_REQUIRE(nvlist_exists_string_array(nvl, key));
+
+	const_result = nvlist_get_string_array(nvl, key, &nitems);
+	ATF_REQUIRE_EQ(nitems, count);
+	ATF_REQUIRE(const_result != NULL);
+	ATF_REQUIRE((intptr_t)const_result == (intptr_t)teststr);
+	for (i = 0; i < nitems; i++) {
+		ATF_REQUIRE_EQ(const_result[i][0], (char)('a' + i));
+		ATF_REQUIRE_EQ(const_result[i][1], '\0');
+	}
+
+	nvlist_destroy(nvl);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(nvlist_nvlist_array__move);
+ATF_TEST_CASE_BODY(nvlist_nvlist_array__move)
+{
+	nvlist **testnv;
+	const nvlist * const *const_result;
+	nvlist_t *nvl;
+	size_t nitems, count;
+	unsigned int i;
+	const char *key;
+
+	key = "nvl/nvlist";
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	ATF_REQUIRE(nvlist_empty(nvl));
+	ATF_REQUIRE(!nvlist_exists_nvlist_array(nvl, key));
+
+	count = 26;
+	testnv = (nvlist**)malloc(sizeof(*testnv) * count);
+	ATF_REQUIRE(testnv != NULL);
+	for (i = 0; i < count; i++) {
+		testnv[i] = nvlist_create(0);
+		ATF_REQUIRE(testnv[i] != NULL);
+	}
+
+	nvlist_move_nvlist_array(nvl, key, testnv, count);
+	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
+	ATF_REQUIRE(!nvlist_empty(nvl));
+	ATF_REQUIRE(nvlist_exists_nvlist_array(nvl, key));
+
+	const_result = nvlist_get_nvlist_array(nvl, key, &nitems);
+	ATF_REQUIRE_EQ(nitems, count);
+	ATF_REQUIRE(const_result != NULL);
+	ATF_REQUIRE((intptr_t)const_result == (intptr_t)testnv);
+	for (i = 0; i < nitems; i++) {
+		ATF_REQUIRE_EQ(nvlist_error(const_result[i]), 0);
+		ATF_REQUIRE(nvlist_empty(const_result[i]));
+		if (i < nitems - 1) {
+			ATF_REQUIRE(nvlist_get_array_next(const_result[i]) ==
+			    const_result[i + 1]);
+		} else {
+			ATF_REQUIRE(nvlist_get_array_next(const_result[i]) ==
+			    NULL);
+		}
+		ATF_REQUIRE(nvlist_get_parent(const_result[i], NULL) == nvl);
+		ATF_REQUIRE(nvlist_in_array(const_result[i]));
+	}
+
+	nvlist_destroy(nvl);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(nvlist_number_array__move);
+ATF_TEST_CASE_BODY(nvlist_number_array__move)
+{
+	uint64_t *testnumber;
+	const uint64_t *const_result;
+	nvlist_t *nvl;
+	size_t nitems, count;
+	unsigned int i;
+	const char *key;
+
+	key = "nvl/number";
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	ATF_REQUIRE(nvlist_empty(nvl));
+	ATF_REQUIRE(!nvlist_exists_string_array(nvl, key));
+
+	count = 1000;
+	testnumber = (uint64_t*)malloc(sizeof(*testnumber) * count);
+	ATF_REQUIRE(testnumber != NULL);
+	for (i = 0; i < count; i++)
+		testnumber[i] = i;
+
+	nvlist_move_number_array(nvl, key, testnumber, count);
+	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
+	ATF_REQUIRE(!nvlist_empty(nvl));
+	ATF_REQUIRE(nvlist_exists_number_array(nvl, key));
+
+	const_result = nvlist_get_number_array(nvl, key, &nitems);
+	ATF_REQUIRE_EQ(nitems, count);
+	ATF_REQUIRE(const_result != NULL);
+	ATF_REQUIRE(const_result == testnumber);
+	for (i = 0; i < nitems; i++)
+		ATF_REQUIRE_EQ(const_result[i], i);
+
+	nvlist_destroy(nvl);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(nvlist_descriptor_array__move);
+ATF_TEST_CASE_BODY(nvlist_descriptor_array__move)
+{
+	int *testfd;
+	const int *const_result;
+	nvlist_t *nvl;
+	size_t nitems, count;
+	unsigned int i;
+	const char *key;
+
+	key = "nvl/fd";
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	ATF_REQUIRE(nvlist_empty(nvl));
+	ATF_REQUIRE(!nvlist_exists_string_array(nvl, key));
+
+	count = 50;
+	testfd = (int*)malloc(sizeof(*testfd) * count);
+	ATF_REQUIRE(testfd != NULL);
+	for (i = 0; i < count; i++) {
+		testfd[i] = dup(STDERR_FILENO);
+		ATF_REQUIRE(fd_is_valid(testfd[i]));
+	}
+
+	nvlist_move_descriptor_array(nvl, key, testfd, count);
+	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
+	ATF_REQUIRE(!nvlist_empty(nvl));
+	ATF_REQUIRE(nvlist_exists_descriptor_array(nvl, key));
+
+	const_result = nvlist_get_descriptor_array(nvl, key, &nitems);
+	ATF_REQUIRE_EQ(nitems, count);
+	ATF_REQUIRE(const_result != NULL);
+	ATF_REQUIRE(const_result == testfd);
+	for (i = 0; i < nitems; i++)
+		ATF_REQUIRE(fd_is_valid(const_result[i]));
+
+	nvlist_destroy(nvl);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(nvlist_arrays__error_null);
+ATF_TEST_CASE_BODY(nvlist_arrays__error_null)
+{
+	nvlist_t *nvl;
+
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	nvlist_add_number_array(nvl, "nvl/number", NULL, 0);
+	ATF_REQUIRE(nvlist_error(nvl) != 0);
+	nvlist_destroy(nvl);
+
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	nvlist_move_number_array(nvl, "nvl/number", NULL, 0);
+	ATF_REQUIRE(nvlist_error(nvl) != 0);
+	nvlist_destroy(nvl);
+
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	nvlist_add_descriptor_array(nvl, "nvl/fd", NULL, 0);
+	ATF_REQUIRE(nvlist_error(nvl) != 0);
+	nvlist_destroy(nvl);
+
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	nvlist_move_descriptor_array(nvl, "nvl/fd", NULL, 0);
+	ATF_REQUIRE(nvlist_error(nvl) != 0);
+	nvlist_destroy(nvl);
+
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	nvlist_add_string_array(nvl, "nvl/string", NULL, 0);
+	ATF_REQUIRE(nvlist_error(nvl) != 0);
+	nvlist_destroy(nvl);
+
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	nvlist_move_string_array(nvl, "nvl/string", NULL, 0);
+	ATF_REQUIRE(nvlist_error(nvl) != 0);
+	nvlist_destroy(nvl);
+
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	nvlist_add_nvlist_array(nvl, "nvl/nvlist", NULL, 0);
+	ATF_REQUIRE(nvlist_error(nvl) != 0);
+	nvlist_destroy(nvl);
+
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	nvlist_move_nvlist_array(nvl, "nvl/nvlist", NULL, 0);
+	ATF_REQUIRE(nvlist_error(nvl) != 0);
+	nvlist_destroy(nvl);
+
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	nvlist_add_bool_array(nvl, "nvl/bool", NULL, 0);
+	ATF_REQUIRE(nvlist_error(nvl) != 0);
+	nvlist_destroy(nvl);
+
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	nvlist_move_bool_array(nvl, "nvl/bool", NULL, 0);
+	ATF_REQUIRE(nvlist_error(nvl) != 0);
+	nvlist_destroy(nvl);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(nvlist_arrays__bad_value);
+ATF_TEST_CASE_BODY(nvlist_arrays__bad_value)
+{
+	nvlist_t *nvl, *nvladd[1], **nvlmove;
+	int fdadd[1], *fdmove;
+
+	nvladd[0] = NULL;
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	nvlist_add_nvlist_array(nvl, "nvl/nvlist", nvladd, 1);
+	ATF_REQUIRE(nvlist_error(nvl) != 0);
+	nvlist_destroy(nvl);
+
+	nvlmove = (nvlist_t**)malloc(sizeof(*nvlmove));
+	ATF_REQUIRE(nvlmove != NULL);
+	nvlmove[0] = NULL;
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	nvlist_move_nvlist_array(nvl, "nvl/nvlist", nvlmove, 1);
+	ATF_REQUIRE(nvlist_error(nvl) != 0);
+	nvlist_destroy(nvl);
+
+	fdadd[0] = -2;
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	nvlist_add_descriptor_array(nvl, "nvl/fd", fdadd, 1);
+	ATF_REQUIRE(nvlist_error(nvl) != 0);
+	nvlist_destroy(nvl);
+
+	fdmove = (int*)malloc(sizeof(*fdmove));
+	ATF_REQUIRE(fdmove != NULL);
+	fdmove[0] = -2;
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	nvlist_move_descriptor_array(nvl, "nvl/fd", fdmove, 1);
+	ATF_REQUIRE(nvlist_error(nvl) != 0);
+	nvlist_destroy(nvl);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(nvlist_nvlist_array__travel);
+ATF_TEST_CASE_BODY(nvlist_nvlist_array__travel)
+{
+	nvlist_t *nvl, *test[5], *nasted;
+	const nvlist_t *travel;
+	void *cookie;
+	int index, i, type;
+	const char *name;
+
+	for (i = 0; i < 5; i++) {
+		test[i] = nvlist_create(0);
+		ATF_REQUIRE(test[i] != NULL);
+		nvlist_add_number(test[i], "nvl/number", i);
+		ATF_REQUIRE(nvlist_error(test[i]) == 0);
+	}
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	nvlist_add_nvlist_array(nvl, "nvl/nvlist_array", test, 5);
+	ATF_REQUIRE(nvlist_error(nvl) == 0);
+	nasted = nvlist_create(0);
+	ATF_REQUIRE(nasted != NULL);
+	nvlist_add_nvlist_array(nasted, "nvl/nvl/nvlist_array", test, 5);
+	ATF_REQUIRE(nvlist_error(nasted) == 0);
+	nvlist_move_nvlist(nvl, "nvl/nvl", nasted);
+	ATF_REQUIRE(nvlist_error(nvl) == 0);
+	nvlist_add_string(nvl, "nvl/string", "END");
+	ATF_REQUIRE(nvlist_error(nvl) == 0);
+
+	cookie = NULL;
+	index = 0;
+	travel = nvl;
+	do {
+		while ((name = nvlist_next(travel, &type, &cookie)) != NULL) {
+			if (index == 0) {
+				ATF_REQUIRE(type == NV_TYPE_NVLIST_ARRAY);
+			} else if (index >= 1 && index <= 5) {
+				ATF_REQUIRE(type == NV_TYPE_NUMBER);
+			} else if (index == 6) {
+				ATF_REQUIRE(type == NV_TYPE_NVLIST);
+			} else if (index == 7) {
+				ATF_REQUIRE(type == NV_TYPE_NVLIST_ARRAY);
+			} else if (index >= 8 && index <= 12) {
+				ATF_REQUIRE(type == NV_TYPE_NUMBER);
+			} else if (index == 13) {
+				ATF_REQUIRE(type == NV_TYPE_STRING);
+			}
+
+			if (type == NV_TYPE_NVLIST) {
+				travel = nvlist_get_nvlist(travel, name);
+				cookie = NULL;
+			} else if (type == NV_TYPE_NVLIST_ARRAY) {
+				travel = nvlist_get_nvlist_array(travel, name,
+				    NULL)[0];
+				cookie = NULL;
+			}
+			index ++;
+		}
+	} while ((travel = nvlist_get_pararr(travel, &cookie)) != NULL);
+
+	for (i = 0; i < 5; i++)
+		nvlist_destroy(test[i]);
+
+	nvlist_destroy(nvl);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(nvlist_nvlist_array__travel_alternative);
+ATF_TEST_CASE_BODY(nvlist_nvlist_array__travel_alternative)
+{
+	nvlist_t *nvl, *test[5], *nasted;
+	const nvlist_t *travel, *tmp;
+	void *cookie;
+	int index, i, type;
+	const char *name;
+
+	for (i = 0; i < 5; i++) {
+		test[i] = nvlist_create(0);
+		ATF_REQUIRE(test[i] != NULL);
+		nvlist_add_number(test[i], "nvl/number", i);
+		ATF_REQUIRE(nvlist_error(test[i]) == 0);
+	}
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	nvlist_add_nvlist_array(nvl, "nvl/nvlist_array", test, 5);
+	ATF_REQUIRE(nvlist_error(nvl) == 0);
+	nasted = nvlist_create(0);
+	ATF_REQUIRE(nasted != NULL);
+	nvlist_add_nvlist_array(nasted, "nvl/nvl/nvlist_array", test, 5);
+	ATF_REQUIRE(nvlist_error(nasted) == 0);
+	nvlist_move_nvlist(nvl, "nvl/nvl", nasted);
+	ATF_REQUIRE(nvlist_error(nvl) == 0);
+	nvlist_add_string(nvl, "nvl/string", "END");
+	ATF_REQUIRE(nvlist_error(nvl) == 0);
+
+	cookie = NULL;
+	index = 0;
+	tmp = travel = nvl;
+	do {
+		do {
+			travel = tmp;
+			while ((name = nvlist_next(travel, &type, &cookie)) !=
+			    NULL) {
+				if (index == 0) {
+					ATF_REQUIRE(type ==
+					    NV_TYPE_NVLIST_ARRAY);
+				} else if (index >= 1 && index <= 5) {
+					ATF_REQUIRE(type == NV_TYPE_NUMBER);
+				} else if (index == 6) {
+					ATF_REQUIRE(type == NV_TYPE_NVLIST);
+				} else if (index == 7) {
+					ATF_REQUIRE(type ==
+					    NV_TYPE_NVLIST_ARRAY);
+				} else if (index >= 8 && index <= 12) {
+					ATF_REQUIRE(type == NV_TYPE_NUMBER);
+				} else if (index == 13) {
+					ATF_REQUIRE(type == NV_TYPE_STRING);
+				}
+
+				if (type == NV_TYPE_NVLIST) {
+					travel = nvlist_get_nvlist(travel,
+					    name);
+					cookie = NULL;
+				} else if (type == NV_TYPE_NVLIST_ARRAY) {
+					travel = nvlist_get_nvlist_array(travel,
+					    name, NULL)[0];
+					cookie = NULL;
+				}
+				index ++;
+			}
+			cookie = NULL;
+		} while ((tmp = nvlist_get_array_next(travel)) != NULL);
+	} while ((tmp = nvlist_get_parent(travel, &cookie)) != NULL);
+
+	for (i = 0; i < 5; i++)
+		nvlist_destroy(test[i]);
+
+	nvlist_destroy(nvl);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(nvlist_bool_array__pack);
+ATF_TEST_CASE_BODY(nvlist_bool_array__pack)
+{
+	nvlist_t *nvl, *unpacked;
+	const char *key;
+	size_t packed_size, count;
+	void *packed;
+	unsigned int i;
+	const bool *const_result;
+	bool testbool[16];
+
+	for (i = 0; i < 16; i++)
+		testbool[i] = (i % 2 == 0);
+
+	key = "nvl/bool";
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	ATF_REQUIRE(nvlist_empty(nvl));
+	ATF_REQUIRE(!nvlist_exists_string_array(nvl, key));
+
+	nvlist_add_bool_array(nvl, key, testbool, 16);
+	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
+	ATF_REQUIRE(!nvlist_empty(nvl));
+	ATF_REQUIRE(nvlist_exists_bool_array(nvl, key));
+
+	packed = nvlist_pack(nvl, &packed_size);
+	ATF_REQUIRE(packed != NULL);
+
+	unpacked = nvlist_unpack(packed, packed_size, 0);
+	ATF_REQUIRE(unpacked != NULL);
+	ATF_REQUIRE_EQ(nvlist_error(unpacked), 0);
+	ATF_REQUIRE(nvlist_exists_bool_array(unpacked, key));
+
+	const_result = nvlist_get_bool_array(unpacked, key, &count);
+	ATF_REQUIRE_EQ(count, 16);
+	for (i = 0; i < count; i++) {
+		ATF_REQUIRE_EQ(testbool[i], const_result[i]);
+	}
+
+	nvlist_destroy(nvl);
+	nvlist_destroy(unpacked);
+	free(packed);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(nvlist_number_array__pack);
+ATF_TEST_CASE_BODY(nvlist_number_array__pack)
+{
+	nvlist_t *nvl, *unpacked;
+	const char *key;
+	size_t packed_size, count;
+	void *packed;
+	unsigned int i;
+	const uint64_t *const_result;
+	const uint64_t number[8] = { 0, UINT_MAX, 7, 123, 90,
+	    100000, 8, 1 };
+
+	key = "nvl/number";
+	nvl = nvlist_create(0);
+	ATF_REQUIRE(nvl != NULL);
+	ATF_REQUIRE(nvlist_empty(nvl));
+	ATF_REQUIRE(!nvlist_exists_string_array(nvl, key));
+
+	nvlist_add_number_array(nvl, key, number, 8);
+	ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
+	ATF_REQUIRE(!nvlist_empty(nvl));
+	ATF_REQUIRE(nvlist_exists_number_array(nvl, key));
+
+	packed = nvlist_pack(nvl, &packed_size);
+	ATF_REQUIRE(packed != NULL);
+
+	unpacked = nvlist_unpack(packed, packed_size, 0);
+	ATF_REQUIRE(unpacked != NULL);
+	ATF_REQUIRE_EQ(nvlist_error(unpacked), 0);
+	ATF_REQUIRE(nvlist_exists_number_array(unpacked, key));
+
+	const_result = nvlist_get_number_array(unpacked, key, &count);
+	ATF_REQUIRE_EQ(count, 8);
+	for (i = 0; i < count; i++) {
+		ATF_REQUIRE_EQ(number[i], const_result[i]);
+	}
+
+	nvlist_destroy(nvl);
+	nvlist_destroy(unpacked);
+	free(packed);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(nvlist_descriptor_array__pack);
+ATF_TEST_CASE_BODY(nvlist_descriptor_array__pack)

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201508150634.t7F6Yopc003939>