✨ feat(bdd): parallel-safe schema-per-package isolation (T12 stage 2/2)
Re-enables BDD_SCHEMA_ISOLATION=true with the foundation from PR #34 (NewPostgresRepositoryFromDSN). Achieves ~2.85x speedup on the BDD test suite by running feature packages in parallel. ARCHITECTURE When BDD_SCHEMA_ISOLATION=true, each test package (process) gets its own isolated PostgreSQL schema: 1. testserver.Start() generates a deterministic schema name per FEATURE 2. CREATE SCHEMA <name> 3. Open a per-package gorm.DB with DSN search_path=<name> 4. AutoMigrate runs in the isolated schema (creates users table) 5. Build a per-package server.Server with this isolated repo via server.NewServerWithUserRepo 6. Stop() drops the schema + closes the per-package pool Packages then run in parallel (default Go test parallelism) without contention because each has its own schema + connection pool. CHANGES - pkg/server/server.go : NEW factory NewServerWithUserRepo(cfg, ctx, userRepo, userService) that injects a per-test repo. Existing NewServer becomes a thin wrapper. - pkg/bdd/testserver/server.go : Start() chooses isolated mode based on BDD_SCHEMA_ISOLATION env var. Stop() drops schema + closes pool. - pkg/user/postgres_repository.go : Exec(sql) helper for the schema lifecycle (CREATE/DROP) used by testserver. - scripts/run-bdd-tests.sh : -p 1 only when BDD_SCHEMA_ISOLATION!=true. When true, default Go parallelism (~ NumCPU packages concurrent). - .gitea/workflows/ci-cd.yaml : exports BDD_SCHEMA_ISOLATION=true. - adr/0025-bdd-scenario-isolation-strategies.md : Status to "Implemented". VALIDATION 5x AuthBDD with isolation: 5/5 PASS, public.users count=0 after runs. Local benchmark on the full features/... suite: - Sequential -p 1 (no isolation): 12.87s - Parallel + isolation (this PR): 4.51s - Speedup: 2.85x 🤖 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -144,9 +144,21 @@ run_tests_with_tags() {
|
||||
# Note: -tags flag in go test is for Go build tags, NOT Godog feature tags
|
||||
# We use GODOG_TAGS env var which is read by the test framework
|
||||
echo "🚀 Running: GODOG_TAGS=\"${DEFAULT_TAGS}\" go test ./features/..."
|
||||
# -p 1 forces sequential package execution to avoid DB-state contention between feature packages
|
||||
# (different packages would otherwise spawn concurrent test servers sharing the same Postgres DB).
|
||||
GODOG_TAGS="$DEFAULT_TAGS" go test ./features/... -v -p 1 -cover -coverpkg=./... -coverprofile=coverage.out 2>&1 | tee /tmp/bdd_test_output.txt && test_output=$(cat /tmp/bdd_test_output.txt) && rm -f /tmp/bdd_test_output.txt || test_output=$(cat /tmp/bdd_test_output.txt 2>/dev/null || echo "")
|
||||
# When BDD_SCHEMA_ISOLATION=true (T12 architecture):
|
||||
# each test PACKAGE gets its own isolated PostgreSQL schema with its own
|
||||
# connection pool + migrations (cf. pkg/bdd/testserver/server.go Start()).
|
||||
# Packages then run in parallel safely. ~2.85x speedup observed locally.
|
||||
# When unset:
|
||||
# fall back to -p 1 (sequential). Uses public schema with TRUNCATE-style
|
||||
# cleanup between scenarios.
|
||||
if [ "${BDD_SCHEMA_ISOLATION:-}" = "true" ]; then
|
||||
PARALLEL_FLAG=""
|
||||
echo "🔀 BDD_SCHEMA_ISOLATION=true → feature packages run in parallel"
|
||||
else
|
||||
PARALLEL_FLAG="-p 1"
|
||||
echo "🐌 BDD_SCHEMA_ISOLATION not set → feature packages run sequentially (-p 1)"
|
||||
fi
|
||||
GODOG_TAGS="$DEFAULT_TAGS" go test ./features/... -v $PARALLEL_FLAG -cover -coverpkg=./... -coverprofile=coverage.out 2>&1 | tee /tmp/bdd_test_output.txt && test_output=$(cat /tmp/bdd_test_output.txt) && rm -f /tmp/bdd_test_output.txt || test_output=$(cat /tmp/bdd_test_output.txt 2>/dev/null || echo "")
|
||||
test_exit_code=${PIPESTATUS[0]}
|
||||
fi
|
||||
|
||||
|
||||
Reference in New Issue
Block a user