mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-08-29 04:06:58 +00:00
84 lines
2.1 KiB
Go
84 lines
2.1 KiB
Go
package pds
|
|
|
|
import (
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestJTIReplayCache_FirstSeenAccepted(t *testing.T) {
|
|
c := newJTIReplayCache()
|
|
if c.Seen("a", time.Now().Add(time.Minute)) {
|
|
t.Fatal("first observation of jti reported as replay")
|
|
}
|
|
}
|
|
|
|
func TestJTIReplayCache_DuplicateRejected(t *testing.T) {
|
|
c := newJTIReplayCache()
|
|
exp := time.Now().Add(time.Minute)
|
|
_ = c.Seen("dup", exp)
|
|
if !c.Seen("dup", exp) {
|
|
t.Error("second observation of same jti not flagged as replay")
|
|
}
|
|
}
|
|
|
|
func TestJTIReplayCache_DistinctJTIsAccepted(t *testing.T) {
|
|
c := newJTIReplayCache()
|
|
exp := time.Now().Add(time.Minute)
|
|
if c.Seen("a", exp) || c.Seen("b", exp) {
|
|
t.Error("distinct jtis should both be accepted")
|
|
}
|
|
}
|
|
|
|
func TestJTIReplayCache_ExpiredEntryReusable(t *testing.T) {
|
|
c := newJTIReplayCache()
|
|
now := time.Unix(1_000_000, 0)
|
|
c.clock = func() time.Time { return now }
|
|
|
|
if c.Seen("a", now.Add(time.Second)) {
|
|
t.Fatal("first seen flagged as replay")
|
|
}
|
|
// advance past expiration
|
|
now = now.Add(2 * time.Second)
|
|
if c.Seen("a", now.Add(time.Second)) {
|
|
t.Error("after exp, jti should be reusable (entry evicted)")
|
|
}
|
|
}
|
|
|
|
func TestJTIReplayCache_DoesNotGrowUnbounded(t *testing.T) {
|
|
c := newJTIReplayCache()
|
|
now := time.Unix(1_000_000, 0)
|
|
c.clock = func() time.Time { return now }
|
|
|
|
for i := range 1024 {
|
|
_ = c.Seen(string(rune('A'+i%64))+string(rune('0'+i/64)), now.Add(time.Second))
|
|
}
|
|
// Jump past all expirations.
|
|
now = now.Add(time.Hour)
|
|
// One more insert triggers a sweep at the 64-multiple boundary.
|
|
for range 200 {
|
|
_ = c.Seen("trigger-"+time.Now().String(), now.Add(time.Second))
|
|
}
|
|
if got := c.size(); got > 300 {
|
|
t.Errorf("cache size after eviction = %d, expected sweep to drop expired entries", got)
|
|
}
|
|
}
|
|
|
|
func TestJTIReplayCache_ConcurrentSafe(t *testing.T) {
|
|
c := newJTIReplayCache()
|
|
exp := time.Now().Add(time.Minute)
|
|
var wg sync.WaitGroup
|
|
for i := range 32 {
|
|
wg.Add(1)
|
|
go func(n int) {
|
|
defer wg.Done()
|
|
c.Seen("concurrent", exp)
|
|
c.Seen(string(rune(n)), exp)
|
|
}(i)
|
|
}
|
|
wg.Wait()
|
|
if c.size() == 0 {
|
|
t.Error("expected entries after concurrent inserts")
|
|
}
|
|
}
|