diff options
author | Jörg Thalheim <Mic92@users.noreply.github.com> | 2020-03-11 09:46:57 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-11 09:46:57 +0000 |
commit | 62d7c2eddf7d7cf4bb0fd10da37970a4caaca9d3 (patch) | |
tree | eaef6b8e2bc902320bb942b742adc0a2d83f8b8b /tests/run.py | |
parent | 62a1812f3c20b7119013650f926806fecd956574 (diff) | |
parent | 9c952961f1f1a643b8b8e5d4efab6717afec1bbe (diff) |
Merge pull request #147 from Mic92/fix-travis
travis: parallelize evaluation and limit RAM usage
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 0000000..653337d --- /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() |