tests/functional2: use bash as builder

...and add both a static bash and busybox into the sandbox for building:

    $ /nix/store/fz43jxs5qfg5vldzk38y2hmrcl58qk18-busybox-1.36.1/bin/sh -c 'declare -A foo'
    /nix/store/fz43jxs5qfg5vldzk38y2hmrcl58qk18-busybox-1.36.1/bin/sh: declare: not found

The reason is that busybox's `sh` doesn't know about `declare` which
means it cannot build derivations with `__structuredAttrs = true;`.

Change-Id: Ie3ca431f862fd3e59dc649582704ae739ee5834a
This commit is contained in:
Maximilian Bosch
2025-12-27 11:11:55 +01:00
parent fa62109164
commit 8d21057d49
7 changed files with 27 additions and 8 deletions
+1
View File
@@ -426,6 +426,7 @@ endif
sandbox_shell = get_option('sandbox-shell')
build_test_shell = get_option('build-test-shell')
build_test_env = get_option('build-test-env')
# Consider it required if we're on Linux and the user explicitly specified a non-default value.
sandbox_shell_required = sandbox_shell != 'busybox' and host_machine.system() == 'linux'
# NOTE(Qyriad): package.nix puts busybox in buildInputs for Linux.
+5 -1
View File
@@ -24,8 +24,12 @@ option('sandbox-shell', type : 'string', value : 'busybox',
description : 'path to a statically-linked shell to use as /bin/sh in sandboxes (usually busybox)',
)
option('build-test-env', type: 'string',
description : 'path to a statically-linked busybox which offers coreutils functionality'
)
option('build-test-shell', type: 'string',
description : 'path to a statically-linked shell which also offeres coreutils functionality'
description : 'path to a statically-linked bash (cannot use busybox sh because of __structuredAttrs)'
)
option('pasta-path', type : 'string', value : 'pasta',
+8 -2
View File
@@ -66,6 +66,7 @@
wrapBintoolsWith,
busybox-sandbox-shell,
bash,
pname ? "lix",
versionSuffix ? "",
@@ -296,9 +297,13 @@ stdenv.mkDerivation (finalAttrs: {
# which don't actually get added to PATH. And buildInputs is correct over
# nativeBuildInputs since this should be a busybox executable on the host.
"-Dsandbox-shell=${lib.getExe' busybox-sandbox-shell "busybox"}"
"-Dbuild-test-shell=${pkgsStatic.busybox}/bin"
"-Dbuild-test-shell=${pkgsStatic.bash}/bin"
"-Dbuild-test-env=${pkgsStatic.busybox}/bin"
"-Dpasta-path=${lib.getExe' passt-lix "pasta"}"
]
++ lib.optionals hostPlatform.isDarwin [
"-Dbuild-test-shell=${bash}/bin"
]
++ lib.optionals useLld [
"-Dc_link_args=-fuse-ld=lld"
"-Dcpp_link_args=-fuse-ld=lld"
@@ -432,7 +437,8 @@ stdenv.mkDerivation (finalAttrs: {
VERSION_SUFFIX = versionSuffix;
}
// lib.optionalAttrs hostPlatform.isLinux {
BUILD_TEST_SHELL = "${pkgsStatic.busybox}/bin";
BUILD_TEST_SHELL = "${pkgsStatic.bash}/bin";
BUILD_TEST_ENV = "${pkgsStatic.busybox}/bin";
}
// lib.optionalAttrs hostPlatform.isStatic {
NIX_CFLAGS_COMPILE = " -static";
+3
View File
@@ -18,6 +18,9 @@ functional2_env.set('NIX_BIN_DIR', fs.parent(nix.full_path()))
if build_test_shell != ''
functional2_env.set('BUILD_TEST_SHELL', build_test_shell)
endif
if build_test_env != ''
functional2_env.set('BUILD_TEST_ENV', build_test_env)
endif
functional2_env.set('system', host_system)
test(
+6 -1
View File
@@ -167,6 +167,7 @@ class ManagedEnv:
# Things fetched from the global env
build_shell = environ.get("BUILD_TEST_SHELL")
global_path = environ.get("PATH")
build_env = environ.get("BUILD_TEST_ENV")
# `NIX_BIN_DIR` either propagated from us or set by meson
# Set to the codebase internal output if started standalone
# This is where the current lix binaries are located.
@@ -176,9 +177,10 @@ class ManagedEnv:
lix_bin = Path(environ.get("NIX_BIN_DIR", lix_base_folder / "outputs/out/bin"))
self._env = {}
self.path = _ManagedPath(build_shell)
self.path = _ManagedPath(build_env)
self._tmp_path = tmp_path
self.shell_dir = build_shell or "/bin"
self.build_env = build_env
self.dirs = _Dirs(
test_root=self._get_dir(""),
@@ -193,6 +195,7 @@ class ManagedEnv:
tmpdir=self._get_dir("tmp"),
)
self.path.prepend(self.dirs.nix_bin_dir)
self.path.prepend(build_shell)
self.init_defaults(global_path)
def _get_dir(self, sub_path: str) -> Path:
@@ -210,6 +213,8 @@ class ManagedEnv:
"PAGER": "cat",
"BUILD_TEST_SHELL": self.shell_dir,
}
if self.build_env:
self._env["BUILD_TEST_ENV"] = self.build_env
if platform.system() == "Darwin":
# Darwin / Apple behaves differently and requires _NIX_TEST_NO_SANDBOX to be set for whatever reason
self._env |= {"_NIX_TEST_NO_SANDBOX": "1"}
@@ -14,7 +14,7 @@ def test_env_inits_defaults(tmp_path: Path):
assert env.get_env("GIT_CONFIG_SYSTEM") == "/dev/null"
if sys.platform != "darwin":
# Darwin doesn't like sandboxes so we don't have a sandbox shell here
assert "busybox" in env.get_env("SHELL")
assert "bash" in env.get_env("SHELL")
else:
assert "/bin/sh" in env.get_env("SHELL")
assert env.get_env("PAGER") == "cat"
@@ -134,7 +134,7 @@ def test_env_to_env(tmp_path: Path):
"PATH",
"BUILD_TEST_SHELL",
"TMPDIR",
} | ({"_NIX_TEST_NO_SANDBOX"} if sys.platform == "darwin" else set())
} | ({"_NIX_TEST_NO_SANDBOX"} if sys.platform == "darwin" else {"BUILD_TEST_ENV"})
def test_path_inits_build_shell():
+2 -2
View File
@@ -149,8 +149,8 @@ def get_global_asset(name: str) -> Fileish:
{
"system": environ.get("system"),
# Either just the build shell or entire global path if we are darwin
"path": environ.get("BUILD_TEST_SHELL") or environ.get("PATH"),
"shell": Path(environ.get("BUILD_TEST_SHELL") or "/bin") / "sh",
"path": environ.get("BUILD_TEST_ENV") or environ.get("PATH"),
"shell": Path(environ.get("BUILD_TEST_SHELL") or "/bin") / "bash",
},
)
return CopyFile(functional2_base_folder / "testlib" / "global_assets" / name)