Skip to content

Commit 42cd006

Browse files
F1bonacc1claude
andcommitted
test: poll log file for shutdown order to tolerate stdout drain lag
ShutDownProject returns once child processes have exited, but each process's stdout-reader goroutine is abandoned during shutdown (process.go waitForStdOutErr → procRunCtx.Done) and may still be flushing the bash trap output to the project log file. Reading the file once after ShutDownProject is a race: on Linux the flush usually beats the test; on macOS CI it doesn't, leaving the file empty and failing the assertion. Poll the file with a 5s deadline instead, breaking out as soon as the expected exit order materializes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent ae47b07 commit 42cd006

1 file changed

Lines changed: 26 additions & 8 deletions

File tree

src/app/system_test.go

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -559,17 +559,35 @@ func TestSystem_TestProcListShutsDownInOrder(t *testing.T) {
559559
t.Errorf("runningProcesses = %d, want %d", runningProcesses, want)
560560
}
561561
//read file and validate the shutdown order
562-
scanner := bufio.NewScanner(file)
563-
order := make([]string, 0)
564-
for scanner.Scan() {
565-
line := scanner.Text()
566-
if strings.Contains(line, "exit") {
567-
order = append(order, line)
568-
}
569-
}
570562
//the order if first D or C exits is not defined
571563
wantOrder1 := []string{"B: exit", "D: exit", "C: exit", "A: exit"}
572564
wantOrder2 := []string{"B: exit", "C: exit", "D: exit", "A: exit"}
565+
566+
// ShutDownProject waits for processes to exit, but each process's
567+
// stdout-reader goroutine is abandoned at shutdown (process.go:233) and
568+
// may still be flushing the trap output to the log file. Poll for the
569+
// expected content instead of reading once — on slower runners (macOS CI)
570+
// the flush can lag behind ShutDownProject's return.
571+
var order []string
572+
deadline := time.Now().Add(5 * time.Second)
573+
for time.Now().Before(deadline) {
574+
if _, err := file.Seek(0, 0); err != nil {
575+
t.Error(err.Error())
576+
return
577+
}
578+
order = order[:0]
579+
scanner := bufio.NewScanner(file)
580+
for scanner.Scan() {
581+
line := scanner.Text()
582+
if strings.Contains(line, "exit") {
583+
order = append(order, line)
584+
}
585+
}
586+
if slices.Equal(order, wantOrder1) || slices.Equal(order, wantOrder2) {
587+
break
588+
}
589+
time.Sleep(50 * time.Millisecond)
590+
}
573591
if !slices.Equal(order, wantOrder1) && !slices.Equal(order, wantOrder2) {
574592
t.Errorf("content = %v, want %v or %v", order, wantOrder1, wantOrder2)
575593
return

0 commit comments

Comments
 (0)