[pypy-svn] r73412 - pypy/branch/cpython-extension/pypy/module/cpyext/test

xoraxax at codespeak.net xoraxax at codespeak.net
Mon Apr 5 17:33:18 CEST 2010


Author: xoraxax
Date: Mon Apr  5 17:33:14 2010
New Revision: 73412

Modified:
   pypy/branch/cpython-extension/pypy/module/cpyext/test/test_api.py
   pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py
Log:
Refactor the leak checking code to work also with api tests.

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_api.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_api.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_api.py	Mon Apr  5 17:33:14 2010
@@ -3,6 +3,7 @@
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.module.cpyext.state import State
 from pypy.module.cpyext import api
+from pypy.module.cpyext.test.test_cpyext import freeze_refcnts, check_and_print_leaks
 PyObject = api.PyObject
 
 @api.cpython_api([PyObject], lltype.Void)
@@ -21,9 +22,14 @@
         cls.api = CAPI()
         CAPI.__dict__.update(api.INTERPLEVEL_API)
 
+    def setup_method(self, func):
+        freeze_refcnts(self)
+
     def teardown_method(self, func):
         state = self.space.fromcache(State)
         assert state.exc_value is None
+        if check_and_print_leaks(self):
+            assert False, "Test leaks or loses object(s)."
 
 class TestConversion(BaseApiTest):
     def test_conversions(self, space, api):

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py	Mon Apr  5 17:33:14 2010
@@ -58,6 +58,65 @@
         standalone=False)
     return str(soname)
 
+def freeze_refcnts(self):
+    state = self.space.fromcache(State)
+    self.frozen_refcounts = {}
+    for w_obj, obj in state.py_objects_w2r.iteritems():
+        self.frozen_refcounts[w_obj] = obj.c_ob_refcnt
+    #state.print_refcounts()
+    self.frozen_ll2callocations = set(ll2ctypes.ALLOCATED.values())
+    self.frozen_lltallocations = lltype.ALLOCATED.copy()
+    lltype.TRACK_ALLOCATIONS = True
+
+def check_and_print_leaks(self):
+    # check for sane refcnts
+    leaking = False
+    state = self.space.fromcache(State)
+    import gc
+    gc.collect()
+    lost_objects_w = identity_dict()
+    lost_objects_w.update((key, None) for key in self.frozen_refcounts.keys())
+    for w_obj, obj in state.py_objects_w2r.iteritems():
+        base_refcnt = self.frozen_refcounts.get(w_obj)
+        delta = obj.c_ob_refcnt
+        if base_refcnt is not None:
+            delta -= base_refcnt
+            lost_objects_w.pop(w_obj)
+        if delta != 0:
+            leaking = True
+            print >>sys.stderr, "Leaking %r: %i references" % (w_obj, delta)
+            lifeline = w_obj.get_pyolifeline()
+            if lifeline is not None:
+                refcnt = lifeline.pyo.c_ob_refcnt
+                if refcnt > 0:
+                    print >>sys.stderr, "\tThe object also held by C code."
+                else:
+                    referrers_repr = []
+                    for o in gc.get_referrers(w_obj):
+                        try:
+                            repr_str = repr(o)
+                        except TypeError, e:
+                            repr_str = "%s (type of o is %s)" % (str(e), type(o))
+                        referrers_repr.append(repr_str)
+                    referrers = ", ".join(referrers_repr)
+                    print >>sys.stderr, "\tThe object is referenced by these objects:", \
+                            referrers
+    for w_obj in lost_objects_w:
+        print >>sys.stderr, "Lost object %r" % (w_obj, )
+        leaking = True
+    for llvalue in set(ll2ctypes.ALLOCATED.values()) - self.frozen_ll2callocations:
+        if getattr(llvalue, "_traceback", None): # this means that the allocation should be tracked
+            leaking = True
+            print >>sys.stderr, "Did not deallocate %r (ll2ctypes)" % (llvalue, )
+            print >>sys.stderr, "\t" + "\n\t".join(llvalue._traceback.splitlines())
+    for llvalue in set_difference(lltype.ALLOCATED, self.frozen_lltallocations).keys():
+        leaking = True
+        print >>sys.stderr, "Did not deallocate %r (llvalue)" % (llvalue, )
+        print >>sys.stderr, "\t" + "\n\t".join(llvalue._traceback.splitlines())
+
+    return leaking
+
+
 class AppTestCpythonExtensionBase:
     def setup_class(cls):
         cls.space = gettestobjspace(usemodules=['cpyext'])
