Move protocol and SCSI code into importable mount/ package with a single public API (Config + Run). Restructure as multi-binary repo with cmd/aten-mount/ CLI wrapper using context-based cancellation. Add Nix flake with go_1_26 for builds and devshell. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
116 lines
3.2 KiB
Go
116 lines
3.2 KiB
Go
package mount
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"testing"
|
|
)
|
|
|
|
func TestBuildPlugInPacket(t *testing.T) {
|
|
pkt := buildPlugInPacket("admin", "admin")
|
|
|
|
// Check fixed header (bytes 0-7, not encrypted)
|
|
if pkt[0] != 0x00 {
|
|
t.Errorf("byte 0: got 0x%02x, want 0x00", pkt[0])
|
|
}
|
|
if pkt[1] != 0x80 {
|
|
t.Errorf("byte 1: got 0x%02x, want 0x80 (RC4 flag)", pkt[1])
|
|
}
|
|
if pkt[3] != 0x01 {
|
|
t.Errorf("byte 3: got 0x%02x, want 0x01 (plug-in type)", pkt[3])
|
|
}
|
|
if pkt[4] != 0x2C {
|
|
t.Errorf("byte 4: got 0x%02x, want 0x2C (base length)", pkt[4])
|
|
}
|
|
|
|
// Packet should be at least 52 bytes (header + descriptors)
|
|
if len(pkt) < 52 {
|
|
t.Errorf("packet too short: %d bytes", len(pkt))
|
|
}
|
|
}
|
|
|
|
func TestBuildSetEPPacket(t *testing.T) {
|
|
pkt := buildSetEPPacket()
|
|
if len(pkt) != 16 {
|
|
t.Fatalf("SetEP packet length: got %d, want 16", len(pkt))
|
|
}
|
|
pduType := binary.BigEndian.Uint32(pkt[0:4])
|
|
if pduType != pduSetEP {
|
|
t.Errorf("PDU type: got 0x%02x, want 0x%02x", pduType, pduSetEP)
|
|
}
|
|
length := binary.LittleEndian.Uint32(pkt[4:8])
|
|
if length != 8 {
|
|
t.Errorf("length: got %d, want 8", length)
|
|
}
|
|
if pkt[8] != 0x06 {
|
|
t.Errorf("subclass: got 0x%02x, want 0x06", pkt[8])
|
|
}
|
|
if pkt[9] != 0x03 {
|
|
t.Errorf("num endpoints: got %d, want 3", pkt[9])
|
|
}
|
|
}
|
|
|
|
func TestBuildKeepAliveResponse(t *testing.T) {
|
|
pkt := buildKeepAliveResponse()
|
|
if len(pkt) != 12 {
|
|
t.Fatalf("keepalive length: got %d, want 12", len(pkt))
|
|
}
|
|
pduType := binary.BigEndian.Uint32(pkt[0:4])
|
|
if pduType != pduKeepAliveResp {
|
|
t.Errorf("PDU type: got 0x%02x, want 0x%02x", pduType, pduKeepAliveResp)
|
|
}
|
|
}
|
|
|
|
func TestBuildUnmountPacket(t *testing.T) {
|
|
pkt := buildUnmountPacket()
|
|
if len(pkt) != 8 {
|
|
t.Fatalf("unmount length: got %d, want 8", len(pkt))
|
|
}
|
|
pduType := binary.BigEndian.Uint32(pkt[0:4])
|
|
if pduType != pduUnmount {
|
|
t.Errorf("PDU type: got 0x%02x, want 0x%02x", pduType, pduUnmount)
|
|
}
|
|
}
|
|
|
|
func TestBuildCSW(t *testing.T) {
|
|
tag := [4]byte{0x01, 0x02, 0x03, 0x04}
|
|
csw := buildCSW(0x20, tag, 1000, 1000, cswStatusPassed)
|
|
if len(csw) != 21 {
|
|
t.Fatalf("CSW length: got %d, want 21", len(csw))
|
|
}
|
|
// Check PDU tag
|
|
if csw[0] != 0x22 || csw[3] != 0xFF {
|
|
t.Error("CSW PDU tag incorrect")
|
|
}
|
|
// Check USBS signature
|
|
if string(csw[8:12]) != "USBS" {
|
|
t.Errorf("CSW signature: got %q, want USBS", string(csw[8:12]))
|
|
}
|
|
// Check tag echoed
|
|
if csw[12] != 0x01 || csw[13] != 0x02 || csw[14] != 0x03 || csw[15] != 0x04 {
|
|
t.Error("CSW tag not echoed correctly")
|
|
}
|
|
// Check residue = 0
|
|
residue := binary.LittleEndian.Uint32(csw[16:20])
|
|
if residue != 0 {
|
|
t.Errorf("CSW residue: got %d, want 0", residue)
|
|
}
|
|
// Check status
|
|
if csw[20] != cswStatusPassed {
|
|
t.Errorf("CSW status: got 0x%02x, want 0x%02x", csw[20], cswStatusPassed)
|
|
}
|
|
}
|
|
|
|
func TestBuildDataPDU(t *testing.T) {
|
|
data := []byte{0xAA, 0xBB, 0xCC}
|
|
pdu := buildDataPDU(0x20, data)
|
|
if len(pdu) != 11 { // 8 header + 3 data
|
|
t.Fatalf("data PDU length: got %d, want 11", len(pdu))
|
|
}
|
|
if pdu[0] != 0x22 || pdu[2] != 0x20 || pdu[3] != 0x00 {
|
|
t.Error("data PDU tag incorrect")
|
|
}
|
|
dataLen := binary.LittleEndian.Uint32(pdu[4:8])
|
|
if dataLen != 3 {
|
|
t.Errorf("data length: got %d, want 3", dataLen)
|
|
}
|
|
}
|