| 1 | package main |
| 2 | |
| 3 | import ( |
| 4 | "testing" |
| 5 | ) |
| 6 | |
| 7 | const backgroundRemoteTestPath = "/sessions/background.jsonl" |
| 8 | |
| 9 | // backgroundFreshness reports the freshness the runtime snapshot assigns to |
| 10 | // the tab's background route. |
| 11 | func backgroundFreshness(t *testing.T, a *App, tab *remoteTab) string { |
| 12 | t.Helper() |
| 13 | for _, session := range a.sampleRemoteRuntimeSessions() { |
| 14 | if session.TabID == tab.id && session.SessionPath == backgroundRemoteTestPath { |
| 15 | return session.Freshness |
| 16 | } |
| 17 | } |
| 18 | t.Fatalf("background route %q missing from the runtime snapshot", backgroundRemoteTestPath) |
| 19 | return "" |
| 20 | } |
| 21 | |
| 22 | // runtimeStates are seeded once and never cleared on suspend or park, so a |
| 23 | // tab that lost its stream keeps whatever phase it last observed. Reporting |
| 24 | // that frozen snapshot as "synced" tells the project tree a session is still |
| 25 | // executing after the tunnel dropped. |
| 26 | func TestBackgroundRouteFreshnessFollowsTheTabConnection(t *testing.T) { |
| 27 | a, tab := remoteRuntimeTestApp(nil) |
| 28 | executing := remoteRuntimeTestSnapshot("epoch-1", 4, "executing") |
| 29 | acceptRemoteRuntimeStateLocked(tab, backgroundRemoteTestPath, executing, true) |
| 30 | if got := backgroundFreshness(t, a, tab); got != "synced" { |
| 31 | t.Fatalf("freshly observed background route = %q, want synced", got) |
| 32 | } |
| 33 | |
| 34 | tab.state = "reconnecting" |
| 35 | if got := backgroundFreshness(t, a, tab); got != "unknown" { |
| 36 | t.Fatalf("disconnected tab background route = %q, want unknown", got) |
| 37 | } |
| 38 | |
| 39 | tab.state = "ready" |
| 40 | tab.runtime.syncFailed = true |
| 41 | if got := backgroundFreshness(t, a, tab); got != "unknown" { |
| 42 | t.Fatalf("failed-sync background route = %q, want unknown", got) |
| 43 | } |
| 44 | |
| 45 | // A foreground ownership change says nothing about another session: the |
| 46 | // stream is live and the background snapshot is still being observed. |
| 47 | tab.runtime.syncFailed = false |
| 48 | tab.session.takenOver = true |
| 49 | if got := backgroundFreshness(t, a, tab); got != "synced" { |
| 50 | t.Fatalf("taken-over foreground invalidated the background route: %q", got) |
| 51 | } |
| 52 | } |
| 53 |