Initial project snapshot
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
package mesh
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSyntheticRelaySchedulerDequeuesByQoSPriority(t *testing.T) {
|
||||
scheduler := testRelayScheduler()
|
||||
telemetry := testRelayEnvelope(SyntheticChannelTelemetry, SyntheticMessageTelemetry, 1)
|
||||
routeControl := testRelayEnvelope(SyntheticChannelRouteControl, SyntheticMessageRouteHealth, 2)
|
||||
fabricControl := testRelayEnvelope(SyntheticChannelFabricControl, SyntheticMessageProbe, 3)
|
||||
|
||||
if _, err := scheduler.Enqueue(telemetry); err != nil {
|
||||
t.Fatalf("enqueue telemetry: %v", err)
|
||||
}
|
||||
if _, err := scheduler.Enqueue(routeControl); err != nil {
|
||||
t.Fatalf("enqueue route control: %v", err)
|
||||
}
|
||||
if _, err := scheduler.Enqueue(fabricControl); err != nil {
|
||||
t.Fatalf("enqueue fabric control: %v", err)
|
||||
}
|
||||
|
||||
first, err := scheduler.Dequeue()
|
||||
if err != nil {
|
||||
t.Fatalf("dequeue first: %v", err)
|
||||
}
|
||||
second, err := scheduler.Dequeue()
|
||||
if err != nil {
|
||||
t.Fatalf("dequeue second: %v", err)
|
||||
}
|
||||
third, err := scheduler.Dequeue()
|
||||
if err != nil {
|
||||
t.Fatalf("dequeue third: %v", err)
|
||||
}
|
||||
if first.Channel != SyntheticChannelFabricControl {
|
||||
t.Fatalf("first channel = %q, want fabric_control", first.Channel)
|
||||
}
|
||||
if second.Channel != SyntheticChannelRouteControl {
|
||||
t.Fatalf("second channel = %q, want route_control", second.Channel)
|
||||
}
|
||||
if third.Channel != SyntheticChannelTelemetry {
|
||||
t.Fatalf("third channel = %q, want telemetry", third.Channel)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyntheticRelaySchedulerDropsOldestTelemetryOnly(t *testing.T) {
|
||||
scheduler := testRelayScheduler()
|
||||
first := testRelayEnvelope(SyntheticChannelTelemetry, SyntheticMessageTelemetry, 1)
|
||||
second := testRelayEnvelope(SyntheticChannelTelemetry, SyntheticMessageTelemetry, 2)
|
||||
|
||||
if result, err := scheduler.Enqueue(first); err != nil || result.Dropped {
|
||||
t.Fatalf("enqueue first result=%+v err=%v", result, err)
|
||||
}
|
||||
result, err := scheduler.Enqueue(second)
|
||||
if err != nil {
|
||||
t.Fatalf("enqueue second: %v", err)
|
||||
}
|
||||
if !result.Dropped || result.DroppedSequence != 1 {
|
||||
t.Fatalf("result = %+v, want dropped sequence 1", result)
|
||||
}
|
||||
dequeued, err := scheduler.Dequeue()
|
||||
if err != nil {
|
||||
t.Fatalf("dequeue: %v", err)
|
||||
}
|
||||
if dequeued.Sequence != 2 {
|
||||
t.Fatalf("dequeued sequence = %d, want 2", dequeued.Sequence)
|
||||
}
|
||||
metrics := scheduler.SnapshotQueueMetrics()
|
||||
if metrics.Dropped != 1 || metrics.Enqueued != 2 {
|
||||
t.Fatalf("metrics = %+v, want one drop and two enqueues", metrics)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyntheticRelaySchedulerRejectsFullReliableQueue(t *testing.T) {
|
||||
scheduler := testRelayScheduler()
|
||||
first := testRelayEnvelope(SyntheticChannelFabricControl, SyntheticMessageProbe, 1)
|
||||
second := testRelayEnvelope(SyntheticChannelFabricControl, SyntheticMessageProbe, 2)
|
||||
|
||||
if _, err := scheduler.Enqueue(first); err != nil {
|
||||
t.Fatalf("enqueue first: %v", err)
|
||||
}
|
||||
_, err := scheduler.Enqueue(second)
|
||||
if !errors.Is(err, ErrSyntheticRelayQueueFull) {
|
||||
t.Fatalf("err = %v, want ErrSyntheticRelayQueueFull", err)
|
||||
}
|
||||
dequeued, err := scheduler.Dequeue()
|
||||
if err != nil {
|
||||
t.Fatalf("dequeue: %v", err)
|
||||
}
|
||||
if dequeued.Sequence != 1 {
|
||||
t.Fatalf("dequeued sequence = %d, want 1", dequeued.Sequence)
|
||||
}
|
||||
metrics := scheduler.SnapshotQueueMetrics()
|
||||
if metrics.Dropped != 0 || metrics.Rejected != 1 {
|
||||
t.Fatalf("metrics = %+v, want no drop and one rejection", metrics)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyntheticRelaySchedulerRejectsInvalidEnvelopes(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
mutate func(*SyntheticEnvelope)
|
||||
want error
|
||||
}{
|
||||
{
|
||||
name: "wrong cluster",
|
||||
mutate: func(envelope *SyntheticEnvelope) {
|
||||
envelope.ClusterID = "cluster-2"
|
||||
},
|
||||
want: ErrClusterMismatch,
|
||||
},
|
||||
{
|
||||
name: "wrong node",
|
||||
mutate: func(envelope *SyntheticEnvelope) {
|
||||
envelope.To.NodeID = "node-x"
|
||||
},
|
||||
want: ErrNodeMismatch,
|
||||
},
|
||||
{
|
||||
name: "unauthorized channel",
|
||||
mutate: func(envelope *SyntheticEnvelope) {
|
||||
envelope.Channel = "rdp_render"
|
||||
},
|
||||
want: ErrUnauthorizedChannel,
|
||||
},
|
||||
{
|
||||
name: "unsupported message",
|
||||
mutate: func(envelope *SyntheticEnvelope) {
|
||||
envelope.MessageType = "rdp.input"
|
||||
},
|
||||
want: ErrUnsupportedSyntheticMessage,
|
||||
},
|
||||
{
|
||||
name: "ttl exhausted",
|
||||
mutate: func(envelope *SyntheticEnvelope) {
|
||||
envelope.TTL = 0
|
||||
},
|
||||
want: ErrTTLExhausted,
|
||||
},
|
||||
{
|
||||
name: "loop detected",
|
||||
mutate: func(envelope *SyntheticEnvelope) {
|
||||
envelope.Visited = append(envelope.Visited, "node-r")
|
||||
},
|
||||
want: ErrLoopDetected,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
scheduler := testRelayScheduler()
|
||||
envelope := testRelayEnvelope(SyntheticChannelFabricControl, SyntheticMessageProbe, 1)
|
||||
tt.mutate(&envelope)
|
||||
_, err := scheduler.Enqueue(envelope)
|
||||
if !errors.Is(err, tt.want) {
|
||||
t.Fatalf("err = %v, want %v", err, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyntheticRelaySchedulerDisabledRejects(t *testing.T) {
|
||||
scheduler := NewSyntheticRelayScheduler(SyntheticRelaySchedulerConfig{
|
||||
Enabled: false,
|
||||
Local: PeerIdentity{ClusterID: "cluster-1", NodeID: "node-r"},
|
||||
})
|
||||
_, err := scheduler.Enqueue(testRelayEnvelope(SyntheticChannelFabricControl, SyntheticMessageProbe, 1))
|
||||
if !errors.Is(err, ErrMeshRuntimeDisabled) {
|
||||
t.Fatalf("err = %v, want ErrMeshRuntimeDisabled", err)
|
||||
}
|
||||
if _, err := scheduler.Dequeue(); !errors.Is(err, ErrMeshRuntimeDisabled) {
|
||||
t.Fatalf("dequeue err = %v, want ErrMeshRuntimeDisabled", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyntheticRelaySchedulerQueueDepthSnapshot(t *testing.T) {
|
||||
scheduler := testRelayScheduler()
|
||||
if _, err := scheduler.Enqueue(testRelayEnvelope(SyntheticChannelFabricControl, SyntheticMessageProbe, 1)); err != nil {
|
||||
t.Fatalf("enqueue fabric control: %v", err)
|
||||
}
|
||||
if _, err := scheduler.Enqueue(testRelayEnvelope(SyntheticChannelRouteControl, SyntheticMessageRouteHealth, 2)); err != nil {
|
||||
t.Fatalf("enqueue route control: %v", err)
|
||||
}
|
||||
metrics := scheduler.SnapshotQueueMetrics()
|
||||
if metrics.QueueDepths[SyntheticChannelFabricControl] != 1 {
|
||||
t.Fatalf("fabric_control depth = %d, want 1", metrics.QueueDepths[SyntheticChannelFabricControl])
|
||||
}
|
||||
if metrics.QueueDepths[SyntheticChannelRouteControl] != 1 {
|
||||
t.Fatalf("route_control depth = %d, want 1", metrics.QueueDepths[SyntheticChannelRouteControl])
|
||||
}
|
||||
}
|
||||
|
||||
func testRelayScheduler() *SyntheticRelayScheduler {
|
||||
return NewSyntheticRelayScheduler(SyntheticRelaySchedulerConfig{
|
||||
Enabled: true,
|
||||
Local: PeerIdentity{ClusterID: "cluster-1", NodeID: "node-r"},
|
||||
QueuePolicies: []SyntheticRelayQueuePolicy{
|
||||
{Channel: SyntheticChannelFabricControl, Capacity: 1, Droppable: false},
|
||||
{Channel: SyntheticChannelRouteControl, Capacity: 1, Droppable: false},
|
||||
{Channel: SyntheticChannelTelemetry, Capacity: 1, Droppable: true},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testRelayEnvelope(channel string, messageType string, sequence uint64) SyntheticEnvelope {
|
||||
route := testRoute("route-relay-scheduler", []string{"node-a", "node-r", "node-b"})
|
||||
envelope := testEnvelope(route, "node-a", "node-r")
|
||||
envelope.Channel = channel
|
||||
envelope.MessageType = messageType
|
||||
envelope.Sequence = sequence
|
||||
return envelope
|
||||
}
|
||||
Reference in New Issue
Block a user