tangled
alpha
login
or
join now
pyrox.dev
/
nixpkgs
0
fork
atom
lol
0
fork
atom
overview
issues
pulls
pipelines
testing-python.nix: Replace makeTest implementation
Robert Hensing
3 years ago
38fb09e4
537f4563
+11
-233
2 changed files
expand all
collapse all
unified
split
nixos
lib
testing-python.nix
modules
installer
tools
nixos-build-vms
build-vms.nix
+10
-232
nixos/lib/testing-python.nix
···
20
20
21
21
inherit pkgs;
22
22
23
23
-
# Run an automated test suite in the given virtual network.
24
24
-
runTests = { driver, driverInteractive, pos }:
25
25
-
stdenv.mkDerivation {
26
26
-
name = "vm-test-run-${driver.testName}";
27
27
-
28
28
-
requiredSystemFeatures = [ "kvm" "nixos-test" ];
29
29
-
30
30
-
buildCommand =
31
31
-
''
32
32
-
mkdir -p $out
33
33
-
34
34
-
# effectively mute the XMLLogger
35
35
-
export LOGFILE=/dev/null
36
36
-
37
37
-
${driver}/bin/nixos-test-driver -o $out
38
38
-
'';
39
39
-
40
40
-
passthru = driver.passthru // {
41
41
-
inherit driver driverInteractive;
42
42
-
};
43
43
-
44
44
-
inherit pos; # for better debugging
45
45
-
};
46
46
-
47
47
-
# Generate convenience wrappers for running the test driver
48
48
-
# has vlans, vms and test script defaulted through env variables
49
49
-
# also instantiates test script with nodes, if it's a function (contract)
50
50
-
setupDriverForTest = {
51
51
-
testScript
52
52
-
, testName
53
53
-
, nodes
54
54
-
, qemu_pkg ? pkgs.qemu_test
55
55
-
, enableOCR ? false
56
56
-
, skipLint ? false
57
57
-
, skipTypeCheck ? false
58
58
-
, passthru ? {}
59
59
-
, interactive ? false
60
60
-
, extraPythonPackages ? (_ :[])
61
61
-
}:
62
62
-
let
63
63
-
# Reifies and correctly wraps the python test driver for
64
64
-
# the respective qemu version and with or without ocr support
65
65
-
testDriver = pkgs.callPackage ./test-driver {
66
66
-
inherit enableOCR extraPythonPackages;
67
67
-
qemu_pkg = qemu_test;
68
68
-
imagemagick_light = imagemagick_light.override { inherit libtiff; };
69
69
-
tesseract4 = tesseract4.override { enableLanguages = [ "eng" ]; };
70
70
-
};
71
71
-
72
72
-
73
73
-
testDriverName =
74
74
-
let
75
75
-
# A standard store path to the vm monitor is built like this:
76
76
-
# /tmp/nix-build-vm-test-run-$name.drv-0/vm-state-machine/monitor
77
77
-
# The max filename length of a unix domain socket is 108 bytes.
78
78
-
# This means $name can at most be 50 bytes long.
79
79
-
maxTestNameLen = 50;
80
80
-
testNameLen = builtins.stringLength testName;
81
81
-
in with builtins;
82
82
-
if testNameLen > maxTestNameLen then
83
83
-
abort
84
84
-
("The name of the test '${testName}' must not be longer than ${toString maxTestNameLen} " +
85
85
-
"it's currently ${toString testNameLen} characters long.")
86
86
-
else
87
87
-
"nixos-test-driver-${testName}";
88
88
-
89
89
-
vlans = map (m: m.config.virtualisation.vlans) (lib.attrValues nodes);
90
90
-
vms = map (m: m.config.system.build.vm) (lib.attrValues nodes);
91
91
-
92
92
-
nodeHostNames = let
93
93
-
nodesList = map (c: c.config.system.name) (lib.attrValues nodes);
94
94
-
in nodesList ++ lib.optional (lib.length nodesList == 1 && !lib.elem "machine" nodesList) "machine";
95
95
-
96
96
-
# TODO: This is an implementation error and needs fixing
97
97
-
# the testing famework cannot legitimately restrict hostnames further
98
98
-
# beyond RFC1035
99
99
-
invalidNodeNames = lib.filter
100
100
-
(node: builtins.match "^[A-z_]([A-z0-9_]+)?$" node == null)
101
101
-
nodeHostNames;
102
102
-
103
103
-
testScript' =
104
104
-
# Call the test script with the computed nodes.
105
105
-
if lib.isFunction testScript
106
106
-
then testScript { inherit nodes; }
107
107
-
else testScript;
108
108
-
109
109
-
uniqueVlans = lib.unique (builtins.concatLists vlans);
110
110
-
vlanNames = map (i: "vlan${toString i}: VLan;") uniqueVlans;
111
111
-
machineNames = map (name: "${name}: Machine;") nodeHostNames;
112
112
-
in
113
113
-
if lib.length invalidNodeNames > 0 then
114
114
-
throw ''
115
115
-
Cannot create machines out of (${lib.concatStringsSep ", " invalidNodeNames})!
116
116
-
All machines are referenced as python variables in the testing framework which will break the
117
117
-
script when special characters are used.
118
118
-
119
119
-
This is an IMPLEMENTATION ERROR and needs to be fixed. Meanwhile,
120
120
-
please stick to alphanumeric chars and underscores as separation.
121
121
-
''
122
122
-
else lib.warnIf skipLint "Linting is disabled" (runCommand testDriverName
123
123
-
{
124
124
-
inherit testName;
125
125
-
nativeBuildInputs = [ makeWrapper mypy ];
126
126
-
buildInputs = [ testDriver ];
127
127
-
testScript = testScript';
128
128
-
preferLocalBuild = true;
129
129
-
passthru = passthru // {
130
130
-
inherit nodes;
131
131
-
};
132
132
-
meta.mainProgram = "nixos-test-driver";
133
133
-
}
134
134
-
''
135
135
-
mkdir -p $out/bin
136
136
-
137
137
-
vmStartScripts=($(for i in ${toString vms}; do echo $i/bin/run-*-vm; done))
138
138
-
139
139
-
${lib.optionalString (!skipTypeCheck) ''
140
140
-
# prepend type hints so the test script can be type checked with mypy
141
141
-
cat "${./test-script-prepend.py}" >> testScriptWithTypes
142
142
-
echo "${builtins.toString machineNames}" >> testScriptWithTypes
143
143
-
echo "${builtins.toString vlanNames}" >> testScriptWithTypes
144
144
-
echo -n "$testScript" >> testScriptWithTypes
145
145
-
146
146
-
mypy --no-implicit-optional \
147
147
-
--pretty \
148
148
-
--no-color-output \
149
149
-
testScriptWithTypes
150
150
-
''}
151
151
-
152
152
-
echo -n "$testScript" >> $out/test-script
153
153
-
154
154
-
ln -s ${testDriver}/bin/nixos-test-driver $out/bin/nixos-test-driver
155
155
-
156
156
-
${testDriver}/bin/generate-driver-symbols
157
157
-
${lib.optionalString (!skipLint) ''
158
158
-
PYFLAKES_BUILTINS="$(
159
159
-
echo -n ${lib.escapeShellArg (lib.concatStringsSep "," nodeHostNames)},
160
160
-
< ${lib.escapeShellArg "driver-symbols"}
161
161
-
)" ${python3Packages.pyflakes}/bin/pyflakes $out/test-script
162
162
-
''}
163
163
-
164
164
-
# set defaults through environment
165
165
-
# see: ./test-driver/test-driver.py argparse implementation
166
166
-
wrapProgram $out/bin/nixos-test-driver \
167
167
-
--set startScripts "''${vmStartScripts[*]}" \
168
168
-
--set testScript "$out/test-script" \
169
169
-
--set vlans '${toString vlans}' \
170
170
-
${lib.optionalString (interactive) "--add-flags --interactive"}
171
171
-
'');
172
172
-
173
23
evalTest = module: nixos-lib.evalTest { imports = [ extraTestModule module ]; };
174
24
runTest = module: nixos-lib.runTest { imports = [ extraTestModule module ]; };
175
25
···
199
49
else builtins.unsafeGetAttrPos "testScript" t)
200
50
, extraPythonPackages ? (_ : [])
201
51
} @ t:
202
202
-
let
203
203
-
mkNodes = qemu_pkg:
204
204
-
let
205
205
-
testScript' =
206
206
-
# Call the test script with the computed nodes.
207
207
-
if lib.isFunction testScript
208
208
-
then testScript { nodes = mkNodes qemu_pkg; }
209
209
-
else testScript;
210
210
-
211
211
-
build-vms = import ./build-vms.nix {
212
212
-
inherit system lib pkgs minimal specialArgs;
213
213
-
extraConfigurations = extraConfigurations ++ [(
214
214
-
{ config, ... }:
215
215
-
{
216
216
-
virtualisation.qemu.package = qemu_pkg;
217
217
-
218
218
-
# Make sure all derivations referenced by the test
219
219
-
# script are available on the nodes. When the store is
220
220
-
# accessed through 9p, this isn't important, since
221
221
-
# everything in the store is available to the guest,
222
222
-
# but when building a root image it is, as all paths
223
223
-
# that should be available to the guest has to be
224
224
-
# copied to the image.
225
225
-
virtualisation.additionalPaths =
226
226
-
lib.optional
227
227
-
# A testScript may evaluate nodes, which has caused
228
228
-
# infinite recursions. The demand cycle involves:
229
229
-
# testScript -->
230
230
-
# nodes -->
231
231
-
# toplevel -->
232
232
-
# additionalPaths -->
233
233
-
# hasContext testScript' -->
234
234
-
# testScript (ad infinitum)
235
235
-
# If we don't need to build an image, we can break this
236
236
-
# cycle by short-circuiting when useNixStoreImage is false.
237
237
-
(config.virtualisation.useNixStoreImage && builtins.hasContext testScript')
238
238
-
(pkgs.writeStringReferencesToFile testScript');
239
239
-
240
240
-
# Ensure we do not use aliases. Ideally this is only set
241
241
-
# when the test framework is used by Nixpkgs NixOS tests.
242
242
-
nixpkgs.config.allowAliases = false;
243
243
-
}
244
244
-
)];
245
245
-
};
246
246
-
in
247
247
-
lib.warnIf (t?machine) "In test `${name}': The `machine' attribute in NixOS tests (pkgs.nixosTest / make-test-python.nix / testing-python.nix / makeTest) is deprecated. Please use the equivalent `nodes.machine'."
248
248
-
build-vms.buildVirtualNetwork (
249
249
-
nodes // lib.optionalAttrs (machine != null) { inherit machine; }
250
250
-
);
251
251
-
252
252
-
driver = setupDriverForTest {
253
253
-
inherit testScript enableOCR skipTypeCheck skipLint passthru extraPythonPackages;
254
254
-
testName = name;
255
255
-
qemu_pkg = pkgs.qemu_test;
256
256
-
nodes = mkNodes pkgs.qemu_test;
52
52
+
runTest {
53
53
+
imports = [
54
54
+
{ _file = "makeTest parameters"; config = t; }
55
55
+
{
56
56
+
defaults = {
57
57
+
_file = "makeTest: extraConfigurations";
58
58
+
imports = extraConfigurations;
59
59
+
};
60
60
+
}
61
61
+
];
257
62
};
258
258
-
driverInteractive = setupDriverForTest {
259
259
-
inherit testScript enableOCR skipTypeCheck skipLint passthru extraPythonPackages;
260
260
-
testName = name;
261
261
-
qemu_pkg = pkgs.qemu;
262
262
-
nodes = mkNodes pkgs.qemu;
263
263
-
interactive = true;
264
264
-
};
265
265
-
266
266
-
test = lib.addMetaAttrs meta (runTests { inherit driver pos driverInteractive; });
267
267
-
268
268
-
in
269
269
-
test // {
270
270
-
inherit test driver driverInteractive;
271
271
-
inherit (driver) nodes;
272
272
-
};
273
273
-
274
274
-
abortForFunction = functionName: abort ''The ${functionName} function was
275
275
-
removed because it is not an essential part of the NixOS testing
276
276
-
infrastructure. It had no usage in NixOS or Nixpkgs and it had no designated
277
277
-
maintainer. You are free to reintroduce it by documenting it in the manual
278
278
-
and adding yourself as maintainer. It was removed in
279
279
-
https://github.com/NixOS/nixpkgs/pull/137013
280
280
-
'';
281
281
-
282
282
-
runInMachine = abortForFunction "runInMachine";
283
283
-
284
284
-
runInMachineWithX = abortForFunction "runInMachineWithX";
285
63
286
64
simpleTest = as: (makeTest as).test;
287
65
+1
-1
nixos/modules/installer/tools/nixos-build-vms/build-vms.nix
···
15
15
inherit system pkgs;
16
16
};
17
17
18
18
-
interactiveDriver = (testing.makeTest { inherit nodes; testScript = "start_all(); join_all();"; }).driverInteractive;
18
18
+
interactiveDriver = (testing.makeTest { inherit nodes; name = "network"; testScript = "start_all(); join_all();"; }).driverInteractive;
19
19
in
20
20
21
21