[Zodb-checkins] CVS: Packages/ZODB/tests - testRecover.py:1.3.8.2

Tim Peters tim.one at comcast.net
Mon Jul 18 11:29:36 EDT 2005


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

Modified Files:
      Tag: Zope-2_7-branch
	testRecover.py 
Log Message:
Collector #1846:  If an uncommitted transaction was found, fsrecover.py
fell into an infinite loop.  It also referenced an undefined global.
Fixed that, and added a new test (testUncommittedAtEnd) to ensure this
stays fixed.


=== Packages/ZODB/tests/testRecover.py 1.3.8.1 => 1.3.8.2 ===
--- Packages/ZODB/tests/testRecover.py:1.3.8.1	Mon Sep 15 17:26:57 2003
+++ Packages/ZODB/tests/testRecover.py	Mon Jul 18 11:29:36 2005
@@ -24,7 +24,7 @@
 import ZODB
 from ZODB.FileStorage import FileStorage
 from ZODB.PersistentMapping import PersistentMapping
-from ZODB.fsrecover import recover
+import ZODB.fsrecover
 from ZODB.tests.StorageTestBase import removefs
 
 from ZODB.fsdump import Dumper
@@ -80,7 +80,7 @@
         try:
             sys.stdout = StringIO.StringIO()
             try:
-                recover(self.path, self.dest,
+                ZODB.fsrecover.recover(self.path, self.dest,
                         verbose=0, partial=1, force=0, pack=1)
             except SystemExit:
                 raise RuntimeError, "recover tried to exit"
@@ -147,6 +147,36 @@
         self.recover(self.path, self.dest)
         self.recovered = FileStorage(self.dest)
         self.recovered.close()
+
+    # Issue 1846:  When a transaction had 'c' status (not yet committed),
+    # the attempt to open a temp file to write the trailing bytes fell
+    # into an infinite loop.
+    def testUncommittedAtEnd(self):
+        # Find a transaction near the end.
+        L = self.storage.undoLog()
+        r = L[1]
+        tid = base64.decodestring(r["id"] + "\n")
+        pos = self.storage._txn_find(tid, 0)
+
+        # Overwrite its status with 'c'.
+        f = open(self.path, "r+b")
+        f.seek(pos + 16)
+        current_status = f.read(1)
+        self.assertEqual(current_status, ' ')
+        f.seek(pos + 16)
+        f.write('c')
+        f.close()
+
+        # Try to recover.  The original bug was that this never completed --
+        # infinite loop in fsrecover.py.  Also, in the ZODB 3.2 line,
+        # reference to an undefined global masked the infinite loop.
+        self.recover(self.path, self.dest)
+
+        # Verify the destination got truncated.
+        self.assertEqual(os.path.getsize(self.dest), pos)
+
+        # Get rid of the temp file holding the truncated bytes.
+        os.remove(ZODB.fsrecover._trname)
 
 
 def test_suite():



More information about the Zodb-checkins mailing list