mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 04:02:41 +01:00
abtest.py: support bisection based on a response file
Also makes LINK_TEST customizable from commandline with `--test` option.
This commit is contained in:
parent
9c918327f6
commit
2ff261f721
@ -7,6 +7,10 @@
|
|||||||
# list of files which should be linked together and result tested. "link_test"
|
# list of files which should be linked together and result tested. "link_test"
|
||||||
# should returns with exitcode 0 if the linking and testing succeeded.
|
# should returns with exitcode 0 if the linking and testing succeeded.
|
||||||
#
|
#
|
||||||
|
# If a response file is provided, only the object files that are listed in the
|
||||||
|
# file are inspected. In addition, the "link_test" is called with a temporary
|
||||||
|
# response file representing one iteration of bisection.
|
||||||
|
#
|
||||||
# abtest.py operates by taking all files from the "before" directory and
|
# abtest.py operates by taking all files from the "before" directory and
|
||||||
# in each step replacing one of them with a file from the "bad" directory.
|
# in each step replacing one of them with a file from the "bad" directory.
|
||||||
#
|
#
|
||||||
@ -41,9 +45,10 @@ import filecmp
|
|||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
# Specify LINKTEST via `--test`. Default value is './link_test'.
|
||||||
LINKTEST = "./link_test"
|
LINKTEST = ""
|
||||||
ESCAPE = "\033[%sm"
|
ESCAPE = "\033[%sm"
|
||||||
BOLD = ESCAPE % "1"
|
BOLD = ESCAPE % "1"
|
||||||
RED = ESCAPE % "31"
|
RED = ESCAPE % "31"
|
||||||
@ -234,22 +239,42 @@ def testrun(files):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def prepare_files(gooddir, baddir):
|
def prepare_files(gooddir, baddir, rspfile):
|
||||||
files_a = find(gooddir, "*")
|
files_a = []
|
||||||
files_b = find(baddir, "*")
|
files_b = []
|
||||||
|
|
||||||
basenames_a = set(map(os.path.basename, files_a))
|
if rspfile is not None:
|
||||||
basenames_b = set(map(os.path.basename, files_b))
|
def get_basename(name):
|
||||||
|
# remove prefix
|
||||||
|
if name.startswith(gooddir):
|
||||||
|
return name[len(gooddir):]
|
||||||
|
if name.startswith(baddir):
|
||||||
|
return name[len(baddir):]
|
||||||
|
assert False, ""
|
||||||
|
|
||||||
|
with open(rspfile, "r") as rf:
|
||||||
|
for line in rf.read().splitlines():
|
||||||
|
for obj in line.split():
|
||||||
|
assert not os.path.isabs(obj), "TODO: support abs path"
|
||||||
|
files_a.append(gooddir + "/" + obj)
|
||||||
|
files_b.append(baddir + "/" + obj)
|
||||||
|
else:
|
||||||
|
get_basename = lambda name: os.path.basename(name)
|
||||||
|
files_a = find(gooddir, "*")
|
||||||
|
files_b = find(baddir, "*")
|
||||||
|
|
||||||
|
basenames_a = set(map(get_basename, files_a))
|
||||||
|
basenames_b = set(map(get_basename, files_b))
|
||||||
|
|
||||||
for name in files_b:
|
for name in files_b:
|
||||||
basename = os.path.basename(name)
|
basename = get_basename(name)
|
||||||
if basename not in basenames_a:
|
if basename not in basenames_a:
|
||||||
warn("There is no corresponding file to '%s' in %s" %
|
warn("There is no corresponding file to '%s' in %s" %
|
||||||
(name, gooddir))
|
(name, gooddir))
|
||||||
choices = []
|
choices = []
|
||||||
skipped = []
|
skipped = []
|
||||||
for name in files_a:
|
for name in files_a:
|
||||||
basename = os.path.basename(name)
|
basename = get_basename(name)
|
||||||
if basename not in basenames_b:
|
if basename not in basenames_b:
|
||||||
warn("There is no corresponding file to '%s' in %s" %
|
warn("There is no corresponding file to '%s' in %s" %
|
||||||
(name, baddir))
|
(name, baddir))
|
||||||
@ -271,13 +296,25 @@ def prepare_files(gooddir, baddir):
|
|||||||
# Note that we iterate over files_a so we don't change the order
|
# Note that we iterate over files_a so we don't change the order
|
||||||
# (cannot use `picks` as it is a dictionary without order)
|
# (cannot use `picks` as it is a dictionary without order)
|
||||||
for x in files_a:
|
for x in files_a:
|
||||||
basename = os.path.basename(x)
|
basename = get_basename(x)
|
||||||
picked = picks.get(basename)
|
picked = picks.get(basename)
|
||||||
if picked is None:
|
if picked is None:
|
||||||
assert basename in skipped
|
assert basename in skipped
|
||||||
files.append(x)
|
files.append(x)
|
||||||
else:
|
else:
|
||||||
files.append(picked)
|
files.append(picked)
|
||||||
|
|
||||||
|
# If response file is used, create a temporary response file for the
|
||||||
|
# picked files.
|
||||||
|
if rspfile is not None:
|
||||||
|
with tempfile.NamedTemporaryFile('w', suffix='.rsp',
|
||||||
|
delete=False) as tf:
|
||||||
|
tf.write(" ".join(files))
|
||||||
|
tf.flush()
|
||||||
|
ret = testrun([tf.name])
|
||||||
|
os.remove(tf.name)
|
||||||
|
return ret
|
||||||
|
|
||||||
return testrun(files)
|
return testrun(files)
|
||||||
|
|
||||||
return perform_test, choices
|
return perform_test, choices
|
||||||
@ -332,6 +369,8 @@ def main():
|
|||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('--a', dest='dir_a', default='before')
|
parser.add_argument('--a', dest='dir_a', default='before')
|
||||||
parser.add_argument('--b', dest='dir_b', default='after')
|
parser.add_argument('--b', dest='dir_b', default='after')
|
||||||
|
parser.add_argument('--rsp', default=None)
|
||||||
|
parser.add_argument('--test', default='./link_test')
|
||||||
parser.add_argument('--insane', help='Skip sanity check',
|
parser.add_argument('--insane', help='Skip sanity check',
|
||||||
action='store_true')
|
action='store_true')
|
||||||
parser.add_argument('--seq',
|
parser.add_argument('--seq',
|
||||||
@ -342,6 +381,9 @@ def main():
|
|||||||
|
|
||||||
gooddir = config.dir_a
|
gooddir = config.dir_a
|
||||||
baddir = config.dir_b
|
baddir = config.dir_b
|
||||||
|
rspfile = config.rsp
|
||||||
|
global LINKTEST
|
||||||
|
LINKTEST = config.test
|
||||||
|
|
||||||
# Preparation phase: Creates a dictionary mapping names to a list of two
|
# Preparation phase: Creates a dictionary mapping names to a list of two
|
||||||
# choices each. The bisection algorithm will pick one choice for each name
|
# choices each. The bisection algorithm will pick one choice for each name
|
||||||
@ -352,7 +394,7 @@ def main():
|
|||||||
perform_test, choices = prepare_functions(config.file, gooddir,
|
perform_test, choices = prepare_functions(config.file, gooddir,
|
||||||
goodfile, badfile)
|
goodfile, badfile)
|
||||||
else:
|
else:
|
||||||
perform_test, choices = prepare_files(gooddir, baddir)
|
perform_test, choices = prepare_files(gooddir, baddir, rspfile)
|
||||||
|
|
||||||
info("%d bisection choices" % len(choices))
|
info("%d bisection choices" % len(choices))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user