The new package internal/imagerequest holds the request type, its two parts Source and Transform, the Format and Fit types, the dimension and fit checks, the /v1/image/ path parsing and the variant key; it imports no other package of pixa. imgcache.ParsedURL, imgcache.ImageRequest, signature.Request, imageprocessor.Request, the second Size, format and fit types and the conversions between them are gone. The image processor takes a Transform only. encurl keeps a private struct with the token's CBOR field names, so tokens made before still decode. VariantKey moves with the function that makes it. Tests follow the moved and renamed code; the tests of the removed conversions go with them. Model: opus-5-5
This commit is contained in:
@@ -16,6 +16,7 @@ import (
|
||||
_ "modernc.org/sqlite"
|
||||
"sneak.berlin/go/pixa/internal/database"
|
||||
"sneak.berlin/go/pixa/internal/httpfetcher"
|
||||
"sneak.berlin/go/pixa/internal/imagerequest"
|
||||
)
|
||||
|
||||
// sqliteTimestampFormat matches the format SQLite's CURRENT_TIMESTAMP
|
||||
@@ -27,10 +28,10 @@ const sqliteTimestampFormat = "2006-01-02 15:04:05"
|
||||
// keys reused across the eviction tests, in the order the tests store
|
||||
// them.
|
||||
const (
|
||||
testVariantKeyOne VariantKey = "aabbccdd0001"
|
||||
testVariantKeyTwo VariantKey = "aabbccdd0002"
|
||||
testVariantKeyThree VariantKey = "aabbccdd0003"
|
||||
testVariantKeyFour VariantKey = "aabbccdd0004"
|
||||
testVariantKeyOne imagerequest.VariantKey = "aabbccdd0001"
|
||||
testVariantKeyTwo imagerequest.VariantKey = "aabbccdd0002"
|
||||
testVariantKeyThree imagerequest.VariantKey = "aabbccdd0003"
|
||||
testVariantKeyFour imagerequest.VariantKey = "aabbccdd0004"
|
||||
)
|
||||
|
||||
// evictionTestDB creates an in-memory SQLite database with the real
|
||||
@@ -88,12 +89,16 @@ func storeEvictionTestSource(
|
||||
) ContentHash {
|
||||
t.Helper()
|
||||
|
||||
req := &ImageRequest{
|
||||
SourceHost: host,
|
||||
SourcePath: path,
|
||||
Format: FormatJPEG,
|
||||
Quality: 85,
|
||||
FitMode: FitCover,
|
||||
req := &imagerequest.Request{
|
||||
Source: imagerequest.Source{
|
||||
Host: host,
|
||||
Path: path,
|
||||
},
|
||||
Transform: imagerequest.Transform{
|
||||
Format: imagerequest.FormatJPEG,
|
||||
Quality: 85,
|
||||
FitMode: imagerequest.FitCover,
|
||||
},
|
||||
}
|
||||
|
||||
result := &httpfetcher.FetchResult{
|
||||
@@ -118,7 +123,7 @@ func storeEvictionTestSource(
|
||||
// storeEvictionTestVariant stores content as a processed variant under
|
||||
// the given cache key.
|
||||
func storeEvictionTestVariant(
|
||||
t *testing.T, cache *Cache, key VariantKey, content []byte,
|
||||
t *testing.T, cache *Cache, key imagerequest.VariantKey, content []byte,
|
||||
) {
|
||||
t.Helper()
|
||||
|
||||
@@ -131,7 +136,7 @@ func storeEvictionTestVariant(
|
||||
// setVariantLastAccessed backdates the last access time of a tracked
|
||||
// variant, to make LRU ordering deterministic in tests.
|
||||
func setVariantLastAccessed(
|
||||
t *testing.T, cache *Cache, key VariantKey, when time.Time,
|
||||
t *testing.T, cache *Cache, key imagerequest.VariantKey, when time.Time,
|
||||
) {
|
||||
t.Helper()
|
||||
|
||||
@@ -244,7 +249,7 @@ func assertNoDanglingReferences(t *testing.T, cache *Cache) {
|
||||
t.Fatalf("failed to scan cache_key: %v", err)
|
||||
}
|
||||
|
||||
if !cache.variants.Exists(VariantKey(key)) {
|
||||
if !cache.variants.Exists(imagerequest.VariantKey(key)) {
|
||||
t.Errorf("variant_content references key %s but the file is missing", key)
|
||||
}
|
||||
}
|
||||
@@ -343,7 +348,7 @@ func TestEvictToLimitEvictsLeastRecentlyUsedFirst(t *testing.T) {
|
||||
cache, _ := newEvictionTestCache(t, limit)
|
||||
|
||||
now := time.Now()
|
||||
keys := []VariantKey{
|
||||
keys := []imagerequest.VariantKey{
|
||||
testVariantKeyOne, testVariantKeyTwo,
|
||||
testVariantKeyThree, testVariantKeyFour,
|
||||
}
|
||||
@@ -516,12 +521,16 @@ func TestZeroMaxBytesDisablesDiskCache(t *testing.T) {
|
||||
|
||||
cache, tmpDir := newEvictionTestCache(t, 0)
|
||||
|
||||
req := &ImageRequest{
|
||||
SourceHost: "src.example.com",
|
||||
SourcePath: "/a.jpg",
|
||||
Format: FormatJPEG,
|
||||
Quality: 85,
|
||||
FitMode: FitCover,
|
||||
req := &imagerequest.Request{
|
||||
Source: imagerequest.Source{
|
||||
Host: "src.example.com",
|
||||
Path: "/a.jpg",
|
||||
},
|
||||
Transform: imagerequest.Transform{
|
||||
Format: imagerequest.FormatJPEG,
|
||||
Quality: 85,
|
||||
FitMode: imagerequest.FitCover,
|
||||
},
|
||||
}
|
||||
|
||||
assertDisabledCacheWritesAreNoOps(t, cache, req)
|
||||
@@ -533,14 +542,14 @@ func TestZeroMaxBytesDisablesDiskCache(t *testing.T) {
|
||||
// assertDisabledCacheWritesAreNoOps verifies that stores against a
|
||||
// disabled cache report success without recording anything.
|
||||
func assertDisabledCacheWritesAreNoOps(
|
||||
t *testing.T, cache *Cache, req *ImageRequest,
|
||||
t *testing.T, cache *Cache, req *imagerequest.Request,
|
||||
) {
|
||||
t.Helper()
|
||||
|
||||
ctx := t.Context()
|
||||
|
||||
err := cache.StoreVariant(
|
||||
ctx, CacheKey(req), bytes.NewReader([]byte("data")), "image/webp",
|
||||
ctx, imagerequest.CacheKey(req), bytes.NewReader([]byte("data")), "image/webp",
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("StoreVariant on disabled cache must be a no-op, got error: %v", err)
|
||||
@@ -566,7 +575,7 @@ func assertDisabledCacheWritesAreNoOps(
|
||||
// assertDisabledCacheReadsAlwaysMiss verifies that lookups against a
|
||||
// disabled cache never report a hit.
|
||||
func assertDisabledCacheReadsAlwaysMiss(
|
||||
t *testing.T, cache *Cache, req *ImageRequest,
|
||||
t *testing.T, cache *Cache, req *imagerequest.Request,
|
||||
) {
|
||||
t.Helper()
|
||||
|
||||
@@ -661,7 +670,7 @@ func TestEvictionRunsUnderWritePressure(t *testing.T) {
|
||||
cache.StartEviction(time.Hour)
|
||||
defer func() { _ = cache.StopEviction(t.Context()) }()
|
||||
|
||||
keys := []VariantKey{
|
||||
keys := []imagerequest.VariantKey{
|
||||
testVariantKeyOne, testVariantKeyTwo, testVariantKeyThree,
|
||||
}
|
||||
fills := []byte{0x11, 0x12, 0x13}
|
||||
@@ -715,7 +724,7 @@ func TestEvictionRunsOnPeriodicSchedule(t *testing.T) {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
|
||||
keys := []VariantKey{
|
||||
keys := []imagerequest.VariantKey{
|
||||
testVariantKeyOne, testVariantKeyTwo, testVariantKeyThree,
|
||||
}
|
||||
fills := []byte{0x21, 0x22, 0x23}
|
||||
@@ -1308,9 +1317,11 @@ func TestEvictSourceBlobExcludesConcurrentStoreOfIdenticalContent(t *testing.T)
|
||||
|
||||
assertNoDanglingReferences(t, cache)
|
||||
|
||||
dupHash, _, err := cache.LookupSource(ctx, &ImageRequest{
|
||||
SourceHost: "race.example.com",
|
||||
SourcePath: "/dup.jpg",
|
||||
dupHash, _, err := cache.LookupSource(ctx, &imagerequest.Request{
|
||||
Source: imagerequest.Source{
|
||||
Host: "race.example.com",
|
||||
Path: "/dup.jpg",
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("LookupSource failed: %v", err)
|
||||
@@ -1336,12 +1347,16 @@ func storeIdenticalContentConcurrently(
|
||||
storeDone := make(chan error, 1)
|
||||
|
||||
go func() {
|
||||
req := &ImageRequest{
|
||||
SourceHost: "race.example.com",
|
||||
SourcePath: "/dup.jpg",
|
||||
Format: FormatJPEG,
|
||||
Quality: 85,
|
||||
FitMode: FitCover,
|
||||
req := &imagerequest.Request{
|
||||
Source: imagerequest.Source{
|
||||
Host: "race.example.com",
|
||||
Path: "/dup.jpg",
|
||||
},
|
||||
Transform: imagerequest.Transform{
|
||||
Format: imagerequest.FormatJPEG,
|
||||
Quality: 85,
|
||||
FitMode: imagerequest.FitCover,
|
||||
},
|
||||
}
|
||||
result := &httpfetcher.FetchResult{
|
||||
StatusCode: 200,
|
||||
|
||||
Reference in New Issue
Block a user