118 lines
3.5 KiB
Go
118 lines
3.5 KiB
Go
package session
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestWriterQueuePriorityAndFairness_HP_SES_03(t *testing.T) {
|
|
t.Parallel()
|
|
queue := NewWriterQueue(4, 1, 2)
|
|
if !queue.EnqueueData(Frame{Kind: FrameData, Payload: []byte("data")}) {
|
|
t.Fatal("initial data enqueue failed")
|
|
}
|
|
if queue.EnqueueData(Frame{Kind: FrameData}) {
|
|
t.Fatal("full data lane accepted another frame")
|
|
}
|
|
for _, value := range []string{"control-1", "control-2", "control-3"} {
|
|
if err := queue.EnqueueControl(Frame{Kind: FrameControl, Payload: []byte(value)}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
ctx := context.Background()
|
|
for index, want := range []string{"control-1", "control-2", "data", "control-3"} {
|
|
frame, err := queue.Next(ctx)
|
|
if err != nil || string(frame.Payload) != want {
|
|
t.Fatalf("frame %d = (%q, %v), want %q", index, frame.Payload, err, want)
|
|
}
|
|
}
|
|
if err := queue.EnqueueControl(Frame{Kind: FrameData}); !errors.Is(err, ErrControlLaneFull) {
|
|
t.Fatalf("wrong control frame error = %v", err)
|
|
}
|
|
queue.Close()
|
|
if _, err := queue.Next(context.Background()); !errors.Is(err, ErrSessionClosed) {
|
|
t.Fatalf("closed queue Next error = %v", err)
|
|
}
|
|
}
|
|
|
|
func TestHeartbeatBoundaries_HP_SES_04(t *testing.T) {
|
|
t.Parallel()
|
|
heartbeat := NewHeartbeat(10*time.Second, 30*time.Second, 0)
|
|
if action := heartbeat.Check(9 * time.Second); action != HeartbeatNone {
|
|
t.Fatalf("9s action = %d", action)
|
|
}
|
|
if action := heartbeat.Check(10 * time.Second); action != HeartbeatPing {
|
|
t.Fatalf("10s action = %d", action)
|
|
}
|
|
if action := heartbeat.Check(29 * time.Second); action != HeartbeatNone {
|
|
t.Fatalf("29s action = %d", action)
|
|
}
|
|
if action := heartbeat.Check(30 * time.Second); action != HeartbeatClose {
|
|
t.Fatalf("30s action = %d", action)
|
|
}
|
|
heartbeat.ObserveInbound(31 * time.Second)
|
|
if action := heartbeat.Check(41 * time.Second); action != HeartbeatPing {
|
|
t.Fatalf("inbound reset action = %d", action)
|
|
}
|
|
if action := heartbeat.Check(1 * time.Second); action != HeartbeatNone {
|
|
t.Fatalf("clock rollback action = %d", action)
|
|
}
|
|
}
|
|
|
|
func TestCapacityShadowAndRegistry_BH_SES_03(t *testing.T) {
|
|
t.Parallel()
|
|
var shadow CapacityShadow
|
|
if shadow.UpdateAdvertised(0, 0, 0, 1) {
|
|
t.Fatal("invalid capacity accepted")
|
|
}
|
|
if !shadow.UpdateAdvertised(0, 0, 1, 1) {
|
|
t.Fatal("valid capacity rejected")
|
|
}
|
|
if got := shadow.Reserve(); got != DispatchRunning {
|
|
t.Fatalf("first lane = %d", got)
|
|
}
|
|
if got := shadow.Reserve(); got != DispatchQueued {
|
|
t.Fatalf("second lane = %d", got)
|
|
}
|
|
if got := shadow.Reserve(); got != DispatchNone {
|
|
t.Fatalf("oversubscription lane = %d", got)
|
|
}
|
|
if !shadow.Release(DispatchRunning) || shadow.Release(DispatchRunning) {
|
|
t.Fatal("shadow release accounting is wrong")
|
|
}
|
|
|
|
registry := NewRegistry()
|
|
first, err := registry.Install("client-a", [16]byte{1}, 1)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
second, err := registry.Install("client-a", [16]byte{2}, 2)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
select {
|
|
case <-first.Context.Done():
|
|
default:
|
|
t.Fatal("replacement did not fence old handle")
|
|
}
|
|
if registry.Remove(first) || registry.Get("client-a") != second {
|
|
t.Fatal("stale handle removed current session")
|
|
}
|
|
if !registry.Wake("client-a") {
|
|
t.Fatal("wake did not find current session")
|
|
}
|
|
select {
|
|
case <-second.DispatchWake():
|
|
default:
|
|
t.Fatal("wake was not delivered to current session")
|
|
}
|
|
if registry.Wake("missing") {
|
|
t.Fatal("wake reported a missing session")
|
|
}
|
|
if !registry.Remove(second) {
|
|
t.Fatal("current handle removal failed")
|
|
}
|
|
}
|