##// END OF EJS Templates
bisect: avoid adding irrelevant revisions to bisect state...
bisect: avoid adding irrelevant revisions to bisect state When adding new revisions to the bisect state, it only makes sense to add information about revisions that are under consideration (i.e., those that are topologically between the known good and bad revisions). However, if the user passes in a revset (e.g., '!merge()' to exclude merge commits), hg will resolve the revset first and add all matching revisions to the bisect state (which in this case would likely be the majority of revisions in the repo). To avoid this, revisions should only be added to the bisect state if they are between the good and bad revisions (and therefore relevant to the bisection). -- Here are the results of some performance tests using the `mozilla-central` repo (since it is one of the largest freely-available hg repositories in the wild). These tests compare the performance of a locally-built `hg` before and after application of this series. Note that `--noupdate` is passed to avoid including update time (which should not vary across cases). Setup (run between each test): $ hg bisect --reset $ hg bisect --noupdate --bad 56c3ad4bde5c70714b784ccf15d099e0df0f5bde $ hg bisect --noupdate --good 57426696adaf08298af3027fa77486fee0633b13 Test using a revset that returns a very large number of revisions: $ time hg bisect --noupdate --skip '!merge()' > /dev/null Before: real 0m9.398s user 0m9.233s sys 0m0.120s After: real 0m1.513s user 0m1.425s sys 0m0.052s Test using a revset that is expensive to compute: $ time hg bisect --noupdate --skip 'desc("Bug")' > /dev/null Before: real 0m49.853s user 0m49.580s sys 0m0.243s After: real 0m4.120s user 0m4.036s sys 0m0.048s

File last commit:

