chore: initialize go-sip repository
This commit is contained in:
@@ -0,0 +1,258 @@
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.ipao.vip/rogee/go-sip/contracts"
|
||||
agentv1 "git.ipao.vip/rogee/go-sip/gen/agent/v1"
|
||||
"git.ipao.vip/rogee/go-sip/internal/contract"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"google.golang.org/grpc/peer"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/grpc/test/bufconn"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func TestPeerCertificateAllowlist(t *testing.T) {
|
||||
_, allowedCert, _ := testCertificate(t, nil, nil, false, []string{"dispatcher.local"}, nil)
|
||||
fingerprint := CertificateFingerprint(allowedCert)
|
||||
server := NewServer(ServerOptions{RequirePeerCertificate: true, PeerCertificateFingerprints: map[string]struct{}{fingerprint: {}}})
|
||||
allowedContext := peer.NewContext(context.Background(), &peer.Peer{AuthInfo: credentials.TLSInfo{State: tls.ConnectionState{VerifiedChains: [][]*x509.Certificate{{allowedCert}}}}})
|
||||
if err := server.checkPeer(allowedContext, "agent-1"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, rejectedCert, _ := testCertificate(t, nil, nil, false, []string{"other-dispatcher.local"}, nil)
|
||||
rejectedContext := peer.NewContext(context.Background(), &peer.Peer{AuthInfo: credentials.TLSInfo{State: tls.ConnectionState{VerifiedChains: [][]*x509.Certificate{{rejectedCert}}}}})
|
||||
if err := server.checkPeer(rejectedContext, "agent-1"); status.Code(err) != codes.PermissionDenied {
|
||||
t.Fatalf("got %v, want PermissionDenied", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAgentStatusSupportsPreActivationProbe(t *testing.T) {
|
||||
now := time.Unix(100, 0)
|
||||
server := NewServer(ServerOptions{
|
||||
Now: func() time.Time { return now },
|
||||
Status: &agentv1.AgentStatus{
|
||||
AgentId: "agent-1",
|
||||
CellId: "cell-1",
|
||||
BootId: "boot-current",
|
||||
SoftwareVersion: "test",
|
||||
ProtocolVersion: "agent.v1",
|
||||
AdmissionState: agentv1.AdmissionState_ADMISSION_STATE_CLOSED,
|
||||
},
|
||||
})
|
||||
response, err := server.GetAgentStatus(context.Background(), &agentv1.GetAgentStatusRequest{
|
||||
Meta: &agentv1.RequestMeta{ProtocolVersion: "agent.v1", RequestId: "probe-request", TraceId: "probe-trace", OperationId: "probe-operation", AgentId: "agent-1", CellId: "cell-1"},
|
||||
Target: &agentv1.AgentBinding{AgentId: "agent-1", CellId: "cell-1"},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "boot-current", response.Status.BootId)
|
||||
require.Equal(t, false, response.Status.SessionActive)
|
||||
require.Equal(t, false, response.Status.MtlsAuthenticated)
|
||||
|
||||
active := activatedServer(now, t)
|
||||
activeResponse, err := active.GetAgentStatus(context.Background(), &agentv1.GetAgentStatusRequest{Meta: testMeta("status-active", "status-active-key", 1), Target: &agentv1.AgentBinding{AgentId: "agent-1", CellId: "cell-1"}})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, true, activeResponse.Status.SessionActive)
|
||||
}
|
||||
|
||||
func TestAgentIdentityIsBoundToConfiguredEndpoint(t *testing.T) {
|
||||
server := NewServer(ServerOptions{Status: &agentv1.AgentStatus{AgentId: "agent-1", CellId: "cell-1"}})
|
||||
_, err := server.GetAgentStatus(context.Background(), &agentv1.GetAgentStatusRequest{
|
||||
Meta: &agentv1.RequestMeta{ProtocolVersion: "agent.v1", RequestId: "wrong-probe", TraceId: "wrong-probe", OperationId: "wrong-probe", AgentId: "agent-2", CellId: "cell-2"},
|
||||
Target: &agentv1.AgentBinding{AgentId: "agent-2", CellId: "cell-2"},
|
||||
})
|
||||
require.Equal(t, codes.PermissionDenied, status.Code(err))
|
||||
|
||||
_, err = server.ActivateAgent(context.Background(), &agentv1.ActivateAgentRequest{
|
||||
Meta: &agentv1.RequestMeta{ProtocolVersion: "agent.v1", RequestId: "wrong-activate", TraceId: "wrong-activate", OperationId: "wrong-activate", AgentId: "agent-2", CellId: "cell-2", BootId: "boot-2", DispatcherEpoch: "epoch-2"},
|
||||
Binding: &agentv1.AgentBinding{AgentId: "agent-2", CellId: "cell-2", ExpectedBootId: "boot-2", DispatcherEpoch: "epoch-2", SessionGeneration: 1},
|
||||
ActivationOperationId: "wrong-activate",
|
||||
})
|
||||
require.Equal(t, codes.PermissionDenied, status.Code(err))
|
||||
}
|
||||
|
||||
func TestSessionGenerationFencesOlderRequests(t *testing.T) {
|
||||
now := time.Unix(100, 0)
|
||||
server := NewServer(ServerOptions{Now: func() time.Time { return now }})
|
||||
firstMeta := testMeta("activate-1", "", 0)
|
||||
firstMeta.OperationId = "activate-1"
|
||||
_, err := server.ActivateAgent(context.Background(), &agentv1.ActivateAgentRequest{
|
||||
Meta: firstMeta,
|
||||
Binding: &agentv1.AgentBinding{AgentId: "agent-1", CellId: "cell-1", ExpectedBootId: "boot-1", DispatcherEpoch: "epoch-1", SessionGeneration: 1},
|
||||
ActivationOperationId: "activate-1",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
secondMeta := testMeta("activate-2", "", 0)
|
||||
secondMeta.BootId = "boot-2"
|
||||
secondMeta.OperationId = "activate-2"
|
||||
_, err = server.ActivateAgent(context.Background(), &agentv1.ActivateAgentRequest{
|
||||
Meta: secondMeta,
|
||||
Binding: &agentv1.AgentBinding{AgentId: "agent-1", CellId: "cell-1", ExpectedBootId: "boot-2", DispatcherEpoch: "epoch-2", SessionGeneration: 2},
|
||||
ActivationOperationId: "activate-2",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = server.GetBootstrap(context.Background(), &agentv1.GetBootstrapRequest{Meta: testMeta("old", "read-old", 1)})
|
||||
require.Error(t, err)
|
||||
require.Equal(t, codes.Aborted, status.Code(err))
|
||||
fresh := testMeta("fresh", "read-fresh", 2)
|
||||
fresh.BootId = "boot-2"
|
||||
fresh.DispatcherEpoch = "epoch-2"
|
||||
_, err = server.GetBootstrap(context.Background(), &agentv1.GetBootstrapRequest{Meta: fresh})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestExecuteIdempotencyAndBinding(t *testing.T) {
|
||||
now := time.Date(2026, 9, 18, 1, 0, 0, 0, time.UTC)
|
||||
server := activatedServer(now, t)
|
||||
raw, err := contracts.Read("examples/call.execute.json")
|
||||
require.NoError(t, err)
|
||||
envelope, payload, err := contract.DecodeExecute(raw)
|
||||
require.NoError(t, err)
|
||||
meta := testMeta("execute-1", "execute-key", 1)
|
||||
req := &agentv1.ExecuteRequest{Meta: meta, Binding: &agentv1.ExecutionBinding{TenantId: envelope.TenantID, TenantKey: envelope.TenantKey, ExecutionId: payload.ExecutionID, TaskId: payload.TaskID, TaskItemId: payload.TaskItemID, TaskRevision: payload.TaskRevision, AgentVersionId: payload.AgentVersionID}, CallExecuteJson: raw, ConfigSha256: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}
|
||||
first, err := server.Execute(context.Background(), req)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, agentv1.ResultCode_RESULT_CODE_ACCEPTED, first.Receipt.Result)
|
||||
replay, err := server.Execute(context.Background(), req)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, first.Receipt.Meta.OperationId, replay.Receipt.Meta.OperationId)
|
||||
conflictReq := proto.Clone(req).(*agentv1.ExecuteRequest)
|
||||
conflictReq.ConfigSha256 = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
|
||||
conflict, err := server.Execute(context.Background(), conflictReq)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, agentv1.ResultCode_RESULT_CODE_CONFLICT, conflict.Receipt.Result)
|
||||
}
|
||||
|
||||
func TestRealModeRejectsExecutionOutsideCallWindow(t *testing.T) {
|
||||
server := NewServer(ServerOptions{
|
||||
Mode: "mixed",
|
||||
Now: func() time.Time { return time.Date(2026, 9, 18, 12, 0, 0, 0, time.UTC) },
|
||||
})
|
||||
activateTestServer(t, server)
|
||||
response, err := server.GetExecutionPermit(context.Background(), &agentv1.GetExecutionPermitRequest{
|
||||
Meta: testMeta("permit-window", "permit-window-key", 1),
|
||||
Binding: &agentv1.ExecutionBinding{ExecutionId: "execution-window"},
|
||||
ResourceReservationId: "reservation-window",
|
||||
})
|
||||
if response != nil || status.Code(err) != codes.FailedPrecondition {
|
||||
t.Fatalf("response=%+v err=%v code=%s", response, err, status.Code(err))
|
||||
}
|
||||
}
|
||||
|
||||
func TestRealModeRejectsMockUploadDataPlane(t *testing.T) {
|
||||
server := NewServer(ServerOptions{Mode: "real"})
|
||||
response, err := server.RequestUpload(context.Background(), &agentv1.RequestUploadRequest{})
|
||||
if response != nil || status.Code(err) != codes.Unimplemented {
|
||||
t.Fatalf("response=%+v err=%v code=%s", response, err, status.Code(err))
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdmissionAndControlCAS(t *testing.T) {
|
||||
server := activatedServer(time.Date(2026, 9, 18, 1, 0, 0, 0, time.UTC), t)
|
||||
meta := testMeta("admission-1", "admission-key", 1)
|
||||
admission, err := server.SetAdmissionState(context.Background(), &agentv1.SetAdmissionStateRequest{Meta: meta, Target: &agentv1.AgentBinding{AgentId: "agent-1", CellId: "cell-1"}, State: agentv1.AdmissionState_ADMISSION_STATE_OPEN})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), admission.AppliedAdmissionGeneration)
|
||||
conflict, err := server.SetAdmissionState(context.Background(), &agentv1.SetAdmissionStateRequest{Meta: testMeta("admission-2", "admission-key-2", 1), Target: &agentv1.AgentBinding{AgentId: "agent-1", CellId: "cell-1"}, State: agentv1.AdmissionState_ADMISSION_STATE_CLOSED})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, agentv1.ResultCode_RESULT_CODE_CONFLICT, conflict.Receipt.Result)
|
||||
|
||||
raw, err := contracts.Read("examples/call.execute.json")
|
||||
require.NoError(t, err)
|
||||
envelope, payload, err := contract.DecodeExecute(raw)
|
||||
require.NoError(t, err)
|
||||
executeMeta := testMeta("execute-control", "execute-control-key", 1)
|
||||
_, err = server.Execute(context.Background(), &agentv1.ExecuteRequest{Meta: executeMeta, Binding: &agentv1.ExecutionBinding{TenantId: envelope.TenantID, TenantKey: envelope.TenantKey, ExecutionId: payload.ExecutionID, TaskId: payload.TaskID, TaskItemId: payload.TaskItemID, TaskRevision: payload.TaskRevision, AgentVersionId: payload.AgentVersionID}, CallExecuteJson: raw, ConfigSha256: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"})
|
||||
require.NoError(t, err)
|
||||
controlMeta := testMeta("control-1", "control-key", 1)
|
||||
paused, err := server.ApplyTaskControl(context.Background(), &agentv1.ApplyTaskControlRequest{Meta: controlMeta, Binding: &agentv1.ExecutionBinding{ExecutionId: payload.ExecutionID, TaskRevision: payload.TaskRevision}, Action: agentv1.ControlAction_CONTROL_ACTION_PAUSE, ExpectedTaskRevision: payload.TaskRevision})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, agentv1.ResultCode_RESULT_CODE_APPLIED, paused.Receipt.Result)
|
||||
stopped, err := server.ApplyTaskControl(context.Background(), &agentv1.ApplyTaskControlRequest{Meta: testMeta("control-2", "control-key-2", 1), Binding: &agentv1.ExecutionBinding{ExecutionId: payload.ExecutionID, TaskRevision: paused.AppliedTaskRevision}, Action: agentv1.ControlAction_CONTROL_ACTION_STOP, ExpectedTaskRevision: paused.AppliedTaskRevision})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, agentv1.ExecutionState_EXECUTION_STATE_TERMINAL, stopped.State)
|
||||
resumed, err := server.ApplyTaskControl(context.Background(), &agentv1.ApplyTaskControlRequest{Meta: testMeta("control-3", "control-key-3", 1), Binding: &agentv1.ExecutionBinding{ExecutionId: payload.ExecutionID, TaskRevision: stopped.AppliedTaskRevision}, Action: agentv1.ControlAction_CONTROL_ACTION_RESUME, ExpectedTaskRevision: stopped.AppliedTaskRevision})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, agentv1.ResultCode_RESULT_CODE_REJECTED, resumed.Receipt.Result)
|
||||
}
|
||||
|
||||
func TestFactDeduplication(t *testing.T) {
|
||||
server := activatedServer(time.Unix(100, 0), t)
|
||||
fact := &agentv1.ExecutionFact{FactId: "fact-1", ContentSha256: "digest-a", Binding: &agentv1.ExecutionBinding{ExecutionId: "execution-1"}, Kind: agentv1.FactKind_FACT_KIND_CALL_STATUS}
|
||||
first, err := server.ReportExecutionEvent(context.Background(), &agentv1.ReportExecutionEventRequest{Meta: testMeta("fact-1", "fact-key-1", 1), Fact: fact})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, agentv1.ResultCode_RESULT_CODE_ACCEPTED, first.Receipt.Result)
|
||||
replay, err := server.ReportExecutionEvent(context.Background(), &agentv1.ReportExecutionEventRequest{Meta: testMeta("fact-2", "fact-key-2", 1), Fact: fact})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, agentv1.ResultCode_RESULT_CODE_ACCEPTED, replay.Receipt.Result)
|
||||
fact.ContentSha256 = "digest-b"
|
||||
conflict, err := server.ReportExecutionEvent(context.Background(), &agentv1.ReportExecutionEventRequest{Meta: testMeta("fact-3", "fact-key-3", 1), Fact: fact})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, agentv1.ResultCode_RESULT_CODE_CONFLICT, conflict.Receipt.Result)
|
||||
}
|
||||
|
||||
func TestGeneratedUnaryServiceWiring(t *testing.T) {
|
||||
server := NewServer(ServerOptions{Now: func() time.Time { return time.Unix(100, 0) }})
|
||||
listener := bufconn.Listen(1024 * 1024)
|
||||
grpcServer := grpc.NewServer()
|
||||
agentv1.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()))
|
||||
require.NoError(t, err)
|
||||
defer conn.Close()
|
||||
client := agentv1.NewAgentControlServiceClient(conn)
|
||||
meta := testMeta("activate-rpc", "", 0)
|
||||
response, err := client.ActivateAgent(context.Background(), &agentv1.ActivateAgentRequest{Meta: meta, Binding: &agentv1.AgentBinding{AgentId: "agent-1", CellId: "cell-1", ExpectedBootId: "boot-1", DispatcherEpoch: "epoch-1", SessionGeneration: 1}, ActivationOperationId: "activate-rpc"})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, agentv1.ActivationState_ACTIVATION_STATE_ACTIVE, response.State)
|
||||
}
|
||||
|
||||
func activatedServer(now time.Time, t *testing.T) *Server {
|
||||
t.Helper()
|
||||
server := NewServer(ServerOptions{Now: func() time.Time { return now }, UploadPolicy: &agentv1.UploadPolicy{Enabled: true, MaxAssetBytes: 16 << 20}})
|
||||
meta := testMeta("activate", "", 0)
|
||||
_, err := server.ActivateAgent(context.Background(), &agentv1.ActivateAgentRequest{Meta: meta, Binding: &agentv1.AgentBinding{AgentId: "agent-1", CellId: "cell-1", ExpectedBootId: "boot-1", DispatcherEpoch: "epoch-1", SessionGeneration: 1}, ActivationOperationId: "activate"})
|
||||
require.NoError(t, err)
|
||||
return server
|
||||
}
|
||||
|
||||
type testAssertions struct{}
|
||||
|
||||
var require testAssertions
|
||||
|
||||
func (testAssertions) NoError(t *testing.T, err error, _ ...any) {
|
||||
t.Helper()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (testAssertions) Error(t *testing.T, err error, _ ...any) {
|
||||
t.Helper()
|
||||
if err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
}
|
||||
|
||||
func (testAssertions) Equal(t *testing.T, expected, actual any, _ ...any) {
|
||||
t.Helper()
|
||||
if !reflect.DeepEqual(expected, actual) {
|
||||
t.Fatalf("expected %#v, got %#v", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func testMeta(operationID, idempotencyKey string, generation uint64) *agentv1.RequestMeta {
|
||||
return &agentv1.RequestMeta{ProtocolVersion: "agent.v1", RequestId: operationID + "-request", TraceId: "trace-1", OperationId: operationID, IdempotencyKey: idempotencyKey, DispatcherEpoch: "epoch-1", AgentId: "agent-1", CellId: "cell-1", BootId: "boot-1", SessionGeneration: generation}
|
||||
}
|
||||
Reference in New Issue
Block a user