[Zodb-checkins] SVN: ZODB/trunk/src/ZODB/ Fixed an undo bug that affects file storages that support blobs in
Jim Fulton
jim at zope.com
Mon Jan 5 14:24:13 EST 2009
Log message for revision 94540:
Fixed an undo bug that affects file storages that support blobs in
special cases involving undo of undo of undo of object additions.
Changed:
U ZODB/trunk/src/ZODB/FileStorage/FileStorage.py
U ZODB/trunk/src/ZODB/tests/testFileStorage.py
-=-
Modified: ZODB/trunk/src/ZODB/FileStorage/FileStorage.py
===================================================================
--- ZODB/trunk/src/ZODB/FileStorage/FileStorage.py 2009-01-05 16:53:07 UTC (rev 94539)
+++ ZODB/trunk/src/ZODB/FileStorage/FileStorage.py 2009-01-05 19:24:12 UTC (rev 94540)
@@ -984,15 +984,19 @@
else:
if self.blob_dir and not p and prev:
- up, userial = self._loadBackTxn(h.oid, prev)
- if ZODB.blob.is_blob_record(up):
- # We're undoing a blob modification operation.
- # We have to copy the blob data
- tmp = ZODB.utils.mktemp(dir=self.fshelper.temp_dir)
- ZODB.utils.cp(
- self.openCommittedBlobFile(h.oid, userial),
- open(tmp, 'wb'))
- self._blob_storeblob(h.oid, self._tid, tmp)
+ try:
+ up, userial = self._loadBackTxn(h.oid, prev)
+ except ZODB.POSException.POSKeyError:
+ pass # It was removed, so no need to copy data
+ else:
+ if ZODB.blob.is_blob_record(up):
+ # We're undoing a blob modification operation.
+ # We have to copy the blob data
+ tmp = ZODB.utils.mktemp(dir=self.fshelper.temp_dir)
+ ZODB.utils.cp(
+ self.openCommittedBlobFile(h.oid, userial),
+ open(tmp, 'wb'))
+ self._blob_storeblob(h.oid, self._tid, tmp)
new = DataHeader(h.oid, self._tid, ipos, otloc, 0, len(p))
Modified: ZODB/trunk/src/ZODB/tests/testFileStorage.py
===================================================================
--- ZODB/trunk/src/ZODB/tests/testFileStorage.py 2009-01-05 16:53:07 UTC (rev 94539)
+++ ZODB/trunk/src/ZODB/tests/testFileStorage.py 2009-01-05 19:24:12 UTC (rev 94540)
@@ -27,18 +27,8 @@
from ZODB.tests import ReadOnlyStorage, RecoveryStorage
from ZODB.tests.StorageTestBase import MinPO, zodb_pickle
-class BaseFileStorageTests(StorageTestBase.StorageTestBase):
-
- def open(self, **kwargs):
- self._storage = ZODB.FileStorage.FileStorage('FileStorageTests.fs',
- **kwargs)
-
- def setUp(self):
- StorageTestBase.StorageTestBase.setUp(self)
- self.open(create=1)
-
class FileStorageTests(
- BaseFileStorageTests,
+ StorageTestBase.StorageTestBase,
BasicStorage.BasicStorage,
TransactionalUndoStorage.TransactionalUndoStorage,
RevisionStorage.RevisionStorage,
@@ -55,6 +45,14 @@
ReadOnlyStorage.ReadOnlyStorage
):
+ def open(self, **kwargs):
+ self._storage = ZODB.FileStorage.FileStorage('FileStorageTests.fs',
+ **kwargs)
+
+ def setUp(self):
+ StorageTestBase.StorageTestBase.setUp(self)
+ self.open(create=1)
+
def checkLongMetadata(self):
s = "X" * 75000
try:
@@ -287,7 +285,14 @@
else:
self.assertNotEqual(next_oid, None)
+class FileStorageTestsWithBlobsEnabled(FileStorageTests):
+ def open(self, **kwargs):
+ if 'blob_dir' not in kwargs:
+ kwargs = kwargs.copy()
+ kwargs['blob_dir'] = 'blobs'
+ return FileStorageTests.open(self, **kwargs)
+
class FileStorageRecoveryTest(
StorageTestBase.StorageTestBase,
RecoveryStorage.RecoveryStorage,
@@ -301,7 +306,6 @@
def tearDown(self):
self._dst.close()
StorageTestBase.StorageTestBase.tearDown(self)
-
def new_dest(self):
return ZODB.FileStorage.FileStorage('Dest.fs')
@@ -332,23 +336,6 @@
pass
-class SlowFileStorageTest(BaseFileStorageTests):
-
- def check10Kstores(self):
- # The _get_cached_serial() method has a special case
- # every 8000 calls. Make sure it gets minimal coverage.
- oids = [[self._storage.new_oid(), None] for i in range(100)]
- for i in range(100):
- t = transaction.Transaction()
- self._storage.tpc_begin(t)
- for j in range(100):
- o = MinPO(j)
- oid, revid = oids[j]
- serial = self._storage.store(oid, revid, zodb_pickle(o), "", t)
- oids[j][1] = serial
- self._storage.tpc_vote(t)
- self._storage.tpc_finish(t)
-
# Raise an exception if the tids in FileStorage fs aren't
# strictly increasing.
def checkIncreasingTids(fs):
@@ -494,7 +481,7 @@
def deal_with_finish_failures():
r"""
-
+
It's really bad to get errors in FileStorage's _finish method, as
that can cause the file storage to be in an inconsistent
state. The data file will be fine, but the internal data
@@ -523,7 +510,7 @@
...
TypeError: <lambda>() takes no arguments (1 given)
-
+
>>> print handler
ZODB.FileStorage CRITICAL
Failure in _finish. Closing.
@@ -559,7 +546,7 @@
>>> conn1.add(conn1.root()[1])
>>> conn1.root()[1].open('w').write('some data')
>>> tm1.commit()
-
+
>>> tm2 = transaction.TransactionManager()
>>> conn2 = db.open(tm2)
>>> f = conn1.root()[1].open()
@@ -586,7 +573,8 @@
suite = unittest.TestSuite()
for klass in [FileStorageTests, Corruption.FileStorageCorruptTests,
FileStorageRecoveryTest, FileStorageNoRestoreRecoveryTest,
- SlowFileStorageTest]:
+ FileStorageTestsWithBlobsEnabled,
+ ]:
suite.addTest(unittest.makeSuite(klass, "check"))
suite.addTest(doctest.DocTestSuite(
setUp=zope.testing.setupstack.setUpDirectory,
More information about the Zodb-checkins
mailing list