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>
104 lines
3.3 KiB
Go
104 lines
3.3 KiB
Go
package migrations_test
|
|
|
|
// index_audit_test.go — Pre-fix tests for missing database indexes.
|
|
//
|
|
// F-B1-5 MEDIUM: GetStuckCommands filters on status + sent_at across all agents.
|
|
// No composite index covers (status, sent_at) on agent_commands.
|
|
// Full table scan on every timeout check.
|
|
//
|
|
// Run: cd aggregator-server && go test ./internal/database/migrations/... -v -run TestStuckCommands
|
|
|
|
import (
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Test 6.1 — Documents missing index for GetStuckCommands (F-B1-5)
|
|
//
|
|
// Category: PASS-NOW (documents the bug)
|
|
// ---------------------------------------------------------------------------
|
|
|
|
func TestStuckCommandsIndexIsMissing(t *testing.T) {
|
|
files, err := os.ReadDir(".")
|
|
if err != nil {
|
|
t.Fatalf("failed to read migrations directory: %v", err)
|
|
}
|
|
|
|
// Search all migration files for a CREATE INDEX on agent_commands that covers sent_at
|
|
foundIndex := false
|
|
for _, f := range files {
|
|
if !strings.HasSuffix(f.Name(), ".up.sql") && !strings.HasSuffix(f.Name(), ".sql") {
|
|
continue
|
|
}
|
|
content, err := os.ReadFile(f.Name())
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
// Split into individual statements and check each CREATE INDEX
|
|
src := string(content)
|
|
lines := strings.Split(src, ";")
|
|
for _, stmt := range lines {
|
|
lower := strings.ToLower(stmt)
|
|
// Must be a CREATE INDEX on agent_commands that specifically includes sent_at
|
|
if strings.Contains(lower, "create index") &&
|
|
strings.Contains(lower, "agent_commands") &&
|
|
strings.Contains(lower, "sent_at") {
|
|
foundIndex = true
|
|
t.Logf("[INFO] [server] [database] found agent_commands sent_at index in %s", f.Name())
|
|
}
|
|
}
|
|
}
|
|
|
|
if foundIndex {
|
|
t.Error("[ERROR] [server] [database] F-B1-5 already fixed: " +
|
|
"index on agent_commands(sent_at) exists")
|
|
}
|
|
|
|
t.Log("[INFO] [server] [database] F-B1-5 confirmed: no index on agent_commands covering sent_at")
|
|
t.Log("[INFO] [server] [database] GetStuckCommands does full table scan on timeout checks")
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Test 6.2 — Composite index for stuck commands must exist (assert fix)
|
|
//
|
|
// Category: FAIL-NOW / PASS-AFTER-FIX
|
|
// ---------------------------------------------------------------------------
|
|
|
|
func TestStuckCommandsIndexExists(t *testing.T) {
|
|
files, err := os.ReadDir(".")
|
|
if err != nil {
|
|
t.Fatalf("failed to read migrations directory: %v", err)
|
|
}
|
|
|
|
foundIndex := false
|
|
for _, f := range files {
|
|
if !strings.HasSuffix(f.Name(), ".up.sql") && !strings.HasSuffix(f.Name(), ".sql") {
|
|
continue
|
|
}
|
|
content, err := os.ReadFile(f.Name())
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
stmts := strings.Split(string(content), ";")
|
|
for _, stmt := range stmts {
|
|
lower := strings.ToLower(stmt)
|
|
if strings.Contains(lower, "create index") &&
|
|
strings.Contains(lower, "agent_commands") &&
|
|
strings.Contains(lower, "sent_at") {
|
|
foundIndex = true
|
|
}
|
|
}
|
|
}
|
|
|
|
if !foundIndex {
|
|
t.Errorf("[ERROR] [server] [database] no index on agent_commands covering sent_at.\n" +
|
|
"F-B1-5: GetStuckCommands needs a composite index on (status, sent_at).\n" +
|
|
"After fix: add CREATE INDEX IF NOT EXISTS idx_agent_commands_stuck\n" +
|
|
"ON agent_commands(status, sent_at) WHERE status IN ('pending', 'sent')")
|
|
}
|
|
}
|