Files
memby/server/internal/credits/queue_test.go
T
2026-08-15 09:23:26 +12:00

144 lines
4.4 KiB
Go

package credits
import (
"testing"
"time"
)
// The queue is bounded, and saturation is a real state with a right answer: throw the
// speculation away. A queue holding forty episodes nobody has reached has stopped describing
// demand.
func queued(id string, priority int) Candidate {
return Candidate{ItemID: id, Priority: priority, LastViewed: now}
}
func TestQueueOrdersByPriority(t *testing.T) {
queue := NewQueue(10)
queue.Push(queued("ahead3", PriorityAhead3))
queue.Push(queued("live", PriorityLive))
queue.Push(queued("next", PriorityNext))
candidate, found := queue.Claim()
if !found || candidate.ItemID != "live" {
t.Fatalf("claimed %+v, want the live candidate first", candidate)
}
candidate, _ = queue.Claim()
if candidate.ItemID != "next" {
t.Fatalf("claimed %q second, want next", candidate.ItemID)
}
}
func TestSaturationDiscardsTheWeakestSpeculation(t *testing.T) {
queue := NewQueue(3)
queue.Push(queued("spec-a", PrioritySpeculative))
queue.Push(queued("spec-b", PrioritySpeculative+1))
queue.Push(queued("spec-c", PrioritySpeculative+2))
if queued := queue.Push(queued("live", PriorityLive)); !queued {
t.Fatal("a full queue refused live playback")
}
if queue.Len() != 3 {
t.Fatalf("queue length %d, want the limit of 3", queue.Len())
}
for _, candidate := range queue.Snapshot() {
if candidate.ItemID == "spec-a" {
t.Fatal("the weakest candidate survived saturation")
}
}
}
func TestSaturationRefusesWeakerWork(t *testing.T) {
queue := NewQueue(2)
queue.Push(queued("next-a", PriorityNext))
queue.Push(queued("next-b", PriorityNext))
if queue.Push(queued("spec", PrioritySpeculative)) {
t.Fatal("a full queue accepted work weaker than everything in it")
}
if queue.Len() != 2 {
t.Fatalf("queue length %d, want 2", queue.Len())
}
}
func TestPushMergesRatherThanDuplicating(t *testing.T) {
queue := NewQueue(10)
queue.Push(queued("bb-s06e08", PriorityAhead2))
queue.Push(Candidate{
ItemID: "bb-s06e08", Priority: PriorityNext, Reason: ReasonMultiUser,
UserCount: 2, LastViewed: now,
})
if queue.Len() != 1 {
t.Fatalf("queue length %d; the same episode must not be queued twice", queue.Len())
}
candidate, _ := queue.Claim()
if candidate.Priority != PriorityNext {
t.Fatalf("priority = %d; the stronger case should have won", candidate.Priority)
}
if candidate.UserCount != 2 {
t.Fatalf("UserCount = %d, want 2", candidate.UserCount)
}
}
// A weaker second viewer must never lower a candidate somebody else is about to reach.
func TestPushNeverLowersPriority(t *testing.T) {
queue := NewQueue(10)
queue.Push(queued("bb-s06e08", PriorityNext))
queue.Push(queued("bb-s06e08", PrioritySpeculative))
candidate, _ := queue.Claim()
if candidate.Priority != PriorityNext {
t.Fatalf("priority = %d, want %d", candidate.Priority, PriorityNext)
}
}
// Cancelling a scan that is already reading a file, to replace it with a marginally better
// candidate, would waste exactly the disk activity this package exists to avoid.
func TestReplaceLeavesClaimedWorkAlone(t *testing.T) {
queue := NewQueue(10)
queue.Push(queued("in-flight", PriorityNext))
claimed, _ := queue.Claim()
queue.Replace([]Candidate{queued("fresh", PriorityNext), queued(claimed.ItemID, PriorityLive)})
for _, candidate := range queue.Snapshot() {
if candidate.ItemID == claimed.ItemID {
t.Fatal("a refresh re-queued an episode already being scanned")
}
}
queue.Release(claimed.ItemID)
if queue.Push(queued(claimed.ItemID, PriorityNext)); queue.Len() != 2 {
t.Fatalf("queue length %d after release, want 2", queue.Len())
}
}
func TestClaimedItemsAreNotReQueued(t *testing.T) {
queue := NewQueue(10)
queue.Push(queued("bb-s06e08", PriorityNext))
claimed, _ := queue.Claim()
if queue.Push(queued(claimed.ItemID, PriorityLive)) {
t.Fatal("an episode being scanned was queued a second time")
}
}
func TestEmptyQueueClaimsNothing(t *testing.T) {
if _, found := NewQueue(5).Claim(); found {
t.Fatal("an empty queue produced work")
}
}
func TestQueueOrderIsTotalAndStable(t *testing.T) {
queue := NewQueue(10)
older := now.Add(-2 * time.Hour)
queue.Push(Candidate{ItemID: "b", Priority: PriorityNext, LastViewed: older})
queue.Push(Candidate{ItemID: "a", Priority: PriorityNext, LastViewed: now})
// Equal priority: the more recent demand goes first.
candidate, _ := queue.Claim()
if candidate.ItemID != "a" {
t.Fatalf("claimed %q; more recent demand should win a tie", candidate.ItemID)
}
}