78 lines
2.1 KiB
Go
78 lines
2.1 KiB
Go
package world
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
)
|
|
|
|
func TestTicketPinsChunkUntilRelease(t *testing.T) {
|
|
cache := NewCacheWithLimit(-1, func(cx, cz int32) *Chunk {
|
|
return NewChunk(cx, cz, BiomePlains)
|
|
}, nil, 2)
|
|
tickets := cache.NewTicketSet()
|
|
tickets.Replace([]ChunkPos{{X: 0, Z: 0}}, nil)
|
|
for x := int32(0); x < 4; x++ {
|
|
if _, err := cache.FrameErr(x, 0); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
if !hasChunk(cache, 0, 0) {
|
|
t.Fatal("ticketed chunk was evicted")
|
|
}
|
|
if got := cache.Stats().Tickets; got != 1 {
|
|
t.Fatalf("ticket count = %d, want 1", got)
|
|
}
|
|
|
|
tickets.Close()
|
|
if got := cache.Stats(); got.Tickets != 0 || got.Chunks > 2 {
|
|
t.Fatalf("after release stats = %+v, want no tickets and <=2 chunks", got)
|
|
}
|
|
}
|
|
|
|
func TestOverlappingTicketSetsRequireFinalRelease(t *testing.T) {
|
|
cache := NewCacheWithLimit(-1, func(cx, cz int32) *Chunk {
|
|
return NewChunk(cx, cz, BiomePlains)
|
|
}, nil, 1)
|
|
first, second := cache.NewTicketSet(), cache.NewTicketSet()
|
|
pos := []ChunkPos{{X: 0, Z: 0}}
|
|
first.Replace(pos, nil)
|
|
second.Replace(nil, pos)
|
|
if _, err := cache.FrameErr(0, 0); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
first.Close()
|
|
if got := cache.Stats().Tickets; got != 1 {
|
|
t.Fatalf("tickets after first close = %d, want 1", got)
|
|
}
|
|
if _, err := cache.FrameErr(1, 0); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !hasChunk(cache, 0, 0) {
|
|
t.Fatal("chunk was evicted while second owner still held it")
|
|
}
|
|
|
|
second.Close()
|
|
second.Close() // idempotent
|
|
if got := cache.Stats(); got.Tickets != 0 || got.Chunks > 1 {
|
|
t.Fatalf("after final close stats = %+v", got)
|
|
}
|
|
}
|
|
|
|
func TestFrameAdmissionCanBeCancelled(t *testing.T) {
|
|
cache := NewCache(-1, func(cx, cz int32) *Chunk {
|
|
return NewChunk(cx, cz, BiomePlains)
|
|
})
|
|
for i := 0; i < cap(cache.frameSlots); i++ {
|
|
cache.frameSlots <- struct{}{}
|
|
}
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
cancel()
|
|
_, err := cache.FrameErrContext(ctx, 0, 0)
|
|
if !errors.Is(err, context.Canceled) {
|
|
t.Fatalf("FrameErrContext error = %v, want context.Canceled", err)
|
|
}
|
|
for i := 0; i < cap(cache.frameSlots); i++ {
|
|
<-cache.frameSlots
|
|
}
|
|
}
|