package messagequeue import ( "sync" "testing" ) func TestMessageQueue_FIFO(t *testing.T) { q := New() q.Enqueue("s", "first") q.Enqueue("s", "second") q.Enqueue("s", "third") want := []string{"first", "second", "third"} for _, w := range want { got, ok := q.Dequeue("s") if !ok || got != w { t.Fatalf("Dequeue = %q,%v want %q,true", got, ok, w) } } if _, ok := q.Dequeue("s"); ok { t.Fatal("Dequeue on drained queue should return ok=false") } } func TestMessageQueue_RequeueFront(t *testing.T) { q := New() q.Enqueue("s", "a") q.Enqueue("s", "b") // Pop "a", then push it back to the front; "a" must come out before "b". a, _ := q.Dequeue("s") q.RequeueFront("s", a) got, _ := q.Dequeue("s") if got != "a" { t.Fatalf("after RequeueFront, Dequeue = %q want %q", got, "a") } got2, _ := q.Dequeue("s") if got2 != "b" { t.Fatalf("next Dequeue = %q want %q", got2, "b") } } func TestMessageQueue_IsolatedPerSession(t *testing.T) { q := New() q.Enqueue("s1", "one") q.Enqueue("s2", "two") if got, _ := q.Dequeue("s1"); got != "one" { t.Fatalf("s1 = %q want one", got) } if got, _ := q.Dequeue("s2"); got != "two" { t.Fatalf("s2 = %q want two", got) } if q.Peek("s1") != 0 || q.Peek("s2") != 0 { t.Fatal("both sessions should be drained") } } func TestMessageQueue_Concurrent(t *testing.T) { q := New() const n = MaxQueuedPerSession // stay under the cap so every Enqueue lands var wg sync.WaitGroup for i := 0; i < n; i++ { wg.Add(1) go func(i int) { defer wg.Done() q.Enqueue("s", "m") }(i) } wg.Wait() if q.Peek("s") != n { t.Fatalf("Peek = %d want %d (all enqueues must be counted)", q.Peek("s"), n) } seen := 0 for { if _, ok := q.Dequeue("s"); !ok { break } seen++ } if seen != n { t.Fatalf("drained %d want %d", seen, n) } } func TestMessageQueue_CapsOverflow(t *testing.T) { q := New() for i := 0; i < MaxQueuedPerSession; i++ { if !q.Enqueue("s", "m") { t.Fatalf("Enqueue #%d within cap should succeed", i) } } if q.Enqueue("s", "overflow") { t.Fatal("Enqueue past the cap should return false (dropped)") } if got := q.Peek("s"); got != MaxQueuedPerSession { t.Fatalf("Peek = %d want %d (overflow must not append)", got, MaxQueuedPerSession) } }