2
"""Detect reference leaks after several unit test runs.
4
The script runs the unit test and counts the objects alive after the run. If
5
the object count differs between the last two runs, a report is printed and the
6
script exits with error 1.
9
# Copyright (C) 2011 Daniele Varrazzo <daniele.varrazzo@gmail.com>
11
# This program is free software; you can redistribute it and/or modify
12
# it under the terms of the GNU General Public License as published by
13
# the Free Software Foundation; either version 2 of the License, or
14
# (at your option) any later version.
16
# This program is distributed in the hope that it will be useful,
17
# but WITHOUT ANY WARRANTY; without even the implied warranty of
18
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
# GNU General Public License for more details.
21
# You should have received a copy of the GNU General Public License
22
# along with this program; if not, write to the Free Software
23
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
29
from pprint import pprint
30
from collections import defaultdict
38
test = getattr(test, opt.suite)
40
sys.stdout.write("test suite %s\n" % test.__name__)
42
for i in range(1, opt.nruns + 1):
43
sys.stdout.write("test suite run %d of %d\n" % (i, opt.nruns))
44
runner = unittest.TextTestRunner()
45
runner.run(test.test_suite())
48
f1 = open('debug-%02d.txt' % (opt.nruns - 1)).readlines()
49
f2 = open('debug-%02d.txt' % (opt.nruns)).readlines()
50
for line in difflib.unified_diff(f1, f2,
51
"run %d" % (opt.nruns - 1), "run %d" % opt.nruns):
52
sys.stdout.write(line)
54
rv = f1 != f2 and 1 or 0
57
f1 = open('objs-%02d.txt' % (opt.nruns - 1)).readlines()
58
f2 = open('objs-%02d.txt' % (opt.nruns)).readlines()
59
for line in difflib.unified_diff(f1, f2,
60
"run %d" % (opt.nruns - 1), "run %d" % opt.nruns):
61
sys.stdout.write(line)
68
parser = optparse.OptionParser(description=__doc__)
69
parser.add_option('--nruns', type='int', metavar="N", default=3,
70
help="number of test suite runs [default: %default]")
71
parser.add_option('--suite', metavar="NAME",
72
help="the test suite to run (e.g. 'test_cursor'). [default: all]")
73
parser.add_option('--objs', metavar="TYPE",
74
help="in case of leaks, print a report of object TYPE "
75
"(support still incomplete)")
77
opt, args = parser.parse_args()
83
objs = gc.get_objects()
90
sorted(((v,str(k)) for k,v in c.items()), reverse=True),
91
stream=open("debug-%02d.txt" % i, "w"))
95
t = getattr(__builtins__, opt.objs)
100
# TODO: very incomplete
102
co.sort(key = lambda d: d.items())
106
pprint(co, stream=open("objs-%02d.txt" % i, "w"))
109
if __name__ == '__main__':