Files

203 lines
4.1 KiB
Go

package broker
import (
"context"
"testing"
"time"
"github.com/seu-usuario/go-react-web-tail/internal/models"
)
func TestBroker_SubscribeUnsubscribe(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
b := New(ctx)
defer b.Shutdown()
// Subscribe
ch := b.Subscribe()
if ch == nil {
t.Fatal("Subscribe returned nil channel")
}
// Give broker time to process
time.Sleep(10 * time.Millisecond)
activeClients, _ := b.GetMetrics()
if activeClients != 1 {
t.Errorf("Expected 1 active client, got %d", activeClients)
}
// Unsubscribe
b.Unsubscribe(ch)
time.Sleep(10 * time.Millisecond)
activeClients, _ = b.GetMetrics()
if activeClients != 0 {
t.Errorf("Expected 0 active clients after unsubscribe, got %d", activeClients)
}
}
func TestBroker_Broadcast(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
b := New(ctx)
defer b.Shutdown()
ch := b.Subscribe()
defer b.Unsubscribe(ch)
entry := models.LogEntry{
Filename: "test.log",
Line: "Test message",
}
// Broadcast
b.Broadcast(entry)
// Receive
select {
case received := <-ch:
if received.Filename != entry.Filename {
t.Errorf("Expected filename %s, got %s", entry.Filename, received.Filename)
}
if received.Line != entry.Line {
t.Errorf("Expected line %s, got %s", entry.Line, received.Line)
}
case <-time.After(1 * time.Second):
t.Fatal("Timeout waiting for broadcast message")
}
}
func TestBroker_MultipleClients(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
b := New(ctx)
defer b.Shutdown()
// Subscribe multiple clients
clients := make([]chan models.LogEntry, 3)
for i := range clients {
clients[i] = b.Subscribe()
}
time.Sleep(10 * time.Millisecond)
activeClients, _ := b.GetMetrics()
if activeClients != 3 {
t.Errorf("Expected 3 active clients, got %d", activeClients)
}
entry := models.LogEntry{
Filename: "test.log",
Line: "Broadcast to all",
}
b.Broadcast(entry)
// All clients should receive
for i, ch := range clients {
select {
case received := <-ch:
if received.Line != entry.Line {
t.Errorf("Client %d: expected line %s, got %s", i, entry.Line, received.Line)
}
case <-time.After(1 * time.Second):
t.Errorf("Client %d: timeout waiting for message", i)
}
}
// Cleanup
for _, ch := range clients {
b.Unsubscribe(ch)
}
}
func TestBroker_Shutdown(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
b := New(ctx)
ch := b.Subscribe()
time.Sleep(10 * time.Millisecond)
b.Shutdown()
time.Sleep(50 * time.Millisecond)
// Channel should be closed
_, ok := <-ch
if ok {
t.Error("Expected channel to be closed after shutdown")
}
}
func TestBroker_GetMetrics(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
b := New(ctx)
defer b.Shutdown()
// Initial metrics
activeClients, totalBroadcasts := b.GetMetrics()
if activeClients != 0 {
t.Errorf("Expected 0 active clients initially, got %d", activeClients)
}
if totalBroadcasts != 0 {
t.Errorf("Expected 0 total broadcasts initially, got %d", totalBroadcasts)
}
// Subscribe and broadcast
ch := b.Subscribe()
defer b.Unsubscribe(ch)
time.Sleep(10 * time.Millisecond)
for i := 0; i < 5; i++ {
b.Broadcast(models.LogEntry{
Filename: "test.log",
Line: "Test",
})
}
time.Sleep(10 * time.Millisecond)
activeClients, totalBroadcasts = b.GetMetrics()
if activeClients != 1 {
t.Errorf("Expected 1 active client, got %d", activeClients)
}
if totalBroadcasts != 5 {
t.Errorf("Expected 5 total broadcasts, got %d", totalBroadcasts)
}
}
func BenchmarkBroker_Broadcast(b *testing.B) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
broker := New(ctx)
defer broker.Shutdown()
ch := broker.Subscribe()
defer broker.Unsubscribe(ch)
// Drain channel in background
go func() {
for range ch {
}
}()
entry := models.LogEntry{
Filename: "test.log",
Line: "Benchmark message",
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
broker.Broadcast(entry)
}
}