Files
lix/tests/functional2/flakes/test_flake_in_submodule.py
T
eldritch horrors 7a3f352105 testing: migrate flakes/flake-in-submodule.sh
Change-Id: I9dcf63a2f63b54de541536a00dbd5d8df941ea33
2026-02-22 20:46:06 +00:00

150 lines
5.4 KiB
Python

"""
Tests that:
- flake.nix may reside inside of a git submodule
- the flake can access content outside of the submodule
rootRepo
├── root.nix
└── submodule
├── flake.nix
└── sub.nix
"""
from testlib.fixtures.nix import Nix
from testlib.fixtures.env import ManagedEnv
from testlib.fixtures.git import Git
from testlib.fixtures.file_helper import with_files, File, EnvTemplate
from testlib.utils import get_global_asset_pack
from pathlib import Path
import pytest
import re
import json
import shutil
root_without_self = get_global_asset_pack(".git") | {"root.nix": File('"expression in root repo"')}
root_with_self = root_without_self | {
"flake.nix": File("""{
inputs.self.submodules = true;
outputs = { self }: {
foo = self.outPath;
};
}""")
}
submodule = get_global_asset_pack(".git") | {
"flake.nix": File("""{
outputs = { self }: {
sub = import ./sub.nix;
root = import ../root.nix;
};
}"""),
"sub.nix": File('"expression in submodule"'),
}
@pytest.fixture(autouse=True)
def common_init(nix: Nix, env: ManagedEnv, git: Git, files: Path):
nix.settings.add_xp_feature("nix-command", "flakes")
# Submodules can't be fetched locally by default, which can cause
# information leakage vulnerabilities, but for these tests our
# submodule is intentionally local and it's all trusted, so we
# disable this restriction. Setting it per repo is not sufficient, as
# the repo-local config does not apply to the commands run from
# outside the repos by Nix.
env["XDG_CONFIG_HOME"] = str(env.dirs.home / ".config")
git(None, "config", "--global", "protocol.file.allow", "always")
git(files / "submodule", "add", "flake.nix", "sub.nix")
git(files / "submodule", "commit", "-m", "Initial")
git(files / "rootRepo", "submodule", "init")
git(files / "rootRepo", "submodule", "add", files / "submodule", "submodule")
git(files / "rootRepo", "add", "root.nix")
git(files / "rootRepo", "commit", "-m", "Add root.nix")
@with_files({"rootRepo": root_without_self, "submodule": submodule})
class TestSubmoduleAccess:
@pytest.fixture(autouse=True)
def init(self, files: Path):
self.flakeref = f"git+file://{files}/rootRepo?submodules=1&dir=submodule"
def test_flake_access_via_dir_param(self, nix: Nix):
result = nix.nix(["eval", "--json", f"{self.flakeref}#sub"]).run().json()
assert result == "expression in submodule"
def test_flake_access_parents_via_dir_param(self, nix: Nix):
result = nix.nix(["eval", "--json", f"{self.flakeref}#root"]).run().json()
assert result == "expression in root repo"
@with_files(
{
"rootRepo": root_with_self,
"submodule": submodule,
"otherRepo": get_global_asset_pack(".git")
| {
"flake.nix": EnvTemplate("""{
inputs.root.url = "git+file://@HOME@/rootRepo";
outputs = { self, root }: {
foo = root.foo;
};
}""")
},
}
)
class TestSelf:
@pytest.fixture(autouse=True)
def init(self, git: Git, files: Path):
git(files / "rootRepo", "add", "flake.nix")
git(files / "rootRepo", "commit", "-m", "Bla")
def test_no_access_without_xp_feature(self, nix: Nix, files: Path):
result = nix.nix(["eval", "--raw", f"{files}/rootRepo#foo"]).run().expect(1)
assert "experimental Lix feature 'flake-self-attrs' is disabled" in result.stderr_s
def test_access_with_xp_feature(self, nix: Nix, files: Path):
nix.settings.add_xp_feature("flake-self-attrs")
result = nix.nix(["eval", "--raw", f"{files}/rootRepo#foo"]).run().ok()
assert (Path(result.stdout_s.strip()) / "submodule").exists()
class TestSelfDependency:
@pytest.fixture(autouse=True)
def init_dep(self, git: Git, files: Path):
git(files / "otherRepo", "add", "flake.nix")
def test_no_access_without_xp_feature(self, nix: Nix, files: Path):
result = nix.nix(["eval", "--raw", f"{files}/otherRepo#foo"]).run().expect(1)
assert "experimental Lix feature 'flake-self-attrs' is disabled" in result.stderr_s
def test_access_with_xp_feature(self, nix: Nix, files: Path):
nix.settings.add_xp_feature("flake-self-attrs")
result = nix.nix(["eval", "--raw", "-vvvvv", f"{files}/otherRepo#foo"]).run().ok()
assert re.search(
r"refetching input 'git\+file://.+/rootRepo.+' due to self attribute",
result.stderr_s,
)
assert (Path(result.stdout_s.strip()) / "submodule").exists()
def test_submodules_are_locked(self, nix: Nix, files: Path):
nix.settings.add_xp_feature("flake-self-attrs")
nix.nix(["eval", "--raw", "-vvvvv", f"{files}/otherRepo#foo"]).run().ok()
lockfile = json.loads((files / "otherRepo/flake.lock").read_text())
assert lockfile["nodes"]["root_2"]["locked"]["submodules"]
def test_double_eval_does_not_refetch(self, nix: Nix, files: Path):
nix.settings.add_xp_feature("flake-self-attrs")
nix.nix(["eval", "--raw", f"{files}/otherRepo#foo"]).run().ok()
shutil.rmtree(nix.env.dirs.home / ".cache")
nix.clear_store()
result = nix.nix(["eval", "--raw", "-vvvvv", f"{files}/otherRepo#foo"]).run().ok()
assert "refetching" not in result.stderr_s