Changelog¶
A curated index of upstream nixpkgs PRs that touched the NixOS test driver, so you don't have to watch the PR firehose yourself. Entries are grouped by month and tagged as bugfix, new feature (with pointers into the relevant section of this manual), or maintenance (brief by design).
2026-05¶
PR #509615 — ty and ruff for test scripts¶
Maintenance: typechecking and linting of testScript now use ty and ruff instead of mypy and pyflakes.
The Astral toolchain (ty for typechecking, ruff for linting) replaces mypy and pyflakes when checking the Python testScript of a NixOS test. The new tools are much faster but produce different — and in some cases stricter — diagnostics, so existing tests may surface new warnings.
Only the test script is migrated in this PR; switching the driver itself is tracked separately in PR #509654.
Contributors: @tfc
PR #511859 — deprecate machine for single-node tests¶
Deprecation: referring to the only node of a test as machine (when the node is named differently) now emits a warning and will be removed.
Tests of the form
— where the only node is named foo but the testScript refers to it as machine — now print a deprecation warning. The behaviour is scheduled for removal in a future release. Use the actual node name (e.g. foo.start()) instead.
Contributors: @Ma27
2026-04¶
PR #512730 — don't assert on vhost_vsock¶
Bugfix: don't assert on vhost_vsock for interactive tests that have only containers and no VMs.
Follow-up to the macOS / vsock work in PR #512733: an assertion on vhost_vsock fired in driverInteractive for tests that contain only nspawn containers (no QEMU VMs).
Contributors: @tfc
PR #512733 — unbreak eval on macOS¶
Bugfix: restore evaluation of NixOS tests on macOS.
Eval on macOS (darwin) broke because the driver pulled in Linux-only dependencies (vhost-device-vsock) and QEMU shared-memory settings unconditionally. The fix:
- only depend on vsock packages on Linux
- only set
sharedMemoryQEMU option on Linux - use
hostPkgs(notpkgs) to build the test script and config file, so eval doesn't try to build Linux things for the guest system on a Darwin host.
Typical error messages looked roughly like error: Package 'vhost-device-vsock-...' is not available on the requested hostPlatform, or attribute 'vhost-device-vsock' missing while evaluating a NixOS test on aarch64-darwin / x86_64-darwin.
PR #511896 — fix driverInteractive test_script invocation¶
Bugfix: restore test_script invocation in driverInteractive after the JSON-config refactor.
Follow-up to PR #510385 (the JSON driver config-file refactor): a small regression in how the interactive driver passed the test script was corrected.
Contributors: @Ma27
PR #511413 — extra requiredFeatures options¶
New feature: declare extra required builder features and opt into the /dev/net sandbox check.
Adds a new option tree requiredFeatures.* on tests:
requiredFeatures.cuda— request arbitrary Nix builder features ("cuda"is just an example) so the builder selection routes the test to machines with GPUs.requiredFeatures.devnet— If a test combines VMs with containers make it an error if the builder is not configured to provide the"devnet"feature string. This is to provide a better error message than leaving the user with VMs and containers that can't connect to each other. See also Features: Container for more explanation.
This is also interesting for anyone running CUDA / GPU tests: see CUDA test tutorial.
Contributors: @tfc
PR #511225 — fix type-check-disabled case¶
Bugfix: restore tests that run with type-checking disabled.
Follow-up fix to PR #510385 (the config-file refactor). The branch that handled tests with type-checking disabled was broken, causing some Hydra failures.
Contributors: @mdaniels5757
PR #510385 — JSON driver config file¶
Maintenance: replace multiple env vars with a single JSON driver config file.
Historically, the old Perl implementation of the test driver used multiple environment variables as a way to provide named parameters in the test driver.
This change introduced a comprehensive configuration attribute set that is provided to the driver as a JSON file.
As a side benefit, the resolved configuration is now inspectable via test.driver.config.driverConfiguration, which is a nice debugging hook.
Contributors: @tfc
PR #510559 — skip sandbox prep outside sandbox¶
Bugfix: don't run sandbox-setup code when the driver runs outside the sandbox.
The driver was unconditionally running sandbox-preparation code (mount/bind-mount setup). This broke container tests when the driver was invoked outside the Nix sandbox — specifically driverInteractive or nix run ...#<test>.driverInteractive, and any non-sandboxed invocation.
Typical error messages look roughly like mount: permission denied, mount: /run/...: not a directory, or Python's PermissionError: [Errno 13] during container startup when running a test interactively (e.g. sudo $(nix build ...driverInteractive)/bin/nixos-test-driver --interactive).
Contributors: @tfc
PR #510699 — add remaining passthru.tests¶
Maintenance: wire the remaining internal driver tests into passthru.tests so CI runs them on every driver change.
Contributors: @m1-s
PR #510561 — driver tidy-up¶
Maintenance: drop an unused SENTINEL object and stop documenting _-prefixed internal methods.
PR #509488 — hide VDE switch log noise¶
New feature: suppress noisy VDE switch log output from test runs.
The VDE (virtual distributed ethernet) switch used for test networking was polluting test logs with implementation-detail messages. These are now suppressed.
Interesting for anyone who reads test logs — less noise, easier to find real issues.
Contributors: @m1-s
PR #453305 — vhost-device-vsock SSH backdoor¶
New feature: SSH backdoor via vhost-device-vsock — no more /dev/vhost-vsock in sandbox-paths, no more CID conflicts.
Rewires the SSH backdoor to use vhost-device-vsock (AF_VSOCK over a UNIX socket on the host side) instead of the kernel's vsock device. Two big user-visible wins:
- You no longer need
--option sandbox-paths /dev/vhost-vsockto debug tests inside the Nix sandbox. That means untrusted users can now debug these tests. - No more CID conflicts —
sshBackdoor.vsockOffsetbecomes unnecessary.
Requires systemd 258 and openssh 10.2p1 for best UX (fast login), but works with older systemd via manual SSH config.
Interesting for everyone using sshBackdoor.enable = true; and/or enableDebugHook = true; when connecting to machines in interactive mode or when debugging sandboxed tests with the error hook.
Contributors: @Ma27
PR #509553 — qemu.forceAccel option¶
New feature: qemu.forceAccel fails fast when KVM/HVF is unavailable instead of silently falling back to slow TCG.
Adds qemu.forceAccel = true; — when enabled, if KVM (Linux) or HVF (macOS) isn't available, the test fails fast with a clear error instead of silently falling back to TCG (which makes tests ~10x slower).
Error message when it trips:
forceAccel is enabled but /dev/kvm is not accessible (permission denied).
Check that your user is in the 'kvm' group or that /dev/kvm has the correct permissions.
Interesting for anyone who want tests to fail instead of getting mysteriously slow after a inadvertendt host reconfiguration. See also the testing host setup chapter.
PR #509654 — ty for the driver itself¶
Maintenance: typechecking of the test driver package switches from mypy to ty.
Sister change to PR #509615, which migrated the testScript side. This PR migrates the test driver package itself to ty, so internal driver development and packaging now use the same Astral toolchain. No user-visible behaviour change for test authors — only relevant when hacking on the driver.
Contributors: @tfc
PR #509867 — driver log levels¶
New feature: proper log levels in the test driver's Python logger.
Users can now control verbosity rather than getting firehose log output.
Interesting for anyone tired of sifting through driver debug logs, and for CI log hygiene.
See the new Driver log levels feature page.
Contributors: @m1-s
PR #504626 — fix create_machine() return type¶
Bugfix: create_machine() return type now correctly annotated as QemuMachine.
Type-annotation fix: create_machine() always returns a QemuMachine, but the type annotation was still referring to the abstract type, which meant callers couldn't invoke QEMU-specific methods without a type-check error.
Contributors: @alyssais
2026-03¶
PR #503686 — driver is overridable¶
New feature: the Python test driver is now a proper package (pkgs.nixos-test-driver) that can be overridden via overlays.
Packages the Python test driver as pkgs.nixos-test-driver and exposes it as config.pythonTestDriverPackage in the test module system. That means users can now override the driver via overlays — e.g. apply patches to the driver Python code for experimental features (exactly what the CUDA tutorial does).
Interesting for advanced users who want to patch the driver (CUDA folks, people implementing new machine backends, people testing driver PRs).
See the Overriding the test driver itself section in the overlays tutorial.
Contributors: @tfc
PR #503070 — fix testScript regressions¶
Bugfix: restore testScript linting and expose a generic machines variable after the nspawn refactor.
Cleanup of regressions introduced by the big nspawn PR #478109: provides a generic machines variable to testScript (union of QEMU and nspawn) plus BaseMachine / QemuMachine / NspawnMachine types for linting, and fixes several nixpkgs tests' type annotations.
Contributors: @kmein
PR #501599 — fix testScript without ellipsis¶
Bugfix: restore testScript = { nodes }: ... (strict pattern match without ...) which broke after the nspawn PR added a containers argument.
The nspawn PR added a containers argument to the testScript function caller. Tests whose testScript = { nodes }: ... used strict pattern matching (no ...) broke, because Nix rejected the unexpected containers arg. Fixed with builtins.intersectAttrs.
Contributors: @Mic92
PR #501294 — fix extract-docstrings types¶
Bugfix: correct type annotations in the docstring-extraction script after the nspawn refactor.
Fixup for #479968 — the docstring-extraction script used for rendering the machine API reference had bad type annotations after the nspawn refactor.
Typical error messages look roughly like a manual build failure with mypy: error: Incompatible types in assignment, or an AttributeError in extract-docstrings.py when nix-build nixos/release.nix -A manual.x86_64-linux runs.
Contributors: @kmein
PR #479968 — document nspawn in NixOS manual¶
New feature: upstream NixOS manual now documents the systemd-nspawn test backend.
Adds/restructures the upstream NixOS manual section for systemd-nspawn test containers: when to choose containers vs VMs, host setup (auto-allocate-uids, sandbox-paths), writing container tests, debugging them.
This is the upstream equivalent of what this manual covers in Features: Containers.
Contributors: @kmein
PR #478109 — nspawn container backend¶
New feature: systemd-nspawn as a second machine backend alongside QEMU — ~25% faster, no bare-metal required, enables GPU/device bind-mounts.
The big one. Adds systemd-nspawn as a second machine backend next to QEMU:
- ~25% faster test execution in benchmarks vs QEMU.
- Runs in cheap VMs (no bare-metal with KVM required).
- Allows device bind-mounts — enabling CUDA/GPU testing inside NixOS tests for the first time.
- Lays the groundwork for further machine backends.
New things exposed to users:
containers.<name>alongsidenodes.<name>in test definitionsmachines,machines_qemu,machines_nspawnintestScriptBaseMachine/QemuMachine/NspawnMachinePython types--keep-machine-statereplacing--keep-vm-state(deprecation)copy_from_machinereplacingcopy_from_vm(deprecation)/etc/hostsis now VLAN-aware- Limitations: no kernel tests, no setuid wrappers, no graphical tests, limited
/devaccess.
Extensively documented in this manual (with references to original NixOS manual):
Contributors: @kmein, @jfly, @KiaraGrouwstra, @roberth
2026-02¶
PR #487754 — fix nix-shell for driver¶
Bugfix: nix-shell now works in nixpkgs/nixos/lib/test-driver again.
Fixes nix-shell in nixpkgs/nixos/lib/test-driver — it was failing because shell.nix called callPackage instead of python3Packages.callPackage, so buildPythonApplication wasn't in scope.
Typical error messages look roughly like:
error: evaluation aborted with the following error message:
'lib.customisation.callPackageWith: Function called without required
argument "buildPythonApplication" at […]/nixos/lib/test-driver/default.nix:4'
Only relevant to people hacking on the test driver itself (entering its dev shell), not to test authors.
2026-01¶
PR #470248 — nspawn-container profile¶
New feature: standalone nspawn-container NixOS profile — the foundation for container-based tests.
Adds the standalone nspawn-container NixOS profile (${modulesPath}/virtualisation/nspawn-container) that builds a runnable run-<name>-nspawn script — analogous to qemu-vm.nix. Shares networking options (virtualisation.vlans, virtualisation.allInterfaces) with qemu-vm.nix via a factored-out module.
This is the foundation on which PR #478109 was then built to enable container tests.
Not documented as a standalone profile in this manual (we document its use via the test driver, not as a general-purpose NixOS profile). The profile is mostly internal plumbing.