| 1 | package session |
| 2 | |
| 3 | import ( |
| 4 | "context" |
| 5 | "testing" |
| 6 | ) |
| 7 | |
| 8 | func TestHistoryReadScopeSharedLifetimeAndNavigationFence(t *testing.T) { |
| 9 | q := newQuery("local", nil, nil) |
| 10 | defer q.rebuildStop() |
| 11 | ref := SessionRef{HostID: "local", SessionID: "history"} |
| 12 | a, releaseA, err := q.AcquireHistoryReader(ref) |
| 13 | if err != nil { |
| 14 | t.Fatal(err) |
| 15 | } |
| 16 | b, releaseB, err := q.AcquireHistoryReader(ref) |
| 17 | if err != nil { |
| 18 | t.Fatal(err) |
| 19 | } |
| 20 | individual, cancel := context.WithCancel(a) |
| 21 | cancel() |
| 22 | if q.historyReadContext(ref.SessionID, individual).Err() != nil { |
| 23 | t.Fatal("one cancelled RPC cancelled shared preparation") |
| 24 | } |
| 25 | releaseA() |
| 26 | releaseA() |
| 27 | if b.Err() != nil { |
| 28 | t.Fatal("one reader retired the shared scope") |
| 29 | } |
| 30 | releaseB() |
| 31 | if b.Err() != context.Canceled { |
| 32 | t.Fatal("last release did not cancel preparation") |
| 33 | } |
| 34 | c, releaseC, err := q.AcquireHistoryReader(ref) |
| 35 | if err != nil { |
| 36 | t.Fatal(err) |
| 37 | } |
| 38 | defer releaseC() |
| 39 | compatibility := q.historyReadContext(ref.SessionID, context.Background()) |
| 40 | if compatibility != q.rebuildCtx { |
| 41 | t.Fatal("unbound RPC borrowed another reader's cancellation owner") |
| 42 | } |
| 43 | if c.Err() != nil { |
| 44 | t.Fatal("new navigation inherited the cancelled scope") |
| 45 | } |
| 46 | if q.historyReadContext(ref.SessionID, a).Err() != context.Canceled { |
| 47 | t.Fatal("late old request borrowed the new reader's preparation lifetime") |
| 48 | } |
| 49 | if q.historyReadContext(ref.SessionID, c).Err() != nil { |
| 50 | t.Fatal("old release affected new scope") |
| 51 | } |
| 52 | } |
| 53 | |
| 54 | func TestUnboundPreparationSurvivesCompletedHTTPRequest(t *testing.T) { |
| 55 | q := newQuery("local", nil, nil) |
| 56 | defer q.rebuildStop() |
| 57 | request, finish := context.WithCancel(context.Background()) |
| 58 | owner := q.historyReadContext("history", request) |
| 59 | finish() |
| 60 | if owner.Err() != nil { |
| 61 | t.Fatal("preparing response canceled its asynchronous preparation") |
| 62 | } |
| 63 | if q.historyReadContext("history", request).Err() != context.Canceled { |
| 64 | t.Fatal("already-canceled request was admitted") |
| 65 | } |
| 66 | } |
| 67 |