返回 DeepSeek-Reasonix
tab_startup_failure_test.go
根目录 / desktop / tab_startup_failure_test.go
1 package main
2
3 import (
4 "errors"
5 "testing"
6
7 "reasonix/internal/agent"
8 )
9
10 func TestTerminalStartupFailureImmediatelyLeavesRestoreSnapshot(t *testing.T) {
11 app := testAppWithOrderedTabs(t, "failed", "failed", "keep")
12 failed := app.tabs["failed"]
13
14 app.mu.Lock()
15 app.newSessionRuntimeLocked(failed, "")
16 _, save := app.markTabStartupFailureLocked(failed, errors.New("restore failed"), suppressStartupRestore)
17 app.mu.Unlock()
18 app.writeTabsSaveRequest(save)
19
20 got := loadTabsFile()
21 if len(got.Tabs) != 1 || got.Tabs[0].ID != "keep" {
22 t.Fatalf("persisted tabs = %#v, want only keep", got.Tabs)
23 }
24 if got.ActiveTab != "keep" {
25 t.Fatalf("persisted active tab = %q, want keep", got.ActiveTab)
26 }
27 if app.tabs["failed"] != failed {
28 t.Fatal("failed tab must remain visible in memory until the user closes or archives it")
29 }
30 }
31
32 func TestRetryableOrTransientStartupFailureStaysRestorable(t *testing.T) {
33 tests := []struct {
34 name string
35 err error
36 policy startupFailureRestorePolicy
37 }{
38 {name: "lease blocked", err: agent.ErrSessionLeaseHeld, policy: suppressStartupRestore},
39 {name: "transient boot failure", err: errors.New("provider unavailable"), policy: keepStartupRestore},
40 }
41 for _, tt := range tests {
42 t.Run(tt.name, func(t *testing.T) {
43 app := testAppWithOrderedTabs(t, "retry", "retry")
44 tab := app.tabs["retry"]
45 app.mu.Lock()
46 app.newSessionRuntimeLocked(tab, "")
47 _, unexpectedSave := app.markTabStartupFailureLocked(tab, tt.err, tt.policy)
48 dir, entries, activeID, version := app.saveTabsCollectLocked()
49 app.mu.Unlock()
50 if unexpectedSave != nil {
51 t.Fatal("retryable/transient failure requested terminal persistence")
52 }
53 app.saveTabsWrite(dir, entries, activeID, version)
54
55 got := loadTabsFile()
56 if len(got.Tabs) != 1 || got.Tabs[0].ID != tab.ID || got.ActiveTab != tab.ID {
57 t.Fatalf("persisted tabs = %#v active=%q, want retry tab", got.Tabs, got.ActiveTab)
58 }
59 })
60 }
61 }
62
63 func TestStartingRetryClearsStartupRestoreSuppression(t *testing.T) {
64 app := testAppWithOrderedTabs(t, "retry", "retry")
65 tab := app.tabs["retry"]
66 app.mu.Lock()
67 app.newSessionRuntimeLocked(tab, "")
68 app.markTabStartupFailureLocked(tab, errors.New("restore failed"), suppressStartupRestore)
69 app.setSessionRuntimePhaseLocked(tab, sessionRuntimeStarting, nil)
70 dir, entries, activeID, version := app.saveTabsCollectLocked()
71 app.mu.Unlock()
72 app.saveTabsWrite(dir, entries, activeID, version)
73
74 got := loadTabsFile()
75 if len(got.Tabs) != 1 || got.Tabs[0].ID != tab.ID {
76 t.Fatalf("persisted tabs after retry = %#v, want retry tab", got.Tabs)
77 }
78 }
79
79 lines GO