115 lines
4.6 KiB
Go
115 lines
4.6 KiB
Go
package dispatcher
|
|
|
|
import (
|
|
"context"
|
|
"net"
|
|
"testing"
|
|
"time"
|
|
|
|
agentpb "git.ipao.vip/rogee/go-sip/gen/agent"
|
|
"git.ipao.vip/rogee/go-sip/internal/contract"
|
|
rpcserver "git.ipao.vip/rogee/go-sip/internal/rpc"
|
|
"git.ipao.vip/rogee/go-sip/internal/testfixture"
|
|
"google.golang.org/grpc"
|
|
"google.golang.org/grpc/credentials/insecure"
|
|
"google.golang.org/grpc/test/bufconn"
|
|
)
|
|
|
|
func TestAgentCoordinatorProbesBeforeActivation(t *testing.T) {
|
|
listener := bufconn.Listen(1024 * 1024)
|
|
server := rpcserver.NewServer(rpcserver.ServerOptions{
|
|
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)
|
|
}
|
|
first, err := coordinator.Activate(context.Background(), "agent-1", "cell-1", status.BootId, "epoch-1", 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
second, err := coordinator.Activate(context.Background(), "agent-1", "cell-1", status.BootId, "epoch-2", 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if first.SessionGeneration != 1 || second.SessionGeneration != 2 {
|
|
t.Fatalf("unexpected generations: first=%d second=%d", first.SessionGeneration, second.SessionGeneration)
|
|
}
|
|
}
|
|
|
|
func TestAgentCoordinatorActivatesExecutesAndControlsWithoutRetryingOriginate(t *testing.T) {
|
|
listener := bufconn.Listen(1024 * 1024)
|
|
server := rpcserver.NewServer(rpcserver.ServerOptions{Now: func() time.Time { return time.Date(2026, 9, 18, 1, 0, 0, 0, time.UTC) }})
|
|
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.Date(2026, 9, 18, 1, 0, 0, 0, time.UTC) })
|
|
if err := coordinator.Register("agent-1", agentpb.NewAgentControlServiceClient(conn)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := coordinator.Activate(context.Background(), "agent-1", "cell-1", "boot-1", "epoch-1", 1); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
raw, err := testfixture.Execute()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
envelope, payload, err := contract.DecodeExecute(raw)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
binding := &agentpb.ExecutionBinding{TenantId: envelope.TenantID, TenantKey: envelope.TenantKey, ExecutionId: payload.ExecutionID, TaskId: payload.TaskID, TaskItemId: payload.TaskItemID, TaskRevision: payload.TaskRevision, AgentVersionId: payload.AgentVersionID, RoutePolicyId: payload.RoutePolicyID, CallerProfileId: payload.CallerProfileID}
|
|
first, err := coordinator.ExecuteRaw(context.Background(), "agent-1", binding, raw, "reservation-1", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if first.Permit == nil || first.Receipt == nil || first.Unknown {
|
|
t.Fatalf("unexpected dispatch result: %+v", first)
|
|
}
|
|
second, err := coordinator.ExecuteRaw(context.Background(), "agent-1", binding, raw, "reservation-1", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if second.Permit == nil || second.Receipt == nil || second.Unknown {
|
|
t.Fatalf("unexpected replay result: %+v", second)
|
|
}
|
|
control, err := coordinator.Control(context.Background(), "agent-1", binding, agentpb.ControlAction_CONTROL_ACTION_PAUSE, agentpb.ActiveCallPolicy_ACTIVE_CALL_POLICY_DRAIN)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if control.Receipt == nil || control.State != agentpb.ExecutionState_EXECUTION_STATE_PERMIT_GRANTED {
|
|
t.Fatalf("unexpected control result: %+v", control)
|
|
}
|
|
}
|