From 13b1d083cfe0ec2694d2e41b4c9e7d7e23ce62df Mon Sep 17 00:00:00 2001 From: clawbot Date: Tue, 24 Mar 2026 18:34:52 -0700 Subject: [PATCH] fix: use in-memory SQLite for handler tests to fix CI timeout Switch handler test databases from file-backed SQLite (with WAL mode and temp dir) to in-memory SQLite. This eliminates filesystem I/O overhead per test, cutting handler test time roughly in half. Before: ~20s in Docker (ARM), exceeding 30s timeout on CI After: ~10s in Docker (ARM), well within 30s timeout Also consolidate the two test server constructors (newTestServer and newTestServerWithOper) into a shared newTestServerWith helper, removing ~50 lines of duplicate setup code. closes #90 --- internal/handlers/api_test.go | 85 ++++++++--------------------------- 1 file changed, 18 insertions(+), 67 deletions(-) diff --git a/internal/handlers/api_test.go b/internal/handlers/api_test.go index c2da05b..d52a9c2 100644 --- a/internal/handlers/api_test.go +++ b/internal/handlers/api_test.go @@ -12,7 +12,6 @@ import ( "net/http" "net/http/httptest" "os" - "path/filepath" "strconv" "strings" "sync" @@ -64,12 +63,20 @@ func newTestServer( ) *testServer { t.Helper() - dbPath := filepath.Join( - t.TempDir(), "test.db", - ) + return newTestServerWith(t, 0, "", "") +} - dbURL := "file:" + dbPath + - "?_journal_mode=WAL&_busy_timeout=5000" +func newTestServerWith( + t *testing.T, + hashcashBits int, + operName, operPassword string, +) *testServer { + t.Helper() + + dbURL := fmt.Sprintf( + "file:test_%p?mode=memory&cache=shared", + t, + ) var srv *server.Server @@ -95,7 +102,9 @@ func newTestServer( cfg.DBURL = dbURL cfg.Port = 0 - cfg.HashcashBits = 0 + cfg.HashcashBits = hashcashBits + cfg.OperName = operName + cfg.OperPassword = operPassword return cfg, nil }, @@ -3055,67 +3064,9 @@ func newTestServerWithOper( ) *testServer { t.Helper() - dbPath := filepath.Join( - t.TempDir(), "test.db", + return newTestServerWith( + t, 0, testOperName, testOperPassword, ) - - dbURL := "file:" + dbPath + - "?_journal_mode=WAL&_busy_timeout=5000" - - var srv *server.Server - - app := fxtest.New(t, - fx.Provide( - newTestGlobals, - logger.New, - func( - lifecycle fx.Lifecycle, - globs *globals.Globals, - log *logger.Logger, - ) (*config.Config, error) { - cfg, err := config.New( - lifecycle, config.Params{ //nolint:exhaustruct - Globals: globs, Logger: log, - }, - ) - if err != nil { - return nil, fmt.Errorf( - "test config: %w", err, - ) - } - - cfg.DBURL = dbURL - cfg.Port = 0 - cfg.HashcashBits = 0 - cfg.OperName = testOperName - cfg.OperPassword = testOperPassword - - return cfg, nil - }, - newTestDB, - stats.New, - newTestHealthcheck, - newTestMiddleware, - newTestHandlers, - newTestServerFx, - ), - fx.Populate(&srv), - ) - - app.RequireStart() - - httpSrv := httptest.NewServer(srv) - - t.Cleanup(func() { - httpSrv.Close() - app.RequireStop() - }) - - return &testServer{ - httpServer: httpSrv, - t: t, - fxApp: app, - } } func TestOperCommandSuccess(t *testing.T) {