nixos/misc/nixpkgs: add tests for nixpkgs.config.allowUnfreePackages

This commit is contained in:
Martin Häcker
2026-01-03 20:40:38 +01:00
parent a3c9221d64
commit b9cccbb973
4 changed files with 270 additions and 2 deletions
@@ -0,0 +1,124 @@
# Test for allowUnfreePackages merging across multiple modules
# Run with: nix-build -A nixosTests.nixpkgs-config-allow-unfree --show-trace
{
evalMinimalConfig,
lib,
}:
let
eval =
modules:
evalMinimalConfig {
imports = [
../nixpkgs.nix
]
++ modules;
};
getConfig = evalResult: evalResult.config.nixpkgs.config;
sortList = list: builtins.sort builtins.lessThan list;
assertEquals =
expected: actual:
let
prettyExpected = lib.generators.toPretty { } expected;
prettyActual = lib.generators.toPretty { } actual;
in
lib.assertMsg (expected == actual) "Expected ${prettyExpected} but got ${prettyActual}";
assertUnfreePackages =
listOfModules: expectedPackages:
let
config = getConfig (eval listOfModules);
actualAllowedUnfreePackages = sortList config.allowUnfreePackages;
in
assertEquals expectedPackages actualAllowedUnfreePackages;
in
lib.recurseIntoAttrs {
singleModuleTest =
assertUnfreePackages
[
{
nixpkgs.config.allowUnfreePackages = [
"package1"
"package2"
];
}
]
[
"package1"
"package2"
];
multipleModulesMerging =
assertUnfreePackages
[
{
_file = "module1.nix";
nixpkgs.config.allowUnfreePackages = [
"package1"
"package2"
];
}
{
_file = "module2.nix";
nixpkgs.config.allowUnfreePackages = [
"package3"
"package4"
];
}
{
_file = "module3.nix";
nixpkgs.config.allowUnfreePackages = [ "package5" ];
}
]
[
"package1"
"package2"
"package3"
"package4"
"package5"
];
overlappingPackagesMerging =
assertUnfreePackages
[
{
_file = "moduleA.nix";
nixpkgs.config.allowUnfreePackages = [
"shared-package"
"unique-a"
];
}
{
_file = "moduleB.nix";
nixpkgs.config.allowUnfreePackages = [
"shared-package"
"unique-b"
];
}
]
[
"shared-package"
"shared-package"
"unique-a"
"unique-b"
];
emptyListMerging =
assertUnfreePackages
[
{
_file = "empty.nix";
nixpkgs.config.allowUnfreePackages = [ ];
}
{
_file = "non-empty.nix";
nixpkgs.config.allowUnfreePackages = [ "some-package" ];
}
]
[ "some-package" ];
}
+7
View File
@@ -1103,6 +1103,13 @@ in
imports = [ ./nixos-rebuild-target-host.nix ];
};
nixpkgs = pkgs.callPackage ../modules/misc/nixpkgs/test.nix { inherit evalMinimalConfig; };
nixpkgs-config-allow-unfree =
pkgs.callPackage ../modules/misc/nixpkgs/test-nixpkgs-config-allow-unfree.nix
{ inherit evalMinimalConfig; };
nixpkgs-config-allow-unfree-packages-and-predicate =
pkgs.callPackage ../../pkgs/stdenv/generic/check-meta-test.nix
{ };
nixseparatedebuginfod = runTest ./nixseparatedebuginfod.nix;
nixseparatedebuginfod2 = runTest ./nixseparatedebuginfod2.nix;
node-red = runTest ./node-red.nix;
nomad = runTest ./nomad.nix;
+128
View File
@@ -0,0 +1,128 @@
# Execute with
# nix-build -A nixosTests.nixpkgs-config-allow-unfree-packages-and-predicate --show-trace
#
# This test exercises the interaction between:
#
# - nixos/modules/misc/nixpkgs.nix (config merging, esp. allowUnfreePackages)
# - pkgs/stdenv/generic/check-meta.nix (allowUnfreePredicate logic)
#
# It checks how:
#
# * config.allowUnfreePackages
# * config.allowUnfreePredicate
#
# interact to determine whether unfree packages are allowed.
{
lib,
pkgs,
}:
let
inherit (lib)
assertMsg
generators
licenses
recurseIntoAttrs
;
mkUnfreePkg = name: {
pname = name;
version = "1.0";
meta.license = licenses.unfree;
};
assertValidity =
{
nixpkgsConfig,
pkg,
expected ? true,
}:
let
testPkgs = import ../../.. {
system = pkgs.stdenv.hostPlatform.system;
config = nixpkgsConfig;
};
checkMeta = testPkgs.callPackage ./check-meta.nix { };
tryEval = expression: builtins.tryEval (builtins.deepSeq expression expression);
actual = tryEval (
checkMeta.assertValidity {
meta = pkg.meta;
attrs = pkg;
}
);
toPretty = generators.toPretty { };
in
assertMsg (actual.success == expected) ''
Expected validity of package ${lib.getName pkg} to be ${toPretty expected},
but got ${toPretty actual} with config:
${toPretty nixpkgsConfig}
'';
runAssertions = assertions: lib.deepSeq assertions "";
in
recurseIntoAttrs {
allowOnlyFreePackagesByDefault = assertValidity {
nixpkgsConfig = { };
pkg = mkUnfreePkg "forbidden";
expected = false;
};
allowAllUnfreePackages = assertValidity {
nixpkgsConfig = {
allowUnfree = true;
};
pkg = mkUnfreePkg "allowed";
};
allowUnfreePackagesWithPredicate =
let
nixpkgsConfig = {
allowUnfreePredicate = pkg: lib.getName pkg == "allowed-by-predicate";
};
in
[
(assertValidity {
inherit nixpkgsConfig;
pkg = mkUnfreePkg "allowed-by-predicate";
})
(assertValidity {
inherit nixpkgsConfig;
pkg = mkUnfreePkg "allowed-by-nothing";
expected = false;
})
];
allowUnfreeWithPackages = runAssertions [
(assertValidity {
nixpkgsConfig = {
allowUnfreePackages = [ "unfree" ];
};
pkg = mkUnfreePkg "unfree";
expected = true;
})
];
allowUnfreePackagesOrPredicate =
let
nixpkgsConfig = {
allowUnfreePackages = [ "allowed-by-packages" ];
allowUnfreePredicate = pkg: lib.getName pkg == "allowed-by-predicate";
};
in
runAssertions [
(assertValidity {
inherit nixpkgsConfig;
pkg = mkUnfreePkg "allowed-by-packages";
})
(assertValidity {
inherit nixpkgsConfig;
pkg = mkUnfreePkg "allowed-by-predicate";
})
(assertValidity {
inherit nixpkgsConfig;
pkg = mkUnfreePkg "forbidden";
expected = false;
})
];
}
+11 -2
View File
@@ -160,8 +160,17 @@ let
# }
# Defaults to allow all names defined in config.allowUnfreePackages
allowUnfreePredicate =
config.allowUnfreePredicate
or (pkg: builtins.elem (lib.getName pkg) config.allowUnfreePackages or [ ]);
let
listPredicate = pkg: builtins.elem (lib.getName pkg) (config.allowUnfreePackages or [ ]);
# Be robust against misconfigured allowUnfreePredicate values such as null
explicitPredicate =
let
raw = config.allowUnfreePredicate or null;
in
if builtins.isFunction raw then raw else (_: false);
in
pkg: (listPredicate pkg) || (explicitPredicate pkg);
# Check whether unfree packages are allowed and if not, whether the
# package has an unfree license and is not explicitly allowed by the