diff options
| -rw-r--r-- | libnvxx/nvxx.cc | 278 | ||||
| -rw-r--r-- | libnvxx/nvxx_base.h | 72 | ||||
| -rw-r--r-- | libnvxx/tests/nvxx_basic.cc | 297 |
3 files changed, 608 insertions, 39 deletions
diff --git a/libnvxx/nvxx.cc b/libnvxx/nvxx.cc index 69b57f5..8decebf 100644 --- a/libnvxx/nvxx.cc +++ b/libnvxx/nvxx.cc @@ -376,7 +376,21 @@ __const_nv_list::exists_null(std::string_view key) const void __nv_list::add_null(std::string_view key) { - ::nvlist_add_null(__m_nv, std::string(key).c_str()); + auto skey = std::string(key); + + ::nvlist_add_null(__m_nv, skey.c_str()); + + switch (auto err = ::nvlist_error(__m_nv)) { + case 0: + return; + + case EEXIST: + throw nv_key_exists(skey); + + default: + throw std::system_error( + std::error_code(err, std::generic_category())); + } } void @@ -392,7 +406,21 @@ __nv_list::free_null(std::string_view key) void __nv_list::add_bool(std::string_view key, bool value) { - ::nvlist_add_bool(__m_nv, std::string(key).c_str(), value); + auto skey = std::string(key); + + ::nvlist_add_bool(__m_nv, skey.c_str(), value); + + switch (auto err = ::nvlist_error(__m_nv)) { + case 0: + return; + + case EEXIST: + throw nv_key_exists(skey); + + default: + throw std::system_error( + std::error_code(err, std::generic_category())); + } } bool @@ -404,13 +432,23 @@ __const_nv_list::exists_bool(std::string_view key) const bool __const_nv_list::get_bool(std::string_view key) const { - return ::nvlist_get_bool(__m_nv, std::string(key).c_str()); + auto skey = std::string(key); + + if (!::nvlist_exists_bool(__m_nv, skey.c_str())) + throw nv_key_not_found(skey); + + return ::nvlist_get_bool(__m_nv, skey.c_str()); } bool __nv_list::take_bool(std::string_view key) { - return ::nvlist_take_bool(__m_nv, std::string(key).c_str()); + auto skey = std::string(key); + + if (!::nvlist_exists_bool(__m_nv, skey.c_str())) + throw nv_key_not_found(skey); + + return ::nvlist_take_bool(__m_nv, skey.c_str()); } void @@ -449,10 +487,23 @@ void __nv_list::add_bool_array(std::string_view key, std::span<bool const> value) { - ::nvlist_add_bool_array(__m_nv, - std::string(key).c_str(), + auto skey = std::string(key); + + ::nvlist_add_bool_array(__m_nv, skey.c_str(), std::ranges::data(value), std::ranges::size(value)); + + switch (auto err = ::nvlist_error(__m_nv)) { + case 0: + return; + + case EEXIST: + throw nv_key_exists(skey); + + default: + throw std::system_error( + std::error_code(err, std::generic_category())); + } } void @@ -482,7 +533,21 @@ __nv_list::free_bool_array(std::string_view key) void __nv_list::add_number(std::string_view key, std::uint64_t value) { - ::nvlist_add_number(__m_nv, std::string(key).c_str(), value); + auto skey = std::string(key); + + ::nvlist_add_number(__m_nv, skey.c_str(), value); + + switch (auto err = ::nvlist_error(__m_nv)) { + case 0: + return; + + case EEXIST: + throw nv_key_exists(skey); + + default: + throw std::system_error( + std::error_code(err, std::generic_category())); + } } bool @@ -494,13 +559,23 @@ __const_nv_list::exists_number(std::string_view key) const std::uint64_t __const_nv_list::get_number(std::string_view key) const { - return ::nvlist_get_number(__m_nv, std::string(key).c_str()); + auto skey = std::string(key); + + if (!::nvlist_exists_number(__m_nv, skey.c_str())) + throw nv_key_not_found(skey); + + return ::nvlist_get_number(__m_nv, skey.c_str()); } std::uint64_t __nv_list::take_number(std::string_view key) { - return ::nvlist_take_number(__m_nv, std::string(key).c_str()); + auto skey = std::string(key); + + if (!::nvlist_exists_number(__m_nv, skey.c_str())) + throw nv_key_not_found(skey); + + return ::nvlist_take_number(__m_nv, skey.c_str()); } void @@ -539,9 +614,23 @@ void __nv_list::add_number_array(std::string_view key, std::span<std::uint64_t const> value) { - ::nvlist_add_number_array(__m_nv, std::string(key).c_str(), + auto skey = std::string(key); + + ::nvlist_add_number_array(__m_nv, skey.c_str(), std::ranges::data(value), std::ranges::size(value)); + + switch (auto err = ::nvlist_error(__m_nv)) { + case 0: + return; + + case EEXIST: + throw nv_key_exists(skey); + + default: + throw std::system_error( + std::error_code(err, std::generic_category())); + } } void @@ -572,9 +661,21 @@ __nv_list::free_number_array(std::string_view key) void __nv_list::add_string(std::string_view key, std::string_view value) { - ::nvlist_add_string(__m_nv, - std::string(key).c_str(), - std::string(value).c_str()); + auto skey = std::string(key); + + ::nvlist_add_string(__m_nv, skey.c_str(), std::string(value).c_str()); + + switch (auto err = ::nvlist_error(__m_nv)) { + case 0: + return; + + case EEXIST: + throw nv_key_exists(skey); + + default: + throw std::system_error( + std::error_code(err, std::generic_category())); + } } void @@ -592,13 +693,23 @@ __const_nv_list::exists_string(std::string_view key) const std::string_view __const_nv_list::get_string(std::string_view key) const { - return nvlist_get_string(__m_nv, std::string(key).c_str()); + auto skey = std::string(key); + + if (!::nvlist_exists_string(__m_nv, skey.c_str())) + throw nv_key_not_found(skey); + + return nvlist_get_string(__m_nv, skey.c_str()); } std::string __nv_list::take_string(std::string_view key) { - return nvlist_take_string(__m_nv, std::string(key).c_str()); + auto skey = std::string(key); + + if (!::nvlist_exists_string(__m_nv, skey.c_str())) + throw nv_key_not_found(skey); + + return nvlist_take_string(__m_nv, skey.c_str()); } void @@ -611,6 +722,8 @@ void __nv_list::add_string_array(std::string_view key, std::span<std::string_view const> value) { + auto skey = std::string(key); + // nvlist_add_string_array expects an array of NUL-terminated // C strings. @@ -622,8 +735,20 @@ __nv_list::add_string_array(std::string_view key, | std::views::transform(&std::string::c_str) | std::ranges::to<std::vector>(); - nvlist_add_string_array(__m_nv, std::string(key).c_str(), - ptrs.data(), ptrs.size()); + ::nvlist_add_string_array(__m_nv, skey.c_str(), + ptrs.data(), ptrs.size()); + + switch (auto err = ::nvlist_error(__m_nv)) { + case 0: + return; + + case EEXIST: + throw nv_key_exists(skey); + + default: + throw std::system_error( + std::error_code(err, std::generic_category())); + } } void @@ -684,7 +809,21 @@ __nv_list::free_string_array(std::string_view key) void __nv_list::add_nvlist(std::string_view key, const_nv_list const &other) { - nvlist_add_nvlist(__m_nv, std::string(key).c_str(), other.__m_nv); + auto skey = std::string(key); + + ::nvlist_add_nvlist(__m_nv, skey.c_str(), other.__m_nv); + + switch (auto err = ::nvlist_error(__m_nv)) { + case 0: + return; + + case EEXIST: + throw nv_key_exists(skey); + + default: + throw std::system_error( + std::error_code(err, std::generic_category())); + } } void @@ -709,14 +848,24 @@ __const_nv_list::exists_nvlist(std::string_view key) const const_nv_list __const_nv_list::get_nvlist(std::string_view key) const { - auto nvl = nvlist_get_nvlist(__m_nv, std::string(key).c_str()); + auto skey = std::string(key); + + if (!::nvlist_exists_nvlist(__m_nv, skey.c_str())) + throw nv_key_not_found(skey); + + auto nvl = ::nvlist_get_nvlist(__m_nv, skey.c_str()); return const_nv_list(nvl); } nv_list __nv_list::take_nvlist(std::string_view key) { - auto nvl = nvlist_take_nvlist(__m_nv, std::string(key).c_str()); + auto skey = std::string(key); + + if (!::nvlist_exists_nvlist(__m_nv, skey.c_str())) + throw nv_key_not_found(skey); + + auto nvl = nvlist_take_nvlist(__m_nv, skey.c_str()); return nv_list(nvl); } @@ -736,24 +885,52 @@ void __nv_list::add_nvlist_array(std::string_view key, std::span<const_nv_list const> value) { + auto skey = std::string(key); + auto ptrs = value | std::views::transform(&const_nv_list::__m_nv) | std::ranges::to<std::vector>(); - ::nvlist_add_nvlist_array(__m_nv, std::string(key).c_str(), + ::nvlist_add_nvlist_array(__m_nv, skey.c_str(), ptrs.data(), ptrs.size()); + + switch (auto err = ::nvlist_error(__m_nv)) { + case 0: + return; + + case EEXIST: + throw nv_key_exists(skey); + + default: + throw std::system_error( + std::error_code(err, std::generic_category())); + } } void __nv_list::add_nvlist_array(std::string_view key, std::span<nv_list const> value) { + auto skey = std::string(key); + auto ptrs = value | std::views::transform(&nv_list::__m_nv) | std::ranges::to<std::vector>(); - nvlist_add_nvlist_array(__m_nv, std::string(key).c_str(), + nvlist_add_nvlist_array(__m_nv, skey.c_str(), ptrs.data(), ptrs.size()); + + switch (auto err = ::nvlist_error(__m_nv)) { + case 0: + return; + + case EEXIST: + throw nv_key_exists(skey); + + default: + throw std::system_error( + std::error_code(err, std::generic_category())); + } } void @@ -820,7 +997,21 @@ __nv_list::take_descriptor(std::string_view key) void __nv_list::add_descriptor(std::string_view key, int value) { - ::nvlist_add_descriptor(__m_nv, std::string(key).c_str(), value); + auto skey = std::string(key); + + ::nvlist_add_descriptor(__m_nv, skey.c_str(), value); + + switch (auto err = ::nvlist_error(__m_nv)) { + case 0: + return; + + case EEXIST: + throw nv_key_exists(skey); + + default: + throw std::system_error( + std::error_code(err, std::generic_category())); + } } void @@ -847,9 +1038,23 @@ void __nv_list::add_descriptor_array(std::string_view key, std::span<int const> value) { - ::nvlist_add_descriptor_array(__m_nv, std::string(key).c_str(), + auto skey = std::string(key); + + ::nvlist_add_descriptor_array(__m_nv, skey.c_str(), std::ranges::data(value), std::ranges::size(value)); + + switch (auto err = ::nvlist_error(__m_nv)) { + case 0: + return; + + case EEXIST: + throw nv_key_exists(skey); + + default: + throw std::system_error( + std::error_code(err, std::generic_category())); + } } void @@ -912,9 +1117,23 @@ __const_nv_list::exists_binary(std::string_view key) const void __nv_list::add_binary(std::string_view key, std::span<std::byte const> value) { - ::nvlist_add_binary(__m_nv, std::string(key).c_str(), + auto skey = std::string(key); + + ::nvlist_add_binary(__m_nv, skey.c_str(), std::ranges::data(value), std::ranges::size(value)); + + switch (auto err = ::nvlist_error(__m_nv)) { + case 0: + return; + + case EEXIST: + throw nv_key_exists(skey); + + default: + throw std::system_error( + std::error_code(err, std::generic_category())); + } } void @@ -943,10 +1162,13 @@ __const_nv_list::get_binary(std::string_view key) const std::vector<std::byte> __nv_list::take_binary(std::string_view key) { + auto skey = std::string(key); + + if (!::nvlist_exists_binary(__m_nv, skey.c_str())) + throw nv_key_not_found(skey); + auto size = std::size_t{}; - auto *data = ::nvlist_take_binary(__m_nv, - std::string(key).c_str(), - &size); + auto *data = ::nvlist_take_binary(__m_nv, skey.c_str(), &size); auto ptr = ptr_guard(static_cast<std::byte *>(data)); return {ptr.ptr, ptr.ptr + size}; } diff --git a/libnvxx/nvxx_base.h b/libnvxx/nvxx_base.h index aa0a765..4700e79 100644 --- a/libnvxx/nvxx_base.h +++ b/libnvxx/nvxx_base.h @@ -33,12 +33,42 @@ #include <system_error> #include <vector> #include <stdexcept> +#include <format> namespace bsd { struct nv_list; struct const_nv_list; +struct nv_error : std::runtime_error { + template<typename... _Args> + nv_error(std::format_string<_Args...> __fmt, _Args && ...__args) + : runtime_error(std::format(__fmt, + std::forward<_Args>(__args)...)) + { + } +}; + +struct nv_key_not_found : nv_error { + std::string key; + + nv_key_not_found(std::string __key) + : nv_error("key \"{0}\" not found", __key) + , key(__key) + { + } +}; + +struct nv_key_exists : nv_error { + std::string key; + + nv_key_exists(std::string __key) + : nv_error("key \"{0}\" already exists", __key) + , key(__key) + { + } +}; + namespace __detail { enum struct __nvlist_owning { @@ -413,6 +443,48 @@ struct __nv_list : virtual __nv_list_base { auto __arr = std::vector(std::from_range, __value); add_number_range(__key, __arr); } + + /* add_nvlist_range */ + + template<std::ranges::contiguous_range _Range> + requires std::is_same_v<nv_list, + std::remove_cvref_t< + std::ranges::range_value_t<_Range>>> + void add_nvlist_range(std::string_view __key, _Range &&__value) + { + add_nvlist_array(__key, std::span(__value)); + } + + template<std::ranges::range _Range> + requires (!std::ranges::contiguous_range<_Range> + && std::is_same_v<nv_list, + std::remove_cvref_t< + std::ranges::range_value_t<_Range>>>) + void add_nvlist_range(std::string_view __key, _Range &&__value) + { + auto __arr = std::vector(std::from_range, __value); + add_nvlist_range(__key, __arr); + } + + template<std::ranges::contiguous_range _Range> + requires std::is_same_v<const_nv_list, + std::remove_cvref_t< + std::ranges::range_value_t<_Range>>> + void add_nvlist_range(std::string_view __key, _Range &&__value) + { + add_nvlist_array(__key, std::span(__value)); + } + + template<std::ranges::range _Range> + requires (!std::ranges::contiguous_range<_Range> + && std::is_same_v<const_nv_list, + std::remove_cvref_t< + std::ranges::range_value_t<_Range>>>) + void add_nvlist_range(std::string_view __key, _Range &&__value) + { + auto __arr = std::vector(std::from_range, __value); + add_nvlist_range(__key, __arr); + } }; } // namespace bsd::__detail diff --git a/libnvxx/tests/nvxx_basic.cc b/libnvxx/tests/nvxx_basic.cc index 1cf2bfd..7cdf639 100644 --- a/libnvxx/tests/nvxx_basic.cc +++ b/libnvxx/tests/nvxx_basic.cc @@ -66,10 +66,40 @@ TEST_CASE(nvxx_ignore_case) TEST_CASE(nvxx_add_null) { + using namespace std::literals; + auto constexpr key = "test_null"sv; + + auto nvl = bsd::nv_list(); + nvl.add_null(key); + ATF_REQUIRE_EQ(true, nvl.exists_null(key)); + ATF_REQUIRE_EQ(true, nvl.exists(key)); +} + +TEST_CASE(nvxx_add_duplicate_null) +{ + using namespace std::literals; + auto constexpr key = "test_null"sv; + + auto nvl = bsd::nv_list(); + nvl.add_null(key); + + ATF_REQUIRE_THROW_RE(bsd::nv_key_exists, + "key \"test_null\" already exists", + nvl.add_null(key)); +} + +TEST_CASE(nvxx_free_null) +{ + using namespace std::literals; + auto constexpr key = "test null"sv; + auto nvl = bsd::nv_list(); - nvl.add_null("test"); - ATF_REQUIRE_EQ(true, nvl.exists_null("test")); - ATF_REQUIRE_EQ(true, nvl.exists("test")); + + nvl.add_null(key); + ATF_REQUIRE_EQ(true, nvl.exists_null(key)); + + nvl.free_null(key); + ATF_REQUIRE_EQ(false, nvl.exists_null(key)); } /* @@ -90,6 +120,29 @@ TEST_CASE(nvxx_add_bool) ATF_REQUIRE_EQ(value, nvl.get_bool(key)); } +TEST_CASE(nvxx_add_duplicate_bool) +{ + using namespace std::literals; + auto constexpr key = "test_bool"sv; + auto constexpr value = true; + + auto nvl = bsd::nv_list(); + nvl.add_bool(key, value); + + ATF_REQUIRE_THROW_RE(bsd::nv_key_exists, + "key \"test_bool\" already exists", + nvl.add_bool(key, value)); +} + +TEST_CASE(nvxx_get_nonexistent_bool) +{ + auto nvl = bsd::nv_list(); + + ATF_REQUIRE_THROW_RE(bsd::nv_key_not_found, + "key \"nonesuch\" not found", + (void)nvl.get_bool("nonesuch")); +} + TEST_CASE(nvxx_take_bool) { using namespace std::literals; @@ -100,7 +153,10 @@ TEST_CASE(nvxx_take_bool) nvl.add_bool(key, value); auto b = nvl.take_bool(key); ATF_REQUIRE_EQ(value, b); - ATF_REQUIRE_EQ(false, nvl.exists(key)); + + ATF_REQUIRE_THROW_RE(bsd::nv_key_not_found, + "key \"test_bool\" not found", + (void)nvl.take_bool(key)); } TEST_CASE(nvxx_free_bool) @@ -140,6 +196,21 @@ TEST_CASE(nvxx_add_bool_array) ATF_REQUIRE_EQ(false, nvl.exists(key)); } +TEST_CASE(nvxx_add_duplicate_bool_array) +{ + using namespace std::literals; + auto constexpr key = "test_bool"sv; + auto data = std::array<bool, 2>{true, false}; + auto value = std::span(data); + + auto nvl = bsd::nv_list(); + nvl.add_bool_array(key, value); + + ATF_REQUIRE_THROW_RE(bsd::nv_key_exists, + "key \"test_bool\" already exists", + nvl.add_bool_array(key, value)); +} + TEST_CASE(nvxx_add_bool_range) { using namespace std::literals; @@ -201,6 +272,28 @@ TEST_CASE(nvxx_add_number) ATF_REQUIRE_EQ(value, nvl.get_number(key)); } +TEST_CASE(nvxx_add_duplicate_number) +{ + using namespace std::literals; + auto constexpr key = "test_number"sv; + auto constexpr value = 42u; + + auto nvl = bsd::nv_list(); + nvl.add_number(key, value); + + ATF_REQUIRE_THROW_RE(bsd::nv_key_exists, + "key \"test_number\" already exists", + nvl.add_number(key, value)); +} + +TEST_CASE(nvxx_get_nonexistent_number) +{ + auto nvl = bsd::nv_list(); + ATF_REQUIRE_THROW_RE(bsd::nv_key_not_found, + "key \"nonesuch\" not found", + (void)nvl.get_number("nonesuch")); +} + TEST_CASE(nvxx_take_number) { using namespace std::literals; @@ -212,7 +305,10 @@ TEST_CASE(nvxx_take_number) nvl.add_number(key, value); auto n = nvl.take_number(key); ATF_REQUIRE_EQ(value, n); - ATF_REQUIRE_EQ(false, nvl.exists(key)); + + ATF_REQUIRE_THROW_RE(bsd::nv_key_not_found, + "key \"test_number\" not found", + (void)nvl.take_number(key)); } TEST_CASE(nvxx_free_number) @@ -251,6 +347,20 @@ TEST_CASE(nvxx_add_number_array) ATF_REQUIRE_EQ(false, nvl.exists(key)); } +TEST_CASE(nvxx_add_duplicate_number_array) +{ + using namespace std::literals; + auto constexpr key = "test_number"sv; + auto value = std::vector{42_u64, 1024_u64}; + + auto nvl = bsd::nv_list(); + nvl.add_number_range(key, value); + + ATF_REQUIRE_THROW_RE(bsd::nv_key_exists, + "key \"test_number\" already exists", + nvl.add_number_range(key, value)); +} + TEST_CASE(nvxx_add_number_range) { using namespace std::literals; @@ -307,6 +417,28 @@ TEST_CASE(nvxx_add_string) ATF_REQUIRE_EQ(value, nvl.get_string(key)); } +TEST_CASE(nvxx_add_duplicate_string) +{ + using namespace std::literals; + auto constexpr key = "test_string"sv; + auto constexpr value = "testing value"sv; + + auto nvl = bsd::nv_list(); + nvl.add_string(key, value); + + ATF_REQUIRE_THROW_RE(bsd::nv_key_exists, + "key \"test_string\" already exists", + nvl.add_string(key, value)); +} + +TEST_CASE(nvxx_get_nonexistent_string) +{ + auto nvl = bsd::nv_list(); + ATF_REQUIRE_THROW_RE(bsd::nv_key_not_found, + "key \"nonesuch\" not found", + (void)nvl.get_string("nonesuch")); +} + TEST_CASE(nvxx_take_string) { using namespace std::literals; @@ -317,7 +449,10 @@ TEST_CASE(nvxx_take_string) nvl.add_string(key, value); auto s = nvl.take_string(key); ATF_REQUIRE_EQ(value, s); - ATF_REQUIRE_EQ(false, nvl.exists(key)); + + ATF_REQUIRE_THROW_RE(bsd::nv_key_not_found, + "key \"test_string\" not found", + (void)nvl.take_string(key)); } TEST_CASE(nvxx_free_string) @@ -353,6 +488,20 @@ TEST_CASE(nvxx_add_string_array) ATF_REQUIRE_EQ(false, nvl.exists(key)); } +TEST_CASE(nvxx_add_duplicate_string_array) +{ + using namespace std::literals; + auto constexpr key = "test_string"sv; + auto value = std::vector{"one"sv, "two"sv, "three"sv}; + + auto nvl = bsd::nv_list(); + nvl.add_string_range(key, value); + + ATF_REQUIRE_THROW_RE(bsd::nv_key_exists, + "key \"test_string\" already exists", + nvl.add_string_range(key, value)); +} + TEST_CASE(nvxx_add_string_range) { using namespace std::literals; @@ -412,16 +561,43 @@ TEST_CASE(nvxx_add_nvlist) .get_number("test_number")); } +TEST_CASE(nvxx_add_duplicate_nvlist) +{ + using namespace std::literals; + auto constexpr key = "test_nvlist"sv; + auto value = bsd::nv_list{}; + + auto nvl = bsd::nv_list{}; + nvl.add_nvlist(key, value); + + ATF_REQUIRE_THROW_RE(bsd::nv_key_exists, + "key \"test_nvlist\" already exists", + nvl.add_nvlist(key, value)); +} + +TEST_CASE(nvxx_get_nonexistent_nvlist) +{ + auto nvl = bsd::nv_list(); + ATF_REQUIRE_THROW_RE(bsd::nv_key_not_found, + "key \"nonesuch\" not found", + (void)nvl.get_nvlist("nonesuch")); +} + TEST_CASE(nvxx_take_nvlist) { + using namespace std::literals; + auto constexpr key = "test_nvlist"sv; auto nvl = bsd::nv_list(), nvl2 = bsd::nv_list(); nvl2.add_number("test_number", 42); - nvl.add_nvlist("test_nvlist", nvl2); + nvl.add_nvlist(key, nvl2); - auto nvl3 = nvl.take_nvlist("test_nvlist"); - ATF_REQUIRE_EQ(false, nvl.exists("test_nvlist")); + auto nvl3 = nvl.take_nvlist(key); ATF_REQUIRE_EQ(42, nvl3.get_number("test_number")); + + ATF_REQUIRE_THROW_RE(bsd::nv_key_not_found, + "key \"test_nvlist\" not found", + (void)nvl.take_nvlist(key)); } TEST_CASE(nvxx_free_nvlist) @@ -469,9 +645,23 @@ TEST_CASE(nvxx_add_nvlist_array) ATF_REQUIRE_EQ(n2, 2); } +TEST_CASE(nvxx_add_duplicate_nvlist_array) +{ + using namespace std::literals; + auto constexpr key = "test_nvlist"sv; + auto value = std::vector<bsd::nv_list>(2); + + auto nvl = bsd::nv_list(); + nvl.add_nvlist_range(key, value); + + ATF_REQUIRE_THROW_RE(bsd::nv_key_exists, + "key \"test_nvlist\" already exists", + nvl.add_nvlist_range(key, value)); +} + TEST_CASE(nvxx_add_descriptor) { - int fds[2] = {}; + auto fds = std::array<int, 2>{}; auto ret = ::pipe(&fds[0]); ATF_REQUIRE_EQ(0, ret); @@ -479,7 +669,7 @@ TEST_CASE(nvxx_add_descriptor) decltype([](auto fds) { ::close(fds[0]); ::close(fds[1]); - })>(fds); + })>(&fds[0]); auto nvl = bsd::nv_list(); nvl.add_descriptor("test_descriptor", fds[0]); @@ -500,6 +690,33 @@ TEST_CASE(nvxx_add_descriptor) ATF_REQUIRE_EQ('4', buf[3]); } +TEST_CASE(nvxx_add_duplicate_descriptor) +{ + using namespace std::literals; + auto constexpr key = "test_descriptor"sv; + + auto fds = std::array<int, 2>{}; + auto ret = ::pipe(&fds[0]); + ATF_REQUIRE_EQ(0, ret); + + auto guard = std::unique_ptr<int[], + decltype([](auto fds) { + ::close(fds[0]); + ::close(fds[1]); + })>(&fds[0]); + + auto nvl = bsd::nv_list{}; + nvl.add_descriptor(key, fds[0]); + + ATF_REQUIRE_THROW_RE(bsd::nv_key_exists, + "key \"test_descriptor\" already exists", + nvl.add_descriptor(key, fds[0])); +} + +/* + * binary + */ + TEST_CASE(nvxx_add_binary) { auto nvl = bsd::nv_list(); @@ -516,6 +733,41 @@ TEST_CASE(nvxx_add_binary) ATF_REQUIRE_EQ(true, std::ranges::equal(data, data2)); } +TEST_CASE(nvxx_add_duplicate_binary) +{ + using namespace std::literals; + auto constexpr key = "test_binary"sv; + auto constexpr value = std::array<std::byte, 16>{}; + + auto nvl = bsd::nv_list(); + nvl.add_binary(key, value); + + ATF_REQUIRE_THROW_RE(bsd::nv_key_exists, + "key \"test_binary\" already exists", + nvl.add_binary(key, value)); +} + +TEST_CASE(nvxx_take_binary) +{ + using namespace std::literals; + auto constexpr key = "test_binary"sv; + auto nvl = bsd::nv_list(); + + auto data = std::array<std::byte, 16>{}; + + for (auto i = 0u; i < data.size(); ++i) + data[i] = static_cast<std::byte>(i); + + nvl.add_binary(key, std::span(data)); + + auto data2 = nvl.take_binary(key); + ATF_REQUIRE_EQ(true, std::ranges::equal(data, data2)); + + ATF_REQUIRE_THROW_RE(bsd::nv_key_not_found, + "key \"test_binary\" not found", + (void)nvl.take_binary(key)); +} + TEST_CASE(nvxx_add_binary_range) { auto nvl = bsd::nv_list(); @@ -538,34 +790,57 @@ ATF_INIT_TEST_CASES(tcs) ATF_ADD_TEST_CASE(tcs, nvxx_ignore_case); ATF_ADD_TEST_CASE(tcs, nvxx_add_null); + ATF_ADD_TEST_CASE(tcs, nvxx_add_duplicate_null); + ATF_ADD_TEST_CASE(tcs, nvxx_free_null); ATF_ADD_TEST_CASE(tcs, nvxx_add_bool); + ATF_ADD_TEST_CASE(tcs, nvxx_add_duplicate_bool); + ATF_ADD_TEST_CASE(tcs, nvxx_get_nonexistent_bool); ATF_ADD_TEST_CASE(tcs, nvxx_take_bool); ATF_ADD_TEST_CASE(tcs, nvxx_free_bool); + ATF_ADD_TEST_CASE(tcs, nvxx_add_bool_array); + ATF_ADD_TEST_CASE(tcs, nvxx_add_duplicate_bool_array); ATF_ADD_TEST_CASE(tcs, nvxx_add_bool_range); ATF_ADD_TEST_CASE(tcs, nvxx_add_bool_contig_range); ATF_ADD_TEST_CASE(tcs, nvxx_add_number); + ATF_ADD_TEST_CASE(tcs, nvxx_add_duplicate_number); + ATF_ADD_TEST_CASE(tcs, nvxx_get_nonexistent_number); ATF_ADD_TEST_CASE(tcs, nvxx_take_number); ATF_ADD_TEST_CASE(tcs, nvxx_free_number); + ATF_ADD_TEST_CASE(tcs, nvxx_add_number_array); + ATF_ADD_TEST_CASE(tcs, nvxx_add_duplicate_number_array); ATF_ADD_TEST_CASE(tcs, nvxx_add_number_range); ATF_ADD_TEST_CASE(tcs, nvxx_add_number_contig_range); ATF_ADD_TEST_CASE(tcs, nvxx_add_string); + ATF_ADD_TEST_CASE(tcs, nvxx_add_duplicate_string); + ATF_ADD_TEST_CASE(tcs, nvxx_get_nonexistent_string); ATF_ADD_TEST_CASE(tcs, nvxx_take_string); ATF_ADD_TEST_CASE(tcs, nvxx_free_string); + ATF_ADD_TEST_CASE(tcs, nvxx_add_string_array); + ATF_ADD_TEST_CASE(tcs, nvxx_add_duplicate_string_array); ATF_ADD_TEST_CASE(tcs, nvxx_add_string_range); ATF_ADD_TEST_CASE(tcs, nvxx_add_string_contig_range); ATF_ADD_TEST_CASE(tcs, nvxx_add_nvlist); + ATF_ADD_TEST_CASE(tcs, nvxx_add_duplicate_nvlist); + ATF_ADD_TEST_CASE(tcs, nvxx_get_nonexistent_nvlist); ATF_ADD_TEST_CASE(tcs, nvxx_take_nvlist); ATF_ADD_TEST_CASE(tcs, nvxx_free_nvlist); + ATF_ADD_TEST_CASE(tcs, nvxx_add_nvlist_array); + ATF_ADD_TEST_CASE(tcs, nvxx_add_duplicate_nvlist_array); ATF_ADD_TEST_CASE(tcs, nvxx_add_descriptor); + ATF_ADD_TEST_CASE(tcs, nvxx_add_duplicate_descriptor); + ATF_ADD_TEST_CASE(tcs, nvxx_add_binary); + ATF_ADD_TEST_CASE(tcs, nvxx_add_duplicate_binary); + ATF_ADD_TEST_CASE(tcs, nvxx_take_binary); + ATF_ADD_TEST_CASE(tcs, nvxx_add_binary_range); } |
