Files
pixa/internal/imgcache/negative_cache_internal_test.go
T
clawbot 04b5db6fbf
check / check (push) Failing after 0s
next -> main (1.0.0 milestone) (#105)
Accumulating milestone branch. One squashed commit per closed issue; `next` is kept green and mergeable to `main` at any time without notice.

Landed so far:

- `chore: update golangci-lint to v2.12.2 with canonical config` (#54) — canonical v2-schema `.golangci.yml`, pins bumped in `Dockerfile` and `script/bootstrap`, tree at `0 issues.`. Three behaviour deltas are recorded in that PR's body: `Cache.StoreVariant` takes a context, `MetadataStorage.Store` no longer leaks temp files on failure, and the `signing_key` too-short error text gained a `value too short:` prefix.

Sequencing for the milestone is tracked in #103.

Reviewed-on: #105
Co-authored-by: clawbot <clawbot@noreply.example.org>
2026-09-21 09:31:54 +02:00

110 lines
2.1 KiB
Go

package imgcache
import (
"context"
"errors"
"testing"
"time"
)
func TestNegativeCache_StoreAndCheck(t *testing.T) {
t.Parallel()
db := setupTestDB(t)
dir := t.TempDir()
cache, err := NewCache(db, CacheConfig{
StateDir: dir,
CacheTTL: time.Hour,
NegativeTTL: 5 * time.Minute,
})
if err != nil {
t.Fatal(err)
}
ctx := context.Background()
req := &ImageRequest{
SourceHost: testHostExample,
SourcePath: "/missing.jpg",
}
// Initially should not be in negative cache
hit, err := cache.checkNegativeCache(ctx, req)
if err != nil {
t.Fatal(err)
}
if hit {
t.Error("expected no negative cache hit initially")
}
// Store a negative entry
err = cache.StoreNegative(ctx, req, 404, "not found")
if err != nil {
t.Fatal(err)
}
// Now should be in negative cache
hit, err = cache.checkNegativeCache(ctx, req)
if err != nil {
t.Fatal(err)
}
if !hit {
t.Error("expected negative cache hit after storing")
}
}
func TestNegativeCache_Expired(t *testing.T) {
t.Parallel()
db := setupTestDB(t)
dir := t.TempDir()
cache, err := NewCache(db, CacheConfig{
StateDir: dir,
CacheTTL: time.Hour,
NegativeTTL: 1 * time.Millisecond, // very short TTL
})
if err != nil {
t.Fatal(err)
}
ctx := context.Background()
req := &ImageRequest{
SourceHost: testHostExample,
SourcePath: "/expired.jpg",
}
// Store a negative entry with very short TTL
err = cache.StoreNegative(ctx, req, 500, "server error")
if err != nil {
t.Fatal(err)
}
// Wait for expiry
time.Sleep(10 * time.Millisecond)
// Should no longer be in negative cache
hit, err := cache.checkNegativeCache(ctx, req)
if err != nil {
t.Fatal(err)
}
if hit {
t.Error("expected expired negative cache entry to be a miss")
}
}
func TestService_Get_ReturnsErrorForNegativeCachedURL(t *testing.T) {
t.Parallel()
// This test verifies that Service.Get() checks the negative cache
// We can't easily test the full pipeline without vips, but we can
// verify the error type
err := ErrNegativeCached
if !errors.Is(err, ErrNegativeCached) {
t.Error("ErrNegativeCached should be identifiable with errors.Is")
}
}