- Add ADR-0012 documenting the decision to format only staged Go files - Update ADR README.md with new entry - Document rationale, alternatives, and verification results - Include future considerations for monitoring and CI/CD integration Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
108 lines
2.1 KiB
Go
108 lines
2.1 KiB
Go
package testserver
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"time"
|
|
|
|
"DanceLessonsCoach/pkg/config"
|
|
"DanceLessonsCoach/pkg/server"
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
type Server struct {
|
|
httpServer *http.Server
|
|
port int
|
|
baseURL string
|
|
}
|
|
|
|
func NewServer() *Server {
|
|
return &Server{
|
|
port: 9191,
|
|
}
|
|
}
|
|
|
|
func (s *Server) Start() error {
|
|
s.baseURL = fmt.Sprintf("http://localhost:%d", s.port)
|
|
|
|
// Create real server instance from pkg/server
|
|
cfg := createTestConfig(s.port)
|
|
realServer := server.NewServer(cfg, context.Background())
|
|
|
|
// Start HTTP server in same process
|
|
s.httpServer = &http.Server{
|
|
Addr: fmt.Sprintf(":%d", s.port),
|
|
Handler: realServer.Router(),
|
|
}
|
|
|
|
go func() {
|
|
if err := s.httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
|
if err != http.ErrServerClosed {
|
|
log.Error().Err(err).Msg("Test server failed")
|
|
}
|
|
}
|
|
}()
|
|
|
|
// Wait for server to be ready
|
|
return s.waitForServerReady()
|
|
}
|
|
|
|
func (s *Server) waitForServerReady() error {
|
|
maxAttempts := 30
|
|
attempt := 0
|
|
|
|
for attempt < maxAttempts {
|
|
resp, err := http.Get(fmt.Sprintf("%s/api/ready", s.baseURL))
|
|
if err == nil && resp.StatusCode == http.StatusOK {
|
|
resp.Body.Close()
|
|
return nil
|
|
}
|
|
if resp != nil {
|
|
resp.Body.Close()
|
|
}
|
|
attempt++
|
|
time.Sleep(100 * time.Millisecond)
|
|
}
|
|
|
|
return fmt.Errorf("server did not become ready after %d attempts", maxAttempts)
|
|
}
|
|
|
|
func (s *Server) Stop() error {
|
|
if s.httpServer == nil {
|
|
return nil
|
|
}
|
|
|
|
// Shutdown HTTP server gracefully
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
|
|
return s.httpServer.Shutdown(ctx)
|
|
}
|
|
|
|
func (s *Server) GetBaseURL() string {
|
|
return s.baseURL
|
|
}
|
|
|
|
func createTestConfig(port int) *config.Config {
|
|
return &config.Config{
|
|
Server: config.ServerConfig{
|
|
Host: "localhost",
|
|
Port: port,
|
|
},
|
|
Shutdown: config.ShutdownConfig{
|
|
Timeout: 5 * time.Second,
|
|
},
|
|
Logging: config.LoggingConfig{
|
|
JSON: false,
|
|
Level: "trace",
|
|
},
|
|
Telemetry: config.TelemetryConfig{
|
|
Enabled: false,
|
|
},
|
|
API: config.APIConfig{
|
|
V2Enabled: true, // Enable v2 for testing
|
|
},
|
|
}
|
|
}
|