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