forked from OSchip/llvm-project
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
f08a2fc09e
commit
bcb8ef2d5a
|
@ -7,6 +7,10 @@
|
|||
# list of files which should be linked together and result tested. "link_test"
|
||||
# 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
|
||||
# in each step replacing one of them with a file from the "bad" directory.
|
||||
#
|
||||
|
@ -41,9 +45,10 @@ import filecmp
|
|||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
|
||||
LINKTEST = "./link_test"
|
||||
# Specify LINKTEST via `--test`. Default value is './link_test'.
|
||||
LINKTEST = ""
|
||||
ESCAPE = "\033[%sm"
|
||||
BOLD = ESCAPE % "1"
|
||||
RED = ESCAPE % "31"
|
||||
|
@ -234,22 +239,42 @@ def testrun(files):
|
|||
return True
|
||||
|
||||
|
||||
def prepare_files(gooddir, baddir):
|
||||
files_a = find(gooddir, "*")
|
||||
files_b = find(baddir, "*")
|
||||
def prepare_files(gooddir, baddir, rspfile):
|
||||
files_a = []
|
||||
files_b = []
|
||||
|
||||
basenames_a = set(map(os.path.basename, files_a))
|
||||
basenames_b = set(map(os.path.basename, files_b))
|
||||
if rspfile is not None:
|
||||
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:
|
||||
basename = os.path.basename(name)
|
||||
basename = get_basename(name)
|
||||
if basename not in basenames_a:
|
||||
warn("There is no corresponding file to '%s' in %s" %
|
||||
(name, gooddir))
|
||||
choices = []
|
||||
skipped = []
|
||||
for name in files_a:
|
||||
basename = os.path.basename(name)
|
||||
basename = get_basename(name)
|
||||
if basename not in basenames_b:
|
||||
warn("There is no corresponding file to '%s' in %s" %
|
||||
(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
|
||||
# (cannot use `picks` as it is a dictionary without order)
|
||||
for x in files_a:
|
||||
basename = os.path.basename(x)
|
||||
basename = get_basename(x)
|
||||
picked = picks.get(basename)
|
||||
if picked is None:
|
||||
assert basename in skipped
|
||||
files.append(x)
|
||||
else:
|
||||
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 perform_test, choices
|
||||
|
@ -332,6 +369,8 @@ def main():
|
|||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--a', dest='dir_a', default='before')
|
||||
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',
|
||||
action='store_true')
|
||||
parser.add_argument('--seq',
|
||||
|
@ -342,6 +381,9 @@ def main():
|
|||
|
||||
gooddir = config.dir_a
|
||||
baddir = config.dir_b
|
||||
rspfile = config.rsp
|
||||
global LINKTEST
|
||||
LINKTEST = config.test
|
||||
|
||||
# Preparation phase: Creates a dictionary mapping names to a list of two
|
||||
# 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,
|
||||
goodfile, badfile)
|
||||
else:
|
||||
perform_test, choices = prepare_files(gooddir, baddir)
|
||||
perform_test, choices = prepare_files(gooddir, baddir, rspfile)
|
||||
|
||||
info("%d bisection choices" % len(choices))
|
||||
|
||||
|
|
Loading…
Reference in New Issue