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

Tim Peters tim.one at comcast.net
Tue Nov 16 16:39:05 EST 2004


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

Modified Files:
      Tag: Zope-2_7-branch
	testFileStorage.py 
Log Message:
Collector 1581:  fspack can blow up when .fs is corrupted

Repaired three places where fspack referenced an undefined global while
*trying* to raise CorruptedError.  Added new checkCorruptionInPack()
test to verify the correct exception gets raised.


=== Packages/ZODB/tests/testFileStorage.py 1.32.8.4 => 1.32.8.5 ===
--- Packages/ZODB/tests/testFileStorage.py:1.32.8.4	Mon Jun 21 22:10:44 2004
+++ Packages/ZODB/tests/testFileStorage.py	Tue Nov 16 16:39:04 2004
@@ -241,6 +241,57 @@
         db.close()
         StorageTestBase.removefs("FileStorageTests.fs")
 
+    def checkCorruptionInPack(self):
+        # This sets up a corrupt .fs file, with a redundant transaction
+        # length mismatch.  The implementation of pack in many releases of
+        # ZODB blew up if the .fs file had such damage:  it detected the
+        # damage, but the code to raise CorruptedError referenced an undefined
+        # global.
+        import time
+
+        from ZODB.DB import DB
+        from ZODB.utils import U64, p64
+        from ZODB.fspack import CorruptedError
+
+        db = DB(self._storage)
+        conn = db.open()
+        conn.root()['xyz'] = 1
+        get_transaction().commit()
+
+        # Ensure it's all on disk.
+        db.close()
+        self._storage.close()
+
+        # Reopen before damaging.
+        self.open()
+
+        # Open .fs directly, and damage content.
+        f = open('FileStorageTests.fs', 'r+b')
+        f.seek(0, 2)
+        pos2 = f.tell() - 8
+        f.seek(pos2)
+        tlen2 = U64(f.read(8))  # length-8 of the last transaction
+        pos1 = pos2 - tlen2 + 8 # skip over the tid at the start
+        f.seek(pos1)
+        tlen1 = U64(f.read(8))  # should be redundant length-8
+        self.assertEqual(tlen1, tlen2)  # verify that it is redundant
+
+        # Now damage the second copy.
+        f.seek(pos2)
+        f.write(p64(tlen2 - 1))
+        f.close()
+
+        # Try to pack.  This used to yield
+        #     NameError: global name 's' is not defined
+        try:
+            self._storage.pack(time.time(), None)
+        except CorruptedError, detail:
+            self.assert_("redundant transaction length does not match "
+                         "initial transaction length" in str(detail))
+        else:
+            self.fail("expected CorruptedError")
+
+
 # Raise an exception if the tids in FileStorage fs aren't
 # strictly increasing.
 def checkIncreasingTids(fs):



More information about the Zodb-checkins mailing list