Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion server.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ func (s *Server) Start(ctx context.Context) error {
shutdownCtx, shutdownCancel := context.WithCancel(context.Background())
defer shutdownCancel()

g, _ := errgroup.WithContext(ctx)
// creates ctx which will be canceled on first failed goroutine
g, ctx := errgroup.WithContext(ctx)

// Start the server in a new goroutine within the errgroup
g.Go(func() error {
Expand Down
41 changes: 39 additions & 2 deletions server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func TestServer(t *testing.T) {
listenAddr := "localhost:9999"

handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello, World!")
_, _ = fmt.Fprintln(w, "Hello, World!")
})
server, err := httpserver.New(listenAddr, handler)
require.NoError(t, err, "Unexpected error creating server")
Expand Down Expand Up @@ -46,7 +46,7 @@ func TestServer(t *testing.T) {
cancel()

// Wait for server to shut down with timeout
shutdownTimeout := time.After(5 * time.Second)
shutdownTimeout := time.After(time.Second)
select {
case err := <-serverErr:
require.True(t, err == nil || errors.Is(err, context.Canceled),
Expand All @@ -59,3 +59,40 @@ func TestServer(t *testing.T) {
_, err = http.Get(fmt.Sprintf("http://%s", listenAddr))
require.Error(t, err, "Expected error after server shutdown")
}

func TestErrorServerStart(t *testing.T) {
listenAddr := "localhost:9999"

handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, _ = fmt.Fprintln(w, "Hello, World!")
})
server, err := httpserver.New(listenAddr, handler)
require.NoError(t, err, "Unexpected error creating server")

// Create a context with cancel for server control
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

// Channel to catch server errors, no need for buffer because we catch error in current test control flow
serverErr := make(chan error)

// Start the server in a goroutine
go func() {
serverErr <- server.Start(ctx)
}()
// Start server will wail because of already used port
go func() {
serverErr <- server.Start(ctx)
}()

select {
case err = <-serverErr:
require.ErrorIs(t, err, httpserver.ErrServerStart,
"Expected ErrServerStart error, got: %v", err)
case <-time.After(time.Second):
t.Fatal("Server shutdown timed out")
}
// Verify server is no longer accepting connections
_, err = http.Get(fmt.Sprintf("http://%s", listenAddr))
require.Error(t, err, "Expected error after server shutdown")
}
Loading