71 lines
3.3 KiB
Go
71 lines
3.3 KiB
Go
package rpc
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
agentpb "git.ipao.vip/rogee/go-sip/gen/agent"
|
|
"google.golang.org/grpc/codes"
|
|
"google.golang.org/grpc/status"
|
|
)
|
|
|
|
func TestSessionRegistryPersistsGenerationAcrossRestart(t *testing.T) {
|
|
path := t.TempDir() + "/rpc-session.json"
|
|
first := NewSessionRegistry(path)
|
|
_, _, err := first.Activate(&agentpb.AgentBinding{AgentId: "agent-1", CellId: "cell-1", ExpectedBootId: "boot-1", DispatcherEpoch: "epoch-1", SessionGeneration: 3}, "activate-1", "digest-1", time.Unix(100, 0))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
second := NewSessionRegistry(path)
|
|
_, _, err = second.Activate(&agentpb.AgentBinding{AgentId: "agent-1", CellId: "cell-1", ExpectedBootId: "boot-2", DispatcherEpoch: "epoch-2", SessionGeneration: 2}, "activate-2", "digest-2", time.Unix(100, 0))
|
|
if status.Code(err) != codes.Aborted {
|
|
t.Fatalf("error = %v, want persisted generation fence", err)
|
|
}
|
|
if _, _, err := second.Activate(&agentpb.AgentBinding{AgentId: "agent-1", CellId: "cell-1", ExpectedBootId: "boot-2", DispatcherEpoch: "epoch-2", SessionGeneration: 4}, "activate-3", "digest-3", time.Unix(100, 0)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestSessionRegistryZeroGenerationAdvancesDurableHighwaterAfterRestart(t *testing.T) {
|
|
path := t.TempDir() + "/rpc-session.json"
|
|
first := NewSessionRegistry(path)
|
|
now := time.Unix(100, 0)
|
|
if _, _, err := first.Activate(&agentpb.AgentBinding{AgentId: "agent-1", CellId: "cell-1", ExpectedBootId: "boot-1", DispatcherEpoch: "epoch-1", SessionGeneration: 7}, "activate-1", "digest-1", now); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
second := NewSessionRegistry(path)
|
|
session, replay, err := second.Activate(&agentpb.AgentBinding{AgentId: "agent-1", CellId: "cell-1", ExpectedBootId: "boot-2", DispatcherEpoch: "epoch-2"}, "activate-2", "digest-2", now)
|
|
if err != nil || replay || session.GetSessionGeneration() != 8 {
|
|
t.Fatalf("Agent could not advance persisted fencing after restart: session=%v replay=%t err=%v", session, replay, err)
|
|
}
|
|
third := NewSessionRegistry(path)
|
|
if _, _, err := third.Activate(&agentpb.AgentBinding{AgentId: "agent-1", CellId: "cell-1", ExpectedBootId: "boot-3", DispatcherEpoch: "epoch-3", SessionGeneration: 7}, "activate-3", "digest-3", now); status.Code(err) != codes.Aborted {
|
|
t.Fatalf("explicit stale generation bypassed the durable fence: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestSessionRegistryZeroGenerationDoesNotWrapAtExhaustion(t *testing.T) {
|
|
path := t.TempDir() + "/rpc-session.json"
|
|
first := NewSessionRegistry(path)
|
|
now := time.Unix(100, 0)
|
|
if _, _, err := first.Activate(&agentpb.AgentBinding{AgentId: "agent-1", CellId: "cell-1", ExpectedBootId: "boot-1", DispatcherEpoch: "epoch-1", SessionGeneration: ^uint64(0)}, "activate-1", "digest-1", now); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, tc := range []struct {
|
|
name string
|
|
registry *SessionRegistry
|
|
boot string
|
|
}{
|
|
{"active", first, "boot-1"},
|
|
{"after restart", NewSessionRegistry(path), "boot-2"},
|
|
} {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
_, _, err := tc.registry.Activate(&agentpb.AgentBinding{AgentId: "agent-1", CellId: "cell-1", ExpectedBootId: tc.boot, DispatcherEpoch: "epoch-2"}, "activate-2", "digest-2", now)
|
|
if status.Code(err) != codes.Aborted || !strings.Contains(err.Error(), "exhausted") {
|
|
t.Fatalf("exhausted generation wrapped or was hidden: %v", err)
|
|
}
|
|
})
|
|
}
|
|
}
|