diff --git a/go/cmd/compass-stack/collector_podman_test.go b/go/cmd/compass-stack/collector_podman_test.go index 0a070620..188fb1f6 100644 --- a/go/cmd/compass-stack/collector_podman_test.go +++ b/go/cmd/compass-stack/collector_podman_test.go @@ -66,7 +66,7 @@ func TestCollectorUpDown(t *testing.T) { binDir := buildBinariesFromModuleRoot(t) stackBin := buildStackBinary(t, binDir) - env := stackEnv(binDir) + env := stackEnv(t, binDir) fx := newContainerFixture(t, shortRoot(t, "-col")) cfg := fx.cfg @@ -143,7 +143,7 @@ func TestExternalOTLPUpDown(t *testing.T) { binDir := buildBinariesFromModuleRoot(t) stackBin := buildStackBinary(t, binDir) - env := stackEnv(binDir) + env := stackEnv(t, binDir) fx := newContainerFixture(t, shortRoot(t, "-extotel")) cfg := fx.cfg diff --git a/go/cmd/compass-stack/container_postgres_podman_test.go b/go/cmd/compass-stack/container_postgres_podman_test.go index a54e023c..cf184814 100644 --- a/go/cmd/compass-stack/container_postgres_podman_test.go +++ b/go/cmd/compass-stack/container_postgres_podman_test.go @@ -71,7 +71,7 @@ func TestContainerPostgresUpDown(t *testing.T) { binDir := buildBinariesFromModuleRoot(t) stackBin := buildStackBinary(t, binDir) - env := stackEnv(binDir) + env := stackEnv(t, binDir) fx := newContainerFixture(t, shortRoot(t, "-ctr")) cfg := fx.cfg @@ -144,7 +144,7 @@ func TestExternalDatabaseUpDown(t *testing.T) { binDir := buildBinariesFromModuleRoot(t) stackBin := buildStackBinary(t, binDir) - env := stackEnv(binDir) + env := stackEnv(t, binDir) // The "external" postgres: a throwaway TCP-published container the test owns. externalDSN := startExternalPostgres(t) @@ -238,6 +238,7 @@ func (c containerCfg) args(sub string, extra ...string) []string { // lives under one unique per-pid dir. func newContainerFixture(t *testing.T, root string) containerFixture { t.Helper() + seedMasterKeyProvider(t) pgSockDir := filepath.Join(root, "pgsock") runtimeDir := filepath.Join(root, "rt") serverSock := filepath.Join(root, "s.sock") diff --git a/go/cmd/compass-stack/cross_process_podman_test.go b/go/cmd/compass-stack/cross_process_podman_test.go index 15d0bb9f..435de4cc 100644 --- a/go/cmd/compass-stack/cross_process_podman_test.go +++ b/go/cmd/compass-stack/cross_process_podman_test.go @@ -118,15 +118,13 @@ func TestCrossProcessTeardown(t *testing.T) { if !podmanUsable() { t.Skip("rootless podman not usable in this environment") } - ctx := context.Background() // test root context (rule://go-thread-context exemption for a _test.go root) - // 1. Build the three stack child binaries AND the compass-stack binary itself // into one dir. The subprocesses resolve the children via exec.LookPath, so // the dir must be first on their PATH; compass-stack is invoked by full path. binDir := buildBinariesFromModuleRoot(t) stackBin := buildStackBinary(t, binDir) - env := stackEnv(binDir) + env := stackEnv(t, binDir) // A short-path, free-port config resolved through the SAME resolveConfig the // CLI uses (no duplicated config logic); the fixture's derived socket paths @@ -282,8 +280,13 @@ func buildStackBinary(t *testing.T, binDir string) string { // compass-stack subprocess resolves the compass-postgres/-server/-runner // children (looked up by bare name via exec.LookPath) to the freshly built // binaries. PATH is rebuilt (not merely re-appended) so there is exactly one -// PATH entry and binDir is unambiguously first. -func stackEnv(binDir string) []string { +// PATH entry and binDir is unambiguously first. It also seeds the master-key +// provider before snapshotting, so the subprocess inherits it. +func stackEnv(t *testing.T, binDir string) []string { + t.Helper() + // Seeded here, not left to the caller: this snapshots the environment, so a + // provider exported afterwards would never reach the subprocess. + seedMasterKeyProvider(t) base := os.Environ() out := make([]string, 0, len(base)+1) oldPath := "" diff --git a/go/cmd/compass-stack/integration_podman_test.go b/go/cmd/compass-stack/integration_podman_test.go index 42155dec..fcfe5188 100644 --- a/go/cmd/compass-stack/integration_podman_test.go +++ b/go/cmd/compass-stack/integration_podman_test.go @@ -61,6 +61,23 @@ import ( "github.com/RigelBuild/compass/go/internal/stack" ) +// stackMasterKey is a throwaway key for tests that boot compass-server, which +// fails closed without an at-rest key; boot decoding requires exactly 64 hex chars. +const stackMasterKey = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef" + +// seedMasterKeyProvider rides the test environment because a spawned +// compass-server inherits it, and compass-stack exposes no --secret-provider flag +// to pass one through. Unconditional: honoring an ambient provider would put the +// outcome back at the mercy of the developer's shell. +func seedMasterKeyProvider(t *testing.T) { + t.Helper() + secretsPath := filepath.Join(t.TempDir(), "secrets.env") + if err := os.WriteFile(secretsPath, []byte("COMPASS_MASTER_KEY="+stackMasterKey+"\n"), 0o600); err != nil { + t.Fatalf("write secrets file: %v", err) + } + t.Setenv("COMPASS_SECRET_PROVIDER", "dotenv://"+secretsPath) +} + // agentImage is a small, pullable public image standing in for the agent image: // the stack pulls it and hands it to the runner, but never runs it as a // container at up (see the file header). Same image the runtime lifecycle test @@ -146,7 +163,7 @@ type stackFixture struct { // t.TempDir — only the socket/runtime paths are budget-constrained. func newFixture(t *testing.T, shortRoot string) (stackFixture, stack.Deps) { t.Helper() - + seedMasterKeyProvider(t) pgSockDir := filepath.Join(shortRoot, "pg") runtimeDir := filepath.Join(shortRoot, "rt") serverSock := filepath.Join(shortRoot, "s.sock") diff --git a/go/cmd/compass-stack/nats_podman_test.go b/go/cmd/compass-stack/nats_podman_test.go index 4850461b..83e8a2da 100644 --- a/go/cmd/compass-stack/nats_podman_test.go +++ b/go/cmd/compass-stack/nats_podman_test.go @@ -60,7 +60,7 @@ func TestNatsUpDown(t *testing.T) { binDir := buildBinariesFromModuleRoot(t) stackBin := buildStackBinary(t, binDir) - env := stackEnv(binDir) + env := stackEnv(t, binDir) fx := newContainerFixture(t, shortRoot(t, "-nats")) cfg := fx.cfg @@ -134,7 +134,7 @@ func TestExternalNatsUpDown(t *testing.T) { binDir := buildBinariesFromModuleRoot(t) stackBin := buildStackBinary(t, binDir) - env := stackEnv(binDir) + env := stackEnv(t, binDir) fx := newContainerFixture(t, shortRoot(t, "-extnats")) cfg := fx.cfg