From f2df62439cbf5e9b4072d5876f28a5b668b648df Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Sun, 22 Feb 2026 23:57:48 +0100 Subject: [PATCH] testing: migrate flakes/flakes.sh (part 18) nonflake inputs Change-Id: I5017ece5028652e3ae19c5e00e67358fc9c0253d --- tests/functional/flakes/flakes.sh | 168 --------------------------- tests/functional/meson.build | 1 - tests/functional2/flakes/test_cli.py | 116 +++++++++++++++++- 3 files changed, 113 insertions(+), 172 deletions(-) delete mode 100644 tests/functional/flakes/flakes.sh diff --git a/tests/functional/flakes/flakes.sh b/tests/functional/flakes/flakes.sh deleted file mode 100644 index f5adb8d33..000000000 --- a/tests/functional/flakes/flakes.sh +++ /dev/null @@ -1,168 +0,0 @@ -source ./common.sh - -requireGit - -clearStore -rm -rf $TEST_HOME/.cache $TEST_HOME/.config - -flake1Dir=$TEST_ROOT/flake1 -flake2Dir=$TEST_ROOT/flake2 -flake3Dir=$TEST_ROOT/flake3 -flake5Dir=$TEST_ROOT/flake5 -flake7Dir=$TEST_ROOT/flake7 -nonFlakeDir=$TEST_ROOT/nonFlake - -for repo in $flake1Dir $flake2Dir $flake3Dir $flake7Dir $nonFlakeDir; do - # Give one repo a non-main initial branch. - extraArgs= - if [[ $repo == $flake2Dir ]]; then - extraArgs="--initial-branch=main" - fi - - createGitRepo "$repo" "$extraArgs" -done - -createSimpleGitFlake $flake1Dir - -cat > $flake2Dir/flake.nix < $flake3Dir/flake.nix < $flake3Dir/default.nix < $nonFlakeDir/README.md < $flake1Dir/foo -git -C $flake1Dir add $flake1Dir/foo -echo -n '# foo' >> $flake1Dir/flake.nix -git -C $flake1Dir commit -a -m 'Foo' - -# set up lockfiles for later tests -nix build -o $TEST_ROOT/result $flake2Dir#bar --commit-lock-file -nix build -o $TEST_ROOT/result $flake3Dir#xyzzy -git -C $flake3Dir add flake.lock -git -C $flake3Dir commit -m 'Add lockfile' - -# Add nonFlakeInputs to flake3. -rm $flake3Dir/flake.nix - -cat > $flake3Dir/flake.nix < \$out - [[ \$(cat \${inputs.nonFlake}/README.md) = \$(cat \${inputs.nonFlakeFile}) ]] - [[ \${inputs.nonFlakeFile} = \${inputs.nonFlakeFile2} ]] - ''; - }; - }; -} -EOF - -cp ../config.nix $flake3Dir - -git -C $flake3Dir add flake.nix config.nix -git -C $flake3Dir commit -m 'Add nonFlakeInputs' - -# Check whether `nix build` works with a lockfile which is missing a -# nonFlakeInputs. -nix build -o $TEST_ROOT/result $flake3Dir#sth --commit-lock-file -# check that the commit message is broadly correct. we can't check for -# exact contents of the message becase the build dirs change too much. -[[ "$(git -C $flake3Dir show -s --format=format:%B)" = \ -"flake.lock: Update - -Flake lock file updates: - -• Added input 'flake1': - 'git+file://"*"/flakes/flakes/flake1?ref=refs/heads/master&rev="*"' "*" -• Added input 'nonFlake': - 'git+file://"*"/flakes/flakes/nonFlake?ref=refs/heads/master&rev="*"' "*" -• Added input 'nonFlakeFile': - 'path:"*"/flakes/flakes/nonFlake/README.md?lastModified="*"&narHash=sha256-cPh6hp48IOdRxVV3xGd0PDgSxgzj5N/2cK0rMPNaR4o%3D' "*" -• Added input 'nonFlakeFile2': - 'path:"*"/flakes/flakes/nonFlake/README.md?lastModified="*"&narHash=sha256-cPh6hp48IOdRxVV3xGd0PDgSxgzj5N/2cK0rMPNaR4o%3D' "* ]] - -nix build -o $TEST_ROOT/result flake3#fnord -[[ $(cat $TEST_ROOT/result) = FNORD ]] - -# Check whether flake input fetching is lazy: flake3#sth does not -# depend on flake2, so this shouldn't fail. -rm -rf $TEST_HOME/.cache -clearStore -mv $flake2Dir $flake2Dir.tmp -mv $nonFlakeDir $nonFlakeDir.tmp -nix build -o $TEST_ROOT/result flake3#sth -(! nix build -o $TEST_ROOT/result flake3#xyzzy) -(! nix build -o $TEST_ROOT/result flake3#fnord) -mv $flake2Dir.tmp $flake2Dir -mv $nonFlakeDir.tmp $nonFlakeDir -nix build -o $TEST_ROOT/result flake3#xyzzy flake3#fnord diff --git a/tests/functional/meson.build b/tests/functional/meson.build index 42ab13dd2..0aa9dc3a5 100644 --- a/tests/functional/meson.build +++ b/tests/functional/meson.build @@ -32,7 +32,6 @@ subdir('test-libstoreconsumer') functional_tests_scripts = [ 'init.sh', 'test-infra.sh', - 'flakes/flakes.sh', 'gc.sh', 'nix-collect-garbage-d.sh', 'nix-collect-garbage-dry-run.sh', diff --git a/tests/functional2/flakes/test_cli.py b/tests/functional2/flakes/test_cli.py index abff4725d..f44dea209 100644 --- a/tests/functional2/flakes/test_cli.py +++ b/tests/functional2/flakes/test_cli.py @@ -1,4 +1,6 @@ +from fnmatch import fnmatch from pathlib import Path +from textwrap import dedent import pytest import re import tarfile @@ -8,7 +10,7 @@ import shutil from testlib.fixtures.nix import Nix from testlib.fixtures.env import ManagedEnv from testlib.fixtures.git import Git -from testlib.utils import get_global_asset_pack +from testlib.utils import get_global_asset_pack, get_global_asset from testlib.fixtures.file_helper import with_files, File, FileDeclaration, _init_files # noqa: PLC2701 from testlib.environ import environ from .common import simple_flake, dependent_flake @@ -154,9 +156,12 @@ def flake7(git: Git, env: ManagedEnv, request: pytest.FixtureRequest) -> Path: @pytest.fixture -def nonflake(env: ManagedEnv, request: pytest.FixtureRequest) -> Path: +def nonflake(git: Git, env: ManagedEnv, request: pytest.FixtureRequest) -> Path: _init_files(nonflake_files, env.dirs.test_root, request.path.parent, env) - return env.dirs.test_root / "nonFlake" + repo = env.dirs.test_root / "nonFlake" + git(repo, "add", ".") + git(repo, "commit", "-m", "Initial") + return repo @pytest.fixture @@ -507,6 +512,111 @@ class TestBuild: nix.nix(["build", "flake4#xyzzy"]).run().ok() +@with_files({"config.nix": get_global_asset("config.nix")}) +@pytest.mark.usefixtures("registry") +class TestWithNonFlake: + @pytest.fixture(autouse=True) + def add_nonflake(self, flake3: Path, nonflake: Path, git: Git, files: Path): + (flake3 / "flake.nix").write_text(f"""{{ + inputs = {{ + flake1 = {{}}; + flake2 = {{}}; + nonFlake = {{ + url = "git+file://{nonflake}"; + flake = false; + }}; + nonFlakeFile = {{ + url = "path://{nonflake}/README.md"; + flake = false; + }}; + nonFlakeFile2 = {{ + url = "{nonflake}/README.md"; + flake = false; + }}; + }}; + outputs = inputs: rec {{ + packages.{system}.xyzzy = inputs.flake2.packages.{system}.bar; + packages.{system}.sth = inputs.flake1.packages.{system}.foo; + packages.{system}.fnord = + with import ./config.nix; + mkDerivation {{ + inherit system; + name = "fnord"; + dummy = builtins.readFile (builtins.path {{ name = "source"; path = ./.; filter = path: type: baseNameOf path == "config.nix"; }} + "/config.nix"); + dummy2 = builtins.readFile (builtins.path {{ name = "source"; path = inputs.flake1; filter = path: type: baseNameOf path == "simple.nix"; }} + "/simple.nix"); + buildCommand = '' + cat ${{inputs.nonFlake}}/README.md > $out + [[ $(cat ${{inputs.nonFlake}}/README.md) = $(cat ${{inputs.nonFlakeFile}}) ]] + [[ ${{inputs.nonFlakeFile}} = ${{inputs.nonFlakeFile2}} ]] + ''; + }}; + }}; + }}""") + (flake3 / "config.nix").write_text((files / "config.nix").read_text()) + git(flake3, "add", "flake.nix", "config.nix") + git(flake3, "commit", "-m", "Add nonFlakeInputs") + + def test_flake_lock_updates(self, nix: Nix, flake3: Path, git: Git): + nix.nix(["build", f"{flake3}#sth", "--commit-lock-file"]).run().ok() + msg = git(flake3, "show", "-s", "--format=format:%B").stdout_s + assert fnmatch( + msg, + dedent("""\ + flake.lock: Add + + Flake lock file updates: + + • Added input 'flake1': + 'git+file://*/flake1[?]ref=refs/heads/main&rev=*' * + • Added input 'nonFlake': + 'git+file://*/nonFlake[?]ref=refs/heads/main&rev=*' * + • Added input 'nonFlakeFile': + 'path:*/nonFlake/README.md[?]lastModified=*&narHash=sha256-W9JwWKcSn1bi98dD6XPmDM3cDkXXPK%2B9tLkPhjxAHyg%3D' * + • Added input 'nonFlakeFile2': + 'path:*/nonFlake/README.md[?]lastModified=*&narHash=sha256-W9JwWKcSn1bi98dD6XPmDM3cDkXXPK%2B9tLkPhjxAHyg%3D' *"""), + ) + + def test_build_nonflake(self, nix: Nix, flake3: Path): + nix.nix(["build", f"{flake3}#fnord"]).run().ok() + assert (nix.env.dirs.home / "result").read_text() == "FNORD" + + class TestFetchIsLazy: + """ + Check whether flake input fetching is lazy: flake3#sth does not + depend on flake2, so this shouldn't fail. + """ + + @pytest.fixture(autouse=True) + def clear_state( + self, + nix: Nix, + registry: Path, # noqa: ARG002 + flake2: Path, # noqa: ARG002 + flake3_locked: Path, # noqa: ARG002 + nonflake: Path, # noqa: ARG002 + ): + shutil.rmtree(nix.env.dirs.home / ".cache") + nix.clear_store() + + def test_deps_not_fetched_unless_needed(self, nix: Nix, flake2: Path, nonflake: Path): + shutil.rmtree(flake2) + shutil.rmtree(nonflake) + + nix.nix(["build", "flake3#sth"]).run().ok() + + def test_dep_fetches_fail_builds(self, nix: Nix, flake2: Path, nonflake: Path): + shutil.rmtree(flake2) + shutil.rmtree(nonflake) + result = nix.nix(["build", "flake3#xyzzy"]).run().expect(1).stderr_s + assert fnmatch(result, "*while fetching the input '*/flake2*'*") + result = nix.nix(["build", "flake3#fnord"]).run().expect(1).stderr_s + assert fnmatch(result, "*while fetching the input '*/nonFlake*'*") + + def test_deps_fetched_when_present(self, nix: Nix): + nix.nix(["build", "flake3#sth"]).run().ok() + nix.nix(["build", "flake3#xyzzy", "flake3#fnord"]).run().ok() + + @pytest.mark.usefixtures("registry") def test_update_with_override_flake(nix: Nix, flake3: Path, git: Git): nix.nix(