mirror of
https://github.com/NixOS/nixos-hardware.git
synced 2025-11-03 08:47:13 +08:00
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.
This commit is contained in:
19
tests/build-profile.nix
Normal file
19
tests/build-profile.nix
Normal file
@@ -0,0 +1,19 @@
|
||||
{ profile }:
|
||||
|
||||
let
|
||||
shim = {
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
|
||||
fileSystems."/" = {
|
||||
device = "/dev/disk/by-uuid/00000000-0000-0000-0000-000000000000";
|
||||
fsType = "btrfs";
|
||||
};
|
||||
|
||||
nixpkgs.config = {
|
||||
allowBroken = true;
|
||||
allowUnfree = true;
|
||||
};
|
||||
};
|
||||
in (import <nixpkgs/nixos> {
|
||||
configuration.imports = [ profile shim ];
|
||||
}).system
|
||||
102
tests/run.py
Executable file
102
tests/run.py
Executable file
@@ -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()
|
||||
Reference in New Issue
Block a user