feat: add first page with auth and containers list and agents

This commit is contained in:
2026-05-18 08:24:02 +02:00
parent 446087ae01
commit 3b4a841bf5
56 changed files with 16267 additions and 0 deletions

View File

@ -0,0 +1,123 @@
package broker
import (
"encoding/json"
"testing"
"time"
)
func TestSubscribePublishUnsubscribe(t *testing.T) {
b := New()
sub := b.Subscribe()
evt := Event{Type: "test.event", AgentID: "agent1", Payload: map[string]string{"k": "v"}}
b.Publish(evt)
select {
case raw := <-sub:
var got Event
if err := json.Unmarshal(raw, &got); err != nil {
t.Fatalf("unmarshal: %v", err)
}
if got.Type != "test.event" || got.AgentID != "agent1" {
t.Errorf("unexpected event: %+v", got)
}
case <-time.After(time.Second):
t.Fatal("timed out waiting for event")
}
b.Unsubscribe(sub)
// channel must be closed after unsubscribe
select {
case _, ok := <-sub:
if ok {
t.Error("expected channel to be closed")
}
case <-time.After(time.Second):
t.Fatal("timed out waiting for channel close")
}
}
func TestMultipleSubscribers(t *testing.T) {
b := New()
sub1 := b.Subscribe()
sub2 := b.Subscribe()
defer b.Unsubscribe(sub1)
defer b.Unsubscribe(sub2)
b.Publish(Event{Type: "ping", Payload: nil})
for i, sub := range []subscriber{sub1, sub2} {
select {
case <-sub:
case <-time.After(time.Second):
t.Fatalf("subscriber %d did not receive event", i)
}
}
}
func TestPublishDropsWhenSubscriberSlow(t *testing.T) {
b := New()
// Channel size is 32; fill it up and then publish one more — it must not block.
sub := b.Subscribe()
defer b.Unsubscribe(sub)
// Fill the buffer
for i := 0; i < 32; i++ {
b.Publish(Event{Type: "flood", Payload: i})
}
// This extra publish must return immediately (dropped, not block).
done := make(chan struct{})
go func() {
b.Publish(Event{Type: "dropped", Payload: nil})
close(done)
}()
select {
case <-done:
case <-time.After(time.Second):
t.Fatal("Publish blocked on slow subscriber")
}
}
func TestPublishNoSubscribers(t *testing.T) {
b := New()
// Should not panic or block
b.Publish(Event{Type: "nobody", Payload: nil})
}
func TestPublishInvalidPayload(t *testing.T) {
b := New()
sub := b.Subscribe()
defer b.Unsubscribe(sub)
// json.Marshal of a channel fails — Publish must not send anything.
b.Publish(Event{Type: "bad", Payload: make(chan int)})
select {
case <-sub:
t.Error("should not have received a message for an unmarshalable event")
default:
// correct: nothing sent
}
}
func TestUnsubscribeRemovesFromBroker(t *testing.T) {
b := New()
sub := b.Subscribe()
b.Unsubscribe(sub)
// After unsubscribe the broker's map should be empty.
b.mu.RLock()
n := len(b.subs)
b.mu.RUnlock()
if n != 0 {
t.Errorf("expected 0 subscribers after unsubscribe, got %d", n)
}
}