- Activate / Deactivate via flox activate --detach (with graceful SIGTERM→SIGKILL) - Non-privileged IsAlive process check with Linux /proc fallback - Dev-mode stub when flox is missing or FLOXENV_DEV_MODE=1 - Unit and integration tests Closes #16
70 lines
1.8 KiB
Go
70 lines
1.8 KiB
Go
//go:build integration
|
|
|
|
package floxenv
|
|
|
|
import (
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// TestIntegration_ActivateDeactivate exercises the real flox binary if present.
|
|
// Run with: go test -tags=integration ./pkg/floxenv
|
|
func TestIntegration_ActivateDeactivate(t *testing.T) {
|
|
if _, err := exec.LookPath(defaultFloxPath); err != nil {
|
|
t.Skip("flox not installed; skipping integration test")
|
|
}
|
|
|
|
// Verify that the installed flox supports --detach.
|
|
if out, err := exec.Command(defaultFloxPath, "activate", "--help").Output(); err == nil {
|
|
if !strings.Contains(string(out), "detach") {
|
|
t.Skip("installed flox does not support --detach; skipping integration test")
|
|
}
|
|
} else {
|
|
t.Skipf("unable to query flox activate help: %v", err)
|
|
}
|
|
|
|
tmpDir := t.TempDir()
|
|
manifest := filepath.Join(tmpDir, "flox.nix")
|
|
if err := os.WriteFile(manifest, []byte(`{
|
|
description = "test env";
|
|
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
|
outputs = { self, nixpkgs }: {};
|
|
}`), 0600); err != nil {
|
|
t.Fatalf("write manifest: %v", err)
|
|
}
|
|
|
|
r := NewRegistry()
|
|
envID, pid, err := r.Activate(manifest)
|
|
if err != nil {
|
|
t.Fatalf("activate failed: %v", err)
|
|
}
|
|
|
|
if !IsAlive(pid) {
|
|
t.Fatalf("expected pid %d to be alive after activation", pid)
|
|
}
|
|
|
|
// Ensure we clean up even if the test panics.
|
|
t.Cleanup(func() {
|
|
_ = r.Deactivate(envID, pid)
|
|
})
|
|
|
|
// Give flox a moment to fully initialise detached state.
|
|
time.Sleep(500 * time.Millisecond)
|
|
|
|
if err := r.Deactivate(envID, pid); err != nil {
|
|
t.Fatalf("deactivate failed: %v", err)
|
|
}
|
|
|
|
// Polling isAlive because flox may take a moment to tear down.
|
|
for i := 0; i < 30; i++ {
|
|
if !IsAlive(pid) {
|
|
return
|
|
}
|
|
time.Sleep(100 * time.Millisecond)
|
|
}
|
|
t.Fatalf("expected pid %d to be dead after deactivate, but it is still alive", pid)
|
|
}
|