From 0929ae54bf400f7cf9ebf2fe5eb4f9a076652659 Mon Sep 17 00:00:00 2001 From: PJ Date: Sat, 15 Aug 2026 19:31:24 +0530 Subject: [PATCH] test(ios): the restart a blown launch triggers has to be bounded --- internal/driver/ioscompanion/driver_test.go | 28 +++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/internal/driver/ioscompanion/driver_test.go b/internal/driver/ioscompanion/driver_test.go index 7db8f36..07316c2 100644 --- a/internal/driver/ioscompanion/driver_test.go +++ b/internal/driver/ioscompanion/driver_test.go @@ -1021,6 +1021,34 @@ func TestLaunchReplacesTheSessionAfterALaunchBlowsItsBound(t *testing.T) { } } +// TestLaunchBoundsTheSessionRestartItTriggers keeps the recovery inside a +// budget of its own. The restart deliberately runs on the driver's lifetime +// context rather than the caller's, so without a deadline a session that never +// comes back would hang the launch path exactly the way #73 stopped it hanging. +func TestLaunchBoundsTheSessionRestartItTriggers(t *testing.T) { + previousLaunch, previousRecovery := launchTimeout, launchRecoveryTimeout + launchTimeout = 100 * time.Millisecond + launchRecoveryTimeout = 200 * time.Millisecond + defer func() { launchTimeout, launchRecoveryTimeout = previousLaunch, previousRecovery }() + + d := newTestDriver(&wedgedUntilRestartCompanion{}) + d.restart = func(restartCtx context.Context) error { + <-restartCtx.Done() + return restartCtx.Err() + } + + done := make(chan error, 1) + go func() { done <- d.Launch(context.Background(), "", false, nil) }() + select { + case err := <-done: + if err == nil || !strings.Contains(err.Error(), "session restart failed") { + t.Fatalf("err = %v, want the failed restart named", err) + } + case <-time.After(10 * time.Second): + t.Fatal("Launch never returned: a session that never comes back hangs the launch path") + } +} + // TestLaunchKeepsTheSessionWhenTheCallersOwnDeadlineExpires holds the recovery // to the driver's own bound. Spending a session restart on a caller that has // already run out of budget cannot produce a launch, only a later failure.