Mercurial > hg
comparison tests/run-tests.py @ 44448:55c443fcb4fc
tests: rename _bytespath() to _sys2bytes() and _strpath() to _sys2str()
The names were not general enough because e.g. _strpath() was used for
converting IP addresses.
author | Manuel Jacob <me@manueljacob.de> |
---|---|
date | Fri, 06 Mar 2020 09:50:57 +0100 |
parents | fc70291f3d24 |
children | ff72bd52d56a |
comparison
equal
deleted
inserted
replaced
44447:fc70291f3d24 | 44448:55c443fcb4fc |
---|---|
141 | 141 |
142 if sys.version_info > (3, 5, 0): | 142 if sys.version_info > (3, 5, 0): |
143 PYTHON3 = True | 143 PYTHON3 = True |
144 xrange = range # we use xrange in one place, and we'd rather not use range | 144 xrange = range # we use xrange in one place, and we'd rather not use range |
145 | 145 |
146 def _bytespath(p): | 146 def _sys2bytes(p): |
147 if p is None: | 147 if p is None: |
148 return p | 148 return p |
149 return p.encode('utf-8') | 149 return p.encode('utf-8') |
150 | 150 |
151 def _strpath(p): | 151 def _bytes2sys(p): |
152 if p is None: | 152 if p is None: |
153 return p | 153 return p |
154 return p.decode('utf-8') | 154 return p.decode('utf-8') |
155 | 155 |
156 osenvironb = getattr(os, 'environb', None) | 156 osenvironb = getattr(os, 'environb', None) |
163 self.__len__ = strenv.__len__ | 163 self.__len__ = strenv.__len__ |
164 self.clear = strenv.clear | 164 self.clear = strenv.clear |
165 self._strenv = strenv | 165 self._strenv = strenv |
166 | 166 |
167 def __getitem__(self, k): | 167 def __getitem__(self, k): |
168 v = self._strenv.__getitem__(_strpath(k)) | 168 v = self._strenv.__getitem__(_bytes2sys(k)) |
169 return _bytespath(v) | 169 return _sys2bytes(v) |
170 | 170 |
171 def __setitem__(self, k, v): | 171 def __setitem__(self, k, v): |
172 self._strenv.__setitem__(_strpath(k), _strpath(v)) | 172 self._strenv.__setitem__(_bytes2sys(k), _bytes2sys(v)) |
173 | 173 |
174 def __delitem__(self, k): | 174 def __delitem__(self, k): |
175 self._strenv.__delitem__(_strpath(k)) | 175 self._strenv.__delitem__(_bytes2sys(k)) |
176 | 176 |
177 def __contains__(self, k): | 177 def __contains__(self, k): |
178 return self._strenv.__contains__(_strpath(k)) | 178 return self._strenv.__contains__(_bytes2sys(k)) |
179 | 179 |
180 def __iter__(self): | 180 def __iter__(self): |
181 return iter([_bytespath(k) for k in iter(self._strenv)]) | 181 return iter([_sys2bytes(k) for k in iter(self._strenv)]) |
182 | 182 |
183 def get(self, k, default=None): | 183 def get(self, k, default=None): |
184 v = self._strenv.get(_strpath(k), _strpath(default)) | 184 v = self._strenv.get(_bytes2sys(k), _bytes2sys(default)) |
185 return _bytespath(v) | 185 return _sys2bytes(v) |
186 | 186 |
187 def pop(self, k, default=None): | 187 def pop(self, k, default=None): |
188 v = self._strenv.pop(_strpath(k), _strpath(default)) | 188 v = self._strenv.pop(_bytes2sys(k), _bytes2sys(default)) |
189 return _bytespath(v) | 189 return _sys2bytes(v) |
190 | 190 |
191 osenvironb = environbytes(os.environ) | 191 osenvironb = environbytes(os.environ) |
192 | 192 |
193 getcwdb = getattr(os, 'getcwdb') | 193 getcwdb = getattr(os, 'getcwdb') |
194 if not getcwdb or os.name == 'nt': | 194 if not getcwdb or os.name == 'nt': |
195 getcwdb = lambda: _bytespath(os.getcwd()) | 195 getcwdb = lambda: _sys2bytes(os.getcwd()) |
196 | 196 |
197 elif sys.version_info >= (3, 0, 0): | 197 elif sys.version_info >= (3, 0, 0): |
198 print( | 198 print( |
199 '%s is only supported on Python 3.5+ and 2.7, not %s' | 199 '%s is only supported on Python 3.5+ and 2.7, not %s' |
200 % (sys.argv[0], '.'.join(str(v) for v in sys.version_info[:3])) | 200 % (sys.argv[0], '.'.join(str(v) for v in sys.version_info[:3])) |
205 | 205 |
206 # In python 2.x, path operations are generally done using | 206 # In python 2.x, path operations are generally done using |
207 # bytestrings by default, so we don't have to do any extra | 207 # bytestrings by default, so we don't have to do any extra |
208 # fiddling there. We define the wrapper functions anyway just to | 208 # fiddling there. We define the wrapper functions anyway just to |
209 # help keep code consistent between platforms. | 209 # help keep code consistent between platforms. |
210 def _bytespath(p): | 210 def _sys2bytes(p): |
211 return p | 211 return p |
212 | 212 |
213 _strpath = _bytespath | 213 _bytes2sys = _sys2bytes |
214 osenvironb = os.environ | 214 osenvironb = os.environ |
215 getcwdb = os.getcwd | 215 getcwdb = os.getcwd |
216 | 216 |
217 # For Windows support | 217 # For Windows support |
218 wifexited = getattr(os, "WIFEXITED", lambda x: False) | 218 wifexited = getattr(os, "WIFEXITED", lambda x: False) |
272 | 272 |
273 | 273 |
274 def Popen4(cmd, wd, timeout, env=None): | 274 def Popen4(cmd, wd, timeout, env=None): |
275 processlock.acquire() | 275 processlock.acquire() |
276 p = subprocess.Popen( | 276 p = subprocess.Popen( |
277 _strpath(cmd), | 277 _bytes2sys(cmd), |
278 shell=True, | 278 shell=True, |
279 bufsize=-1, | 279 bufsize=-1, |
280 cwd=_strpath(wd), | 280 cwd=_bytes2sys(wd), |
281 env=env, | 281 env=env, |
282 close_fds=closefds, | 282 close_fds=closefds, |
283 stdin=subprocess.PIPE, | 283 stdin=subprocess.PIPE, |
284 stdout=subprocess.PIPE, | 284 stdout=subprocess.PIPE, |
285 stderr=subprocess.STDOUT, | 285 stderr=subprocess.STDOUT, |
313 elif os.environ.get('PYTHON'): | 313 elif os.environ.get('PYTHON'): |
314 sysexecutable = os.environ['PYTHON'] | 314 sysexecutable = os.environ['PYTHON'] |
315 else: | 315 else: |
316 raise AssertionError('Could not find Python interpreter') | 316 raise AssertionError('Could not find Python interpreter') |
317 | 317 |
318 PYTHON = _bytespath(sysexecutable.replace('\\', '/')) | 318 PYTHON = _sys2bytes(sysexecutable.replace('\\', '/')) |
319 IMPL_PATH = b'PYTHONPATH' | 319 IMPL_PATH = b'PYTHONPATH' |
320 if 'java' in sys.platform: | 320 if 'java' in sys.platform: |
321 IMPL_PATH = b'JYTHONPATH' | 321 IMPL_PATH = b'JYTHONPATH' |
322 | 322 |
323 defaults = { | 323 defaults = { |
638 options.pure = True | 638 options.pure = True |
639 | 639 |
640 if options.local: | 640 if options.local: |
641 if options.with_hg or options.with_chg: | 641 if options.with_hg or options.with_chg: |
642 parser.error('--local cannot be used with --with-hg or --with-chg') | 642 parser.error('--local cannot be used with --with-hg or --with-chg') |
643 testdir = os.path.dirname(_bytespath(canonpath(sys.argv[0]))) | 643 testdir = os.path.dirname(_sys2bytes(canonpath(sys.argv[0]))) |
644 reporootdir = os.path.dirname(testdir) | 644 reporootdir = os.path.dirname(testdir) |
645 pathandattrs = [(b'hg', 'with_hg')] | 645 pathandattrs = [(b'hg', 'with_hg')] |
646 if options.chg: | 646 if options.chg: |
647 pathandattrs.append((b'contrib/chg/chg', 'with_chg')) | 647 pathandattrs.append((b'contrib/chg/chg', 'with_chg')) |
648 for relpath, attr in pathandattrs: | 648 for relpath, attr in pathandattrs: |
650 if os.name != 'nt' and not os.access(binpath, os.X_OK): | 650 if os.name != 'nt' and not os.access(binpath, os.X_OK): |
651 parser.error( | 651 parser.error( |
652 '--local specified, but %r not found or ' | 652 '--local specified, but %r not found or ' |
653 'not executable' % binpath | 653 'not executable' % binpath |
654 ) | 654 ) |
655 setattr(options, attr, _strpath(binpath)) | 655 setattr(options, attr, _bytes2sys(binpath)) |
656 | 656 |
657 if options.with_hg: | 657 if options.with_hg: |
658 options.with_hg = canonpath(_bytespath(options.with_hg)) | 658 options.with_hg = canonpath(_sys2bytes(options.with_hg)) |
659 if not ( | 659 if not ( |
660 os.path.isfile(options.with_hg) | 660 os.path.isfile(options.with_hg) |
661 and os.access(options.with_hg, os.X_OK) | 661 and os.access(options.with_hg, os.X_OK) |
662 ): | 662 ): |
663 parser.error('--with-hg must specify an executable hg script') | 663 parser.error('--with-hg must specify an executable hg script') |
667 | 667 |
668 if (options.chg or options.with_chg) and os.name == 'nt': | 668 if (options.chg or options.with_chg) and os.name == 'nt': |
669 parser.error('chg does not work on %s' % os.name) | 669 parser.error('chg does not work on %s' % os.name) |
670 if options.with_chg: | 670 if options.with_chg: |
671 options.chg = False # no installation to temporary location | 671 options.chg = False # no installation to temporary location |
672 options.with_chg = canonpath(_bytespath(options.with_chg)) | 672 options.with_chg = canonpath(_sys2bytes(options.with_chg)) |
673 if not ( | 673 if not ( |
674 os.path.isfile(options.with_chg) | 674 os.path.isfile(options.with_chg) |
675 and os.access(options.with_chg, os.X_OK) | 675 and os.access(options.with_chg, os.X_OK) |
676 ): | 676 ): |
677 parser.error('--with-chg must specify a chg executable') | 677 parser.error('--with-chg must specify a chg executable') |
940 startport = defaults['port'] | 940 startport = defaults['port'] |
941 if slowtimeout is None: | 941 if slowtimeout is None: |
942 slowtimeout = defaults['slowtimeout'] | 942 slowtimeout = defaults['slowtimeout'] |
943 self.path = path | 943 self.path = path |
944 self.bname = os.path.basename(path) | 944 self.bname = os.path.basename(path) |
945 self.name = _strpath(self.bname) | 945 self.name = _bytes2sys(self.bname) |
946 self._testdir = os.path.dirname(path) | 946 self._testdir = os.path.dirname(path) |
947 self._outputdir = outputdir | 947 self._outputdir = outputdir |
948 self._tmpname = os.path.basename(path) | 948 self._tmpname = os.path.basename(path) |
949 self.errpath = os.path.join(self._outputdir, b'%s.err' % self.bname) | 949 self.errpath = os.path.join(self._outputdir, b'%s.err' % self.bname) |
950 | 950 |
954 self._first = first | 954 self._first = first |
955 self._timeout = timeout | 955 self._timeout = timeout |
956 self._slowtimeout = slowtimeout | 956 self._slowtimeout = slowtimeout |
957 self._startport = startport | 957 self._startport = startport |
958 self._extraconfigopts = extraconfigopts or [] | 958 self._extraconfigopts = extraconfigopts or [] |
959 self._shell = _bytespath(shell) | 959 self._shell = _sys2bytes(shell) |
960 self._hgcommand = hgcommand or b'hg' | 960 self._hgcommand = hgcommand or b'hg' |
961 self._usechg = usechg | 961 self._usechg = usechg |
962 self._useipv6 = useipv6 | 962 self._useipv6 = useipv6 |
963 | 963 |
964 self._aborted = False | 964 self._aborted = False |
1266 def _genrestoreenv(self, testenv): | 1266 def _genrestoreenv(self, testenv): |
1267 """Generate a script that can be used by tests to restore the original | 1267 """Generate a script that can be used by tests to restore the original |
1268 environment.""" | 1268 environment.""" |
1269 # Put the restoreenv script inside self._threadtmp | 1269 # Put the restoreenv script inside self._threadtmp |
1270 scriptpath = os.path.join(self._threadtmp, b'restoreenv.sh') | 1270 scriptpath = os.path.join(self._threadtmp, b'restoreenv.sh') |
1271 testenv['HGTEST_RESTOREENV'] = _strpath(scriptpath) | 1271 testenv['HGTEST_RESTOREENV'] = _bytes2sys(scriptpath) |
1272 | 1272 |
1273 # Only restore environment variable names that the shell allows | 1273 # Only restore environment variable names that the shell allows |
1274 # us to export. | 1274 # us to export. |
1275 name_regex = re.compile('^[a-zA-Z][a-zA-Z0-9_]*$') | 1275 name_regex = re.compile('^[a-zA-Z][a-zA-Z0-9_]*$') |
1276 | 1276 |
1300 env["HGPORT%s" % offset] = '%s' % (self._startport + i) | 1300 env["HGPORT%s" % offset] = '%s' % (self._startport + i) |
1301 | 1301 |
1302 env = os.environ.copy() | 1302 env = os.environ.copy() |
1303 env['PYTHONUSERBASE'] = sysconfig.get_config_var('userbase') or '' | 1303 env['PYTHONUSERBASE'] = sysconfig.get_config_var('userbase') or '' |
1304 env['HGEMITWARNINGS'] = '1' | 1304 env['HGEMITWARNINGS'] = '1' |
1305 env['TESTTMP'] = _strpath(self._testtmp) | 1305 env['TESTTMP'] = _bytes2sys(self._testtmp) |
1306 env['TESTNAME'] = self.name | 1306 env['TESTNAME'] = self.name |
1307 env['HOME'] = _strpath(self._testtmp) | 1307 env['HOME'] = _bytes2sys(self._testtmp) |
1308 # This number should match portneeded in _getport | 1308 # This number should match portneeded in _getport |
1309 for port in xrange(3): | 1309 for port in xrange(3): |
1310 # This list should be parallel to _portmap in _getreplacements | 1310 # This list should be parallel to _portmap in _getreplacements |
1311 defineport(port) | 1311 defineport(port) |
1312 env["HGRCPATH"] = _strpath(os.path.join(self._threadtmp, b'.hgrc')) | 1312 env["HGRCPATH"] = _bytes2sys(os.path.join(self._threadtmp, b'.hgrc')) |
1313 env["DAEMON_PIDS"] = _strpath( | 1313 env["DAEMON_PIDS"] = _bytes2sys( |
1314 os.path.join(self._threadtmp, b'daemon.pids') | 1314 os.path.join(self._threadtmp, b'daemon.pids') |
1315 ) | 1315 ) |
1316 env["HGEDITOR"] = ( | 1316 env["HGEDITOR"] = ( |
1317 '"' + sysexecutable + '"' + ' -c "import sys; sys.exit(0)"' | 1317 '"' + sysexecutable + '"' + ' -c "import sys; sys.exit(0)"' |
1318 ) | 1318 ) |
1340 if extraextensions: | 1340 if extraextensions: |
1341 env['HGTESTEXTRAEXTENSIONS'] = b' '.join(extraextensions) | 1341 env['HGTESTEXTRAEXTENSIONS'] = b' '.join(extraextensions) |
1342 | 1342 |
1343 # LOCALIP could be ::1 or 127.0.0.1. Useful for tests that require raw | 1343 # LOCALIP could be ::1 or 127.0.0.1. Useful for tests that require raw |
1344 # IP addresses. | 1344 # IP addresses. |
1345 env['LOCALIP'] = _strpath(self._localip()) | 1345 env['LOCALIP'] = _bytes2sys(self._localip()) |
1346 | 1346 |
1347 # This has the same effect as Py_LegacyWindowsStdioFlag in exewrapper.c, | 1347 # This has the same effect as Py_LegacyWindowsStdioFlag in exewrapper.c, |
1348 # but this is needed for testing python instances like dummyssh, | 1348 # but this is needed for testing python instances like dummyssh, |
1349 # dummysmtpd.py, and dumbhttp.py. | 1349 # dummysmtpd.py, and dumbhttp.py. |
1350 if PYTHON3 and os.name == 'nt': | 1350 if PYTHON3 and os.name == 'nt': |
1449 | 1449 |
1450 Return a tuple (exitcode, output). output is None in debug mode. | 1450 Return a tuple (exitcode, output). output is None in debug mode. |
1451 """ | 1451 """ |
1452 if self._debug: | 1452 if self._debug: |
1453 proc = subprocess.Popen( | 1453 proc = subprocess.Popen( |
1454 _strpath(cmd), shell=True, cwd=_strpath(self._testtmp), env=env | 1454 _bytes2sys(cmd), |
1455 shell=True, | |
1456 cwd=_bytes2sys(self._testtmp), | |
1457 env=env, | |
1455 ) | 1458 ) |
1456 ret = proc.wait() | 1459 ret = proc.wait() |
1457 return (ret, None) | 1460 return (ret, None) |
1458 | 1461 |
1459 proc = Popen4(cmd, self._testtmp, self._timeout, env) | 1462 proc = Popen4(cmd, self._testtmp, self._timeout, env) |
1559 self._case = case | 1562 self._case = case |
1560 self._allcases = {x for y in parsettestcases(path) for x in y} | 1563 self._allcases = {x for y in parsettestcases(path) for x in y} |
1561 super(TTest, self).__init__(path, *args, **kwds) | 1564 super(TTest, self).__init__(path, *args, **kwds) |
1562 if case: | 1565 if case: |
1563 casepath = b'#'.join(case) | 1566 casepath = b'#'.join(case) |
1564 self.name = '%s#%s' % (self.name, _strpath(casepath)) | 1567 self.name = '%s#%s' % (self.name, _bytes2sys(casepath)) |
1565 self.errpath = b'%s#%s.err' % (self.errpath[:-4], casepath) | 1568 self.errpath = b'%s#%s.err' % (self.errpath[:-4], casepath) |
1566 self._tmpname += b'-%s' % casepath | 1569 self._tmpname += b'-%s' % casepath |
1567 self._have = {} | 1570 self._have = {} |
1568 | 1571 |
1569 @property | 1572 @property |
1610 | 1613 |
1611 if allreqs in self._have: | 1614 if allreqs in self._have: |
1612 return self._have.get(allreqs) | 1615 return self._have.get(allreqs) |
1613 | 1616 |
1614 # TODO do something smarter when all other uses of hghave are gone. | 1617 # TODO do something smarter when all other uses of hghave are gone. |
1615 runtestdir = os.path.abspath(os.path.dirname(_bytespath(__file__))) | 1618 runtestdir = os.path.abspath(os.path.dirname(_sys2bytes(__file__))) |
1616 tdir = runtestdir.replace(b'\\', b'/') | 1619 tdir = runtestdir.replace(b'\\', b'/') |
1617 proc = Popen4( | 1620 proc = Popen4( |
1618 b'%s -c "%s/hghave %s"' % (self._shell, tdir, allreqs), | 1621 b'%s -c "%s/hghave %s"' % (self._shell, tdir, allreqs), |
1619 self._testtmp, | 1622 self._testtmp, |
1620 0, | 1623 0, |
2197 pass | 2200 pass |
2198 elif self._options.view: | 2201 elif self._options.view: |
2199 v = self._options.view | 2202 v = self._options.view |
2200 subprocess.call( | 2203 subprocess.call( |
2201 r'"%s" "%s" "%s"' | 2204 r'"%s" "%s" "%s"' |
2202 % (v, _strpath(test.refpath), _strpath(test.errpath)), | 2205 % (v, _bytes2sys(test.refpath), _bytes2sys(test.errpath)), |
2203 shell=True, | 2206 shell=True, |
2204 ) | 2207 ) |
2205 else: | 2208 else: |
2206 servefail, lines = getdiff( | 2209 servefail, lines = getdiff( |
2207 expected, got, test.refpath, test.errpath | 2210 expected, got, test.refpath, test.errpath |
2686 # TODO: we probably need to forward more options | 2689 # TODO: we probably need to forward more options |
2687 # that alter hg's behavior inside the tests. | 2690 # that alter hg's behavior inside the tests. |
2688 opts = '' | 2691 opts = '' |
2689 withhg = self._runner.options.with_hg | 2692 withhg = self._runner.options.with_hg |
2690 if withhg: | 2693 if withhg: |
2691 opts += ' --with-hg=%s ' % shellquote(_strpath(withhg)) | 2694 opts += ' --with-hg=%s ' % shellquote(_bytes2sys(withhg)) |
2692 rtc = '%s %s %s %s' % (sysexecutable, sys.argv[0], opts, test) | 2695 rtc = '%s %s %s %s' % (sysexecutable, sys.argv[0], opts, test) |
2693 data = pread(bisectcmd + ['--command', rtc]) | 2696 data = pread(bisectcmd + ['--command', rtc]) |
2694 m = re.search( | 2697 m = re.search( |
2695 ( | 2698 ( |
2696 br'\nThe first (?P<goodbad>bad|good) revision ' | 2699 br'\nThe first (?P<goodbad>bad|good) revision ' |
2928 """Run the test suite.""" | 2931 """Run the test suite.""" |
2929 oldmask = os.umask(0o22) | 2932 oldmask = os.umask(0o22) |
2930 try: | 2933 try: |
2931 parser = parser or getparser() | 2934 parser = parser or getparser() |
2932 options = parseargs(args, parser) | 2935 options = parseargs(args, parser) |
2933 tests = [_bytespath(a) for a in options.tests] | 2936 tests = [_sys2bytes(a) for a in options.tests] |
2934 if options.test_list is not None: | 2937 if options.test_list is not None: |
2935 for listfile in options.test_list: | 2938 for listfile in options.test_list: |
2936 with open(listfile, 'rb') as f: | 2939 with open(listfile, 'rb') as f: |
2937 tests.extend(t for t in f.read().splitlines() if t) | 2940 tests.extend(t for t in f.read().splitlines() if t) |
2938 self.options = options | 2941 self.options = options |
2960 pathname = os.path.dirname(testdescs[0]['path']) | 2963 pathname = os.path.dirname(testdescs[0]['path']) |
2961 if pathname: | 2964 if pathname: |
2962 testdir = os.path.join(testdir, pathname) | 2965 testdir = os.path.join(testdir, pathname) |
2963 self._testdir = osenvironb[b'TESTDIR'] = testdir | 2966 self._testdir = osenvironb[b'TESTDIR'] = testdir |
2964 if self.options.outputdir: | 2967 if self.options.outputdir: |
2965 self._outputdir = canonpath(_bytespath(self.options.outputdir)) | 2968 self._outputdir = canonpath(_sys2bytes(self.options.outputdir)) |
2966 else: | 2969 else: |
2967 self._outputdir = getcwdb() | 2970 self._outputdir = getcwdb() |
2968 if testdescs and pathname: | 2971 if testdescs and pathname: |
2969 self._outputdir = os.path.join(self._outputdir, pathname) | 2972 self._outputdir = os.path.join(self._outputdir, pathname) |
2970 previoustimes = {} | 2973 previoustimes = {} |
2977 # we do the randomness ourself to know what seed is used | 2980 # we do the randomness ourself to know what seed is used |
2978 os.environ['PYTHONHASHSEED'] = str(random.getrandbits(32)) | 2981 os.environ['PYTHONHASHSEED'] = str(random.getrandbits(32)) |
2979 | 2982 |
2980 if self.options.tmpdir: | 2983 if self.options.tmpdir: |
2981 self.options.keep_tmpdir = True | 2984 self.options.keep_tmpdir = True |
2982 tmpdir = _bytespath(self.options.tmpdir) | 2985 tmpdir = _sys2bytes(self.options.tmpdir) |
2983 if os.path.exists(tmpdir): | 2986 if os.path.exists(tmpdir): |
2984 # Meaning of tmpdir has changed since 1.3: we used to create | 2987 # Meaning of tmpdir has changed since 1.3: we used to create |
2985 # HGTMP inside tmpdir; now HGTMP is tmpdir. So fail if | 2988 # HGTMP inside tmpdir; now HGTMP is tmpdir. So fail if |
2986 # tmpdir already exists. | 2989 # tmpdir already exists. |
2987 print("error: temp dir %r already exists" % tmpdir) | 2990 print("error: temp dir %r already exists" % tmpdir) |
3006 self._hgcommand = os.path.basename(whg) | 3009 self._hgcommand = os.path.basename(whg) |
3007 self._tmpbindir = os.path.join(self._hgtmp, b'install', b'bin') | 3010 self._tmpbindir = os.path.join(self._hgtmp, b'install', b'bin') |
3008 os.makedirs(self._tmpbindir) | 3011 os.makedirs(self._tmpbindir) |
3009 | 3012 |
3010 normbin = os.path.normpath(os.path.abspath(whg)) | 3013 normbin = os.path.normpath(os.path.abspath(whg)) |
3011 normbin = normbin.replace(_bytespath(os.sep), b'/') | 3014 normbin = normbin.replace(_sys2bytes(os.sep), b'/') |
3012 | 3015 |
3013 # Other Python scripts in the test harness need to | 3016 # Other Python scripts in the test harness need to |
3014 # `import mercurial`. If `hg` is a Python script, we assume | 3017 # `import mercurial`. If `hg` is a Python script, we assume |
3015 # the Mercurial modules are relative to its path and tell the tests | 3018 # the Mercurial modules are relative to its path and tell the tests |
3016 # to load Python modules from its directory. | 3019 # to load Python modules from its directory. |
3055 self._hgcommand = os.path.basename(self.options.with_chg) | 3058 self._hgcommand = os.path.basename(self.options.with_chg) |
3056 | 3059 |
3057 osenvironb[b"BINDIR"] = self._bindir | 3060 osenvironb[b"BINDIR"] = self._bindir |
3058 osenvironb[b"PYTHON"] = PYTHON | 3061 osenvironb[b"PYTHON"] = PYTHON |
3059 | 3062 |
3060 fileb = _bytespath(__file__) | 3063 fileb = _sys2bytes(__file__) |
3061 runtestdir = os.path.abspath(os.path.dirname(fileb)) | 3064 runtestdir = os.path.abspath(os.path.dirname(fileb)) |
3062 osenvironb[b'RUNTESTDIR'] = runtestdir | 3065 osenvironb[b'RUNTESTDIR'] = runtestdir |
3063 if PYTHON3: | 3066 if PYTHON3: |
3064 sepb = _bytespath(os.pathsep) | 3067 sepb = _sys2bytes(os.pathsep) |
3065 else: | 3068 else: |
3066 sepb = os.pathsep | 3069 sepb = os.pathsep |
3067 path = [self._bindir, runtestdir] + osenvironb[b"PATH"].split(sepb) | 3070 path = [self._bindir, runtestdir] + osenvironb[b"PATH"].split(sepb) |
3068 if os.path.islink(__file__): | 3071 if os.path.islink(__file__): |
3069 # test helper will likely be at the end of the symlink | 3072 # test helper will likely be at the end of the symlink |
3119 logexceptions = os.path.join(self._testdir, b'logexceptions.py') | 3122 logexceptions = os.path.join(self._testdir, b'logexceptions.py') |
3120 self.options.extra_config_opt.append( | 3123 self.options.extra_config_opt.append( |
3121 'extensions.logexceptions=%s' % logexceptions.decode('utf-8') | 3124 'extensions.logexceptions=%s' % logexceptions.decode('utf-8') |
3122 ) | 3125 ) |
3123 | 3126 |
3124 vlog("# Using TESTDIR", _strpath(self._testdir)) | 3127 vlog("# Using TESTDIR", _bytes2sys(self._testdir)) |
3125 vlog("# Using RUNTESTDIR", _strpath(osenvironb[b'RUNTESTDIR'])) | 3128 vlog("# Using RUNTESTDIR", _bytes2sys(osenvironb[b'RUNTESTDIR'])) |
3126 vlog("# Using HGTMP", _strpath(self._hgtmp)) | 3129 vlog("# Using HGTMP", _bytes2sys(self._hgtmp)) |
3127 vlog("# Using PATH", os.environ["PATH"]) | 3130 vlog("# Using PATH", os.environ["PATH"]) |
3128 vlog( | 3131 vlog( |
3129 "# Using", _strpath(IMPL_PATH), _strpath(osenvironb[IMPL_PATH]), | 3132 "# Using", _bytes2sys(IMPL_PATH), _bytes2sys(osenvironb[IMPL_PATH]), |
3130 ) | 3133 ) |
3131 vlog("# Writing to directory", _strpath(self._outputdir)) | 3134 vlog("# Writing to directory", _bytes2sys(self._outputdir)) |
3132 | 3135 |
3133 try: | 3136 try: |
3134 return self._runtests(testdescs) or 0 | 3137 return self._runtests(testdescs) or 0 |
3135 finally: | 3138 finally: |
3136 time.sleep(0.1) | 3139 time.sleep(0.1) |
3144 """ | 3147 """ |
3145 if not args: | 3148 if not args: |
3146 if self.options.changed: | 3149 if self.options.changed: |
3147 proc = Popen4( | 3150 proc = Popen4( |
3148 b'hg st --rev "%s" -man0 .' | 3151 b'hg st --rev "%s" -man0 .' |
3149 % _bytespath(self.options.changed), | 3152 % _sys2bytes(self.options.changed), |
3150 None, | 3153 None, |
3151 0, | 3154 0, |
3152 ) | 3155 ) |
3153 stdout, stderr = proc.communicate() | 3156 stdout, stderr = proc.communicate() |
3154 args = stdout.strip(b'\0').split(b'\0') | 3157 args = stdout.strip(b'\0').split(b'\0') |
3364 def _cleanup(self): | 3367 def _cleanup(self): |
3365 """Clean up state from this test invocation.""" | 3368 """Clean up state from this test invocation.""" |
3366 if self.options.keep_tmpdir: | 3369 if self.options.keep_tmpdir: |
3367 return | 3370 return |
3368 | 3371 |
3369 vlog("# Cleaning up HGTMP", _strpath(self._hgtmp)) | 3372 vlog("# Cleaning up HGTMP", _bytes2sys(self._hgtmp)) |
3370 shutil.rmtree(self._hgtmp, True) | 3373 shutil.rmtree(self._hgtmp, True) |
3371 for f in self._createdfiles: | 3374 for f in self._createdfiles: |
3372 try: | 3375 try: |
3373 os.remove(f) | 3376 os.remove(f) |
3374 except OSError: | 3377 except OSError: |
3432 | 3435 |
3433 # Run installer in hg root | 3436 # Run installer in hg root |
3434 script = os.path.realpath(sys.argv[0]) | 3437 script = os.path.realpath(sys.argv[0]) |
3435 exe = sysexecutable | 3438 exe = sysexecutable |
3436 if PYTHON3: | 3439 if PYTHON3: |
3437 compiler = _bytespath(compiler) | 3440 compiler = _sys2bytes(compiler) |
3438 script = _bytespath(script) | 3441 script = _sys2bytes(script) |
3439 exe = _bytespath(exe) | 3442 exe = _sys2bytes(exe) |
3440 hgroot = os.path.dirname(os.path.dirname(script)) | 3443 hgroot = os.path.dirname(os.path.dirname(script)) |
3441 self._hgroot = hgroot | 3444 self._hgroot = hgroot |
3442 os.chdir(hgroot) | 3445 os.chdir(hgroot) |
3443 nohome = b'--home=""' | 3446 nohome = b'--home=""' |
3444 if os.name == 'nt': | 3447 if os.name == 'nt': |
3476 | 3479 |
3477 makedirs(self._pythondir) | 3480 makedirs(self._pythondir) |
3478 makedirs(self._bindir) | 3481 makedirs(self._bindir) |
3479 | 3482 |
3480 vlog("# Running", cmd.decode("utf-8")) | 3483 vlog("# Running", cmd.decode("utf-8")) |
3481 if subprocess.call(_strpath(cmd), shell=True) == 0: | 3484 if subprocess.call(_bytes2sys(cmd), shell=True) == 0: |
3482 if not self.options.verbose: | 3485 if not self.options.verbose: |
3483 try: | 3486 try: |
3484 os.remove(installerrs) | 3487 os.remove(installerrs) |
3485 except OSError as e: | 3488 except OSError as e: |
3486 if e.errno != errno.ENOENT: | 3489 if e.errno != errno.ENOENT: |
3556 return self._hgpath | 3559 return self._hgpath |
3557 | 3560 |
3558 cmd = b'"%s" -c "import mercurial; print (mercurial.__path__[0])"' | 3561 cmd = b'"%s" -c "import mercurial; print (mercurial.__path__[0])"' |
3559 cmd = cmd % PYTHON | 3562 cmd = cmd % PYTHON |
3560 if PYTHON3: | 3563 if PYTHON3: |
3561 cmd = _strpath(cmd) | 3564 cmd = _bytes2sys(cmd) |
3562 | 3565 |
3563 p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True) | 3566 p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True) |
3564 out, err = p.communicate() | 3567 out, err = p.communicate() |
3565 | 3568 |
3566 self._hgpath = out.strip() | 3569 self._hgpath = out.strip() |
3602 | 3605 |
3603 vlog('# Producing coverage report') | 3606 vlog('# Producing coverage report') |
3604 # chdir is the easiest way to get short, relative paths in the | 3607 # chdir is the easiest way to get short, relative paths in the |
3605 # output. | 3608 # output. |
3606 os.chdir(self._hgroot) | 3609 os.chdir(self._hgroot) |
3607 covdir = os.path.join(_strpath(self._installdir), '..', 'coverage') | 3610 covdir = os.path.join(_bytes2sys(self._installdir), '..', 'coverage') |
3608 cov = coverage(data_file=os.path.join(covdir, 'cov')) | 3611 cov = coverage(data_file=os.path.join(covdir, 'cov')) |
3609 | 3612 |
3610 # Map install directory paths back to source directory. | 3613 # Map install directory paths back to source directory. |
3611 cov.config.paths['srcdir'] = ['.', _strpath(self._pythondir)] | 3614 cov.config.paths['srcdir'] = ['.', _bytes2sys(self._pythondir)] |
3612 | 3615 |
3613 cov.combine() | 3616 cov.combine() |
3614 | 3617 |
3615 omit = [ | 3618 omit = [ |
3616 _strpath(os.path.join(x, b'*')) | 3619 _bytes2sys(os.path.join(x, b'*')) |
3617 for x in [self._bindir, self._testdir] | 3620 for x in [self._bindir, self._testdir] |
3618 ] | 3621 ] |
3619 cov.report(ignore_errors=True, omit=omit) | 3622 cov.report(ignore_errors=True, omit=omit) |
3620 | 3623 |
3621 if self.options.htmlcov: | 3624 if self.options.htmlcov: |
3622 htmldir = os.path.join(_strpath(self._outputdir), 'htmlcov') | 3625 htmldir = os.path.join(_bytes2sys(self._outputdir), 'htmlcov') |
3623 cov.html_report(directory=htmldir, omit=omit) | 3626 cov.html_report(directory=htmldir, omit=omit) |
3624 if self.options.annotate: | 3627 if self.options.annotate: |
3625 adir = os.path.join(_strpath(self._outputdir), 'annotated') | 3628 adir = os.path.join(_bytes2sys(self._outputdir), 'annotated') |
3626 if not os.path.isdir(adir): | 3629 if not os.path.isdir(adir): |
3627 os.mkdir(adir) | 3630 os.mkdir(adir) |
3628 cov.annotate(directory=adir, omit=omit) | 3631 cov.annotate(directory=adir, omit=omit) |
3629 | 3632 |
3630 def _findprogram(self, program): | 3633 def _findprogram(self, program): |
3631 """Search PATH for a executable program""" | 3634 """Search PATH for a executable program""" |
3632 dpb = _bytespath(os.defpath) | 3635 dpb = _sys2bytes(os.defpath) |
3633 sepb = _bytespath(os.pathsep) | 3636 sepb = _sys2bytes(os.pathsep) |
3634 for p in osenvironb.get(b'PATH', dpb).split(sepb): | 3637 for p in osenvironb.get(b'PATH', dpb).split(sepb): |
3635 name = os.path.join(p, program) | 3638 name = os.path.join(p, program) |
3636 if os.name == 'nt' or os.access(name, os.X_OK): | 3639 if os.name == 'nt' or os.access(name, os.X_OK): |
3637 return name | 3640 return name |
3638 return None | 3641 return None |
3643 if os.name == 'nt' and not p.endswith(b'.exe'): | 3646 if os.name == 'nt' and not p.endswith(b'.exe'): |
3644 p += b'.exe' | 3647 p += b'.exe' |
3645 found = self._findprogram(p) | 3648 found = self._findprogram(p) |
3646 p = p.decode("utf-8") | 3649 p = p.decode("utf-8") |
3647 if found: | 3650 if found: |
3648 vlog("# Found prerequisite", p, "at", _strpath(found)) | 3651 vlog("# Found prerequisite", p, "at", _bytes2sys(found)) |
3649 else: | 3652 else: |
3650 print("WARNING: Did not find prerequisite tool: %s " % p) | 3653 print("WARNING: Did not find prerequisite tool: %s " % p) |
3651 | 3654 |
3652 | 3655 |
3653 def aggregateexceptions(path): | 3656 def aggregateexceptions(path): |