1 { config, lib, hostPkgs, ... }:
3 inherit (lib) mkOption types literalMD;
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" ]; };
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);
22 nodesList = map (c: c.system.name) (lib.attrValues config.nodes);
24 nodesList ++ lib.optional (lib.length nodesList == 1 && !lib.elem "machine" nodesList) "machine";
28 head = lib.substring 0 1 name;
29 tail = lib.substring 1 (-1) name;
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;
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;
39 withChecks = lib.warnIf config.skipLint "Linting is disabled";
42 hostPkgs.runCommand "nixos-test-driver-${config.name}"
44 # inherit testName; TODO (roberth): need this?
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";
59 vmStartScripts=($(for i in ${toString vms}; do echo $i/bin/run-*-vm; done))
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
68 echo "Running type check (enable/disable: config.skipTypeCheck)"
69 echo "See https://nixos.org/manual/nixos/stable/#test-opt-skipTypeCheck"
71 mypy --no-implicit-optional \
77 echo -n "$testScript" >> $out/test-script
79 ln -s ${testDriver}/bin/nixos-test-driver $out/bin/nixos-test-driver
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"
87 echo -n ${lib.escapeShellArg (lib.concatStringsSep "," pythonizedNames)},
88 < ${lib.escapeShellArg "driver-symbols"}
89 )" ${hostPkgs.python3Packages.pyflakes}/bin/pyflakes $out/test-script
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)}
107 description = "Package containing a script that runs the test.";
108 type = types.package;
109 defaultText = literalMD "set by the test framework";
112 hostPkgs = mkOption {
113 description = "Nixpkgs attrset used outside the nodes.";
115 example = lib.literalExpression ''
116 import nixpkgs { inherit system config overlays; }
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";
127 globalTimeout = mkOption {
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.
132 By default, we use a 1 hour timeout.
139 enableOCR = mkOption {
141 Whether to enable Optical Character Recognition functionality for
142 testing graphical programs. See [Machine objects](`ssec-machine-objects`).
148 extraPythonPackages = mkOption {
150 Python packages to add to the test driver.
152 The argument is a Python package set, similar to `pkgs.pythonPackages`.
154 example = lib.literalExpression ''
157 type = types.functionTo (types.listOf types.package);
161 extraDriverArgs = mkOption {
163 Extra arguments to pass to the test driver.
165 They become part of [{option}`driver`](#test-opt-driver) via `wrapProgram`.
167 type = types.listOf types.str;
171 skipLint = mkOption {
175 Do not run the linters. This may speed up your iteration cycle, but it is not something you should commit.
179 skipTypeCheck = mkOption {
183 Disable type checking. This must not be enabled for new NixOS tests.
185 This may speed up your iteration cycle, unless you're working on the [{option}`testScript`](#test-opt-testScript).
193 # Comment is in nixos/modules/misc/nixpkgs.nix
194 lib.mkOverride lib.modules.defaultOverridePriority
195 config.hostPkgs.__splicedPackages;
198 driver = withChecks driver;
200 # make available on the test runner
201 passthru.driver = config.driver;