Pre-fix test suite documenting 9 database migration and schema integrity bugs. Tests FAIL where they assert correct post-fix behavior, PASS where they document current buggy state. Tests added: - F-B1-11 P0: main.go swallows migration errors (3 tests) - F-B1-13: Duplicate migration numbers 009/012 (2 tests) - F-B1-1: Migration 024 self-insert into schema_migrations (2 tests) - F-B1-2: Migration 024 references non-existent column (2 tests) - F-B1-3: Migration 018 wrong file suffix (2 tests) - F-B1-4: Migration 018 GRANT to wrong role (1 test) - F-B1-15: 7+ migrations not idempotent (2 tests) - F-B1-5: Missing agent_commands sent_at index (2 tests) - F-B1-6: N+1 query in GetDashboardStats (2 tests) - F-B1-10: No background refresh token cleanup (2 tests) Current state: 10 PASS, 10 FAIL, 0 SKIP. All A-series tests continue to pass (no regressions). See docs/B1_PreFix_Tests.md for full inventory. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
143 lines
5.1 KiB
Go
143 lines
5.1 KiB
Go
package migrations_test
|
|
|
|
// migration024_test.go — Pre-fix tests for migration 024 bugs.
|
|
//
|
|
// F-B1-1 CRITICAL: Migration 024 self-inserts into schema_migrations,
|
|
// causing duplicate key when the runner also inserts.
|
|
// 024_disable_updates_subsystem.up.sql:18-19
|
|
//
|
|
// F-B1-2 CRITICAL: Migration 024 references non-existent `deprecated`
|
|
// column on agent_subsystems. The column was never added.
|
|
//
|
|
// Run: cd aggregator-server && go test ./internal/database/migrations/... -v -run TestMigration024
|
|
|
|
import (
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Test 2.1 — Migration 024 contains self-insert (documents F-B1-1)
|
|
//
|
|
// Category: PASS-NOW (documents the bug)
|
|
// ---------------------------------------------------------------------------
|
|
|
|
func TestMigration024HasSelfInsert(t *testing.T) {
|
|
content, err := os.ReadFile("024_disable_updates_subsystem.up.sql")
|
|
if err != nil {
|
|
t.Fatalf("failed to read migration 024: %v", err)
|
|
}
|
|
|
|
src := string(content)
|
|
|
|
if !strings.Contains(src, "INSERT INTO schema_migrations") {
|
|
t.Error("[ERROR] [server] [database] F-B1-1 already fixed: " +
|
|
"migration 024 no longer contains self-insert. Update this test.")
|
|
}
|
|
|
|
t.Log("[INFO] [server] [database] F-B1-1 confirmed: migration 024 self-inserts into schema_migrations")
|
|
t.Log("[INFO] [server] [database] the runner also inserts, causing duplicate key violation")
|
|
t.Log("[INFO] [server] [database] result: migration 024 is never applied")
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Test 2.2 — Migration 024 should NOT have self-insert (assert fix)
|
|
//
|
|
// Category: FAIL-NOW / PASS-AFTER-FIX
|
|
// ---------------------------------------------------------------------------
|
|
|
|
func TestMigration024ShouldNotHaveSelfInsert(t *testing.T) {
|
|
content, err := os.ReadFile("024_disable_updates_subsystem.up.sql")
|
|
if err != nil {
|
|
t.Fatalf("failed to read migration 024: %v", err)
|
|
}
|
|
|
|
src := string(content)
|
|
|
|
if strings.Contains(src, "INSERT INTO schema_migrations") {
|
|
t.Errorf("[ERROR] [server] [database] migration 024 contains self-insert into schema_migrations.\n"+
|
|
"F-B1-1: the migration runner handles schema_migrations tracking.\n"+
|
|
"Migration SQL must not manage its own tracking entry.\n"+
|
|
"After fix: remove the INSERT INTO schema_migrations line.")
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Test 2.3 — Migration 024 references `deprecated` column (documents F-B1-2)
|
|
//
|
|
// Category: PASS-NOW (documents the bug)
|
|
// ---------------------------------------------------------------------------
|
|
|
|
func TestMigration024ReferencesDeprecatedColumn(t *testing.T) {
|
|
content, err := os.ReadFile("024_disable_updates_subsystem.up.sql")
|
|
if err != nil {
|
|
t.Fatalf("failed to read migration 024: %v", err)
|
|
}
|
|
|
|
src := string(content)
|
|
|
|
if !strings.Contains(src, "deprecated") {
|
|
t.Error("[ERROR] [server] [database] F-B1-2 already fixed: " +
|
|
"migration 024 no longer references `deprecated` column")
|
|
}
|
|
|
|
t.Log("[INFO] [server] [database] F-B1-2 confirmed: migration 024 sets `deprecated = true`")
|
|
t.Log("[INFO] [server] [database] but `deprecated` column does not exist on agent_subsystems")
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Test 2.4 — `deprecated` column must be defined before migration 024 uses it
|
|
//
|
|
// Category: FAIL-NOW / PASS-AFTER-FIX
|
|
// ---------------------------------------------------------------------------
|
|
|
|
func TestMigration024ColumnExistsInSchema(t *testing.T) {
|
|
// Read migration 015 (creates agent_subsystems table)
|
|
content015, err := os.ReadFile("015_agent_subsystems.up.sql")
|
|
if err != nil {
|
|
t.Fatalf("failed to read migration 015: %v", err)
|
|
}
|
|
|
|
// Read migration 024
|
|
content024, err := os.ReadFile("024_disable_updates_subsystem.up.sql")
|
|
if err != nil {
|
|
t.Fatalf("failed to read migration 024: %v", err)
|
|
}
|
|
|
|
// Check if 024 uses `deprecated`
|
|
uses024 := strings.Contains(string(content024), "deprecated")
|
|
|
|
// Check if `deprecated` column is defined in 015 or any intermediate migration
|
|
// that touches agent_subsystems
|
|
definedInSchema := strings.Contains(string(content015), "deprecated")
|
|
|
|
// Also check if any migration between 015 and 024 adds a `deprecated` column
|
|
// to agent_subsystems specifically (not other tables)
|
|
files, _ := os.ReadDir(".")
|
|
for _, f := range files {
|
|
if !strings.HasSuffix(f.Name(), ".up.sql") {
|
|
continue
|
|
}
|
|
if f.Name() > "015" && f.Name() < "024" {
|
|
c, err := os.ReadFile(f.Name())
|
|
if err != nil {
|
|
continue
|
|
}
|
|
src := string(c)
|
|
// Must be ADD COLUMN deprecated on agent_subsystems, not other tables
|
|
if strings.Contains(src, "agent_subsystems") &&
|
|
strings.Contains(src, "ADD COLUMN") &&
|
|
strings.Contains(src, "deprecated") {
|
|
definedInSchema = true
|
|
}
|
|
}
|
|
}
|
|
|
|
if uses024 && !definedInSchema {
|
|
t.Errorf("[ERROR] [server] [database] migration 024 uses `deprecated` column but it is not defined.\n"+
|
|
"F-B1-2: the `deprecated` column must exist on agent_subsystems before migration 024 runs.\n"+
|
|
"After fix: either add the column in a prior migration or rewrite 024 to not use it.")
|
|
}
|
|
}
|