From owner-svn-src-user@freebsd.org Sun Jan 3 09:16:43 2016 Return-Path: Delivered-To: svn-src-user@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 8403FA5F524 for ; Sun, 3 Jan 2016 09:16:43 +0000 (UTC) (envelope-from ngie@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 47CAC12A9; Sun, 3 Jan 2016 09:16:43 +0000 (UTC) (envelope-from ngie@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u039Ggji029139; Sun, 3 Jan 2016 09:16:42 GMT (envelope-from ngie@FreeBSD.org) Received: (from ngie@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u039GgOq029136; Sun, 3 Jan 2016 09:16:42 GMT (envelope-from ngie@FreeBSD.org) Message-Id: <201601030916.u039GgOq029136@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ngie set sender to ngie@FreeBSD.org using -f From: Garrett Cooper Date: Sun, 3 Jan 2016 09:16:42 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r293094 - in user/ngie/stable-10-libnv: lib/libnv/tests share/man/man9 sys/cddl/compat/opensolaris/sys sys/contrib/libnv sys/sys X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 03 Jan 2016 09:16:43 -0000 Author: ngie Date: Sun Jan 3 09:16:42 2016 New Revision: 293094 URL: https://svnweb.freebsd.org/changeset/base/293094 Log: MFC r286796: r286796 (by oshogbo): 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 Added: user/ngie/stable-10-libnv/lib/libnv/tests/nv_array_tests.cc - copied unchanged from r286796, head/lib/libnv/tests/nv_array_tests.cc Modified: user/ngie/stable-10-libnv/lib/libnv/tests/Makefile user/ngie/stable-10-libnv/share/man/man9/nv.9 user/ngie/stable-10-libnv/sys/cddl/compat/opensolaris/sys/nvpair.h user/ngie/stable-10-libnv/sys/contrib/libnv/nv_impl.h user/ngie/stable-10-libnv/sys/contrib/libnv/nvlist.c user/ngie/stable-10-libnv/sys/contrib/libnv/nvlist_impl.h user/ngie/stable-10-libnv/sys/contrib/libnv/nvpair.c user/ngie/stable-10-libnv/sys/contrib/libnv/nvpair_impl.h user/ngie/stable-10-libnv/sys/sys/nv.h Directory Properties: user/ngie/stable-10-libnv/ (props changed) Modified: user/ngie/stable-10-libnv/lib/libnv/tests/Makefile ============================================================================== --- user/ngie/stable-10-libnv/lib/libnv/tests/Makefile Sun Jan 3 09:11:55 2016 (r293093) +++ user/ngie/stable-10-libnv/lib/libnv/tests/Makefile Sun Jan 3 09:16:42 2016 (r293094) @@ -4,6 +4,7 @@ TESTSDIR= ${TESTSBASE}/lib/libnv ATF_TESTS_CXX= \ dnv_tests \ + nv_array_tests \ nv_tests \ TAP_TESTS_C+= nvlist_add_test Copied: user/ngie/stable-10-libnv/lib/libnv/tests/nv_array_tests.cc (from r286796, head/lib/libnv/tests/nv_array_tests.cc) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/ngie/stable-10-libnv/lib/libnv/tests/nv_array_tests.cc Sun Jan 3 09:16:42 2016 (r293094, copy of r286796, head/lib/libnv/tests/nv_array_tests.cc) @@ -0,0 +1,1191 @@ +/*- + * Copyright (c) 2015 Mariusz Zaborski + * 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#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 ***