160 lines
4.6 KiB
Go
160 lines
4.6 KiB
Go
package artnet
|
|
|
|
import (
|
|
"bytes"
|
|
"testing"
|
|
)
|
|
|
|
func FuzzParsePacket(f *testing.F) {
|
|
validDMX := BuildDMXPacket(NewUniverse(0, 0, 1), 0, make([]byte, 512))
|
|
f.Add(validDMX)
|
|
f.Add(BuildDMXPacket(NewUniverse(127, 15, 15), 255, make([]byte, 512)))
|
|
f.Add(BuildDMXPacket(NewUniverse(0, 0, 0), 0, make([]byte, 2)))
|
|
f.Add(BuildPollPacket())
|
|
f.Add(BuildPollReplyPacket([4]byte{192, 168, 1, 1}, [6]byte{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}, "short", "long name", []Universe{NewUniverse(0, 0, 1)}, false))
|
|
f.Add([]byte{})
|
|
f.Add(make([]byte, 9))
|
|
f.Add(make([]byte, 10))
|
|
f.Add(make([]byte, 17))
|
|
f.Add(make([]byte, 18))
|
|
f.Add(make([]byte, 206))
|
|
f.Add(make([]byte, 207))
|
|
|
|
wrongHeader := make([]byte, 100)
|
|
copy(wrongHeader, []byte("Wrong-Ne"))
|
|
f.Add(wrongHeader)
|
|
|
|
f.Fuzz(func(t *testing.T, data []byte) {
|
|
opCode, pkt, err := ParsePacket(data)
|
|
if err != nil {
|
|
return
|
|
}
|
|
switch opCode {
|
|
case OpDmx:
|
|
_, ok := pkt.(*DMXPacket)
|
|
if !ok && pkt != nil {
|
|
t.Fatal("OpDmx returned non-DMXPacket")
|
|
}
|
|
case OpPoll:
|
|
_, ok := pkt.(*PollPacket)
|
|
if !ok && pkt != nil {
|
|
t.Fatal("OpPoll returned non-PollPacket")
|
|
}
|
|
case OpPollReply:
|
|
if reply, ok := pkt.(*PollReplyPacket); ok {
|
|
if reply.NumPorts() > 4 {
|
|
t.Fatalf("NumPorts exceeds 4: %d", reply.NumPorts())
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
func FuzzDMXRoundtrip(f *testing.F) {
|
|
f.Add(uint8(0), uint8(0), uint8(0), uint8(0), make([]byte, 512))
|
|
f.Add(uint8(127), uint8(15), uint8(15), uint8(255), make([]byte, 512))
|
|
f.Add(uint8(0), uint8(0), uint8(1), uint8(128), make([]byte, 100))
|
|
f.Add(uint8(50), uint8(8), uint8(10), uint8(1), make([]byte, 2))
|
|
|
|
f.Fuzz(func(t *testing.T, netVal, subnet, uni, seq uint8, dmxInput []byte) {
|
|
universe := NewUniverse(netVal, subnet, uni)
|
|
packet := BuildDMXPacket(universe, seq, dmxInput)
|
|
|
|
opCode, pkt, err := ParsePacket(packet)
|
|
if err != nil {
|
|
t.Fatalf("failed to parse packet we just built: %v", err)
|
|
}
|
|
if opCode != OpDmx {
|
|
t.Fatalf("expected OpDmx, got %d", opCode)
|
|
}
|
|
dmx, ok := pkt.(*DMXPacket)
|
|
if !ok {
|
|
t.Fatal("expected DMXPacket")
|
|
}
|
|
if dmx.Sequence != seq {
|
|
t.Fatalf("sequence mismatch: sent %d, got %d", seq, dmx.Sequence)
|
|
}
|
|
if dmx.Universe != universe {
|
|
t.Fatalf("universe mismatch: sent %v, got %v", universe, dmx.Universe)
|
|
}
|
|
expectedLen := len(dmxInput)
|
|
if expectedLen > 512 {
|
|
expectedLen = 512
|
|
}
|
|
if expectedLen%2 != 0 {
|
|
expectedLen++
|
|
}
|
|
if int(dmx.Length) != expectedLen {
|
|
t.Fatalf("length mismatch: expected %d, got %d", expectedLen, dmx.Length)
|
|
}
|
|
compareLen := len(dmxInput)
|
|
if compareLen > 512 {
|
|
compareLen = 512
|
|
}
|
|
if !bytes.Equal(dmx.Data[:compareLen], dmxInput[:compareLen]) {
|
|
t.Fatal("dmx data mismatch")
|
|
}
|
|
})
|
|
}
|
|
|
|
func FuzzPollReplyRoundtrip(f *testing.F) {
|
|
f.Add([]byte{192, 168, 1, 1}, []byte{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}, "short", "long name", uint8(0), uint8(0), uint8(1), true)
|
|
f.Add([]byte{10, 0, 0, 1}, []byte{0, 0, 0, 0, 0, 0}, "", "", uint8(127), uint8(15), uint8(15), false)
|
|
|
|
f.Fuzz(func(t *testing.T, ipSlice, macSlice []byte, shortName, longName string, netVal, subnet, uni uint8, isInput bool) {
|
|
if len(ipSlice) < 4 || len(macSlice) < 6 {
|
|
return
|
|
}
|
|
var ip [4]byte
|
|
var mac [6]byte
|
|
copy(ip[:], ipSlice[:4])
|
|
copy(mac[:], macSlice[:6])
|
|
|
|
universe := NewUniverse(netVal, subnet, uni)
|
|
packet := BuildPollReplyPacket(ip, mac, shortName, longName, []Universe{universe}, isInput)
|
|
|
|
opCode, pkt, err := ParsePacket(packet)
|
|
if err != nil {
|
|
t.Fatalf("failed to parse packet we just built: %v", err)
|
|
}
|
|
if opCode != OpPollReply {
|
|
t.Fatalf("expected OpPollReply, got %d", opCode)
|
|
}
|
|
reply, ok := pkt.(*PollReplyPacket)
|
|
if !ok {
|
|
t.Fatal("expected PollReplyPacket")
|
|
}
|
|
if reply.IPAddress != ip {
|
|
t.Fatalf("IP mismatch")
|
|
}
|
|
if !bytes.Equal(reply.MAC[:], mac[:]) {
|
|
t.Fatal("MAC mismatch")
|
|
}
|
|
})
|
|
}
|
|
|
|
func FuzzUniverse(f *testing.F) {
|
|
f.Add(uint8(0), uint8(0), uint8(0))
|
|
f.Add(uint8(127), uint8(15), uint8(15))
|
|
f.Add(uint8(50), uint8(8), uint8(10))
|
|
|
|
f.Fuzz(func(t *testing.T, netVal, subnet, uni uint8) {
|
|
universe := NewUniverse(netVal, subnet, uni)
|
|
gotNet := universe.Net()
|
|
gotSubnet := universe.SubNet()
|
|
gotUni := universe.Universe()
|
|
expectedNet := netVal & 0x7F
|
|
expectedSubnet := subnet & 0x0F
|
|
expectedUni := uni & 0x0F
|
|
if gotNet != expectedNet {
|
|
t.Fatalf("Net mismatch: input %d, expected %d, got %d", netVal, expectedNet, gotNet)
|
|
}
|
|
if gotSubnet != expectedSubnet {
|
|
t.Fatalf("SubNet mismatch: input %d, expected %d, got %d", subnet, expectedSubnet, gotSubnet)
|
|
}
|
|
if gotUni != expectedUni {
|
|
t.Fatalf("Universe mismatch: input %d, expected %d, got %d", uni, expectedUni, gotUni)
|
|
}
|
|
})
|
|
}
|