mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-07-06 17:13:24 -05:00
275 lines
8.5 KiB
Nix
275 lines
8.5 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
hostPkgs,
|
|
...
|
|
}:
|
|
let
|
|
inherit (lib)
|
|
mkOption
|
|
types
|
|
literalExpression
|
|
literalMD
|
|
;
|
|
|
|
inherit (config) sshBackdoor;
|
|
|
|
inherit (hostPkgs.stdenv.hostPlatform) isLinux isAarch64;
|
|
|
|
# Reifies and correctly wraps the python test driver for
|
|
# the respective qemu version and with or without ocr support
|
|
testDriver = config.pythonTestDriverPackage.override {
|
|
inherit (config) enableOCR extraPythonPackages;
|
|
enableNspawn = config.containers != { };
|
|
};
|
|
|
|
typeHints =
|
|
let
|
|
pythonizeName =
|
|
name:
|
|
let
|
|
head = lib.substring 0 1 name;
|
|
tail = lib.substring 1 (-1) name;
|
|
in
|
|
(if builtins.match "[A-z_]" head == null then "_" else head)
|
|
+ lib.stringAsChars (c: if builtins.match "[A-z0-9_]" c == null then "_" else c) tail;
|
|
|
|
vmMachineNames = lib.attrNames config.driverConfiguration.vms;
|
|
containerMachineNames = lib.attrNames config.driverConfiguration.containers;
|
|
|
|
theOnlyMachine =
|
|
let
|
|
exactlyOneMachine = lib.length (lib.attrValues config.nodes) == 1;
|
|
allMachineNames = lib.attrNames config.allMachines;
|
|
in
|
|
lib.optional (exactlyOneMachine && !lib.elem "machine" allMachineNames) "machine";
|
|
|
|
vmMachineTypeHints = map (name: "${pythonizeName name} = create_fake_qemu_machine()") (
|
|
vmMachineNames ++ theOnlyMachine
|
|
);
|
|
containerMachineTypeHints = map (
|
|
name: "${pythonizeName name} = create_fake_nspawn_machine()"
|
|
) containerMachineNames;
|
|
vlanTypeHints = map (i: "vlan${toString i} = create_fake_vlan()") config.driverConfiguration.vlans;
|
|
in
|
|
lib.strings.concatStringsSep "\n" (
|
|
vlanTypeHints ++ vmMachineTypeHints ++ containerMachineTypeHints
|
|
);
|
|
|
|
withChecks = lib.warnIf config.skipLint "Linting is disabled";
|
|
|
|
driver =
|
|
hostPkgs.runCommand "nixos-test-driver-${config.name}"
|
|
{
|
|
# inherit testName; TODO (roberth): need this?
|
|
nativeBuildInputs = [
|
|
hostPkgs.makeWrapper
|
|
]
|
|
++ lib.optionals (!config.skipTypeCheck) [ hostPkgs.ty ]
|
|
++ lib.optionals (!config.skipLint) [ hostPkgs.ruff ];
|
|
buildInputs = [ testDriver ];
|
|
testScript = config.testScriptString;
|
|
preferLocalBuild = true;
|
|
passthru = config.passthru;
|
|
meta = config.meta // {
|
|
mainProgram = "nixos-test-driver";
|
|
};
|
|
}
|
|
''
|
|
mkdir -p $out/bin
|
|
|
|
${lib.optionalString (!config.skipTypeCheck || !config.skipLint) ''
|
|
# prepend type hints so the test script can be type checked with ty
|
|
cat "${../test-script-prepend.py}" >> testScriptWithTypes
|
|
echo "${toString typeHints}" >> testScriptWithTypes
|
|
echo -n "$testScript" >> testScriptWithTypes
|
|
''}
|
|
|
|
${lib.optionalString (!config.skipTypeCheck) ''
|
|
echo "Running type check (enable/disable: config.skipTypeCheck)"
|
|
echo "See https://nixos.org/manual/nixos/stable/#test-opt-skipTypeCheck"
|
|
|
|
ty check testScriptWithTypes
|
|
''}
|
|
|
|
${lib.optionalString (!config.skipLint) ''
|
|
echo "Linting test script (enable/disable: config.skipLint)"
|
|
echo "See https://nixos.org/manual/nixos/stable/#test-opt-skipLint"
|
|
|
|
# F are the "(py)flakes" checks.
|
|
# we can't go with the defaults because these include
|
|
# code style/formatting
|
|
ruff check --select F testScriptWithTypes
|
|
''}
|
|
|
|
cp "${config.driverConfiguration.test_script}" $out/test-script
|
|
|
|
ln -s ${testDriver}/bin/nixos-test-driver $out/bin/nixos-test-driver
|
|
|
|
wrapProgram $out/bin/nixos-test-driver \
|
|
--add-flags "--config ${config.driverConfigurationFile}" \
|
|
--add-flags "--log-level ${config.logLevel}" \
|
|
${lib.escapeShellArgs (
|
|
lib.concatMap (arg: [
|
|
"--add-flags"
|
|
arg
|
|
]) config.extraDriverArgs
|
|
)}
|
|
'';
|
|
|
|
in
|
|
{
|
|
options = {
|
|
pythonTestDriverPackage = mkOption {
|
|
description = "Package containing the python NixOS test driver implementation";
|
|
type = types.package;
|
|
default = hostPkgs.nixos-test-driver;
|
|
defaultText = literalExpression "hostPkgs.nixos-test-driver";
|
|
readOnly = true;
|
|
};
|
|
|
|
driver = mkOption {
|
|
description = "Package containing a script that runs the test.";
|
|
type = types.package;
|
|
defaultText = literalMD "set by the test framework";
|
|
};
|
|
|
|
hostPkgs = mkOption {
|
|
description = "Nixpkgs attrset used outside the nodes.";
|
|
type = types.raw;
|
|
example = lib.literalExpression ''
|
|
import nixpkgs { inherit system config overlays; }
|
|
'';
|
|
};
|
|
|
|
qemu.package = mkOption {
|
|
description = "Which qemu package to use for the virtualisation of [{option}`nodes`](#test-opt-nodes).";
|
|
type = types.package;
|
|
default = hostPkgs.qemu_test;
|
|
defaultText = "hostPkgs.qemu_test";
|
|
};
|
|
|
|
qemu.forceAccel = mkOption {
|
|
description = ''
|
|
Whether to force the use of hardware-accelerated virtualisation.
|
|
When enabled, QEMU will not fall back to the slower software emulation
|
|
(TCG) and will instead error out if the accelerator is not available.
|
|
'';
|
|
type = types.bool;
|
|
default = false;
|
|
};
|
|
|
|
globalTimeout = mkOption {
|
|
description = ''
|
|
A global timeout for the complete test, expressed in seconds.
|
|
Beyond that timeout, every resource will be killed and released and the test will fail.
|
|
|
|
By default, we use a 1 hour timeout.
|
|
'';
|
|
type = types.int;
|
|
default = 60 * 60;
|
|
example = 10 * 60;
|
|
};
|
|
|
|
enableOCR = mkOption {
|
|
description = ''
|
|
Whether to enable Optical Character Recognition functionality for
|
|
testing graphical programs. See [`Machine objects`](#ssec-machine-objects).
|
|
'';
|
|
type = types.bool;
|
|
default = false;
|
|
};
|
|
|
|
extraPythonPackages = mkOption {
|
|
description = ''
|
|
Python packages to add to the test driver.
|
|
|
|
The argument is a Python package set, similar to `pkgs.pythonPackages`.
|
|
'';
|
|
example = lib.literalExpression ''
|
|
p: [ p.numpy ]
|
|
'';
|
|
type = types.functionTo (types.listOf types.package);
|
|
default = ps: [ ];
|
|
};
|
|
|
|
extraDriverArgs = mkOption {
|
|
description = ''
|
|
Extra arguments to pass to the test driver.
|
|
|
|
They become part of [{option}`driver`](#test-opt-driver) via `wrapProgram`.
|
|
'';
|
|
type = types.listOf types.str;
|
|
default = [ ];
|
|
};
|
|
|
|
skipLint = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
description = ''
|
|
Do not run the linters. This may speed up your iteration cycle, but it is not something you should commit.
|
|
'';
|
|
};
|
|
|
|
skipTypeCheck = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
description = ''
|
|
Disable type checking. This must not be enabled for new NixOS tests.
|
|
|
|
This may speed up your iteration cycle, unless you're working on the [{option}`testScript`](#test-opt-testScript).
|
|
'';
|
|
};
|
|
|
|
logLevel = mkOption {
|
|
description = "Log level for the test driver.";
|
|
type = types.enum [
|
|
"debug"
|
|
"info"
|
|
"warning"
|
|
"error"
|
|
];
|
|
default = "info";
|
|
example = "warning";
|
|
};
|
|
};
|
|
|
|
config = {
|
|
_module.args = {
|
|
hostPkgs =
|
|
# Comment is in nixos/modules/misc/nixpkgs.nix
|
|
lib.mkOverride lib.modules.defaultOverridePriority config.hostPkgs;
|
|
};
|
|
|
|
driver = withChecks driver;
|
|
|
|
# make available on the test runner
|
|
passthru.driver = config.driver;
|
|
|
|
nodeDefaults =
|
|
{ config, ... }:
|
|
{
|
|
# This is needed for the SSH backdoor to function.
|
|
# Set this to `true` by default to not change essential QEMU flags
|
|
# depending on whether debugging is enabled.
|
|
#
|
|
# If needed, this can still be turned off.
|
|
virtualisation.qemu.enableSharedMemory = lib.mkDefault isLinux;
|
|
# Needed for screenshots to work (in e.g `nixosTests.login`)
|
|
virtualisation.qemu.options = lib.optionals (isLinux && isAarch64) [
|
|
"-device virtio-gpu-pci"
|
|
];
|
|
|
|
assertions = [
|
|
{
|
|
assertion = sshBackdoor.enable -> config.virtualisation.qemu.enableSharedMemory;
|
|
message = ''
|
|
When turning on the SSH backdoor of the NixOS test-framework,
|
|
`virtualisation.qemu.enableSharedMemory` MUST be `true`
|
|
(affected: ${config.networking.hostName}).
|
|
'';
|
|
}
|
|
];
|
|
};
|
|
};
|
|
}
|