diff --git a/tests/functional/meson.build b/tests/functional/meson.build index c0262769e..352bcb03a 100644 --- a/tests/functional/meson.build +++ b/tests/functional/meson.build @@ -111,7 +111,6 @@ functional_tests_scripts = [ 'build-jobless.sh', 'nar-access.sh', 'impure-eval.sh', - 'pure-eval.sh', 'eval.sh', 'repl.sh', 'binary-cache-build-remote.sh', diff --git a/tests/functional/pure-eval.sh b/tests/functional/pure-eval.sh deleted file mode 100644 index 0eefae288..000000000 --- a/tests/functional/pure-eval.sh +++ /dev/null @@ -1,27 +0,0 @@ -source common.sh - -clearStore - -nix eval --expr 'assert 1 + 2 == 3; true' - -[[ $(nix eval --impure --expr 'builtins.readFile ./pure-eval.sh') =~ clearStore ]] - -missingImpureErrorMsg=$(! nix eval --expr 'builtins.readFile ./pure-eval.sh' 2>&1) - -echo "$missingImpureErrorMsg" | grepQuiet -- --impure || \ - fail "The error message should mention the “--impure” flag to unblock users" - -[[ $(nix eval --expr 'builtins.pathExists ./pure-eval.sh') == false ]] || \ - fail "Calling 'pathExists' on a non-authorised path should return false" - -(! nix eval --expr builtins.currentTime) -(! nix eval --expr builtins.currentSystem) - -(! nix-instantiate --pure-eval ./simple.nix) -(! nix eval --expr 'builtins.readDir "/"') - -[[ $(nix eval --impure --expr "(import (builtins.fetchurl { url = \"file://$(pwd)/pure-eval.nix\"; })).x") == 123 ]] -(! nix eval --expr "(import (builtins.fetchurl { url = \"file://$(pwd)/pure-eval.nix\"; })).x") -nix eval --expr "(import (builtins.fetchurl { url = \"file://$(pwd)/pure-eval.nix\"; sha256 = \"$(nix hash file pure-eval.nix --type sha256)\"; })).x" - -(! nix eval --expr '~/foo') diff --git a/tests/functional/pure-eval.nix b/tests/functional2/eval/assets/pure-eval.nix similarity index 100% rename from tests/functional/pure-eval.nix rename to tests/functional2/eval/assets/pure-eval.nix diff --git a/tests/functional2/eval/test_eval_trivial.py b/tests/functional2/eval/test_eval_trivial.py index eb292c1c9..95baae6a4 100644 --- a/tests/functional2/eval/test_eval_trivial.py +++ b/tests/functional2/eval/test_eval_trivial.py @@ -3,3 +3,7 @@ from functional2.testlib.fixtures.nix import Nix def test_trivial_addition(nix: Nix): assert nix.eval("1 + 1").json() == 2 + + +def test_trivial_assert(nix: Nix): + assert nix.eval("assert 1 + 2 == 3; true").json() is True diff --git a/tests/functional2/eval/test_pure_eval.py b/tests/functional2/eval/test_pure_eval.py new file mode 100644 index 000000000..0571b3be3 --- /dev/null +++ b/tests/functional2/eval/test_pure_eval.py @@ -0,0 +1,81 @@ +from pathlib import Path + +import pytest + +from functional2.testlib.fixtures.file_helper import with_files, File, CopyFile +from functional2.testlib.fixtures.nix import Nix +from functional2.testlib.utils import get_global_asset + + +use_impure_message = "is forbidden in pure eval mode (use '--impure' to override)" + + +def test_missing_impure_flag(nix: Nix): + res = nix.eval("builtins.readFile ./test_pure_eval.py").expect(1) + assert use_impure_message in res.stderr_s + + +def test_unauthorized_paths(nix: Nix): + res = nix.eval("builtins.pathExists ./test_pure_eval.py").json() + assert res is False, "Calling 'pathExists' on a non-authorised path should return false" + + +def test_builtins_time_not_available(nix: Nix): + res = nix.eval("builtins.currentTime").expect(1) + assert "error: attribute 'currentTime' missing" in res.stderr_s + + +def test_builtins_system_not_available(nix: Nix): + res = nix.eval("builtins.currentSystem").expect(1) + assert "error: attribute 'currentSystem' missing" in res.stderr_s + + +@with_files({"trivial.nix": get_global_asset("trivial.nix")}) +def test_pure_eval_simple_not_working(nix: Nix): + res = nix.nix_instantiate(["--pure-eval", "trivial.nix"]).run().expect(1) + assert use_impure_message in res.stderr_s + + +def test_readdir_not_allowed(nix: Nix): + res = nix.eval('builtins.readDir "/"').expect(1) + assert use_impure_message in res.stderr_s + + +@with_files({"test-file": File("bäh-sh")}) +def test_impure_allows_readfile(nix: Nix): + res = ( + nix.nix(["eval", "--impure", "--expr", "builtins.readFile ./test-file"], flake=True) + .run() + .ok() + ) + assert res.stdout_plain == '"bäh-sh"' + + +@pytest.fixture +def fetch_url_expr(files: Path) -> str: + return f'(import (builtins.fetchurl {{ url = "file://{files}/pure-eval.nix"; }})).x' + + +@with_files({"pure-eval.nix": CopyFile("assets/pure-eval.nix")}) +def test_impure_allows_fetchurl(nix: Nix, fetch_url_expr: str): + res = nix.nix(["eval", "--impure", "--expr", fetch_url_expr], flake=True).run().ok() + assert res.stdout_plain == "123" + + +@with_files({"pure-eval.nix": CopyFile("assets/pure-eval.nix")}) +def test_fetchurl_requires_hash(nix: Nix, fetch_url_expr: str): + res = nix.nix(["eval", "--expr", fetch_url_expr], flake=True).run().expect(1) + assert "error: in pure evaluation mode, 'fetchurl' requires a 'sha256'" in res.stderr_s + + +@with_files({"pure-eval.nix": CopyFile("assets/pure-eval.nix")}) +def test_fetchurl_available_with_hash(nix: Nix, files: Path): + expected_hash = "sha256-YXhmEC+QvjpS/+wE8kE0hqpu5w+A7jhIfqCLpRVpw8w=" + nix.eval( + f'(import (builtins.fetchurl {{ url = "file://{files}/pure-eval.nix"; sha256 = "{expected_hash}"; }})).x' + ) + + +def test_eval_no_resolve_in_pure(nix: Nix): + res = nix.eval("~/foo").expect(1) + assert "can not be resolved in pure mode" in res.stderr_plain diff --git a/tests/functional2/testlib/global_assets/trivial.nix b/tests/functional2/testlib/global_assets/trivial.nix new file mode 100644 index 000000000..42b6e1aa6 --- /dev/null +++ b/tests/functional2/testlib/global_assets/trivial.nix @@ -0,0 +1,5 @@ +{ + foo = 42; + bar = "low"; + fops = "cute"; +}