diff options
author | Ned Batchelder <ned@nedbatchelder.com> | 2009-11-22 19:51:55 -0500 |
---|---|---|
committer | Ned Batchelder <ned@nedbatchelder.com> | 2009-11-22 19:51:55 -0500 |
commit | d8775b5f8dfbc4f47c78ac50f0947bafe4b77744 (patch) | |
tree | 6b08d551993b7cfc1e854e27c80674165dc4cf59 | |
parent | 411d1943e5cb901a3d65dbb263f26ed606942c25 (diff) | |
download | python-coveragepy-git-d8775b5f8dfbc4f47c78ac50f0947bafe4b77744.tar.gz |
Add a test for leaking memory in the C extension. Windows only for now, kind of experimental.
-rw-r--r-- | test/coveragetest.py | 2 | ||||
-rw-r--r-- | test/osinfo.py | 40 | ||||
-rw-r--r-- | test/test_coverage.py | 31 |
3 files changed, 72 insertions, 1 deletions
diff --git a/test/coveragetest.py b/test/coveragetest.py index b86794d4..dffffb29 100644 --- a/test/coveragetest.py +++ b/test/coveragetest.py @@ -214,7 +214,7 @@ class CoverageTest(unittest.TestCase): cov.report(mod, file=frep) rep = " ".join(frep.getvalue().split("\n")[2].split()[1:]) self.assertEqual(report, rep) - + def assert_raises_msg(self, excClass, msg, callableObj, *args, **kwargs): """ Just like unittest.TestCase.assertRaises, but checks that the message is right too. diff --git a/test/osinfo.py b/test/osinfo.py new file mode 100644 index 00000000..5932c537 --- /dev/null +++ b/test/osinfo.py @@ -0,0 +1,40 @@ +"""OS information for testing.""" + +import sys + +if sys.hexversion >= 0x02050000 and sys.platform == 'win32': + # Windows implementation + def process_ram(): + """How much RAM is this process using? (Windows)""" + import ctypes + # lifted from: + # lists.ubuntu.com/archives/bazaar-commits/2009-February/011990.html + class PROCESS_MEMORY_COUNTERS_EX(ctypes.Structure): + """Used by GetProcessMemoryInfo""" + _fields_ = [('cb', ctypes.c_ulong), + ('PageFaultCount', ctypes.c_ulong), + ('PeakWorkingSetSize', ctypes.c_size_t), + ('WorkingSetSize', ctypes.c_size_t), + ('QuotaPeakPagedPoolUsage', ctypes.c_size_t), + ('QuotaPagedPoolUsage', ctypes.c_size_t), + ('QuotaPeakNonPagedPoolUsage', ctypes.c_size_t), + ('QuotaNonPagedPoolUsage', ctypes.c_size_t), + ('PagefileUsage', ctypes.c_size_t), + ('PeakPagefileUsage', ctypes.c_size_t), + ('PrivateUsage', ctypes.c_size_t), + ] + + mem_struct = PROCESS_MEMORY_COUNTERS_EX() + ret = ctypes.windll.psapi.GetProcessMemoryInfo( + ctypes.windll.kernel32.GetCurrentProcess(), + ctypes.byref(mem_struct), + ctypes.sizeof(mem_struct) + ) + if not ret: + return 0 + return mem_struct.PrivateUsage + +else: + def process_ram(): + """How much RAM is this process using? (no implementation)""" + return 0 diff --git a/test/test_coverage.py b/test/test_coverage.py index 093065f8..e8f5c745 100644 --- a/test/test_coverage.py +++ b/test/test_coverage.py @@ -9,6 +9,7 @@ coverage.use_cache(0) sys.path.insert(0, os.path.split(__file__)[0]) # Force relative import for Py3k from coveragetest import CoverageTest +import osinfo class BasicCoverageTest(CoverageTest): @@ -1730,6 +1731,36 @@ class RecursionTest(CoverageTest): [1,2,3,5,7], "") +class MemoryLeakTest(CoverageTest): + """Attempt the impossible: test that memory doesn't leak.""" + + def test_for_leaks(self): + lines = list(range(301, 315)) + lines.remove(306) + baseline_ram = osinfo.process_ram() + # Ugly string mumbo jumbo to get 300 blank lines at the beginning.. + self.check_coverage("""\ + # blank line\n""" * 300 + """\ + def once(x): + if x % 100 == 0: + raise Exception("100!") + elif x % 2: + return 10 + else: + return 11 + i = 0 # Portable loop without alloc'ing memory. + while i < 10000: + try: + once(i) + except: + pass + i += 1 + """, + lines, "") + ram_growth = osinfo.process_ram() - baseline_ram + self.assert_(ram_growth < 100000, "RAM grew by %d" % (ram_growth)) + + class PyexpatTest(CoverageTest): """Pyexpat screws up tracing. Make sure we've counter-defended properly.""" |