[Zope3-checkins] CVS: Zope3/lib/python/ZODB/tests - StorageTestBase.py:1.21 RecoveryStorage.py:1.4

Jeremy Hylton jeremy@zope.com
Fri, 6 Dec 2002 18:09:30 -0500


Update of /cvs-repository/Zope3/lib/python/ZODB/tests
In directory cvs.zope.org:/tmp/cvs-serv18478/tests

Modified Files:
	StorageTestBase.py RecoveryStorage.py 
Log Message:
Fix subtle bug in restore().

The _txn_find() must not stop at the pack boundary when it is called
by restore().  It was originally written for _txn_undo() which isn't
supposed to undo to a transaction across a pack.  But it should be
legal to restore() a transaction with a reference to a data record in
a transaction that was packed.

Fix by adding stop_at_pack flag to _txn_find() and add tests of this
behavior for FileStorage.


=== Zope3/lib/python/ZODB/tests/StorageTestBase.py 1.20 => 1.21 ===
--- Zope3/lib/python/ZODB/tests/StorageTestBase.py:1.20	Tue Nov 26 12:41:21 2002
+++ Zope3/lib/python/ZODB/tests/StorageTestBase.py	Fri Dec  6 18:09:29 2002
@@ -166,7 +166,7 @@
         return self._dostore(oid, revid, data, version, already_pickled=1)
     # The following methods depend on optional storage features.
 
-    def _undo(self, tid, oid):
+    def _undo(self, tid, oid=None):
         # Undo a tid that affects a single object (oid).
         # XXX This is very specialized
         t = Transaction()
@@ -175,8 +175,9 @@
         oids = self._storage.transactionalUndo(tid, t)
         self._storage.tpc_vote(t)
         self._storage.tpc_finish(t)
-        self.assertEqual(len(oids), 1)
-        self.assertEqual(oids[0], oid)
+        if oid is not None:
+            self.assertEqual(len(oids), 1)
+            self.assertEqual(oids[0], oid)
         return self._storage.lastTransaction()
 
     def _commitVersion(self, src, dst):


=== Zope3/lib/python/ZODB/tests/RecoveryStorage.py 1.3 => 1.4 ===
--- Zope3/lib/python/ZODB/tests/RecoveryStorage.py:1.3	Fri Dec  6 14:51:31 2002
+++ Zope3/lib/python/ZODB/tests/RecoveryStorage.py	Fri Dec  6 18:09:29 2002
@@ -20,7 +20,11 @@
 from ZODB.tests.IteratorStorage import IteratorDeepCompare
 from ZODB.tests.StorageTestBase import MinPO, zodb_unpickle, removefs
 from ZODB.FileStorage import FileStorage
+from ZODB.DB import DB
 
+from Transaction import get_transaction
+
+import time
 
 class RecoveryStorage(IteratorDeepCompare):
     # Requires a setUp() that creates a self._dst destination storage
@@ -129,3 +133,27 @@
         self._dst = FileStorage('Dest.fs')
         self._dst.copyTransactionsFrom(self._storage)
         self.compare(self._storage, self._dst)
+        
+    def checkRestoreAcrossPack(self):
+        db = DB(self._storage)
+        c = db.open()
+        r = c.root()
+        obj1 = r["obj1"] = MinPO(1)
+        get_transaction().commit()
+        obj1 = r["obj2"] = MinPO(1)
+        get_transaction().commit()
+
+        self._dst.copyTransactionsFrom(self._storage)
+        self._dst.pack(time.time())
+
+        self._undo(self._storage.undoInfo()[0]['id'])
+
+        # copy the final transaction manually.  even though there
+        # was a pack, the restore() ought to succeed.
+        final = list(self._storage.iterator())[-1]
+        self._dst.tpc_begin(final, final.tid, final.status)
+        for r in final:
+            self._dst.restore(r.oid, r.serial, r.data, r.version, r.data_txn,
+                         final)
+        self._dst.tpc_vote(final)
+        self._dst.tpc_finish(final)