返回 DeepSeek-Reasonix
session_temp_rebuild_test.go
根目录 / desktop / session_temp_rebuild_test.go
1 package main
2
3 import (
4 "os"
5 "path/filepath"
6 "testing"
7
8 "reasonix/internal/control"
9 )
10
11 // TestDesktopHotRebuildPathsKeepSessionTemp covers the three same-session
12 // rebuilds that use boot.Build directly (not boot.Rebuild): model, effort,
13 // and token-mode switches. Each must pass the old Controller's SessionTemp so
14 // temporary files survive (Issue #7575).
15 func TestDesktopHotRebuildPathsKeepSessionTemp(t *testing.T) {
16 for _, tc := range []struct {
17 name string
18 prepare func(*App, *WorkspaceTab)
19 rebuild func(*App, *WorkspaceTab) error
20 }{
21 {
22 name: "model",
23 prepare: func(*App, *WorkspaceTab) {},
24 rebuild: func(app *App, tab *WorkspaceTab) error {
25 return app.SetModelForTab(tab.ID, "alt/alt-model")
26 },
27 },
28 {
29 name: "effort",
30 prepare: func(*App, *WorkspaceTab) {},
31 rebuild: func(app *App, tab *WorkspaceTab) error {
32 return app.SetEffortForTab(tab.ID, "high")
33 },
34 },
35 {
36 name: "token mode",
37 prepare: func(*App, *WorkspaceTab) {},
38 rebuild: func(app *App, tab *WorkspaceTab) error {
39 return app.SetTokenModeForTab(tab.ID, "delivery")
40 },
41 },
42 } {
43 t.Run(tc.name, func(t *testing.T) {
44 app, tab, oldAPI, _ := newGoalDeliveryYoloTestApp(t, control.GoalStatusRunning)
45 oldCtrl, ok := oldAPI.(*control.Controller)
46 if !ok || oldCtrl == nil {
47 t.Fatal("old controller is not *control.Controller")
48 }
49 tc.prepare(app, tab)
50
51 // Plant a file in the session-private temporary directory.
52 lease, err := oldCtrl.SessionTemp().Acquire()
53 if err != nil {
54 t.Fatalf("acquire old session temp: %v", err)
55 }
56 oldMgr := oldCtrl.SessionTemp()
57 oldDir := lease.Dir()
58 marker := filepath.Join(oldDir, "desktop-hot-rebuild.txt")
59 if err := os.WriteFile(marker, []byte(tc.name), 0o600); err != nil {
60 t.Fatal(err)
61 }
62 lease.Release()
63
64 if err := tc.rebuild(app, tab); err != nil {
65 t.Fatalf("rebuild: %v", err)
66 }
67
68 newAPI := app.controllerForTab(tab)
69 newCtrl, ok := newAPI.(*control.Controller)
70 if !ok || newCtrl == nil || newCtrl == oldCtrl {
71 t.Fatal("rebuild did not install a replacement *control.Controller")
72 }
73 if newCtrl.SessionTemp() != oldMgr {
74 t.Fatalf("%s rebuild did not reuse SessionTemp Manager (got %p want %p)",
75 tc.name, newCtrl.SessionTemp(), oldMgr)
76 }
77 if oldMgr.Sealed() {
78 t.Fatal("shared manager sealed after hot rebuild (replacement must retain first)")
79 }
80
81 again, err := newCtrl.SessionTemp().Acquire()
82 if err != nil {
83 t.Fatalf("acquire after rebuild: %v", err)
84 }
85 defer again.Release()
86 if again.Dir() != oldDir {
87 t.Fatalf("%s rebuild rotated temporary generation: got %q want %q",
88 tc.name, again.Dir(), oldDir)
89 }
90 body, err := os.ReadFile(marker)
91 if err != nil || string(body) != tc.name {
92 t.Fatalf("temp file lost across %s rebuild: %q %v", tc.name, body, err)
93 }
94 })
95 }
96 }
97
98 func TestSessionTempFromControllerHelper(t *testing.T) {
99 if sessionTempFromController(nil) != nil {
100 t.Fatal("nil controller should yield nil SessionTemp")
101 }
102 ctrl := control.New(control.Options{})
103 defer ctrl.Close()
104 if sessionTempFromController(ctrl) == nil {
105 t.Fatal("want non-nil SessionTemp from live controller")
106 }
107 if sessionTempFromController(ctrl) != ctrl.SessionTemp() {
108 t.Fatal("helper must return the controller's Manager")
109 }
110 }
111
111 lines GO