1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 02:33:06 +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:
Yuanfang Chen 2021-04-08 09:43:08 -07:00
parent 9c918327f6
commit 2ff261f721

View File

@ -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))