savinmax 3d14b7fcb8 feat(logging): add configurable log output and log level support
Add a 'logging' section to config.yaml supporting:
- output: stderr (default), stdout, or a file path
- level: debug, info, warn, error (default: info)

Implementation:
- New internal/logging package with Setup() for output destination
  and Logger struct with level-aware Debug/Info/Warn/Error methods
- Config struct extended with Logging section (output + level fields)
- Hub refactored to accept *logging.Logger via constructor injection
- main.go initializes logging early after config load

The leveled logger suppresses messages below the configured threshold
while maintaining the stdlib log format. File output uses append mode
with 0644 permissions for safe log rotation.

🤖 Assisted by the code-assist SOP
2026-06-11 19:21:20 +02:00

75 lines
1.3 KiB
Go

package hub
import (
"bytes"
"testing"
"time"
"websocket-relay/internal/logging"
)
func newTestLogger() *logging.Logger {
return logging.NewLogger("debug", &bytes.Buffer{})
}
func TestNew(t *testing.T) {
h := New(newTestLogger())
if h == nil {
t.Fatal("New returned nil")
}
if h.clients == nil {
t.Error("clients map not initialized")
}
if h.broadcast == nil {
t.Error("broadcast channel not initialized")
}
if h.stop == nil {
t.Error("stop channel not initialized")
}
}
func TestClientCount(t *testing.T) {
h := New(newTestLogger())
go h.Run()
defer h.Shutdown()
if count := h.ClientCount(); count != 0 {
t.Errorf("Expected 0 clients, got %d", count)
}
}
func TestBroadcastChannel(t *testing.T) {
h := New(newTestLogger())
go h.Run()
defer h.Shutdown()
select {
case h.broadcast <- []byte("test"):
// Channel is working
case <-time.After(100 * time.Millisecond):
t.Error("broadcast channel blocked")
}
}
func TestShutdown(t *testing.T) {
h := New(newTestLogger())
done := make(chan struct{})
go func() {
h.Run()
close(done)
}()
// Ensure Run is processing before shutdown
time.Sleep(10 * time.Millisecond)
h.Shutdown()
select {
case <-done:
// Hub.Run() returned successfully
case <-time.After(1 * time.Second):
t.Fatal("Hub.Run() did not return after Shutdown")
}
}