diff --git a/internal/imgcache/negative_cache_internal_test.go b/internal/imgcache/negative_cache_internal_test.go index 3f7c9c2..a2fa4d3 100644 --- a/internal/imgcache/negative_cache_internal_test.go +++ b/internal/imgcache/negative_cache_internal_test.go @@ -241,6 +241,37 @@ func TestCleanExpiredDeletesInBatches(t *testing.T) { } } +// TestCleanExpiredRemovesMoreThanOneBatch stores one expired negative +// cache row more than one batch holds and calls CleanExpired once: it +// must remove them all, so it fails if CleanExpired stops after its +// first batch. +func TestCleanExpiredRemovesMoreThanOneBatch(t *testing.T) { + t.Parallel() + + cache, err := NewCache(evictionTestDB(t), CacheConfig{StateDir: t.TempDir()}) + if err != nil { + t.Fatalf("failed to create cache: %v", err) + } + + insertExpiredNegativeCacheRows(t, cache, cleanExpiredBatchSize+1) + + before := negativeCacheTableRowCount(t, cache) + + err = cache.CleanExpired(t.Context()) + if err != nil { + t.Fatalf("CleanExpired failed: %v", err) + } + + after := negativeCacheTableRowCount(t, cache) + + t.Logf("CleanExpired removed %d of %d expired rows, %d per batch", + before-after, before, cleanExpiredBatchSize) + + if after != 0 { + t.Errorf("negative_cache holds %d rows after CleanExpired, want 0", after) + } +} + // TestCleanExpiredStopsOnceContextEnds runs CleanExpired with a context // that has already ended: it must return the context's error and delete // no row.