[Zodb-checkins] CVS: Zope3/lib/python/ZODB/tests - MTStorage.py:1.2.14.1 ReadOnlyStorage.py:1.2.14.1 testfsIndex.py:1.4.10.1 BasicStorage.py:1.14.6.3 ConflictResolution.py:1.6.30.2 Corruption.py:1.2.36.1 HistoryStorage.py:1.5.24.1 IteratorStorage.py:1.4.24.1 StorageTestBase.py:1.9.6.2 Synchronization.py:1.2.36.2 TransactionalUndoStorage.py:1.13.24.1 TransactionalUndoVersionStorage.py:1.4.66.2 VersionStorage.py:1.11.10.1 speed.py:1.1.88.1 testFileStorage.py:1.13.12.1 testMappingStorage.py:1.1.14.1 testTransaction.py:1.2.40.1
Jeremy Hylton
jeremy@zope.com
Sat, 9 Mar 2002 00:33:35 -0500
Update of /cvs-repository/Zope3/lib/python/ZODB/tests
In directory cvs.zope.org:/tmp/cvs-serv13221
Modified Files:
Tag: Zope-3x-branch
BasicStorage.py ConflictResolution.py Corruption.py
HistoryStorage.py IteratorStorage.py StorageTestBase.py
Synchronization.py TransactionalUndoStorage.py
TransactionalUndoVersionStorage.py VersionStorage.py speed.py
testFileStorage.py testMappingStorage.py testTransaction.py
Added Files:
Tag: Zope-3x-branch
MTStorage.py ReadOnlyStorage.py testfsIndex.py
Log Message:
Merge ZODB changes from Zope2 HEAD.
=== Added File Zope3/lib/python/ZODB/tests/MTStorage.py ===
import random
import threading
import time
import ZODB
from Persistence import PersistentMapping
from ZODB.tests.StorageTestBase \
import StorageTestBase, zodb_pickle, zodb_unpickle, handle_serials
from ZODB.tests.MinPO import MinPO
from ZODB.Transaction import Transaction
from ZODB.POSException import ConflictError
SHORT_DELAY = 0.01
def sort(l):
"Sort a list in place and return it."
l.sort()
return l
class ZODBClientThread(threading.Thread):
__super_init = threading.Thread.__init__
def __init__(self, db, test, commits=10, delay=SHORT_DELAY):
self.__super_init()
self.db = db
self.test = test
self.commits = commits
self.delay = delay
def run(self):
conn = self.db.open()
root = conn.root()
d = self.get_thread_dict(root)
if d is None:
self.test.fail()
else:
for i in range(self.commits):
self.commit(d, i)
self.test.assertEqual(sort(d.keys()), range(self.commits))
def commit(self, d, num):
d[num] = time.time()
time.sleep(self.delay)
get_transaction().commit()
time.sleep(self.delay)
def get_thread_dict(self, root):
name = self.getName()
# arbitrarily limit to 10 re-tries
for i in range(10):
try:
m = PersistentMapping()
root[name] = m
get_transaction().commit()
break
except ConflictError, err:
get_transaction().abort()
for i in range(10):
try:
return root.get(name)
except ConflictError, err:
get_transaction().abort()
class StorageClientThread(threading.Thread):
__super_init = threading.Thread.__init__
def __init__(self, storage, test, commits=10, delay=SHORT_DELAY):
self.__super_init()
self.storage = storage
self.test = test
self.commits = commits
self.delay = delay
self.oids = {}
def run(self):
for i in range(self.commits):
self.dostore(i)
self.check()
def check(self):
for oid, revid in self.oids.items():
data, serial = self.storage.load(oid, '')
self.test.assertEqual(serial, revid)
obj = zodb_unpickle(data)
self.test.assertEqual(obj.value[0], self.getName())
def pause(self):
time.sleep(self.delay)
def oid(self):
oid = self.storage.new_oid()
self.oids[oid] = None
return oid
def dostore(self, i):
data = zodb_pickle(MinPO((self.getName(), i)))
t = Transaction()
oid = self.oid()
self.pause()
self.storage.tpc_begin(t)
self.pause()
# Always create a new object, signified by None for revid
r1 = self.storage.store(oid, None, data, '', t)
self.pause()
r2 = self.storage.tpc_vote(t)
self.pause()
self.storage.tpc_finish(t)
self.pause()
revid = handle_serials(oid, r1, r2)
self.oids[oid] = revid
class ExtStorageClientThread(StorageClientThread):
def run(self):
# pick some other storage ops to execute
ops = [getattr(self, meth) for meth in dir(ExtStorageClientThread)
if meth.startswith('do_')]
assert ops, "Didn't find an storage ops in %s" % self.storage
# do a store to guarantee there's at least one oid in self.oids
self.dostore(0)
for i in range(self.commits - 1):
meth = random.choice(ops)
meth()
self.dostore(i)
self.check()
def pick_oid(self):
return random.choice(self.oids.keys())
def do_load(self):
oid = self.pick_oid()
self.storage.load(oid, '')
def do_loadSerial(self):
oid = self.pick_oid()
self.storage.loadSerial(oid, self.oids[oid])
def do_modifiedInVersion(self):
oid = self.pick_oid()
self.storage.modifiedInVersion(oid)
def do_undoLog(self):
self.storage.undoLog(0, -20)
def do_iterator(self):
try:
iter = self.storage.iterator()
except AttributeError:
# XXX It's hard to detect that a ZEO ClientStorage
# doesn't have this method, but does have all the others.
return
for obj in iter:
pass
class MTStorage:
"Test a storage with multiple client threads executing concurrently."
def _checkNThreads(self, n, constructor, *args):
threads = [constructor(*args) for i in range(n)]
for t in threads:
t.start()
for t in threads:
t.join()
def check2ZODBThreads(self):
db = ZODB.DB(self._storage)
self._checkNThreads(2, ZODBClientThread, db, self)
def check7ZODBThreads(self):
db = ZODB.DB(self._storage)
self._checkNThreads(7, ZODBClientThread, db, self)
def check2StorageThreads(self):
self._checkNThreads(2, StorageClientThread, self._storage, self)
def check7StorageThreads(self):
self._checkNThreads(7, StorageClientThread, self._storage, self)
def check4ExtStorageThread(self):
self._checkNThreads(4, ExtStorageClientThread, self._storage, self)
=== Added File Zope3/lib/python/ZODB/tests/ReadOnlyStorage.py ===
from ZODB.POSException import ReadOnlyError
from ZODB.Transaction import Transaction
class ReadOnlyStorage:
def _create_data(self):
# test a read-only storage that already has some data
self.oids = {}
for i in range(10):
oid = self._storage.new_oid()
revid = self._dostore(oid)
self.oids[oid] = revid
def _make_readonly(self):
self._storage.close()
self.open(read_only=1)
self.assert_(self._storage.isReadOnly())
def checkReadMethods(self):
self._create_data()
self._make_readonly()
# XXX not going to bother checking all read methods
for oid in self.oids.keys():
data, revid = self._storage.load(oid, '')
self.assertEqual(revid, self.oids[oid])
self.assert_(not self._storage.modifiedInVersion(oid))
_data = self._storage.loadSerial(oid, revid)
self.assertEqual(data, _data)
def checkWriteMethods(self):
self._make_readonly()
self.assertRaises(ReadOnlyError, self._storage.new_oid)
self.assertRaises(ReadOnlyError, self._storage.undo,
'\000' * 8)
t = Transaction()
self._storage.tpc_begin(t)
self.assertRaises(ReadOnlyError, self._storage.abortVersion,
'', t)
self._storage.tpc_abort(t)
t = Transaction()
self._storage.tpc_begin(t)
self.assertRaises(ReadOnlyError, self._storage.commitVersion,
'', '', t)
self._storage.tpc_abort(t)
t = Transaction()
self._storage.tpc_begin(t)
self.assertRaises(ReadOnlyError, self._storage.store,
'\000' * 8, None, '', '', t)
self._storage.tpc_abort(t)
if self._storage.supportsTransactionalUndo():
t = Transaction()
self._storage.tpc_begin(t)
self.assertRaises(ReadOnlyError, self._storage.transactionalUndo,
'\000' * 8, t)
self._storage.tpc_abort(t)
=== Added File Zope3/lib/python/ZODB/tests/testfsIndex.py ===
import unittest, sys
from ZODB.fsIndex import fsIndex
from ZODB.utils import p64
class Test(unittest.TestCase):
def testInserts(self):
index=fsIndex()
for i in range(200):
index[p64(i*1000)]=(i*1000L+1)
for i in range(0,200):
self.assertEqual((i,index[p64(i*1000)]), (i,(i*1000L+1)))
self.assertEqual(len(index), 200)
key=p64(2000)
self.assertEqual(index.get(key), 2001)
key=p64(2001)
self.assertEqual(index.get(key), None)
self.assertEqual(index.get(key, ''), '')
# self.failUnless(len(index._data) > 1)
def testUpdate(self):
index=fsIndex()
d={}
for i in range(200):
d[p64(i*1000)]=(i*1000L+1)
index.update(d)
for i in range(400,600):
d[p64(i*1000)]=(i*1000L+1)
index.update(d)
for i in range(100, 500):
d[p64(i*1000)]=(i*1000L+2)
index.update(d)
self.assertEqual(index.get(p64(2000)), 2001)
self.assertEqual(index.get(p64(599000)), 599001)
self.assertEqual(index.get(p64(399000)), 399002)
self.assertEqual(len(index), 600)
def test_suite():
loader=unittest.TestLoader()
return loader.loadTestsFromTestCase(Test)
if __name__=='__main__':
unittest.TextTestRunner().run(test_suite())
=== Zope3/lib/python/ZODB/tests/BasicStorage.py 1.14.6.2 => 1.14.6.3 ===
from ZODB.tests.MinPO import MinPO
-from ZODB.tests.StorageTestBase import zodb_unpickle, zodb_pickle
+from ZODB.tests.StorageTestBase \
+ import zodb_unpickle, zodb_pickle, handle_serials
ZERO = '\0'*8
@@ -31,14 +32,15 @@
class BasicStorage:
def checkBasics(self):
- self._storage.tpc_begin(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
# This should simply return
- self._storage.tpc_begin(self._transaction)
+ self._storage.tpc_begin(t)
# Aborting is easy
- self._storage.tpc_abort(self._transaction)
+ self._storage.tpc_abort(t)
# Test a few expected exceptions when we're doing operations giving a
# different Transaction object than the one we've begun on.
- self._storage.tpc_begin(self._transaction)
+ self._storage.tpc_begin(t)
self.assertRaises(
POSException.StorageTransactionError,
self._storage.store,
@@ -77,12 +79,12 @@
POSException.StorageTransactionError,
self._storage.store,
0, 1, 2, 3, Transaction())
- self._storage.tpc_abort(self._transaction)
+ self._storage.tpc_abort(t)
def checkSerialIsNoneForInitialRevision(self):
eq = self.assertEqual
oid = self._storage.new_oid()
- txn = self._transaction
+ txn = Transaction()
self._storage.tpc_begin(txn)
# Use None for serial. Don't use _dostore() here because that coerces
# serial=None to serial=ZERO.
@@ -90,7 +92,7 @@
'', txn)
r2 = self._storage.tpc_vote(txn)
self._storage.tpc_finish(txn)
- newrevid = self._handle_serials(oid, r1, r2)
+ newrevid = handle_serials(oid, r1, r2)
data, revid = self._storage.load(oid, '')
value = zodb_unpickle(data)
eq(value, MinPO(11))
@@ -131,13 +133,12 @@
def checkWriteAfterAbort(self):
oid = self._storage.new_oid()
- self._storage.tpc_begin(self._transaction)
- self._storage.store(oid, ZERO, zodb_pickle(MinPO(5)),
- '', self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
+ self._storage.store(oid, ZERO, zodb_pickle(MinPO(5)), '', t)
# Now abort this transaction
- self._storage.tpc_abort(self._transaction)
+ self._storage.tpc_abort(t)
# Now start all over again
- self._transaction = Transaction()
oid = self._storage.new_oid()
self._dostore(oid=oid, data=MinPO(6))
@@ -145,14 +146,13 @@
oid1 = self._storage.new_oid()
revid1 = self._dostore(oid=oid1, data=MinPO(-2))
oid = self._storage.new_oid()
- self._storage.tpc_begin(self._transaction)
- self._storage.store(oid, ZERO, zodb_pickle(MinPO(5)),
- '', self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
+ self._storage.store(oid, ZERO, zodb_pickle(MinPO(5)), '', t)
# Now abort this transaction
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_abort(self._transaction)
+ self._storage.tpc_vote(t)
+ self._storage.tpc_abort(t)
# Now start all over again
- self._transaction = Transaction()
oid = self._storage.new_oid()
revid = self._dostore(oid=oid, data=MinPO(6))
@@ -186,3 +186,14 @@
# And another one
revid2 = self._dostore(oid, revid=revid1, data=p42)
eq(revid2, self._storage.getSerial(oid))
+
+ def checkTwoArgBegin(self):
+ # XXX how standard is three-argument tpc_begin()?
+ t = Transaction()
+ tid = chr(42) * 8
+ self._storage.tpc_begin(t, tid)
+ oid = self._storage.new_oid()
+ data = zodb_pickle(MinPO(8))
+ self._storage.store(oid, None, data, '', t)
+ self._storage.tpc_vote(t)
+ self._storage.tpc_finish(t)
=== Zope3/lib/python/ZODB/tests/ConflictResolution.py 1.6.30.1 => 1.6.30.2 ===
info = self._storage.undoInfo()
tid = info[1]['id']
- self._storage.tpc_begin(self._transaction)
- self._storage.transactionalUndo(tid, self._transaction)
- self._storage.tpc_finish(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
+ self._storage.transactionalUndo(tid, t)
+ self._storage.tpc_finish(t)
def checkUndoUnresolvable(self):
# This test is based on checkNotUndoable in the
@@ -164,9 +165,9 @@
# Start the undo
info = self._storage.undoInfo()
tid = info[1]['id']
- self._storage.tpc_begin(self._transaction)
- self.assertRaises(UndoError,
- self._storage.transactionalUndo,
- tid, self._transaction)
- self._storage.tpc_abort(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
+ self.assertRaises(UndoError, self._storage.transactionalUndo,
+ tid, t)
+ self._storage.tpc_abort(t)
=== Zope3/lib/python/ZODB/tests/Corruption.py 1.2 => 1.2.36.1 ===
class FileStorageCorruptTests(StorageTestBase):
- __super_setUp = StorageTestBase.setUp
- __super_tearDown = StorageTestBase.tearDown
def setUp(self):
self.path = tempfile.mktemp()
self._storage = ZODB.FileStorage.FileStorage(self.path, create=1)
- self.__super_setUp()
def tearDown(self):
- self.__super_tearDown()
+ self._storage.close()
for ext in '', '.old', '.tmp', '.lock', '.index':
path = self.path + ext
if os.path.exists(path):
=== Zope3/lib/python/ZODB/tests/HistoryStorage.py 1.5 => 1.5.24.1 ===
"""
+from ZODB.Transaction import Transaction
from ZODB.tests.MinPO import MinPO
from ZODB.tests.StorageTestBase import zodb_unpickle
@@ -111,10 +112,11 @@
revid6 = self._dostore(oid, revid=revid5, data=MinPO(16),
version=version)
# Now commit the version
- self._storage.tpc_begin(self._transaction)
- oids = self._storage.commitVersion(version, '', self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
+ oids = self._storage.commitVersion(version, '', t)
+ self._storage.tpc_vote(t)
+ self._storage.tpc_finish(t)
# After consultation with Jim, we agreed that the semantics of
# revision id's after a version commit is that the committed object
# gets a new serial number (a.k.a. revision id). Note that
@@ -168,10 +170,11 @@
revid6 = self._dostore(oid, revid=revid5, data=MinPO(16),
version=version)
# Now commit the version
- self._storage.tpc_begin(self._transaction)
- oids = self._storage.abortVersion(version, self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
+ oids = self._storage.abortVersion(version, t)
+ self._storage.tpc_vote(t)
+ self._storage.tpc_finish(t)
# After consultation with Jim, we agreed that the semantics of
# revision id's after a version commit is that the committed object
# gets a new serial number (a.k.a. revision id). Note that
=== Zope3/lib/python/ZODB/tests/IteratorStorage.py 1.4 => 1.4.24.1 ===
from ZODB.tests.MinPO import MinPO
from ZODB.tests.StorageTestBase import zodb_unpickle
-
+from ZODB.utils import U64, p64
+from ZODB.Transaction import Transaction
-class IteratorStorage:
- def checkSimpleIteration(self):
+class IteratorCompare:
+
+ def iter_verify(self, txniter, revids, val0):
eq = self.assertEqual
- # Store a bunch of revisions of a single object
- oid = self._storage.new_oid()
- revid1 = self._dostore(oid, data=MinPO(11))
- revid2 = self._dostore(oid, revid=revid1, data=MinPO(12))
- revid3 = self._dostore(oid, revid=revid2, data=MinPO(13))
- # Now iterate over all the transactions
- val = 11
- txniter = self._storage.iterator()
- for reciter, revid in zip(txniter, (revid1, revid2, revid3)):
+ oid = self._oid
+ val = val0
+ for reciter, revid in zip(txniter, revids + [None]):
eq(reciter.tid, revid)
for rec in reciter:
eq(rec.oid, oid)
@@ -28,3 +24,147 @@
eq(rec.version, '')
eq(zodb_unpickle(rec.data), MinPO(val))
val = val + 1
+ eq(val, val0 + len(revids))
+
+class IteratorStorage(IteratorCompare):
+
+ def checkSimpleIteration(self):
+ # Store a bunch of revisions of a single object
+ self._oid = oid = self._storage.new_oid()
+ revid1 = self._dostore(oid, data=MinPO(11))
+ revid2 = self._dostore(oid, revid=revid1, data=MinPO(12))
+ revid3 = self._dostore(oid, revid=revid2, data=MinPO(13))
+ # Now iterate over all the transactions and compare carefully
+ txniter = self._storage.iterator()
+ self.iter_verify(txniter, [revid1, revid2, revid3], 11)
+
+ def checkClose(self):
+ self._oid = oid = self._storage.new_oid()
+ revid1 = self._dostore(oid, data=MinPO(11))
+ txniter = self._storage.iterator()
+ txniter.close()
+ self.assertRaises(IOError, txniter.__getitem__, 0)
+
+ def checkVersionIterator(self):
+ if not self._storage.supportsVersions():
+ return
+ self._dostore()
+ self._dostore(version='abort')
+ self._dostore()
+ self._dostore(version='abort')
+ t = Transaction()
+ self._storage.tpc_begin(t)
+ self._storage.abortVersion('abort', t)
+ self._storage.tpc_vote(t)
+ self._storage.tpc_finish(t)
+
+ self._dostore(version='commit')
+ self._dostore()
+ self._dostore(version='commit')
+ t = Transaction()
+ self._storage.tpc_begin(t)
+ self._storage.commitVersion('commit', '', t)
+ self._storage.tpc_vote(t)
+ self._storage.tpc_finish(t)
+
+ txniter = self._storage.iterator()
+ for trans in txniter:
+ for data in trans:
+ pass
+
+ def checkUndoZombieNonVersion(self):
+ if not hasattr(self._storage, 'supportsTransactionalUndo'):
+ return
+ if not self._storage.supportsTransactionalUndo():
+ return
+
+ oid = self._storage.new_oid()
+ revid = self._dostore(oid, data=MinPO(94))
+ # Get the undo information
+ info = self._storage.undoInfo()
+ tid = info[0]['id']
+ # Undo the creation of the object, rendering it a zombie
+ t = Transaction()
+ self._storage.tpc_begin(t)
+ oids = self._storage.transactionalUndo(tid, t)
+ self._storage.tpc_vote(t)
+ self._storage.tpc_finish(t)
+ # Now attempt to iterator over the storage
+ iter = self._storage.iterator()
+ for txn in iter:
+ for rec in txn:
+ pass
+
+ # The last transaction performed an undo of the transaction that
+ # created object oid. (As Barry points out, the object is now in the
+ # George Bailey state.) Assert that the final data record contains
+ # None in the data attribute.
+ self.assertEqual(rec.oid, oid)
+ self.assertEqual(rec.data, None)
+
+
+class ExtendedIteratorStorage(IteratorCompare):
+
+ def checkExtendedIteration(self):
+ # Store a bunch of revisions of a single object
+ self._oid = oid = self._storage.new_oid()
+ revid1 = self._dostore(oid, data=MinPO(11))
+ revid2 = self._dostore(oid, revid=revid1, data=MinPO(12))
+ revid3 = self._dostore(oid, revid=revid2, data=MinPO(13))
+ revid4 = self._dostore(oid, revid=revid3, data=MinPO(14))
+ # Note that the end points are included
+ # Iterate over all of the transactions with explicit start/stop
+ txniter = self._storage.iterator(revid1, revid4)
+ self.iter_verify(txniter, [revid1, revid2, revid3, revid4], 11)
+ # Iterate over some of the transactions with explicit start
+ txniter = self._storage.iterator(revid3)
+ self.iter_verify(txniter, [revid3, revid4], 13)
+ # Iterate over some of the transactions with explicit stop
+ txniter = self._storage.iterator(None, revid2)
+ self.iter_verify(txniter, [revid1, revid2], 11)
+ # Iterate over some of the transactions with explicit start+stop
+ txniter = self._storage.iterator(revid2, revid3)
+ self.iter_verify(txniter, [revid2, revid3], 12)
+ # Specify an upper bound somewhere in between values
+ revid3a = p64((U64(revid3) + U64(revid4)) / 2)
+ txniter = self._storage.iterator(revid2, revid3a)
+ self.iter_verify(txniter, [revid2, revid3], 12)
+ # Specify a lower bound somewhere in between values.
+ # revid2 == revid1+1 is very likely on Windows. Adding 1 before
+ # dividing ensures that "the midpoint" we compute is strictly larger
+ # than revid1.
+ revid1a = p64((U64(revid1) + 1 + U64(revid2)) / 2)
+ assert revid1 < revid1a
+ txniter = self._storage.iterator(revid1a, revid3a)
+ self.iter_verify(txniter, [revid2, revid3], 12)
+ # Specify an empty range
+ txniter = self._storage.iterator(revid3, revid2)
+ self.iter_verify(txniter, [], 13)
+ # Specify a singleton range
+ txniter = self._storage.iterator(revid3, revid3)
+ self.iter_verify(txniter, [revid3], 13)
+
+class IteratorDeepCompare:
+ def compare(self, storage1, storage2):
+ eq = self.assertEqual
+ iter1 = storage1.iterator()
+ iter2 = storage2.iterator()
+ for txn1, txn2 in zip(iter1, iter2):
+ eq(txn1.tid, txn2.tid)
+ eq(txn1.status, txn2.status)
+ eq(txn1.user, txn2.user)
+ eq(txn1.description, txn2.description)
+ eq(txn1._extension, txn2._extension)
+ for rec1, rec2 in zip(txn1, txn2):
+ eq(rec1.oid, rec2.oid)
+ eq(rec1.serial, rec2.serial)
+ eq(rec1.version, rec2.version)
+ eq(rec1.data, rec2.data)
+ # Make sure there are no more records left in rec1 and rec2,
+ # meaning they were the same length.
+ self.assertRaises(IndexError, txn1.next)
+ self.assertRaises(IndexError, txn2.next)
+ # Make sure ther are no more records left in txn1 and txn2, meaning
+ # they were the same length
+ self.assertRaises(IndexError, iter1.next)
+ self.assertRaises(IndexError, iter2.next)
=== Zope3/lib/python/ZODB/tests/StorageTestBase.py 1.9.6.1 => 1.9.6.2 ===
return inst
+def handle_all_serials(oid, *args):
+ """Return dict of oid to serialno from store() and tpc_vote().
+
+ Raises an exception if one of the calls raised an exception.
+
+ The storage interface got complicated when ZEO was introduced.
+ Any individual store() call can return None or a sequence of
+ 2-tuples where the 2-tuple is either oid, serialno or an
+ exception to be raised by the client.
+
+ The original interface just returned the serialno for the
+ object.
+ """
+ d = {}
+ for arg in args:
+ if isinstance(arg, types.StringType):
+ d[oid] = arg
+ elif arg is None:
+ pass
+ else:
+ for oid, serial in arg:
+ if not isinstance(serial, types.StringType):
+ raise serial # error from ZEO server
+ d[oid] = serial
+ return d
+
+def handle_serials(oid, *args):
+ """Return the serialno for oid based on multiple return values.
+
+ A helper for function _handle_all_serials().
+ """
+ args = (oid,) + args
+ return apply(handle_all_serials, args)[oid]
+
def import_helper(name):
mod = __import__(name)
- for part in string.split(name, ".")[1:]:
- mod = getattr(mod, part)
- return mod
+ return sys.modules[name]
class StorageTestBase(unittest.TestCase):
+
+ # XXX It would be simpler if concrete tests didn't need to extend
+ # setUp() and tearDown().
+
def setUp(self):
# You need to override this with a setUp that creates self._storage
- self._transaction = Transaction()
+ self._storage = None
def _close(self):
# You should override this if closing your storage requires additional
# shutdown operations.
- self._transaction.abort()
- self._storage.close()
+ if self._storage is not None:
+ self._storage.close()
def tearDown(self):
self._close()
- def _handle_all_serials(self, oid, *args):
- """Return dict of oid to serialno from store() and tpc_vote().
-
- Raises an exception if one of the calls raised an exception.
-
- The storage interface got complicated when ZEO was introduced.
- Any individual store() call can return None or a sequence of
- 2-tuples where the 2-tuple is either oid, serialno or an
- exception to be raised by the client.
-
- The original interface just returned the serialno for the
- object.
- """
- d = {}
- for arg in args:
- if isinstance(arg, types.StringType):
- d[oid] = arg
- elif arg is None:
- pass
- else:
- for oid, serial in arg:
- if not isinstance(serial, types.StringType):
- raise arg
- d[oid] = serial
- return d
-
- def _handle_serials(self, oid, *args):
- """Return the serialno for oid based on multiple return values.
-
- A helper for function _handle_all_serials().
- """
- args = (oid,) + args
- return apply(self._handle_all_serials, args)[oid]
-
def _dostore(self, oid=None, revid=None, data=None, version=None,
- already_pickled=0):
+ already_pickled=0, user=None, description=None):
"""Do a complete storage transaction. The defaults are:
- oid=None, ask the storage for a new oid
@@ -146,14 +148,24 @@
if version is None:
version = ''
# Begin the transaction
- self._storage.tpc_begin(self._transaction)
- # Store an object
- r1 = self._storage.store(oid, revid, data, version,
- self._transaction)
- # Finish the transaction
- r2 = self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._transaction)
- return self._handle_serials(oid, r1, r2)
+ t = Transaction()
+ if user is not None:
+ t.user = user
+ if description is not None:
+ t.description = description
+ try:
+ self._storage.tpc_begin(t)
+ # Store an object
+ r1 = self._storage.store(oid, revid, data, version, t)
+ # Finish the transaction
+ r2 = self._storage.tpc_vote(t)
+ revid = handle_serials(oid, r1, r2)
+ self._storage.tpc_finish(t)
+ except:
+ self._storage.tpc_abort(t)
+ raise
+ return revid
- def _dostoreNP(self, oid=None, revid=None, data=None, version=None):
+ 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)
=== Zope3/lib/python/ZODB/tests/Synchronization.py 1.2.36.1 => 1.2.36.2 ===
def verifyWrongTrans(self, callable, *args):
- self._storage.tpc_begin(self._transaction)
- args = (StorageTransactionError, callable) + args
- apply(self.assertRaises, args)
+ t = Transaction()
+ self._storage.tpc_begin(t)
+ self.assertRaises(StorageTransactionError, callable, *args)
+ self._storage.tpc_abort(t)
def checkAbortVersionNotCommitting(self):
self.verifyNotCommitting(self._storage.abortVersion,
- VERSION, self._transaction)
+ VERSION, Transaction())
def checkAbortVersionWrongTrans(self):
self.verifyWrongTrans(self._storage.abortVersion,
@@ -81,7 +82,7 @@
def checkCommitVersionNotCommitting(self):
self.verifyNotCommitting(self._storage.commitVersion,
- VERSION, "", self._transaction)
+ VERSION, "", Transaction())
def checkCommitVersionWrongTrans(self):
self.verifyWrongTrans(self._storage.commitVersion,
@@ -90,7 +91,7 @@
def checkStoreNotCommitting(self):
self.verifyNotCommitting(self._storage.store,
- OID, SERIALNO, "", "", self._transaction)
+ OID, SERIALNO, "", "", Transaction())
def checkStoreWrongTrans(self):
self.verifyWrongTrans(self._storage.store,
@@ -107,18 +108,26 @@
self._storage.tpc_abort(Transaction())
def checkAbortWrongTrans(self):
- self._storage.tpc_begin(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
self._storage.tpc_abort(Transaction())
+ self._storage.tpc_abort(t)
def checkFinishNotCommitting(self):
- self._storage.tpc_finish(Transaction())
+ t = Transaction()
+ self._storage.tpc_finish(t)
+ self._storage.tpc_abort(t)
def checkFinishWrongTrans(self):
- self._storage.tpc_begin(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
self._storage.tpc_finish(Transaction())
+ self._storage.tpc_abort(t)
def checkBeginCommitting(self):
- self._storage.tpc_begin(self._transaction)
- self._storage.tpc_begin(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
+ self._storage.tpc_begin(t)
+ self._storage.tpc_abort(t)
# XXX how to check undo?
=== Zope3/lib/python/ZODB/tests/TransactionalUndoStorage.py 1.13 => 1.13.24.1 ===
import types
from ZODB import POSException
+from ZODB.Transaction import Transaction
from ZODB.tests.MinPO import MinPO
from ZODB.tests.StorageTestBase import zodb_pickle, zodb_unpickle
@@ -37,13 +38,14 @@
def _multi_obj_transaction(self, objs):
newrevs = {}
- self._storage.tpc_begin(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
self._transaction_begin()
for oid, rev, data in objs:
- self._transaction_store(oid, rev, data, '', self._transaction)
+ self._transaction_store(oid, rev, data, '', t)
newrevs[oid] = None
- self._transaction_vote(self._transaction)
- self._storage.tpc_finish(self._transaction)
+ self._transaction_vote(t)
+ self._storage.tpc_finish(t)
for oid in newrevs.keys():
newrevs[oid] = self._transaction_newserial(oid)
return newrevs
@@ -58,11 +60,12 @@
info = self._storage.undoInfo()
tid = info[0]['id']
# Now start an undo transaction
- self._transaction.note('undo1')
- self._storage.tpc_begin(self._transaction)
- oids = self._storage.transactionalUndo(tid, self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._transaction)
+ t = Transaction()
+ t.note('undo1')
+ 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, '')
@@ -70,11 +73,12 @@
# Do another one
info = self._storage.undoInfo()
tid = info[2]['id']
- self._transaction.note('undo2')
- self._storage.tpc_begin(self._transaction)
- oids = self._storage.transactionalUndo(tid, self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._transaction)
+ t = Transaction()
+ t.note('undo2')
+ 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, '')
@@ -82,11 +86,12 @@
# Try to undo the first record
info = self._storage.undoInfo()
tid = info[4]['id']
- self._transaction.note('undo3')
- self._storage.tpc_begin(self._transaction)
- oids = self._storage.transactionalUndo(tid, self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._transaction)
+ t = Transaction()
+ t.note('undo3')
+ 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)
@@ -96,10 +101,11 @@
# And now let's try to redo the object's creation
info = self._storage.undoInfo()
tid = info[0]['id']
- self._storage.tpc_begin(self._transaction)
- oids = self._storage.transactionalUndo(tid, self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._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, '')
@@ -113,10 +119,11 @@
# Undo the last transaction
info = self._storage.undoInfo()
tid = info[0]['id']
- self._storage.tpc_begin(self._transaction)
- oids = self._storage.transactionalUndo(tid, self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._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, '')
@@ -125,10 +132,11 @@
# creation. Let's undo the object creation.
info = self._storage.undoInfo()
tid = info[2]['id']
- self._storage.tpc_begin(self._transaction)
- oids = self._storage.transactionalUndo(tid, self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._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)
self.assertRaises(KeyError, self._storage.load, oid, '')
@@ -141,10 +149,11 @@
# Undo the last transaction
info = self._storage.undoInfo()
tid = info[0]['id']
- self._storage.tpc_begin(self._transaction)
- oids = self._storage.transactionalUndo(tid, self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._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, '')
@@ -153,10 +162,11 @@
# creation. Let's redo the last undo
info = self._storage.undoInfo()
tid = info[0]['id']
- self._storage.tpc_begin(self._transaction)
- oids = self._storage.transactionalUndo(tid, self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._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, '')
@@ -171,26 +181,28 @@
oid2 = self._storage.new_oid()
revid1 = revid2 = ZERO
# Store two objects in the same transaction
- self._storage.tpc_begin(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
self._transaction_begin()
- self._transaction_store(oid1, revid1, p31, '', self._transaction)
- self._transaction_store(oid2, revid2, p51, '', self._transaction)
+ self._transaction_store(oid1, revid1, p31, '', t)
+ self._transaction_store(oid2, revid2, p51, '', t)
# Finish the transaction
- self._transaction_vote(self._transaction)
+ self._transaction_vote(t)
revid1 = self._transaction_newserial(oid1)
revid2 = self._transaction_newserial(oid2)
- self._storage.tpc_finish(self._transaction)
+ self._storage.tpc_finish(t)
eq(revid1, revid2)
# Update those same two objects
- self._storage.tpc_begin(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
self._transaction_begin()
- self._transaction_store(oid1, revid1, p32, '', self._transaction)
- self._transaction_store(oid2, revid2, p52, '', self._transaction)
+ self._transaction_store(oid1, revid1, p32, '', t)
+ self._transaction_store(oid2, revid2, p52, '', t)
# Finish the transaction
- self._transaction_vote(self._transaction)
+ self._transaction_vote(t)
revid1 = self._transaction_newserial(oid1)
revid2 = self._transaction_newserial(oid2)
- self._storage.tpc_finish(self._transaction)
+ self._storage.tpc_finish(t)
eq(revid1, revid2)
# Make sure the objects have the current value
data, revid1 = self._storage.load(oid1, '')
@@ -200,10 +212,11 @@
# Now attempt to undo the transaction containing two objects
info = self._storage.undoInfo()
tid = info[0]['id']
- self._storage.tpc_begin(self._transaction)
- oids = self._storage.transactionalUndo(tid, self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._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), 2)
self.failUnless(oid1 in oids)
self.failUnless(oid2 in oids)
@@ -249,14 +262,15 @@
info = self._storage.undoInfo()
tid = info[0]['id']
tid1 = info[1]['id']
- self._storage.tpc_begin(self._transaction)
- oids = self._storage.transactionalUndo(tid, self._transaction)
- oids1 = self._storage.transactionalUndo(tid1, self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
+ oids = self._storage.transactionalUndo(tid, t)
+ oids1 = self._storage.transactionalUndo(tid1, t)
+ self._storage.tpc_vote(t)
+ self._storage.tpc_finish(t)
# We get the finalization stuff called an extra time:
-## self._storage.tpc_vote(self._transaction)
-## self._storage.tpc_finish(self._transaction)
+## self._storage.tpc_vote(t)
+## self._storage.tpc_finish(t)
eq(len(oids), 2)
eq(len(oids1), 2)
unless(oid1 in oids)
@@ -268,10 +282,11 @@
# Now try to undo the one we just did to undo, whew
info = self._storage.undoInfo()
tid = info[0]['id']
- self._storage.tpc_begin(self._transaction)
- oids = self._storage.transactionalUndo(tid, self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._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), 2)
unless(oid1 in oids)
unless(oid2 in oids)
@@ -292,23 +307,25 @@
revid1 = self._dostore(oid1, data=p31, already_pickled=1)
revid2 = self._dostore(oid2, data=p51, already_pickled=1)
# Update those same two objects
- self._storage.tpc_begin(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
self._transaction_begin()
- self._transaction_store(oid1, revid1, p32, '', self._transaction)
- self._transaction_store(oid2, revid2, p52, '', self._transaction)
+ self._transaction_store(oid1, revid1, p32, '', t)
+ self._transaction_store(oid2, revid2, p52, '', t)
# Finish the transaction
- self._transaction_vote(self._transaction)
- self._storage.tpc_finish(self._transaction)
+ self._transaction_vote(t)
+ self._storage.tpc_finish(t)
revid1 = self._transaction_newserial(oid1)
revid2 = self._transaction_newserial(oid2)
eq(revid1, revid2)
# Now attempt to undo the transaction containing two objects
info = self._storage.undoInfo()
tid = info[0]['id']
- self._storage.tpc_begin(self._transaction)
- oids = self._storage.transactionalUndo(tid, self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._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), 2)
self.failUnless(oid1 in oids)
self.failUnless(oid2 in oids)
@@ -318,13 +335,14 @@
eq(zodb_unpickle(data), MinPO(51))
# Like the above, but this time, the second transaction contains only
# one object.
- self._storage.tpc_begin(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
self._transaction_begin()
- self._transaction_store(oid1, revid1, p33, '', self._transaction)
- self._transaction_store(oid2, revid2, p53, '', self._transaction)
+ self._transaction_store(oid1, revid1, p33, '', t)
+ self._transaction_store(oid2, revid2, p53, '', t)
# Finish the transaction
- self._transaction_vote(self._transaction)
- self._storage.tpc_finish(self._transaction)
+ self._transaction_vote(t)
+ self._storage.tpc_finish(t)
revid1 = self._transaction_newserial(oid1)
revid2 = self._transaction_newserial(oid2)
eq(revid1, revid2)
@@ -334,10 +352,11 @@
# Now attempt to undo the transaction containing two objects
info = self._storage.undoInfo()
tid = info[1]['id']
- self._storage.tpc_begin(self._transaction)
- oids = self._storage.transactionalUndo(tid, self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._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)
self.failUnless(oid1 in oids)
self.failUnless(not oid2 in oids)
@@ -357,11 +376,12 @@
# Start the undo
info = self._storage.undoInfo()
tid = info[1]['id']
- self._storage.tpc_begin(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
self.assertRaises(POSException.UndoError,
self._storage.transactionalUndo,
- tid, self._transaction)
- self._storage.tpc_abort(self._transaction)
+ tid, t)
+ self._storage.tpc_abort(t)
# Now have more fun: object1 and object2 are in the same transaction,
# which we'll try to undo to, but one of them has since modified in
# different transaction, so the undo should fail.
@@ -372,12 +392,13 @@
p81, p82, p91, p92 = map(zodb_pickle,
map(MinPO, (81, 82, 91, 92)))
- self._storage.tpc_begin(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
self._transaction_begin()
- self._transaction_store(oid1, revid1, p81, '', self._transaction)
- self._transaction_store(oid2, revid2, p91, '', self._transaction)
- self._transaction_vote(self._transaction)
- self._storage.tpc_finish(self._transaction)
+ self._transaction_store(oid1, revid1, p81, '', t)
+ self._transaction_store(oid2, revid2, p91, '', t)
+ self._transaction_vote(t)
+ self._storage.tpc_finish(t)
revid1 = self._transaction_newserial(oid1)
revid2 = self._transaction_newserial(oid2)
eq(revid1, revid2)
@@ -394,8 +415,9 @@
self.assertNotEqual(revid2, revid_22)
info = self._storage.undoInfo()
tid = info[1]['id']
- self._storage.tpc_begin(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
self.assertRaises(POSException.UndoError,
self._storage.transactionalUndo,
- tid, self._transaction)
- self._storage.tpc_abort(self._transaction)
+ tid, t)
+ self._storage.tpc_abort(t)
=== Zope3/lib/python/ZODB/tests/TransactionalUndoVersionStorage.py 1.4.66.1 => 1.4.66.2 ===
from ZODB import POSException
+from ZODB.Transaction import Transaction
from ZODB.tests.MinPO import MinPO
from ZODB.tests.StorageTestBase import zodb_unpickle
@@ -17,10 +18,11 @@
version=version)
info=self._storage.undoInfo()
tid=info[0]['id']
- self._storage.tpc_begin(self._transaction)
- oids = self._storage.transactionalUndo(tid, self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
+ oids = self._storage.transactionalUndo(tid, t)
+ self._storage.tpc_vote(t)
+ self._storage.tpc_finish(t)
assert len(oids) == 1
assert oids[0] == oid
data, revid = self._storage.load(oid, '')
@@ -30,10 +32,11 @@
assert revid > revid_b and revid > revid_c
assert zodb_unpickle(data) == MinPO(92)
# Now commit the version...
- self._storage.tpc_begin(self._transaction)
- oids = self._storage.commitVersion(version, '', self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
+ oids = self._storage.commitVersion(version, '', t)
+ self._storage.tpc_vote(t)
+ self._storage.tpc_finish(t)
assert len(oids) == 1
assert oids[0] == oid
@@ -48,10 +51,11 @@
# ...and undo the commit
info=self._storage.undoInfo()
tid=info[0]['id']
- self._storage.tpc_begin(self._transaction)
- oids = self._storage.transactionalUndo(tid, self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
+ oids = self._storage.transactionalUndo(tid, t)
+ self._storage.tpc_vote(t)
+ self._storage.tpc_finish(t)
assert len(oids) == 1
assert oids[0] == oid
data, revid = self._storage.load(oid, version)
@@ -59,10 +63,11 @@
data, revid = self._storage.load(oid, '')
assert zodb_unpickle(data) == MinPO(91)
# Now abort the version
- self._storage.tpc_begin(self._transaction)
- oids = self._storage.abortVersion(version, self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
+ oids = self._storage.abortVersion(version, t)
+ self._storage.tpc_vote(t)
+ self._storage.tpc_finish(t)
assert len(oids) == 1
assert oids[0] == oid
# The object should not exist in the version now, but it should exist
@@ -78,10 +83,11 @@
# Now undo the abort
info=self._storage.undoInfo()
tid=info[0]['id']
- self._storage.tpc_begin(self._transaction)
- oids = self._storage.transactionalUndo(tid, self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
+ oids = self._storage.transactionalUndo(tid, t)
+ self._storage.tpc_vote(t)
+ self._storage.tpc_finish(t)
assert len(oids) == 1
assert oids[0] == oid
# And the object should be back in versions 'one' and ''
=== Zope3/lib/python/ZODB/tests/VersionStorage.py 1.11 => 1.11.10.1 ===
from ZODB import POSException
+from ZODB.Transaction import Transaction
from ZODB.tests.MinPO import MinPO
from ZODB.tests.StorageTestBase import zodb_unpickle
@@ -144,10 +145,11 @@
## s1 = self._storage.getSerial(oid)
# Now abort the version -- must be done in a transaction
- self._storage.tpc_begin(self._transaction)
- oids = self._storage.abortVersion(version, self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
+ oids = self._storage.abortVersion(version, t)
+ self._storage.tpc_vote(t)
+ self._storage.tpc_finish(t)
## s2 = self._storage.getSerial(oid)
## eq(s1, s2) # or self.assert(s2 > s1) ?
eq(len(oids), 1)
@@ -159,14 +161,15 @@
eq = self.assertEqual
oid, version = self._setup_version()
# Now abort a bogus version
- self._storage.tpc_begin(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
#JF# The spec is silent on what happens if you abort or commit
#JF# a non-existent version. FileStorage consideres this a noop.
#JF# We can change the spec, but until we do ....
#JF# self.assertRaises(POSException.VersionError,
#JF# self._storage.abortVersion,
- #JF# 'bogus', self._transaction)
+ #JF# 'bogus', t)
# And try to abort the empty version
if (hasattr(self._storage, 'supportsTransactionalUndo')
@@ -174,12 +177,12 @@
# XXX FileStorage used to be broken on this one
self.assertRaises(POSException.VersionError,
self._storage.abortVersion,
- '', self._transaction)
+ '', t)
# But now we really try to abort the version
- oids = self._storage.abortVersion(version, self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._transaction)
+ oids = self._storage.abortVersion(version, 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, '')
@@ -194,19 +197,24 @@
oid1, version1 = self._setup_version('one')
data, revid1 = self._storage.load(oid1, version1)
eq(zodb_unpickle(data), MinPO(54))
- self._storage.tpc_begin(self._transaction)
- self.assertRaises(POSException.VersionCommitError,
- self._storage.commitVersion,
- 'one', 'one', self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
+ try:
+ self.assertRaises(POSException.VersionCommitError,
+ self._storage.commitVersion,
+ 'one', 'one', t)
+ finally:
+ self._storage.tpc_abort(t)
def checkModifyAfterAbortVersion(self):
eq = self.assertEqual
oid, version = self._setup_version()
# Now abort the version
- self._storage.tpc_begin(self._transaction)
- oids = self._storage.abortVersion(version, self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
+ oids = self._storage.abortVersion(version, t)
+ self._storage.tpc_vote(t)
+ self._storage.tpc_finish(t)
# Load the object's current state (which gets us the revid)
data, revid = self._storage.load(oid, '')
# And modify it a few times
@@ -225,10 +233,11 @@
data, revid = self._storage.load(oid, '')
eq(zodb_unpickle(data), MinPO(51))
# Try committing this version to the empty version
- self._storage.tpc_begin(self._transaction)
- oids = self._storage.commitVersion(version, '', self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
+ oids = self._storage.commitVersion(version, '', t)
+ self._storage.tpc_vote(t)
+ self._storage.tpc_finish(t)
data, revid = self._storage.load(oid, '')
eq(zodb_unpickle(data), MinPO(54))
@@ -251,11 +260,12 @@
eq(zodb_unpickle(data), MinPO(51))
# Okay, now let's commit object1 to version2
- self._storage.tpc_begin(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
oids = self._storage.commitVersion(version1, version2,
- self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._transaction)
+ t)
+ self._storage.tpc_vote(t)
+ self._storage.tpc_finish(t)
eq(len(oids), 1)
eq(oids[0], oid1)
data, revid = self._storage.load(oid1, version2)
@@ -286,10 +296,11 @@
eq(zodb_unpickle(data), MinPO(51))
# First, let's abort version1
- self._storage.tpc_begin(self._transaction)
- oids = self._storage.abortVersion(version1, self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
+ oids = self._storage.abortVersion(version1, t)
+ self._storage.tpc_vote(t)
+ self._storage.tpc_finish(t)
eq(len(oids), 1)
eq(oids[0], oid1)
data, revid = self._storage.load(oid1, '')
@@ -310,10 +321,11 @@
data, revid = self._storage.load(oid2, version2)
eq(zodb_unpickle(data), MinPO(54))
# Okay, now let's commit version2 back to the trunk
- self._storage.tpc_begin(self._transaction)
- oids = self._storage.commitVersion(version2, '', self._transaction)
- self._storage.tpc_vote(self._transaction)
- self._storage.tpc_finish(self._transaction)
+ t = Transaction()
+ self._storage.tpc_begin(t)
+ oids = self._storage.commitVersion(version2, '', t)
+ self._storage.tpc_vote(t)
+ self._storage.tpc_finish(t)
eq(len(oids), 1)
eq(oids[0], oid2)
data, revid = self._storage.load(oid1, '')
=== Zope3/lib/python/ZODB/tests/speed.py 1.1 => 1.1.88.1 ===
-#
-# Zope Public License (ZPL) Version 1.0
-# -------------------------------------
-#
-# Copyright (c) Digital Creations. All rights reserved.
-#
-# This license has been certified as Open Source(tm).
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# 1. Redistributions in source code must retain the above copyright
-# notice, this list of conditions, and the following disclaimer.
-#
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions, and the following disclaimer in
-# the documentation and/or other materials provided with the
-# distribution.
-#
-# 3. Digital Creations requests that attribution be given to Zope
-# in any manner possible. Zope includes a "Powered by Zope"
-# button that is installed by default. While it is not a license
-# violation to remove this button, it is requested that the
-# attribution remain. A significant investment has been put
-# into Zope, and this effort will continue if the Zope community
-# continues to grow. This is one way to assure that growth.
-#
-# 4. All advertising materials and documentation mentioning
-# features derived from or use of this software must display
-# the following acknowledgement:
-#
-# "This product includes software developed by Digital Creations
-# for use in the Z Object Publishing Environment
-# (http://www.zope.org/)."
-#
-# In the event that the product being advertised includes an
-# intact Zope distribution (with copyright and license included)
-# then this clause is waived.
-#
-# 5. Names associated with Zope or Digital Creations must not be used to
-# endorse or promote products derived from this software without
-# prior written permission from Digital Creations.
-#
-# 6. Modified redistributions of any form whatsoever must retain
-# the following acknowledgment:
-#
-# "This product includes software developed by Digital Creations
-# for use in the Z Object Publishing Environment
-# (http://www.zope.org/)."
-#
-# Intact (re-)distributions of any official Zope release do not
-# require an external acknowledgement.
-#
-# 7. Modifications are encouraged but must be packaged separately as
-# patches to official Zope releases. Distributions that do not
-# clearly separate the patches from the original work must be clearly
-# labeled as unofficial distributions. Modifications which do not
-# carry the name Zope may be packaged in any form, as long as they
-# conform to all of the clauses above.
-#
-#
-# Disclaimer
-#
-# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
-# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
-# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-# SUCH DAMAGE.
-#
-#
-# This software consists of contributions made by Digital Creations and
-# many individuals on behalf of Digital Creations. Specific
-# attributions are listed in the accompanying credits file.
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
#
##############################################################################
usage="""Test speed of a ZODB storage
=== Zope3/lib/python/ZODB/tests/testFileStorage.py 1.13 => 1.13.12.1 ===
+
import ZODB.FileStorage
import sys, os, unittest
+import errno
+from Transaction import Transaction
from ZODB.tests import StorageTestBase, BasicStorage, \
TransactionalUndoStorage, VersionStorage, \
TransactionalUndoVersionStorage, PackableStorage, \
Synchronization, ConflictResolution, HistoryStorage, \
- IteratorStorage, Corruption, RevisionStorage, PersistentStorage
+ IteratorStorage, Corruption, RevisionStorage, PersistentStorage, \
+ MTStorage, ReadOnlyStorage
class FileStorageTests(
StorageTestBase.StorageTestBase,
@@ -19,7 +24,10 @@
ConflictResolution.ConflictResolvingStorage,
HistoryStorage.HistoryStorage,
IteratorStorage.IteratorStorage,
+ IteratorStorage.ExtendedIteratorStorage,
PersistentStorage.PersistentStorage,
+ MTStorage.MTStorage,
+ ReadOnlyStorage.ReadOnlyStorage
):
def open(self, **kwargs):
@@ -32,19 +40,90 @@
def setUp(self):
self.open(create=1)
- StorageTestBase.StorageTestBase.setUp(self)
def tearDown(self):
- StorageTestBase.StorageTestBase.tearDown(self)
+ self._storage.close()
for ext in '', '.old', '.tmp', '.lock', '.index':
path = 'FileStorageTests.fs' + ext
if os.path.exists(path):
os.remove(path)
+class FileStorageRecoveryTest(
+ StorageTestBase.StorageTestBase,
+ IteratorStorage.IteratorDeepCompare,
+ ):
+
+ def setUp(self):
+ self._storage = ZODB.FileStorage.FileStorage('Source.fs')
+ self._dst = ZODB.FileStorage.FileStorage('Dest.fs')
+
+ def tearDown(self):
+ self._storage.close()
+ self._dst.close()
+ for ext in '', '.old', '.tmp', '.lock', '.index':
+ for fs in 'Source', 'Dest':
+ path = fs + '.fs' + ext
+ try:
+ os.remove(path)
+ except OSError, e:
+ if e.errno <> errno.ENOENT: raise
+
+ 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:trans[i], 1)
+ self.assertEqual(data.oid, oid)
+ self.assertEqual(data.data, None)
+
+
def test_suite():
suite = unittest.makeSuite(FileStorageTests, 'check')
suite2 = unittest.makeSuite(Corruption.FileStorageCorruptTests, 'check')
+ suite3 = unittest.makeSuite(FileStorageRecoveryTest, 'check')
suite.addTest(suite2)
+ suite.addTest(suite3)
return suite
def main():
=== Zope3/lib/python/ZODB/tests/testMappingStorage.py 1.1 => 1.1.14.1 ===
def setUp(self):
self._storage = ZODB.MappingStorage.MappingStorage()
- StorageTestBase.StorageTestBase.setUp(self)
+
+ def tearDown(self):
+ self._storage.close()
def test_suite():
suite = unittest.makeSuite(MappingStorageTests, 'check')
=== Zope3/lib/python/ZODB/tests/testTransaction.py 1.2 => 1.2.40.1 ===
meth = getattr(obj, meth_name)
meth(1)
- get_transaction().commit()
-
+ get_transaction().commit()
+
checkSubSingleCommit = lambda self:\
self.wrap_test(BasicTests, "checkSingleCommit")