freebsd-nq/lib/libnv/tests/nv_tests.cc
Enji Cooper 6399b5e03a :nvlist_unpack__duplicate_key : check the result of nvlist_pack(3)
This fixes a potential NULL pointer dereference.

MFC after:	3 days
Reported by:	Coverity
CID:		1362051
Sponsored by:	Dell EMC Isilon
2017-05-29 18:39:28 +00:00

1278 lines
32 KiB
C++

/*-
* Copyright (c) 2014-2015 Sandvine Inc. All rights reserved.
* 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 <atf-c++.hpp>
#include <errno.h>
#include <limits>
#include <set>
#include <sstream>
#include <string>
/*
* Test that a newly created nvlist has no errors, and is empty.
*/
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_create__is_empty);
ATF_TEST_CASE_BODY(nvlist_create__is_empty)
{
nvlist_t *nvl;
int type;
void *it;
nvl = nvlist_create(0);
ATF_REQUIRE(nvl != NULL);
ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
ATF_REQUIRE(nvlist_empty(nvl));
it = NULL;
ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &it), static_cast<const char *>(NULL));
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_add_null__single_insert);
ATF_TEST_CASE_BODY(nvlist_add_null__single_insert)
{
nvlist_t *nvl;
void *it;
const char *key;
int type;
key = "key";
nvl = nvlist_create(0);
ATF_REQUIRE(nvl != NULL);
ATF_REQUIRE(!nvlist_exists(nvl, key));
nvlist_add_null(nvl, key);
ATF_REQUIRE(!nvlist_empty(nvl));
ATF_REQUIRE(nvlist_exists(nvl, key));
ATF_REQUIRE(nvlist_exists_null(nvl, key));
ATF_REQUIRE(nvlist_exists_null(nvl, "key"));
/* Iterate over the nvlist; ensure that it has only our one key. */
it = NULL;
ATF_REQUIRE_EQ(strcmp(nvlist_next(nvl, &type, &it), key), 0);
ATF_REQUIRE_EQ(type, NV_TYPE_NULL);
ATF_REQUIRE_EQ(nvlist_next(nvl, &type,&it), static_cast<const char *>(NULL));
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_add_bool__single_insert);
ATF_TEST_CASE_BODY(nvlist_add_bool__single_insert)
{
nvlist_t *nvl;
void *it;
const char *key;
int type;
key = "name";
nvl = nvlist_create(0);
ATF_REQUIRE(nvl != NULL);
ATF_REQUIRE(!nvlist_exists(nvl, key));
nvlist_add_bool(nvl, key, true);
ATF_REQUIRE(!nvlist_empty(nvl));
ATF_REQUIRE(nvlist_exists(nvl, key));
ATF_REQUIRE(nvlist_exists(nvl, "name"));
ATF_REQUIRE(nvlist_exists_bool(nvl, key));
ATF_REQUIRE(nvlist_exists_bool(nvl, "name"));
ATF_REQUIRE_EQ(nvlist_get_bool(nvl, key), true);
/* Iterate over the nvlist; ensure that it has only our one key. */
it = NULL;
ATF_REQUIRE_EQ(strcmp(nvlist_next(nvl, &type, &it), key), 0);
ATF_REQUIRE_EQ(type, NV_TYPE_BOOL);
ATF_REQUIRE_EQ(nvlist_next(nvl, &type,&it), static_cast<const char *>(NULL));
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_add_number__single_insert);
ATF_TEST_CASE_BODY(nvlist_add_number__single_insert)
{
nvlist_t *nvl;
void *it;
const char *key;
uint64_t value;
int type;
key = "foo123";
value = 71965;
nvl = nvlist_create(0);
ATF_REQUIRE(nvl != NULL);
ATF_REQUIRE(!nvlist_exists(nvl, key));
nvlist_add_number(nvl, key, value);
ATF_REQUIRE(!nvlist_empty(nvl));
ATF_REQUIRE(nvlist_exists(nvl, key));
ATF_REQUIRE(nvlist_exists(nvl, "foo123"));
ATF_REQUIRE(nvlist_exists_number(nvl, key));
ATF_REQUIRE_EQ(nvlist_get_number(nvl, key), value);
/* Iterate over the nvlist; ensure that it has only our one key. */
it = NULL;
ATF_REQUIRE_EQ(strcmp(nvlist_next(nvl, &type, &it), key), 0);
ATF_REQUIRE_EQ(type, NV_TYPE_NUMBER);
ATF_REQUIRE_EQ(nvlist_next(nvl, &type,&it), static_cast<const char *>(NULL));
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_add_string__single_insert);
ATF_TEST_CASE_BODY(nvlist_add_string__single_insert)
{
nvlist_t *nvl;
void *it;
const char *key;
const char *value;
int type;
key = "test";
value = "fgjdkgjdk";
nvl = nvlist_create(0);
ATF_REQUIRE(nvl != NULL);
ATF_REQUIRE(!nvlist_exists(nvl, key));
nvlist_add_string(nvl, key, value);
ATF_REQUIRE(!nvlist_empty(nvl));
ATF_REQUIRE(nvlist_exists(nvl, key));
ATF_REQUIRE(nvlist_exists(nvl, "test"));
ATF_REQUIRE(nvlist_exists_string(nvl, key));
ATF_REQUIRE(nvlist_exists_string(nvl, "test"));
ATF_REQUIRE_EQ(strcmp(nvlist_get_string(nvl, key), value), 0);
/* nvlist_add_* is required to clone the value, so check for that. */
ATF_REQUIRE(nvlist_get_string(nvl, key) != value);
/* Iterate over the nvlist; ensure that it has only our one key. */
it = NULL;
ATF_REQUIRE_EQ(strcmp(nvlist_next(nvl, &type, &it), key), 0);
ATF_REQUIRE_EQ(type, NV_TYPE_STRING);
ATF_REQUIRE_EQ(nvlist_next(nvl, &type,&it), static_cast<const char *>(NULL));
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_add_nvlist__single_insert);
ATF_TEST_CASE_BODY(nvlist_add_nvlist__single_insert)
{
nvlist_t *nvl;
void *it;
const char *key, *subkey;
nvlist_t *sublist;
const nvlist_t *value;
int type;
key = "test";
subkey = "subkey";
sublist = nvlist_create(0);
nvl = nvlist_create(0);
ATF_REQUIRE(nvl != NULL);
ATF_REQUIRE(!nvlist_exists(nvl, key));
nvlist_add_null(sublist, subkey);
nvlist_add_nvlist(nvl, key, sublist);
ATF_REQUIRE(!nvlist_empty(nvl));
ATF_REQUIRE(nvlist_exists(nvl, key));
ATF_REQUIRE(nvlist_exists(nvl, "test"));
ATF_REQUIRE(nvlist_exists_nvlist(nvl, key));
ATF_REQUIRE(nvlist_exists_nvlist(nvl, "test"));
value = nvlist_get_nvlist(nvl, key);
ATF_REQUIRE(nvlist_exists_null(value, subkey));
/* nvlist_add_* is required to clone the value, so check for that. */
ATF_REQUIRE(sublist != value);
/* Iterate over the nvlist; ensure that it has only our one key. */
it = NULL;
ATF_REQUIRE_EQ(strcmp(nvlist_next(nvl, &type, &it), key), 0);
ATF_REQUIRE_EQ(type, NV_TYPE_NVLIST);
ATF_REQUIRE_EQ(nvlist_next(nvl, &type,&it), static_cast<const char *>(NULL));
nvlist_destroy(sublist);
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_add_nvlist__child_with_error);
ATF_TEST_CASE_BODY(nvlist_add_nvlist__child_with_error)
{
nvlist_t *nvl, *parent;
nvl = nvlist_create(0);
parent = nvlist_create(0);
nvlist_set_error(nvl, EBADF);
nvlist_add_nvlist(parent, "test", nvl);
ATF_REQUIRE_EQ(nvlist_error(parent), EBADF);
nvlist_destroy(nvl);
nvlist_destroy(parent);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_add_binary__single_insert);
ATF_TEST_CASE_BODY(nvlist_add_binary__single_insert)
{
nvlist_t *nvl;
void *it;
const char *key;
void *value;
const void *ret_value;
size_t value_size, ret_size;
int type;
key = "binary";
value_size = 13;
value = malloc(value_size);
memset(value, 0xa5, value_size);
nvl = nvlist_create(0);
ATF_REQUIRE(nvl != NULL);
ATF_REQUIRE(!nvlist_exists(nvl, key));
nvlist_add_binary(nvl, key, value, value_size);
ATF_REQUIRE(!nvlist_empty(nvl));
ATF_REQUIRE(nvlist_exists(nvl, key));
ATF_REQUIRE(nvlist_exists(nvl, "binary"));
ATF_REQUIRE(nvlist_exists_binary(nvl, key));
ATF_REQUIRE(nvlist_exists_binary(nvl, "binary"));
ret_value = nvlist_get_binary(nvl, key, &ret_size);
ATF_REQUIRE_EQ(value_size, ret_size);
ATF_REQUIRE_EQ(memcmp(value, ret_value, ret_size), 0);
/* nvlist_add_* is required to clone the value, so check for that. */
ATF_REQUIRE(value != ret_value);
/* Iterate over the nvlist; ensure that it has only our one key. */
it = NULL;
ATF_REQUIRE_EQ(strcmp(nvlist_next(nvl, &type, &it), key), 0);
ATF_REQUIRE_EQ(type, NV_TYPE_BINARY);
ATF_REQUIRE_EQ(nvlist_next(nvl, &type,&it), static_cast<const char *>(NULL));
nvlist_destroy(nvl);
free(value);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_clone__empty_nvlist);
ATF_TEST_CASE_BODY(nvlist_clone__empty_nvlist)
{
nvlist_t *nvl, *clone;
nvl = nvlist_create(0);
ATF_REQUIRE(nvl != NULL);
clone = nvlist_clone(nvl);
ATF_REQUIRE(clone != NULL);
ATF_REQUIRE(clone != nvl);
ATF_REQUIRE(nvlist_empty(clone));
nvlist_destroy(clone);
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_clone__nonempty_nvlist);
ATF_TEST_CASE_BODY(nvlist_clone__nonempty_nvlist)
{
nvlist_t *nvl, *clone;
const char *key;
void *it;
uint64_t value;
int type;
nvl = nvlist_create(0);
ATF_REQUIRE(nvl != NULL);
key = "testkey";
value = 684874;
nvlist_add_number(nvl, key, value);
clone = nvlist_clone(nvl);
ATF_REQUIRE(clone != NULL);
ATF_REQUIRE(clone != nvl);
ATF_REQUIRE(nvlist_exists_number(clone, key));
ATF_REQUIRE_EQ(nvlist_get_number(clone, key), value);
/* Iterate over the nvlist; ensure that it has only our one key. */
it = NULL;
ATF_REQUIRE_EQ(strcmp(nvlist_next(clone, &type, &it), key), 0);
ATF_REQUIRE_EQ(type, NV_TYPE_NUMBER);
ATF_REQUIRE_EQ(nvlist_next(clone, &type, &it), static_cast<const char *>(NULL));
nvlist_destroy(clone);
nvlist_destroy(nvl);
}
static const char * const test_subnvlist_key = "nvlist";
static const char * const test_string_key = "string";
static const char * const test_string_val = "59525";
static nvlist_t*
create_test_nvlist(void)
{
nvlist_t *nvl, *sublist;
nvl = nvlist_create(0);
ATF_REQUIRE(nvl != NULL);
sublist = nvlist_create(0);
ATF_REQUIRE(sublist != NULL);
nvlist_add_string(sublist, test_string_key, test_string_val);
nvlist_move_nvlist(nvl, test_subnvlist_key, sublist);
return (nvl);
}
static void
verify_test_nvlist(const nvlist_t *nvl)
{
void *it;
const nvlist_t *value;
int type;
ATF_REQUIRE(nvlist_exists_nvlist(nvl, test_subnvlist_key));
value = nvlist_get_nvlist(nvl, test_subnvlist_key);
ATF_REQUIRE(nvlist_exists_string(value, test_string_key));
ATF_REQUIRE_EQ(strcmp(nvlist_get_string(value, test_string_key), test_string_val), 0);
ATF_REQUIRE(nvlist_get_string(value, test_string_key) != test_string_val);
/* Iterate over both nvlists; ensure that each has only the one key. */
it = NULL;
ATF_REQUIRE_EQ(strcmp(nvlist_next(value, &type, &it),
test_string_key), 0);
ATF_REQUIRE_EQ(type, NV_TYPE_STRING);
ATF_REQUIRE_EQ(nvlist_next(value, &type, &it), static_cast<const char *>(NULL));
it = NULL;
ATF_REQUIRE_EQ(strcmp(nvlist_next(nvl, &type, &it),
test_subnvlist_key), 0);
ATF_REQUIRE_EQ(type, NV_TYPE_NVLIST);
ATF_REQUIRE_EQ(nvlist_next(nvl, &type, &it), static_cast<const char *>(NULL));
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_clone__nested_nvlist);
ATF_TEST_CASE_BODY(nvlist_clone__nested_nvlist)
{
nvlist_t *nvl, *clone;
nvl = create_test_nvlist();
clone = nvlist_clone(nvl);
ATF_REQUIRE(clone != NULL);
ATF_REQUIRE(clone != nvl);
verify_test_nvlist(clone);
nvlist_destroy(clone);
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_clone__error_nvlist);
ATF_TEST_CASE_BODY(nvlist_clone__error_nvlist)
{
nvlist_t *nvl, *clone;
nvl = nvlist_create(0);
ATF_REQUIRE(nvl != NULL);
nvlist_set_error(nvl, ENOMEM);
clone = nvlist_clone(nvl);
ATF_REQUIRE(clone == NULL);
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_pack__empty_nvlist);
ATF_TEST_CASE_BODY(nvlist_pack__empty_nvlist)
{
nvlist_t *nvl, *unpacked;
void *packed;
size_t packed_size;
nvl = nvlist_create(0);
ATF_REQUIRE(nvl != NULL);
packed = nvlist_pack(nvl, &packed_size);
ATF_REQUIRE(packed != NULL);
unpacked = nvlist_unpack(packed, packed_size, 0);
ATF_REQUIRE(unpacked != NULL);
ATF_REQUIRE(unpacked != nvl);
ATF_REQUIRE(nvlist_empty(unpacked));
nvlist_destroy(unpacked);
nvlist_destroy(nvl);
free(packed);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_unpack__flags_nvlist);
ATF_TEST_CASE_BODY(nvlist_unpack__flags_nvlist)
{
nvlist_t *nvl, *unpacked;
void *packed;
size_t packed_size;
nvl = nvlist_create(NV_FLAG_NO_UNIQUE);
ATF_REQUIRE(nvl != NULL);
nvlist_add_bool(nvl, "name", true);
ATF_REQUIRE(!nvlist_empty(nvl));
ATF_REQUIRE(nvlist_exists_bool(nvl, "name"));
packed = nvlist_pack(nvl, &packed_size);
ATF_REQUIRE(packed != NULL);
unpacked = nvlist_unpack(packed, packed_size, 0);
ATF_REQUIRE(unpacked == NULL);
unpacked = nvlist_unpack(packed, packed_size, NV_FLAG_IGNORE_CASE);
ATF_REQUIRE(unpacked == NULL);
unpacked = nvlist_unpack(packed, packed_size, NV_FLAG_NO_UNIQUE);
ATF_REQUIRE(unpacked != NULL);
ATF_REQUIRE(unpacked != nvl);
ATF_REQUIRE(!nvlist_empty(unpacked));
ATF_REQUIRE(nvlist_exists_bool(unpacked, "name"));
nvlist_destroy(unpacked);
nvlist_destroy(nvl);
free(packed);
}
static void
verify_null(const nvlist_t *nvl, int type)
{
ATF_REQUIRE_EQ(type, NV_TYPE_NULL);
}
static void
verify_number(const nvlist_t *nvl, const char *name, int type, uint64_t value)
{
ATF_REQUIRE_EQ(type, NV_TYPE_NUMBER);
ATF_REQUIRE_EQ(nvlist_get_number(nvl, name), value);
}
static void
verify_string(const nvlist_t *nvl, const char *name, int type,
const char * value)
{
ATF_REQUIRE_EQ(type, NV_TYPE_STRING);
ATF_REQUIRE_EQ(strcmp(nvlist_get_string(nvl, name), value), 0);
}
static void
verify_nvlist(const nvlist_t *nvl, const char *name, int type)
{
ATF_REQUIRE_EQ(type, NV_TYPE_NVLIST);
verify_test_nvlist(nvlist_get_nvlist(nvl, name));
}
static void
verify_binary(const nvlist_t *nvl, const char *name, int type,
const void * value, size_t size)
{
const void *actual_value;
size_t actual_size;
ATF_REQUIRE_EQ(type, NV_TYPE_BINARY);
actual_value = nvlist_get_binary(nvl, name, &actual_size);
ATF_REQUIRE_EQ(size, actual_size);
ATF_REQUIRE_EQ(memcmp(value, actual_value, size), 0);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_pack__multiple_values);
ATF_TEST_CASE_BODY(nvlist_pack__multiple_values)
{
std::ostringstream msg;
std::set<std::string> keys_seen;
nvlist_t *nvl, *unpacked, *nvvalue;
const char *nullkey, *numkey, *strkey, *nvkey, *binkey, *name;
int numvalue;
const char * strvalue;
void *binvalue, *packed, *it;
size_t binsize, packed_size;
int type;
nvl = nvlist_create(0);
nullkey = "null";
nvlist_add_null(nvl, nullkey);
numkey = "number";
numvalue = 939853984;
nvlist_add_number(nvl, numkey, numvalue);
strkey = "string";
strvalue = "jfieutijf";
nvlist_add_string(nvl, strkey, strvalue);
nvkey = "nvlist";
nvvalue = create_test_nvlist();
nvlist_move_nvlist(nvl, nvkey, nvvalue);
binkey = "binary";
binsize = 4;
binvalue = malloc(binsize);
memset(binvalue, 'b', binsize);
nvlist_move_binary(nvl, binkey, binvalue, binsize);
packed = nvlist_pack(nvl, &packed_size);
ATF_REQUIRE(packed != NULL);
unpacked = nvlist_unpack(packed, packed_size, 0);
ATF_REQUIRE(unpacked != 0);
it = NULL;
while ((name = nvlist_next(unpacked, &type, &it)) != NULL) {
/* Ensure that we see every key only once. */
ATF_REQUIRE_EQ(keys_seen.count(name), 0);
if (strcmp(name, nullkey) == 0)
verify_null(unpacked, type);
else if (strcmp(name, numkey) == 0)
verify_number(unpacked, name, type, numvalue);
else if (strcmp(name, strkey) == 0)
verify_string(unpacked, name, type, strvalue);
else if (strcmp(name, nvkey) == 0)
verify_nvlist(unpacked, name, type);
else if (strcmp(name, binkey) == 0)
verify_binary(unpacked, name, type, binvalue, binsize);
else {
msg << "Unexpected key :'" << name << "'";
ATF_FAIL(msg.str().c_str());
}
keys_seen.insert(name);
}
/* Ensure that we saw every key. */
ATF_REQUIRE_EQ(keys_seen.size(), 5);
nvlist_destroy(nvl);
nvlist_destroy(unpacked);
free(packed);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_pack__error_nvlist);
ATF_TEST_CASE_BODY(nvlist_pack__error_nvlist)
{
nvlist_t *nvl;
void *packed;
size_t size;
nvl = nvlist_create(0);
ATF_REQUIRE(nvl != NULL);
nvlist_set_error(nvl, ENOMEM);
packed = nvlist_pack(nvl, &size);
ATF_REQUIRE(packed == NULL);
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_unpack__duplicate_key);
ATF_TEST_CASE_BODY(nvlist_unpack__duplicate_key)
{
nvlist_t *nvl, *unpacked;
const char *key1, *key2;
void *packed, *keypos;
size_t size, keylen;
nvl = nvlist_create(0);
key1 = "key1";
keylen = strlen(key1);
nvlist_add_number(nvl, key1, 5);
key2 = "key2";
ATF_REQUIRE_EQ(keylen, strlen(key2));
nvlist_add_number(nvl, key2, 10);
packed = nvlist_pack(nvl, &size);
ATF_REQUIRE(packed != NULL);
/*
* Mangle the packed nvlist by replacing key1 with key2, creating a
* packed nvlist with a duplicate key.
*/
keypos = memmem(packed, size, key1, keylen);
ATF_REQUIRE(keypos != NULL);
memcpy(keypos, key2, keylen);
unpacked = nvlist_unpack(packed, size, 0);
ATF_REQUIRE(nvlist_error(unpacked) != 0);
free(packed);
nvlist_destroy(nvl);
nvlist_destroy(unpacked);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_move_string__single_insert);
ATF_TEST_CASE_BODY(nvlist_move_string__single_insert)
{
nvlist_t *nvl;
const char *key;
char *value;
nvl = nvlist_create(0);
ATF_REQUIRE(nvl != NULL);
key = "testkey";
value = strdup("testval");
ATF_REQUIRE(value != NULL);
nvlist_move_string(nvl, key, value);
ATF_REQUIRE_EQ(nvlist_get_string(nvl, key), value);
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_move_nvlist__null_child);
ATF_TEST_CASE_BODY(nvlist_move_nvlist__null_child)
{
nvlist_t *parent;
parent = nvlist_create(0);
nvlist_move_nvlist(parent, "test", NULL);
ATF_REQUIRE(nvlist_error(parent) != 0);
nvlist_destroy(parent);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_move_nvlist__child_with_error);
ATF_TEST_CASE_BODY(nvlist_move_nvlist__child_with_error)
{
nvlist_t *nvl, *parent;
nvl = nvlist_create(0);
parent = nvlist_create(0);
nvlist_set_error(nvl, EBADF);
nvlist_move_nvlist(parent, "test", nvl);
ATF_REQUIRE_EQ(nvlist_error(parent), EBADF);
nvlist_destroy(parent);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_move_nvlist__single_insert);
ATF_TEST_CASE_BODY(nvlist_move_nvlist__single_insert)
{
nvlist_t *nvl;
const char *key;
nvlist_t *value;
nvl = nvlist_create(0);
ATF_REQUIRE(nvl != NULL);
key = "testkey";
value = nvlist_create(0);
ATF_REQUIRE(value != NULL);
nvlist_move_nvlist(nvl, key, value);
ATF_REQUIRE_EQ(nvlist_get_nvlist(nvl, key), value);
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_move_binary__single_insert);
ATF_TEST_CASE_BODY(nvlist_move_binary__single_insert)
{
nvlist_t *nvl;
const char *key;
void *value;
size_t size, actual_size;
nvl = nvlist_create(0);
ATF_REQUIRE(nvl != NULL);
key = "testkey";
size = 73;
value = malloc(size);
ATF_REQUIRE(value != NULL);
nvlist_move_binary(nvl, key, value, size);
ATF_REQUIRE_EQ(nvlist_get_binary(nvl, key, &actual_size), value);
ATF_REQUIRE_EQ(size, actual_size);
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_take_bool__single_remove);
ATF_TEST_CASE_BODY(nvlist_take_bool__single_remove)
{
nvlist_t *nvl;
const char *testkey;
bool testval;
nvl = nvlist_create(0);
ATF_REQUIRE(nvl != NULL);
testkey = "boolkey";
testval = false;
nvlist_add_bool(nvl, testkey, testval);
ATF_REQUIRE_EQ(nvlist_take_bool(nvl, testkey), testval);
ATF_REQUIRE(nvlist_empty(nvl));
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_take_bool__other_keys_unchanged);
ATF_TEST_CASE_BODY(nvlist_take_bool__other_keys_unchanged)
{
nvlist_t *nvl;
const char *testkey, *otherkey1, *otherkey2;
bool testval, otherval1;
nvlist_t *otherval2;
nvl = nvlist_create(0);
ATF_REQUIRE(nvl != NULL);
testkey = "boolkey";
testval = true;
nvlist_add_bool(nvl, testkey, testval);
otherkey1 = "key1";
otherval1 = false;
nvlist_add_bool(nvl, otherkey1, otherval1);
otherkey2 = "key2";
otherval2 = create_test_nvlist();
nvlist_move_nvlist(nvl, otherkey2, otherval2);
ATF_REQUIRE_EQ(nvlist_take_bool(nvl, testkey), testval);
ATF_REQUIRE(nvlist_exists_bool(nvl, otherkey1));
ATF_REQUIRE_EQ(nvlist_get_bool(nvl, otherkey1), otherval1);
ATF_REQUIRE(nvlist_exists_nvlist(nvl, otherkey2));
verify_test_nvlist(nvlist_get_nvlist(nvl, otherkey2));
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_take_number__single_remove);
ATF_TEST_CASE_BODY(nvlist_take_number__single_remove)
{
nvlist_t *nvl;
const char *testkey;
uint64_t testval;
nvl = nvlist_create(0);
ATF_REQUIRE(nvl != NULL);
testkey = "numkey";
testval = std::numeric_limits<uint64_t>::max();
nvlist_add_number(nvl, testkey, testval);
ATF_REQUIRE_EQ(nvlist_take_number(nvl, testkey), testval);
ATF_REQUIRE(nvlist_empty(nvl));
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_take_number__other_keys_unchanged);
ATF_TEST_CASE_BODY(nvlist_take_number__other_keys_unchanged)
{
nvlist_t *nvl;
const char *testkey, *otherkey1, *otherkey2;
uint64_t testval, otherval1;
const char *otherval2;
nvl = nvlist_create(0);
ATF_REQUIRE(nvl != NULL);
otherkey1 = "key1";
otherval1 = 5;
nvlist_add_number(nvl, otherkey1, otherval1);
testkey = "numkey";
testval = 1654;
nvlist_add_number(nvl, testkey, testval);
otherkey2 = "key2";
otherval2 = "string";
nvlist_add_string(nvl, otherkey2, otherval2);
ATF_REQUIRE_EQ(nvlist_take_number(nvl, testkey), testval);
ATF_REQUIRE(nvlist_exists_number(nvl, otherkey1));
ATF_REQUIRE_EQ(nvlist_get_number(nvl, otherkey1), otherval1);
ATF_REQUIRE(nvlist_exists_string(nvl, otherkey2));
ATF_REQUIRE_EQ(strcmp(nvlist_get_string(nvl, otherkey2), otherval2), 0);
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_take_string__single_remove);
ATF_TEST_CASE_BODY(nvlist_take_string__single_remove)
{
nvlist_t *nvl;
const char *testkey;
const char *testval;
nvl = nvlist_create(0);
ATF_REQUIRE(nvl != NULL);
testkey = "numkey";
testval = "nvlist";
nvlist_add_string(nvl, testkey, testval);
ATF_REQUIRE_EQ(strcmp(nvlist_take_string(nvl, testkey), testval), 0);
ATF_REQUIRE(nvlist_empty(nvl));
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_take_string__other_keys_unchanged);
ATF_TEST_CASE_BODY(nvlist_take_string__other_keys_unchanged)
{
nvlist_t *nvl;
const char *testkey, *otherkey1, *otherkey2;
const char *testval, *otherval1;
bool otherval2;
nvl = nvlist_create(0);
ATF_REQUIRE(nvl != NULL);
otherkey1 = "key1";
otherval1 = "fjdifjdk";
nvlist_add_string(nvl, otherkey1, otherval1);
otherkey2 = "key2";
otherval2 = true;
nvlist_add_bool(nvl, otherkey2, otherval2);
testkey = "strkey";
testval = "1654";
nvlist_add_string(nvl, testkey, testval);
ATF_REQUIRE_EQ(strcmp(nvlist_take_string(nvl, testkey), testval), 0);
ATF_REQUIRE(nvlist_exists_string(nvl, otherkey1));
ATF_REQUIRE_EQ(strcmp(nvlist_get_string(nvl, otherkey1), otherval1), 0);
ATF_REQUIRE(nvlist_exists_bool(nvl, otherkey2));
ATF_REQUIRE_EQ(nvlist_get_bool(nvl, otherkey2), otherval2);
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_take_nvlist__single_remove);
ATF_TEST_CASE_BODY(nvlist_take_nvlist__single_remove)
{
nvlist_t *nvl;
const char *testkey;
nvlist_t *testval;
nvl = nvlist_create(0);
ATF_REQUIRE(nvl != NULL);
testkey = "numkey";
testval = create_test_nvlist();
nvlist_move_nvlist(nvl, testkey, testval);
verify_test_nvlist(nvlist_take_nvlist(nvl, testkey));
ATF_REQUIRE(nvlist_empty(nvl));
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_take_nvlist__other_keys_unchanged);
ATF_TEST_CASE_BODY(nvlist_take_nvlist__other_keys_unchanged)
{
nvlist_t *nvl;
const char *testkey, *otherkey1, *otherkey2;
nvlist_t *testval, *otherval1;
nvl = nvlist_create(0);
ATF_REQUIRE(nvl != NULL);
testkey = "strkey";
testval = create_test_nvlist();
nvlist_move_nvlist(nvl, testkey, testval);
otherkey1 = "key1";
otherval1 = nvlist_create(0);
nvlist_move_nvlist(nvl, otherkey1, otherval1);
otherkey2 = "key2";
nvlist_add_null(nvl, otherkey2);
verify_test_nvlist(nvlist_take_nvlist(nvl, testkey));
ATF_REQUIRE(nvlist_exists_nvlist(nvl, otherkey1));
ATF_REQUIRE(nvlist_empty(nvlist_get_nvlist(nvl, otherkey1)));
ATF_REQUIRE(nvlist_exists_null(nvl, otherkey2));
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_take_binary__single_remove);
ATF_TEST_CASE_BODY(nvlist_take_binary__single_remove)
{
nvlist_t *nvl;
const char *testkey;
void *testval;
const void *actual_val;
size_t testsize, actual_size;
nvl = nvlist_create(0);
ATF_REQUIRE(nvl != NULL);
testkey = "numkey";
testsize = 457;
testval = malloc(testsize);
memset(testval, '5', testsize);
nvlist_move_binary(nvl, testkey, testval, testsize);
actual_val = nvlist_take_binary(nvl, testkey, &actual_size);
ATF_REQUIRE_EQ(testsize, actual_size);
ATF_REQUIRE_EQ(memcmp(actual_val, testval, testsize), 0);
ATF_REQUIRE(nvlist_empty(nvl));
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_take_binary__other_keys_unchanged);
ATF_TEST_CASE_BODY(nvlist_take_binary__other_keys_unchanged)
{
nvlist_t *nvl;
const char *testkey, *otherkey1, *otherkey2;
const void *actual_value;
char testval[] = "gjiertj";
char otherval1[] = "fdreg";
size_t testsize, othersize, actual_size;
bool otherval2;
nvl = nvlist_create(0);
ATF_REQUIRE(nvl != NULL);
otherkey1 = "key1";
othersize = sizeof(otherval1);
nvlist_add_binary(nvl, otherkey1, otherval1, othersize);
otherkey2 = "key2";
otherval2 = true;
nvlist_add_bool(nvl, otherkey2, otherval2);
testkey = "strkey";
testsize = sizeof(testval);
nvlist_add_binary(nvl, testkey, testval, testsize);
actual_value = nvlist_take_binary(nvl, testkey, &actual_size);
ATF_REQUIRE_EQ(testsize, actual_size);
ATF_REQUIRE_EQ(memcmp(actual_value, testval, testsize), 0);
ATF_REQUIRE(nvlist_exists_binary(nvl, otherkey1));
actual_value = nvlist_get_binary(nvl, otherkey1, &actual_size);
ATF_REQUIRE_EQ(othersize, actual_size);
ATF_REQUIRE_EQ(memcmp(actual_value, otherval1, othersize), 0);
ATF_REQUIRE(nvlist_exists_bool(nvl, otherkey2));
ATF_REQUIRE_EQ(nvlist_get_bool(nvl, otherkey2), otherval2);
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_free__single_null);
ATF_TEST_CASE_BODY(nvlist_free__single_null)
{
nvlist_t *nvl;
const char *key;
nvl = nvlist_create(0);
key = "test";
nvlist_add_null(nvl, key);
nvlist_free(nvl, key);
ATF_REQUIRE(nvlist_empty(nvl));
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_free__single_bool);
ATF_TEST_CASE_BODY(nvlist_free__single_bool)
{
nvlist_t *nvl;
const char *key;
nvl = nvlist_create(0);
key = "test";
nvlist_add_bool(nvl, key, true);
nvlist_free(nvl, key);
ATF_REQUIRE(nvlist_empty(nvl));
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_free__single_number);
ATF_TEST_CASE_BODY(nvlist_free__single_number)
{
nvlist_t *nvl;
const char *key;
nvl = nvlist_create(0);
key = "test";
nvlist_add_number(nvl, key, 584);
nvlist_free(nvl, key);
ATF_REQUIRE(nvlist_empty(nvl));
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_free__single_string);
ATF_TEST_CASE_BODY(nvlist_free__single_string)
{
nvlist_t *nvl;
const char *key;
nvl = nvlist_create(0);
key = "test";
nvlist_add_string(nvl, key, "gjkfkjd");
nvlist_free(nvl, key);
ATF_REQUIRE(nvlist_empty(nvl));
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_free__single_nvlist);
ATF_TEST_CASE_BODY(nvlist_free__single_nvlist)
{
nvlist_t *nvl;
const char *key;
nvl = nvlist_create(0);
key = "test";
nvlist_add_nvlist(nvl, key, nvlist_create(0));
nvlist_free(nvl, key);
ATF_REQUIRE(nvlist_empty(nvl));
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_free__single_binary);
ATF_TEST_CASE_BODY(nvlist_free__single_binary)
{
nvlist_t *nvl;
const char *key;
nvl = nvlist_create(0);
key = "test";
nvlist_add_binary(nvl, key, "jgjgfd", 6);
nvlist_free(nvl, key);
ATF_REQUIRE(nvlist_empty(nvl));
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_free_null__single_null);
ATF_TEST_CASE_BODY(nvlist_free_null__single_null)
{
nvlist_t *nvl;
const char *key;
nvl = nvlist_create(0);
key = "test";
nvlist_add_null(nvl, key);
nvlist_free_null(nvl, key);
ATF_REQUIRE(nvlist_empty(nvl));
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_free_bool__single_bool);
ATF_TEST_CASE_BODY(nvlist_free_bool__single_bool)
{
nvlist_t *nvl;
const char *key;
nvl = nvlist_create(0);
key = "test";
nvlist_add_bool(nvl, key, true);
nvlist_free_bool(nvl, key);
ATF_REQUIRE(nvlist_empty(nvl));
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_free_number__single_number);
ATF_TEST_CASE_BODY(nvlist_free_number__single_number)
{
nvlist_t *nvl;
const char *key;
nvl = nvlist_create(0);
key = "test";
nvlist_add_number(nvl, key, 584);
nvlist_free_number(nvl, key);
ATF_REQUIRE(nvlist_empty(nvl));
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_free_string__single_string);
ATF_TEST_CASE_BODY(nvlist_free_string__single_string)
{
nvlist_t *nvl;
const char *key;
nvl = nvlist_create(0);
key = "test";
nvlist_add_string(nvl, key, "gjkfkjd");
nvlist_free_string(nvl, key);
ATF_REQUIRE(nvlist_empty(nvl));
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_free_nvlist__single_nvlist);
ATF_TEST_CASE_BODY(nvlist_free_nvlist__single_nvlist)
{
nvlist_t *nvl;
const char *key;
nvl = nvlist_create(0);
key = "test";
nvlist_add_nvlist(nvl, key, nvlist_create(0));
nvlist_free_nvlist(nvl, key);
ATF_REQUIRE(nvlist_empty(nvl));
nvlist_destroy(nvl);
}
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_free_binary__single_binary);
ATF_TEST_CASE_BODY(nvlist_free_binary__single_binary)
{
nvlist_t *nvl;
const char *key;
nvl = nvlist_create(0);
key = "test";
nvlist_add_binary(nvl, key, "jgjgfd", 6);
nvlist_free_binary(nvl, key);
ATF_REQUIRE(nvlist_empty(nvl));
nvlist_destroy(nvl);
}
ATF_INIT_TEST_CASES(tp)
{
ATF_ADD_TEST_CASE(tp, nvlist_create__is_empty);
ATF_ADD_TEST_CASE(tp, nvlist_add_null__single_insert);
ATF_ADD_TEST_CASE(tp, nvlist_add_bool__single_insert);
ATF_ADD_TEST_CASE(tp, nvlist_add_number__single_insert);
ATF_ADD_TEST_CASE(tp, nvlist_add_string__single_insert);
ATF_ADD_TEST_CASE(tp, nvlist_add_nvlist__single_insert);
ATF_ADD_TEST_CASE(tp, nvlist_add_nvlist__child_with_error);
ATF_ADD_TEST_CASE(tp, nvlist_add_binary__single_insert);
ATF_ADD_TEST_CASE(tp, nvlist_clone__empty_nvlist);
ATF_ADD_TEST_CASE(tp, nvlist_clone__nonempty_nvlist);
ATF_ADD_TEST_CASE(tp, nvlist_clone__nested_nvlist);
ATF_ADD_TEST_CASE(tp, nvlist_clone__error_nvlist);
ATF_ADD_TEST_CASE(tp, nvlist_pack__empty_nvlist);
ATF_ADD_TEST_CASE(tp, nvlist_pack__multiple_values);
ATF_ADD_TEST_CASE(tp, nvlist_pack__error_nvlist);
ATF_ADD_TEST_CASE(tp, nvlist_unpack__duplicate_key);
ATF_ADD_TEST_CASE(tp, nvlist_unpack__flags_nvlist);
ATF_ADD_TEST_CASE(tp, nvlist_move_string__single_insert);
ATF_ADD_TEST_CASE(tp, nvlist_move_nvlist__single_insert);
ATF_ADD_TEST_CASE(tp, nvlist_move_nvlist__null_child);
ATF_ADD_TEST_CASE(tp, nvlist_move_nvlist__child_with_error);
ATF_ADD_TEST_CASE(tp, nvlist_move_binary__single_insert);
ATF_ADD_TEST_CASE(tp, nvlist_take_bool__single_remove);
ATF_ADD_TEST_CASE(tp, nvlist_take_bool__other_keys_unchanged);
ATF_ADD_TEST_CASE(tp, nvlist_take_number__single_remove);
ATF_ADD_TEST_CASE(tp, nvlist_take_number__other_keys_unchanged);
ATF_ADD_TEST_CASE(tp, nvlist_take_string__single_remove);
ATF_ADD_TEST_CASE(tp, nvlist_take_string__other_keys_unchanged);
ATF_ADD_TEST_CASE(tp, nvlist_take_nvlist__single_remove);
ATF_ADD_TEST_CASE(tp, nvlist_take_nvlist__other_keys_unchanged);
ATF_ADD_TEST_CASE(tp, nvlist_take_binary__single_remove);
ATF_ADD_TEST_CASE(tp, nvlist_take_binary__other_keys_unchanged);
ATF_ADD_TEST_CASE(tp, nvlist_free__single_null);
ATF_ADD_TEST_CASE(tp, nvlist_free__single_bool);
ATF_ADD_TEST_CASE(tp, nvlist_free__single_number);
ATF_ADD_TEST_CASE(tp, nvlist_free__single_string);
ATF_ADD_TEST_CASE(tp, nvlist_free__single_nvlist);
ATF_ADD_TEST_CASE(tp, nvlist_free__single_binary);
ATF_ADD_TEST_CASE(tp, nvlist_free_null__single_null);
ATF_ADD_TEST_CASE(tp, nvlist_free_bool__single_bool);
ATF_ADD_TEST_CASE(tp, nvlist_free_number__single_number);
ATF_ADD_TEST_CASE(tp, nvlist_free_string__single_string);
ATF_ADD_TEST_CASE(tp, nvlist_free_nvlist__single_nvlist);
ATF_ADD_TEST_CASE(tp, nvlist_free_binary__single_binary);
}