Files
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

133 lines
3.3 KiB
Go

package agentruntime
import (
"testing"
"time"
)
func TestEventHubScopesEventsByRoom(t *testing.T) {
t.Parallel()
hub := NewEventHub()
roomAEvents, unsubscribeRoomA := hub.Subscribe("room-a", "session-1")
defer unsubscribeRoomA()
roomBEvents, unsubscribeRoomB := hub.Subscribe("room-b", "session-1")
defer unsubscribeRoomB()
hub.Publish("room-a", "session-1", []StreamEvent{{
EventType: StreamEventMessageUpdate,
Data: map[string]any{"text": "room a"},
}})
select {
case event := <-roomAEvents:
data := event.Data.(map[string]any)
if data["text"] != "room a" {
t.Fatalf("room-a event data = %#v, want room a", event.Data)
}
case <-time.After(time.Second):
t.Fatal("expected room-a subscriber to receive event")
}
select {
case event := <-roomBEvents:
t.Fatalf("room-b subscriber received cross-room event: %#v", event)
case <-time.After(50 * time.Millisecond):
}
hub.Publish("room-b", "session-1", []StreamEvent{{
EventType: StreamEventMessageUpdate,
Data: map[string]any{"text": "room b"},
}})
select {
case event := <-roomBEvents:
data := event.Data.(map[string]any)
if data["text"] != "room b" {
t.Fatalf("room-b event data = %#v, want room b", event.Data)
}
case <-time.After(time.Second):
t.Fatal("expected room-b subscriber to receive event")
}
}
func TestEventHubQueuesSubscriberBackpressureWithoutDropping(t *testing.T) {
t.Parallel()
hub := NewEventHub()
events, unsubscribe := hub.Subscribe("room-a", "session-1")
defer unsubscribe()
const eventCount = 96
published := make([]StreamEvent, 0, eventCount)
for i := range eventCount {
published = append(published, StreamEvent{
EventType: StreamEventMessageUpdate,
Data: map[string]any{"index": i},
})
}
hub.Publish("room-a", "session-1", published)
for i := range eventCount {
select {
case event := <-events:
data := event.Data.(map[string]any)
if data["index"] != i {
t.Fatalf("event index = %#v, want %d", data["index"], i)
}
case <-time.After(time.Second):
t.Fatalf("timed out waiting for event %d", i)
}
}
}
func TestEventHubReconcilesAndClosesOverflowedSubscriber(t *testing.T) {
t.Parallel()
hub := NewEventHub()
events, unsubscribe := hub.Subscribe("room-a", "session-1")
defer unsubscribe()
published := make([]StreamEvent, 0, eventHubSubscriberQueueLimit+128)
for i := 0; i < eventHubSubscriberQueueLimit+128; i++ {
published = append(published, StreamEvent{
EventType: StreamEventMessageDelta,
Data: map[string]any{"index": i},
})
}
hub.Publish("room-a", "session-1", published)
for {
select {
case event, ok := <-events:
if !ok {
t.Fatal("overflowed subscriber closed before reconcile event")
}
if event.EventType != StreamEventSessionReconcileRequired {
continue
}
data, ok := event.Data.(map[string]any)
if !ok || data["reason"] != "event_hub_queue_overflow" {
t.Fatalf("reconcile event data = %#v", event.Data)
}
if data["agentSessionId"] != "session-1" {
t.Fatalf("reconcile event session = %#v", data["agentSessionId"])
}
goto reconciled
case <-time.After(time.Second):
t.Fatal("timed out waiting for reconcile event")
}
}
reconciled:
select {
case _, ok := <-events:
if ok {
t.Fatal("overflowed subscriber emitted events after reconcile")
}
case <-time.After(time.Second):
t.Fatal("overflowed subscriber did not close")
}
}