@@ -31,7 +31,7 @@ func TestRunCommand_ConfigValidation(t *testing.T) {
3131 for _ , tt := range tests {
3232 t .Run (tt .name , func (t * testing.T ) {
3333 var stdoutBuf , stderrBuf bytes.Buffer
34- exitCode := runCLICommand (t , tt .args , & stdoutBuf , & stderrBuf , 5 * time .Second )
34+ exitCode := runCLICommand (tt .args , & stdoutBuf , & stderrBuf , 5 * time .Second )
3535 output := stdoutBuf .String () + stderrBuf .String ()
3636
3737 if exitCode != tt .expectedExit {
@@ -69,12 +69,20 @@ func TestRunCommand_Foreground(t *testing.T) {
6969 t .Fatalf ("Failed to create test config file: %v" , err )
7070 }
7171
72- ctx , cancel := context .WithTimeout (t .Context (), 3 * time .Second )
72+ ctx , cancel := context .WithTimeout (t .Context (), 2 * time .Second )
7373 defer cancel ()
7474
7575 cmd := exec .CommandContext (ctx , "go" , "run" , "." )
7676 cmd .Args = append (cmd .Args , []string {"run" , "-config" , configFile }... )
7777
78+ // Set process group to ensure we can kill child processes
79+ // Running test creates a chain of processes:
80+ // 1. go run . (parent)
81+ // 2. The compiled meeseeks binary (child)
82+ // 3. Potentially other child processes started by meeseeks
83+ // By using syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL), we kill the entire process group
84+ cmd .SysProcAttr = & syscall.SysProcAttr {Setpgid : true }
85+
7886 // Use pipes instead of bytes.Buffer to avoid deadlock.
7987 // When using bytes.Buffer directly with cmd.Stdout/Stderr, the process can block
8088 // writing to the buffer if nothing is reading from it. This causes the test to hang
@@ -112,13 +120,21 @@ func TestRunCommand_Foreground(t *testing.T) {
112120 stderr .ReadFrom (stderrPipe )
113121 }()
114122
115- // Send SIGTERM after a short delay to gracefully stop the daemon
116- go func () {
117- time .Sleep (500 * time .Millisecond )
123+ // Send SIGTERM after allowing time for startup message
124+ terminateProcess := func () {
125+ time .Sleep (1 * time .Second ) // Give more time for startup
118126 if cmd .Process != nil {
119- cmd .Process .Signal (syscall .SIGTERM )
127+ // First try SIGTERM to the process group
128+ syscall .Kill (- cmd .Process .Pid , syscall .SIGTERM )
129+
130+ // Give it time to exit gracefully, then force kill the process group
131+ time .Sleep (300 * time .Millisecond )
132+ if cmd .Process != nil {
133+ syscall .Kill (- cmd .Process .Pid , syscall .SIGKILL )
134+ }
120135 }
121- }()
136+ }
137+ go terminateProcess ()
122138
123139 err = cmd .Wait ()
124140
@@ -129,7 +145,7 @@ func TestRunCommand_Foreground(t *testing.T) {
129145 if err != nil && ! strings .Contains (err .Error (), "signal" ) &&
130146 ! strings .Contains (err .Error (), "interrupt" ) &&
131147 ! strings .Contains (err .Error (), "context deadline" ) {
132- t .Fatalf ("Unexpected error (ignoring interrupt/timeout): %v" , err )
148+ t .Fatalf ("Unexpected error (ignoring interrupt/timeout/killed ): %v" , err )
133149 }
134150
135151 output := stdout .String () + stderr .String ()
@@ -161,7 +177,6 @@ func TestRunCommand_Detached(t *testing.T) {
161177
162178 var stdout , stderr bytes.Buffer
163179 exitCode := runCLICommand (
164- t ,
165180 []string {"run" , "-d" , "-config" , configFile },
166181 & stdout ,
167182 & stderr ,
@@ -194,7 +209,6 @@ func TestRunCommand_Detached(t *testing.T) {
194209
195210 var stdoutBuf , stderrBuf bytes.Buffer
196211 exitCode = runCLICommand (
197- t ,
198212 []string {"status" },
199213 & stdoutBuf ,
200214 & stderrBuf ,
@@ -209,7 +223,7 @@ func TestRunCommand_Detached(t *testing.T) {
209223 t .Fatalf ("Status command could not connect to daemon: %q" , statusOutput )
210224 }
211225
212- exitCode = runCLICommand (t , []string {"exit" }, nil , nil , 5 * time .Second )
226+ exitCode = runCLICommand ([]string {"exit" }, nil , nil , 5 * time .Second )
213227 if exitCode != 0 {
214228 t .Fatalf ("Expected exit code %d, got %d" , 0 , exitCode )
215229 }
@@ -224,7 +238,6 @@ func TestRunCommand_Detached(t *testing.T) {
224238
225239 var stdoutBuf2 , stderrBuf2 bytes.Buffer
226240 exitCode = runCLICommand (
227- t ,
228241 []string {"status" },
229242 & stdoutBuf2 ,
230243 & stderrBuf2 ,
0 commit comments