comparison tests/run-tests.py @ 2144:d3bddedfdbd0

Add code coverage to the python version of run-tests (inc. annotation) Also include a minor work-around to coverage.py to avoid errors about /<string>
author Stephen Darnell <stephen@darnell.plus.com>
date Thu, 27 Apr 2006 21:59:44 -0700
parents 4334be196f8d
children 5bb3cb9e5d13
comparison
equal deleted inserted replaced
2138:f5046cab9e2e 2144:d3bddedfdbd0
13 import popen2 13 import popen2
14 from optparse import OptionParser 14 from optparse import OptionParser
15 15
16 required_tools = ["python", "diff", "grep", "unzip", "gunzip", "bunzip2", "sed"] 16 required_tools = ["python", "diff", "grep", "unzip", "gunzip", "bunzip2", "sed"]
17 17
18 parser = OptionParser() 18 parser = OptionParser("%prog [options] [tests]")
19 parser.add_option("-v", "--verbose", action="store_true", dest="verbose", 19 parser.add_option("-v", "--verbose", action="store_true",
20 default=False, help="output verbose messages") 20 help="output verbose messages")
21 parser.add_option("-c", "--cover", action="store_true",
22 help="print a test coverage report")
23 parser.add_option("-s", "--cover_stdlib", action="store_true",
24 help="print a test coverage report inc. standard libraries")
25 parser.add_option("-C", "--annotate", action="store_true",
26 help="output files annotated with coverage")
21 (options, args) = parser.parse_args() 27 (options, args) = parser.parse_args()
22 verbose = options.verbose 28 verbose = options.verbose
29 coverage = options.cover or options.cover_stdlib or options.annotate
23 30
24 def vlog(*msg): 31 def vlog(*msg):
25 if verbose: 32 if verbose:
26 for m in msg: 33 for m in msg:
27 print m, 34 print m,
57 print "# Cleaning up HGTMP", HGTMP 64 print "# Cleaning up HGTMP", HGTMP
58 shutil.rmtree(HGTMP, True) 65 shutil.rmtree(HGTMP, True)
59 66
60 def install_hg(): 67 def install_hg():
61 vlog("# Performing temporary installation of HG") 68 vlog("# Performing temporary installation of HG")
62 INST = os.path.join(HGTMP, "install")
63 BINDIR = os.path.join(INST, "bin")
64 PYTHONDIR = os.path.join(INST, "lib", "python")
65 installerrs = os.path.join("tests", "install.err") 69 installerrs = os.path.join("tests", "install.err")
66 70
67 os.chdir("..") # Get back to hg root 71 os.chdir("..") # Get back to hg root
68 cmd = '%s setup.py install --home="%s" --install-lib="%s" >%s 2>&1' % \ 72 cmd = '%s setup.py install --home="%s" --install-lib="%s" >%s 2>&1' % \
69 (sys.executable, INST, PYTHONDIR, installerrs) 73 (sys.executable, INST, PYTHONDIR, installerrs)
79 sys.exit(1) 83 sys.exit(1)
80 os.chdir(TESTDIR) 84 os.chdir(TESTDIR)
81 85
82 os.environ["PATH"] = "%s%s%s" % (BINDIR, os.pathsep, os.environ["PATH"]) 86 os.environ["PATH"] = "%s%s%s" % (BINDIR, os.pathsep, os.environ["PATH"])
83 os.environ["PYTHONPATH"] = PYTHONDIR 87 os.environ["PYTHONPATH"] = PYTHONDIR
88
89 if coverage:
90 vlog("# Installing coverage wrapper")
91 os.environ['COVERAGE_FILE'] = COVERAGE_FILE
92 if os.path.exists(COVERAGE_FILE):
93 os.unlink(COVERAGE_FILE)
94 # Create a wrapper script to invoke hg via coverage.py
95 os.rename(os.path.join(BINDIR, "hg"), os.path.join(BINDIR, "_hg.py"))
96 f = open(os.path.join(BINDIR, 'hg'), 'w')
97 f.write('#!' + sys.executable + '\n')
98 f.write('import sys, os; os.execv(sys.executable, [sys.executable, '+ \
99 '"%s", "-x", "%s"] + sys.argv[1:])\n' % (
100 os.path.join(TESTDIR, 'coverage.py'),
101 os.path.join(BINDIR, '_hg.py')))
102 f.close()
103 os.chmod(os.path.join(BINDIR, 'hg'), 0700)
104
105 def output_coverage():
106 if coverage:
107 vlog("# Producing coverage report")
108 omit = [BINDIR, TESTDIR, PYTHONDIR]
109 if not options.cover_stdlib:
110 # Exclude as system paths (ignoring empty strings seen on win)
111 omit += [x for x in sys.path if x != '']
112 omit = ','.join(omit)
113 os.chdir(PYTHONDIR)
114 cmd = '"%s" "%s" -r "--omit=%s"' % (
115 sys.executable, os.path.join(TESTDIR, 'coverage.py'), omit)
116 vlog("# Running: "+cmd)
117 os.system(cmd)
118 if options.annotate:
119 adir = os.path.join(TESTDIR, 'annotated')
120 if not os.path.isdir(adir):
121 os.mkdir(adir)
122 cmd = '"%s" "%s" -a "--directory=%s" "--omit=%s"' % (
123 sys.executable, os.path.join(TESTDIR, 'coverage.py'),
124 adir, omit)
125 vlog("# Running: "+cmd)
126 os.system(cmd)
84 127
85 def run(cmd, split_lines=True): 128 def run(cmd, split_lines=True):
86 """Run command in a sub-process, capturing the output (stdout and stderr). 129 """Run command in a sub-process, capturing the output (stdout and stderr).
87 Return the exist code, and output.""" 130 Return the exist code, and output."""
88 # TODO: Use subprocess.Popen if we're running on Python 2.4 131 # TODO: Use subprocess.Popen if we're running on Python 2.4
175 TESTDIR = os.environ["TESTDIR"] = os.getcwd() 218 TESTDIR = os.environ["TESTDIR"] = os.getcwd()
176 HGTMP = os.environ["HGTMP"] = tempfile.mkdtemp("", "hgtests.") 219 HGTMP = os.environ["HGTMP"] = tempfile.mkdtemp("", "hgtests.")
177 vlog("# Using TESTDIR", TESTDIR) 220 vlog("# Using TESTDIR", TESTDIR)
178 vlog("# Using HGTMP", HGTMP) 221 vlog("# Using HGTMP", HGTMP)
179 222
223 INST = os.path.join(HGTMP, "install")
224 BINDIR = os.path.join(INST, "bin")
225 PYTHONDIR = os.path.join(INST, "lib", "python")
226 COVERAGE_FILE = os.path.join(TESTDIR, ".coverage")
227
180 try: 228 try:
181 install_hg() 229 install_hg()
182 230
183 tests = 0 231 tests = 0
184 failed = 0 232 failed = 0
192 if not run_one(test): 240 if not run_one(test):
193 failed += 1 241 failed += 1
194 tests += 1 242 tests += 1
195 243
196 print "\n# Ran %d tests, %d failed." % (tests, failed) 244 print "\n# Ran %d tests, %d failed." % (tests, failed)
245 output_coverage()
197 finally: 246 finally:
198 cleanup_exit() 247 cleanup_exit()
199 248
200 if failed: 249 if failed:
201 sys.exit(1) 250 sys.exit(1)