From c0945246de2d656ec8f427a0ba89a0b3d1d899dc Mon Sep 17 00:00:00 2001 From: Kurt Sassenrath Date: Fri, 12 Jan 2024 13:37:39 -0800 Subject: [PATCH] Refactor packer tests to make recompilation faster --- tests/msgpack/BUILD | 18 -- tests/msgpack/packer/BUILD | 9 + tests/msgpack/packer/bytes.cpp | 63 ++++++ tests/msgpack/packer/ranges.cpp | 63 ++++++ tests/msgpack/packer/signed.cpp | 71 ++++++ tests/msgpack/packer/simple_types.cpp | 50 +++++ tests/msgpack/packer/strings.cpp | 46 ++++ tests/msgpack/packer/test_packer.h | 42 ++++ tests/msgpack/packer/unsigned.cpp | 71 ++++++ tests/msgpack/test_packer_rc.cpp | 306 -------------------------- 10 files changed, 415 insertions(+), 324 deletions(-) create mode 100644 tests/msgpack/packer/BUILD create mode 100644 tests/msgpack/packer/bytes.cpp create mode 100644 tests/msgpack/packer/ranges.cpp create mode 100644 tests/msgpack/packer/signed.cpp create mode 100644 tests/msgpack/packer/simple_types.cpp create mode 100644 tests/msgpack/packer/strings.cpp create mode 100644 tests/msgpack/packer/test_packer.h create mode 100644 tests/msgpack/packer/unsigned.cpp delete mode 100644 tests/msgpack/test_packer_rc.cpp diff --git a/tests/msgpack/BUILD b/tests/msgpack/BUILD index 58eb902..ea9d660 100644 --- a/tests/msgpack/BUILD +++ b/tests/msgpack/BUILD @@ -26,24 +26,6 @@ cc_test( deps = ["common"], ) -cc_test( - name = "packer", - size = "small", - srcs = [ - "test_packer.cpp", - ], - deps = ["common"], -) - -cc_test( - name = "packer_rc", - size = "small", - srcs = [ - "test_packer_rc.cpp", - ], - deps = ["common", "@rapidcheck"], -) - cc_test( name = "writer", size = "small", diff --git a/tests/msgpack/packer/BUILD b/tests/msgpack/packer/BUILD new file mode 100644 index 0000000..6f7b55f --- /dev/null +++ b/tests/msgpack/packer/BUILD @@ -0,0 +1,9 @@ +cc_test( + name = "packer", + size = "small", + srcs = glob([ + "*.cpp", + "*.h", + ]), + deps = ["//tests/msgpack:common", "@rapidcheck"], +) diff --git a/tests/msgpack/packer/bytes.cpp b/tests/msgpack/packer/bytes.cpp new file mode 100644 index 0000000..06c11c1 --- /dev/null +++ b/tests/msgpack/packer/bytes.cpp @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// ___ __ _ _ +// / _ \__ _ _ __ ___ ___ / /(_)_ __ | | __ +// / /_)/ _` | '__/ __|/ _ \/ / | | '_ \| |/ / +// / ___/ (_| | | \__ \ __/ /__| | | | | < +// \/ \__,_|_| |___/\___\____/_|_| |_|_|\_\ . +// +//----------------------------------------------------------------------------- +// Author: Kurt Sassenrath +// Module: msgpack +// +// Packer tests, byte types +// +// Copyright (c) 2023 Kurt Sassenrath. +// +// License TBD. +//----------------------------------------------------------------------------- + +#include "test_packer.h" + +using namespace boost::ut; + +suite pack_bytes = [] { +#if 0 + // Byte ranges -> Binary + "packer::pack>"_test = [] { + expect(test_deduced>()); + }; +#endif + "packer::pack>"_test = [] { + { + constexpr auto data = test::make_bytes(0x01, 0x02, 0x03, 0x04); + constexpr auto expected = + test::make_bytes(0xc4, 0x04, 0x01, 0x02, 0x03, 0x04); + std::array payload; + + msgpack::packer packer(payload); + expect(!!packer.pack(data)); + expect(std::ranges::equal(payload, expected)); + } + { + constexpr std::array data{}; + constexpr std::array expected{ + std::byte(0xc5), std::byte(0x01), std::byte(0x00)}; + std::array payload; + + msgpack::packer packer(payload); + expect(!!packer.pack(data)); + expect(std::ranges::equal(payload, expected)); + } + { + constexpr std::array data{}; + constexpr std::array expected{ + std::byte(0xc6), std::byte(0x00), std::byte(0x01), + std::byte(0x00), std::byte(0x00)}; + std::array payload; + + msgpack::packer packer(payload); + expect(!!packer.pack(data)); + expect(std::ranges::equal(payload, expected)); + } + }; +}; diff --git a/tests/msgpack/packer/ranges.cpp b/tests/msgpack/packer/ranges.cpp new file mode 100644 index 0000000..1888049 --- /dev/null +++ b/tests/msgpack/packer/ranges.cpp @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// ___ __ _ _ +// / _ \__ _ _ __ ___ ___ / /(_)_ __ | | __ +// / /_)/ _` | '__/ __|/ _ \/ / | | '_ \| |/ / +// / ___/ (_| | | \__ \ __/ /__| | | | | < +// \/ \__,_|_| |___/\___\____/_|_| |_|_|\_\ . +// +//----------------------------------------------------------------------------- +// Author: Kurt Sassenrath +// Module: msgpack +// +// Packer tests, ranges (for types that serialize to array / map formats) +// +// Copyright (c) 2023 Kurt Sassenrath. +// +// License TBD. +//----------------------------------------------------------------------------- + +#include "test_packer.h" + +#include + +using namespace boost::ut; + +namespace { +constexpr bool expect_equal(auto const& expected, auto const& actual) { + if (!std::ranges::equal(expected, actual)) { + fmt::print("\n\tExpected: "); + for (auto x : expected) { + fmt::print("{:02x} ", x); + } + fmt::print("\n\t Actual: "); + for (auto x : actual) { + fmt::print("{:02x} ", x); + } + fmt::print("\n"); + return false; + } + return true; +} +} // namespace + +suite pack_ranges = [] { + "packer::pack>"_test = [] { + constexpr auto data_array = std::to_array({5, 10, 15, 20}); + constexpr auto expected = test::make_bytes(0x94, 0x05, 0xa, 0xf, 0x14); + + { + std::array payload; + msgpack::packer packer(payload); + expect(!!packer.pack(data_array)); + expect(expect_equal(std::span(expected), payload)); + } + + { + std::span data_span{data_array}; + std::array payload; + msgpack::packer packer(payload); + expect(!!packer.pack(data_span)); + expect(expect_equal(expected, payload)); + } + }; +}; diff --git a/tests/msgpack/packer/signed.cpp b/tests/msgpack/packer/signed.cpp new file mode 100644 index 0000000..2b41666 --- /dev/null +++ b/tests/msgpack/packer/signed.cpp @@ -0,0 +1,71 @@ +//----------------------------------------------------------------------------- +// ___ __ _ _ +// / _ \__ _ _ __ ___ ___ / /(_)_ __ | | __ +// / /_)/ _` | '__/ __|/ _ \/ / | | '_ \| |/ / +// / ___/ (_| | | \__ \ __/ /__| | | | | < +// \/ \__,_|_| |___/\___\____/_|_| |_|_|\_\ . +// +//----------------------------------------------------------------------------- +// Author: Kurt Sassenrath +// Module: msgpack +// +// Packer tests, signed ints. +// +// Copyright (c) 2023 Kurt Sassenrath. +// +// License TBD. +//----------------------------------------------------------------------------- +#include "test_packer.h" + +#include + +using namespace boost::ut; + +namespace { + +template +auto check_pack() { + return rc::check([](T value) { + std::array payload; + msgpack::packer packer(payload); + if (!packer.pack(value)) return false; + + if (value < 128 && value >= -32) { + // positive_fixint/negative_fixint + return packer.tell() == 1 + && payload[0] == static_cast(value); + } else if (within(value)) { + return payload[0] == msgpack::format::int8::marker + && verify_packed(packer, value); + } else if (within(value)) { + return payload[0] == msgpack::format::int16::marker + && verify_packed(packer, value); + } else if (within(value)) { + return payload[0] == msgpack::format::int32::marker + && verify_packed(packer, value); + } else { + return payload[0] == msgpack::format::int64::marker + && verify_packed(packer, value); + } + }); +} + +} // anonymous namespace + +suite pack_signed_types = [] { + "packer::pack"_test = [] { + expect(check_pack()); + }; + + "packer::pack"_test = [] { + expect(check_pack()); + }; + + "packer::pack"_test = [] { + expect(check_pack()); + }; + + "packer::pack"_test = [] { + expect(check_pack()); + }; +}; diff --git a/tests/msgpack/packer/simple_types.cpp b/tests/msgpack/packer/simple_types.cpp new file mode 100644 index 0000000..265e5c1 --- /dev/null +++ b/tests/msgpack/packer/simple_types.cpp @@ -0,0 +1,50 @@ +//----------------------------------------------------------------------------- +// ___ __ _ _ +// / _ \__ _ _ __ ___ ___ / /(_)_ __ | | __ +// / /_)/ _` | '__/ __|/ _ \/ / | | '_ \| |/ / +// / ___/ (_| | | \__ \ __/ /__| | | | | < +// \/ \__,_|_| |___/\___\____/_|_| |_|_|\_\ . +// +//----------------------------------------------------------------------------- +// Author: Kurt Sassenrath +// Module: msgpack +// +// Packer tests, simple types +// +// Copyright (c) 2023 Kurt Sassenrath. +// +// License TBD. +//----------------------------------------------------------------------------- + +#include "test_packer.h" + +using namespace boost::ut; + +suite pack_simple_types = [] { + "packer::pack"_test = [] { + std::array payload; + msgpack::packer packer(payload); + expect(!!packer.pack(msgpack::nil{})); + expect(packer.tell() == 1); + expect(payload[0] == std::byte{0xc0}); + }; + + "packer::pack"_test = [] { + std::array payload; + msgpack::packer packer(payload); + expect(!!packer.pack(msgpack::invalid{})); + expect(packer.tell() == 1); + expect(payload[0] == std::byte{0xc1}); + }; + + "packer::pack"_test = [] { + std::array payload; + msgpack::packer packer(payload); + expect(!!packer.pack(false)); + expect(packer.tell() == 1); + expect(payload[0] == std::byte{0xc2}); + expect(!!packer.pack(true)); + expect(packer.tell() == 2); + expect(payload[1] == std::byte{0xc3}); + }; +}; diff --git a/tests/msgpack/packer/strings.cpp b/tests/msgpack/packer/strings.cpp new file mode 100644 index 0000000..bc1e613 --- /dev/null +++ b/tests/msgpack/packer/strings.cpp @@ -0,0 +1,46 @@ +//----------------------------------------------------------------------------- +// ___ __ _ _ +// / _ \__ _ _ __ ___ ___ / /(_)_ __ | | __ +// / /_)/ _` | '__/ __|/ _ \/ / | | '_ \| |/ / +// / ___/ (_| | | \__ \ __/ /__| | | | | < +// \/ \__,_|_| |___/\___\____/_|_| |_|_|\_\ . +// +//----------------------------------------------------------------------------- +// Author: Kurt Sassenrath +// Module: msgpack +// +// Packer tests, strings. +// +// Copyright (c) 2023 Kurt Sassenrath. +// +// License TBD. +//----------------------------------------------------------------------------- +#include "test_packer.h" + +#include + +using namespace boost::ut; + +namespace { + +template +auto check_string() { + return rc::check([](LenType value) { + auto str = *rc::gen::container( + value, rc::gen::character()); + std::vector payload; + payload.resize(value + 32); + msgpack::packer packer(payload); + if (!packer.pack(str)) return false; + return true; + }); +} + +} // anonymous namespace + +suite pack_strings = [] { + "packer::pack"_test = [] { + expect(check_string()); + expect(check_string()); + }; +}; diff --git a/tests/msgpack/packer/test_packer.h b/tests/msgpack/packer/test_packer.h new file mode 100644 index 0000000..52af920 --- /dev/null +++ b/tests/msgpack/packer/test_packer.h @@ -0,0 +1,42 @@ +//----------------------------------------------------------------------------- +// ___ __ _ _ +// / _ \__ _ _ __ ___ ___ / /(_)_ __ | | __ +// / /_)/ _` | '__/ __|/ _ \/ / | | '_ \| |/ / +// / ___/ (_| | | \__ \ __/ /__| | | | | < +// \/ \__,_|_| |___/\___\____/_|_| |_|_|\_\ . +// +//----------------------------------------------------------------------------- +// Author: Kurt Sassenrath +// Module: msgpack +// +// Packer tests, common code. +// +// Copyright (c) 2023 Kurt Sassenrath. +// +// License TBD. +//----------------------------------------------------------------------------- +#ifndef tests_msgpack_packer_6e9a5bf8e14223bc +#define tests_msgpack_packer_6e9a5bf8e14223bc + +#include "parselink/msgpack/core/packer.h" + +#include "test_utils.h" + +template +constexpr auto within(auto value) noexcept { + return value >= std::numeric_limits::min() + && value <= std::numeric_limits::max(); +} + +template +constexpr auto verify_packed(auto const& packer, auto value) noexcept { + std::array::digits + 7) / 8> raw; + if (packer.tell() != 1 + raw.size()) return false; + + auto packed = packer.subspan().subspan(1); + be_to_host(packed.begin(), packed.end(), raw.begin()); + auto actual = std::bit_cast(raw); + return actual == value; +} + +#endif // tests_msgpack_packer_6e9a5bf8e14223bc diff --git a/tests/msgpack/packer/unsigned.cpp b/tests/msgpack/packer/unsigned.cpp new file mode 100644 index 0000000..c36db14 --- /dev/null +++ b/tests/msgpack/packer/unsigned.cpp @@ -0,0 +1,71 @@ +//----------------------------------------------------------------------------- +// ___ __ _ _ +// / _ \__ _ _ __ ___ ___ / /(_)_ __ | | __ +// / /_)/ _` | '__/ __|/ _ \/ / | | '_ \| |/ / +// / ___/ (_| | | \__ \ __/ /__| | | | | < +// \/ \__,_|_| |___/\___\____/_|_| |_|_|\_\ . +// +//----------------------------------------------------------------------------- +// Author: Kurt Sassenrath +// Module: msgpack +// +// Packer tests, unsigned ints. +// +// Copyright (c) 2023 Kurt Sassenrath. +// +// License TBD. +//----------------------------------------------------------------------------- +#include "test_packer.h" + +#include + +using namespace boost::ut; + +namespace { + +template +auto check_unsigned() { + return rc::check([](T value) { + std::array payload; + msgpack::packer packer(payload); + if (!packer.pack(value)) return false; + + if (value < 128) { + // positive_fixint + return packer.tell() == 1 + && payload[0] == static_cast(value); + } else if (within(value)) { + return payload[0] == msgpack::format::uint8::marker + && verify_packed(packer, value); + } else if (within(value)) { + return payload[0] == msgpack::format::uint16::marker + && verify_packed(packer, value); + } else if (within(value)) { + return payload[0] == msgpack::format::uint32::marker + && verify_packed(packer, value); + } else { + return payload[0] == msgpack::format::uint64::marker + && verify_packed(packer, value); + } + }); +} + +} // anonymous namespace + +suite packer_unsigned_ints = [] { + "packer::pack"_test = [] { + expect(check_unsigned()); + }; + + "packer::pack"_test = [] { + expect(check_unsigned()); + }; + + "packer::pack"_test = [] { + expect(check_unsigned()); + }; + + "packer::pack"_test = [] { + expect(check_unsigned()); + }; +}; diff --git a/tests/msgpack/test_packer_rc.cpp b/tests/msgpack/test_packer_rc.cpp deleted file mode 100644 index f399ad5..0000000 --- a/tests/msgpack/test_packer_rc.cpp +++ /dev/null @@ -1,306 +0,0 @@ -//----------------------------------------------------------------------------- -// ___ __ _ _ -// / _ \__ _ _ __ ___ ___ / /(_)_ __ | | __ -// / /_)/ _` | '__/ __|/ _ \/ / | | '_ \| |/ / -// / ___/ (_| | | \__ \ __/ /__| | | | | < -// \/ \__,_|_| |___/\___\____/_|_| |_|_|\_\ . -// -//----------------------------------------------------------------------------- -// Author: Kurt Sassenrath -// Module: msgpack -// -// Default packer tests. -// -// Copyright (c) 2023 Kurt Sassenrath. -// -// License TBD. -//----------------------------------------------------------------------------- - -#include "parselink/msgpack/core/packer.h" - -#include -#include - -#include "rng.h" -#include -#include -#include -#include - -using namespace boost::ut; - -template <> -struct fmt::formatter : fmt::formatter { - template - auto format(msgpack::nil const&, FormatContext& ctx) const { - return fmt::format_to(ctx.out(), "{{msgpack::invalid}}"); - } -}; - -template <> -struct fmt::formatter : fmt::formatter { - template - auto format(msgpack::nil const&, FormatContext& ctx) const { - return fmt::format_to(ctx.out(), "{{msgpack::nil}}"); - } -}; - -template <> -struct fmt::formatter : fmt::formatter { - template - auto format(msgpack::map_desc const& value, FormatContext& ctx) const { - return fmt::format_to( - ctx.out(), "{{msgpack::map_desc: {}}}", value.count); - } -}; - -template <> -struct fmt::formatter : fmt::formatter { - template - auto format(msgpack::array_desc const& value, FormatContext& ctx) const { - return fmt::format_to( - ctx.out(), "{{msgpack::array_desc: {}}}", value.count); - } -}; - -namespace { - -template -constexpr auto within(auto value) noexcept { - return value >= std::numeric_limits::min() - && value <= std::numeric_limits::max(); -} - -template -std::byte marker_for; - -template -constexpr auto verify_packed(auto const& packer, auto value) noexcept { - std::array::digits + 7) / 8> raw; - if (packer.tell() != 1 + raw.size()) return false; - - auto packed = packer.subspan().subspan(1); - be_to_host(packed.begin(), packed.end(), raw.begin()); - auto actual = std::bit_cast(raw); - return actual == value; -} - -template -auto check_signed() { - return rc::check([](T value) { - std::array payload; - msgpack::packer packer(payload); - if (!packer.pack(value)) return false; - - if (value < 128 && value >= -32) { - // positive_fixint/negative_fixint - return packer.tell() == 1 - && payload[0] == static_cast(value); - } else if (within(value)) { - return payload[0] == msgpack::format::int8::marker - && verify_packed(packer, value); - } else if (within(value)) { - return payload[0] == msgpack::format::int16::marker - && verify_packed(packer, value); - } else if (within(value)) { - return payload[0] == msgpack::format::int32::marker - && verify_packed(packer, value); - } else { - return payload[0] == msgpack::format::int64::marker - && verify_packed(packer, value); - } - }); -} - -template -auto check_unsigned() { - return rc::check([](T value) { - std::array payload; - msgpack::packer packer(payload); - if (!packer.pack(value)) return false; - - if (value < 128) { - // positive_fixint - return packer.tell() == 1 - && payload[0] == static_cast(value); - } else if (within(value)) { - return payload[0] == msgpack::format::uint8::marker - && verify_packed(packer, value); - } else if (within(value)) { - return payload[0] == msgpack::format::uint16::marker - && verify_packed(packer, value); - } else if (within(value)) { - return payload[0] == msgpack::format::uint32::marker - && verify_packed(packer, value); - } else { - return payload[0] == msgpack::format::uint64::marker - && verify_packed(packer, value); - } - }); -} - -template -auto check_string() { - return rc::check([](LenType value) { - auto str = *rc::gen::container( - value, rc::gen::character()); - std::vector payload; - payload.resize(value + 32); - msgpack::packer packer(payload); - if (!packer.pack(str)) return false; - return true; - }); -} - -} // anonymous namespace - -suite packer_single_format = [] { - "packer::pack"_test = [] { - std::array payload; - msgpack::packer packer(payload); - expect(!!packer.pack(msgpack::nil{})); - expect(packer.tell() == 1); - expect(payload[0] == std::byte{0xc0}); - }; - - "packer::pack"_test = [] { - std::array payload; - msgpack::packer packer(payload); - expect(!!packer.pack(msgpack::invalid{})); - expect(packer.tell() == 1); - expect(payload[0] == std::byte{0xc1}); - }; - - "packer::pack"_test = [] { - std::array payload; - msgpack::packer packer(payload); - expect(!!packer.pack(false)); - expect(packer.tell() == 1); - expect(payload[0] == std::byte{0xc2}); - expect(!!packer.pack(true)); - expect(packer.tell() == 2); - expect(payload[1] == std::byte{0xc3}); - }; - - "packer::pack"_test = [] { - expect(check_unsigned()); - }; - - "packer::pack"_test = [] { - expect(check_unsigned()); - }; - - "packer::pack"_test = [] { - expect(check_unsigned()); - }; - - "packer::pack"_test = [] { - expect(check_unsigned()); - }; - - "packer::pack"_test = [] { - expect(check_signed()); - }; - - "packer::pack"_test = [] { - expect(check_signed()); - }; - - "packer::pack"_test = [] { - expect(check_signed()); - }; - - "packer::pack"_test = [] { - expect(check_signed()); - }; - - "packer::pack"_test = [] { - expect(check_string()); - expect(check_string()); - }; -}; -#if 0 - // Strings - "packer::pack"_test = [] { - expect(test_deduced()); - }; -#if 0 - "packer::pack"_test = [] { - expect(test_deduced()); - }; -#endif - - // Byte ranges -> Binary - - "packer::pack>"_test = [] { - expect(test_deduced>()); - }; - - "packer::pack>"_test = [] { - { - constexpr auto data = make_bytes(0x01, 0x02, 0x03, 0x04); - constexpr auto expected = - make_bytes(0xc4, 0x04, 0x01, 0x02, 0x03, 0x04); - std::array payload; - - msgpack::packer packer(payload); - expect(!!packer.pack(data)); - expect(std::ranges::equal(payload, expected)); - } - { - constexpr std::array data{}; - constexpr std::array expected{ - std::byte(0xc5), std::byte(0x01), std::byte(0x00)}; - std::array payload; - - msgpack::packer packer(payload); - expect(!!packer.pack(data)); - expect(std::ranges::equal(payload, expected)); - } - { - constexpr std::array data{}; - constexpr std::array expected{ - std::byte(0xc6), std::byte(0x00), std::byte(0x01), - std::byte(0x00), std::byte(0x00)}; - std::array payload; - - msgpack::packer packer(payload); - expect(!!packer.pack(data)); - expect(std::ranges::equal(payload, expected)); - } - }; - - // array_desc - Just the header of the array. - "packer::pack"_test = [] { - expect(test_deduced()); - }; - - // map_desc - Just the header of the map. - "packer::pack"_test = [] { - expect(test_deduced()); - }; -}; - -suite packer_ranges = [] { - "packer::pack>"_test = [] { - constexpr auto data_array = std::to_array({5, 10, 15, 20}); - constexpr auto expected = - make_bytes(0x94, 0xd0, 0x05, 0xd0, 0xa, 0xd0, 0xf, 0xd0, 0x14); - - { - std::array payload; - msgpack::packer packer(payload); - expect(!!packer.pack(data_array)); - expect(std::ranges::equal(payload, expected)); - } - - { - std::span data_span{data_array}; - std::array payload; - msgpack::packer packer(payload); - expect(!!packer.pack(data_span)); - expect(std::ranges::equal(payload, expected)); - } - }; -}; -#endif