From 2151ee2fcb1d22b0b86c7a97a619be4e661283c9 Mon Sep 17 00:00:00 2001 From: Dom Rodriguez Date: Mon, 28 Sep 2026 00:05:32 +0100 Subject: [PATCH] buildstream: run the pytest suite as a NixOS VM test buildbox-casd finds `buildbox-fuse` on PATH and defaults to real FUSE-based staging, which needs `/dev/fuse` and a working mount path that the Nix build sandbox doesn't provide, hence the `BUILDBOX_STAGER=copy-or-link` workaround forcing the hardlink/copy fallback stager, and the `/usr/bin/env sh` shebang patch for the dummy buildbox-casd scripts in tests/internals/cascache.py. Add nixosTests.buildstream and point passthru.tests.pytest at it instead: so the suite exercises the actual FUSE-backed staging path. The main derivation no longer builds the pytest/test-fixture inputs at all (they're only needed by the VM test), keeping just `versionCheckHook` for the existing install-check. `bst` is a buildPythonApplication, so its own site-packages only contains buildstream's own files, not the propagated runtime deps (protobuf, grpcio, click, ...) that only reach the wrapped `bst` script's own PYTHONPATH; `toPythonModule` reinterprets it as a regular library so `withPackages` pulls in its full dependency closure for `pytest` to import from. The default `diskSize = "auto"` only sizes the VM's root filesystem to fit the system closure, with no scratch space; the suite builds real CAS/cache artifacts under pytest's basetemp for hundreds of parametrized cases, easily exceeding that. Bumped disk/memory sizing to comfortably cover a full run. Verified this run passes: `nix-build -E 'let pkgs = import ./. {}; in pkgs.nixosTests.buildstream.test'` completes successfully. Assisted-by: Claude --- nixos/tests/all-tests.nix | 1 + nixos/tests/buildstream.nix | 71 +++++++++++++++++++++++++ pkgs/by-name/bu/buildstream/package.nix | 52 +++++------------- 3 files changed, 84 insertions(+), 40 deletions(-) create mode 100644 nixos/tests/buildstream.nix diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index a446bad2b517..4b155895d172 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -380,6 +380,7 @@ in budgie = runTest ./budgie.nix; buildbot = runTest ./buildbot.nix; buildkite-agents = runTest ./buildkite-agents.nix; + buildstream = runTest ./buildstream.nix; bulwark = runTest ./bulwark.nix; c2fmzq = runTest ./c2fmzq.nix; caddy = runTest ./caddy.nix; diff --git a/nixos/tests/buildstream.nix b/nixos/tests/buildstream.nix new file mode 100644 index 000000000000..dc09fc58a6fc --- /dev/null +++ b/nixos/tests/buildstream.nix @@ -0,0 +1,71 @@ +{ pkgs, ... }: +let + bst = pkgs.buildstream; + + # `bst` is a buildPythonApplication; its own site-packages only contains + # buildstream's own files, not the propagated runtime deps (protobuf, + # grpcio, click, ...) that only reach the wrapped `bst` script's PYTHONPATH. + # `toPythonModule` reinterprets it as a regular library so its full + # dependency closure gets merged in by `withPackages` below. + bstModule = pkgs.python3.pkgs.toPythonModule bst; + + # Test fixture plugin package used by test_source_mirror_plugin[pip]; upstream + # normally installs this via tox before running the pip-origin plugin loading test. + samplePlugins = pkgs.python3Packages.buildPythonPackage { + pname = "sample-plugins"; + version = "1.2.3"; + pyproject = true; + build-system = [ pkgs.python3Packages.setuptools ]; + src = "${bst.src}/tests/plugins/sample-plugins"; + dontCheck = true; + }; +in +{ + name = "buildstream"; + + meta.maintainers = with pkgs.lib.maintainers; [ shymega ]; + + nodes.machine = + { pkgs, ... }: + { + # The default "auto" diskSize only sizes the root filesystem to fit + # the system closure, with no scratch space; the suite builds real + # CAS/cache artifacts under pytest's basetemp (`./tmp`, per + # setup.cfg) for hundreds of parametrized cases, which exhausts that + # in a few minutes (`OSError: could not create numbered dir`). + virtualisation.diskSize = 16 * 1024; + virtualisation.memorySize = 2048; + + environment.systemPackages = [ + (pkgs.python3.withPackages ( + ps: with ps; [ + bstModule + pexpect + pyftpdlib + pytest + pytest-datafiles + pytest-env + pytest-timeout + pytest-xdist + samplePlugins + ] + )) + bst + pkgs.buildbox + pkgs.gitMinimal + ]; + }; + + testScript = '' + machine.succeed("cp -r ${bst.src} /tmp/src && chmod -R u+w /tmp/src") + + # The dummy buildbox-casd scripts spawned by tests/internals/cascache.py use + # an `/usr/bin/env sh` shebang, which doesn't exist here either. + machine.succeed( + "sed -i 's|#!/usr/bin/env sh|#!${pkgs.runtimeShell}|'" + + " /tmp/src/tests/internals/cascache.py" + ) + + machine.succeed("cd /tmp/src && HOME=/root pytest") + ''; +} diff --git a/pkgs/by-name/bu/buildstream/package.nix b/pkgs/by-name/bu/buildstream/package.nix index 16cd4db146ff..a2d31205ff48 100644 --- a/pkgs/by-name/bu/buildstream/package.nix +++ b/pkgs/by-name/bu/buildstream/package.nix @@ -3,7 +3,7 @@ python3Packages, fetchFromGitHub, gitUpdater, - runtimeShell, + nixosTests, # buildInputs buildbox, @@ -15,8 +15,6 @@ installShellFiles, # tests - addBinToPathHook, - gitMinimal, versionCheckHook, # Optional features @@ -73,46 +71,16 @@ python3Packages.buildPythonApplication (finalAttrs: { patch ]; - # The dummy buildbox-casd scripts spawned by tests/internals/cascache.py use - # an `/usr/bin/env sh` shebang, which doesn't exist in the Nix build sandbox. - postPatch = '' - substituteInPlace tests/internals/cascache.py \ - --replace-fail '#!/usr/bin/env sh' '#!${runtimeShell}' - ''; - # /dev/fuse is not available inside the Nix build sandbox, so buildbox-casd's - # default FUSE-based staging strategy cannot work here. Force the hardlink/copy - # stager instead (this is a real, supported buildbox-casd staging mode, not a - # workaround: https://gitlab.com/BuildGrid/buildbox/buildbox/-/blob/main/casd/buildboxcasd_server.cpp). - preCheck = '' - export BUILDBOX_STAGER=copy-or-link - ''; - + # default FUSE-based staging strategy cannot work here, and the shebang used + # by tests/internals/cascache.py's dummy buildbox-casd scripts + # (`/usr/bin/env sh`) doesn't exist there either. The pytest suite is run as + # a NixOS VM test instead, where both of those are available; see + # `passthru.tests.pytest`. pythonImportsCheck = [ "buildstream" ]; nativeCheckInputs = [ - addBinToPathHook - buildbox - gitMinimal - python3Packages.pexpect - python3Packages.pyftpdlib - python3Packages.pytest-datafiles - python3Packages.pytest-env - python3Packages.pytest-timeout - python3Packages.pytest-xdist - python3Packages.pytestCheckHook versionCheckHook - - # Test fixture plugin package used by test_source_mirror_plugin[pip]; upstream - # normally installs this via tox before running the pip-origin plugin loading test. - (python3Packages.buildPythonPackage { - pname = "sample-plugins"; - version = "1.2.3"; - pyproject = true; - build-system = [ python3Packages.setuptools ]; - src = "${finalAttrs.src}/tests/plugins/sample-plugins"; - dontCheck = true; - }) ]; postInstall = '' @@ -123,8 +91,12 @@ python3Packages.buildPythonApplication (finalAttrs: { versionCheckProgram = "${placeholder "out"}/bin/bst"; - passthru.updateScript = gitUpdater { - ignoredVersions = "dev"; + passthru = { + updateScript = gitUpdater { + ignoredVersions = "dev"; + }; + + tests.pytest = nixosTests.buildstream; }; meta = {