84 lines
2.5 KiB
Go
84 lines
2.5 KiB
Go
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, []byte("hello")}, {3103, 300, bytes.Repeat([]byte{1}, 300)}, {1301, 0, nil}}
|
|
if len(got) != len(want) {
|
|
t.Fatalf("got %v, want %v", got, want)
|
|
}
|
|
for i := range want {
|
|
if got[i].Type != want[i].Type || got[i].Size != want[i].Size || !bytes.Equal(got[i].Data, want[i].Data) {
|
|
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))
|
|
}
|
|
}
|
|
|
|
func TestSendMessageRoundTrip(t *testing.T) {
|
|
m := SendMessage{OpID: 300, Queue: "/chat/1", Mount: "messages", Message: []byte(`{"message": "*use 80 1"}`)}
|
|
data := m.Marshal()
|
|
got, err := ParseSendMessage(data)
|
|
if err != nil || got.OpID != 300 || got.Queue != "/chat/1" || got.Mount != "messages" || string(got.Message) != string(m.Message) {
|
|
t.Fatalf("%+v %v", got, err)
|
|
}
|
|
// A frame of it reads back as one frame with the same data.
|
|
var r Reader
|
|
frames, err := r.Write(EncodeFrame(C2gSendMessage, data))
|
|
if err != nil || len(frames) != 1 || frames[0].Type != C2gSendMessage || !bytes.Equal(frames[0].Data, data) {
|
|
t.Fatalf("%v %v", frames, err)
|
|
}
|
|
if _, err := ParseSendMessage(Result(1, 0)); err == nil {
|
|
t.Fatal("a G2cResult parsed as a C2gSendMessage")
|
|
}
|
|
}
|