cql-pytest: fix flaky timeuuid_test.py

The test timeuuid_test.py::testTimeuuid sporadically failed, and it turns out
the reason was a bug in the test - which this patch fixes.

The buggy test created a timeuuid and then compared the time stored in it
to the result of the dateOf() CQL function. The problem is that dateOf()
returns a CQL "timestamp", which has millisecond resolution, while the
timeuuid *may* have finer than millisecond resolution. The reason why this
test rarely failed is that in our implementation, the timeuuid almost
always gets a millisecond-resolution timestamp. Only if now() gets called
more than once in one millisecond, does it pick a higher time incremented
by less than a millisecond.

What this patch does is to truncate the time read from the timeuuid to
millisecond resolution, and only then compare it to the result of dateOf().
We cannot hope for more.

Fixes #8060

Signed-off-by: Nadav Har'El <nyh@scylladb.com>
Message-Id: <20210211165046.878371-1-nyh@scylladb.com>
This commit is contained in:
Nadav Har'El
2021-02-11 18:50:46 +02:00
committed by Avi Kivity
parent 234f9dbe85
commit a03a8a89a9

View File

@@ -49,6 +49,16 @@ def testTimeuuid(cql, test_keyspace):
for i in range(4):
uuid = rows[i][1]
datetime = datetime_from_uuid1(uuid)
# Before comparing this datetime to the result of dateOf(), we
# must truncate the resolution of datetime to milliseconds.
# he problem is that the dateOf(timeuuid) CQL function converts a
# timeuuid to CQL's "timestamp" type, which has millisecond
# resolution, but datetime *may* have finer resolution. It will
# usually be whole milliseconds, because this is what the now()
# implementation usually does, but when now() is called more than
# once per millisecond, it *may* start incrementing the sub-
# millisecond part.
datetime = datetime.replace(microsecond=datetime.microsecond//1000*1000)
timestamp = round(datetime.replace(tzinfo=timezone.utc).timestamp() * 1000)
assert_rows(execute(cql, table, "SELECT dateOf(t), unixTimestampOf(t) FROM %s WHERE k = 0 AND t = ?", rows[i][1]),
[datetime, timestamp])