Files
rdp-proxy/agents/rap-node-agent/internal/fabricproto/frame_test.go
T

139 lines
3.9 KiB
Go

package fabricproto
import (
"bytes"
"errors"
"io"
"testing"
)
func TestMarshalUnmarshalFrameRoundTrip(t *testing.T) {
frame := Frame{
Type: FrameData,
Flags: 3,
TrafficClass: TrafficClassInteractive,
StreamID: 42,
Sequence: 7,
Payload: []byte("hello"),
}
encoded, err := MarshalFrame(frame)
if err != nil {
t.Fatalf("marshal frame: %v", err)
}
decoded, err := UnmarshalFrame(encoded, DefaultMaxPayload)
if err != nil {
t.Fatalf("unmarshal frame: %v", err)
}
if decoded.Type != frame.Type || decoded.Flags != frame.Flags || decoded.TrafficClass != frame.TrafficClass ||
decoded.StreamID != frame.StreamID || decoded.Sequence != frame.Sequence || !bytes.Equal(decoded.Payload, frame.Payload) {
t.Fatalf("decoded frame = %+v, want %+v", decoded, frame)
}
}
func TestReadWriteFrameRoundTrip(t *testing.T) {
var buf bytes.Buffer
frame := Frame{
Type: FrameOpenStream,
TrafficClass: TrafficClassReliable,
StreamID: 9,
Payload: []byte(`{"service":"vpn"}`),
}
if err := WriteFrame(&buf, frame); err != nil {
t.Fatalf("write frame: %v", err)
}
decoded, err := ReadFrame(&buf, DefaultMaxPayload)
if err != nil {
t.Fatalf("read frame: %v", err)
}
if decoded.Type != frame.Type || decoded.StreamID != frame.StreamID || !bytes.Equal(decoded.Payload, frame.Payload) {
t.Fatalf("decoded frame = %+v, want %+v", decoded, frame)
}
}
func TestRejectsInvalidMagic(t *testing.T) {
encoded, err := MarshalFrame(Frame{Type: FrameHello})
if err != nil {
t.Fatalf("marshal frame: %v", err)
}
encoded[0] = 0
_, err = UnmarshalFrame(encoded, DefaultMaxPayload)
if !errors.Is(err, ErrInvalidMagic) {
t.Fatalf("error = %v, want %v", err, ErrInvalidMagic)
}
}
func TestRejectsUnsupportedVersion(t *testing.T) {
encoded, err := MarshalFrame(Frame{Type: FrameHello})
if err != nil {
t.Fatalf("marshal frame: %v", err)
}
encoded[4] = Version + 1
_, err = UnmarshalFrame(encoded, DefaultMaxPayload)
if !errors.Is(err, ErrUnsupportedVer) {
t.Fatalf("error = %v, want %v", err, ErrUnsupportedVer)
}
}
func TestRejectsUnknownFrameType(t *testing.T) {
if err := ValidateFrame(Frame{Type: FrameType(255)}, DefaultMaxPayload); !errors.Is(err, ErrUnknownFrameType) {
t.Fatalf("error = %v, want %v", err, ErrUnknownFrameType)
}
}
func TestRejectsStreamFrameWithoutStreamID(t *testing.T) {
if err := ValidateFrame(Frame{Type: FrameData}, DefaultMaxPayload); !errors.Is(err, ErrInvalidStreamID) {
t.Fatalf("error = %v, want %v", err, ErrInvalidStreamID)
}
}
func TestRejectsOversizedPayload(t *testing.T) {
frame := Frame{
Type: FrameData,
StreamID: 1,
Payload: bytes.Repeat([]byte("x"), 5),
}
if err := ValidateFrame(frame, 4); !errors.Is(err, ErrInvalidPayloadLen) {
t.Fatalf("error = %v, want %v", err, ErrInvalidPayloadLen)
}
}
func TestRejectsUnknownTrafficClass(t *testing.T) {
frame := Frame{
Type: FrameOpenStream,
TrafficClass: TrafficClass(99),
StreamID: 1,
}
if err := ValidateFrame(frame, DefaultMaxPayload); !errors.Is(err, ErrUnknownTraffic) {
t.Fatalf("error = %v, want %v", err, ErrUnknownTraffic)
}
}
func TestUnmarshalRequiresExactPayloadLength(t *testing.T) {
encoded, err := MarshalFrame(Frame{Type: FrameData, StreamID: 1, Payload: []byte("hello")})
if err != nil {
t.Fatalf("marshal frame: %v", err)
}
encoded = encoded[:len(encoded)-1]
_, err = UnmarshalFrame(encoded, DefaultMaxPayload)
if !errors.Is(err, ErrInvalidPayloadLen) {
t.Fatalf("error = %v, want %v", err, ErrInvalidPayloadLen)
}
}
func TestReadFrameReturnsUnexpectedEOFOnShortPayload(t *testing.T) {
encoded, err := MarshalFrame(Frame{Type: FrameData, StreamID: 1, Payload: []byte("hello")})
if err != nil {
t.Fatalf("marshal frame: %v", err)
}
_, err = ReadFrame(bytes.NewReader(encoded[:len(encoded)-1]), DefaultMaxPayload)
if !errors.Is(err, io.ErrUnexpectedEOF) {
t.Fatalf("error = %v, want %v", err, io.ErrUnexpectedEOF)
}
}