test(perSystem): make sure it is memoized

This commit is contained in:
Robert Hensing 2026-05-02 18:33:24 +01:00
parent 345165ec93
commit 35814d5c11
3 changed files with 51 additions and 0 deletions

View file

@ -42,6 +42,10 @@
let tests = import ./tests/eval-tests.nix { flake-parts = self; };
in tests.runTests pkgs.emptyFile // { internals = tests; };
checks.perSystem-memoize = pkgs.callPackage ./tests/perSystem-memoize.nix {
flake-parts = self;
};
nix-unit.tests = import ./tests/nix-unit.nix { flake-parts = self; };
# nix-unit evaluates the flake, which triggers the dev partition via

View file

@ -0,0 +1,32 @@
# Test that perSystem evaluation is memoized: calling withSystem twice for the
# same undeclared system should only evaluate perSystem once.
# Run with:
# nix build .#checks.x86_64-linux.perSystem-memoize
{ flake-parts, runCommand, nix }:
runCommand "perSystem-memoize" { nativeBuildInputs = [ nix ]; } ''
export HOME="$(realpath .)"
unset NIX_STORE
export NIX_STORE_DIR=${builtins.storeDir}
export NIX_REMOTE="$HOME/storedata"
nix eval \
--extra-experimental-features 'nix-command flakes' \
--no-write-lock-file \
--offline \
--substituters "" \
--override-input flake-parts ${flake-parts} \
--override-input flake-parts/nixpkgs-lib ${flake-parts.inputs.nixpkgs-lib} \
"${./perSystem-memoize}#result" \
2>eval-stderr
count=$(grep -c "Evaluating perSystem for foo" eval-stderr || true)
cat eval-stderr >&2
echo "Trace count: $count"
if [ "$count" -ne 1 ]; then
echo "FAIL: expected perSystem to be evaluated exactly once, but it was evaluated $count times"
exit 1
fi
echo "PASS: perSystem evaluated exactly once"
touch $out
''

View file

@ -0,0 +1,15 @@
{
inputs.flake-parts.url = "github:hercules-ci/flake-parts";
outputs = inputs:
inputs.flake-parts.lib.mkFlake { inherit inputs; } ({ withSystem, ... }: {
systems = [ ];
perSystem = { system, ... }:
builtins.trace "Evaluating perSystem for ${system}" { };
flake.result =
let
a = withSystem "foo" ({ config, ... }: null);
b = withSystem "foo" ({ config, ... }: "ok");
in
builtins.seq a b;
});
}