summaryrefslogtreecommitdiffstats
path: root/tests/run.py
diff options
context:
space:
mode:
authorJörg Thalheim <Mic92@users.noreply.github.com>2020-03-11 09:46:57 +0000
committerGitHub <noreply@github.com>2020-03-11 09:46:57 +0000
commit62d7c2eddf7d7cf4bb0fd10da37970a4caaca9d3 (patch)
treeeaef6b8e2bc902320bb942b742adc0a2d83f8b8b /tests/run.py
parent62a1812f3c20b7119013650f926806fecd956574 (diff)
parent9c952961f1f1a643b8b8e5d4efab6717afec1bbe (diff)
Merge pull request #147 from Mic92/fix-travis
travis: parallelize evaluation and limit RAM usage
Diffstat (limited to 'tests/run.py')
-rwxr-xr-xtests/run.py102
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()