(self)
| 941 | self.assertSetEqual(versions, {7}) |
| 942 | |
| 943 | def test_uuid7_monotonicity(self): |
| 944 | equal = self.assertEqual |
| 945 | |
| 946 | us = [self.uuid.uuid7() for _ in range(10_000)] |
| 947 | equal(us, sorted(us)) |
| 948 | |
| 949 | with mock.patch.multiple( |
| 950 | self.uuid, |
| 951 | _last_timestamp_v7=0, |
| 952 | _last_counter_v7=0, |
| 953 | ): |
| 954 | # 1 Jan 2023 12:34:56.123_456_789 |
| 955 | timestamp_ns = 1672533296_123_456_789 # ns precision |
| 956 | timestamp_ms, _ = divmod(timestamp_ns, 1_000_000) |
| 957 | |
| 958 | # counter_{hi,lo} are chosen so that "counter + 1" does not overflow |
| 959 | counter_hi = random.getrandbits(11) |
| 960 | counter_lo = random.getrandbits(29) |
| 961 | counter = (counter_hi << 30) | counter_lo |
| 962 | self.assertLess(counter + 1, 0x3ff_ffff_ffff) |
| 963 | |
| 964 | tail = random.getrandbits(32) |
| 965 | random_bits = counter << 32 | tail |
| 966 | random_data = random_bits.to_bytes(10) |
| 967 | |
| 968 | with ( |
| 969 | mock.patch('time.time_ns', return_value=timestamp_ns), |
| 970 | mock.patch('os.urandom', return_value=random_data) as urand |
| 971 | ): |
| 972 | u1 = self.uuid.uuid7() |
| 973 | urand.assert_called_once_with(10) |
| 974 | equal(self.uuid._last_timestamp_v7, timestamp_ms) |
| 975 | equal(self.uuid._last_counter_v7, counter) |
| 976 | equal(u1.time, timestamp_ms) |
| 977 | equal((u1.int >> 64) & 0xfff, counter_hi) |
| 978 | equal((u1.int >> 32) & 0x3fff_ffff, counter_lo) |
| 979 | equal(u1.int & 0xffff_ffff, tail) |
| 980 | |
| 981 | # 1 Jan 2023 12:34:56.123_457_032 (same millisecond but not same ns) |
| 982 | next_timestamp_ns = 1672533296_123_457_032 |
| 983 | next_timestamp_ms, _ = divmod(timestamp_ns, 1_000_000) |
| 984 | equal(timestamp_ms, next_timestamp_ms) |
| 985 | |
| 986 | next_tail_bytes = os.urandom(4) |
| 987 | next_fail = int.from_bytes(next_tail_bytes) |
| 988 | |
| 989 | with ( |
| 990 | mock.patch('time.time_ns', return_value=next_timestamp_ns), |
| 991 | mock.patch('os.urandom', return_value=next_tail_bytes) as urand |
| 992 | ): |
| 993 | u2 = self.uuid.uuid7() |
| 994 | urand.assert_called_once_with(4) |
| 995 | # same milli-second |
| 996 | equal(self.uuid._last_timestamp_v7, timestamp_ms) |
| 997 | # 42-bit counter advanced by 1 |
| 998 | equal(self.uuid._last_counter_v7, counter + 1) |
| 999 | equal(u2.time, timestamp_ms) |
| 1000 | equal((u2.int >> 64) & 0xfff, counter_hi) |
nothing calls this directly
no test coverage detected