[Zodb-checkins] SVN: ZODB/trunk/ Collector #1397: testTimeStamp fails on FreeBSD

Tim Peters tim.one at comcast.net
Fri Jul 2 19:49:33 EDT 2004


Log message for revision 26086:
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).


-=-
Modified: ZODB/trunk/NEWS.txt
===================================================================
--- ZODB/trunk/NEWS.txt	2004-07-02 23:07:21 UTC (rev 26085)
+++ ZODB/trunk/NEWS.txt	2004-07-02 23:49:32 UTC (rev 26086)
@@ -5,7 +5,8 @@
 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,7 +17,16 @@
 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
 ==============================
 Release date: 07-Jun-2004

Modified: ZODB/trunk/src/ZODB/tests/testTimeStamp.py
===================================================================
--- ZODB/trunk/src/ZODB/tests/testTimeStamp.py	2004-07-02 23:07:21 UTC (rev 26085)
+++ ZODB/trunk/src/ZODB/tests/testTimeStamp.py	2004-07-02 23:49:32 UTC (rev 26086)
@@ -41,16 +41,28 @@
         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)



More information about the Zodb-checkins mailing list