From 00376dcc2a8c1a3ee24284585319ea5e7ff92306 Mon Sep 17 00:00:00 2001 From: Timo Koch <timo.koch@iws.uni-stuttgart.de> Date: Tue, 24 Nov 2020 10:33:09 +0100 Subject: [PATCH] [test] Add script to identify tests that are affected by a change --- bin/testing/findtests.py | 69 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100755 bin/testing/findtests.py diff --git a/bin/testing/findtests.py b/bin/testing/findtests.py new file mode 100755 index 0000000000..676a297f91 --- /dev/null +++ b/bin/testing/findtests.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python3 + +""" +Find those tests that are affected by changes +Run this in the build directory +Warning: This runs 'make clean' on the build directory +""" + +import multiprocessing as mp +import json +import subprocess +from glob import glob +from subprocess import PIPE +import os + +import sys + +# Whether the two lists a and b have a common member +def has_common_member(myset, mylist): + return not myset.isdisjoint(mylist) + +def make_dryrun(config): + lines = subprocess.check_output(["make", "--dry-run", config["target"]], encoding='ascii').splitlines() + return [l for l in lines if "g++" in l] + +def build_command_and_dir(config, cache): + lines = make_dryrun(config) + if len(lines) == 0: + with open(cache) as c: + data = json.load(c) + return data["command"], data["dir"] + else: + (_, dir), command = [l.split() for l in lines[0].split("&&")] + with open(cache, "w") as c: + json.dump({"command":command, "dir":dir}, c) + + return command, dir + +# find the changes files +changed_files = subprocess.check_output(["git", "diff-tree", "-r", "--name-only", "HEAD", "master"], encoding='ascii').splitlines() +changed_files = set(changed_files) + +def is_affected_tests(test): + with open(test) as config_file: + config = json.load(config_file) + + command, dir = build_command_and_dir(config, "TestTargets/"+config["target"]+".json") + # for some reason g++ writes to stderr + lines = subprocess.run(command + ["-MM", "-H"], stderr=PIPE, stdout=PIPE, cwd=dir, encoding='ascii').stderr.splitlines() + + # filter lines + project_dir = os.path.abspath(os.getcwd().rstrip("build-cmake")) + test_files = set([os.path.relpath(l.lstrip(". "), project_dir) for l in lines if project_dir in l]) + + if has_common_member(changed_files, test_files): + return True, config["name"], config["target"] + + return False, config["name"], config["target"] + +if __name__ == '__main__': + + subprocess.run(["make", "clean"]) + subprocess.run(["make"]) + + # create cache folder + os.makedirs("TestTargets", exist_ok=True) + + for test in glob("TestMetaData/*json"): + print(is_affected_tests(test)) -- GitLab