[Zope-Checkins] CVS: Zope/lib/python/ZODB/tests - RecoveryStorage.py:1.2.4.1 testStorageConfig.py:1.4.2.1 ConflictResolution.py:1.8.4.1 PackableStorage.py:1.13.4.1 StorageTestBase.py:1.17.4.1 Synchronization.py:1.6.4.1 TransactionalUndoStorage.py:1.21.4.3 TransactionalUndoVersionStorage.py:1.8.4.2 VersionStorage.py:1.14.4.2 testFileStorage.py:1.19.4.1 testZODB.py:1.4.4.2

Chris McDonough chrism@zope.com
Sun, 24 Nov 2002 19:10:16 -0500


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

Modified Files:
      Tag: chrism-install-branch
	ConflictResolution.py PackableStorage.py StorageTestBase.py 
	Synchronization.py TransactionalUndoStorage.py 
	TransactionalUndoVersionStorage.py VersionStorage.py 
	testFileStorage.py testZODB.py 
Added Files:
      Tag: chrism-install-branch
	RecoveryStorage.py testStorageConfig.py 
Log Message:
Merge with HEAD.


=== Added File Zope/lib/python/ZODB/tests/RecoveryStorage.py ===
"""More recovery and iterator tests."""

from ZODB.Transaction import Transaction
from ZODB.tests.IteratorStorage import IteratorDeepCompare
from ZODB.tests.StorageTestBase import MinPO, zodb_unpickle


class RecoveryStorage(IteratorDeepCompare):
    # Requires a setUp() that creates a self._dst destination storage
    def checkSimpleRecovery(self):
        oid = self._storage.new_oid()
        revid = self._dostore(oid, data=11)
        revid = self._dostore(oid, revid=revid, data=12)
        revid = self._dostore(oid, revid=revid, data=13)
        self._dst.copyTransactionsFrom(self._storage)
        self.compare(self._storage, self._dst)

    def checkRecoveryAcrossVersions(self):
        oid = self._storage.new_oid()
        revid = self._dostore(oid, data=21)
        revid = self._dostore(oid, revid=revid, data=22)
        revid = self._dostore(oid, revid=revid, data=23, version='one')
        revid = self._dostore(oid, revid=revid, data=34, version='one')
        # Now commit the version
        t = Transaction()
        self._storage.tpc_begin(t)
        self._storage.commitVersion('one', '', t)
        self._storage.tpc_vote(t)
        self._storage.tpc_finish(t)
        self._dst.copyTransactionsFrom(self._storage)
        self.compare(self._storage, self._dst)

    def checkRecoverAbortVersion(self):
        oid = self._storage.new_oid()
        revid = self._dostore(oid, data=21, version="one")
        revid = self._dostore(oid, revid=revid, data=23, version='one')
        revid = self._dostore(oid, revid=revid, data=34, version='one')
        # Now abort the version and the creation
        t = Transaction()
        self._storage.tpc_begin(t)
        oids = self._storage.abortVersion('one', t)
        self._storage.tpc_vote(t)
        self._storage.tpc_finish(t)
        self.assertEqual(oids, [oid])
        self._dst.copyTransactionsFrom(self._storage)
        self.compare(self._storage, self._dst)
        # Also make sure the the last transaction has a data record
        # with None for its data attribute, because we've undone the
        # object.
        for s in self._storage, self._dst:
            iter = s.iterator()
            for trans in iter:
                pass # iterate until we get the last one
            data = trans[0]
            self.assertRaises(IndexError, lambda i, t=trans: t[i], 1)
            self.assertEqual(data.oid, oid)
            self.assertEqual(data.data, None)
    
    def checkRecoverUndoInVersion(self):
        oid = self._storage.new_oid()
        version = "aVersion"
        revid_a = self._dostore(oid, data=MinPO(91))
        revid_b = self._dostore(oid, revid=revid_a, version=version,
                                data=MinPO(92))
        revid_c = self._dostore(oid, revid=revid_b, version=version,
                                data=MinPO(93))
        self._undo(self._storage.undoInfo()[0]['id'], oid)
        self._commitVersion(version, '')
        self._undo(self._storage.undoInfo()[0]['id'], oid)

        # now copy the records to a new storage
        self._dst.copyTransactionsFrom(self._storage)
        
        self._abortVersion(version)
        self.assert_(self._storage.versionEmpty(version))
        self._undo(self._storage.undoInfo()[0]['id'], oid)
        self.assert_(not self._storage.versionEmpty(version))

        # check the data is what we expect it to be
        data, revid = self._storage.load(oid, version)
        self.assertEqual(zodb_unpickle(data), MinPO(92))
        data, revid = self._storage.load(oid, '')
        self.assertEqual(zodb_unpickle(data), MinPO(91))

        # and swap the storages
        tmp = self._storage
        self._storage = self._dst
        self._abortVersion(version)
        self.assert_(self._storage.versionEmpty(version))
        self._undo(self._storage.undoInfo()[0]['id'], oid)
        self.assert_(not self._storage.versionEmpty(version))

        # check the data is what we expect it to be
        data, revid = self._storage.load(oid, version)
        self.assertEqual(zodb_unpickle(data), MinPO(92))
        data, revid = self._storage.load(oid, '')
        self.assertEqual(zodb_unpickle(data), MinPO(91))

        # Now remove _dst and copy all the transactions a second time.
        # This time we will be able to confirm via compare().
        self._storage = tmp
        self._dst.close()
        self._dst = self.new_dest()
        self._dst.copyTransactionsFrom(self._storage)
        self.compare(self._storage, self._dst)


