106 lines
2.8 KiB
Go
106 lines
2.8 KiB
Go
|
|
package stario
|
||
|
|
|
||
|
|
import (
|
||
|
|
"bytes"
|
||
|
|
"errors"
|
||
|
|
"io"
|
||
|
|
"testing"
|
||
|
|
)
|
||
|
|
|
||
|
|
type chunkedReader struct {
|
||
|
|
data []byte
|
||
|
|
max int
|
||
|
|
}
|
||
|
|
|
||
|
|
func (reader *chunkedReader) Read(p []byte) (int, error) {
|
||
|
|
if len(reader.data) == 0 {
|
||
|
|
return 0, io.EOF
|
||
|
|
}
|
||
|
|
if reader.max > 0 && len(p) > reader.max {
|
||
|
|
p = p[:reader.max]
|
||
|
|
}
|
||
|
|
n := copy(p, reader.data)
|
||
|
|
reader.data = reader.data[n:]
|
||
|
|
return n, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestFrameWriterReaderRoundTrip(t *testing.T) {
|
||
|
|
var wire bytes.Buffer
|
||
|
|
writer := NewFrameWriter(&wire, nil)
|
||
|
|
if err := writer.WriteFrame([]byte("one")); err != nil {
|
||
|
|
t.Fatalf("WriteFrame failed: %v", err)
|
||
|
|
}
|
||
|
|
if err := writer.WriteFramesBuffers([][]byte{[]byte("two"), []byte("three")}...); err != nil {
|
||
|
|
t.Fatalf("WriteFramesBuffers failed: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
reader := NewFrameReader(bytes.NewReader(wire.Bytes()), nil)
|
||
|
|
cases := []string{"one", "two", "three"}
|
||
|
|
for _, want := range cases {
|
||
|
|
got, err := reader.Next()
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("Next returned error: %v", err)
|
||
|
|
}
|
||
|
|
if string(got) != want {
|
||
|
|
t.Fatalf("unexpected frame: got %q want %q", got, want)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if _, err := reader.Next(); !errors.Is(err, io.EOF) {
|
||
|
|
t.Fatalf("expected EOF after draining frames, got %v", err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestFrameReaderHandlesPartialTransportReads(t *testing.T) {
|
||
|
|
var wire bytes.Buffer
|
||
|
|
writer := NewFrameWriter(&wire, nil)
|
||
|
|
if err := writer.WriteFrame([]byte("hello")); err != nil {
|
||
|
|
t.Fatalf("WriteFrame failed: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
reader := NewFrameReader(&chunkedReader{data: wire.Bytes(), max: 3}, nil)
|
||
|
|
reader.SetReadBufferSize(3)
|
||
|
|
got, err := reader.Next()
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("Next returned error: %v", err)
|
||
|
|
}
|
||
|
|
if string(got) != "hello" {
|
||
|
|
t.Fatalf("unexpected frame: %q", got)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestFrameWriterNilWriterFails(t *testing.T) {
|
||
|
|
writer := NewFrameWriter(nil, nil)
|
||
|
|
if err := writer.WriteFrame([]byte("hello")); !errors.Is(err, io.ErrClosedPipe) {
|
||
|
|
t.Fatalf("expected io.ErrClosedPipe, got %v", err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestFrameReaderTruncatedFrameReturnsUnexpectedEOF(t *testing.T) {
|
||
|
|
queue := NewQueue()
|
||
|
|
frame := queue.BuildMessage([]byte("hello"))
|
||
|
|
reader := NewFrameReader(bytes.NewReader(frame[:len(frame)-1]), nil)
|
||
|
|
|
||
|
|
if _, err := reader.Next(); !errors.Is(err, io.ErrUnexpectedEOF) {
|
||
|
|
t.Fatalf("expected io.ErrUnexpectedEOF, got %v", err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestFrameReaderReturnsUnexpectedEOFAfterPendingFrames(t *testing.T) {
|
||
|
|
queue := NewQueue()
|
||
|
|
first := queue.BuildMessage([]byte("one"))
|
||
|
|
second := queue.BuildMessage([]byte("two"))
|
||
|
|
wire := append(append([]byte{}, first...), second[:len(second)-1]...)
|
||
|
|
reader := NewFrameReader(bytes.NewReader(wire), nil)
|
||
|
|
|
||
|
|
got, err := reader.Next()
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("unexpected error on first frame: %v", err)
|
||
|
|
}
|
||
|
|
if string(got) != "one" {
|
||
|
|
t.Fatalf("unexpected first frame: %q", got)
|
||
|
|
}
|
||
|
|
if _, err := reader.Next(); !errors.Is(err, io.ErrUnexpectedEOF) {
|
||
|
|
t.Fatalf("expected io.ErrUnexpectedEOF after draining pending frame, got %v", err)
|
||
|
|
}
|
||
|
|
}
|