Files

69 lines
1.8 KiB
Go

package gc
import (
"testing"
"time"
)
// stubGate satisfies TakedownGate for tests so we can exercise the GC's
// reachability decisions without standing up a full labeler cache or PDS.
type stubGate struct {
uri string
cts time.Time
}
func (s stubGate) IsTakenDown(uri string) (time.Time, bool) {
if uri == s.uri {
return s.cts, true
}
return time.Time{}, false
}
func TestIsManifestTakenDown(t *testing.T) {
t.Run("nil gate", func(t *testing.T) {
gc := &GarbageCollector{}
if _, ok := gc.isManifestTakenDown("at://x"); ok {
t.Fatalf("nil gate should report no takedowns")
}
})
t.Run("matching uri", func(t *testing.T) {
cts := time.Now()
gc := &GarbageCollector{takedownGate: stubGate{uri: "at://x", cts: cts}}
got, ok := gc.isManifestTakenDown("at://x")
if !ok {
t.Fatalf("gate should report takedown for matching URI")
}
if !got.Equal(cts) {
t.Fatalf("cts = %v, want %v", got, cts)
}
})
t.Run("non-matching uri", func(t *testing.T) {
gc := &GarbageCollector{takedownGate: stubGate{uri: "at://x", cts: time.Now()}}
if _, ok := gc.isManifestTakenDown("at://y"); ok {
t.Fatalf("non-matching URI should not report takedown")
}
})
}
func TestTakedownExpired(t *testing.T) {
tests := []struct {
name string
cts time.Time
grace time.Duration
expired bool
}{
{"in-window", time.Now().Add(-time.Hour), 24 * time.Hour, false},
{"past-window", time.Now().Add(-48 * time.Hour), 24 * time.Hour, true},
{"zero grace expires immediately", time.Now(), 0, true},
{"negative grace expires immediately", time.Now(), -time.Hour, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gc := &GarbageCollector{takedownGrace: tt.grace}
if got := gc.takedownExpired(tt.cts); got != tt.expired {
t.Fatalf("takedownExpired = %v, want %v", got, tt.expired)
}
})
}
}