=== Added File Zope/lib/python/ZODB/tests/testStorageConfig.py ===
import os
import shutil
import tempfile
import unittest
from StringIO import StringIO

import ZConfig

from ZODB import StorageConfig

class StorageTestCase(unittest.TestCase):

    def setUp(self):
        unittest.TestCase.setUp(self)
        self.tmpfn = tempfile.mktemp()
        self.storage = None

    def tearDown(self):
        unittest.TestCase.tearDown(self)
        storage = self.storage
        self.storage = None
        try:
            if storage is not None:
                storage.close()
        except:
            pass
        try:
            # Full storage creates a directory
            if os.path.isdir(self.tmpfn):
                shutil.rmtree(self.tmpfn)
            else:
                os.remove(self.tmpfn)
        except os.error:
            pass

    def testFileStorage(self):
        from ZODB.FileStorage import FileStorage
        sample = """
        <Storage>
        type       FileStorage
        file_name  %s
        create     yes
        </Storage>
        """ % self.tmpfn
        io = StringIO(sample)
        rootconf = ZConfig.loadfile(io)
        storageconf = rootconf.getSection("Storage")
        cls, args = StorageConfig.getStorageInfo(storageconf)
        self.assertEqual(cls, FileStorage)
        self.assertEqual(args, {"file_name": self.tmpfn, "create": 1})
        self.storage = StorageConfig.createStorage(storageconf)
        self.assert_(isinstance(self.storage, FileStorage))

    def testZEOStorage(self):
        from ZEO.ClientStorage import ClientStorage
        sample = """
        <Storage>
        type       ClientStorage
        addr       zeo://www.python.org:9001
        wait       no
        </Storage>
        """
        io = StringIO(sample)
        rootconf = ZConfig.loadfile(io)
        storageconf = rootconf.getSection("Storage")
        cls, args = StorageConfig.getStorageInfo(storageconf)
        self.assertEqual(cls, ClientStorage)
        self.assertEqual(args, {"addr": [("www.python.org", 9001)], "wait": 0})
        self.storage = StorageConfig.createStorage(storageconf)
        self.assert_(isinstance(self.storage, ClientStorage))

    def testDemoStorage(self):
        from ZODB.DemoStorage import DemoStorage
        sample = """
        <Storage>
        type       DemoStorage
        </Storage>
        """
        io = StringIO(sample)
        rootconf = ZConfig.loadfile(io)
        storageconf = rootconf.getSection("Storage")
        cls, args = StorageConfig.getStorageInfo(storageconf)
        self.assertEqual(cls, DemoStorage)
        self.assertEqual(args, {})
        self.storage = StorageConfig.createStorage(storageconf)
        self.assert_(isinstance(self.storage, DemoStorage))

    def testModuleStorage(self):
        # Test explicit module+class
        from ZODB.DemoStorage import DemoStorage
        sample = """
        <Storage>
        type       ZODB.DemoStorage.DemoStorage
        </Storage>
        """
        io = StringIO(sample)
        rootconf = ZConfig.loadfile(io)
        storageconf = rootconf.getSection("Storage")
        cls, args = StorageConfig.getStorageInfo(storageconf)
        self.assertEqual(cls, DemoStorage)
        self.assertEqual(args, {})
        self.storage = StorageConfig.createStorage(storageconf)
        self.assert_(isinstance(self.storage, DemoStorage))

    def testFullStorage(self):
        try:
            from bsddb3Storage.Full import Full
        except ImportError:
            return
        sample = """
        <Storage>
        type       Full
        name       %s
        cachesize  1000
        </Storage>
        """ % self.tmpfn
        os.mkdir(self.tmpfn)
        io = StringIO(sample)
        rootconf = ZConfig.loadfile(io)
        storageconf = rootconf.getSection("Storage")
        cls, args = StorageConfig.getStorageInfo(storageconf)
        self.assertEqual(cls, Full)
        # It's too hard to test the config instance equality
        args = args.copy()
        del args['config']
        self.assertEqual(args, {"name": self.tmpfn})
        self.storage = StorageConfig.createStorage(storageconf)
        self.assert_(isinstance(self.storage, Full))
        # XXX _config isn't public
        self.assert_(self.storage._config.cachesize, 1000)

    def testMinimalStorage(self):
        try:
            from bsddb3Storage.Minimal import Minimal
        except ImportError:
            return
        sample = """
        <Storage>
        type       Minimal
        name       %s
        cachesize  1000
        </Storage>
        """ % self.tmpfn
        os.mkdir(self.tmpfn)
        io = StringIO(sample)
        rootconf = ZConfig.loadfile(io)
        storageconf = rootconf.getSection("Storage")
        cls, args = StorageConfig.getStorageInfo(storageconf)
        self.assertEqual(cls, Minimal)
        # It's too hard to test the config instance equality
        args = args.copy()
        del args['config']
        self.assertEqual(args, {"name": self.tmpfn})
        self.storage = StorageConfig.createStorage(storageconf)
        self.assert_(isinstance(self.storage, Minimal))
        # XXX _config isn't public
        self.assert_(self.storage._config.cachesize, 1000)

