package imq import ( "bytes" "errors" "testing" ) // frame encodes a frame as the client does: field 1 the type, field 2 the data. func frame(t uint64, data []byte) []byte { b := append([]byte{0x08}, uvarint(t)...) b = append(b, 0x12) b = append(b, uvarint(uint64(len(data)))...) return append(b, data...) } func uvarint(v uint64) []byte { var b []byte for v >= 0x80 { b = append(b, byte(v)|0x80) v >>= 7 } return append(b, byte(v)) } func TestReaderSplitsFrames(t *testing.T) { stream := append(frame(1302, []byte("hello")), frame(3103, bytes.Repeat([]byte{1}, 300))...) stream = append(stream, frame(1301, nil)...) // Fed a byte at a time, the frames still come out whole and in order. var r Reader var got []Frame for i := range stream { frames, err := r.Write(stream[i : i+1]) if err != nil { t.Fatal(err) } got = append(got, frames...) } want := []Frame{{1302, 5}, {3103, 300}, {1301, 0}} if len(got) != len(want) { t.Fatalf("got %v, want %v", got, want) } for i := range want { if got[i] != want[i] { t.Fatalf("got %v, want %v", got, want) } } } func TestReaderRejectsOtherStreams(t *testing.T) { var r Reader // A TLS ClientHello isn't IMQ. if _, err := r.Write([]byte{0x16, 0x03, 0x01, 0x00, 0xa5}); !errors.Is(err, ErrMalformed) { t.Fatalf("got %v, want ErrMalformed", err) } if _, err := r.Write(frame(1301, nil)); !errors.Is(err, ErrMalformed) { t.Fatal("a reader keeps failing after a malformed frame") } } func TestTypeName(t *testing.T) { if TypeName(3104) != "G2cSendMessage" || TypeName(7) != "type 7" { t.Fatal(TypeName(3104), TypeName(7)) } }