/* * Copyright (C) 2017-present ScyllaDB */ /* * SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0 */ #define BOOST_TEST_MODULE core #include "vint-serialization.hh" #include "bytes.hh" #include #include #include #include using namespace seastar; namespace { typename bytes::value_type operator ""_b(unsigned long long value) { return static_cast(value); } template void test_serialized_size_from_first_byte(vint_size_type size, bytes_view bytes) { } template <> void test_serialized_size_from_first_byte(vint_size_type size, bytes_view bytes) { BOOST_REQUIRE_EQUAL(size, unsigned_vint::serialized_size_from_first_byte(bytes[0])); } // Check that the encoded value decodes back to the value. Also allows inspecting the encoded bytes. template void check_bytes_and_roundtrip(typename Vint::value_type value, BytesInspector&& f) { static std::array encoding_buffer({}); const auto size = Vint::serialize(value, encoding_buffer.begin()); const auto view = bytes_view(encoding_buffer.data(), size); f(view); const auto deserialized = Vint::deserialize(view); BOOST_REQUIRE_EQUAL(deserialized, value); test_serialized_size_from_first_byte(size, view); }; // Check that the encoded value decodes back to the value. template void check_roundtrip(typename Vint::value_type value) { check_bytes_and_roundtrip(value, [](const bytes_view&) {}); } template void with_random_samples(RandomEngine& rng, std::size_t count, Callback&& f) { std::uniform_int_distribution distribution; for (std::size_t i = 0; i < count; ++i) { f(distribution(rng)); } } template void check_roundtrip_sweep(std::size_t count, RandomEngine& rng) { with_random_samples(rng, count, &check_roundtrip); }; auto& random_engine() { static std::random_device rd; static std::mt19937 rng(rd()); return rng; } } BOOST_AUTO_TEST_CASE(sanity_unsigned_examples) { using vint = unsigned_vint; check_bytes_and_roundtrip(0, [](bytes_view v) { BOOST_REQUIRE_EQUAL(v, (bytes{0_b})); }); check_bytes_and_roundtrip(5, [](bytes_view v) { BOOST_REQUIRE_EQUAL(v, (bytes{0b0000'0101_b})); }); check_bytes_and_roundtrip(1111, [](bytes_view v) { BOOST_REQUIRE_EQUAL(v, (bytes{0b1000'0100_b, 0b0101'0111_b})); }); check_bytes_and_roundtrip(256'000, [](bytes_view v) { BOOST_REQUIRE_EQUAL(v, (bytes{0b1100'0011_b, 0b1110'1000_b, 0b0000'0000_b})); }); check_bytes_and_roundtrip(0xff'ee'dd'cc'bb'aa'99'88, [](bytes_view v) { BOOST_REQUIRE_EQUAL(v, (bytes{0xff_b, 0xff_b, 0xee_b, 0xdd_b, 0xcc_b, 0xbb_b, 0xaa_b, 0x99_b, 0x88_b})); }); } BOOST_AUTO_TEST_CASE(sanity_unsigned_sweep) { check_roundtrip_sweep(100'000, random_engine()); } BOOST_AUTO_TEST_CASE(sanity_signed_examples) { using vint = signed_vint; check_bytes_and_roundtrip(0, [](bytes_view v) { BOOST_REQUIRE_EQUAL(v, (bytes{0_b})); }); check_bytes_and_roundtrip(-1, [](bytes_view v) { BOOST_REQUIRE_EQUAL(v, (bytes{0b0000'0001_b})); }); check_bytes_and_roundtrip(1, [](bytes_view v) { BOOST_REQUIRE_EQUAL(v, (bytes{0b0000'0010_b})); }); check_bytes_and_roundtrip(-2, [](bytes_view v) { BOOST_REQUIRE_EQUAL(v, (bytes{0b0000'0011_b})); }); check_bytes_and_roundtrip(2, [](bytes_view v) { BOOST_REQUIRE_EQUAL(v, (bytes{0b0000'0100_b})); }); check_bytes_and_roundtrip(-256'000, [](bytes_view v) { BOOST_REQUIRE_EQUAL(v, (bytes{0b1100'0111_b, 0b1100'1111_b, 0b1111'1111_b})); }); } BOOST_AUTO_TEST_CASE(sanity_signed_sweep) { check_roundtrip_sweep(100'000, random_engine()); }