at 23.11-pre 6.0 kB view raw
1{ config, lib, hostPkgs, ... }: 2let 3 inherit (lib) mkOption types literalMD mdDoc; 4 5 # Reifies and correctly wraps the python test driver for 6 # the respective qemu version and with or without ocr support 7 testDriver = hostPkgs.callPackage ../test-driver { 8 inherit (config) enableOCR extraPythonPackages; 9 qemu_pkg = config.qemu.package; 10 imagemagick_light = hostPkgs.imagemagick_light.override { inherit (hostPkgs) libtiff; }; 11 tesseract4 = hostPkgs.tesseract4.override { enableLanguages = [ "eng" ]; }; 12 }; 13 14 15 vlans = map (m: m.virtualisation.vlans) (lib.attrValues config.nodes); 16 vms = map (m: m.system.build.vm) (lib.attrValues config.nodes); 17 18 nodeHostNames = 19 let 20 nodesList = map (c: c.system.name) (lib.attrValues config.nodes); 21 in 22 nodesList ++ lib.optional (lib.length nodesList == 1 && !lib.elem "machine" nodesList) "machine"; 23 24 pythonizeName = name: 25 let 26 head = lib.substring 0 1 name; 27 tail = lib.substring 1 (-1) name; 28 in 29 (if builtins.match "[A-z_]" head == null then "_" else head) + 30 lib.stringAsChars (c: if builtins.match "[A-z0-9_]" c == null then "_" else c) tail; 31 32 uniqueVlans = lib.unique (builtins.concatLists vlans); 33 vlanNames = map (i: "vlan${toString i}: VLan;") uniqueVlans; 34 pythonizedNames = map pythonizeName nodeHostNames; 35 machineNames = map (name: "${name}: Machine;") pythonizedNames; 36 37 withChecks = lib.warnIf config.skipLint "Linting is disabled"; 38 39 driver = 40 hostPkgs.runCommand "nixos-test-driver-${config.name}" 41 { 42 # inherit testName; TODO (roberth): need this? 43 nativeBuildInputs = [ 44 hostPkgs.makeWrapper 45 ] ++ lib.optionals (!config.skipTypeCheck) [ hostPkgs.mypy ]; 46 buildInputs = [ testDriver ]; 47 testScript = config.testScriptString; 48 preferLocalBuild = true; 49 passthru = config.passthru; 50 meta = config.meta // { 51 mainProgram = "nixos-test-driver"; 52 }; 53 } 54 '' 55 mkdir -p $out/bin 56 57 vmStartScripts=($(for i in ${toString vms}; do echo $i/bin/run-*-vm; done)) 58 59 ${lib.optionalString (!config.skipTypeCheck) '' 60 # prepend type hints so the test script can be type checked with mypy 61 cat "${../test-script-prepend.py}" >> testScriptWithTypes 62 echo "${builtins.toString machineNames}" >> testScriptWithTypes 63 echo "${builtins.toString vlanNames}" >> testScriptWithTypes 64 echo -n "$testScript" >> testScriptWithTypes 65 66 cat -n testScriptWithTypes 67 68 mypy --no-implicit-optional \ 69 --pretty \ 70 --no-color-output \ 71 testScriptWithTypes 72 ''} 73 74 echo -n "$testScript" >> $out/test-script 75 76 ln -s ${testDriver}/bin/nixos-test-driver $out/bin/nixos-test-driver 77 78 ${testDriver}/bin/generate-driver-symbols 79 ${lib.optionalString (!config.skipLint) '' 80 PYFLAKES_BUILTINS="$( 81 echo -n ${lib.escapeShellArg (lib.concatStringsSep "," pythonizedNames)}, 82 < ${lib.escapeShellArg "driver-symbols"} 83 )" ${hostPkgs.python3Packages.pyflakes}/bin/pyflakes $out/test-script 84 ''} 85 86 # set defaults through environment 87 # see: ./test-driver/test-driver.py argparse implementation 88 wrapProgram $out/bin/nixos-test-driver \ 89 --set startScripts "''${vmStartScripts[*]}" \ 90 --set testScript "$out/test-script" \ 91 --set vlans '${toString vlans}' \ 92 ${lib.escapeShellArgs (lib.concatMap (arg: ["--add-flags" arg]) config.extraDriverArgs)} 93 ''; 94 95in 96{ 97 options = { 98 99 driver = mkOption { 100 description = mdDoc "Package containing a script that runs the test."; 101 type = types.package; 102 defaultText = literalMD "set by the test framework"; 103 }; 104 105 hostPkgs = mkOption { 106 description = mdDoc "Nixpkgs attrset used outside the nodes."; 107 type = types.raw; 108 example = lib.literalExpression '' 109 import nixpkgs { inherit system config overlays; } 110 ''; 111 }; 112 113 qemu.package = mkOption { 114 description = mdDoc "Which qemu package to use for the virtualisation of [{option}`nodes`](#test-opt-nodes)."; 115 type = types.package; 116 default = hostPkgs.qemu_test; 117 defaultText = "hostPkgs.qemu_test"; 118 }; 119 120 enableOCR = mkOption { 121 description = mdDoc '' 122 Whether to enable Optical Character Recognition functionality for 123 testing graphical programs. See [Machine objects](`ssec-machine-objects`). 124 ''; 125 type = types.bool; 126 default = false; 127 }; 128 129 extraPythonPackages = mkOption { 130 description = mdDoc '' 131 Python packages to add to the test driver. 132 133 The argument is a Python package set, similar to `pkgs.pythonPackages`. 134 ''; 135 example = lib.literalExpression '' 136 p: [ p.numpy ] 137 ''; 138 type = types.functionTo (types.listOf types.package); 139 default = ps: [ ]; 140 }; 141 142 extraDriverArgs = mkOption { 143 description = mdDoc '' 144 Extra arguments to pass to the test driver. 145 146 They become part of [{option}`driver`](#test-opt-driver) via `wrapProgram`. 147 ''; 148 type = types.listOf types.str; 149 default = []; 150 }; 151 152 skipLint = mkOption { 153 type = types.bool; 154 default = false; 155 description = mdDoc '' 156 Do not run the linters. This may speed up your iteration cycle, but it is not something you should commit. 157 ''; 158 }; 159 160 skipTypeCheck = mkOption { 161 type = types.bool; 162 default = false; 163 description = mdDoc '' 164 Disable type checking. This must not be enabled for new NixOS tests. 165 166 This may speed up your iteration cycle, unless you're working on the [{option}`testScript`](#test-opt-testScript). 167 ''; 168 }; 169 }; 170 171 config = { 172 _module.args.hostPkgs = config.hostPkgs; 173 174 driver = withChecks driver; 175 176 # make available on the test runner 177 passthru.driver = config.driver; 178 }; 179}