comparison tests/run-tests.py @ 43283:96eb9ef777a8

run-tests: make code coverage work on Python 3 This code path was obviously not tested on Python 3 because it blew up in several places due to str/bytes mismatch. For internal code, we normalize paths to bytes. For code calling into `coverage`, we normalize paths to str, which is what `coverage` seems to expect. After this, `run-tests.py -H` works on Python 3! Differential Revision: https://phab.mercurial-scm.org/D7133
author Gregory Szorc <gregory.szorc@gmail.com>
date Thu, 17 Oct 2019 20:40:12 -0700
parents 2372284d9457
children b4b1131187c4
comparison
equal deleted inserted replaced
43282:47946f08e463 43283:96eb9ef777a8
3512 f.write(data) 3512 f.write(data)
3513 else: 3513 else:
3514 print('WARNING: cannot fix hg.bat reference to python.exe') 3514 print('WARNING: cannot fix hg.bat reference to python.exe')
3515 3515
3516 if self.options.anycoverage: 3516 if self.options.anycoverage:
3517 custom = os.path.join(osenvironb[b'RUNTESTDIR'], 'sitecustomize.py') 3517 custom = os.path.join(
3518 target = os.path.join(self._pythondir, 'sitecustomize.py') 3518 osenvironb[b'RUNTESTDIR'], b'sitecustomize.py'
3519 )
3520 target = os.path.join(self._pythondir, b'sitecustomize.py')
3519 vlog('# Installing coverage trigger to %s' % target) 3521 vlog('# Installing coverage trigger to %s' % target)
3520 shutil.copyfile(custom, target) 3522 shutil.copyfile(custom, target)
3521 rc = os.path.join(self._testdir, '.coveragerc') 3523 rc = os.path.join(self._testdir, b'.coveragerc')
3522 vlog('# Installing coverage rc to %s' % rc) 3524 vlog('# Installing coverage rc to %s' % rc)
3523 os.environ['COVERAGE_PROCESS_START'] = rc 3525 osenvironb[b'COVERAGE_PROCESS_START'] = rc
3524 covdir = os.path.join(self._installdir, '..', 'coverage') 3526 covdir = os.path.join(self._installdir, b'..', b'coverage')
3525 try: 3527 try:
3526 os.mkdir(covdir) 3528 os.mkdir(covdir)
3527 except OSError as e: 3529 except OSError as e:
3528 if e.errno != errno.EEXIST: 3530 if e.errno != errno.EEXIST:
3529 raise 3531 raise
3530 3532
3531 os.environ['COVERAGE_DIR'] = covdir 3533 osenvironb[b'COVERAGE_DIR'] = covdir
3532 3534
3533 def _checkhglib(self, verb): 3535 def _checkhglib(self, verb):
3534 """Ensure that the 'mercurial' package imported by python is 3536 """Ensure that the 'mercurial' package imported by python is
3535 the one we expect it to be. If not, print a warning to stderr.""" 3537 the one we expect it to be. If not, print a warning to stderr."""
3536 if (self._bindir == self._pythondir) and ( 3538 if (self._bindir == self._pythondir) and (
3600 3602
3601 vlog('# Producing coverage report') 3603 vlog('# Producing coverage report')
3602 # chdir is the easiest way to get short, relative paths in the 3604 # chdir is the easiest way to get short, relative paths in the
3603 # output. 3605 # output.
3604 os.chdir(self._hgroot) 3606 os.chdir(self._hgroot)
3605 covdir = os.path.join(self._installdir, '..', 'coverage') 3607 covdir = os.path.join(_strpath(self._installdir), '..', 'coverage')
3606 cov = coverage(data_file=os.path.join(covdir, 'cov')) 3608 cov = coverage(data_file=os.path.join(covdir, 'cov'))
3607 3609
3608 # Map install directory paths back to source directory. 3610 # Map install directory paths back to source directory.
3609 cov.config.paths['srcdir'] = ['.', self._pythondir] 3611 cov.config.paths['srcdir'] = ['.', _strpath(self._pythondir)]
3610 3612
3611 cov.combine() 3613 cov.combine()
3612 3614
3613 omit = [os.path.join(x, '*') for x in [self._bindir, self._testdir]] 3615 omit = [
3616 _strpath(os.path.join(x, b'*'))
3617 for x in [self._bindir, self._testdir]
3618 ]
3614 cov.report(ignore_errors=True, omit=omit) 3619 cov.report(ignore_errors=True, omit=omit)
3615 3620
3616 if self.options.htmlcov: 3621 if self.options.htmlcov:
3617 htmldir = os.path.join(self._outputdir, 'htmlcov') 3622 htmldir = os.path.join(_strpath(self._outputdir), 'htmlcov')
3618 cov.html_report(directory=htmldir, omit=omit) 3623 cov.html_report(directory=htmldir, omit=omit)
3619 if self.options.annotate: 3624 if self.options.annotate:
3620 adir = os.path.join(self._outputdir, 'annotated') 3625 adir = os.path.join(_strpath(self._outputdir), 'annotated')
3621 if not os.path.isdir(adir): 3626 if not os.path.isdir(adir):
3622 os.mkdir(adir) 3627 os.mkdir(adir)
3623 cov.annotate(directory=adir, omit=omit) 3628 cov.annotate(directory=adir, omit=omit)
3624 3629
3625 def _findprogram(self, program): 3630 def _findprogram(self, program):