[Zodb-checkins] CVS: Zope/lib/python/ZODB/tests - TransactionalUndoStorage.py:1.13.44.2 TransactionalUndoVersionStorage.py:1.4.88.2

Jeremy Hylton jeremy@zope.com
Thu, 11 Apr 2002 16:40:36 -0400


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

Modified Files:
      Tag: Zope-2_5-branch
	TransactionalUndoStorage.py TransactionalUndoVersionStorage.py 
Log Message:
Backport fix of transaction_id generation from the trunk.

The transaction_id generated by undoLog() is now meaningful across
packs or across multiple Standby storages.  It's possible that the
transaction won't be present, but the storage will find it if it is
regardless of its exact location in the file.



=== Zope/lib/python/ZODB/tests/TransactionalUndoStorage.py 1.13.44.1 => 1.13.44.2 ===
 """
 
+import time
 import types
 from ZODB import POSException
 from ZODB.Transaction import Transaction
+from ZODB.referencesf import referencesf
+from ZODB.utils import u64
 
 from ZODB.tests.MinPO import MinPO
 from ZODB.tests.StorageTestBase import zodb_pickle, zodb_unpickle
@@ -421,3 +424,36 @@
                           self._storage.transactionalUndo,
                           tid, t)
         self._storage.tpc_abort(t)
+
+    def checkTransactionalUndoAfterPack(self):
+        eq = self.assertEqual
+        # Add a few object revisions
+        oid = self._storage.new_oid()
+        revid1 = self._dostore(oid, data=MinPO(51))
+        # Save now for packing away revid1
+        packtime = time.time()
+        time.sleep(1)
+        revid2 = self._dostore(oid, revid=revid1, data=MinPO(52))
+        revid3 = self._dostore(oid, revid=revid2, data=MinPO(53))
+        # Now get the undo log
+        info = self._storage.undoInfo()
+        eq(len(info), 3)
+        tid = info[0]['id']
+        # Now pack just the initial revision of the object.  We need the
+        # second revision otherwise we won't be able to undo the third
+        # revision!
+        self._storage.pack(packtime, referencesf)
+        # Make some basic assertions about the undo information now
+        info2 = self._storage.undoInfo()
+        eq(len(info2), 2)
+        # And now attempt to undo the last transaction
+        t = Transaction()
+        self._storage.tpc_begin(t)
+        oids = self._storage.transactionalUndo(tid, t)
+        self._storage.tpc_vote(t)
+        self._storage.tpc_finish(t)
+        eq(len(oids), 1)
+        eq(oids[0], oid)
+        data, revid = self._storage.load(oid, '')
+        # The object must now be at the second state
+        eq(zodb_unpickle(data), MinPO(52))


=== Zope/lib/python/ZODB/tests/TransactionalUndoVersionStorage.py 1.4.88.1 => 1.4.88.2 ===
+
 # Check interactions between transactionalUndo() and versions.  Any storage
 # that supports both transactionalUndo() and versions must pass these tests.
 
+import time
+
 from ZODB import POSException
+from ZODB.referencesf import referencesf
 from ZODB.Transaction import Transaction
 from ZODB.tests.MinPO import MinPO
 from ZODB.tests.StorageTestBase import zodb_unpickle
@@ -95,3 +100,115 @@
         assert zodb_unpickle(data) == MinPO(92)
         data, revid = self._storage.load(oid, '')
         assert zodb_unpickle(data) == MinPO(91)
+
+    def checkUndoCommitVersion(self):
+        def load_value(oid, version=''):
+            data, revid = self._storage.load(oid, version)
+            return zodb_unpickle(data).value
+
+        # create a bunch of packable transactions
+        oid = self._storage.new_oid()
+        revid = '\000' * 8
+        for i in range(4):
+            revid = self._dostore(oid, revid, description='packable%d' % i)
+        pt = time.time()
+        time.sleep(1)
+        
+        oid1 = self._storage.new_oid()
+        version = 'version'
+        revid1 = self._dostore(oid1, data=MinPO(0), description='create1')
+        revid2 = self._dostore(oid1, data=MinPO(1), revid=revid1,
+                               version=version, description='version1')
+        revid3 = self._dostore(oid1, data=MinPO(2), revid=revid2,
+                               version=version, description='version2')
+        self._dostore(description='create2')
+
+        t = Transaction()
+        t.description = 'commit version'
+        self._storage.tpc_begin(t)
+        self._storage.commitVersion(version, '', t)
+        self._storage.tpc_vote(t)
+        self._storage.tpc_finish(t)
+
+        info = self._storage.undoInfo()
+        t_id = info[0]['id']
+
+        self.assertEqual(load_value(oid1), 2)
+        self.assertEqual(load_value(oid1, version), 2)
+
+        self._storage.pack(pt, referencesf)
+
+        t = Transaction()
+        t.description = 'undo commit version'
+        self._storage.tpc_begin(t)
+        self._storage.transactionalUndo(t_id, t)
+        self._storage.tpc_vote(t)
+        self._storage.tpc_finish(t)
+
+        self.assertEqual(load_value(oid1), 0)
+        self.assertEqual(load_value(oid1, version), 2)
+
+    def checkUndoAbortVersion(self):
+        def load_value(oid, version=''):
+            data, revid = self._storage.load(oid, version)
+            return zodb_unpickle(data).value
+
+        # create a bunch of packable transactions
+        oid = self._storage.new_oid()
+        revid = '\000' * 8
+        for i in range(3):
+            revid = self._dostore(oid, revid, description='packable%d' % i)
+        pt = time.time()
+        time.sleep(1)
+        
+        oid1 = self._storage.new_oid()
+        version = 'version'
+        revid1 = self._dostore(oid1, data=MinPO(0), description='create1')
+        revid2 = self._dostore(oid1, data=MinPO(1), revid=revid1,
+                               version=version, description='version1')
+        revid3 = self._dostore(oid1, data=MinPO(2), revid=revid2,
+                               version=version, description='version2')
+        self._dostore(description='create2')
+
+        t = Transaction()
+        t.description = 'abort version'
+        self._storage.tpc_begin(t)
+        self._storage.abortVersion(version, t)
+        self._storage.tpc_vote(t)
+        self._storage.tpc_finish(t)
+
+        info = self._storage.undoInfo()
+        t_id = info[0]['id']
+
+        self.assertEqual(load_value(oid1), 0)
+        # after abort, we should see non-version data
+        self.assertEqual(load_value(oid1, version), 0)
+
+        t = Transaction()
+        t.description = 'undo abort version'
+        self._storage.tpc_begin(t)
+        self._storage.transactionalUndo(t_id, t)
+        self._storage.tpc_vote(t)
+        self._storage.tpc_finish(t)
+
+        self.assertEqual(load_value(oid1), 0)
+        # t undo will re-create the version
+        self.assertEqual(load_value(oid1, version), 2)
+
+        info = self._storage.undoInfo()
+        t_id = info[0]['id']
+
+        self._storage.pack(pt, referencesf)
+
+        t = Transaction()
+        t.description = 'undo undo'
+        self._storage.tpc_begin(t)
+        self._storage.transactionalUndo(t_id, t)
+        self._storage.tpc_vote(t)
+        self._storage.tpc_finish(t)
+
+        # undo of undo will put as back where we started
+        self.assertEqual(load_value(oid1), 0)
+        # after abort, we should see non-version data
+        self.assertEqual(load_value(oid1, version), 0)
+