def test_suite():
    return unittest.makeSuite(StorageTestCase)

if __name__ == '__main__':
    unittest.main(defaultTest='test_suite')


=== Zope/lib/python/ZODB/tests/ConflictResolution.py 1.8 => 1.8.4.1 ===
--- Zope/lib/python/ZODB/tests/ConflictResolution.py:1.8	Wed Aug 14 18:07:09 2002
+++ Zope/lib/python/ZODB/tests/ConflictResolution.py	Sun Nov 24 19:10:13 2002
@@ -104,7 +104,7 @@
         # pickle is to commit two different transactions relative to
         # revid1 that add two to _value.
         revid2 = self._dostoreNP(oid, revid=revid1, data=zodb_pickle(obj))
-        self.assertRaises(AttributeError,
+        self.assertRaises(ConflictError,
                           self._dostoreNP,
                           oid, revid=revid1, data=zodb_pickle(obj))
 
@@ -122,7 +122,7 @@
         # pickle is to commit two different transactions relative to
         # revid1 that add two to _value.
         revid2 = self._dostoreNP(oid, revid=revid1, data=zodb_pickle(obj))
-        self.assertRaises(TypeError,
+        self.assertRaises(ConflictError,
                           self._dostoreNP,
                           oid, revid=revid1, data=zodb_pickle(obj))
 


=== Zope/lib/python/ZODB/tests/PackableStorage.py 1.13 => 1.13.4.1 ===
--- Zope/lib/python/ZODB/tests/PackableStorage.py:1.13	Wed Aug 14 18:07:09 2002
+++ Zope/lib/python/ZODB/tests/PackableStorage.py	Sun Nov 24 19:10:13 2002
@@ -13,6 +13,8 @@
     from StringIO import StringIO
 
 import time
+from ZODB import DB
+from Persistence import Persistent
 from ZODB.referencesf import referencesf
 
 
@@ -42,6 +44,9 @@
         return self._oid
 
 
+class C(Persistent):
+    pass
+
 # Here's where all the magic occurs.  Sadly, the pickle module is a bit
 # underdocumented, but here's what happens: by setting the persistent_id
 # attribute to getpersid() on the pickler, that function gets called for every
@@ -159,8 +164,10 @@
         eq(pobj.value, 3)
         # Now pack all transactions; need to sleep a second to make
         # sure that the pack time is greater than the last commit time.
-        time.sleep(1)
-        self._storage.pack(time.time(), referencesf)
+        now = packtime = time.time()
+        while packtime <= now:
+            packtime = time.time()
+        self._storage.pack(packtime, referencesf)
         # All revisions of the object should be gone, since there is no
         # reference from the root object to this object.
         raises(KeyError, self._storage.loadSerial, oid, revid1)
@@ -210,8 +217,10 @@
         eq(pobj.value, 3)
         # Now pack just revisions 1 and 2.  The object's current revision
         # should stay alive because it's pointed to by the root.
-        time.sleep(1)
-        self._storage.pack(time.time(), referencesf)
+        now = packtime = time.time()
+        while packtime <= now:
+            packtime = time.time()
+        self._storage.pack(packtime, referencesf)
         # Make sure the revisions are gone, but that object zero and revision
         # 3 are still there and correct
         data, revid = self._storage.load(ZERO, '')
@@ -287,8 +296,10 @@
         # Now pack just revisions 1 and 2 of object1.  Object1's current
         # revision should stay alive because it's pointed to by the root, as
         # should Object2's current revision.
-        time.sleep(1)
-        self._storage.pack(time.time(), referencesf)
+        now = packtime = time.time()
+        while packtime <= now:
+            packtime = time.time()
+        self._storage.pack(packtime, referencesf)
         # Make sure the revisions are gone, but that object zero, object2, and
         # revision 3 of object1 are still there and correct.
         data, revid = self._storage.load(ZERO, '')
@@ -312,3 +323,43 @@
         pobj = pickle.loads(data)
         eq(pobj.getoid(), oid2)
         eq(pobj.value, 11)
+
+    def checkPackUnlinkedFromRoot(self):
+        eq = self.assertEqual
+        db = DB(self._storage)
+        conn = db.open()
+        root = conn.root()
+
+        txn = get_transaction()
+        txn.note('root')
+        txn.commit()
+
+        now = packtime = time.time()
+        while packtime <= now:
+            packtime = time.time()
+
+        obj = C()
+        obj.value = 7
+
+        root['obj'] = obj
+        txn = get_transaction()
+        txn.note('root -> o1')
+        txn.commit()
+
+        del root['obj']
+        txn = get_transaction()
+        txn.note('root -x-> o1')
+        txn.commit()
+
+        self._storage.pack(packtime, referencesf)
+
+        log = self._storage.undoLog()
+        tid = log[0]['id']
+        db.undo(tid)
+        txn = get_transaction()
+        txn.note('undo root -x-> o1')
+        txn.commit()
+
+        conn.sync()
+
+        eq(root['obj'].value, 7)


=== Zope/lib/python/ZODB/tests/StorageTestBase.py 1.17 => 1.17.4.1 ===
--- Zope/lib/python/ZODB/tests/StorageTestBase.py:1.17	Wed Aug 14 18:07:09 2002
+++ Zope/lib/python/ZODB/tests/StorageTestBase.py	Sun Nov 24 19:10:13 2002
@@ -100,8 +100,7 @@
 
     A helper for function _handle_all_serials().
     """
-    args = (oid,) + args
-    return apply(handle_all_serials, args)[oid]
+    return handle_all_serials(oid, *args)[oid]
 
 def import_helper(name):
     mod = __import__(name)
@@ -181,3 +180,35 @@
     def _dostoreNP(self, oid=None, revid=None, data=None, version=None,
                    user=None, description=None):
         return self._dostore(oid, revid, data, version, already_pickled=1)
+    # The following methods depend on optional storage features.
+
+    def _undo(self, tid, oid):
+        # Undo a tid that affects a single object (oid).
+        # XXX This is very specialized
+        t = Transaction()
+        t.note("undo")
+        self._storage.tpc_begin(t)
+        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)
+        return self._storage.lastTransaction()
+
+    def _commitVersion(self, src, dst):
+        t = Transaction()
+        t.note("commit %r to %r" % (src, dst))
+        self._storage.tpc_begin(t)
+        oids = self._storage.commitVersion(src, dst, t)
+        self._storage.tpc_vote(t)
+        self._storage.tpc_finish(t)
+        return oids
+
+    def _abortVersion(self, ver):
+        t = Transaction()
+        t.note("abort %r" % ver)
+        self._storage.tpc_begin(t)
+        oids = self._storage.abortVersion(ver, t)
+        self._storage.tpc_vote(t)
+        self._storage.tpc_finish(t)
+        return oids


=== Zope/lib/python/ZODB/tests/Synchronization.py 1.6 => 1.6.4.1 ===
--- Zope/lib/python/ZODB/tests/Synchronization.py:1.6	Wed Aug 14 18:07:09 2002
+++ Zope/lib/python/ZODB/tests/Synchronization.py	Sun Nov 24 19:10:13 2002
@@ -63,8 +63,7 @@
 ##        self.assertRaises(StorageTransactionError, callable *args)
 
     def verifyNotCommitting(self, callable, *args):
-        args = (StorageTransactionError, callable) + args
-        apply(self.assertRaises, args)
+        self.assertRaises(StorageTransactionError, callable, *args)
 
     def verifyWrongTrans(self, callable, *args):
         t = Transaction()


=== Zope/lib/python/ZODB/tests/TransactionalUndoStorage.py 1.21.4.2 => 1.21.4.3 ===
--- Zope/lib/python/ZODB/tests/TransactionalUndoStorage.py:1.21.4.2	Sat Oct 26 15:51:49 2002
+++ Zope/lib/python/ZODB/tests/TransactionalUndoStorage.py	Sun Nov 24 19:10:13 2002
@@ -556,7 +556,7 @@
         orig = []
         for i in range(BATCHES):
             t = Transaction()
-            tid = p64(i+1)
+            tid = p64(i + 1)
             s.tpc_begin(t, tid)
             for j in range(OBJECTS):
                 oid = s.new_oid()


=== Zope/lib/python/ZODB/tests/TransactionalUndoVersionStorage.py 1.8.4.1 => 1.8.4.2 ===
--- Zope/lib/python/ZODB/tests/TransactionalUndoVersionStorage.py:1.8.4.1	Sat Oct 26 15:51:50 2002
+++ Zope/lib/python/ZODB/tests/TransactionalUndoVersionStorage.py	Sun Nov 24 19:10:13 2002
@@ -29,9 +29,25 @@
                 pass # not expected
         return self._dostore(*args, **kwargs)
 
+    def _undo(self, tid, oid):
+        t = Transaction()
+        self._storage.tpc_begin(t)
+        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)
+
     def checkUndoInVersion(self):
         eq = self.assertEqual
         unless = self.failUnless
+
+        def check_objects(nonversiondata, versiondata):
+            data, revid = self._storage.load(oid, version)
+            self.assertEqual(zodb_unpickle(data), MinPO(versiondata))
+            data, revid = self._storage.load(oid, '')
+            self.assertEqual(zodb_unpickle(data), MinPO(nonversiondata))
+        
         oid = self._storage.new_oid()
         version = 'one'
         revid_a = self._dostore(oid, data=MinPO(91))
@@ -39,21 +55,17 @@
                                 version=version)
         revid_c = self._dostore(oid, revid=revid_b, data=MinPO(93),
                                 version=version)
-        info=self._storage.undoInfo()
-        tid=info[0]['id']
-        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)
+        
+        info = self._storage.undoInfo()
+        self._undo(info[0]['id'], oid)
+        
         data, revid = self._storage.load(oid, '')
         eq(revid, revid_a)
         eq(zodb_unpickle(data), MinPO(91))
         data, revid = self._storage.load(oid, version)
         unless(revid > revid_b and revid > revid_c)
         eq(zodb_unpickle(data), MinPO(92))
+        
         # Now commit the version...
         t = Transaction()
         self._storage.tpc_begin(t)
@@ -63,61 +75,25 @@
         eq(len(oids), 1)
         eq(oids[0], oid)
 
-        #JF# No, because we fall back to non-version data.
-        #JF# self.assertRaises(POSException.VersionError,
-        #JF#                   self._storage.load,
-        #JF#                   oid, version)
-        data, revid = self._storage.load(oid, version)
-        eq(zodb_unpickle(data), MinPO(92))
-        data, revid = self._storage.load(oid, '')
-        eq(zodb_unpickle(data), MinPO(92))
+        check_objects(92, 92)
+        
         # ...and undo the commit
-        info=self._storage.undoInfo()
-        tid=info[0]['id']
-        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, version)
-        eq(zodb_unpickle(data), MinPO(92))
-        data, revid = self._storage.load(oid, '')
-        eq(zodb_unpickle(data), MinPO(91))
-        # Now abort the version
-        t = Transaction()
-        self._storage.tpc_begin(t)
-        oids = self._storage.abortVersion(version, t)
-        self._storage.tpc_vote(t)
-        self._storage.tpc_finish(t)
-        eq(len(oids), 1)
-        eq(oids[0], oid)
-        # The object should not exist in the version now, but it should exist
-        # in the non-version
-        #JF# No, because we fall back
-        #JF# self.assertRaises(POSException.VersionError,
-        #JF#                   self._storage.load,
-        #JF#                   oid, version)
-        data, revid = self._storage.load(oid, version)
-        eq(zodb_unpickle(data), MinPO(91))
-        data, revid = self._storage.load(oid, '')
-        eq(zodb_unpickle(data), MinPO(91))
+        info = self._storage.undoInfo()
+        self._undo(info[0]['id'], oid)
+
+        check_objects(91, 92)
+
+        oids = self._abortVersion(version)
+        assert len(oids) == 1
+        assert oids[0] == oid
+
+        check_objects(91, 91)
+        
         # Now undo the abort
         info=self._storage.undoInfo()
-        tid=info[0]['id']
-        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)
-        # And the object should be back in versions 'one' and ''
-        data, revid = self._storage.load(oid, version)
-        eq(zodb_unpickle(data), MinPO(92))
-        data, revid = self._storage.load(oid, '')
-        eq(zodb_unpickle(data), MinPO(91))
+        self._undo(info[0]['id'], oid)
+        
+        check_objects(91, 92)
 
     def checkUndoCommitVersion(self):
         def load_value(oid, version=''):


=== Zope/lib/python/ZODB/tests/VersionStorage.py 1.14.4.1 => 1.14.4.2 ===
--- Zope/lib/python/ZODB/tests/VersionStorage.py:1.14.4.1	Thu Aug 29 01:31:24 2002
+++ Zope/lib/python/ZODB/tests/VersionStorage.py	Sun Nov 24 19:10:13 2002
@@ -14,22 +14,6 @@
 
 class VersionStorage:
 
-    def _commitVersion(self, src, dst):
-        t = Transaction()
-        self._storage.tpc_begin(t)
-        oids = self._storage.commitVersion(src, dst, t)
-        self._storage.tpc_vote(t)
-        self._storage.tpc_finish(t)
-        return oids
-
-    def _abortVersion(self, ver):
-        t = Transaction()
-        self._storage.tpc_begin(t)
-        oids = self._storage.abortVersion(ver, t)
-        self._storage.tpc_vote(t)
-        self._storage.tpc_finish(t)
-        return oids
-
     def checkCommitVersionSerialno(self):
         oid = self._storage.new_oid()
         revid1 = self._dostore(oid, data=MinPO(12))
@@ -366,3 +350,16 @@
                           self._storage.load, oid, '')
         self.assertRaises(KeyError,
                           self._storage.load, oid, 'two')
+
+    def checkCreateObjectInVersionWithAbort(self):
+        oid = self._storage.new_oid()
+        revid = self._dostore(oid, data=21, version="one")
+        revid = self._dostore(oid, revid=revid, data=23, version='one')
+        revid = self._dostore(oid, revid=revid, data=34, version='one')
+        # Now abort the version and the creation
+        t = Transaction()
+        self._storage.tpc_begin(t)
+        oids = self._storage.abortVersion('one', t)
+        self._storage.tpc_vote(t)
+        self._storage.tpc_finish(t)
+        self.assertEqual(oids, [oid])


=== Zope/lib/python/ZODB/tests/testFileStorage.py 1.19 => 1.19.4.1 ===
--- Zope/lib/python/ZODB/tests/testFileStorage.py:1.19	Wed Aug 14 18:07:09 2002
+++ Zope/lib/python/ZODB/tests/testFileStorage.py	Sun Nov 24 19:10:13 2002
@@ -11,7 +11,8 @@
      TransactionalUndoVersionStorage, PackableStorage, \
      Synchronization, ConflictResolution, HistoryStorage, \
      IteratorStorage, Corruption, RevisionStorage, PersistentStorage, \
-     MTStorage, ReadOnlyStorage
+     MTStorage, ReadOnlyStorage, RecoveryStorage
+from ZODB.tests.StorageTestBase import MinPO, zodb_unpickle
 
 class FileStorageTests(
     StorageTestBase.StorageTestBase,
@@ -32,12 +33,8 @@
     ):
 
     def open(self, **kwargs):
-        if kwargs:
-            self._storage = apply(ZODB.FileStorage.FileStorage,
-                                  ('FileStorageTests.fs',), kwargs)
-        else:
-            self._storage = ZODB.FileStorage.FileStorage(
-                'FileStorageTests.fs', **kwargs)
+        self._storage = ZODB.FileStorage.FileStorage('FileStorageTests.fs',
+                                                     **kwargs)
 
     def setUp(self):
         self.open(create=1)
@@ -63,10 +60,12 @@
 
 class FileStorageRecoveryTest(
     StorageTestBase.StorageTestBase,
-    IteratorStorage.IteratorDeepCompare,
+    RecoveryStorage.RecoveryStorage,
     ):
 
     def setUp(self):
+        StorageTestBase.removefs("Source.fs")
+        StorageTestBase.removefs("Dest.fs")
         self._storage = ZODB.FileStorage.FileStorage('Source.fs')
         self._dst = ZODB.FileStorage.FileStorage('Dest.fs')
 
@@ -76,55 +75,67 @@
         StorageTestBase.removefs("Source.fs")
         StorageTestBase.removefs("Dest.fs")
 
-    def checkSimpleRecovery(self):
-        oid = self._storage.new_oid()
-        revid = self._dostore(oid, data=11)
-        revid = self._dostore(oid, revid=revid, data=12)
-        revid = self._dostore(oid, revid=revid, data=13)
-        self._dst.copyTransactionsFrom(self._storage)
-        self.compare(self._storage, self._dst)
+    def new_dest(self):
+        StorageTestBase.removefs('Dest.fs')
+        return ZODB.FileStorage.FileStorage('Dest.fs')
 
-    def checkRecoveryAcrossVersions(self):
+    def checkRecoverUndoInVersion(self):
         oid = self._storage.new_oid()
-        revid = self._dostore(oid, data=21)
-        revid = self._dostore(oid, revid=revid, data=22)
-        revid = self._dostore(oid, revid=revid, data=23, version='one')
-        revid = self._dostore(oid, revid=revid, data=34, version='one')
-        # Now commit the version
-        t = Transaction()
-        self._storage.tpc_begin(t)
-        self._storage.commitVersion('one', '', t)
-        self._storage.tpc_vote(t)
-        self._storage.tpc_finish(t)
+        version = "aVersion"
+        revid_a = self._dostore(oid, data=MinPO(91))
+        revid_b = self._dostore(oid, revid=revid_a, version=version,
+                                data=MinPO(92))
+        revid_c = self._dostore(oid, revid=revid_b, version=version,
+                                data=MinPO(93))
+        self._undo(self._storage.undoInfo()[0]['id'], oid)
+        self._commitVersion(version, '')
+        self._undo(self._storage.undoInfo()[0]['id'], oid)
+
+        # now copy the records to a new storage
         self._dst.copyTransactionsFrom(self._storage)
         self.compare(self._storage, self._dst)
 
-    def checkRecoverAbortVersion(self):
-        oid = self._storage.new_oid()
-        revid = self._dostore(oid, data=21, version="one")
-        revid = self._dostore(oid, revid=revid, data=23, version='one')
-        revid = self._dostore(oid, revid=revid, data=34, version='one')
-        # Now abort the version and the creation
-        t = Transaction()
-        self._storage.tpc_begin(t)
-        oids = self._storage.abortVersion('one', t)
-        self._storage.tpc_vote(t)
-        self._storage.tpc_finish(t)
-        self.assertEqual(oids, [oid])
+        # The last two transactions were applied directly rather than
+        # copied.  So we can't use compare() to verify that they new
+        # transactions are applied correctly.  (The new transactions
+        # will have different timestamps for each storage.)
+
+        self._abortVersion(version)
+        self.assert_(self._storage.versionEmpty(version))
+        self._undo(self._storage.undoInfo()[0]['id'], oid)
+        self.assert_(not self._storage.versionEmpty(version))
+
+        # check the data is what we expect it to be
+        data, revid = self._storage.load(oid, version)
+        self.assertEqual(zodb_unpickle(data), MinPO(92))
+        data, revid = self._storage.load(oid, '')
+        self.assertEqual(zodb_unpickle(data), MinPO(91))
+
+        # and swap the storages
+        tmp = self._storage
+        self._storage = self._dst
+        self._abortVersion(version)
+        self.assert_(self._storage.versionEmpty(version))
+        self._undo(self._storage.undoInfo()[0]['id'], oid)
+        self.assert_(not self._storage.versionEmpty(version))
+
+        # check the data is what we expect it to be
+        data, revid = self._storage.load(oid, version)
+        self.assertEqual(zodb_unpickle(data), MinPO(92))
+        data, revid = self._storage.load(oid, '')
+        self.assertEqual(zodb_unpickle(data), MinPO(91))
+
+        # swap them back
+        self._storage = tmp
+
+        # Now remove _dst and copy all the transactions a second time.
+        # This time we will be able to confirm via compare().
+        self._dst.close()
+        StorageTestBase.removefs("Dest.fs")
+        self._dst = ZODB.FileStorage.FileStorage('Dest.fs')
         self._dst.copyTransactionsFrom(self._storage)
         self.compare(self._storage, self._dst)
-        # Also make sure the the last transaction has a data record
-        # with None for its data attribute, because we've undone the
-        # object.
-        for s in self._storage, self._dst:
-            iter = s.iterator()
-            for trans in iter:
-                pass # iterate until we get the last one
-            data = trans[0]
-            self.assertRaises(IndexError, lambda i:trans[i], 1)
-            self.assertEqual(data.oid, oid)
-            self.assertEqual(data.data, None)
-
+        
 
 def test_suite():
     suite = unittest.makeSuite(FileStorageTests, 'check')


=== Zope/lib/python/ZODB/tests/testZODB.py 1.4.4.1 => 1.4.4.2 ===
--- Zope/lib/python/ZODB/tests/testZODB.py:1.4.4.1	Tue Sep 10 23:36:38 2002
+++ Zope/lib/python/ZODB/tests/testZODB.py	Sun Nov 24 19:10:13 2002
@@ -94,28 +94,6 @@
         self._storage.close()
         removefs("ZODBTests.fs")
 
-    def checkUnmodifiedObject(self):
-        # Test that a transaction with only unmodified objects works
-        # correctly.  The specific sequence of events is:
-        #     - an object is modified
-        #     - it is registered with the transaction
-        #     - the object is explicitly "unmodified"
-        #     - the transaction commits, but now has no modified objects
-        # We'd like to avoid doing anything with the storage.
-        ltid = self._storage.lastTransaction()
-        _objects = get_transaction()._objects
-        self.assertEqual(len(_objects), 0)
-        r = self._db.open().root()
-        obj = r["test"][0]
-        obj[1] = 1
-        self.assertEqual(obj._p_changed, 1)
-        self.assertEqual(len(_objects), 1)
-        del obj._p_changed
-        self.assertEqual(obj._p_changed, None)
-        self.assertEqual(len(_objects), 1)
-        get_transaction().commit()
-        self.assertEqual(ltid, self._storage.lastTransaction())
-
     def checkVersionOnly(self):
         # Make sure the changes to make empty transactions a no-op
         # still allow things like abortVersion().  This should work