Define distributed fabric node protocol plan
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user