[Zodb-checkins] CVS: Packages/ZODB/tests - testFileStorage.py:1.32.8.4

Tim Peters tim.one at comcast.net
Mon Jun 21 22:10:45 EDT 2004


Update of /cvs-repository/Packages/ZODB/tests
In directory cvs.zope.org:/tmp/cvs-serv12383/ZODB/tests

Modified Files:
      Tag: Zope-2_7-branch
	testFileStorage.py 
Log Message:
Collector 1327:  FileStorage init confused by time travel

If the system clock moved back in time more than 30 days between
a FileStorage close and (re)open, new txn ids could be smaller
than txn ids already in the database.  Plugged that hole.

Includes a stripped-down rewrite of the new test in ZODB 3.3.  Main
difference is that this version doesn't automatically check that new
log messages are actually produced; that's easier to do in 3.3,
building on an extension to the logging package Jim wrote for Zope 3.


=== Packages/ZODB/tests/testFileStorage.py 1.32.8.3 => 1.32.8.4 ===
--- Packages/ZODB/tests/testFileStorage.py:1.32.8.3	Fri May 21 12:14:05 2004
+++ Packages/ZODB/tests/testFileStorage.py	Mon Jun 21 22:10:44 2004
@@ -179,6 +179,86 @@
     def checkPackAfterUndoDeletion(self):
         pass
 
+
+    def checkTimeTravelOnOpen(self):
+        from ZODB.DB import DB
+
+        # This tests what happens if we open a FileStorage and its
+        # last tid appears to be in the future.  This can happen if,
+        # e.g., the system clock has been set backwards.  Part of
+        # the test is to check that we continue to create increasing
+        # tids anyway.  The other part is to check that we log
+        # appropriate msgs.  In ZODB 3.3, that latter part *is* checked,
+        # by adding additional handlers to the logging package.  In
+        # this (3.2) version of the test, it isn't checked
+        # automatically.  You have to enable logging and eyeball the
+        # log file in 3.2.
+
+        # First check the normal case:  transactions are recorded with
+        # increasing tids, and time doesn't run backwards.
+
+        db = DB(self._storage)
+        conn = db.open()
+        conn.root()['xyz'] = 1
+        get_transaction().commit()
+        checkIncreasingTids(self._storage)
+        db.close()
+        StorageTestBase.removefs("FileStorageTests.fs")
+
+        # Now force the database to have transaction records with tids from
+        # the future.
+
+        self.open(create=1)
+        self._storage._ts = timestamp(15)  # 15 minutes in the future
+        db = DB(self._storage)
+        db.close()
+
+        self.open() # this should log a warning
+        db = DB(self._storage)
+        conn = db.open()
+        conn.root()['xyz'] = 1
+        get_transaction().commit()
+        checkIncreasingTids(self._storage)
+        db.close()
+        StorageTestBase.removefs("FileStorageTests.fs")
+
+        # And one more time, with transaction records far in the future.
+        # We expect to log a critical error then, as a time so far in the
+        # future probably indicates a real problem with the system.
+        # Shorter spans may be due to clock drift.
+
+        self.open(create=1)
+        self._storage._ts = timestamp(60)  # an hour in the future
+        db = DB(self._storage)
+        db.close()
+
+        self.open() # this should log a critical error
+        db = DB(self._storage)
+        conn = db.open()
+        conn.root()['xyz'] = 1
+        get_transaction().commit()
+        checkIncreasingTids(self._storage)
+        db.close()
+        StorageTestBase.removefs("FileStorageTests.fs")
+
+# Raise an exception if the tids in FileStorage fs aren't
+# strictly increasing.
+def checkIncreasingTids(fs):
+    lasttid = '\0' * 8
+    for txn in fs.iterator():
+        if lasttid >= txn.tid:
+            raise ValueError("tids out of order %r >= %r" % (lasttid, tid))
+        lasttid = txn.tid
+
+# Return a TimeStamp object 'minutes' minutes in the future.
+def timestamp(minutes):
+    import time
+    from ZODB.TimeStamp import TimeStamp
+
+    t = time.time() + 60 * minutes
+    return TimeStamp(*time.gmtime(t)[:5] + (t % 60,))
+
+
 class FileStorageRecoveryTest(
     StorageTestBase.StorageTestBase,
     RecoveryStorage.RecoveryStorage,




More information about the Zodb-checkins mailing list