iop/apps/edge/internal/events/bus_test.go
toki 6e2a1fc2f2 feat: edge runtime, opsconsole, CLI target terminology, and e2e validation updates
- Add edge runtime config and opsconsole package
- Refactor edge console to use new runtime config
- Add service source metadata support
- Update CLI adapter with target terminology
- Add edge operation contract and event bus replay
- Update node label and command ops surface
- Add E2E smoke tests and full validation
- Update proto runtime definitions
- Update documentation and agent-ops rules
2026-05-17 14:57:49 +09:00

136 lines
3.9 KiB
Go

package events_test
import (
"testing"
edgeevents "iop/apps/edge/internal/events"
iop "iop/proto/gen/iop"
)
func TestBusPublishesRunToSpecificAndAllSubscribers(t *testing.T) {
bus := edgeevents.NewBus()
specific, unsubscribeSpecific := bus.SubscribeRun("run-1", 1)
defer unsubscribeSpecific()
all, unsubscribeAll := bus.SubscribeAllRuns(1)
defer unsubscribeAll()
bus.PublishRun(&iop.RunEvent{RunId: "run-1", Type: "start"})
select {
case event := <-specific:
if event.GetRunId() != "run-1" {
t.Fatalf("specific run id: %q", event.GetRunId())
}
default:
t.Fatal("expected specific run subscriber event")
}
select {
case event := <-all:
if event.GetRunId() != "run-1" {
t.Fatalf("all run id: %q", event.GetRunId())
}
default:
t.Fatal("expected all run subscriber event")
}
}
func TestBusCountsDroppedRunEvents(t *testing.T) {
bus := edgeevents.NewBus()
_, unsubscribe := bus.SubscribeRun("run-1", 1)
defer unsubscribe()
// First event fills the buffer; subsequent ones are dropped until drained.
bus.PublishRun(&iop.RunEvent{RunId: "run-1", Type: "start"})
bus.PublishRun(&iop.RunEvent{RunId: "run-1", Type: "chunk-1"})
bus.PublishRun(&iop.RunEvent{RunId: "run-1", Type: "chunk-2"})
stats := bus.Stats()
if stats.DroppedRunEvents != 2 {
t.Fatalf("DroppedRunEvents: got %d want 2", stats.DroppedRunEvents)
}
if stats.DroppedNodeEvents != 0 {
t.Fatalf("DroppedNodeEvents: got %d want 0", stats.DroppedNodeEvents)
}
}
func TestBusCountsDroppedNodeEvents(t *testing.T) {
bus := edgeevents.NewBus()
_, unsubscribe := bus.SubscribeNode("node-1", 1)
defer unsubscribe()
bus.PublishNode(&iop.EdgeNodeEvent{NodeId: "node-1", Type: "node.connected"})
bus.PublishNode(&iop.EdgeNodeEvent{NodeId: "node-1", Type: "node.disconnected"})
bus.PublishNode(&iop.EdgeNodeEvent{NodeId: "node-1", Type: "node.reconnected"})
stats := bus.Stats()
if stats.DroppedNodeEvents != 2 {
t.Fatalf("DroppedNodeEvents: got %d want 2", stats.DroppedNodeEvents)
}
if stats.DroppedRunEvents != 0 {
t.Fatalf("DroppedRunEvents: got %d want 0", stats.DroppedRunEvents)
}
}
func TestBusReplaysRecentRunEvents(t *testing.T) {
bus := edgeevents.NewBus()
bus.PublishRun(&iop.RunEvent{RunId: "run-1", Type: "start"})
bus.PublishRun(&iop.RunEvent{RunId: "run-2", Type: "start"})
bus.PublishRun(&iop.RunEvent{RunId: "run-1", Type: "complete"})
replay := bus.ReplayRun("run-1")
if len(replay) != 2 {
t.Fatalf("ReplayRun len: got %d want 2", len(replay))
}
if replay[0].GetType() != "start" || replay[1].GetType() != "complete" {
t.Fatalf("replay order: got [%q,%q] want [start,complete]", replay[0].GetType(), replay[1].GetType())
}
if got := bus.ReplayRun("missing"); got != nil {
t.Fatalf("expected nil replay for unknown run, got %v", got)
}
}
func TestBusReplayIsBounded(t *testing.T) {
const cap = 3
bus := edgeevents.NewBusWithReplayCapacity(cap)
for i := 0; i < cap+5; i++ {
bus.PublishRun(&iop.RunEvent{RunId: "run-1", Type: "tick"})
bus.PublishNode(&iop.EdgeNodeEvent{NodeId: "node-1", Type: "tick"})
}
if got := bus.ReplayRun("run-1"); len(got) != cap {
t.Fatalf("ReplayRun len: got %d want %d", len(got), cap)
}
if got := bus.ReplayNode("node-1"); len(got) != cap {
t.Fatalf("ReplayNode len: got %d want %d", len(got), cap)
}
}
func TestBusPublishesNodeToSpecificAndAllSubscribers(t *testing.T) {
bus := edgeevents.NewBus()
specific, unsubscribeSpecific := bus.SubscribeNode("node-1", 1)
defer unsubscribeSpecific()
all, unsubscribeAll := bus.SubscribeAllNodes(1)
defer unsubscribeAll()
bus.PublishNode(&iop.EdgeNodeEvent{NodeId: "node-1", Type: "node.disconnected"})
select {
case event := <-specific:
if event.GetNodeId() != "node-1" {
t.Fatalf("specific node id: %q", event.GetNodeId())
}
default:
t.Fatal("expected specific node subscriber event")
}
select {
case event := <-all:
if event.GetNodeId() != "node-1" {
t.Fatalf("all node id: %q", event.GetNodeId())
}
default:
t.Fatal("expected all node subscriber event")
}
}