##// END OF EJS Templates
tests: use external coverage, mandate newer version...
Dirkjan Ochtman -
r10648:58128004 stable
parent child Browse files
Show More
@@ -0,0 +1,6 b''
1 try:
2 import coverage
3 if hasattr(coverage, 'process_startup'):
4 coverage.process_startup()
5 except ImportError:
6 pass
@@ -41,6 +41,7 b''
41 # completes fairly quickly, includes both shell and Python scripts, and
41 # completes fairly quickly, includes both shell and Python scripts, and
42 # includes some scripts that run daemon processes.)
42 # includes some scripts that run daemon processes.)
43
43
44 from distutils import version
44 import difflib
45 import difflib
45 import errno
46 import errno
46 import optparse
47 import optparse
@@ -110,8 +111,6 b' def parseargs():'
110 " (default: $%s or %d)" % defaults['port'])
111 " (default: $%s or %d)" % defaults['port'])
111 parser.add_option("-r", "--retest", action="store_true",
112 parser.add_option("-r", "--retest", action="store_true",
112 help="retest failed tests")
113 help="retest failed tests")
113 parser.add_option("-s", "--cover_stdlib", action="store_true",
114 help="print a test coverage report inc. standard libraries")
115 parser.add_option("-S", "--noskips", action="store_true",
114 parser.add_option("-S", "--noskips", action="store_true",
116 help="don't report skip tests verbosely")
115 help="don't report skip tests verbosely")
117 parser.add_option("-t", "--timeout", type="int",
116 parser.add_option("-t", "--timeout", type="int",
@@ -155,16 +154,20 b' def parseargs():'
155 % hgbin)
154 % hgbin)
156 options.with_hg = hgbin
155 options.with_hg = hgbin
157
156
158 options.anycoverage = (options.cover or
157 options.anycoverage = options.cover or options.annotate
159 options.cover_stdlib or
158 if options.anycoverage:
160 options.annotate)
159 try:
160 import coverage
161 covver = version.StrictVersion(coverage.__version__).version
162 if covver < (3, 3):
163 parser.error('coverage options require coverage 3.3 or later')
164 except ImportError:
165 parser.error('coverage options now require the coverage package')
161
166
162 if options.anycoverage and options.with_hg:
167 if options.anycoverage and options.local:
163 # I'm not sure if this is a fundamental limitation or just a
168 # this needs some path mangling somewhere, I guess
164 # bug. But I don't want to waste people's time and energy doing
169 parser.error("sorry, coverage options do not work when --local "
165 # test runs that don't give the results they want.
170 "is specified")
166 parser.error("sorry, coverage options do not work when --with-hg "
167 "or --local specified")
168
171
169 global vlog
172 global vlog
170 if options.verbose:
173 if options.verbose:
@@ -390,20 +393,15 b' def installhg(options):'
390 f.close()
393 f.close()
391
394
392 if options.anycoverage:
395 if options.anycoverage:
393 vlog("# Installing coverage wrapper")
396 custom = os.path.join(TESTDIR, 'sitecustomize.py')
394 os.environ['COVERAGE_FILE'] = COVERAGE_FILE
397 target = os.path.join(PYTHONDIR, 'sitecustomize.py')
395 if os.path.exists(COVERAGE_FILE):
398 vlog('# Installing coverage trigger to %s' % target)
396 os.unlink(COVERAGE_FILE)
399 shutil.copyfile(custom, target)
397 # Create a wrapper script to invoke hg via coverage.py
400 rc = os.path.join(TESTDIR, '.coveragerc')
398 os.rename(os.path.join(BINDIR, "hg"), os.path.join(BINDIR, "_hg.py"))
401 vlog('# Installing coverage rc to %s' % rc)
399 f = open(os.path.join(BINDIR, 'hg'), 'w')
402 os.environ['COVERAGE_PROCESS_START'] = rc
400 f.write('#!' + sys.executable + '\n')
403 fn = os.path.join(INST, '..', '.coverage')
401 f.write('import sys, os; os.execv(sys.executable, [sys.executable, '
404 os.environ['COVERAGE_FILE'] = fn
402 '"%s", "-x", "-p", "%s"] + sys.argv[1:])\n' %
403 (os.path.join(TESTDIR, 'coverage.py'),
404 os.path.join(BINDIR, '_hg.py')))
405 f.close()
406 os.chmod(os.path.join(BINDIR, 'hg'), 0700)
407
405
408 def outputcoverage(options):
406 def outputcoverage(options):
409
407
@@ -411,22 +409,15 b' def outputcoverage(options):'
411 os.chdir(PYTHONDIR)
409 os.chdir(PYTHONDIR)
412
410
413 def covrun(*args):
411 def covrun(*args):
414 start = sys.executable, os.path.join(TESTDIR, 'coverage.py')
412 cmd = 'coverage %s' % ' '.join(args)
415 cmd = '"%s" "%s" %s' % (start[0], start[1], ' '.join(args))
416 vlog('# Running: %s' % cmd)
413 vlog('# Running: %s' % cmd)
417 os.system(cmd)
414 os.system(cmd)
418
415
419 omit = [BINDIR, TESTDIR, PYTHONDIR]
416 if options.child:
420 if not options.cover_stdlib:
417 return
421 # Exclude as system paths (ignoring empty strings seen on win)
422 omit += [x for x in sys.path if x != '']
423 omit = ','.join(omit)
424
418
425 covrun('-c') # combine from parallel processes
419 covrun('-c')
426 for fn in os.listdir(TESTDIR):
420 omit = ','.join([BINDIR, TESTDIR])
427 if fn.startswith('.coverage.'):
428 os.unlink(os.path.join(TESTDIR, fn))
429
430 covrun('-i', '-r', '"--omit=%s"' % omit) # report
421 covrun('-i', '-r', '"--omit=%s"' % omit) # report
431 if options.annotate:
422 if options.annotate:
432 adir = os.path.join(TESTDIR, 'annotated')
423 adir = os.path.join(TESTDIR, 'annotated')
@@ -668,6 +659,8 b' def runchildren(options, tests):'
668 optcopy['jobs'] = 1
659 optcopy['jobs'] = 1
669 if optcopy['with_hg'] is None:
660 if optcopy['with_hg'] is None:
670 optcopy['with_hg'] = os.path.join(BINDIR, "hg")
661 optcopy['with_hg'] = os.path.join(BINDIR, "hg")
662 optcopy.pop('anycoverage', None)
663
671 opts = []
664 opts = []
672 for opt, value in optcopy.iteritems():
665 for opt, value in optcopy.iteritems():
673 name = '--' + opt.replace('_', '-')
666 name = '--' + opt.replace('_', '-')
@@ -729,6 +722,9 b' def runchildren(options, tests):'
729 _checkhglib("Tested")
722 _checkhglib("Tested")
730 print "# Ran %d tests, %d skipped, %d failed." % (
723 print "# Ran %d tests, %d skipped, %d failed." % (
731 tested, skipped, failed)
724 tested, skipped, failed)
725
726 if options.anycoverage:
727 outputcoverage(options)
732 sys.exit(failures != 0)
728 sys.exit(failures != 0)
733
729
734 def runtests(options, tests):
730 def runtests(options, tests):
1 NO CONTENT: file was removed
NO CONTENT: file was removed
This diff has been collapsed as it changes many lines, (1166 lines changed) Show them Hide them
General Comments 0
You need to be logged in to leave comments. Login now