[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