summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_bsddb.py
diff options
context:
space:
mode:
authorGregory P. Smith <greg@mad-scientist.com>2008-05-25 08:28:29 (GMT)
committerGregory P. Smith <greg@mad-scientist.com>2008-05-25 08:28:29 (GMT)
commit9e6468be1dc6ab460a2b88af096aa62c2fe0ce44 (patch)
tree7ed8a0f5251620a0b4f99cd33038fe46f2168fce /Lib/test/test_bsddb.py
parente08e3d06864c5ad993f74613d9ed4ce69cc6cbc6 (diff)
downloadcpython-9e6468be1dc6ab460a2b88af096aa62c2fe0ce44.zip
cpython-9e6468be1dc6ab460a2b88af096aa62c2fe0ce44.tar.gz
cpython-9e6468be1dc6ab460a2b88af096aa62c2fe0ce44.tar.bz2
Fix issue2669: bsddb simple/legacy interface iteration silently fails
when database changes size during iteration. It now behaves like a dictionary, the next attempt to get a value from the iterator after the database has changed size will raise a RuntimeError.
Diffstat (limited to 'Lib/test/test_bsddb.py')
-rwxr-xr-xLib/test/test_bsddb.py63
1 files changed, 51 insertions, 12 deletions
diff --git a/Lib/test/test_bsddb.py b/Lib/test/test_bsddb.py
index acd4972..f6e6ad0 100755
--- a/Lib/test/test_bsddb.py
+++ b/Lib/test/test_bsddb.py
@@ -66,9 +66,6 @@ class TestBSDDB(unittest.TestCase):
self.assertSetEquals(d.iteritems(), f.iteritems())
def test_iter_while_modifying_values(self):
- if not hasattr(self.f, '__iter__'):
- return
-
di = iter(self.d)
while 1:
try:
@@ -80,20 +77,62 @@ class TestBSDDB(unittest.TestCase):
# it should behave the same as a dict. modifying values
# of existing keys should not break iteration. (adding
# or removing keys should)
+ loops_left = len(self.f)
fi = iter(self.f)
while 1:
try:
key = fi.next()
self.f[key] = 'modified '+key
+ loops_left -= 1
except StopIteration:
break
+ self.assertEqual(loops_left, 0)
self.test_mapping_iteration_methods()
- def test_iteritems_while_modifying_values(self):
- if not hasattr(self.f, 'iteritems'):
- return
+ def test_iter_abort_on_changed_size(self):
+ def DictIterAbort():
+ di = iter(self.d)
+ while 1:
+ try:
+ di.next()
+ self.d['newkey'] = 'SPAM'
+ except StopIteration:
+ break
+ self.assertRaises(RuntimeError, DictIterAbort)
+
+ def DbIterAbort():
+ fi = iter(self.f)
+ while 1:
+ try:
+ fi.next()
+ self.f['newkey'] = 'SPAM'
+ except StopIteration:
+ break
+ self.assertRaises(RuntimeError, DbIterAbort)
+ def test_iteritems_abort_on_changed_size(self):
+ def DictIteritemsAbort():
+ di = self.d.iteritems()
+ while 1:
+ try:
+ di.next()
+ self.d['newkey'] = 'SPAM'
+ except StopIteration:
+ break
+ self.assertRaises(RuntimeError, DictIteritemsAbort)
+
+ def DbIteritemsAbort():
+ fi = self.f.iteritems()
+ while 1:
+ try:
+ key, value = fi.next()
+ del self.f[key]
+ except StopIteration:
+ break
+ self.assertRaises(RuntimeError, DbIteritemsAbort)
+
+ def test_iteritems_while_modifying_values(self):
di = self.d.iteritems()
while 1:
try:
@@ -105,13 +144,16 @@ class TestBSDDB(unittest.TestCase):
# it should behave the same as a dict. modifying values
# of existing keys should not break iteration. (adding
# or removing keys should)
+ loops_left = len(self.f)
fi = self.f.iteritems()
while 1:
try:
k, v = fi.next()
self.f[k] = 'modified '+v
+ loops_left -= 1
except StopIteration:
break
+ self.assertEqual(loops_left, 0)
self.test_mapping_iteration_methods()
@@ -177,8 +219,8 @@ class TestBSDDB(unittest.TestCase):
# the database write and locking+threading support is enabled
# the cursor's read lock will deadlock the write lock request..
- # test the iterator interface (if present)
- if hasattr(self.f, 'iteritems'):
+ # test the iterator interface
+ if True:
if debug: print "D"
i = self.f.iteritems()
k,v = i.next()
@@ -213,10 +255,7 @@ class TestBSDDB(unittest.TestCase):
self.assert_(self.f[k], "be gone with ye deadlocks")
def test_for_cursor_memleak(self):
- if not hasattr(self.f, 'iteritems'):
- return
-
- # do the bsddb._DBWithCursor _iter_mixin internals leak cursors?
+ # do the bsddb._DBWithCursor iterator internals leak cursors?
nc1 = len(self.f._cursor_refs)
# create iterator
i = self.f.iteritems()