返回 DeepSeek-Reasonix
remote_sessions_ensure_test.go
根目录 / desktop / remote_sessions_ensure_test.go
1 package main
2
3 import (
4 "net/http"
5 "testing"
6 )
7
8 // The explicit-intent listing contract: a remote group click may cold-start
9 // the serve, while the passive listing keeps refusing to wake one.
10
11 // TestRemoteProjectSessionsEnsureColdStartsServe pins the group-click path:
12 // with nothing running, EnsureRemoteProjectSessions boots the serve through
13 // EnsureServer and returns the mapped rows.
14 func TestRemoteProjectSessionsEnsureColdStartsServe(t *testing.T) {
15 fs := newFakeServe(t, "s3cret", []serveSessionEntry{
16 {Name: "s1", Path: "/remote/sessions/s1.jsonl", Title: "First chat", Turns: 2},
17 })
18 kernel := &fakeRemoteKernel{
19 statuses: []RemoteConnectionStatusView{{HostID: "box", State: "connected"}},
20 ensureView: RemoteServerView{HostID: "box", State: "ready", LocalURL: fs.server.URL},
21 ensureToken: "s3cret",
22 snapshotMiss: true, // registry says nothing is running; EnsureServer can boot it
23 }
24 seedBridgeTestHost(t, "box")
25 a := &App{remoteRuntime: kernel}
26 cleanupRemoteTabPumps(t, a)
27
28 // The read-only listing must still refuse while the serve is down.
29 if _, err := a.RemoteProjectSessions("box", "~/app"); err == nil {
30 t.Fatal("read-only listing must fail while the serve is stopped")
31 }
32
33 rows, err := a.EnsureRemoteProjectSessions("box", "~/app")
34 if err != nil {
35 t.Fatal(err)
36 }
37 if kernel.ensureCalls == 0 {
38 t.Fatal("ensure listing never cold-started the serve")
39 }
40 if len(rows) != 1 || rows[0].Name != "s1" || rows[0].Title != "First chat" || rows[0].Turns != 2 {
41 t.Fatalf("ensured sessions = %+v, want the mapped s1 entry", rows)
42 }
43 cleanupRemoteTabPumps(t, a)
44 }
45
46 // TestRemoteProjectSessionsEnsureReusesRunningServe pins the warm path: when
47 // a serve registration is already live, the ensure listing must not run a
48 // second EnsureServer round.
49 func TestRemoteProjectSessionsEnsureReusesRunningServe(t *testing.T) {
50 fs := newFakeServe(t, "s3cret", []serveSessionEntry{
51 {Name: "s1", Path: "/remote/sessions/s1.jsonl", Title: "First chat", Turns: 1},
52 })
53 kernel := &fakeRemoteKernel{
54 statuses: []RemoteConnectionStatusView{{HostID: "box", State: "connected"}},
55 ensureView: RemoteServerView{HostID: "box", State: "ready", LocalURL: fs.server.URL},
56 ensureToken: "s3cret",
57 }
58 seedBridgeTestHost(t, "box")
59 a := &App{remoteRuntime: kernel}
60 cleanupRemoteTabPumps(t, a)
61
62 rows, err := a.EnsureRemoteProjectSessions("box", "~/app")
63 if err != nil {
64 t.Fatal(err)
65 }
66 if kernel.ensureCalls != 0 {
67 t.Fatalf("ensure listing booted a serve that was already running: %d calls", kernel.ensureCalls)
68 }
69 if len(rows) != 1 || rows[0].Name != "s1" {
70 t.Fatalf("ensured sessions = %+v, want s1", rows)
71 }
72 cleanupRemoteTabPumps(t, a)
73 }
74
75 // TestRemoteProjectSessionsEnsureRejectsSuspendedTabClient pins reconnect
76 // recovery: a suspended tab retains its old client for later reattachment, but
77 // an explicit group refresh must not reuse that client as a live Serve path.
78 func TestRemoteProjectSessionsEnsureRejectsSuspendedTabClient(t *testing.T) {
79 fs := newFakeServe(t, "s3cret", []serveSessionEntry{
80 {Name: "s1", Path: "/remote/sessions/s1.jsonl", Title: "Recovered chat", Turns: 3},
81 })
82 kernel := &fakeRemoteKernel{
83 statuses: []RemoteConnectionStatusView{{HostID: "box", State: "connected"}},
84 ensureView: RemoteServerView{HostID: "box", State: "ready", LocalURL: fs.server.URL},
85 ensureToken: "s3cret",
86 snapshotMiss: true,
87 }
88 seedBridgeTestHost(t, "box")
89 a := &App{
90 remoteRuntime: kernel,
91 remoteTabs: map[string]*remoteTab{
92 "suspended": {
93 id: "suspended", ref: RemoteTabRef{HostID: "box", Workspace: "~/app"},
94 state: "reconnecting", client: &http.Client{}, base: "http://127.0.0.1:1",
95 },
96 },
97 }
98 cleanupRemoteTabPumps(t, a)
99
100 rows, err := a.EnsureRemoteProjectSessions("box", "~/app")
101 if err != nil {
102 t.Fatal(err)
103 }
104 if kernel.ensureCalls == 0 {
105 t.Fatal("ensure listing reused the suspended tab client instead of recovering Serve")
106 }
107 if len(rows) != 1 || rows[0].Name != "s1" {
108 t.Fatalf("ensured sessions = %+v, want recovered s1", rows)
109 }
110 }
111
111 lines GO