| 1 | package main |
| 2 | |
| 3 | import "testing" |
| 4 | |
| 5 | func TestRemoteContextPanelReadsServeContext(t *testing.T) { |
| 6 | fs := newFakeServe(t, "s3cret", nil) |
| 7 | fs.newSessionPath = "/sessions/remote.jsonl" |
| 8 | kernel := &fakeRemoteKernel{ |
| 9 | statuses: []RemoteConnectionStatusView{{HostID: "box", State: "connected"}}, |
| 10 | ensureView: RemoteServerView{HostID: "box", State: "ready", LocalURL: fs.server.URL}, |
| 11 | ensureToken: "s3cret", |
| 12 | } |
| 13 | seedBridgeTestHost(t, "box") |
| 14 | a := &App{remoteRuntime: kernel} |
| 15 | cleanupRemoteTabPumps(t, a) |
| 16 | meta, err := a.OpenRemoteProjectTab("box", "~/app", RemoteTabOpenOptions{NewSession: true}) |
| 17 | if err != nil { |
| 18 | t.Fatal(err) |
| 19 | } |
| 20 | waitForTabState(t, a, meta.ID, "ready") |
| 21 | if got := a.ContextPanel(meta.ID); got.UsedTokens != 10 || got.WindowTokens != 128 { |
| 22 | t.Fatalf("remote panel context = %d/%d, want Serve /context value 10/128", got.UsedTokens, got.WindowTokens) |
| 23 | } |
| 24 | if got := a.ContextUsageForTab(meta.ID); got.Used != 10 || got.Window != 128 { |
| 25 | t.Fatalf("remote usage context = %d/%d, want 10/128", got.Used, got.Window) |
| 26 | } |
| 27 | fs.mu.Lock() |
| 28 | expected := fs.contextExpected |
| 29 | fs.mu.Unlock() |
| 30 | a.remoteTabMu.Lock() |
| 31 | selected := a.remoteTabs[meta.ID].routing.currentPath |
| 32 | a.remoteTabMu.Unlock() |
| 33 | if expected != selected { |
| 34 | t.Fatalf("remote context request targeted %q, want selected %q", expected, selected) |
| 35 | } |
| 36 | a.remoteTabMu.Lock() |
| 37 | a.remoteTabs[meta.ID].routing.currentPath = remoteSessionIDRoutePrefix + "canonical-a" |
| 38 | a.remoteTabs[meta.ID].routing.pathRevision++ |
| 39 | a.remoteTabMu.Unlock() |
| 40 | if got := a.ContextPanel(meta.ID); got.UsedTokens != 10 { |
| 41 | t.Fatalf("canonical remote panel used tokens = %d, want 10", got.UsedTokens) |
| 42 | } |
| 43 | fs.mu.Lock() |
| 44 | expected = fs.contextExpected |
| 45 | fs.mu.Unlock() |
| 46 | if expected != remoteSessionIDRoutePrefix+"canonical-a" { |
| 47 | t.Fatalf("canonical context header = %q", expected) |
| 48 | } |
| 49 | started, release := make(chan struct{}, 1), make(chan struct{}) |
| 50 | fs.mu.Lock() |
| 51 | fs.contextStarted, fs.contextRelease = started, release |
| 52 | fs.mu.Unlock() |
| 53 | done := make(chan ContextPanelInfo, 1) |
| 54 | go func() { done <- a.ContextPanel(meta.ID) }() |
| 55 | <-started |
| 56 | a.remoteTabMu.Lock() |
| 57 | a.remoteTabs[meta.ID].routing.currentPath = remoteSessionIDRoutePrefix + "canonical-b" |
| 58 | a.remoteTabs[meta.ID].routing.pathRevision++ |
| 59 | a.remoteTabMu.Unlock() |
| 60 | close(release) |
| 61 | if got := <-done; got.UsedTokens != 0 || got.WindowTokens != 0 { |
| 62 | t.Fatalf("stale remote context reached the switched tab: %+v", got) |
| 63 | } |
| 64 | } |
| 65 |