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. }