96 lines
4.8 KiB
Go
96 lines
4.8 KiB
Go
package rpc
|
|
|
|
import (
|
|
"context"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
agentpb "git.ipao.vip/rogee/go-sip/gen/agent"
|
|
"git.ipao.vip/rogee/go-sip/internal/agent"
|
|
"google.golang.org/grpc/codes"
|
|
"google.golang.org/grpc/status"
|
|
)
|
|
|
|
func TestApprovedTaskControlRequiresCurrentSessionAndValidTaskPolicy(t *testing.T) {
|
|
now := time.Date(2026, 9, 20, 10, 0, 0, 0, time.UTC)
|
|
execution := approvedTestRequest(t, now)
|
|
server := activatedApprovedServer(t, now, filepath.Join(t.TempDir(), "agent-session.json"), execution.DispatcherId, 1, nil)
|
|
server.approvedTaskCalls = &agent.TaskCalls{}
|
|
request := &agentpb.ApplyApprovedTaskControlRequest{
|
|
Meta: testMeta("control-1", "", 1), DispatcherId: execution.DispatcherId,
|
|
TenantId: execution.TenantId, TaskId: execution.TaskId,
|
|
Action: agentpb.ControlAction_CONTROL_ACTION_PAUSE, ActiveCallPolicy: agentpb.ActiveCallPolicy_ACTIVE_CALL_POLICY_HANGUP,
|
|
}
|
|
response, err := server.ApplyApprovedTaskControl(context.Background(), request)
|
|
if err != nil || response == nil || !response.Accepted {
|
|
t.Fatalf("authenticated task pause was not applied: response=%v err=%v", response, err)
|
|
}
|
|
// A second delivery is a second control attempt, not an internal command-ID replay.
|
|
if response, err = server.ApplyApprovedTaskControl(context.Background(), request); err != nil || response == nil || !response.Accepted {
|
|
t.Fatalf("repeat pause was silently deduplicated or rejected: response=%v err=%v", response, err)
|
|
}
|
|
request.DispatcherId = "another-dispatcher"
|
|
if _, err := server.ApplyApprovedTaskControl(context.Background(), request); status.Code(err) != codes.PermissionDenied {
|
|
t.Fatalf("foreign Dispatcher was admitted: %v", err)
|
|
}
|
|
request.DispatcherId = execution.DispatcherId
|
|
request.Meta.SessionGeneration = 2
|
|
if _, err := server.ApplyApprovedTaskControl(context.Background(), request); status.Code(err) != codes.Aborted {
|
|
t.Fatalf("stale or unknown session was admitted: %v", err)
|
|
}
|
|
request.Meta.SessionGeneration = 1
|
|
request.TenantId = 0
|
|
if _, err := server.ApplyApprovedTaskControl(context.Background(), request); status.Code(err) != codes.InvalidArgument {
|
|
t.Fatalf("control without a numeric tenant was admitted: %v", err)
|
|
}
|
|
request.TenantId = execution.TenantId
|
|
request.Action = agentpb.ControlAction_CONTROL_ACTION_RESUME
|
|
if _, err := server.ApplyApprovedTaskControl(context.Background(), request); status.Code(err) != codes.InvalidArgument {
|
|
t.Fatalf("resume with a hangup policy was admitted: %v", err)
|
|
}
|
|
request.ActiveCallPolicy = agentpb.ActiveCallPolicy_ACTIVE_CALL_POLICY_UNSPECIFIED
|
|
if response, err := server.ApplyApprovedTaskControl(context.Background(), request); err != nil || response == nil || !response.Accepted {
|
|
t.Fatalf("approved resume was not applied: response=%v err=%v", response, err)
|
|
}
|
|
server.approvedTaskCalls = nil
|
|
if _, err := server.ApplyApprovedTaskControl(context.Background(), request); status.Code(err) != codes.FailedPrecondition {
|
|
t.Fatalf("missing Agent control adapter reported success: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestApprovedTaskStopDrainRetainsBarrierAcrossTimeoutAndRedelivery(t *testing.T) {
|
|
now := time.Date(2026, 9, 20, 10, 0, 0, 0, time.UTC)
|
|
execution := approvedTestRequest(t, now)
|
|
server := activatedApprovedServer(t, now, filepath.Join(t.TempDir(), "agent-session.json"), execution.DispatcherId, 1, nil)
|
|
calls := &agent.TaskCalls{}
|
|
server.approvedTaskCalls = calls
|
|
task := agent.TaskIdentity{DispatcherID: execution.DispatcherId, TenantID: execution.TenantId, TaskID: execution.TaskId}
|
|
release, err := calls.Register(task, "active-call", func() {})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
request := &agentpb.ApplyApprovedTaskControlRequest{
|
|
Meta: testMeta("stop", "", 1), DispatcherId: execution.DispatcherId,
|
|
TenantId: execution.TenantId, TaskId: execution.TaskId,
|
|
Action: agentpb.ControlAction_CONTROL_ACTION_STOP, ActiveCallPolicy: agentpb.ActiveCallPolicy_ACTIVE_CALL_POLICY_DRAIN,
|
|
}
|
|
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Millisecond)
|
|
defer cancel()
|
|
if _, err := server.ApplyApprovedTaskControl(ctx, request); status.Code(err) != codes.DeadlineExceeded {
|
|
t.Fatalf("stop/drain acknowledged before active call ended: %v", err)
|
|
}
|
|
request.Action = agentpb.ControlAction_CONTROL_ACTION_RESUME
|
|
request.ActiveCallPolicy = agentpb.ActiveCallPolicy_ACTIVE_CALL_POLICY_UNSPECIFIED
|
|
if _, err := server.ApplyApprovedTaskControl(context.Background(), request); status.Code(err) != codes.FailedPrecondition {
|
|
t.Fatalf("stopped task resumed after a timed-out drain: %v", err)
|
|
}
|
|
release()
|
|
request.Action = agentpb.ControlAction_CONTROL_ACTION_STOP
|
|
request.ActiveCallPolicy = agentpb.ActiveCallPolicy_ACTIVE_CALL_POLICY_DRAIN
|
|
response, err := server.ApplyApprovedTaskControl(context.Background(), request)
|
|
if err != nil || response == nil || !response.Accepted {
|
|
t.Fatalf("explicit redelivery of stopped task did not drain: response=%v err=%v", response, err)
|
|
}
|
|
}
|