Files
go-sip/internal/dispatcher/agent_test.go
T

89 lines
3.5 KiB
Go

package dispatcher
import (
"context"
"net"
"testing"
"time"
agentpb "git.ipao.vip/rogee/go-sip/gen/agent"
rpcserver "git.ipao.vip/rogee/go-sip/internal/rpc"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/test/bufconn"
)
const approvedTestDispatcherID = "c046b893-8628-4589-ae50-619d049248a6"
func TestAgentCoordinatorProbesBeforeActivation(t *testing.T) {
listener := bufconn.Listen(1024 * 1024)
server := rpcserver.NewServer(rpcserver.ServerOptions{
ApprovedDispatcherID: approvedTestDispatcherID,
Now: func() time.Time { return time.Date(2026, 9, 18, 1, 0, 0, 0, time.UTC) },
Status: &agentpb.AgentStatus{
AgentId: "agent-1",
CellId: "cell-1",
BootId: "boot-probed",
ProtocolVersion: "agent.v1",
},
})
grpcServer := grpc.NewServer()
agentpb.RegisterAgentControlServiceServer(grpcServer, server)
go func() { _ = grpcServer.Serve(listener) }()
defer grpcServer.Stop()
conn, err := grpc.NewClient("passthrough:///bufnet", grpc.WithContextDialer(func(context.Context, string) (net.Conn, error) { return listener.Dial() }), grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
t.Fatal(err)
}
defer conn.Close()
coordinator := NewAgentCoordinator(func() time.Time { return time.Unix(100, 0) })
if err := coordinator.Register("agent-1", agentpb.NewAgentControlServiceClient(conn)); err != nil {
t.Fatal(err)
}
status, err := coordinator.Probe(context.Background(), "agent-1", "cell-1")
if err != nil {
t.Fatal(err)
}
if status.BootId != "boot-probed" || status.SessionActive {
t.Fatalf("unexpected pre-activation status: %+v", status)
}
if _, err := coordinator.Activate(context.Background(), "not-a-dispatcher", "agent-1", "cell-1", status.BootId, "epoch-1", 0); err == nil {
t.Fatal("unapproved Dispatcher identity was admitted")
}
first, err := coordinator.Activate(context.Background(), approvedTestDispatcherID, "agent-1", "cell-1", status.BootId, "epoch-1", 0)
if err != nil {
t.Fatal(err)
}
second, err := coordinator.Activate(context.Background(), approvedTestDispatcherID, "agent-1", "cell-1", status.BootId, "epoch-2", 0)
if err != nil {
t.Fatal(err)
}
third, err := coordinator.Activate(context.Background(), approvedTestDispatcherID, "agent-1", "cell-1", status.BootId, "epoch-2", 0)
if err != nil {
t.Fatal(err)
}
if first.SessionGeneration != 1 || second.SessionGeneration != 2 || third.SessionGeneration != 3 {
t.Fatalf("a new activation replayed an old session: first=%d second=%d third=%d", first.SessionGeneration, second.SessionGeneration, third.SessionGeneration)
}
one, err := coordinator.ApprovedMeta(context.Background(), "agent-1")
if err != nil {
t.Fatal(err)
}
two, err := coordinator.ApprovedMeta(context.Background(), "agent-1")
if err != nil {
t.Fatal(err)
}
if one.AgentId != "agent-1" || one.CellId != "cell-1" || one.BootId != status.BootId ||
one.DispatcherEpoch != "epoch-2" || one.SessionGeneration != 3 || one.RequestId == two.RequestId || one.OperationId == two.OperationId {
t.Fatal("approved metadata did not bind the latest unique Agent session")
}
if _, err := coordinator.ApprovedMeta(context.Background(), "unknown-agent"); err == nil {
t.Fatal("an unregistered Agent inherited another session")
}
coordinator.now = func() time.Time { return time.Date(2026, 9, 18, 1, 11, 0, 0, time.UTC) }
if _, err := coordinator.ApprovedMeta(context.Background(), "agent-1"); err == nil {
t.Fatal("expired Agent session authorized another operation")
}
}