carlos / platform Public

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
Paul Campbell 4686aa6de04630b16d6ff144261b0c3633946ba7 parent 2834e62
2 files changed, +16 −1
  • auth_e2e_test.go +11 −1
  • scopedkeys_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
}