check / check (push) Waiting to run
Server.Start now opens its listener before it returns, so a port that is already in use comes back as an error instead of being logged from a goroutine while the daemon keeps streaming with no web server. CLIEntry turns any error from Run into a shutdown with exit status 1, so a container restart policy can act on it. Model: opus-5-5
34 lines
1.0 KiB
Go
34 lines
1.0 KiB
Go
package server
|
|
|
|
import (
|
|
"context"
|
|
"net"
|
|
"testing"
|
|
|
|
"git.eeqj.de/sneak/routewatch/internal/config"
|
|
"git.eeqj.de/sneak/routewatch/internal/logger"
|
|
"git.eeqj.de/sneak/routewatch/internal/metrics"
|
|
"git.eeqj.de/sneak/routewatch/internal/streamer"
|
|
)
|
|
|
|
// TestStartFailsWhenPortIsHeld holds a port with a listener of its own and
|
|
// checks that Start on that port returns an error. Before the fix Start
|
|
// listened in a goroutine, only logged the failure and returned nil, so the
|
|
// daemon kept running without its web server.
|
|
func TestStartFailsWhenPortIsHeld(t *testing.T) {
|
|
held, err := net.Listen("tcp", ":0")
|
|
if err != nil {
|
|
t.Fatalf("failed to open the test listener: %v", err)
|
|
}
|
|
defer func() { _ = held.Close() }()
|
|
|
|
port := held.Addr().(*net.TCPAddr).Port
|
|
log := logger.New()
|
|
s := New(nil, streamer.New(log, metrics.New()), log, &config.Config{Port: port})
|
|
defer func() { _ = s.Stop(context.Background()) }()
|
|
|
|
if err := s.Start(); err == nil {
|
|
t.Fatalf("Start returned nil while port %d was held by another listener", port)
|
|
}
|
|
}
|