Files
galahad2lcd/internal/protocol/protocol_test.go
T
Maksim Totmin 4c34f0bedc Initial commit: Go driver for the Lian Li Galahad II LCD
Streams H.264 to the Galahad II LCD via USB (gousb) with:
- ffmpeg CLI transcoding (no fragile FFmpeg C-ABI bindings)
- pure-Go Annex-B access-unit splitting
- framerate pacing with graceful shutdown and USB reconnect
- TOML config, cobra CLI, structured slog logging, unit tests
2026-08-19 12:03:54 +07:00

105 lines
2.9 KiB
Go

package protocol
import (
"bytes"
"encoding/binary"
"reflect"
"testing"
)
func TestEncodePacketsSingleChunk(t *testing.T) {
frame := []byte{0x00, 0x00, 0x01, 0x67, 0x42}
packets, err := EncodePackets(frame)
if err != nil {
t.Fatalf("EncodePackets error = %v", err)
}
if len(packets) != 1 {
t.Fatalf("got %d packets, want 1", len(packets))
}
pkt := packets[0]
if len(pkt) != PacketSize {
t.Errorf("packet size = %d, want %d", len(pkt), PacketSize)
}
// Header golden bytes.
want := []byte{
0x02, // report id
0x0D, // command
0x00, 0x00, 0x00, 0x05, // total size = 5
0x00, 0x00, 0x00, // idx = 0
0x00, 0x05, // chunk len = 5
}
if !bytes.Equal(pkt[:HeaderSize], want) {
t.Errorf("header = % x, want % x", pkt[:HeaderSize], want)
}
if !bytes.Equal(pkt[HeaderSize:HeaderSize+len(frame)], frame) {
t.Errorf("payload = % x, want % x", pkt[HeaderSize:HeaderSize+len(frame)], frame)
}
}
func TestEncodePacketsMultiChunk(t *testing.T) {
frame := bytes.Repeat([]byte{0xAB}, MaxPayloadSize+17)
packets, err := EncodePackets(frame)
if err != nil {
t.Fatalf("EncodePackets error = %v", err)
}
if len(packets) != 2 {
t.Fatalf("got %d packets, want 2", len(packets))
}
// First packet carries a full 501-byte chunk.
if got := binary.BigEndian.Uint16(packets[0][9:11]); int(got) != MaxPayloadSize {
t.Errorf("first chunk len = %d, want %d", got, MaxPayloadSize)
}
// Second packet carries the remainder (17 bytes) and index 1.
if got := binary.BigEndian.Uint16(packets[1][9:11]); int(got) != 17 {
t.Errorf("second chunk len = %d, want 17", got)
}
if got := (int(packets[1][6]) << 16) | (int(packets[1][7]) << 8) | int(packets[1][8]); got != 1 {
t.Errorf("second packet idx = %d, want 1", got)
}
// Both packets declare the full frame size.
for i, pkt := range packets {
if got := binary.BigEndian.Uint32(pkt[2:6]); int(got) != len(frame) {
t.Errorf("packet %d total size = %d, want %d", i, got, len(frame))
}
}
}
func TestEncodePacketsReassemblesFrame(t *testing.T) {
frame := make([]byte, 2000)
for i := range frame {
frame[i] = byte(i)
}
packets, err := EncodePackets(frame)
if err != nil {
t.Fatalf("EncodePackets error = %v", err)
}
var got []byte
for _, pkt := range packets {
n := binary.BigEndian.Uint16(pkt[9:11])
got = append(got, pkt[HeaderSize:HeaderSize+int(n)]...)
}
if !reflect.DeepEqual(got, frame) {
t.Errorf("reassembled frame differs from input")
}
}
func TestEncodePacketsEmptyFrame(t *testing.T) {
if _, err := EncodePackets(nil); err == nil {
t.Error("expected error for empty frame, got nil")
}
}
func TestEncodePacketsIdxWrapsAt24Bits(t *testing.T) {
frame := bytes.Repeat([]byte{0x01}, 10)
packets, err := EncodePackets(frame)
if err != nil {
t.Fatalf("EncodePackets error = %v", err)
}
_ = packets // idx wrapping needs > 16M packets; covered by construction.
}