diff options
author | Jörg Thalheim <joerg@thalheim.io> | 2020-02-19 11:01:02 +0000 |
---|---|---|
committer | Jörg Thalheim <joerg@thalheim.io> | 2020-02-23 21:29:22 +0000 |
commit | 9c952961f1f1a643b8b8e5d4efab6717afec1bbe (patch) | |
tree | e82cd82b09d80d1ce072db6664e6a8f0c27643ea /tests/run.py | |
parent | 5904e7605c5c6b26994e3b49153feaa29c35e388 (diff) | |
download | nixlib-9c952961f1f1a643b8b8e5d4efab6717afec1bbe.tar nixlib-9c952961f1f1a643b8b8e5d4efab6717afec1bbe.tar.gz nixlib-9c952961f1f1a643b8b8e5d4efab6717afec1bbe.tar.bz2 nixlib-9c952961f1f1a643b8b8e5d4efab6717afec1bbe.tar.lz nixlib-9c952961f1f1a643b8b8e5d4efab6717afec1bbe.tar.xz nixlib-9c952961f1f1a643b8b8e5d4efab6717afec1bbe.tar.zst nixlib-9c952961f1f1a643b8b8e5d4efab6717afec1bbe.zip |
Add parallel test runner
The new test runner will evaluate all test profiles from the README.md in parallel in separate nix-build processes. Since we do not load all processes into one process, this also helps saving memory.
Diffstat (limited to 'tests/run.py')
-rwxr-xr-x | tests/run.py | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/tests/run.py b/tests/run.py new file mode 100755 index 000000000000..653337d19190 --- /dev/null +++ b/tests/run.py @@ -0,0 +1,102 @@ +#!/usr/bin/env nix-shell +#!nix-shell -p nix -p python3 -i python + +import argparse +import multiprocessing +import re +import subprocess +import sys +from pathlib import Path +from typing import List, Tuple + +TEST_ROOT = Path(__file__).resolve().parent +ROOT = TEST_ROOT.parent + +GREEN = "\033[92m" +RED = "\033[91m" +RESET = "\033[0m" + + +def parse_readme() -> List[str]: + profiles = set() + with open(ROOT.joinpath("README.md")) as f: + for line in f: + results = re.findall(r"<nixos-hardware/[^>]+>", line) + profiles.update(results) + return list(profiles) + + +def build_profile(profile: str) -> Tuple[str, subprocess.CompletedProcess]: + # Hard-code this for now until we have enough other architectures to care about this. + system = "x86_64-linux" + if "raspberry-pi/2" in profile: + system = "armv7l-linux" + + cmd = [ + "nix-build", + "-I", + f"nixos-hardware={ROOT}", + "--dry-run", + "--show-trace", + "build-profile.nix", + "--system", + system, + "--arg", + "profile", + profile, + ] + res = subprocess.run( + cmd, cwd=TEST_ROOT, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, + ) + return (profile, res) + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description="Run hardware tests") + parser.add_argument( + "--jobs", + type=int, + default=multiprocessing.cpu_count(), + help="Number of parallel evaluations." + "If set to 1 it disable multi processing (suitable for debugging)", + ) + parser.add_argument("profiles", nargs="*") + return parser.parse_args() + + +def main() -> None: + args = parse_args() + if len(args.profiles) == 0: + profiles = parse_readme() + else: + profiles = args.profiles + + failed_profiles = [] + + def eval_finished(args: Tuple[str, subprocess.CompletedProcess]) -> None: + profile, res = args + if res.returncode == 0: + print(f"{GREEN}OK {profile}{RESET}") + else: + print(f"{RED}FAIL {profile}:{RESET}", file=sys.stderr) + if res.stdout != "": + print(f"{RED}{res.stdout.rstrip()}{RESET}", file=sys.stderr) + print(f"{RED}{res.stderr.rstrip()}{RESET}", file=sys.stderr) + failed_profiles.append(profile) + + if len(profiles) == 0 or args.jobs == 1: + for profile in profiles: + eval_finished(build_profile(profile)) + else: + pool = multiprocessing.Pool(processes=args.jobs) + for r in pool.imap(build_profile, profiles): + eval_finished(r) + if len(failed_profiles) > 0: + print(f"\n{RED}The following {len(failed_profiles)} test(s) failed:{RESET}") + for profile in failed_profiles: + print(f"{sys.argv[0]} '{profile}'") + sys.exit(1) + + +if __name__ == "__main__": + main() |