Test the eviction, source cache, upstream and transform metrics
The tests check the metrics on a variant hit, on misses that fetch or use the cached source, on a failed fetch, and on both kinds of eviction. They fail until the metrics exist. Model: opus-5-5
This commit is contained in:
1 parent
e34463acf8
commit
fe5bf393b1
2 files changed
+249
No files matched your search
@@ -0,0 +1,112 @@
|
||||
package imageproxy
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"sneak.berlin/go/pixa/internal/imagerequest"
|
||||
)
|
||||
|
||||
// metricValues holds the metrics of a proxy and its cache that
|
||||
// TestProxy_Get_CountsSourceCacheFetchesAndTransforms checks. A histogram
|
||||
// is given by its count of observations.
|
||||
type metricValues struct {
|
||||
sourceCacheHits uint64
|
||||
sourceCacheMisses uint64
|
||||
fetchDurations uint64
|
||||
fetchErrors uint64
|
||||
transformDuration uint64
|
||||
inProgress float64
|
||||
}
|
||||
|
||||
// readMetricValues reads the metrics of svc and its cache that
|
||||
// metricValues holds from their metrics registry.
|
||||
func readMetricValues(t *testing.T, svc *testProxy) metricValues {
|
||||
t.Helper()
|
||||
|
||||
families, err := svc.registry.Gather()
|
||||
if err != nil {
|
||||
t.Fatalf("failed to gather the metrics: %v", err)
|
||||
}
|
||||
|
||||
var values metricValues
|
||||
|
||||
for _, family := range families {
|
||||
metric := family.GetMetric()[0]
|
||||
|
||||
switch family.GetName() {
|
||||
case "pixa_source_cache_hits_total":
|
||||
values.sourceCacheHits = uint64(metric.GetCounter().GetValue())
|
||||
case "pixa_source_cache_misses_total":
|
||||
values.sourceCacheMisses = uint64(metric.GetCounter().GetValue())
|
||||
case "pixa_upstream_fetch_duration_seconds":
|
||||
values.fetchDurations = metric.GetHistogram().GetSampleCount()
|
||||
case "pixa_upstream_fetch_errors_total":
|
||||
values.fetchErrors = uint64(metric.GetCounter().GetValue())
|
||||
case "pixa_transform_duration_seconds":
|
||||
values.transformDuration = metric.GetHistogram().GetSampleCount()
|
||||
case "pixa_transforms_in_progress":
|
||||
values.inProgress = metric.GetGauge().GetValue()
|
||||
}
|
||||
}
|
||||
|
||||
return values
|
||||
}
|
||||
|
||||
// TestProxy_Get_CountsSourceCacheFetchesAndTransforms walks Get through a
|
||||
// miss that fetches the source, a hit, a miss that uses the cached source
|
||||
// and a miss whose source is not found upstream, checking the source cache,
|
||||
// upstream fetch and transform metrics after each.
|
||||
func TestProxy_Get_CountsSourceCacheFetchesAndTransforms(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
svc, fixtures := setupTestProxy(t)
|
||||
|
||||
// want is source cache hits, source cache misses, fetch durations
|
||||
// observed, fetch errors, transform durations observed, transforms in
|
||||
// progress.
|
||||
steps := []struct {
|
||||
name string
|
||||
path string
|
||||
size int
|
||||
wantErr bool
|
||||
want metricValues
|
||||
}{
|
||||
{"miss that fetches the source", testPathPhoto, 50, false,
|
||||
metricValues{0, 1, 1, 0, 1, 0}},
|
||||
{"hit", testPathPhoto, 50, false,
|
||||
metricValues{0, 1, 1, 0, 1, 0}},
|
||||
{"miss that uses the cached source", testPathPhoto, 25, false,
|
||||
metricValues{1, 1, 1, 0, 2, 0}},
|
||||
{"miss whose source is not found", "/images/absent.jpg", 50, true,
|
||||
metricValues{1, 2, 1, 1, 2, 0}},
|
||||
}
|
||||
|
||||
for _, step := range steps {
|
||||
resp, err := svc.Get(t.Context(), &imagerequest.Request{
|
||||
Source: imagerequest.Source{
|
||||
Host: fixtures.GoodHost,
|
||||
Path: step.path,
|
||||
},
|
||||
Transform: imagerequest.Transform{
|
||||
Size: imagerequest.Size{Width: step.size, Height: step.size},
|
||||
Format: imagerequest.FormatJPEG,
|
||||
Quality: 85,
|
||||
FitMode: imagerequest.FitCover,
|
||||
},
|
||||
})
|
||||
if (err != nil) != step.wantErr {
|
||||
t.Fatalf("%s: Get() error = %v, want error %t", step.name, err, step.wantErr)
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
_ = resp.Content.Close()
|
||||
}
|
||||
|
||||
got := readMetricValues(t, svc)
|
||||
t.Logf("after the %s: metrics = %+v", step.name, got)
|
||||
|
||||
if got != step.want {
|
||||
t.Fatalf("after the %s: metrics = %+v, want %+v", step.name, got, step.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user