e2e: isolate every carlos subprocess from the machine's real ~/.carlos
pick() now consults .carlos/config walking up from cwd, so a subprocess running from the real checkout reads the developer's real config the moment one exists. Same scrub TestAccountsCLI already got: HOME and CARLOS_CONSOLE overridden, cmd.Dir pointed at scratch space.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KxXEWoRXU8WVTXjTJypuJ5
2 files changed,
+16
−1
auth_e2e_test.go+11 −1scopedkeys_e2e_test.go+5 −0
diff --git a/auth_e2e_test.go b/auth_e2e_test.go| index 967e34ef3..b62de7985 100644 |
| --- a/auth_e2e_test.go |
| +++ b/auth_e2e_test.go |
| @@ -48,11 +48,17 @@ func TestAuthCLI(t *testing.T) { |
| fc := newFakeConsole(t) |
| home := t.TempDir() |
| creds := filepath.Join(home, ".carlos", "credentials") |
| - env := append(os.Environ(), "CARLOS_CREDENTIALS="+creds) |
| + env := append(os.Environ(), |
| + "CARLOS_CREDENTIALS="+creds, |
| + "HOME="+home, |
| + "CARLOS_CONSOLE=", |
| + ) |
| run := func(args ...string) (string, error) { |
| cmd := exec.Command(bin, args...) |
| cmd.Env = env |
| + // pick() walks cwd ancestors for .carlos/config, so the subprocess must not run from the real checkout. |
| + cmd.Dir = home |
| out, err := cmd.CombinedOutput() |
| return string(out), err |
| } |
| @@ -116,9 +122,13 @@ func TestAccountsCreateNeedsAnOwner(t *testing.T) { |
| "CARLOS_DEPLOYMENT_DIR="+filepath.Join(tmp, "store"), |
| "CARLOS_CREDENTIALS="+filepath.Join(tmp, "credentials"), |
| "CARLOS_DATA_DIR="+tmp, |
| + "HOME="+tmp, |
| + "CARLOS_CONSOLE=", |
| ) |
| cmd := exec.Command(bin, "accounts", "create", "-name", "Orphan") |
| cmd.Env = env |
| + // pick() walks cwd ancestors for .carlos/config, so the subprocess must not run from the real checkout. |
| + cmd.Dir = tmp |
| out, err := cmd.CombinedOutput() |
| if err == nil { |
| t.Fatalf("ownerless accounts create exited 0:\n%s", out) |
diff --git a/scopedkeys_e2e_test.go b/scopedkeys_e2e_test.go| index 044b96012..bfee855fb 100644 |
| --- a/scopedkeys_e2e_test.go |
| +++ b/scopedkeys_e2e_test.go |
| @@ -18,6 +18,7 @@ import ( |
| func TestScopedKeysCLI(t *testing.T) { |
| bin := buildCarlos(t) |
| bucket := t.TempDir() |
| + scratch := t.TempDir() |
| run := func(env []string, args ...string) (string, error) { |
| t.Helper() |
| @@ -27,7 +28,11 @@ func TestScopedKeysCLI(t *testing.T) { |
| "CARLOS_DEPLOYMENT_DIR=" + bucket, |
| "CARLOS_DATA_DIR=" + t.TempDir(), |
| "CARLOS_CREDENTIALS=" + filepath.Join(t.TempDir(), "credentials"), |
| + "HOME=" + scratch, |
| + "CARLOS_CONSOLE=", |
| }, env...)...) |
| + // pick() walks cwd ancestors for .carlos/config, so the subprocess must not run from the real checkout. |
| + cmd.Dir = scratch |
| out, err := cmd.CombinedOutput() |
| return string(out), err |
| } |