test: add a test case for monotonicity of timeuuid least significant bits

Ensure that timeuuid least significant bits are compared correctly.
This commit is contained in:
Konstantin Osipov
2020-12-05 00:11:31 +03:00
parent 0af3758aff
commit d6e65a3735

View File

@@ -96,6 +96,44 @@ BOOST_AUTO_TEST_CASE(test_get_time_uuid) {
BOOST_CHECK(unix_timestamp == millis);
}
BOOST_AUTO_TEST_CASE(test_timeuuid_submicro_is_monotonic) {
const int64_t PAD6 = 0xFFFF'FFFF'FFFF;
using namespace std::chrono;
using utils::UUID, utils::UUID_gen;
UUID current_timeuuid = UUID_gen::get_time_UUID();
// Node identifier must be set to avoid collisions
BOOST_CHECK((current_timeuuid.get_least_significant_bits() & PAD6) != 0);
int64_t micros = UUID_gen::micros_timestamp(current_timeuuid);
int maxsubmicro = (1 << 17) - 1;
int step = 1 + (random() % 169);
auto prev = UUID_gen::get_time_UUID_bytes_from_micros_and_submicros(micros, 0);
auto prev_timeuuid = UUID_gen::get_UUID(prev.data());
// Check prev_timeuuid node identifier is set. It uses
// a spoof MAC address, not the same as a standard UUID.
BOOST_CHECK((prev_timeuuid.get_least_significant_bits() & PAD6) != 0);
auto check_is_valid_timeuuid = [&](UUID uuid) {
// UUID is version 1
BOOST_CHECK(uuid.is_timestamp());
// UUID preserves the original microsecond time
BOOST_CHECK(UUID_gen::micros_timestamp(uuid) == micros);
// UUID 100nsec time grows monotonically
BOOST_CHECK(uuid.timestamp() >= prev_timeuuid.timestamp());
// UUID node is the same for all generated UUIDs
BOOST_CHECK((prev_timeuuid.get_least_significant_bits() & PAD6) ==
(uuid.get_least_significant_bits() & PAD6));
};
for (int i = 1; i <= maxsubmicro; i += step) {
auto uuid = UUID_gen::get_time_UUID_bytes_from_micros_and_submicros(
micros, i);
check_is_valid_timeuuid(UUID_gen::get_UUID(uuid.data()));
// UUID submicro part grows monotonically
BOOST_CHECK(utils::timeuuid_tri_compare({uuid.data(), 16}, {prev.data(), 16}) > 0);
prev = uuid;
}
BOOST_CHECK_EXCEPTION(UUID_gen::get_time_UUID_bytes_from_micros_and_submicros(micros, 2 * maxsubmicro),
utils::timeuuid_submicro_out_of_range, [](auto& x) -> bool { return true; });
}
BOOST_AUTO_TEST_CASE(test_min_time_uuid) {
using namespace std::chrono;