Skip to content

Commit 09cc2ee

Browse files
davidslaterGitHub Ace
andauthored
test(cmd): make step-summary warning test hermetic (#776)
TestRunWarnsOnUnwritableStepSummary was the only test in cmd/threat-detect that reached the engine invocation without stubbing an engine on PATH, so it executed whatever real `copilot` binary the host provided. On a runner with working engine credentials (e.g. inside the AWF sandbox during the standalone smoke workflows) this starts a live agentic session that never returns, hanging the package until the 10 minute `go test` timeout and failing `make test`. Stub a fake copilot for that test, and make runWithTestArgsCapture default PATH to an empty directory when a test does not set one, so no future test can silently fall through to a real engine CLI. Co-authored-by: GitHub Ace <githubnext@users.noreply.github.com> Co-authored-by: David Slater <12449447+davidslater@users.noreply.github.com>
1 parent 0caa4f9 commit 09cc2ee

2 files changed

Lines changed: 14 additions & 0 deletions

File tree

cmd/threat-detect/logfile_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,13 +440,21 @@ func TestRunWarnsOnUnwritableStepSummary(t *testing.T) {
440440
writeMinimalArtifacts(t, artifactsDir)
441441
logPath := filepath.Join(t.TempDir(), "run.jsonl")
442442
summaryPath := filepath.Join(t.TempDir(), "missing-dir", "summary.md")
443+
// This test runs past the step-summary write into the engine invocation, so
444+
// the engine must be stubbed. Without a fake copilot on PATH the run would
445+
// execute whatever real `copilot` the host provides — which, on a runner
446+
// with working engine credentials, starts a live agentic session and hangs
447+
// until the package test timeout.
448+
sinkJSON := `{"prompt_injection":false,"secret_leak":false,"malicious_patch":false,"reasons":[]}`
449+
fakeBinDir := writeFakeCopilotWithSink(t, filepath.Join(t.TempDir(), "copilot-called"), sinkJSON, 0)
443450

444451
code, stderr := runWithTestArgsCapture(t, []string{
445452
"threat-detect",
446453
"-log-file", logPath,
447454
artifactsDir,
448455
}, map[string]string{
449456
"GITHUB_STEP_SUMMARY": summaryPath,
457+
"PATH": fakeBinDir + string(os.PathListSeparator) + os.Getenv("PATH"),
450458
})
451459

452460
if code == exitError && strings.Contains(stderr, "reason=config_error") {

cmd/threat-detect/main_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,12 @@ func runWithTestArgsCapture(t *testing.T, args []string, env map[string]string)
426426
for key, value := range env {
427427
t.Setenv(key, value)
428428
}
429+
if _, ok := env["PATH"]; !ok {
430+
// Keep the package hermetic: a test that reaches the engine without
431+
// explicitly stubbing one must not fall through to a real engine CLI on
432+
// the host PATH, which can block on network/auth until the test timeout.
433+
t.Setenv("PATH", t.TempDir())
434+
}
429435

430436
r, w, err := os.Pipe()
431437
if err != nil {

0 commit comments

Comments
 (0)