check / check (push) Failing after 1s
The default cache_max_bytes was 75% of the space free at startup. The cache's own files are not free space, so a fuller cache got a smaller limit after a restart and eviction then deleted most of it. The default is now 75% of the sum of the free space and what the cache already holds by its own size accounting, at least 500 MiB. The cache works it out when it opens, after the database is open, so the computation and its tests moved from internal/config to internal/imgcache. The config only records whether cache_max_bytes was set; newCacheConfig in the handlers turns the disk cache off only for an explicit 0, and is tested for an omitted, a zero and a positive value. Model: opus-5-5
148 lines
4.0 KiB
Go
148 lines
4.0 KiB
Go
package handlers
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"go.uber.org/fx/fxtest"
|
|
|
|
"sneak.berlin/go/pixa/internal/config"
|
|
"sneak.berlin/go/pixa/internal/database"
|
|
"sneak.berlin/go/pixa/internal/globals"
|
|
"sneak.berlin/go/pixa/internal/logger"
|
|
)
|
|
|
|
// TestNewCacheConfigFromCacheMaxBytes checks the cache configuration
|
|
// built from cache_max_bytes: omitted, the cache works out the default
|
|
// limit; 0 turns the disk cache off; a positive value is the limit,
|
|
// unchanged.
|
|
func TestNewCacheConfigFromCacheMaxBytes(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
const oneGiB = 1 << 30
|
|
|
|
cases := []struct {
|
|
name string
|
|
cacheMaxBytes int64
|
|
cacheMaxBytesExplicit bool
|
|
wantMaxBytes int64
|
|
wantUseDefaultMaxBytes bool
|
|
wantDisableDiskCache bool
|
|
}{
|
|
{
|
|
name: "cache_max_bytes omitted",
|
|
cacheMaxBytes: 0,
|
|
cacheMaxBytesExplicit: false,
|
|
wantMaxBytes: 0,
|
|
wantUseDefaultMaxBytes: true,
|
|
wantDisableDiskCache: false,
|
|
},
|
|
{
|
|
name: "cache_max_bytes: 0",
|
|
cacheMaxBytes: 0,
|
|
cacheMaxBytesExplicit: true,
|
|
wantMaxBytes: 0,
|
|
wantUseDefaultMaxBytes: false,
|
|
wantDisableDiskCache: true,
|
|
},
|
|
{
|
|
name: "cache_max_bytes: 1 GiB",
|
|
cacheMaxBytes: oneGiB,
|
|
cacheMaxBytesExplicit: true,
|
|
wantMaxBytes: oneGiB,
|
|
wantUseDefaultMaxBytes: false,
|
|
wantDisableDiskCache: false,
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
cfg := &config.Config{
|
|
CacheMaxBytes: tc.cacheMaxBytes,
|
|
CacheMaxBytesExplicit: tc.cacheMaxBytesExplicit,
|
|
}
|
|
|
|
got := newCacheConfig(cfg, nil)
|
|
t.Logf("MaxBytes = %d, UseDefaultMaxBytes = %v, DisableDiskCache = %v",
|
|
got.MaxBytes, got.UseDefaultMaxBytes, got.DisableDiskCache)
|
|
|
|
if got.MaxBytes != tc.wantMaxBytes {
|
|
t.Errorf("MaxBytes = %d, want %d", got.MaxBytes, tc.wantMaxBytes)
|
|
}
|
|
|
|
if got.UseDefaultMaxBytes != tc.wantUseDefaultMaxBytes {
|
|
t.Errorf("UseDefaultMaxBytes = %v, want %v",
|
|
got.UseDefaultMaxBytes, tc.wantUseDefaultMaxBytes)
|
|
}
|
|
|
|
if got.DisableDiskCache != tc.wantDisableDiskCache {
|
|
t.Errorf("DisableDiskCache = %v, want %v",
|
|
got.DisableDiskCache, tc.wantDisableDiskCache)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestDiskCacheOffOnlyForExplicitZeroCacheMaxBytes starts the handlers
|
|
// once with cache_max_bytes omitted and once with cache_max_bytes: 0,
|
|
// and checks by whether the cache directories were created that the
|
|
// disk cache is on in the first case and off in the second.
|
|
func TestDiskCacheOffOnlyForExplicitZeroCacheMaxBytes(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
cases := []struct {
|
|
name string
|
|
cacheMaxBytesExplicit bool
|
|
wantDiskCache bool
|
|
}{
|
|
{name: "cache_max_bytes omitted", cacheMaxBytesExplicit: false, wantDiskCache: true},
|
|
{name: "cache_max_bytes: 0", cacheMaxBytesExplicit: true, wantDiskCache: false},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
stateDir := t.TempDir()
|
|
cfg := &config.Config{
|
|
SigningKey: testSigningKey,
|
|
StateDir: stateDir,
|
|
DBURL: "file:" + filepath.Join(stateDir, "state.sqlite3"),
|
|
CacheMaxBytes: 0,
|
|
CacheMaxBytesExplicit: tc.cacheMaxBytesExplicit,
|
|
}
|
|
|
|
lc := fxtest.NewLifecycle(t)
|
|
|
|
log, err := logger.New(lc, logger.Params{Globals: &globals.Globals{}})
|
|
if err != nil {
|
|
t.Fatalf("logger.New() error = %v", err)
|
|
}
|
|
|
|
db, err := database.New(lc, database.Params{Logger: log, Config: cfg})
|
|
if err != nil {
|
|
t.Fatalf("database.New() error = %v", err)
|
|
}
|
|
|
|
_, err = New(lc, Params{Logger: log, Database: db, Config: cfg})
|
|
if err != nil {
|
|
t.Fatalf("New() error = %v", err)
|
|
}
|
|
|
|
lc.RequireStart()
|
|
t.Cleanup(lc.RequireStop)
|
|
|
|
_, err = os.Stat(filepath.Join(stateDir, "cache", "variants"))
|
|
gotDiskCache := err == nil
|
|
|
|
if gotDiskCache != tc.wantDiskCache {
|
|
t.Errorf("cache directories created = %v, want %v",
|
|
gotDiskCache, tc.wantDiskCache)
|
|
}
|
|
})
|
|
}
|
|
}
|