[Python-checkins] python/dist/src/Lib/test test_bsddb.py,1.15,1.16

greg at users.sourceforge.net greg at users.sourceforge.net
Sun Nov 2 20:04:43 EST 2003


Update of /cvsroot/python/python/dist/src/Lib/test
In directory sc8-pr-cvs1:/tmp/cvs-serv10424/Lib/test

Modified Files:
	test_bsddb.py 
Log Message:
* Use weakref's of DBCursor objects for the iterator cursors to avoid a
  memory leak that would've occurred for all iterators that were
  destroyed before having iterated until they raised StopIteration.

* Simplify some code.

* Add new test cases to check for the memleak and ensure that mixing
  iteration with modification of the values for existing keys works.


Index: test_bsddb.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/test/test_bsddb.py,v
retrieving revision 1.15
retrieving revision 1.16
diff -C2 -d -r1.15 -r1.16
*** test_bsddb.py	2 Nov 2003 09:10:16 -0000	1.15
--- test_bsddb.py	3 Nov 2003 01:04:41 -0000	1.16
***************
*** 4,7 ****
--- 4,8 ----
  """
  import os, sys
+ import copy
  import bsddb
  import dbhash # Just so we know it's imported
***************
*** 65,68 ****
--- 66,119 ----
          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:
+                 key = di.next()
+                 self.d[key] = 'modified '+key
+             except StopIteration:
+                 break
+ 
+         # it should behave the same as a dict.  modifying values
+         # of existing keys should not break iteration.  (adding
+         # or removing keys should)
+         fi = iter(self.f)
+         while 1:
+             try:
+                 key = fi.next()
+                 self.f[key] = 'modified '+key
+             except StopIteration:
+                 break
+ 
+         self.test_mapping_iteration_methods()
+ 
+     def test_iteritems_while_modifying_values(self):
+         if not hasattr(self.f, 'iteritems'):
+             return
+ 
+         di = self.d.iteritems()
+         while 1:
+             try:
+                 k, v = di.next()
+                 self.d[k] = 'modified '+v
+             except StopIteration:
+                 break
+ 
+         # it should behave the same as a dict.  modifying values
+         # of existing keys should not break iteration.  (adding
+         # or removing keys should)
+         fi = self.f.iteritems()
+         while 1:
+             try:
+                 k, v = fi.next()
+                 self.f[k] = 'modified '+v
+             except StopIteration:
+                 break
+ 
+         self.test_mapping_iteration_methods()
+ 
      def test_first_next_looping(self):
          items = [self.f.first()]
***************
*** 112,118 ****
  
          # test the iterator interface (if present)
!         if hasattr(self, 'iteritems'):
              if debug: print "D"
!             k,v = self.f.iteritems()
              if debug: print "E"
              self.f[k] = "please don't deadlock"
--- 163,170 ----
  
          # test the iterator interface (if present)
!         if hasattr(self.f, 'iteritems'):
              if debug: print "D"
!             i = self.f.iteritems()
!             k,v = i.next()
              if debug: print "E"
              self.f[k] = "please don't deadlock"
***************
*** 120,124 ****
              while 1:
                  try:
!                     k,v = self.f.iteritems()
                  except StopIteration:
                      break
--- 172,176 ----
              while 1:
                  try:
!                     k,v = i.next()
                  except StopIteration:
                      break
***************
*** 144,147 ****
--- 196,220 ----
          self.f[k] = "be gone with ye deadlocks"
          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?
+         nc1 = len(self.f._cursor_refs)
+         # create iterator
+         i = self.f.iteritems()
+         nc2 = len(self.f._cursor_refs)
+         # use the iterator (should run to the first yeild, creating the cursor)
+         k, v = i.next()
+         nc3 = len(self.f._cursor_refs)
+         # destroy the iterator; this should cause the weakref callback
+         # to remove the cursor object from self.f._cursor_refs
+         del i
+         nc4 = len(self.f._cursor_refs)
+ 
+         self.assertEqual(nc1, nc2)
+         self.assertEqual(nc1, nc4)
+         self.assert_(nc3 == nc1+1)
  
      def test_popitem(self):





More information about the Python-checkins mailing list