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