Commit 53a30f02 authored by Benji York's avatar Benji York

- fix bug that made it possible for DemoStorage to hand out the same OID

  twice (with test)
- remove irrelevent and unused test_suite definition from testDemoStorage.py
parent 2fa9b2b1
...@@ -176,9 +176,15 @@ class DemoStorage(object): ...@@ -176,9 +176,15 @@ class DemoStorage(object):
except ZODB.POSException.POSKeyError: except ZODB.POSException.POSKeyError:
return self.base.loadSerial(oid, serial) return self.base.loadSerial(oid, serial)
_issued_oids = {}
def new_oid(self): def new_oid(self):
while 1: while 1:
oid = ZODB.utils.p64(random.randint(1, 9223372036854775807)) oid = ZODB.utils.p64(random.randint(1, 9223372036854775807))
if oid in self._issued_oids:
continue
try: try:
self.changes.load(oid, '') self.changes.load(oid, '')
except ZODB.POSException.POSKeyError: except ZODB.POSException.POSKeyError:
...@@ -192,6 +198,7 @@ class DemoStorage(object): ...@@ -192,6 +198,7 @@ class DemoStorage(object):
else: else:
continue continue
self._issued_oids[oid] = None
return oid return oid
def pack(self, t, referencesf, gc=None): def pack(self, t, referencesf, gc=None):
...@@ -222,6 +229,11 @@ class DemoStorage(object): ...@@ -222,6 +229,11 @@ class DemoStorage(object):
def store(self, oid, serial, data, version, transaction): def store(self, oid, serial, data, version, transaction):
assert version=='', "versions aren't supported" assert version=='', "versions aren't supported"
# Since the OID is being used, we don't have to keep up with it any
# more.
if oid in self._issued_oids:
del self._issued_oids[oid]
# See if we already have changes for this oid # See if we already have changes for this oid
try: try:
old = self.changes.load(oid, '')[1] old = self.changes.load(oid, '')[1]
...@@ -239,6 +251,12 @@ class DemoStorage(object): ...@@ -239,6 +251,12 @@ class DemoStorage(object):
def storeBlob(self, oid, oldserial, data, blobfilename, version, def storeBlob(self, oid, oldserial, data, blobfilename, version,
transaction): transaction):
# Since the OID is being used, we don't have to keep up with it any
# more.
if oid in self._issued_oids:
del self._issued_oids[oid]
try: try:
return self.changes.storeBlob( return self.changes.storeBlob(
oid, oldserial, data, blobfilename, version, transaction) oid, oldserial, data, blobfilename, version, transaction)
......
...@@ -327,3 +327,50 @@ and base options: ...@@ -327,3 +327,50 @@ and base options:
'base.fs' 'base.fs'
>>> storage.close() >>> storage.close()
Generating OIDs
===============
When asked for a new OID DemoStorage randomly chooses a value and then verifies
that neither the base or changes storages already contain that OID.
Under rare circumstances an OID can be chosen that has already been handed out,
but which hasn't yet been comitted. Lets verify that if the same OID is chosen
twice during a transaction that everything will still work.
First we'll get a single OID.
>>> import random
>>> storage = DemoStorage.push(storage)
>>> random.seed(47)
>>> storage.new_oid()
'\x10\x01\xa6bZ\x12\x98\xa2'
Then we'll force the random number generator to use the same seed for the
subsequent call to "new_oid" and show that we get a different OID.
>>> random.seed(47)
>>> oid = storage.new_oid()
>>> oid
'A\xe6\xcb\x06W\xed\xa2\x15'
DemoStorage keeps up with the issued OIDs to know when not to reissue them...
>>> oid in storage._issued_oids
True
...but once data is stored with a given OID...
>>> t = transaction.begin()
>>> storage.tpc_begin(t)
>>> tid = storage.store(oid, 0, 'data', '', t)
...there's no need to remember it any longer:
>>> oid in storage._issued_oids
False
We're done with the storage, so "unwrap" the underlying storage.
>>> storage = storage.pop()
...@@ -156,20 +156,6 @@ def testSomeDelegation(): ...@@ -156,20 +156,6 @@ def testSomeDelegation():
""" """
def test_suite():
return unittest.TestSuite((
doctest.DocFileSuite('synchronized.txt'),
doctest.DocTestSuite(
setUp=setUp, tearDown=ZODB.tests.util.tearDown,
),
doctest.DocFileSuite(
'README.txt',
setUp=setUp, tearDown=ZODB.tests.util.tearDown,
),
))
def test_suite(): def test_suite():
suite = unittest.TestSuite(( suite = unittest.TestSuite((
......
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