def __init__(self, nr: int, tmp_dir: Path): self.nr = nr self.socket_dir = tmp_dir / f"vde{self.nr}.ctl" # TODO: don't side-effect environment here os.environ[f"QEMU_VDE_SOCKET_{self.nr}"] = str(self.socket_dir) rootlog.info("start vlan") pty_master, pty_slave = pty.openpty() self.process = subprocess.Popen( ["vde_switch", "-s", self.socket_dir, "--dirmode", "0700"], stdin=pty_slave, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, ) self.pid = self.process.pid self.fd = os.fdopen(pty_master, "w") self.fd.write("version\n") # TODO: perl version checks if this can be read from # an if not, dies. we could hang here forever. Fix it. assert self.process.stdout is not None self.process.stdout.readline() if not (self.socket_dir / "ctl").exists(): rootlog.error("cannot start vde_switch") rootlog.info(f"running vlan (pid {self.pid})")
def main() -> None: arg_parser = argparse.ArgumentParser(prog="nixos-test-driver") arg_parser.add_argument( "-K", "--keep-vm-state", help="re-use a VM state coming from a previous run", action="store_true", ) arg_parser.add_argument( "-I", "--interactive", help="drop into a python repl and run the tests interactively", action="store_true", ) arg_parser.add_argument( "--start-scripts", metavar="START-SCRIPT", action=EnvDefault, envvar="startScripts", nargs="*", help="start scripts for participating virtual machines", ) arg_parser.add_argument( "--vlans", metavar="VLAN", action=EnvDefault, envvar="vlans", nargs="*", help="vlans to span by the driver", ) arg_parser.add_argument( "testscript", action=EnvDefault, envvar="testScript", help="the test script to run", type=Path, ) args = arg_parser.parse_args() if not args.keep_vm_state: 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) as driver: if args.interactive: ptpython.repl.embed(driver.test_symbols(), {}) else: tic = time.time() driver.run_tests() toc = time.time() rootlog.info(f"test script finished in {(toc-tic):.2f}s")
def release(self) -> None: if self.pid is None: return rootlog.info(f"kill machine (pid {self.pid})") assert self.process assert self.shell assert self.monitor assert self.serial_thread self.process.terminate() self.shell.close() self.monitor.close() self.serial_thread.join()
def __init__(self, nr: int, tmp_dir: Path): self.nr = nr self.socket_dir = tmp_dir / f"vde{self.nr}.ctl" # TODO: don't side-effect environment here os.environ[f"QEMU_VDE_SOCKET_{self.nr}"] = str(self.socket_dir) rootlog.info("start vlan") pty_master, pty_slave = pty.openpty() # The --hub is required for the scenario determined by # nixos/tests/networking.nix vlan-ping. # VLAN Tagged traffic (802.1Q) seams to be blocked if a vde_switch is # used without the hub mode (flood packets to all ports). self.process = subprocess.Popen( [ "vde_switch", "-s", self.socket_dir, "--dirmode", "0700", "--hub" ], stdin=pty_slave, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, ) self.pid = self.process.pid self.fd = os.fdopen(pty_master, "w") self.fd.write("version\n") # TODO: perl version checks if this can be read from # an if not, dies. we could hang here forever. Fix it. assert self.process.stdout is not None self.process.stdout.readline() if not (self.socket_dir / "ctl").exists(): rootlog.error("cannot start vde_switch") rootlog.info(f"running vlan (pid {self.pid}; ctl {self.socket_dir})")
def __del__(self) -> None: rootlog.info(f"kill vlan (pid {self.pid})") self.fd.close() self.process.terminate()
def main() -> None: arg_parser = argparse.ArgumentParser(prog="nixos-test-driver") arg_parser.add_argument( "-K", "--keep-vm-state", help="re-use a VM state coming from a previous run", action="store_true", ) arg_parser.add_argument( "-I", "--interactive", help="drop into a python repl and run the tests interactively", action=argparse.BooleanOptionalAction, ) arg_parser.add_argument( "--start-scripts", metavar="START-SCRIPT", action=EnvDefault, envvar="startScripts", nargs="*", help="start scripts for participating virtual machines", ) arg_parser.add_argument( "--vlans", metavar="VLAN", action=EnvDefault, envvar="vlans", nargs="*", 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", help="the test script to run", type=Path, ) args = arg_parser.parse_args() if not args.keep_vm_state: 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.output_directory.resolve(), args.keep_vm_state, ) as driver: if args.interactive: ptpython.repl.embed(driver.test_symbols(), {}) else: tic = time.time() driver.run_tests() toc = time.time() rootlog.info(f"test script finished in {(toc-tic):.2f}s")