package protocol_test import ( "os" "reflect" "strings" "testing" protocol "git.sechmachine.io.vn/sechmachine/VerseVDI-Protocol/gen/go/protocol" ) func TestRC6GeneratedContractsHaveFrozenExactShapes(t *testing.T) { tests := []struct { value any fields []string }{ {protocol.VideoProfile{}, []string{"Codec", "BitDepth", "ChromaSubsampling", "ColorSpace", "TransferFunction"}}, {protocol.AudioProfile{}, []string{"Codec", "SampleRateHz", "Channels", "ChannelLayout", "PacketDurationMs"}}, {protocol.BitratePreference{}, []string{"Mode", "TargetKbps"}}, {protocol.SessionQualityLimits{}, []string{"PolicyVersionID", "PolicyDisplayLimit", "SelectableDisplayMaximum", "DisplayLimitOverride", "BitrateMinimumKbps", "BitrateTargetKbps", "BitrateMaximumKbps"}}, {protocol.SessionAdjustment{}, []string{"DisplayReason", "BitrateReason"}}, {protocol.SelectedSessionDescriptor{}, []string{"VideoProfile", "AudioProfile", "DisplayMode", "BitrateTargetKbps", "BitrateMaximumKbps", "Adjustment", "MediaTimestampBasis"}}, } for _, test := range tests { typeOf := reflect.TypeOf(test.value) if typeOf.NumField() != len(test.fields) { t.Fatalf("%s field count = %d, want %d", typeOf.Name(), typeOf.NumField(), len(test.fields)) } for index, field := range test.fields { if typeOf.Field(index).Name != field { t.Fatalf("%s field %d = %s, want %s", typeOf.Name(), index, typeOf.Field(index).Name, field) } } } } func TestRC6ProfileValidationAndOrderedIntersection(t *testing.T) { h264 := protocol.VideoProfile{Codec: "h264", BitDepth: 8, ChromaSubsampling: "4:2:0", ColorSpace: "bt709-limited", TransferFunction: "sdr"} hevc := h264 hevc.Codec = "hevc" audio := protocol.AudioProfile{Codec: "opus", SampleRateHz: 48000, Channels: 2, ChannelLayout: "stereo", PacketDurationMs: 5} first := protocol.CapabilityProfile{Transport: "quic-tls13", Framing: "datagram-v2", Media: "encoded", SourceRateControl: "server", VideoProfiles: []protocol.VideoProfile{h264, hevc}, AudioProfiles: []protocol.AudioProfile{audio}} second := first second.VideoProfiles = []protocol.VideoProfile{hevc, h264} selected, err := protocol.IntersectCapabilityProfiles(first, second) if err != nil || !reflect.DeepEqual(selected.VideoProfiles, []protocol.VideoProfile{h264, hevc}) { t.Fatalf("ordered intersection = %+v, %v", selected.VideoProfiles, err) } duplicate := first duplicate.VideoProfiles = []protocol.VideoProfile{h264, h264} if duplicate.Validate() == nil { t.Fatal("CapabilityProfile accepted duplicate video profiles") } invalid := h264 invalid.BitDepth = 10 if invalid.Validate() == nil { t.Fatal("VideoProfile accepted a non-RC6 bit depth") } } func TestRC6StrictDecodeRejectsLegacyAndMalformedBodies(t *testing.T) { for name, test := range map[string]struct { payload []byte decode func([]byte) error }{ "opaque capability": {[]byte(`{"transport":"quic-tls13","framing":"datagram-v2","media":"encoded","audio":"encoded","source_rate_control":"server","client_decode":["h264-opus"]}`), func(raw []byte) error { _, err := protocol.DecodeCapabilityProfile(raw); return err }}, "old session request": {[]byte(`{"client_device_id":"device-1","device_key_id":"key-1","pool_id":"pool-1","idempotency_key":"request-1"}`), func(raw []byte) error { _, err := protocol.DecodeSessionRequest(raw); return err }}, "old provider policy": {[]byte(`{"resolution_width":1920,"resolution_height":1080,"fps":60,"codec":"H264","bitrate_kbps":20000,"audio_enabled":true}`), func(raw []byte) error { _, err := protocol.DecodeProviderStreamPolicy(raw); return err }}, "unknown field": {[]byte(`{"mode":"explicit","target_kbps":1000,"unknown":true}`), func(raw []byte) error { _, err := protocol.DecodeBitratePreference(raw); return err }}, "duplicate key": {[]byte(`{"mode":"explicit","mode":"auto","target_kbps":1000}`), func(raw []byte) error { _, err := protocol.DecodeBitratePreference(raw); return err }}, "trailing JSON": {[]byte(`{"mode":"explicit","target_kbps":1000} {}`), func(raw []byte) error { _, err := protocol.DecodeBitratePreference(raw); return err }}, } { if err := test.decode(test.payload); err == nil { t.Fatalf("RC6 accepted %s", name) } } } func TestRC6BitratePreferenceTaggedBounds(t *testing.T) { for _, valid := range []protocol.BitratePreference{{Mode: "auto"}, {Mode: "explicit", TargetKbps: int64Pointer(100)}, {Mode: "explicit", TargetKbps: int64Pointer(1_000_000)}} { if err := valid.Validate(); err != nil { t.Fatalf("valid preference %+v rejected: %v", valid, err) } } for _, invalid := range []protocol.BitratePreference{{Mode: "auto", TargetKbps: int64Pointer(100)}, {Mode: "explicit"}, {Mode: "explicit", TargetKbps: int64Pointer(99)}, {Mode: "explicit", TargetKbps: int64Pointer(1_000_001)}} { if invalid.Validate() == nil { t.Fatalf("invalid preference %+v accepted", invalid) } } } func TestRC6GatewayQualityDiscoveryAndLeaseFencing(t *testing.T) { operationID := "12345678-1234-1234-1234-123456789abc" revision := int64(7) leaseGeneration := int64(3) currentRevision := int64(6) poll := protocol.GatewayQualityWorkRequest{Version: "1", SessionID: "session-1", GatewayID: "gateway-1", ReconnectSequence: 2, Acquisition: "poll"} if err := poll.Validate(); err != nil { t.Fatalf("session-bound lost-prompt poll rejected: %v", err) } prompt := poll prompt.Acquisition = "prompt" prompt.OperationID = operationID prompt.Revision = &revision if err := prompt.Validate(); err != nil { t.Fatalf("prompt-bound acquisition rejected: %v", err) } observation := prompt observation.Acquisition = "observation" observation.LeaseGeneration = &leaseGeneration observation.CurrentAppliedRevision = ¤tRevision if err := observation.Validate(); err != nil { t.Fatalf("lease-bound applied-revision observation rejected: %v", err) } for name, invalid := range map[string]protocol.GatewayQualityWorkRequest{ "poll with unknown coordinates": prompt, "prompt missing revision": {Version: "1", SessionID: "session-1", GatewayID: "gateway-1", Acquisition: "prompt", OperationID: operationID}, "observation missing lease": {Version: "1", SessionID: "session-1", GatewayID: "gateway-1", Acquisition: "observation", OperationID: operationID, Revision: &revision, CurrentAppliedRevision: ¤tRevision}, } { if name == "poll with unknown coordinates" { invalid.Acquisition = "poll" } if invalid.Validate() == nil { t.Fatalf("accepted invalid %s: %+v", name, invalid) } } stopPoll := protocol.GatewayStopWorkRequest{Version: "1", SessionID: "session-1", GatewayID: "gateway-1", ReconnectSequence: 2, Acquisition: "poll"} if err := stopPoll.Validate(); err != nil { t.Fatalf("session-bound Stop poll rejected: %v", err) } stopPrompt := stopPoll stopPrompt.Acquisition = "prompt" stopPrompt.OperationID = operationID if err := stopPrompt.Validate(); err != nil { t.Fatalf("prompt-bound Stop acquisition rejected: %v", err) } stopPoll.OperationID = operationID if stopPoll.Validate() == nil { t.Fatal("Stop poll accepted unknown operation coordinates") } } func TestRC6GatewayQualityAckHasUnambiguousObservation(t *testing.T) { revision := int64(7) prior := int64(6) base := protocol.GatewayQualityAck{ Version: "1", SessionID: "session-1", GatewayID: "gateway-1", ReconnectSequence: 2, OperationID: "12345678-1234-1234-1234-123456789abc", Revision: revision, LeaseGeneration: 3, } for _, valid := range []protocol.GatewayQualityAck{ func() protocol.GatewayQualityAck { value := base value.Outcome = "applied" value.CurrentAppliedRevision = &revision return value }(), func() protocol.GatewayQualityAck { value := base value.Outcome = "proven_prior" value.CurrentAppliedRevision = &prior return value }(), func() protocol.GatewayQualityAck { value := base; value.Outcome = "unknown"; return value }(), } { if err := valid.Validate(); err != nil { t.Fatalf("valid quality acknowledgement rejected: %+v: %v", valid, err) } } for _, invalid := range []protocol.GatewayQualityAck{ func() protocol.GatewayQualityAck { value := base value.Outcome = "applied" value.CurrentAppliedRevision = &prior return value }(), func() protocol.GatewayQualityAck { value := base value.Outcome = "proven_prior" value.CurrentAppliedRevision = &revision return value }(), func() protocol.GatewayQualityAck { value := base value.Outcome = "unknown" value.CurrentAppliedRevision = &prior return value }(), func() protocol.GatewayQualityAck { value := base value.Outcome = "unknown" value.LeaseGeneration = 0 return value }(), } { if invalid.Validate() == nil { t.Fatalf("contradictory or unfenced quality acknowledgement accepted: %+v", invalid) } } } func TestRC6JSONFixturesAndCanonicalOperationFields(t *testing.T) { validFixtures := map[string]func([]byte) error{ "../../fixtures/valid/session-request.json": func(raw []byte) error { _, err := protocol.DecodeSessionRequest(raw); return err }, "../../fixtures/valid/selected-session-descriptor.json": func(raw []byte) error { _, err := protocol.DecodeSelectedSessionDescriptor(raw); return err }, "../../fixtures/valid/session-quality-limits.json": func(raw []byte) error { _, err := protocol.DecodeSessionQualityLimits(raw); return err }, "../../fixtures/valid/gateway-quality-poll.json": func(raw []byte) error { _, err := protocol.DecodeGatewayQualityWorkRequest(raw); return err }, "../../fixtures/valid/gateway-quality-ack-applied.json": func(raw []byte) error { _, err := protocol.DecodeGatewayQualityAck(raw); return err }, } for path, decode := range validFixtures { raw, err := os.ReadFile(path) if err != nil { t.Fatalf("read valid fixture %s: %v", path, err) } if err := decode(raw); err != nil { t.Fatalf("valid fixture %s rejected: %v", path, err) } } invalidFixtures := map[string]func([]byte) error{ "../../fixtures/invalid/capability-rc5-opaque.json": func(raw []byte) error { _, err := protocol.DecodeCapabilityProfile(raw); return err }, "../../fixtures/invalid/session-request-rc5.json": func(raw []byte) error { _, err := protocol.DecodeSessionRequest(raw); return err }, "../../fixtures/invalid/provider-stream-policy-rc5.json": func(raw []byte) error { _, err := protocol.DecodeProviderStreamPolicy(raw); return err }, "../../fixtures/invalid/video-profile-unknown.json": func(raw []byte) error { _, err := protocol.DecodeVideoProfile(raw); return err }, "../../fixtures/invalid/bitrate-preference-auto-target.json": func(raw []byte) error { _, err := protocol.DecodeBitratePreference(raw); return err }, "../../fixtures/invalid/selected-session-descriptor-provider-field.json": func(raw []byte) error { _, err := protocol.DecodeSelectedSessionDescriptor(raw); return err }, "../../fixtures/invalid/gateway-quality-poll-coordinates.json": func(raw []byte) error { _, err := protocol.DecodeGatewayQualityWorkRequest(raw); return err }, "../../fixtures/invalid/gateway-quality-ack-contradictory.json": func(raw []byte) error { _, err := protocol.DecodeGatewayQualityAck(raw); return err }, "../../fixtures/invalid/gateway-quality-ack-uppercase-uuid.json": func(raw []byte) error { _, err := protocol.DecodeGatewayQualityAck(raw); return err }, "../../fixtures/invalid/gateway-quality-ack-zero-uuid.json": func(raw []byte) error { _, err := protocol.DecodeGatewayQualityAck(raw); return err }, "../../fixtures/invalid/quality-operation-offset-time.json": func(raw []byte) error { _, err := protocol.DecodeQualityChangeOperation(raw); return err }, "../../fixtures/invalid/quality-operation-noncanonical-fraction.json": func(raw []byte) error { _, err := protocol.DecodeQualityChangeOperation(raw); return err }, } for path, decode := range invalidFixtures { raw, err := os.ReadFile(path) if err != nil { t.Fatal(err) } if decode(raw) == nil { t.Fatalf("invalid fixture %s accepted", path) } } validOperation := `{"operation_id":"12345678-1234-1234-1234-123456789abc","session_id":"session-1","revision":1,"state":"pending","requested_bitrate_preference":{"mode":"auto"},"effective_bitrate_kbps":20000,"governing_policy_version":"policy-1","session_version":1,"created_at":"2099-01-01T00:00:00Z","deadline_at":"2099-01-01T00:00:30Z","updated_at":"2099-01-01T00:00:00Z"}` if _, err := protocol.DecodeQualityChangeOperation([]byte(validOperation)); err != nil { t.Fatalf("valid quality operation rejected: %v", err) } for _, invalid := range []string{ strings.Replace(validOperation, "123456789abc", "123456789ABC", 1), strings.Replace(validOperation, "12345678-1234-1234-1234-123456789abc", "00000000-0000-0000-0000-000000000000", 1), strings.Replace(validOperation, "2099-01-01T00:00:00Z", "2099-01-01T00:00:00+00:00", 1), strings.Replace(validOperation, `,"revision":1`, "", 1), } { if _, err := protocol.DecodeQualityChangeOperation([]byte(invalid)); err == nil { t.Fatalf("invalid operation accepted: %s", invalid) } } } func int64Pointer(value int64) *int64 { return &value }