🚀 feat: implement random port selection for BDD tests to prevent conflicts
Some checks failed
CI/CD Pipeline / Build Docker Cache (push) Successful in 9s
CI/CD Pipeline / CI Pipeline (push) Failing after 4m47s

This commit is contained in:
2026-04-10 14:29:04 +02:00
parent 9467fd942c
commit 7b0135c537
3 changed files with 57 additions and 3 deletions

View File

@@ -1,6 +1,10 @@
package bdd package bdd
import ( import (
"fmt"
"strings"
"time"
"dance-lessons-coach/pkg/bdd/steps" "dance-lessons-coach/pkg/bdd/steps"
"dance-lessons-coach/pkg/bdd/testserver" "dance-lessons-coach/pkg/bdd/testserver"
@@ -12,9 +16,16 @@ var sharedServer *testserver.Server
func InitializeTestSuite(ctx *godog.TestSuiteContext) { func InitializeTestSuite(ctx *godog.TestSuiteContext) {
ctx.BeforeSuite(func() { ctx.BeforeSuite(func() {
// Small delay to ensure any previous server instances are fully cleaned up
time.Sleep(50 * time.Millisecond)
sharedServer = testserver.NewServer() sharedServer = testserver.NewServer()
if err := sharedServer.Start(); err != nil { 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 <PID>' 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 { if err := sharedServer.CloseDatabase(); err != nil {
log.Warn().Err(err).Msg("Failed to close database connection") 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 // Cleanup any test config files
steps.CleanupAllTestConfigFiles() steps.CleanupAllTestConfigFiles()

View File

@@ -4,6 +4,7 @@ import (
"context" "context"
"database/sql" "database/sql"
"fmt" "fmt"
"math/rand"
"net/http" "net/http"
"os" "os"
"strconv" "strconv"
@@ -25,12 +26,22 @@ type Server struct {
db *sql.DB db *sql.DB
} }
func init() {
// Seed the random number generator for random port selection
rand.Seed(time.Now().UnixNano())
}
func NewServer() *Server { func NewServer() *Server {
// Get feature-specific port from configuration // Get feature-specific port from configuration
feature := os.Getenv("FEATURE") feature := os.Getenv("FEATURE")
port := 9191 // Default port 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 // Try to read port from feature-specific config
configPath := fmt.Sprintf("features/%s/%s-test-config.yaml", feature, feature) configPath := fmt.Sprintf("features/%s/%s-test-config.yaml", feature, feature)
if _, statErr := os.Stat(configPath); statErr == nil { if _, statErr := os.Stat(configPath); statErr == nil {

View File

@@ -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