Something went wrong. Try again.
Educational demo of a single node, sqlite, Datastar, CQRS app with low latency UX.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129package main
import ( "fmt" "testing" "time")
// TestHubBounded churns random client-chosen sids and asserts the hub never// grows past its cap (P0.3a), while a session with a live stream survives the// eviction that makes room.func TestHubBounded(t *testing.T) { h := &Hub{sessions: make(map[string]*Session), max: 8} // no tickers needed
live := h.getOrCreate("live-tab") ch := live.subscribe() defer live.unsubscribe(ch)
for i := 0; i < 100; i++ { h.getOrCreate(fmt.Sprintf("sid-%d", i)) if n := h.count(); n > h.max { t.Fatalf("after %d sids: %d sessions, want <= %d", i+1, n, h.max) } } if n := h.count(); n != h.max { t.Fatalf("got %d sessions, want the cap %d", n, h.max) } if s := h.getOrCreate("live-tab"); s != live { t.Fatal("session with a live stream was evicted") }}
// TestHubFullOfLiveSessions: when every stored session has a subscriber, a new// sid still gets a working session but the map refuses to grow.func TestHubFullOfLiveSessions(t *testing.T) { h := &Hub{sessions: make(map[string]*Session), max: 4} for i := 0; i < h.max; i++ { s := h.getOrCreate(fmt.Sprintf("live-%d", i)) defer s.unsubscribe(s.subscribe()) } s := h.getOrCreate("overflow") if s == nil { t.Fatal("getOrCreate returned nil at capacity") } if n := h.count(); n != h.max { t.Fatalf("got %d sessions, want %d (unregistered overflow)", n, h.max) }}
// TestHubFrameWakesDirty: notify only marks the session dirty; the frame// ticker (not the write path) is what wakes the subscribed stream, clearing// the flag.func TestHubFrameWakesDirty(t *testing.T) { h := newHub(time.Millisecond, time.Minute) s := h.getOrCreate("tab") ch := s.subscribe() defer s.unsubscribe(ch)
s.notify() select { case <-ch: case <-time.After(2 * time.Second): t.Fatal("frame ticker never woke the dirty session's stream") } if s.dirty.Load() { t.Fatal("dirty flag not cleared by the frame flush") }}
// TestHubSweepEvictsIdle: a sweep within ttl keeps everything; past ttl it// reclaims the subscriber-less session but never one with a live stream.func TestHubSweepEvictsIdle(t *testing.T) { h := &Hub{sessions: make(map[string]*Session), ttl: time.Minute, max: maxSessions} // no tickers needed now := time.Now()
h.getOrCreate("idle") live := h.getOrCreate("live") ch := live.subscribe() defer live.unsubscribe(ch)
h.sweep(now.Add(30 * time.Second)) if n := h.count(); n != 2 { t.Fatalf("sweep within ttl evicted: %d sessions, want 2", n) }
h.sweep(now.Add(2 * time.Minute)) h.mu.Lock() _, idleKept := h.sessions["idle"] _, liveKept := h.sessions["live"] h.mu.Unlock() if idleKept { t.Fatal("idle session survived a sweep past ttl") } if !liveKept { t.Fatal("session with a live stream was swept") }}
// TestWriteLimiterPerIdentity: the bucket is keyed by login, so rotating sids// (i.e. fresh sessions) does not reset one login's write budget (P0.3b), while// a different login keeps its own.func TestWriteLimiterPerIdentity(t *testing.T) { l := newWriteLimiter() now := time.Now()
// Each call simulates a request under a brand-new sid — the limiter only // ever sees the authenticated login, so the burst is spent exactly once. for i := 0; i < int(writeBurst); i++ { if !l.allow("alice", now) { t.Fatalf("write %d within burst denied", i+1) } } if l.allow("alice", now) { t.Fatal("write over burst allowed despite sid rotation") } if !l.allow("bob", now) { t.Fatal("independent login denied by alice's spent budget") }
// Refill: one token accrues after 1/writeRate seconds. later := now.Add(time.Duration(float64(time.Second) / writeRate)) if !l.allow("alice", later) { t.Fatal("refilled token denied") } if l.allow("alice", later) { t.Fatal("second write allowed after a single-token refill") }}