Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

feat: Test isolation prototype — namespaces and NixOS VMs#1324

Open
garbas wants to merge 4 commits intomainfrom
feature/test-isolation
Open

feat: Test isolation prototype — namespaces and NixOS VMs#1324
garbas wants to merge 4 commits intomainfrom
feature/test-isolation

Conversation

@garbas
Copy link
Contributor

@garbas garbas commented Feb 25, 2026

Summary

Prototype and research for isolated test execution (ST-006 in the
environment health testing effort). Addresses the core problem:
concurrent test runs on shared builders fight over ports (MySQL,
Elasticsearch, Postgres) and leave orphaned services.

Three solutions documented and compared:

Solution Isolation Overhead CI changes
Linux namespaces Network+PID ~0ms Small
Nix+unshare Network+PID ~0ms None
NixOS VM tests Full kernel ~10-30s Small

Recommended: Nix+unshare as default — bake namespace
isolation into mkFloxEnvPkg in flake.nix. Zero CI changes,
Nix provides all deps and caches the derivation. Needs further
investigation for Darwin equivalent to achieve cross-platform
isolation.

What's included

  • scripts/isolated-test.sh — Standalone namespace wrapper
    (Solution 1). Usage: ./scripts/isolated-test.sh postgres --start-services
  • scripts/flake-unshare-patch.nix — Concrete flake.nix patch
    showing the Nix+unshare approach (Solution 2)
  • scripts/nix-isolation-proposal.md — Unified comparison of
    all three solutions with pros/cons and phased rollout plan
  • scripts/ISOLATION.md — Original research notes

Key findings

  • Port conflicts are hardcoded in manifest vars (Postgres 15432,
    MySQL 13306, Elasticsearch 19200)
  • unshare --net --pid --fork gives each test its own loopback
    and port space — conflicts impossible
  • PID namespace auto-kills orphaned services on test exit
  • Nix+unshare is the sweet spot: isolation baked into the cached
    Nix derivation, zero CI changes, ~0ms overhead
  • NixOS VM tests are stronger but heavier — good for phase 2
    if namespaces prove insufficient
  • Darwin isolation needs further investigation (no unshare on
    macOS, but sandbox-exec or Virtualization.framework may work)

Open questions

  • Does Darwin have an equivalent isolation mechanism?
    (sandbox-exec, Seatbelt, Virtualization.framework?)
  • Do the builders have user namespace support enabled?
    (sysctl kernel.unprivileged_userns_clone)
  • Should we apply isolation to all environments or only
    service environments?

Related

  • Effort: efforts/2026/02-environment-health-testing/ (ST-006, TH-004)
  • Forge PR: flox/forge#485

Test plan

  • ./scripts/isolated-test.sh postgres --start-services
    runs without port conflicts on Linux
  • Two concurrent postgres tests on same machine don't clash
  • Orphaned services are cleaned up after test failure
  • Non-service environments (go, python) work with isolation
  • Fallback works on systems without namespace support

Via Forge (interactive) • 97e38ba

@github-actions github-actions bot added the team-content Issues to be picked up by @flox/team-content label Feb 25, 2026
scripts/isolated-test.sh wraps environment tests in Linux
namespaces (network + PID) to prevent port conflicts and
orphaned services between concurrent test runs.

scripts/ISOLATION.md documents the approaches considered
(namespaces, systemd-nspawn, Firecracker, QEMU) and how
to integrate with the existing CI workflow.

This is a prototype — the Nix-based VM approach using NixOS
test infrastructure may be a better fit given the builders
are already Nix-capable machines.
Three approaches documented for Nix-native test isolation:

1. unshare in mkFloxEnvPkg: add util-linux/iproute2 to the
   Nix derivation, wrap flox activate with unshare --net --pid.
   Zero CI changes. Nix caches the derivation.

2. NixOS VM tests: full QEMU VMs via nixos/tests framework.
   Strongest isolation, Nix caches VM images. ~10-30s boot.

3. Hybrid (recommended): unshare for non-service envs,
   NixOS VMs for service envs (postgres, mysql, etc.),
   current approach for macOS.

Includes concrete flake.nix patch prototype showing the
minimal change for approach 1.
Renamed from "Nix-native proposal" to "Test Isolation Solutions"
covering all three approaches equally:

1. Linux namespaces (standalone wrapper) — simplest, ~0ms
   overhead, plain bash, no Nix dependency
2. Nix+unshare (flake-integrated) — same isolation, Nix
   provides deps and caches the derivation
3. NixOS VM tests — full kernel isolation via QEMU, Nix
   caches VM images, strongest but ~10-30s boot

Includes comparison table and phased recommendation.
Confirmed macOS has no equivalent to unshare --net. Darwin
kernel does not support network namespaces. sandbox-exec can
deny network but cannot isolate port spaces.

Documented three macOS mitigation options:
1. Accept no isolation (current behavior, conflicts rare)
2. Randomize ports (fragile workaround)
3. Tart VMs on Mac minis (phase 3, full isolation)

Updated recommendation: Nix+unshare for Linux (phase 1),
Tart for macOS (phase 3 when needed).
@garbas garbas force-pushed the feature/test-isolation branch from 32d297b to 6257386 Compare February 26, 2026 15:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

team-content Issues to be picked up by @flox/team-content

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant