text: /*-
   * Copyright (c) 2014-2015 Sandvine Inc.  All rights reserved.
   * Copyright (c) 2020 David Zero <zero-one@zer0-one.net>
   * 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.
   */
  
  #ifdef __linux__
  #include <bsd/sys/cdefs.h>
  #else
  #include <sys/cdefs.h>
  #endif
  
  #include "nv.h"
  
  #include <atf-c++.hpp>
  
  #include <cstring>
  #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);
  }
  