Commit a3252542 authored by Tim Peters's avatar Tim Peters

Collector #1397: testTimeStamp fails on FreeBSD

Forward-porting from Zope 2.7.
Merged from 3.3 branch, revision 26085.

The checkFullTimeStamp() test was sensitive to unique mktime() behavior
on FreeBSD.  See:

http://lists.freebsd.org/pipermail/freebsd-standards/2003-November/000268.html 

The purpose of this test is to exercise ZODB's TimeStamp object, so got
rid of dependence on platform mktime() and time.timezone quirks --
TimeStamp works in GMT, so how mktime() treats tm_isdst should be
irrelevant in all TimeStamp tests.

Also added a comment about the highly non-obvious numeric characteristics
of TimeStamp's treatment of seconds (round-tripping is surprisingly
inaccurate, but for a real reason).
parent a9ed1d85
......@@ -5,7 +5,8 @@ Release date: DD-MMM-2004
Storages
--------
Collector #1327 FileStorage init confused by time travel.
Collector #1327: FileStorage init confused by time travel
If the system clock "went backwards" a long time between the times a
FileStorage was closed and reopened, new transaction ids could be
smaller than transaction ids already in the storage, violating a
......@@ -16,6 +17,15 @@ warning level; if time appears to have run backwards at least 30
minutes, the message is logged at critical level (and you should
investigate to find and repair the true cause).
Test suite
----------
Collector #1397: testTimeStamp fails on FreeBSD
The *BSD distributions are unique in that their mktime() implementation
usually ignores the input tm_isdst value. Test checkFullTimeStamp()
was sensitive to this platform quirk.
What's new in ZODB3 3.3 beta 1
==============================
......
......@@ -41,16 +41,28 @@ class TimeStampTests(unittest.TestCase):
self.assertEquals(dy, t[2])
def checkFullTimeStamp(self):
t = time.gmtime()
native_ts = int(time.time()) # fractional seconds get in the way
t = time.gmtime(native_ts) # the corresponding GMT struct tm
ts = TimeStamp(*t[:6])
# XXX floating point comparison
self.assertEquals(ts.timeTime() + time.timezone, time.mktime(t))
# Seconds are stored internally via (conceptually) multiplying by
# 2**32 then dividing by 60, ending up with a 32-bit integer.
# While this gives a lot of room for cramming many distinct
# TimeStamps into a second, it's not good at roundtrip accuracy.
# For example, 1 second is stored as int(2**32/60) == 71582788.
# Converting back gives 71582788*60.0/2**32 == 0.9999999962747097.
# In general, we can lose up to 0.999... to truncation during
# storing, creating an absolute error up to about 1*60.0/2**32 ==
# 0.000000014 on the seconds value we get back. This is so even
# when we have an exact integral second value going in (as we
# do in this test), so we can't expect equality in any comparison
# involving seconds. Minutes (etc) are stored exactly, so we
# can expect equality for those.
self.assert_(abs(ts.timeTime() - native_ts) < EPSILON)
self.assertEqual(ts.year(), t[0])
self.assertEqual(ts.month(), t[1])
self.assertEqual(ts.day(), t[2])
self.assertEquals(ts.hour(), t[3])
self.assertEquals(ts.minute(), t[4])
self.assert_(abs(ts.second() - t[5]) < EPSILON)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment