e6e3f297d6
- dbtest.ResetDB.dataTables now truncates lidarr_quarantine + lidarr_quarantine_actions alongside the other M2-M4 data tables. Without this, M5b service tests would inherit residual state across runs. - DeleteTrackFile godoc spells out the post-file/pre-DB failure window reconciles via the next library scan; the function is retry-safe by design, not atomic.
76 lines
2.5 KiB
Go
76 lines
2.5 KiB
Go
// Package dbtest provides shared helpers for integration tests that need
|
|
// a clean Postgres state without disturbing the operator's admin user.
|
|
//
|
|
// Background: when integration tests run against the same Postgres
|
|
// instance an operator uses for local dev (a common dev-laptop setup),
|
|
// a TRUNCATE that includes the users table wipes the operator's admin
|
|
// login between every test run. To avoid that, tests should:
|
|
//
|
|
// 1. Call ResetDB instead of issuing TRUNCATE statements directly. It
|
|
// truncates every data table EXCEPT users, then deletes only those
|
|
// users whose username starts with TestUserPrefix.
|
|
// 2. Always create test user rows with a username that begins with
|
|
// TestUserPrefix; otherwise those rows survive across runs and
|
|
// leak into other tests.
|
|
//
|
|
// One test legitimately needs to wipe the entire users table:
|
|
// internal/auth/bootstrap_test.go, which exercises first-time admin
|
|
// bootstrap. That file does its own TRUNCATE and does not use this
|
|
// helper.
|
|
package dbtest
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
// TestUserPrefix is the required username prefix for any user row
|
|
// created by an integration test. ResetDB removes every user matching
|
|
// this prefix and leaves all others intact.
|
|
const TestUserPrefix = "test-"
|
|
|
|
// dataTables is the union of every non-users table touched by any
|
|
// integration test in the repo. Truncating the union is harmless for
|
|
// callers that only care about a subset; truncating tables that don't
|
|
// exist would error, but every name here corresponds to a migration
|
|
// that has shipped.
|
|
var dataTables = []string{
|
|
"artist_similarity",
|
|
"track_similarity",
|
|
"scrobble_queue",
|
|
"contextual_likes",
|
|
"general_likes_albums",
|
|
"general_likes_artists",
|
|
"general_likes",
|
|
"play_events",
|
|
"skip_events",
|
|
"play_sessions",
|
|
"sessions",
|
|
"lidarr_quarantine_actions",
|
|
"lidarr_quarantine",
|
|
"tracks",
|
|
"albums",
|
|
"artists",
|
|
}
|
|
|
|
// ResetDB clears all data tables and removes any user whose username
|
|
// begins with TestUserPrefix. Users without that prefix (notably the
|
|
// operator's admin row) are left alone. Calls t.Fatalf on error.
|
|
func ResetDB(t *testing.T, pool *pgxpool.Pool) {
|
|
t.Helper()
|
|
ctx := context.Background()
|
|
stmt := "TRUNCATE " + strings.Join(dataTables, ", ") + " RESTART IDENTITY CASCADE"
|
|
if _, err := pool.Exec(ctx, stmt); err != nil {
|
|
t.Fatalf("dbtest.ResetDB truncate: %v", err)
|
|
}
|
|
if _, err := pool.Exec(ctx,
|
|
"DELETE FROM users WHERE username LIKE $1",
|
|
TestUserPrefix+"%",
|
|
); err != nil {
|
|
t.Fatalf("dbtest.ResetDB delete test users: %v", err)
|
|
}
|
|
}
|