wcfs: tests: Fix thinko in how py vs go timestamps are asserted
When verifying WCFS we are checking that mtime of particular bigfile corresponds to last transaction that modified its data. However there is a peculiarity that py and go construct time from TID a bit differently with the difference going up to 1µs(*). With that wcfs_test.py, when asserting on timestamps, tries to verify mtime returned by wcfs to tid of corresponding transaction with that 1µs of tolerance. There is a bug, however, in the implementation of tolerance logic. In that logic, when tid is converted to timestamp on py side it is rounded to 6th decimal digit. And it used to work on py2 only due to the fact that on py2 current time is measured to that same 6th decimal digit - to the microsecond precision. That fact is relevant here because ZODB constructs transaction IDs from current time, and if the time precision is only 1µs so will tid, when converted back to time, also have that 1µs precision. However py3, after https://github.com/python/cpython/commit/ad95c2d25c5f, started to use clock_gettime which has 1ns precision instead of 1µs precision of gittimeofday used previously. This results in the breakage of the above logic as demonstrated by the following failure: @func def test_wcfs_basic(): t = tDB(); zf = t.zfile defer(t.close) # >>> lookup non-BigFile -> must be rejected with raises(OSError) as exc: t.wc._stat("head/bigfile/%s" % h(t.nonzfile._p_oid)) assert exc.value.errno == EINVAL # >>> file initially empty f = t.open(zf) f.assertCache([]) > f.assertData ([], mtime=t.at0) wcfs_test.py:1337: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ t = <wcfs.wcfs_test.tFile object at 0x7f674f0d7490>, dataokv = [], mtime = @at0 (03fb8b696044aebb) def assertData(t, dataokv, mtime=None): st = os.fstat(t.f.fileno()) assert st.st_blksize == t.blksize assert st.st_size == len(dataokv)*t.blksize if mtime is not None: > assert st.st_mtime == tidtime(mtime) E assert 1727274802.5628808 == 1727274802.562881 E + where 1727274802.5628808 = os.stat_result(st_mode=33060, st_ino=10, st_dev=71, st_nlink=1, st_uid=1000, st_gid=1000, st_size=0, st_atime=0, st_mtime=1727274802, st_ctime=1727274802).st_mtime E + and 1727274802.562881 = tidtime(@at0 (03fb8b696044aebb)) Here t.at0 is 03fb8b696044aebb which corresponds to 1727274802.5628808 timestamp with 7 digits after point. However tidtime, due to round(·, 6) returns another float with only 6 digits after point which results in the check failure. -> Fix that by adjusting the assert to explicitly verify that the difference in between st_mtime returned by wcfs and tidtime of corresponding transaction ≤ 1µs. (*) see neo@9112f21e for details
Showing
Please register or sign in to comment