PR #26 added BDD_SCHEMA_ISOLATION=true to CI but this creates per-scenario schemas WITHOUT running migrations on them, causing 500 errors on user registration. This PR reverts that and instead relies on: 1. The existing CleanupDatabase hook (truncates all tables AfterScenario) 2. Sequential test package execution (-p 1) to avoid contention between feature packages sharing the same Postgres DB Plus defensive additions for future-proofing: - pkg/server/server.go: GetCacheService() exposed for test cleanup - pkg/bdd/testserver/server.go: cacheService field + FlushCache() method - pkg/bdd/testserver/state_tracer.go: TraceStateCacheOperation - pkg/bdd/suite.go: AfterScenario hook calls FlushCache() - scripts/run-bdd-tests.sh: -p 1 added (sequential package execution) Validation: - AuthBDD alone: 5/5 PASS (was 0/5 with broken schema isolation) - Full features/ via run-bdd-tests.sh: ALL PASS (auth, config, greet, health, jwt) Out of scope (follow-up T12): - Proper parallel BDD with schema migrations per scenario + dedicated connection pools. Required for scaling tests but architecturally significant. Tracked. Co-Authored-By: Mistral Vibe (devstral-2 / mistral-medium-3.5) - cache flush diagnosis Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> - root cause + revert
92 lines
2.6 KiB
Go
92 lines
2.6 KiB
Go
package testserver
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
)
|
|
|
|
// TraceStateScenarioStart logs the start of a scenario
|
|
func TraceStateScenarioStart(feature, scenario string) {
|
|
writeTraceLine(feature, scenario, "SCENARIO_START", "")
|
|
}
|
|
|
|
// TraceStateScenarioEnd logs the end of a scenario
|
|
func TraceStateScenarioEnd(feature, scenario string, err error) {
|
|
status := "PASSED"
|
|
if err != nil {
|
|
status = fmt.Sprintf("FAILED: %v", err)
|
|
}
|
|
writeTraceLine(feature, scenario, "SCENARIO_END", status)
|
|
}
|
|
|
|
// TraceStateDBCleanup logs a database cleanup operation
|
|
func TraceStateDBCleanup(feature, scenario, table string) {
|
|
writeTraceLine(feature, scenario, "DB_CLEANUP", table)
|
|
}
|
|
|
|
// TraceStateJWTSecretOperation logs a JWT secret operation
|
|
func TraceStateJWTSecretOperation(feature, scenario, operation, details string) {
|
|
writeTraceLine(feature, scenario, "JWT_"+operation, details)
|
|
}
|
|
|
|
// TraceStateCacheOperation logs a cache operation
|
|
func TraceStateCacheOperation(feature, scenario, operation, details string) {
|
|
writeTraceLine(feature, scenario, "CACHE_"+operation, details)
|
|
}
|
|
|
|
// TraceStateSchemaIsolation logs a schema isolation operation
|
|
func TraceStateSchemaIsolation(feature, scenario, operation, details string) {
|
|
writeTraceLine(feature, scenario, "SCHEMA_"+operation, details)
|
|
}
|
|
|
|
// TraceStateTransaction logs a transaction boundary
|
|
func TraceStateTransaction(feature, scenario, action, details string) {
|
|
writeTraceLine(feature, scenario, "TX_"+action, details)
|
|
}
|
|
|
|
// TraceStateDBRead logs a database read operation
|
|
func TraceStateDBRead(feature, scenario, table, details string) {
|
|
writeTraceLine(feature, scenario, "DB_SELECT", fmt.Sprintf("table=%s %s", table, details))
|
|
}
|
|
|
|
// StateTracingEnabled returns true if BDD_TRACE_STATE environment variable is set to "1"
|
|
func StateTracingEnabled() bool {
|
|
return os.Getenv("BDD_TRACE_STATE") == "1"
|
|
}
|
|
|
|
// writeTraceLine writes a trace line to the state trace file in $TMPDIR
|
|
func writeTraceLine(feature, scenario, action, details string) {
|
|
if !StateTracingEnabled() {
|
|
return
|
|
}
|
|
tmpDir := os.Getenv("TMPDIR")
|
|
if tmpDir == "" {
|
|
tmpDir = "/tmp"
|
|
}
|
|
timestamp := time.Now().Format("20060102-150405")
|
|
pid := os.Getpid()
|
|
filename := fmt.Sprintf("bdd-state-trace-%s-%d.log", timestamp, pid)
|
|
filePath := filepath.Join(tmpDir, filename)
|
|
|
|
line := fmt.Sprintf("%s | %-15s | %-40s | %-16s | %s\n",
|
|
time.Now().Format("2006-01-02T15:04:05.000000"),
|
|
feature,
|
|
scenario,
|
|
action,
|
|
details,
|
|
)
|
|
|
|
file, err := os.OpenFile(filePath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
|
|
if err != nil {
|
|
return
|
|
}
|
|
defer file.Close()
|
|
|
|
if _, err := file.WriteString(line); err != nil {
|
|
return
|
|
}
|
|
file.Sync()
|
|
}
|