From 7b0135c537a0ddd9ad452dfbad0a4ffe17004cb6 Mon Sep 17 00:00:00 2001 From: Gabriel Radureau Date: Fri, 10 Apr 2026 14:29:04 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=80=20feat:=20implement=20random=20por?= =?UTF-8?q?t=20selection=20for=20BDD=20tests=20to=20prevent=20conflicts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/bdd/suite.go | 20 +++++++++++++++++-- pkg/bdd/testserver/server.go | 13 ++++++++++++- scripts/run-tests-with-random-ports.sh | 27 ++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 3 deletions(-) create mode 100755 scripts/run-tests-with-random-ports.sh diff --git a/pkg/bdd/suite.go b/pkg/bdd/suite.go index d5703fe..fd68b89 100644 --- a/pkg/bdd/suite.go +++ b/pkg/bdd/suite.go @@ -1,6 +1,10 @@ package bdd import ( + "fmt" + "strings" + "time" + "dance-lessons-coach/pkg/bdd/steps" "dance-lessons-coach/pkg/bdd/testserver" @@ -12,9 +16,16 @@ var sharedServer *testserver.Server func InitializeTestSuite(ctx *godog.TestSuiteContext) { ctx.BeforeSuite(func() { + // Small delay to ensure any previous server instances are fully cleaned up + time.Sleep(50 * time.Millisecond) + sharedServer = testserver.NewServer() if err := sharedServer.Start(); err != nil { - panic(err) + // Improved error message for port conflicts + if strings.Contains(err.Error(), "address already in use") { + panic(fmt.Sprintf("Port conflict: %v. Try running 'lsof -i :9191' and 'kill -9 ' to free the port", err)) + } + panic(fmt.Sprintf("Failed to start test server: %v", err)) } }) @@ -28,7 +39,12 @@ func InitializeTestSuite(ctx *godog.TestSuiteContext) { if err := sharedServer.CloseDatabase(); err != nil { log.Warn().Err(err).Msg("Failed to close database connection") } - sharedServer.Stop() + // Shutdown HTTP server gracefully + if err := sharedServer.Stop(); err != nil { + log.Warn().Err(err).Msg("Failed to shutdown HTTP server") + } + // Small delay to ensure port is fully released + time.Sleep(100 * time.Millisecond) } // Cleanup any test config files steps.CleanupAllTestConfigFiles() diff --git a/pkg/bdd/testserver/server.go b/pkg/bdd/testserver/server.go index a25931f..7b5aabd 100644 --- a/pkg/bdd/testserver/server.go +++ b/pkg/bdd/testserver/server.go @@ -4,6 +4,7 @@ import ( "context" "database/sql" "fmt" + "math/rand" "net/http" "os" "strconv" @@ -25,12 +26,22 @@ type Server struct { db *sql.DB } +func init() { + // Seed the random number generator for random port selection + rand.Seed(time.Now().UnixNano()) +} + func NewServer() *Server { // Get feature-specific port from configuration feature := os.Getenv("FEATURE") port := 9191 // Default port - if feature != "" { + // Check for random port mode (better for parallel testing) + if os.Getenv("RANDOM_TEST_PORT") == "true" { + // Generate a random port in the test range (10000-19999) + port = 10000 + rand.Intn(9999) + log.Debug().Int("port", port).Msg("Using random test port") + } else if feature != "" { // Try to read port from feature-specific config configPath := fmt.Sprintf("features/%s/%s-test-config.yaml", feature, feature) if _, statErr := os.Stat(configPath); statErr == nil { diff --git a/scripts/run-tests-with-random-ports.sh b/scripts/run-tests-with-random-ports.sh new file mode 100755 index 0000000..cac8ac7 --- /dev/null +++ b/scripts/run-tests-with-random-ports.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +# Script to run BDD tests with random ports to avoid port conflicts +# Usage: ./scripts/run-tests-with-random-ports.sh [feature] + +echo "🚀 Running BDD tests with random ports..." +echo " This prevents port conflicts in parallel test execution" + +# Set environment variable for random port selection +export RANDOM_TEST_PORT="true" + +# Run the specified feature tests, or all tests if no feature specified +if [ $# -eq 0 ]; then + echo "📋 Running all BDD tests..." + go test ./features/... -v +else + echo "📋 Running tests for feature: $1" + go test ./features/$1/... -v +fi + +# Check the exit status +if [ $? -eq 0 ]; then + echo "✅ All tests passed!" +else + echo "❌ Some tests failed" + exit 1 +fi \ No newline at end of file