Files
pixa/internal/imgcache/cache_internal_test.go
T
clawbot 078bae74a5
check / check (push) Waiting to run
Split internal/imgcache into the image proxy and the cache (closes #317)
The new package internal/imageproxy holds Proxy, which was imgcache.Service,
with its Config, ImageResponse, CacheStatus and errors. internal/imgcache holds
the cache only, and imgcache.CacheConfig is imgcache.Config. The cache reads
and writes each kind it keeps with one pair of methods: Variant and PutVariant,
Source and PutSource, Failure and PutFailure. Source replaces LookupSource
followed by GetSourceContent. imgcache.go and module.go are gone. The proxy's
tests moved with it. They reach the cache through its database, its state
directory and its metrics registry, and run its reconciliation pass with a
second cache, as pixad does at startup.

Model: opus-5-5
2026-10-26 15:56:47 +00:00

129 lines
2.7 KiB
Go

package imgcache
import (
"context"
"database/sql"
"os"
"testing"
"time"
"github.com/prometheus/client_golang/prometheus"
_ "modernc.org/sqlite"
)
func setupTestDB(t *testing.T) *sql.DB {
t.Helper()
db, err := sql.Open("sqlite", ":memory:")
if err != nil {
t.Fatalf("failed to open test db: %v", err)
}
// Create schema
schema := `
CREATE TABLE source_content (
source_key TEXT PRIMARY KEY,
size_bytes INTEGER NOT NULL,
last_accessed_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE negative_cache (
id INTEGER PRIMARY KEY AUTOINCREMENT,
source_host TEXT NOT NULL,
source_path TEXT NOT NULL,
source_query TEXT NOT NULL DEFAULT '',
expires_at DATETIME NOT NULL,
UNIQUE(source_host, source_path, source_query)
);
`
_, err = db.ExecContext(t.Context(), schema)
if err != nil {
t.Fatalf("failed to create schema: %v", err)
}
return db
}
func TestCache_CleanExpired(t *testing.T) {
t.Parallel()
tmpDir := t.TempDir()
db := setupTestDB(t)
cache, _ := NewCache(db, Config{
StateDir: tmpDir,
NegativeTTL: 1 * time.Millisecond,
MaxBytes: 1 << 30,
}, prometheus.NewRegistry())
ctx := context.Background()
// Insert expired negative cache entry directly
_, err := db.ExecContext(ctx, `
INSERT INTO negative_cache
(source_host, source_path, source_query, expires_at)
VALUES ('example.com', '/old.jpg', '', datetime('now', '-1 hour'))
`)
if err != nil {
t.Fatalf("failed to insert test data: %v", err)
}
// Verify it exists
var count int
err = db.QueryRowContext(ctx, `SELECT COUNT(*) FROM negative_cache`).Scan(&count)
if err != nil {
t.Fatalf("failed to count negative cache entries: %v", err)
}
if count != 1 {
t.Fatalf("expected 1 negative cache entry, got %d", count)
}
// Clean expired
err = cache.CleanExpired(ctx)
if err != nil {
t.Fatalf("CleanExpired() error = %v", err)
}
// Verify it's gone
err = db.QueryRowContext(ctx, `SELECT COUNT(*) FROM negative_cache`).Scan(&count)
if err != nil {
t.Fatalf("failed to count negative cache entries: %v", err)
}
if count != 0 {
t.Errorf("expected 0 negative cache entries after clean, got %d", count)
}
}
func TestCache_StorageDirectoriesCreated(t *testing.T) {
t.Parallel()
tmpDir := t.TempDir()
db := setupTestDB(t)
_, err := NewCache(db, Config{
StateDir: tmpDir,
MaxBytes: 1 << 30,
}, prometheus.NewRegistry())
if err != nil {
t.Fatalf("NewCache() error = %v", err)
}
// Verify directories were created
dirs := []string{
"cache/sources",
"cache/variants",
}
for _, dir := range dirs {
path := tmpDir + "/" + dir
_, err := os.Stat(path)
if os.IsNotExist(err) {
t.Errorf("directory %s was not created", dir)
}
}
}