Mercurial > hg
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() |