lol

Merge pull request #125979 from blaggacao/nixos-test-ref/03-normalse-the-python-entrypoint

nixos/test-driver: normalize the python entrypoint

authored by

lewo and committed by
GitHub
7aa78642 3a3f8263

+89 -63
+2 -11
nixos/doc/manual/development/running-nixos-tests-interactively.section.md
··· 5 5 6 6 ```ShellSession 7 7 $ nix-build nixos/tests/login.nix -A driverInteractive 8 - $ ./result/bin/nixos-test-driver 8 + $ ./result/bin/nixos-test-driver --interactive 9 9 starting VDE switch for network 1 10 10 > 11 11 ``` ··· 24 24 you to inspect the state of the VMs after the test (e.g. to debug the 25 25 test script). 26 26 27 - To just start and experiment with the VMs, run: 28 - 29 - ```ShellSession 30 - $ nix-build nixos/tests/login.nix -A driverInteractive 31 - $ ./result/bin/nixos-run-vms 32 - ``` 33 - 34 - The script `nixos-run-vms` starts the virtual machines defined by test. 35 - 36 27 You can re-use the VM states coming from a previous run by setting the 37 28 `--keep-vm-state` flag. 38 29 39 30 ```ShellSession 40 - $ ./result/bin/nixos-run-vms --keep-vm-state 31 + $ ./result/bin/nixos-test-driver --interactive --keep-vm-state 41 32 ``` 42 33 43 34 The machine state is stored in the `$TMPDIR/vm-state-machinename`
+2 -13
nixos/doc/manual/from_md/development/running-nixos-tests-interactively.section.xml
··· 6 6 </para> 7 7 <programlisting> 8 8 $ nix-build nixos/tests/login.nix -A driverInteractive 9 - $ ./result/bin/nixos-test-driver 9 + $ ./result/bin/nixos-test-driver --interactive 10 10 starting VDE switch for network 1 11 11 &gt; 12 12 </programlisting> ··· 26 26 the test (e.g. to debug the test script). 27 27 </para> 28 28 <para> 29 - To just start and experiment with the VMs, run: 30 - </para> 31 - <programlisting> 32 - $ nix-build nixos/tests/login.nix -A driverInteractive 33 - $ ./result/bin/nixos-run-vms 34 - </programlisting> 35 - <para> 36 - The script <literal>nixos-run-vms</literal> starts the virtual 37 - machines defined by test. 38 - </para> 39 - <para> 40 29 You can re-use the VM states coming from a previous run by setting 41 30 the <literal>--keep-vm-state</literal> flag. 42 31 </para> 43 32 <programlisting> 44 - $ ./result/bin/nixos-run-vms --keep-vm-state 33 + $ ./result/bin/nixos-test-driver --interactive --keep-vm-state 45 34 </programlisting> 46 35 <para> 47 36 The machine state is stored in the
+73 -28
nixos/lib/test-driver/test-driver.py
··· 24 24 import telnetlib 25 25 import tempfile 26 26 import time 27 - import traceback 28 27 import unicodedata 29 28 30 29 CHAR_TO_KEY = { ··· 930 929 machine.wait_for_shutdown() 931 930 932 931 933 - def test_script() -> None: 934 - exec(os.environ["testScript"]) 935 - 936 - 937 - def run_tests() -> None: 932 + def run_tests(interactive: bool = False) -> None: 938 933 global machines 939 - tests = os.environ.get("tests", None) 940 - if tests is not None: 941 - with log.nested("running the VM test script"): 942 - try: 943 - exec(tests, globals()) 944 - except Exception as e: 945 - eprint("error: ") 946 - traceback.print_exc() 947 - sys.exit(1) 934 + if interactive: 935 + ptpython.repl.embed(globals(), locals()) 948 936 else: 949 - ptpython.repl.embed(locals(), globals()) 950 - 951 - # TODO: Collect coverage data 952 - 953 - for machine in machines: 954 - if machine.is_up(): 955 - machine.execute("sync") 937 + test_script() 938 + # TODO: Collect coverage data 939 + for machine in machines: 940 + if machine.is_up(): 941 + machine.execute("sync") 956 942 957 943 958 944 def serial_stdout_on() -> None: ··· 965 951 log._print_serial_logs = False 966 952 967 953 954 + class EnvDefault(argparse.Action): 955 + """An argpars Action that takes values from the specified 956 + environment variable as the flags default value. 957 + """ 958 + 959 + def __init__(self, envvar, required=False, default=None, nargs=None, **kwargs): # type: ignore 960 + if not default and envvar: 961 + if envvar in os.environ: 962 + if nargs is not None and (nargs.isdigit() or nargs in ["*", "+"]): 963 + default = os.environ[envvar].split() 964 + else: 965 + default = os.environ[envvar] 966 + kwargs["help"] = ( 967 + kwargs["help"] + f" (default from environment: {default})" 968 + ) 969 + if required and default: 970 + required = False 971 + super(EnvDefault, self).__init__( 972 + default=default, required=required, nargs=nargs, **kwargs 973 + ) 974 + 975 + def __call__(self, parser, namespace, values, option_string=None): # type: ignore 976 + setattr(namespace, self.dest, values) 977 + 978 + 968 979 @contextmanager 969 980 def subtest(name: str) -> Iterator[None]: 970 981 with log.nested(name): ··· 986 997 help="re-use a VM state coming from a previous run", 987 998 action="store_true", 988 999 ) 989 - (cli_args, vm_scripts) = arg_parser.parse_known_args() 1000 + arg_parser.add_argument( 1001 + "-I", 1002 + "--interactive", 1003 + help="drop into a python repl and run the tests interactively", 1004 + action="store_true", 1005 + ) 1006 + arg_parser.add_argument( 1007 + "--start-scripts", 1008 + metavar="START-SCRIPT", 1009 + action=EnvDefault, 1010 + envvar="startScripts", 1011 + nargs="*", 1012 + help="start scripts for participating virtual machines", 1013 + ) 1014 + arg_parser.add_argument( 1015 + "--vlans", 1016 + metavar="VLAN", 1017 + action=EnvDefault, 1018 + envvar="vlans", 1019 + nargs="*", 1020 + help="vlans to span by the driver", 1021 + ) 1022 + arg_parser.add_argument( 1023 + "testscript", 1024 + action=EnvDefault, 1025 + envvar="testScript", 1026 + help="the test script to run", 1027 + type=pathlib.Path, 1028 + ) 1029 + 1030 + args = arg_parser.parse_args() 1031 + global test_script 1032 + 1033 + def test_script() -> None: 1034 + with log.nested("running the VM test script"): 1035 + exec(pathlib.Path(args.testscript).read_text(), globals()) 990 1036 991 1037 log = Logger() 992 1038 993 - vlan_nrs = list(dict.fromkeys(os.environ.get("VLANS", "").split())) 994 - vde_sockets = [create_vlan(v) for v in vlan_nrs] 1039 + vde_sockets = [create_vlan(v) for v in args.vlans] 995 1040 for nr, vde_socket, _, _ in vde_sockets: 996 1041 os.environ["QEMU_VDE_SOCKET_{}".format(nr)] = vde_socket 997 1042 998 1043 machines = [ 999 - create_machine({"startCommand": s, "keepVmState": cli_args.keep_vm_state}) 1000 - for s in vm_scripts 1044 + create_machine({"startCommand": s, "keepVmState": args.keep_vm_state}) 1045 + for s in args.start_scripts 1001 1046 ] 1002 1047 machine_eval = [ 1003 1048 "{0} = machines[{1}]".format(m.name, idx) for idx, m in enumerate(machines) ··· 1017 1062 log.close() 1018 1063 1019 1064 tic = time.time() 1020 - run_tests() 1065 + run_tests(args.interactive) 1021 1066 toc = time.time() 1022 1067 print("test script finished in {:.2f}s".format(toc - tic))
+12 -11
nixos/lib/testing-python.nix
··· 83 83 '' 84 84 mkdir -p $out 85 85 86 - LOGFILE=/dev/null tests='exec(os.environ["testScript"])' ${driver}/bin/nixos-test-driver 86 + # effectively mute the XMLLogger 87 + export LOGFILE=/dev/null 88 + 89 + ${driver}/bin/nixos-test-driver 87 90 ''; 88 91 89 92 passthru = driver.passthru // { ··· 166 169 '' 167 170 mkdir -p $out/bin 168 171 172 + vmStartScripts=($(for i in ${toString vms}; do echo $i/bin/run-*-vm; done)) 169 173 echo -n "$testScript" > $out/test-script 174 + ln -s ${testDriver}/bin/nixos-test-driver $out/bin/nixos-test-driver 175 + 170 176 ${lib.optionalString (!skipLint) '' 171 177 PYFLAKES_BUILTINS="$( 172 178 echo -n ${lib.escapeShellArg (lib.concatStringsSep "," nodeHostNames)}, ··· 174 180 )" ${python3Packages.pyflakes}/bin/pyflakes $out/test-script 175 181 ''} 176 182 177 - ln -s ${testDriver}/bin/nixos-test-driver $out/bin/ 178 - vms=($(for i in ${toString vms}; do echo $i/bin/run-*-vm; done)) 183 + # set defaults through environment 184 + # see: ./test-driver/test-driver.py argparse implementation 179 185 wrapProgram $out/bin/nixos-test-driver \ 180 - --add-flags "''${vms[*]}" \ 181 - --run "export testScript=\"\$(${coreutils}/bin/cat $out/test-script)\"" \ 182 - --set VLANS '${toString vlans}' 183 - ln -s ${testDriver}/bin/nixos-test-driver $out/bin/nixos-run-vms 184 - wrapProgram $out/bin/nixos-run-vms \ 185 - --add-flags "''${vms[*]}" \ 186 - --set tests 'start_all(); join_all();' \ 187 - --set VLANS '${toString vlans}' 186 + --set startScripts "''${vmStartScripts[*]}" \ 187 + --set testScript "$out/test-script" \ 188 + --set vlans '${toString vlans}' 188 189 ''); 189 190 190 191 # Make a full-blown test