Skip to content

Commit 221a295

Browse files
committed
test: harden mainnet e2e shutdown and tune CI timeout
1 parent 4febade commit 221a295

2 files changed

Lines changed: 38 additions & 6 deletions

File tree

.github/workflows/e2e-mainnet.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ concurrency:
3333
jobs:
3434
e2e-mainnet:
3535
runs-on: ubuntu-latest
36-
timeout-minutes: 30
36+
timeout-minutes: 5
3737

3838
steps:
3939
- uses: actions/checkout@v6.0.2

neutrino_server/e2e/mainnet_test.go

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"crypto/tls"
2929
"crypto/x509"
3030
"encoding/json"
31+
"errors"
3132
"fmt"
3233
"io"
3334
"math"
@@ -164,19 +165,36 @@ func TestMainnetE2E(t *testing.T) {
164165
defer func() {
165166
t.Log("Stopping server...")
166167
if cmd.Process != nil {
167-
cmd.Process.Signal(syscall.SIGTERM)
168-
// Wait with timeout
169168
done := make(chan error, 1)
170169
go func() {
171170
done <- cmd.Wait()
172171
}()
172+
173+
if err := signalServerProcessGroup(cmd, syscall.SIGTERM); err != nil {
174+
t.Logf("Failed to send SIGTERM: %v", err)
175+
}
176+
173177
select {
174-
case <-done:
178+
case err := <-done:
179+
if err != nil {
180+
t.Logf("Server exited with error: %v", err)
181+
}
175182
t.Log("Server stopped gracefully")
176183
case <-time.After(5 * time.Second):
177184
t.Log("Server did not stop gracefully, killing...")
178-
cmd.Process.Kill()
179-
cmd.Wait()
185+
if err := signalServerProcessGroup(cmd, syscall.SIGKILL); err != nil {
186+
t.Logf("Failed to send SIGKILL: %v", err)
187+
return
188+
}
189+
190+
select {
191+
case err := <-done:
192+
if err != nil {
193+
t.Logf("Server exited with error after SIGKILL: %v", err)
194+
}
195+
case <-time.After(5 * time.Second):
196+
t.Log("Server did not exit within 5s after SIGKILL")
197+
}
180198
}
181199
}
182200
}()
@@ -297,6 +315,7 @@ func startServer(ctx context.Context, t *testing.T, binaryPath, dataDir, listenA
297315
// Redirect output to test logs
298316
cmd.Stdout = &testLogWriter{t: t, prefix: "[SERVER] "}
299317
cmd.Stderr = &testLogWriter{t: t, prefix: "[SERVER] "}
318+
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
300319

301320
if err := cmd.Start(); err != nil {
302321
t.Fatalf("Failed to start server: %v", err)
@@ -306,6 +325,19 @@ func startServer(ctx context.Context, t *testing.T, binaryPath, dataDir, listenA
306325
return cmd
307326
}
308327

328+
func signalServerProcessGroup(cmd *exec.Cmd, sig syscall.Signal) error {
329+
if cmd == nil || cmd.Process == nil {
330+
return nil
331+
}
332+
333+
// Signal the entire process group so any child processes do not outlive the parent.
334+
if err := syscall.Kill(-cmd.Process.Pid, sig); err == nil || errors.Is(err, syscall.ESRCH) {
335+
return nil
336+
}
337+
338+
return cmd.Process.Signal(sig)
339+
}
340+
309341
// testLogWriter writes to test logs with a prefix
310342
type testLogWriter struct {
311343
t *testing.T

0 commit comments

Comments
 (0)