r49730:6000f5b2 default
r50337:81623652 default
Show More
test-demandimport.py
236 lines | 6.6 KiB | text/x-python | PythonLexer
/ tests / test-demandimport.py
from mercurial import demandimport
demandimport.enable()
import os
import subprocess
import sys
import types
# Don't import pycompat because it has too many side-effects.
ispy3 = sys.version_info[0] >= 3
# Only run if demandimport is allowed
if subprocess.call(
[os.environ['PYTHON'], '%s/hghave' % os.environ['TESTDIR'], 'demandimport']
):
sys.exit(80)
# We rely on assert, which gets optimized out.
if sys.flags.optimize:
sys.exit(80)
# The demand importer doesn't work on Python 3.5.
if sys.version_info[0:2] == (3, 5):
sys.exit(80)
if ispy3:
from importlib.util import _LazyModule
try:
from importlib.util import _Module as moduletype
except ImportError:
moduletype = types.ModuleType
else:
moduletype = types.ModuleType
if os.name != 'nt':
try:
import distutils.msvc9compiler
print(
'distutils.msvc9compiler needs to be an immediate '
'importerror on non-windows platforms'
)
distutils.msvc9compiler
except ImportError:
pass
import re
rsub = re.sub
def f(obj):
l = repr(obj)
l = rsub("0x[0-9a-fA-F]+", "0x?", l)
l = rsub("from '.*'", "from '?'", l)
l = rsub("'<[a-z]*>'", "'<whatever>'", l)
return l
demandimport.disable()
os.environ['HGDEMANDIMPORT'] = 'disable'
# this enable call should not actually enable demandimport!
demandimport.enable()
from mercurial import node
# We use assert instead of a unittest test case because having imports inside
# functions changes behavior of the demand importer.
if ispy3:
assert not isinstance(node, _LazyModule)
else:
assert f(node) == "<module 'mercurial.node' from '?'>", f(node)
# now enable it for real
del os.environ['HGDEMANDIMPORT']
demandimport.enable()
# Test access to special attributes through demandmod proxy
assert 'mercurial.error' not in sys.modules
from mercurial import error as errorproxy
if ispy3:
# unsure why this isn't lazy.
assert not isinstance(f, _LazyModule)
assert f(errorproxy) == "<module 'mercurial.error' from '?'>", f(errorproxy)
else:
assert f(errorproxy) == "<unloaded module 'error'>", f(errorproxy)
doc = ' '.join(errorproxy.__doc__.split()[:3])
assert doc == 'Mercurial exceptions. This', doc
assert errorproxy.__name__ == 'mercurial.error', errorproxy.__name__
# __name__ must be accessible via __dict__ so the relative imports can be
# resolved
name = errorproxy.__dict__['__name__']
assert name == 'mercurial.error', name
if ispy3:
assert not isinstance(errorproxy, _LazyModule)
assert f(errorproxy) == "<module 'mercurial.error' from '?'>", f(errorproxy)
else:
assert f(errorproxy) == "<proxied module 'error'>", f(errorproxy)
import os
if ispy3:
assert not isinstance(os, _LazyModule)
assert f(os) == "<module 'os' from '?'>", f(os)
else:
assert f(os) == "<unloaded module 'os'>", f(os)
assert f(os.system) == '<built-in function system>', f(os.system)
assert f(os) == "<module 'os' from '?'>", f(os)
assert 'mercurial.utils.procutil' not in sys.modules
from mercurial.utils import procutil
if ispy3:
assert isinstance(procutil, _LazyModule)
assert f(procutil) == "<module 'mercurial.utils.procutil' from '?'>", f(
procutil
)
else:
assert f(procutil) == "<unloaded module 'procutil'>", f(procutil)
assert f(procutil.system) == '<function system at 0x?>', f(procutil.system)
assert procutil.__class__ == moduletype, procutil.__class__
assert f(procutil) == "<module 'mercurial.utils.procutil' from '?'>", f(
procutil
)
assert f(procutil.system) == '<function system at 0x?>', f(procutil.system)
assert 'mercurial.hgweb' not in sys.modules
from mercurial import hgweb
if ispy3:
assert isinstance(hgweb, _LazyModule)
assert f(hgweb) == "<module 'mercurial.hgweb' from '?'>", f(hgweb)
assert isinstance(hgweb.hgweb_mod, _LazyModule)
assert (
f(hgweb.hgweb_mod) == "<module 'mercurial.hgweb.hgweb_mod' from '?'>"
), f(hgweb.hgweb_mod)
else:
assert f(hgweb) == "<unloaded module 'hgweb'>", f(hgweb)
assert f(hgweb.hgweb_mod) == "<unloaded module 'hgweb_mod'>", f(
hgweb.hgweb_mod
)
assert f(hgweb) == "<module 'mercurial.hgweb' from '?'>", f(hgweb)
import re as fred
if ispy3:
assert not isinstance(fred, _LazyModule)
assert f(fred) == "<module 're' from '?'>"
else:
assert f(fred) == "<unloaded module 're'>", f(fred)
import re as remod
if ispy3:
assert not isinstance(remod, _LazyModule)
assert f(remod) == "<module 're' from '?'>"
else:
assert f(remod) == "<unloaded module 're'>", f(remod)
import sys as re
if ispy3:
assert not isinstance(re, _LazyModule)
assert f(re) == "<module 'sys' (built-in)>"
else:
assert f(re) == "<unloaded module 'sys'>", f(re)
if ispy3:
assert not isinstance(fred, _LazyModule)
assert f(fred) == "<module 're' from '?'>", f(fred)
else:
assert f(fred) == "<unloaded module 're'>", f(fred)
assert f(fred.sub) == '<function sub at 0x?>', f(fred.sub)
if ispy3:
assert not isinstance(fred, _LazyModule)
assert f(fred) == "<module 're' from '?'>", f(fred)
else:
assert f(fred) == "<proxied module 're'>", f(fred)
remod.escape # use remod
assert f(remod) == "<module 're' from '?'>", f(remod)
if ispy3:
assert not isinstance(re, _LazyModule)
assert f(re) == "<module 'sys' (built-in)>"
assert f(type(re.stderr)) == "<class '_io.TextIOWrapper'>", f(
type(re.stderr)
)
assert f(re) == "<module 'sys' (built-in)>"
else:
assert f(re) == "<unloaded module 'sys'>", f(re)
assert f(re.stderr) == "<open file '<whatever>', mode 'w' at 0x?>", f(
re.stderr
)
assert f(re) == "<proxied module 'sys'>", f(re)
assert 'telnetlib' not in sys.modules
import telnetlib
if ispy3:
assert isinstance(telnetlib, _LazyModule)
assert f(telnetlib) == "<module 'telnetlib' from '?'>"
else:
assert f(telnetlib) == "<unloaded module 'telnetlib'>", f(telnetlib)
try:
from telnetlib import unknownattr
assert False, (
'no demandmod should be created for attribute of non-package '
'module:\ntelnetlib.unknownattr = %s' % f(unknownattr)
)
except ImportError as inst:
assert rsub(r"'", '', str(inst)).startswith(
'cannot import name unknownattr'
)
from mercurial import util
# Unlike the import statement, __import__() function should not raise
# ImportError even if fromlist has an unknown item
# (see Python/import.c:import_module_level() and ensure_fromlist())
assert 'ftplib' not in sys.modules
zipfileimp = __import__('ftplib', globals(), locals(), ['unknownattr'])
assert f(zipfileimp) == "<module 'ftplib' from '?'>", f(zipfileimp)
assert not util.safehasattr(zipfileimp, 'unknownattr')