Skip to content

Commit

Permalink
macOS support for NixOS tests (#282401)
Browse files Browse the repository at this point in the history
Closes #193336
Closes #261694
Related to #108984

The goal here was to get the following flake to build and run on
`aarch64-darwin`:

```nix
{ inputs.nixpkgs.url = <this branch>;

  outputs = { nixpkgs, ... }: {
    checks.aarch64-darwin.default =
      nixpkgs.legacyPackages.aarch64-darwin.nixosTest {
        name = "test";

        nodes.machine = { };

        testScript = "";
      };
  };
}
```

… and after this change it does.  There's no longer a need for the
user to set `nodes.*.nixpkgs.pkgs` or
`nodes.*.virtualisation.host.pkgs` as the correct values are inferred
from the host system.
  • Loading branch information
Gabriella439 authored Mar 2, 2024
1 parent 458b097 commit b8698cd
Show file tree
Hide file tree
Showing 9 changed files with 51 additions and 10 deletions.
22 changes: 21 additions & 1 deletion nixos/lib/testing/nodes.nix
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,25 @@ let
types
;

inherit (hostPkgs) hostPlatform;

guestSystem =
if hostPlatform.isLinux
then hostPlatform.system
else
let
hostToGuest = {
"x86_64-darwin" = "x86_64-linux";
"aarch64-darwin" = "aarch64-linux";
};

supportedHosts = lib.concatStringsSep ", " (lib.attrNames hostToGuest);

message =
"NixOS Test: don't know which VM guest system to pair with VM host system: ${hostPlatform.system}. Perhaps you intended to run the tests on a Linux host, or one of the following systems that may run NixOS tests: ${supportedHosts}";
in
hostToGuest.${hostPlatform.system} or (throw message);

baseOS =
import ../eval-config.nix {
inherit lib;
Expand All @@ -27,13 +46,14 @@ let
({ config, ... }:
{
virtualisation.qemu.package = testModuleArgs.config.qemu.package;
virtualisation.host.pkgs = hostPkgs;
})
({ options, ... }: {
key = "nodes.nix-pkgs";
config = optionalAttrs (!config.node.pkgsReadOnly) (
mkIf (!options.nixpkgs.pkgs.isDefined) {
# TODO: switch to nixpkgs.hostPlatform and make sure containers-imperative test still evaluates.
nixpkgs.system = hostPkgs.stdenv.hostPlatform.system;
nixpkgs.system = guestSystem;
}
);
})
Expand Down
6 changes: 5 additions & 1 deletion nixos/lib/testing/pkgs.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
{
config = {
# default pkgs for use in VMs
_module.args.pkgs = hostPkgs;
_module.args.pkgs =
# TODO: deprecate it everywhere; not just on darwin. Throw on darwin?
lib.warnIf hostPkgs.stdenv.hostPlatform.isDarwin
"Do not use the `pkgs` module argument in tests you want to run on darwin. It is ambiguous, and many tests are broken because of it. If you need to use a package on the VM host, use `hostPkgs`. Otherwise, use `config.node.pkgs`, or `config.nodes.<name>.nixpkgs.pkgs`."
hostPkgs;

defaults = {
# TODO: a module to set a shared pkgs, if options.nixpkgs.* is untouched by user (highestPrio) */
Expand Down
4 changes: 3 additions & 1 deletion nixos/lib/testing/run.nix
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ in
rawTestDerivation = hostPkgs.stdenv.mkDerivation {
name = "vm-test-run-${config.name}";

requiredSystemFeatures = [ "kvm" "nixos-test" ];
requiredSystemFeatures = [ "nixos-test" ]
++ lib.optionals hostPkgs.stdenv.hostPlatform.isLinux [ "kvm" ]
++ lib.optionals hostPkgs.stdenv.hostPlatform.isDarwin [ "apple-virt" ];

buildCommand = ''
mkdir -p $out
Expand Down
5 changes: 4 additions & 1 deletion nixos/tests/acme.nix
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{ pkgs, lib, ... }: let
{ config, lib, ... }: let

pkgs = config.node.pkgs;

commonConfig = ./common/acme/client;

dnsServerIP = nodes: nodes.dnsserver.networking.primaryIPAddress;
Expand Down
3 changes: 2 additions & 1 deletion nixos/tests/all-tests.nix
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,9 @@ let
# it with `allowAliases = false`?
# warnIf pkgs.config.allowAliases "nixosTests: pkgs includes aliases."
{
_file = "${__curPos.file} readOnlyPkgs";
_class = "nixosTest";
node.pkgs = pkgs;
node.pkgs = pkgs.pkgsLinux;
};

in {
Expand Down
6 changes: 3 additions & 3 deletions pkgs/build-support/testers/default.nix
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{ pkgs, buildPackages, lib, callPackage, runCommand, stdenv, substituteAll, testers }:
{ pkgs, pkgsLinux, buildPackages, lib, callPackage, runCommand, stdenv, substituteAll, testers }:
# Documentation is in doc/builders/testers.chapter.md
{
# See https://nixos.org/manual/nixpkgs/unstable/#tester-testBuildFailure
Expand Down Expand Up @@ -107,7 +107,7 @@
(lib.setDefaultModuleLocation "the argument that was passed to pkgs.runNixOSTest" testModule)
];
hostPkgs = pkgs;
node.pkgs = pkgs;
node.pkgs = pkgsLinux;
};

# See doc/builders/testers.chapter.md or
Expand All @@ -123,7 +123,7 @@
inherit pkgs;
extraConfigurations = [(
{ lib, ... }: {
config.nixpkgs.pkgs = lib.mkDefault pkgs;
config.nixpkgs.pkgs = lib.mkDefault pkgsLinux;
}
)];
});
Expand Down
4 changes: 2 additions & 2 deletions pkgs/build-support/testers/test/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ lib.recurseIntoAttrs {

# Check that the wiring of nixosTest is correct.
# Correct operation of the NixOS test driver should be asserted elsewhere.
nixosTest-example = pkgs-with-overlay.testers.nixosTest ({ lib, pkgs, figlet, ... }: {
nixosTest-example = pkgs-with-overlay.testers.nixosTest ({ lib, ... }: {
name = "nixosTest-test";
nodes.machine = { pkgs, ... }: {
system.nixos = dummyVersioning;
environment.systemPackages = [ pkgs.proof-of-overlay-hello figlet ];
environment.systemPackages = [ pkgs.proof-of-overlay-hello pkgs.figlet ];
};
testScript = ''
machine.succeed("hello | figlet >/dev/console")
Expand Down
1 change: 1 addition & 0 deletions pkgs/top-level/release-attrpaths-superset.nix
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ let
pkgsStatic = true;
pkgsCross = true;
pkgsi686Linux = true;
pkgsLinux = true;
pkgsExtraHardening = true;
};

Expand Down
10 changes: 10 additions & 0 deletions pkgs/top-level/stage.nix
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,16 @@ let
};
} else throw "x86_64 Darwin package set can only be used on Darwin systems.";

# If already linux: the same package set unaltered
# Otherwise, return a natively built linux package set for the current cpu architecture string.
# (ABI and other details will be set to the default for the cpu/os pair)
pkgsLinux =
if stdenv.hostPlatform.isLinux
then self
else nixpkgsFun {
localSystem = lib.systems.elaborate "${stdenv.hostPlatform.parsed.cpu.name}-linux";
};

# Extend the package set with zero or more overlays. This preserves
# preexisting overlays. Prefer to initialize with the right overlays
# in one go when calling Nixpkgs, for performance and simplicity.
Expand Down

0 comments on commit b8698cd

Please sign in to comment.