Commit 27e353fc authored by Toby Dickenson's avatar Toby Dickenson

New tests covering corner cases in the storage API, derived from code coverage...

New tests covering corner cases in the storage API, derived from code coverage analysis of DirectoryStorage. FileStorage currently fails checkCreationUndoneGetSerial
parent cbfbdf25
......@@ -184,3 +184,56 @@ class BasicStorage:
self._storage.store(oid, None, data, '', t)
self._storage.tpc_vote(t)
self._storage.tpc_finish(t)
def checkLen(self):
# len(storage) reports the number of objects.
# check it is zero when empty
self.assertEqual(len(self._storage),0)
# check it is correct when the storage contains two object.
# len may also be zero, for storages that do not keep track
# of this number
self._dostore(data=MinPO(22))
self._dostore(data=MinPO(23))
self.assert_(len(self._storage) in [0,2])
def checkGetSize(self):
self._dostore(data=MinPO(25))
# the size should be a byte count
size = self._storage.getSize()
# all Zope really cares about is that the size is printable
str(size)
if type(size) in [type(0),type(0L),type(0.0)]:
# a numerical size - that means we can check that the size is reasonable.
self.assert_(10<size<100*1024, size)
def checkNote(self):
oid = self._storage.new_oid()
t = Transaction()
self._storage.tpc_begin(t)
t.note('this is a test')
self._storage.store(oid, ZERO, zodb_pickle(MinPO(5)), '', t)
self._storage.tpc_vote(t)
self._storage.tpc_finish(t)
def checkOversizeNote(self):
oid = self._storage.new_oid()
t = Transaction()
# Most storages cant cope with comments this long
t.note('0'*128*1024)
try:
self._storage.tpc_begin(t)
self._storage.store(oid, ZERO, zodb_pickle(MinPO(5)), '', t)
self._storage.tpc_vote(t)
self._storage.tpc_finish(t)
except POSException.POSError:
# failed as expected
pass
else:
self.fail()
def checkGetExtensionMethods(self):
m = self._storage.getExtensionMethods()
self.assertEqual(type(m),type({}))
for k,v in m.items():
self.assertEqual(v,None)
self.assert_(callable(getattr(self._storage,k)))
......@@ -28,6 +28,7 @@ class HistoryStorage:
eq = self.assertEqual
# Store a couple of non-version revisions of the object
oid = self._storage.new_oid()
self.assertRaises(KeyError,self._storage.history,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))
......
......@@ -381,6 +381,65 @@ class PackableStorage(PackableStorageBase):
eq(root['obj'].value, 7)
def checkPackUndoLog(self):
self._initroot()
eq = self.assertEqual
raises = self.assertRaises
# Create a `persistent' object
obj = self._newobj()
oid = obj.getoid()
obj.value = 1
# Commit two different revisions
revid1 = self._dostoreNP(oid, data=pickle.dumps(obj))
obj.value = 2
now = packtime = time.time()
while packtime <= now:
packtime = time.time()
revid2 = self._dostoreNP(oid, revid=revid1, data=pickle.dumps(obj))
# Now pack the first transaction
self.assertEqual(3,len(self._storage.undoLog()))
self._storage.pack(packtime, referencesf)
# The undo log contains only the most resent transaction
self.assertEqual(1,len(self._storage.undoLog()))
def dont_checkPackUndoLogUndoable(self):
# A disabled test. I wanted to test that the content of the undo log was consistent,
# but every storage appears to include something slightly different. If the result of
# this method is only used to fill a GUI then this difference doesnt matter.
# Perhaps re-enable this test once we agree what should be asserted.
self._initroot()
# Create two `persistent' object
obj1 = self._newobj()
oid1 = obj1.getoid()
obj1.value = 1
obj2 = self._newobj()
oid2 = obj2.getoid()
obj2.value = 2
# Commit the first revision of each of them
revid11 = self._dostoreNP(oid1, data=pickle.dumps(obj1), description="1-1")
revid22 = self._dostoreNP(oid2, data=pickle.dumps(obj2), description="2-2")
# remember the time. everything above here will be packed away
now = packtime = time.time()
while packtime <= now:
packtime = time.time()
# Commit two revisions of the first object
obj1.value = 3
revid13 = self._dostoreNP(oid1, revid=revid11, data=pickle.dumps(obj1), description="1-3")
obj1.value = 4
revid14 = self._dostoreNP(oid1, revid=revid13, data=pickle.dumps(obj1), description="1-4")
# Commit one revision of the second object
obj2.value = 5
revid25 = self._dostoreNP(oid2, revid=revid22, data=pickle.dumps(obj2), description="2-5")
# Now pack
self.assertEqual(6,len(self._storage.undoLog()))
print '\ninitial undoLog was'
for r in self._storage.undoLog(): print r
self._storage.pack(packtime, referencesf)
# The undo log contains only two undoable transaction.
print '\nafter packing undoLog was'
for r in self._storage.undoLog(): print r
# what can we assert about that?
def checkPackWhileWriting(self):
# A storage should allow some reading and writing during
# a pack. This test attempts to exercise locking code
......
......@@ -209,7 +209,7 @@ class StorageTestBase(unittest.TestCase):
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)
return self._dostore(oid, revid, data, version, 1, user, description)
# The following methods depend on optional storage features.
......
......@@ -2,14 +2,14 @@
#
# 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.
#
#
##############################################################################
"""Check transactionalUndo().
......@@ -141,7 +141,6 @@ class TransactionalUndoStorage:
oids = self._storage.transactionalUndo(tid, t)
self._storage.tpc_vote(t)
self._storage.tpc_finish(t)
eq(len(oids), 1)
eq(oids[0], oid)
# This should fail since we've undone the object's creation
......@@ -161,6 +160,23 @@ class TransactionalUndoStorage:
eq(zodb_unpickle(data), MinPO(23))
self._iterate()
def checkCreationUndoneGetSerial(self):
# create an object
oid = self._storage.new_oid()
revid = self._dostore(oid, data=MinPO(23))
# undo its creation
info = self._storage.undoInfo()
tid = info[0]['id']
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)
# Check that calling getSerial on an uncreated object raises a KeyError
# The current version of FileStorage fails this test
self.assertRaises(KeyError, self._storage.getSerial, oid)
def checkUndoCreationBranch1(self):
eq = self.assertEqual
oid = self._storage.new_oid()
......@@ -753,3 +769,25 @@ class TransactionalUndoStorage:
eq(L1, L2)
self.assertRaises(IndexError, iter.__getitem__, offset)
def checkUndoLogMetadata(self):
# test that the metadata is correct in the undo log
t = get_transaction()
t.note('t1')
t.setExtendedInfo('k2','this is transaction metadata')
t.setUser('u3',path='p3')
db = DB(self._storage)
conn = db.open()
root = conn.root()
o1 = C()
root['obj'] = o1
txn = get_transaction()
txn.commit()
l = self._storage.undoLog()
self.assertEqual(len(l),2)
d = l[0]
self.assertEqual(d['description'],'t1')
self.assertEqual(d['k2'],'this is transaction metadata')
self.assertEqual(d['user_name'],'p3 u3')
......@@ -2,14 +2,14 @@
#
# 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.
#
#
##############################################################################
import ZODB.DemoStorage
import os, unittest
......@@ -29,6 +29,13 @@ class DemoStorageTests(StorageTestBase.StorageTestBase,
def tearDown(self):
self._storage.close()
def checkOversizeNote(self):
# This base class test checks for the common case where a storage
# doesnt support huge transaction metadata. This storage doesnt
# have this limit, so we inhibit this test here.
pass
def test_suite():
suite = unittest.makeSuite(DemoStorageTests, 'check')
return suite
......
......@@ -2,14 +2,14 @@
#
# 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.
#
#
##############################################################################
import ZODB.MappingStorage
import os, unittest
......@@ -27,6 +27,12 @@ class MappingStorageTests(StorageTestBase.StorageTestBase,
def tearDown(self):
self._storage.close()
def checkOversizeNote(self):
# This base class test checks for the common case where a storage
# doesnt support huge transaction metadata. This storage doesnt
# have this limit, so we inhibit this test here.
pass
def test_suite():
suite = unittest.makeSuite(MappingStorageTests, 'check')
return suite
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment