mirror of
https://github.com/sartoopjj/thefeed.git
synced 2026-05-18 05:24:36 +03:00
151 lines
4.3 KiB
Go
151 lines
4.3 KiB
Go
package protocol
|
|
|
|
import (
|
|
"bytes"
|
|
"testing"
|
|
)
|
|
|
|
func TestSerializeParseMetadata(t *testing.T) {
|
|
original := &Metadata{
|
|
Marker: [3]byte{0xAA, 0xBB, 0xCC},
|
|
Timestamp: 1700000000,
|
|
Channels: []ChannelInfo{
|
|
{Name: "VahidOnline", Blocks: 5, LastMsgID: 1234},
|
|
{Name: "test", Blocks: 3, LastMsgID: 5678},
|
|
},
|
|
}
|
|
data := SerializeMetadata(original)
|
|
parsed, err := ParseMetadata(data)
|
|
if err != nil {
|
|
t.Fatalf("ParseMetadata: %v", err)
|
|
}
|
|
if parsed.Marker != original.Marker {
|
|
t.Errorf("marker: got %v, want %v", parsed.Marker, original.Marker)
|
|
}
|
|
if parsed.Timestamp != original.Timestamp {
|
|
t.Errorf("timestamp: got %d, want %d", parsed.Timestamp, original.Timestamp)
|
|
}
|
|
if len(parsed.Channels) != len(original.Channels) {
|
|
t.Fatalf("channels: got %d, want %d", len(parsed.Channels), len(original.Channels))
|
|
}
|
|
for i := range original.Channels {
|
|
if parsed.Channels[i] != original.Channels[i] {
|
|
t.Errorf("channel %d mismatch", i)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSerializeParseMessages(t *testing.T) {
|
|
original := []Message{
|
|
{ID: 100, Timestamp: 1700000000, Text: "Hello world"},
|
|
{ID: 101, Timestamp: 1700000060, Text: "Test farsi"},
|
|
{ID: 102, Timestamp: 1700000120, Text: "[IMAGE] Caption"},
|
|
}
|
|
data := SerializeMessages(original)
|
|
parsed, err := ParseMessages(data)
|
|
if err != nil {
|
|
t.Fatalf("ParseMessages: %v", err)
|
|
}
|
|
if len(parsed) != len(original) {
|
|
t.Fatalf("messages: got %d, want %d", len(parsed), len(original))
|
|
}
|
|
for i := range original {
|
|
if parsed[i] != original[i] {
|
|
t.Errorf("message %d mismatch", i)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSplitIntoBlocks(t *testing.T) {
|
|
// MaxBlockPayload*3+50 guarantees at least 4 blocks (ceil((MaxBlockPayload*3+50)/MaxBlockPayload) = 4).
|
|
data := bytes.Repeat([]byte("A"), MaxBlockPayload*3+50)
|
|
blocks := SplitIntoBlocks(data)
|
|
if len(blocks) < 4 {
|
|
t.Fatalf("expected at least 4 blocks for %d bytes, got %d", len(data), len(blocks))
|
|
}
|
|
// Every non-last block must be within [MinBlockPayload, MaxBlockPayload].
|
|
for i, b := range blocks[:len(blocks)-1] {
|
|
if len(b) < MinBlockPayload || len(b) > MaxBlockPayload {
|
|
t.Errorf("block %d: size %d, want [%d, %d]", i, len(b), MinBlockPayload, MaxBlockPayload)
|
|
}
|
|
}
|
|
// Reassembled data must equal original.
|
|
var reassembled []byte
|
|
for _, b := range blocks {
|
|
reassembled = append(reassembled, b...)
|
|
}
|
|
if !bytes.Equal(reassembled, data) {
|
|
t.Error("reassembled data does not match original")
|
|
}
|
|
}
|
|
|
|
func TestSplitIntoBlocksEmpty(t *testing.T) {
|
|
blocks := SplitIntoBlocks(nil)
|
|
if len(blocks) != 1 {
|
|
t.Fatalf("empty should produce 1 block, got %d", len(blocks))
|
|
}
|
|
}
|
|
|
|
func TestMessageRoundtripThroughBlocks(t *testing.T) {
|
|
msgs := []Message{
|
|
{ID: 1, Timestamp: 1700000000, Text: "Short"},
|
|
{ID: 2, Timestamp: 1700000001, Text: string(bytes.Repeat([]byte("X"), 300))},
|
|
{ID: 3, Timestamp: 1700000002, Text: "End"},
|
|
}
|
|
data := SerializeMessages(msgs)
|
|
blocks := SplitIntoBlocks(data)
|
|
var reassembled []byte
|
|
for _, b := range blocks {
|
|
reassembled = append(reassembled, b...)
|
|
}
|
|
parsed, err := ParseMessages(reassembled)
|
|
if err != nil {
|
|
t.Fatalf("ParseMessages: %v", err)
|
|
}
|
|
if len(parsed) != len(msgs) {
|
|
t.Fatalf("got %d messages, want %d", len(parsed), len(msgs))
|
|
}
|
|
for i := range msgs {
|
|
if parsed[i] != msgs[i] {
|
|
t.Errorf("message %d mismatch", i)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestParseMetadataTooShort(t *testing.T) {
|
|
_, err := ParseMetadata([]byte{0x01, 0x02})
|
|
if err == nil {
|
|
t.Error("expected error for short metadata")
|
|
}
|
|
}
|
|
|
|
func TestEncodeDecodeVersionData(t *testing.T) {
|
|
versions := []string{"", "v1.0.0", "v2.3.14", "1.0.0-beta"}
|
|
for _, ver := range versions {
|
|
block, err := EncodeVersionData(ver)
|
|
if err != nil {
|
|
t.Fatalf("EncodeVersionData(%q): %v", ver, err)
|
|
}
|
|
if len(block) < MinBlockPayload {
|
|
t.Errorf("EncodeVersionData(%q): block len %d < MinBlockPayload %d", ver, len(block), MinBlockPayload)
|
|
}
|
|
if len(block) > MaxBlockPayload {
|
|
t.Errorf("EncodeVersionData(%q): block len %d > MaxBlockPayload %d", ver, len(block), MaxBlockPayload)
|
|
}
|
|
got, err := DecodeVersionData(block)
|
|
if err != nil {
|
|
t.Fatalf("DecodeVersionData(%q): %v", ver, err)
|
|
}
|
|
if got != ver {
|
|
t.Errorf("round-trip: got %q, want %q", got, ver)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDecodeVersionDataTooShort(t *testing.T) {
|
|
_, err := DecodeVersionData([]byte{0x01})
|
|
if err == nil {
|
|
t.Error("expected error for 1-byte block")
|
|
}
|
|
}
|