Skip to content

Commit 675fc3e

Browse files
author
Piotr
committed
stding test fixes
1 parent d05ae20 commit 675fc3e

File tree

1 file changed

+47
-12
lines changed

1 file changed

+47
-12
lines changed

tests/stdin_test.go

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"io"
66
"os/exec"
77
"strings"
8+
"syscall"
89
"testing"
910
"time"
1011

@@ -16,6 +17,9 @@ func runCmd(cmds []string, t *testing.T) {
1617
// -t enables fallthrough so we can see the output
1718
cmd := exec.Command("go", cmds...)
1819

20+
// Set process group for clean shutdown
21+
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
22+
1923
// Get stdin pipe
2024
stdin, err := cmd.StdinPipe()
2125
assert.NoError(t, err)
@@ -30,6 +34,7 @@ func runCmd(cmds []string, t *testing.T) {
3034

3135
// Create a channel to collect output lines
3236
outputChan := make(chan string)
37+
done := make(chan bool)
3338

3439
// Start goroutine to read stdout
3540
go func() {
@@ -41,7 +46,10 @@ func runCmd(cmds []string, t *testing.T) {
4146
return
4247
}
4348
if err != nil {
44-
t.Errorf("Error reading stdout: %v", err)
49+
// Ignore pipe errors since we're killing the process
50+
if !strings.Contains(err.Error(), "pipe") {
51+
t.Errorf("Error reading stdout: %v", err)
52+
}
4553
close(outputChan)
4654
return
4755
}
@@ -67,25 +75,52 @@ func runCmd(cmds []string, t *testing.T) {
6775
assert.NoError(t, err)
6876
}
6977

78+
// Close stdin to signal we're done writing
79+
stdin.Close()
80+
7081
// Collect output with timeout
7182
receivedLines := make([]string, 0)
7283
timeout := time.After(5 * time.Second)
7384

74-
for i := 0; i < len(testLines); i++ {
75-
select {
76-
case line, ok := <-outputChan:
77-
if !ok {
78-
t.Fatal("Output channel closed before receiving all expected lines")
85+
go func() {
86+
for i := 0; i < len(testLines); i++ {
87+
select {
88+
case line, ok := <-outputChan:
89+
if !ok {
90+
return
91+
}
92+
receivedLines = append(receivedLines, line)
93+
if len(receivedLines) == len(testLines) {
94+
done <- true
95+
return
96+
}
97+
case <-timeout:
98+
done <- true
99+
return
79100
}
80-
receivedLines = append(receivedLines, line)
81-
case <-timeout:
82-
t.Fatal("Timeout waiting for output")
83101
}
102+
}()
103+
104+
<-done
105+
106+
// Kill the process group to ensure clean shutdown
107+
pgid, err := syscall.Getpgid(cmd.Process.Pid)
108+
if err == nil {
109+
syscall.Kill(-pgid, syscall.SIGTERM)
84110
}
85111

86-
// Kill the process since we're done testing
87-
if err := cmd.Process.Kill(); err != nil {
88-
t.Errorf("Failed to kill process: %v", err)
112+
// Wait with timeout to avoid hanging
113+
waitChan := make(chan error)
114+
go func() {
115+
waitChan <- cmd.Wait()
116+
}()
117+
118+
select {
119+
case <-waitChan:
120+
// Process exited
121+
case <-time.After(2 * time.Second):
122+
// Force kill if it didn't exit cleanly
123+
cmd.Process.Kill()
89124
}
90125

91126
// Verify output matches input

0 commit comments

Comments
 (0)