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