/** * @file tests/unit/test_uuid.cpp * @brief Tests for UUID byte layout, generation, formatting, and ordering. */ // test includes #include "../tests_common.h" // standard includes #include #include #include #include #include // local includes #include #include TEST(UuidTest, PreservesNativeLayoutAndCanonicalFormatting) { static_assert(sizeof(uuid_util::uuid_t) == 16); static_assert(alignof(uuid_util::uuid_t) == alignof(std::uint64_t)); static_assert(std::is_trivially_copyable_v); const uuid_util::uuid_t uuid {.b8 = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}}; EXPECT_EQ(uuid.string(), "00112233-4455-6677-8899-AABBCCDDEEFF"); // NOSONAR(cpp:S6232): Calling a union member function does not access an inactive data member. } TEST(UuidTest, GenerationPreservesDrawOrderAndMasks) { std::default_random_engine engine {42}; // NOSONAR(cpp:S2245): Deterministic regression fixture; no security-sensitive values are generated. auto expected_engine = engine; // NOSONAR(cpp:S2245): Copy the deterministic fixture to verify draw order independently. std::uniform_int_distribution distribution(0, 255); std::array expected; for (auto &byte : expected) { byte = distribution(expected_engine); } expected[7] = std::to_integer(std::byte {expected[7]} & std::byte {0b00101111}); expected[9] = std::to_integer(std::byte {expected[9]} & std::byte {0b10011111}); const auto uuid = uuid_util::uuid_t::generate(engine); EXPECT_EQ(uuid.b8, expected); EXPECT_EQ(std::byte {uuid.b8[7]} & std::byte {0xD0}, std::byte {0}); EXPECT_EQ(std::byte {uuid.b8[9]} & std::byte {0x60}, std::byte {0}); EXPECT_EQ(engine, expected_engine); EXPECT_EQ(uuid_util::uuid_t::generate().string().size(), 36U); } TEST(UuidTest, ComparesBothWordsInTheirEstablishedOrder) { const uuid_util::uuid_t base {.b64 = {2, 3}}; const uuid_util::uuid_t equal {.b64 = {2, 3}}; const uuid_util::uuid_t lower_first {.b64 = {1, 9}}; const uuid_util::uuid_t higher_first {.b64 = {3, 1}}; const uuid_util::uuid_t lower_second {.b64 = {2, 2}}; const uuid_util::uuid_t higher_second {.b64 = {2, 4}}; EXPECT_EQ(base, equal); EXPECT_FALSE(base < equal); EXPECT_FALSE(base > equal); for (const auto &lower : {lower_first, lower_second}) { EXPECT_FALSE(base == lower); EXPECT_TRUE(lower < base); EXPECT_TRUE(base > lower); EXPECT_FALSE(base < lower); EXPECT_FALSE(lower > base); } for (const auto &higher : {higher_first, higher_second}) { EXPECT_FALSE(base == higher); EXPECT_TRUE(base < higher); EXPECT_TRUE(higher > base); EXPECT_FALSE(higher < base); EXPECT_FALSE(base > higher); } }