diff options
author | Dmitry Kalinkin <dmitry.kalinkin@gmail.com> | 2022-01-27 00:54:10 -0500 |
---|---|---|
committer | Dmitry Kalinkin <dmitry.kalinkin@gmail.com> | 2022-01-27 00:54:10 -0500 |
commit | 0693fd77f772c9b65fe819f383321035323ffd0d (patch) | |
tree | 92adbbb6683e7d814d772026355ee5bdc2e44735 /nixos/lib | |
parent | b20ad47fa3fe642a15a6a56250af62d19228d051 (diff) | |
parent | b32ed60c942b8b039b25e0a44fea32d58fb894db (diff) | |
download | nixlib-0693fd77f772c9b65fe819f383321035323ffd0d.tar nixlib-0693fd77f772c9b65fe819f383321035323ffd0d.tar.gz nixlib-0693fd77f772c9b65fe819f383321035323ffd0d.tar.bz2 nixlib-0693fd77f772c9b65fe819f383321035323ffd0d.tar.lz nixlib-0693fd77f772c9b65fe819f383321035323ffd0d.tar.xz nixlib-0693fd77f772c9b65fe819f383321035323ffd0d.tar.zst nixlib-0693fd77f772c9b65fe819f383321035323ffd0d.zip |
Merge branch 'staging-next' into staging
Conflicts: nixos/doc/manual/from_md/release-notes/rl-2205.section.xml nixos/doc/manual/release-notes/rl-2205.section.md pkgs/development/python-modules/aioesphomeapi/default.nix pkgs/development/python-modules/mat2/default.nix pkgs/development/python-modules/pydevccu/default.nix pkgs/development/python-modules/pywlroots/default.nix pkgs/development/python-modules/rokuecp/default.nix
Diffstat (limited to 'nixos/lib')
-rwxr-xr-x | nixos/lib/test-driver/test_driver/__init__.py | 34 | ||||
-rw-r--r-- | nixos/lib/test-driver/test_driver/driver.py | 33 | ||||
-rw-r--r-- | nixos/lib/test-driver/test_driver/machine.py | 9 | ||||
-rw-r--r-- | nixos/lib/testing-python.nix | 7 |
4 files changed, 70 insertions, 13 deletions
diff --git a/nixos/lib/test-driver/test_driver/__init__.py b/nixos/lib/test-driver/test_driver/__init__.py index 5477ab5cd038..61d91c9ed654 100755 --- a/nixos/lib/test-driver/test_driver/__init__.py +++ b/nixos/lib/test-driver/test_driver/__init__.py @@ -33,6 +33,22 @@ class EnvDefault(argparse.Action): setattr(namespace, self.dest, values) +def writeable_dir(arg: str) -> Path: + """Raises an ArgumentTypeError if the given argument isn't a writeable directory + Note: We want to fail as early as possible if a directory isn't writeable, + since an executed nixos-test could fail (very late) because of the test-driver + writing in a directory without proper permissions. + """ + path = Path(arg) + if not path.is_dir(): + raise argparse.ArgumentTypeError("{0} is not a directory".format(path)) + if not os.access(path, os.W_OK): + raise argparse.ArgumentTypeError( + "{0} is not a writeable directory".format(path) + ) + return path + + def main() -> None: arg_parser = argparse.ArgumentParser(prog="nixos-test-driver") arg_parser.add_argument( @@ -45,7 +61,7 @@ def main() -> None: "-I", "--interactive", help="drop into a python repl and run the tests interactively", - action="store_true", + action=argparse.BooleanOptionalAction, ) arg_parser.add_argument( "--start-scripts", @@ -64,6 +80,14 @@ def main() -> None: help="vlans to span by the driver", ) arg_parser.add_argument( + "-o", + "--output_directory", + help="""The path to the directory where outputs copied from the VM will be placed. + By e.g. Machine.copy_from_vm or Machine.screenshot""", + default=Path.cwd(), + type=writeable_dir, + ) + arg_parser.add_argument( "testscript", action=EnvDefault, envvar="testScript", @@ -77,7 +101,11 @@ def main() -> None: rootlog.info("Machine state will be reset. To keep it, pass --keep-vm-state") with Driver( - args.start_scripts, args.vlans, args.testscript.read_text(), args.keep_vm_state + args.start_scripts, + args.vlans, + args.testscript.read_text(), + args.output_directory.resolve(), + args.keep_vm_state, ) as driver: if args.interactive: ptpython.repl.embed(driver.test_symbols(), {}) @@ -94,7 +122,7 @@ def generate_driver_symbols() -> None: in user's test scripts. That list is then used by pyflakes to lint those scripts. """ - d = Driver([], [], "") + d = Driver([], [], "", Path()) test_symbols = d.test_symbols() with open("driver-symbols", "w") as fp: fp.write(",".join(test_symbols.keys())) diff --git a/nixos/lib/test-driver/test_driver/driver.py b/nixos/lib/test-driver/test_driver/driver.py index 49a42fe5fb4e..880b1c5fdec0 100644 --- a/nixos/lib/test-driver/test_driver/driver.py +++ b/nixos/lib/test-driver/test_driver/driver.py @@ -10,6 +10,28 @@ from test_driver.vlan import VLan from test_driver.polling_condition import PollingCondition +def get_tmp_dir() -> Path: + """Returns a temporary directory that is defined by TMPDIR, TEMP, TMP or CWD + Raises an exception in case the retrieved temporary directory is not writeable + See https://docs.python.org/3/library/tempfile.html#tempfile.gettempdir + """ + tmp_dir = Path(tempfile.gettempdir()) + tmp_dir.mkdir(mode=0o700, exist_ok=True) + if not tmp_dir.is_dir(): + raise NotADirectoryError( + "The directory defined by TMPDIR, TEMP, TMP or CWD: {0} is not a directory".format( + tmp_dir + ) + ) + if not os.access(tmp_dir, os.W_OK): + raise PermissionError( + "The directory defined by TMPDIR, TEMP, TMP, or CWD: {0} is not writeable".format( + tmp_dir + ) + ) + return tmp_dir + + class Driver: """A handle to the driver that sets up the environment and runs the tests""" @@ -24,12 +46,13 @@ class Driver: start_scripts: List[str], vlans: List[int], tests: str, + out_dir: Path, keep_vm_state: bool = False, ): self.tests = tests + self.out_dir = out_dir - tmp_dir = Path(os.environ.get("TMPDIR", tempfile.gettempdir())) - tmp_dir.mkdir(mode=0o700, exist_ok=True) + tmp_dir = get_tmp_dir() with rootlog.nested("start all VLans"): self.vlans = [VLan(nr, tmp_dir) for nr in vlans] @@ -47,6 +70,7 @@ class Driver: name=cmd.machine_name, tmp_dir=tmp_dir, callbacks=[self.check_polling_conditions], + out_dir=self.out_dir, ) for cmd in cmd(start_scripts) ] @@ -141,8 +165,8 @@ class Driver: "Using legacy create_machine(), please instantiate the" "Machine class directly, instead" ) - tmp_dir = Path(os.environ.get("TMPDIR", tempfile.gettempdir())) - tmp_dir.mkdir(mode=0o700, exist_ok=True) + + tmp_dir = get_tmp_dir() if args.get("startCommand"): start_command: str = args.get("startCommand", "") @@ -154,6 +178,7 @@ class Driver: return Machine( tmp_dir=tmp_dir, + out_dir=self.out_dir, start_command=cmd, name=name, keep_vm_state=args.get("keep_vm_state", False), diff --git a/nixos/lib/test-driver/test_driver/machine.py b/nixos/lib/test-driver/test_driver/machine.py index e050cbd7d990..a41c419ebe6a 100644 --- a/nixos/lib/test-driver/test_driver/machine.py +++ b/nixos/lib/test-driver/test_driver/machine.py @@ -297,6 +297,7 @@ class Machine: the machine lifecycle with the help of a start script / command.""" name: str + out_dir: Path tmp_dir: Path shared_dir: Path state_dir: Path @@ -325,6 +326,7 @@ class Machine: def __init__( self, + out_dir: Path, tmp_dir: Path, start_command: StartCommand, name: str = "machine", @@ -332,6 +334,7 @@ class Machine: allow_reboot: bool = False, callbacks: Optional[List[Callable]] = None, ) -> None: + self.out_dir = out_dir self.tmp_dir = tmp_dir self.keep_vm_state = keep_vm_state self.allow_reboot = allow_reboot @@ -702,10 +705,9 @@ class Machine: self.connected = True def screenshot(self, filename: str) -> None: - out_dir = os.environ.get("out", os.getcwd()) word_pattern = re.compile(r"^\w+$") if word_pattern.match(filename): - filename = os.path.join(out_dir, "{}.png".format(filename)) + filename = os.path.join(self.out_dir, "{}.png".format(filename)) tmp = "{}.ppm".format(filename) with self.nested( @@ -756,7 +758,6 @@ class Machine: all the VMs (using a temporary directory). """ # Compute the source, target, and intermediate shared file names - out_dir = Path(os.environ.get("out", os.getcwd())) vm_src = Path(source) with tempfile.TemporaryDirectory(dir=self.shared_dir) as shared_td: shared_temp = Path(shared_td) @@ -766,7 +767,7 @@ class Machine: # Copy the file to the shared directory inside VM self.succeed(make_command(["mkdir", "-p", vm_shared_temp])) self.succeed(make_command(["cp", "-r", vm_src, vm_intermediate])) - abs_target = out_dir / target_dir / vm_src.name + abs_target = self.out_dir / target_dir / vm_src.name abs_target.parent.mkdir(exist_ok=True, parents=True) # Copy the file from the shared directory outside VM if intermediate.is_dir(): diff --git a/nixos/lib/testing-python.nix b/nixos/lib/testing-python.nix index a67040468136..0d3c3a89e783 100644 --- a/nixos/lib/testing-python.nix +++ b/nixos/lib/testing-python.nix @@ -30,7 +30,7 @@ rec { # effectively mute the XMLLogger export LOGFILE=/dev/null - ${driver}/bin/nixos-test-driver + ${driver}/bin/nixos-test-driver -o $out ''; passthru = driver.passthru // { @@ -51,6 +51,7 @@ rec { , enableOCR ? false , skipLint ? false , passthru ? {} + , interactive ? false }: let # Reifies and correctly wraps the python test driver for @@ -139,7 +140,8 @@ rec { wrapProgram $out/bin/nixos-test-driver \ --set startScripts "''${vmStartScripts[*]}" \ --set testScript "$out/test-script" \ - --set vlans '${toString vlans}' + --set vlans '${toString vlans}' \ + ${lib.optionalString (interactive) "--add-flags --interactive"} ''); # Make a full-blown test @@ -217,6 +219,7 @@ rec { testName = name; qemu_pkg = pkgs.qemu; nodes = nodes pkgs.qemu; + interactive = true; }; test = |