package dockerexec import ( "context" "os" "path/filepath" "regexp" "strconv" "strings" "testing" ) // TestR650_RealDockerIsRefusedUnderGoTest is the decoy: a harmless-looking `docker ps` with the // real PATH must NOT run. The consequence asserted is that Run returns the refusal, naming the // command — and that nothing was started (ProcessState stays nil). func TestR650_RealDockerIsRefusedUnderGoTest(t *testing.T) { t.Setenv(OptInEnv, "") for _, name := range []string{"docker", "docker-compose", "/usr/bin/docker"} { cmd := Command(name, "ps", "-a") err := cmd.Run() if err == nil || !strings.Contains(err.Error(), "R-650") || !strings.Contains(err.Error(), "ps -a") { t.Fatalf("%s: want an R-650 refusal naming the command, got %v", name, err) } if cmd.ProcessState != nil { t.Fatalf("%s: a process was started", name) } c2 := CommandContext(context.Background(), name, "volume", "create", "r650-decoy") if _, err := c2.CombinedOutput(); err == nil || !strings.Contains(err.Error(), "volume create r650-decoy") { t.Fatalf("%s: CommandContext not refused: %v", name, err) } } } // TestR650_StubOnPathIsAllowed — a test's own fake in t.TempDir() is a seam, not Docker. func TestR650_StubOnPathIsAllowed(t *testing.T) { bin := t.TempDir() if err := os.WriteFile(filepath.Join(bin, "docker"), []byte("#!/bin/sh\necho stub:$*\n"), 0o755); err != nil { t.Fatal(err) } t.Setenv("PATH", bin) out, err := Command("docker", "ps").CombinedOutput() if err != nil || strings.TrimSpace(string(out)) != "stub:ps" { t.Fatalf("stub should run: out=%q err=%v", out, err) } } // TestR650_OptInAndProductionAndNonDockerPassThrough — the guard refuses nothing else. func TestR650_OptInAndProductionAndNonDockerPassThrough(t *testing.T) { t.Setenv(OptInEnv, "1") if err := refusal("docker", []string{"ps"}); err != nil { t.Fatalf("opt-in must allow: %v", err) } t.Setenv(OptInEnv, "") if err := refusal("du", []string{"-sb", "/"}); err != nil { t.Fatalf("a non-docker command must pass: %v", err) } old := underTest underTest = func() bool { return false } defer func() { underTest = old }() if err := refusal("docker", []string{"ps"}); err != nil { t.Fatalf("the production binary must never refuse: %v", err) } if Command("docker", "ps").Err != nil { t.Fatal("production Command carried an error") } } // TestR650_NoBareDockerExec pins the invariant the package doc states: every production path that // builds a docker process goes through this package. A new `exec.Command("docker", …)` in // non-test code fails here, naming the file and line. func TestR650_NoBareDockerExec(t *testing.T) { root := filepath.Join("..", "..") bare := regexp.MustCompile(`\bexec\.Command(Context)?\(([^,()]+, )?"docker`) var hits []string n := 0 err := filepath.Walk(root, func(p string, info os.FileInfo, err error) error { if err != nil { return err } if info.IsDir() || !strings.HasSuffix(p, ".go") || strings.HasSuffix(p, "_test.go") { return nil } b, err := os.ReadFile(p) if err != nil { return err } n++ for i, line := range strings.Split(string(b), "\n") { if bare.MatchString(line) { hits = append(hits, p+":"+strconv.Itoa(i+1)+": "+strings.TrimSpace(line)) } } return nil }) if err != nil { t.Fatal(err) } if n < 100 { t.Fatalf("scope: only %d Go files walked — the sweep is not looking at the tree", n) } if len(hits) > 0 { t.Fatalf("bare docker exec outside dockerexec (R-650):\n%s", strings.Join(hits, "\n")) } }