89 lines
3.2 KiB
Go
89 lines
3.2 KiB
Go
package rpc
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
agentpb "git.ipao.vip/rogee/go-sip/gen/agent"
|
|
"git.ipao.vip/rogee/go-sip/internal/configread"
|
|
"git.ipao.vip/rogee/go-sip/internal/dispatcher"
|
|
"google.golang.org/grpc"
|
|
"google.golang.org/grpc/credentials/insecure"
|
|
"google.golang.org/grpc/test/bufconn"
|
|
)
|
|
|
|
func mockApprovedGRPC(t *testing.T, server *Server) agentpb.AgentControlServiceClient {
|
|
t.Helper()
|
|
listener := bufconn.Listen(1 << 20)
|
|
grpcServer := grpc.NewServer()
|
|
agentpb.RegisterAgentControlServiceServer(grpcServer, server)
|
|
go func() { _ = grpcServer.Serve(listener) }()
|
|
t.Cleanup(grpcServer.Stop)
|
|
t.Cleanup(func() { _ = listener.Close() })
|
|
conn, err := grpc.NewClient("bufnet",
|
|
grpc.WithContextDialer(func(context.Context, string) (net.Conn, error) { return listener.Dial() }),
|
|
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
|
)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Cleanup(func() { _ = conn.Close() })
|
|
return agentpb.NewAgentControlServiceClient(conn)
|
|
}
|
|
|
|
func TestApprovedDispatcherToAgentUnaryMockRetainsSnapshotAndOneShotCall(t *testing.T) {
|
|
now := time.Date(2026, 9, 20, 10, 0, 0, 0, time.UTC)
|
|
req := approvedTestRequest(t, now)
|
|
calls := 0
|
|
agent := activatedApprovedServer(t, now, filepath.Join(t.TempDir(), "agent-session.json"), req.DispatcherId, 1,
|
|
func(_ context.Context, call ApprovedExecution) error {
|
|
calls++
|
|
if call.SIPRevision != 8 || call.AI.Mode != "asr_only" || call.AI.ASR.Provider.Credential != "example-only-not-a-real-secret" || call.MaxCallDuration != 20*time.Second {
|
|
t.Fatal("Agent received the wrong frozen execution configuration")
|
|
}
|
|
return nil
|
|
})
|
|
client := mockApprovedGRPC(t, agent)
|
|
orig := &dispatcher.ApprovedOriginator{DispatcherID: req.DispatcherId, Client: client,
|
|
Meta: func(context.Context) (*agentpb.RequestMeta, error) { return testMeta("inspect-loaded", "", 1), nil },
|
|
}
|
|
sipJSON, err := os.ReadFile("../../contracts/local/examples/config-read-sip.json")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var sip configread.CurrentSIP
|
|
if err := json.Unmarshal(sipJSON, &sip); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var task configread.CurrentTask
|
|
if err := json.Unmarshal(req.TaskConfigJson, &task); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var providers map[string]configread.CurrentProvider
|
|
if err := json.Unmarshal(req.ProvidersJson, &providers); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
snapshot := configread.CurrentSnapshot{SIP: sip, Task: task, Providers: providers}
|
|
if err := orig.VerifySIP(context.Background(), sip); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
spec := dispatcher.CurrentCallSpec{
|
|
EventID: req.SourceEventId, TaskID: task.TaskID, TenantID: task.TenantID,
|
|
TrunkID: req.SelectedTrunkId, Callee: req.Callee, DialedCallee: req.DialedCallee,
|
|
CallerID: req.CallerId, RingTimeoutMS: req.RingTimeoutMs,
|
|
MaxCallDurationMS: req.MaxCallDurationMs, Deadline: time.UnixMilli(req.DialBeforeUnixMs),
|
|
Snapshot: snapshot,
|
|
}
|
|
if err := orig.Originate(context.Background(), spec); err != nil || calls != 1 {
|
|
t.Fatalf("approved mock call was not accepted once: calls=%d err=%v", calls, err)
|
|
}
|
|
if err := orig.Originate(context.Background(), spec); err == nil || calls != 1 {
|
|
t.Fatalf("duplicate unary call must not redial: calls=%d err=%v", calls, err)
|
|
}
|
|
}
|