[Zodb-checkins] CVS: Zope3/src/zodb/btrees/tests - test_btrees.py:1.4

Tim Peters tim.one@comcast.net
Fri, 31 Jan 2003 14:50:33 -0500


Update of /cvs-repository/Zope3/src/zodb/btrees/tests
In directory cvs.zope.org:/tmp/cvs-serv13788/src/zodb/btrees/tests

Modified Files:
	test_btrees.py 
Log Message:
BTreeItems_seek():  Even if i == pseudoindex on entry, bucket mutation
since the last call may have left us with an invalid index.  Raise
RuntimeError instead of segfaulting (or picking up random trash) if so.
A new (and previously segfaulting) test case is courtesy of Steve
Alexander.


=== Zope3/src/zodb/btrees/tests/test_btrees.py 1.3 => 1.4 ===
--- Zope3/src/zodb/btrees/tests/test_btrees.py:1.3	Tue Jan 14 16:51:46 2003
+++ Zope3/src/zodb/btrees/tests/test_btrees.py	Fri Jan 31 14:50:30 2003
@@ -457,7 +457,6 @@
         self.t.update([(1, 2)])
         self.assertEqual(list(self.t.items()), [(1, 2)])
 
-
 class NormalSetTests(Base):
     """ Test common to all set types """
 
@@ -892,6 +891,30 @@
         self.assertEqual(t.insert(0, 1) , 0)
         self.assertEqual(t.insert(1, 1) , 1)
         self.assertEqual(lsubtract(list(t.keys()), [0,1]) , [])
+
+    def testDamagedIterator(self):
+        # A cute one from Steve Alexander.  This caused the BTreeItems
+        # object to go insane, accessing memory beyond the allocated part
+        # of the bucket.  If it fails, the symptom is either a C-level
+        # assertion error (if the BTree code was compiled without NDEBUG),
+        # or most likely a segfault (if the BTree code was compiled with
+        # NDEBUG).
+
+        t = self.t.__class__()
+        self._populate(t, 10)
+        # In order for this to fail, it's important that k be a "lazy"
+        # iterator, referring to the BTree by indirect position (index)
+        # instead of a fully materialized list.  Then the position can
+        # end up pointing into trash memory, if the bucket pointed to
+        # shrinks.
+        k = t.keys()
+        for dummy in range(20):
+            try:
+                del t[k[0]]
+            except RuntimeError, detail:
+                self.assertEqual(str(detail), "the bucket being iterated "
+                                              "changed size")
+                break
 
 # tests of various type errors