comparison tests/run-tests.py @ 8097:eea3c1a8fba8

run-tests: removed some underscores (coding style)
author Martin Geisler <mg@lazybytes.net>
date Tue, 21 Apr 2009 11:19:10 +0200
parents a110d7a20f3f
children 0eeb4f0a5d21
comparison
equal deleted inserted replaced
8096:a110d7a20f3f 8097:eea3c1a8fba8
37 SKIPPED_STATUS = 80 37 SKIPPED_STATUS = 80
38 SKIPPED_PREFIX = 'skipped: ' 38 SKIPPED_PREFIX = 'skipped: '
39 FAILED_PREFIX = 'hghave check failed: ' 39 FAILED_PREFIX = 'hghave check failed: '
40 PYTHON = sys.executable 40 PYTHON = sys.executable
41 41
42 required_tools = ["python", "diff", "grep", "unzip", "gunzip", "bunzip2", "sed"] 42 requiredtools = ["python", "diff", "grep", "unzip", "gunzip", "bunzip2", "sed"]
43 43
44 defaults = { 44 defaults = {
45 'jobs': ('HGTEST_JOBS', 1), 45 'jobs': ('HGTEST_JOBS', 1),
46 'timeout': ('HGTEST_TIMEOUT', 180), 46 'timeout': ('HGTEST_TIMEOUT', 180),
47 'port': ('HGTEST_PORT', 20059), 47 'port': ('HGTEST_PORT', 20059),
48 } 48 }
49 49
50 def parse_args(): 50 def parseargs():
51 parser = optparse.OptionParser("%prog [options] [tests]") 51 parser = optparse.OptionParser("%prog [options] [tests]")
52 parser.add_option("-C", "--annotate", action="store_true", 52 parser.add_option("-C", "--annotate", action="store_true",
53 help="output files annotated with coverage") 53 help="output files annotated with coverage")
54 parser.add_option("--child", type="int", 54 parser.add_option("--child", type="int",
55 help="run as child process, summary to given fd") 55 help="run as child process, summary to given fd")
135 lines.append(last) 135 lines.append(last)
136 return lines 136 return lines
137 lines.append(text[i:n+1]) 137 lines.append(text[i:n+1])
138 i = n + 1 138 i = n + 1
139 139
140 def parse_hghave_output(lines): 140 def parsehghaveoutput(lines):
141 '''Parse hghave log lines. 141 '''Parse hghave log lines.
142 Return tuple of lists (missing, failed): 142 Return tuple of lists (missing, failed):
143 * the missing/unknown features 143 * the missing/unknown features
144 * the features for which existence check failed''' 144 * the features for which existence check failed'''
145 missing = [] 145 missing = []
152 line = line.splitlines()[0] 152 line = line.splitlines()[0]
153 failed.append(line[len(FAILED_PREFIX):]) 153 failed.append(line[len(FAILED_PREFIX):])
154 154
155 return missing, failed 155 return missing, failed
156 156
157 def show_diff(expected, output): 157 def showdiff(expected, output):
158 for line in difflib.unified_diff(expected, output, 158 for line in difflib.unified_diff(expected, output,
159 "Expected output", "Test output"): 159 "Expected output", "Test output"):
160 sys.stdout.write(line) 160 sys.stdout.write(line)
161 161
162 def find_program(program): 162 def findprogram(program):
163 """Search PATH for a executable program""" 163 """Search PATH for a executable program"""
164 for p in os.environ.get('PATH', os.defpath).split(os.pathsep): 164 for p in os.environ.get('PATH', os.defpath).split(os.pathsep):
165 name = os.path.join(p, program) 165 name = os.path.join(p, program)
166 if os.access(name, os.X_OK): 166 if os.access(name, os.X_OK):
167 return name 167 return name
168 return None 168 return None
169 169
170 def check_required_tools(): 170 def checktools():
171 # Before we go any further, check for pre-requisite tools 171 # Before we go any further, check for pre-requisite tools
172 # stuff from coreutils (cat, rm, etc) are not tested 172 # stuff from coreutils (cat, rm, etc) are not tested
173 for p in required_tools: 173 for p in requiredtools:
174 if os.name == 'nt': 174 if os.name == 'nt':
175 p += '.exe' 175 p += '.exe'
176 found = find_program(p) 176 found = findprogram(p)
177 if found: 177 if found:
178 vlog("# Found prerequisite", p, "at", found) 178 vlog("# Found prerequisite", p, "at", found)
179 else: 179 else:
180 print "WARNING: Did not find prerequisite tool: "+p 180 print "WARNING: Did not find prerequisite tool: "+p
181 181
182 def cleanup_exit(options): 182 def cleanup(options):
183 if not options.keep_tmpdir: 183 if not options.keep_tmpdir:
184 if options.verbose: 184 if options.verbose:
185 print "# Cleaning up HGTMP", HGTMP 185 print "# Cleaning up HGTMP", HGTMP
186 shutil.rmtree(HGTMP, True) 186 shutil.rmtree(HGTMP, True)
187 187
188 def use_correct_python(): 188 def usecorrectpython():
189 # some tests run python interpreter. they must use same 189 # some tests run python interpreter. they must use same
190 # interpreter we use or bad things will happen. 190 # interpreter we use or bad things will happen.
191 exedir, exename = os.path.split(sys.executable) 191 exedir, exename = os.path.split(sys.executable)
192 if exename == 'python': 192 if exename == 'python':
193 path = find_program('python') 193 path = findprogram('python')
194 if os.path.dirname(path) == exedir: 194 if os.path.dirname(path) == exedir:
195 return 195 return
196 vlog('# Making python executable in test path use correct Python') 196 vlog('# Making python executable in test path use correct Python')
197 my_python = os.path.join(BINDIR, 'python') 197 mypython = os.path.join(BINDIR, 'python')
198 try: 198 try:
199 os.symlink(sys.executable, my_python) 199 os.symlink(sys.executable, mypython)
200 except AttributeError: 200 except AttributeError:
201 # windows fallback 201 # windows fallback
202 shutil.copyfile(sys.executable, my_python) 202 shutil.copyfile(sys.executable, mypython)
203 shutil.copymode(sys.executable, my_python) 203 shutil.copymode(sys.executable, mypython)
204 204
205 def install_hg(options): 205 def installhg(options):
206 global PYTHON 206 global PYTHON
207 vlog("# Performing temporary installation of HG") 207 vlog("# Performing temporary installation of HG")
208 installerrs = os.path.join("tests", "install.err") 208 installerrs = os.path.join("tests", "install.err")
209 pure = options.pure and "--pure" or "" 209 pure = options.pure and "--pure" or ""
210 210
234 pythonpath = pydir + os.pathsep + pythonpath 234 pythonpath = pydir + os.pathsep + pythonpath
235 else: 235 else:
236 pythonpath = pydir 236 pythonpath = pydir
237 os.environ["PYTHONPATH"] = pythonpath 237 os.environ["PYTHONPATH"] = pythonpath
238 238
239 use_correct_python() 239 usecorrectpython()
240 global hgpkg 240 global hgpkg
241 hgpkg = _hgpath() 241 hgpkg = _hgpath()
242 242
243 vlog("# Installing dummy diffstat") 243 vlog("# Installing dummy diffstat")
244 f = open(os.path.join(BINDIR, 'diffstat'), 'w') 244 f = open(os.path.join(BINDIR, 'diffstat'), 'w')
275 hgpath = os.popen(cmd % PYTHON) 275 hgpath = os.popen(cmd % PYTHON)
276 path = hgpath.read().strip() 276 path = hgpath.read().strip()
277 hgpath.close() 277 hgpath.close()
278 return path 278 return path
279 279
280 def output_coverage(options): 280 def outputcoverage(options):
281 vlog("# Producing coverage report") 281 vlog("# Producing coverage report")
282 omit = [BINDIR, TESTDIR, PYTHONDIR] 282 omit = [BINDIR, TESTDIR, PYTHONDIR]
283 if not options.cover_stdlib: 283 if not options.cover_stdlib:
284 # Exclude as system paths (ignoring empty strings seen on win) 284 # Exclude as system paths (ignoring empty strings seen on win)
285 omit += [x for x in sys.path if x != ''] 285 omit += [x for x in sys.path if x != '']
333 ret = signal.SIGTERM << 8 333 ret = signal.SIGTERM << 8
334 output += ("\n### Abort: timeout after %d seconds.\n" 334 output += ("\n### Abort: timeout after %d seconds.\n"
335 % options.timeout) 335 % options.timeout)
336 return ret, splitnewlines(output) 336 return ret, splitnewlines(output)
337 337
338 def run_one(options, test, skips, fails): 338 def runone(options, test, skips, fails):
339 '''tristate output: 339 '''tristate output:
340 None -> skipped 340 None -> skipped
341 True -> passed 341 True -> passed
342 False -> failed''' 342 False -> failed'''
343 343
421 421
422 skipped = (ret == SKIPPED_STATUS) 422 skipped = (ret == SKIPPED_STATUS)
423 # If reference output file exists, check test output against it 423 # If reference output file exists, check test output against it
424 if os.path.exists(ref): 424 if os.path.exists(ref):
425 f = open(ref, "r") 425 f = open(ref, "r")
426 ref_out = splitnewlines(f.read()) 426 refout = splitnewlines(f.read())
427 f.close() 427 f.close()
428 else: 428 else:
429 ref_out = [] 429 refout = []
430 if skipped: 430 if skipped:
431 mark = 's' 431 mark = 's'
432 missing, failed = parse_hghave_output(out) 432 missing, failed = parsehghaveoutput(out)
433 if not missing: 433 if not missing:
434 missing = ['irrelevant'] 434 missing = ['irrelevant']
435 if failed: 435 if failed:
436 fail("hghave failed checking for %s" % failed[-1]) 436 fail("hghave failed checking for %s" % failed[-1])
437 skipped = False 437 skipped = False
438 else: 438 else:
439 skip(missing[-1]) 439 skip(missing[-1])
440 elif out != ref_out: 440 elif out != refout:
441 mark = '!' 441 mark = '!'
442 if ret: 442 if ret:
443 fail("output changed and returned error code %d" % ret) 443 fail("output changed and returned error code %d" % ret)
444 else: 444 else:
445 fail("output changed") 445 fail("output changed")
446 if not options.nodiff: 446 if not options.nodiff:
447 show_diff(ref_out, out) 447 showdiff(refout, out)
448 ret = 1 448 ret = 1
449 elif ret: 449 elif ret:
450 mark = '!' 450 mark = '!'
451 fail("returned error code %d" % ret) 451 fail("returned error code %d" % ret)
452 452
490 shutil.rmtree(tmpd, True) 490 shutil.rmtree(tmpd, True)
491 if skipped: 491 if skipped:
492 return None 492 return None
493 return ret == 0 493 return ret == 0
494 494
495 def run_children(options, expecthg, tests): 495 def runchildren(options, expecthg, tests):
496 if not options.with_hg: 496 if not options.with_hg:
497 install_hg() 497 installhg()
498 if hgpkg != expecthg: 498 if hgpkg != expecthg:
499 print '# Testing unexpected mercurial: %s' % hgpkg 499 print '# Testing unexpected mercurial: %s' % hgpkg
500 500
501 optcopy = dict(options.__dict__) 501 optcopy = dict(options.__dict__)
502 optcopy['jobs'] = 1 502 optcopy['jobs'] = 1
555 print '# Tested unexpected mercurial: %s' % hgpkg 555 print '# Tested unexpected mercurial: %s' % hgpkg
556 print "# Ran %d tests, %d skipped, %d failed." % ( 556 print "# Ran %d tests, %d skipped, %d failed." % (
557 tested, skipped, failed) 557 tested, skipped, failed)
558 sys.exit(failures != 0) 558 sys.exit(failures != 0)
559 559
560 def run_tests(options, expecthg, tests): 560 def runtests(options, expecthg, tests):
561 global DAEMON_PIDS, HGRCPATH 561 global DAEMON_PIDS, HGRCPATH
562 DAEMON_PIDS = os.environ["DAEMON_PIDS"] = os.path.join(HGTMP, 'daemon.pids') 562 DAEMON_PIDS = os.environ["DAEMON_PIDS"] = os.path.join(HGTMP, 'daemon.pids')
563 HGRCPATH = os.environ["HGRCPATH"] = os.path.join(HGTMP, '.hgrc') 563 HGRCPATH = os.environ["HGRCPATH"] = os.path.join(HGTMP, '.hgrc')
564 564
565 try: 565 try:
566 if not options.with_hg: 566 if not options.with_hg:
567 install_hg(options) 567 installhg(options)
568 568
569 if hgpkg != expecthg: 569 if hgpkg != expecthg:
570 print '# Testing unexpected mercurial: %s' % hgpkg 570 print '# Testing unexpected mercurial: %s' % hgpkg
571 571
572 if options.timeout > 0: 572 if options.timeout > 0:
596 fails = [] 596 fails = []
597 for test in tests: 597 for test in tests:
598 if options.retest and not os.path.exists(test + ".err"): 598 if options.retest and not os.path.exists(test + ".err"):
599 skipped += 1 599 skipped += 1
600 continue 600 continue
601 ret = run_one(options, test, skips, fails) 601 ret = runone(options, test, skips, fails)
602 if ret is None: 602 if ret is None:
603 skipped += 1 603 skipped += 1
604 elif not ret: 604 elif not ret:
605 if options.interactive: 605 if options.interactive:
606 print "Accept this change? [n] ", 606 print "Accept this change? [n] ",
633 print '# Tested unexpected mercurial: %s' % hgpkg 633 print '# Tested unexpected mercurial: %s' % hgpkg
634 print "# Ran %d tests, %d skipped, %d failed." % ( 634 print "# Ran %d tests, %d skipped, %d failed." % (
635 tested, skipped, failed) 635 tested, skipped, failed)
636 636
637 if options.anycoverage: 637 if options.anycoverage:
638 output_coverage(options) 638 outputcoverage(options)
639 except KeyboardInterrupt: 639 except KeyboardInterrupt:
640 failed = True 640 failed = True
641 print "\ninterrupted!" 641 print "\ninterrupted!"
642 642
643 if failed: 643 if failed:
644 sys.exit(1) 644 sys.exit(1)
645 645
646 def main(): 646 def main():
647 (options, args) = parse_args() 647 (options, args) = parseargs()
648 if not options.child: 648 if not options.child:
649 os.umask(022) 649 os.umask(022)
650 650
651 check_required_tools() 651 checktools()
652 652
653 # Reset some environment variables to well-known values so that 653 # Reset some environment variables to well-known values so that
654 # the tests produce repeatable output. 654 # the tests produce repeatable output.
655 os.environ['LANG'] = os.environ['LC_ALL'] = 'C' 655 os.environ['LANG'] = os.environ['LC_ALL'] = 'C'
656 os.environ['TZ'] = 'GMT' 656 os.environ['TZ'] = 'GMT'
698 vlog("# Using TESTDIR", TESTDIR) 698 vlog("# Using TESTDIR", TESTDIR)
699 vlog("# Using HGTMP", HGTMP) 699 vlog("# Using HGTMP", HGTMP)
700 700
701 try: 701 try:
702 if len(tests) > 1 and options.jobs > 1: 702 if len(tests) > 1 and options.jobs > 1:
703 run_children(options, expecthg, tests) 703 runchildren(options, expecthg, tests)
704 else: 704 else:
705 run_tests(options, expecthg, tests) 705 runtests(options, expecthg, tests)
706 finally: 706 finally:
707 cleanup_exit(options) 707 cleanup(options)
708 708
709 main() 709 main()