mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-02 11:07:10 +00:00
fix(testrun): stop the sidecar with SIGTERM before killing
This commit is contained in:
1 parent
fc822ee359
commit
132b05c2fd
1 file changed
+41
-5
@@ -8,6 +8,8 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/priyanshujain/sanderling/internal/android"
|
||||
"github.com/priyanshujain/sanderling/internal/driver"
|
||||
@@ -53,6 +55,13 @@ func buildDriver(ctx context.Context, options Options, stdout io.Writer) (driver
|
||||
sidecarCommand.Stdout = stdout
|
||||
sidecarCommand.Stderr = stdout
|
||||
sidecarCommand.Env = android.EnvWithAndroidPlatformTools(os.Environ())
|
||||
// SIGTERM lets the sidecar's shutdown hook stop the iOS XCTest runner.
|
||||
// SIGKILL skips the hook and orphans an xcodebuild session that later
|
||||
// restarts its runner and hijacks the simulator mid-run.
|
||||
sidecarCommand.Cancel = func() error {
|
||||
return sidecarCommand.Process.Signal(syscall.SIGTERM)
|
||||
}
|
||||
sidecarCommand.WaitDelay = sidecarShutdownGrace
|
||||
if err := sidecarCommand.Start(); err != nil {
|
||||
return nil, nil, fmt.Errorf("spawn sidecar: %w", err)
|
||||
}
|
||||
@@ -60,7 +69,7 @@ func buildDriver(ctx context.Context, options Options, stdout io.Writer) (driver
|
||||
|
||||
driverClient, err := driverSidecar.Dial(fmt.Sprintf("127.0.0.1:%d", sidecarPort))
|
||||
if err != nil {
|
||||
_ = sidecarCommand.Process.Kill()
|
||||
stopSidecar(sidecarCommand)
|
||||
return nil, nil, fmt.Errorf("dial sidecar: %w", err)
|
||||
}
|
||||
driverClient.SetPlatform(options.Platform)
|
||||
@@ -70,7 +79,7 @@ func buildDriver(ctx context.Context, options Options, stdout io.Writer) (driver
|
||||
healthCtx, healthCancel := context.WithTimeout(ctx, sidecarStartupTimeout)
|
||||
if err := driverClient.WaitForHealth(healthCtx, 250e6); err != nil {
|
||||
healthCancel()
|
||||
_ = sidecarCommand.Process.Kill()
|
||||
stopSidecar(sidecarCommand)
|
||||
_ = driverClient.Close()
|
||||
return nil, nil, fmt.Errorf("sidecar health check: %w", err)
|
||||
}
|
||||
@@ -79,13 +88,40 @@ func buildDriver(ctx context.Context, options Options, stdout io.Writer) (driver
|
||||
|
||||
cleanup := func() {
|
||||
_ = driverClient.Close()
|
||||
if sidecarCommand.Process != nil {
|
||||
_ = sidecarCommand.Process.Kill()
|
||||
}
|
||||
stopSidecar(sidecarCommand)
|
||||
}
|
||||
return driverClient, cleanup, nil
|
||||
}
|
||||
|
||||
// sidecarShutdownGrace bounds how long the sidecar gets to run its shutdown
|
||||
// hook (terminate the app, stop the XCTest runner) before being killed.
|
||||
const sidecarShutdownGrace = 15 * time.Second
|
||||
|
||||
// stopSidecar terminates the sidecar gracefully so its shutdown hook can stop
|
||||
// the device-side runner processes, escalating to SIGKILL when it does not
|
||||
// exit within the grace window.
|
||||
func stopSidecar(sidecarCommand *exec.Cmd) {
|
||||
if sidecarCommand.Process == nil {
|
||||
return
|
||||
}
|
||||
if err := sidecarCommand.Process.Signal(syscall.SIGTERM); err != nil {
|
||||
_ = sidecarCommand.Process.Kill()
|
||||
_ = sidecarCommand.Wait()
|
||||
return
|
||||
}
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
_ = sidecarCommand.Wait()
|
||||
close(done)
|
||||
}()
|
||||
select {
|
||||
case <-done:
|
||||
case <-time.After(sidecarShutdownGrace):
|
||||
_ = sidecarCommand.Process.Kill()
|
||||
<-done
|
||||
}
|
||||
}
|
||||
|
||||
func pickFreePort() (int, error) {
|
||||
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
|
||||
Reference in new issue
Block a user