diff options
author | Gregory P. Smith <greg@mad-scientist.com> | 2008-05-25 08:28:29 (GMT) |
---|---|---|
committer | Gregory P. Smith <greg@mad-scientist.com> | 2008-05-25 08:28:29 (GMT) |
commit | 9e6468be1dc6ab460a2b88af096aa62c2fe0ce44 (patch) | |
tree | 7ed8a0f5251620a0b4f99cd33038fe46f2168fce /Lib/test/test_bsddb.py | |
parent | e08e3d06864c5ad993f74613d9ed4ce69cc6cbc6 (diff) | |
download | cpython-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-x | Lib/test/test_bsddb.py | 63 |
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() |