@@ -123,7 +182,7 @@
     def setup_method(self, func):
         self.w_import_module = self.space.wrap(self.import_module)
         self.w_import_extension = self.space.wrap(self.import_extension)
-        self.freeze_refcnts()
+        freeze_refcnts(self)
         #self.check_and_print_leaks()
 
     def teardown_method(self, func):
@@ -140,68 +199,9 @@
             pass
         except AttributeError:
             pass
-        state = self.space.fromcache(State)
-        if self.check_and_print_leaks():
+        if check_and_print_leaks(self):
             assert False, "Test leaks or loses object(s)."
 
-    def freeze_refcnts(self):
-        state = self.space.fromcache(State)
-        self.frozen_refcounts = {}
-        for w_obj, obj in state.py_objects_w2r.iteritems():
-            self.frozen_refcounts[w_obj] = obj.c_ob_refcnt
-        #state.print_refcounts()
-        self.frozen_ll2callocations = set(ll2ctypes.ALLOCATED.values())
-        self.frozen_lltallocations = lltype.ALLOCATED.copy()
-        lltype.TRACK_ALLOCATIONS = True
-
-    def check_and_print_leaks(self):
-        # check for sane refcnts
-        leaking = False
-        state = self.space.fromcache(State)
-        import gc
-        gc.collect()
-        lost_objects_w = identity_dict()
-        lost_objects_w.update((key, None) for key in self.frozen_refcounts.keys())
-        for w_obj, obj in state.py_objects_w2r.iteritems():
-            base_refcnt = self.frozen_refcounts.get(w_obj)
-            delta = obj.c_ob_refcnt
-            if base_refcnt is not None:
-                delta -= base_refcnt
-                lost_objects_w.pop(w_obj)
-            if delta != 0:
-                leaking = True
-                print >>sys.stderr, "Leaking %r: %i references" % (w_obj, delta)
-                lifeline = w_obj.get_pyolifeline()
-                if lifeline is not None:
-                    refcnt = lifeline.pyo.c_ob_refcnt
-                    if refcnt > 0:
-                        print >>sys.stderr, "\tThe object also held by C code."
-                    else:
-                        referrers_repr = []
-                        for o in gc.get_referrers(w_obj):
-                            try:
-                                repr_str = repr(o)
-                            except TypeError, e:
-                                repr_str = "%s (type of o is %s)" % (str(e), type(o))
-                            referrers_repr.append(repr_str)
-                        referrers = ", ".join(referrers_repr)
-                        print >>sys.stderr, "\tThe object is referenced by these objects:", \
-                                referrers
-        for w_obj in lost_objects_w:
-            print >>sys.stderr, "Lost object %r" % (w_obj, )
-            leaking = True
-        for llvalue in set(ll2ctypes.ALLOCATED.values()) - self.frozen_ll2callocations:
-            if getattr(llvalue, "_traceback", None): # this means that the allocation should be tracked
-                leaking = True
-                print >>sys.stderr, "Did not deallocate %r (ll2ctypes)" % (llvalue, )
-                print >>sys.stderr, "\t" + "\n\t".join(llvalue._traceback.splitlines())
-        for llvalue in set_difference(lltype.ALLOCATED, self.frozen_lltallocations).keys():
-            leaking = True
-            print >>sys.stderr, "Did not deallocate %r (llvalue)" % (llvalue, )
-            print >>sys.stderr, "\t" + "\n\t".join(llvalue._traceback.splitlines())
-
-        return leaking
-
 
 class AppTestCpythonExtension(AppTestCpythonExtensionBase):
     def test_createmodule(self):



More information about the Pypy-commit mailing list