Mercurial > hg
changeset 14493:5cc7905bccc9
run-tests: allow whitelisting tests that should always run
It's desirable to run some tests all the time, for example
test-check-pyflakes.t and test-check-code-hg.py. This allows passing
--whitelist as a path to a file (flag can be specified more than once)
which contains a list of files to whitelist. Whitelisted tests are run
even if they're blacklisted or wouldn't match a --keyword test
run. For example, to do a quick test of usehttp2, one can now do
$ cat > test-whitelist <<EOF
> test-check-pyflakes.t
> test-check-code-hg.py
> EOF
$ (cd tests && ./run-tests.py --extra-config-opt 'ui.usehttp2=true'
> -k http -j 8 --whitelist test-whitelist)
and have all http-specific tests run as well as the two code linters.
author | Augie Fackler <durin42@gmail.com> |
---|---|
date | Tue, 31 May 2011 20:39:04 -0500 |
parents | f0f965098810 |
children | 1ffeeb91c55d |
files | tests/run-tests.py |
diffstat | 1 files changed, 55 insertions(+), 36 deletions(-) [+] |
line wrap: on
line diff
--- a/tests/run-tests.py Tue May 31 19:49:17 2011 -0500 +++ b/tests/run-tests.py Tue May 31 20:39:04 2011 -0500 @@ -104,12 +104,35 @@ 'shell': ('HGTEST_SHELL', '/bin/sh'), } +def parselistfiles(files, listtype, warn=True): + entries = dict() + for filename in files: + try: + path = os.path.expanduser(os.path.expandvars(filename)) + f = open(path, "r") + except IOError, err: + if err.errno != errno.ENOENT: + raise + if warn: + print "warning: no such %s file: %s" % (listtype, filename) + continue + + for line in f.readlines(): + line = line.split('#', 1)[0].strip() + if line: + entries[line] = filename + + f.close() + return entries + def parseargs(): parser = optparse.OptionParser("%prog [options] [tests]") # keep these sorted parser.add_option("--blacklist", action="append", help="skip tests listed in the specified blacklist file") + parser.add_option("--whitelist", action="append", + help="always run tests listed in the specified whitelist file") parser.add_option("-C", "--annotate", action="store_true", help="output files annotated with coverage") parser.add_option("--child", type="int", @@ -247,25 +270,12 @@ if sys.version_info[:2] < (2, 6) or sys.version_info[:2] >= (3, 0): parser.error('--py3k-warnings can only be used on Python 2.6+') if options.blacklist: - blacklist = dict() - for filename in options.blacklist: - try: - path = os.path.expanduser(os.path.expandvars(filename)) - f = open(path, "r") - except IOError, err: - if err.errno != errno.ENOENT: - raise - print "warning: no such blacklist file: %s" % filename - continue - - for line in f.readlines(): - line = line.split('#', 1)[0].strip() - if line: - blacklist[line] = filename - - f.close() - - options.blacklist = blacklist + options.blacklist = parselistfiles(options.blacklist, 'blacklist') + if options.whitelist: + options.whitelisted = parselistfiles(options.whitelist, 'whitelist', + warn=options.child is None) + else: + options.whitelisted = {} return (options, args) @@ -733,24 +743,25 @@ else: return None # not a supported test, don't record - if options.blacklist and test in options.blacklist: - skip("blacklisted") - return None + if not (options.whitelisted and test in options.whitelisted): + if options.blacklist and test in options.blacklist: + skip("blacklisted") + return None - if options.retest and not os.path.exists(test + ".err"): - ignore("not retesting") - return None + if options.retest and not os.path.exists(test + ".err"): + ignore("not retesting") + return None - if options.keywords: - fp = open(test) - t = fp.read().lower() + test.lower() - fp.close() - for k in options.keywords.lower().split(): - if k in t: - break - else: - ignore("doesn't match keyword") - return None + if options.keywords: + fp = open(test) + t = fp.read().lower() + test.lower() + fp.close() + for k in options.keywords.lower().split(): + if k in t: + break + else: + ignore("doesn't match keyword") + return None vlog("# Test", test) @@ -920,6 +931,14 @@ optcopy = dict(options.__dict__) optcopy['jobs'] = 1 + # Because whitelist has to override keyword matches, we have to + # actually load the whitelist in the children as well, so we allow + # the list of whitelist files to pass through and be parsed in the + # children, but not the dict of whitelisted tests resulting from + # the parse, used here to override blacklisted tests. + whitelist = optcopy['whitelisted'] or [] + del optcopy['whitelisted'] + blacklist = optcopy['blacklist'] or [] del optcopy['blacklist'] blacklisted = [] @@ -946,7 +965,7 @@ if not tests: break test = tests.pop() - if test in blacklist: + if test not in whitelist and test in blacklist: blacklisted.append(test) else: job.append(test)