sts-sponsors team mailing list archive
-
sts-sponsors team
-
Mailing list archive
-
Message #08206
[Merge] ~troyanov/maas:refactor-maasagent-tests into maas:master
Anton Troyanov has proposed merging ~troyanov/maas:refactor-maasagent-tests into maas:master.
Commit message:
refactor(maasagent): tests refactoring and cleanup
Requested reviews:
MAAS Maintainers (maas-maintainers)
For more details, see:
https://code.launchpad.net/~troyanov/maas/+git/maas/+merge/442489
--
Your team MAAS Maintainers is requested to review the proposed merge of ~troyanov/maas:refactor-maasagent-tests into maas:master.
diff --git a/.golangci.yaml b/.golangci.yaml
index 91aed41..9f41cd2 100644
--- a/.golangci.yaml
+++ b/.golangci.yaml
@@ -175,10 +175,15 @@ issues:
linters:
- revive
- - path: main.go
+ - path: main\.go
text: "package-comments:"
linters:
- revive
+
+ - path: _test\.go
+ text: "fieldalignment:"
+ linters:
+ - govet
# Independently of option `exclude` we use default exclude patterns,
# it can be disabled by this option.
# To list all excluded by default patterns execute `golangci-lint run --help`.
diff --git a/src/maasagent/Makefile b/src/maasagent/Makefile
index 8541604..f22503f 100644
--- a/src/maasagent/Makefile
+++ b/src/maasagent/Makefile
@@ -36,22 +36,15 @@ test:
CGO_ENABLED=1 $(GO) test -race ./...
.PHONY: generate
-generate: $(BIN_DIR)/mockgen
+generate:
$(GO) generate ./...
-.PHONY: tools
-tools: $(BIN_DIR)/mockgen
-
.PHONY: vendor
vendor: $(VENDOR_DIR)/modules.txt
$(VENDOR_DIR)/modules.txt: go.mod
$(GO) mod vendor
-$(BIN_DIR)/mockgen: MOCKGEN_VERSION=1.6.0
-$(BIN_DIR)/mockgen: | $(BIN_DIR)
- GOFLAGS="" GOBIN="$(realpath $(dir $@))" $(GO) install github.com/golang/mock/mockgen@v$(MOCKGEN_VERSION)
-
.PHONY: clean
clean:
rm -rf $(VENDOR_DIR) $(BIN_DIR) $(BUILD_DIR)
diff --git a/src/maasagent/go.mod b/src/maasagent/go.mod
index 0707adc..02dfb83 100644
--- a/src/maasagent/go.mod
+++ b/src/maasagent/go.mod
@@ -8,6 +8,7 @@ require (
github.com/rs/zerolog v1.29.1
github.com/stretchr/testify v1.7.0
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4
+ golang.org/x/tools v0.1.12
)
require (
@@ -17,6 +18,7 @@ require (
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/sirupsen/logrus v1.4.2 // indirect
+ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/net v0.7.0 // indirect
golang.org/x/sys v0.5.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
diff --git a/src/maasagent/go.sum b/src/maasagent/go.sum
index 9ac9620..cdacc6c 100644
--- a/src/maasagent/go.sum
+++ b/src/maasagent/go.sum
@@ -121,6 +121,7 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -168,6 +169,7 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
diff --git a/src/maasagent/internal/ethernet/arp.go b/src/maasagent/internal/ethernet/arp.go
index ef8dd2d..da3238f 100644
--- a/src/maasagent/internal/ethernet/arp.go
+++ b/src/maasagent/internal/ethernet/arp.go
@@ -14,49 +14,57 @@ import (
"net/netip"
)
+type HardwareType uint16
+
+//go:generate go run golang.org/x/tools/cmd/stringer -type=HardwareType -trimprefix=HardwareType
+
const (
// HardwareTypeReserved is a special value for hardware type
- HardwareTypeReserved uint16 = 0 // see RFC5494
+ HardwareTypeReserved HardwareType = 0 // see RFC5494
// HardwareTypeEthernet is the hardware type value for Ethernet
// we only care about ethernet, but additional types are defined for
// testing and possible future use
- HardwareTypeEthernet uint16 = 1
+ HardwareTypeEthernet HardwareType = 1
// HardwareTypeExpEth is the hardware type for experimental ethernet
- HardwareTypeExpEth uint16 = 2
+ HardwareTypeExpEth HardwareType = 2
// HardwareTypeAX25 is the hardware type for Radio AX.25
- HardwareTypeAX25 uint16 = 3
+ HardwareTypeAX25 HardwareType = 3
// HardwareTypeChaos is a chaos value for hardware type
- HardwareTypeChaos uint16 = 4
+ HardwareTypeChaos HardwareType = 4
// HardwareTypeIEEE802 is for IEEE 802 networks
- HardwareTypeIEEE802 uint16 = 5
+ HardwareTypeIEEE802 HardwareType = 5
// skipping propriatary networks
// HardwareTypeFiberChannel is the hardware type for fiber channel
- HardwareTypeFiberChannel uint16 = 18
+ HardwareTypeFiberChannel HardwareType = 18
// HardwareTypeSerialLine is the hardware type for serial line
- HardwareTypeSerialLine uint16 = 19
+ HardwareTypeSerialLine HardwareType = 19
// HardwareTypeHIPARP is the hardware type for HIPARP
- HardwareTypeHIPARP uint16 = 28
+ HardwareTypeHIPARP HardwareType = 28
// HardwareTypeIPARPISO7163 is the hardware type for IP and ARP over ISO 7816-3
- HardwareTypeIPARPISO7163 uint16 = 29
+ HardwareTypeIPARPISO7163 HardwareType = 29
// HardwareTypeARPSec is the hardware type for ARPSec
- HardwareTypeARPSec uint16 = 30
+ HardwareTypeARPSec HardwareType = 30
// HardwareTypeIPSec is the hardware type for IPSec tunnel
- HardwareTypeIPSec uint16 = 31
+ HardwareTypeIPSec HardwareType = 31
// HardwareTypeInfiniBand is the hardware type for InfiniBand
- HardwareTypeInfiniBand uint16 = 32
+ HardwareTypeInfiniBand HardwareType = 32
)
+type ProtocolType uint16
+
+//go:generate go run golang.org/x/tools/cmd/stringer -type=ProtocolType -trimprefix=ProtocolType
+
const (
// ProtocolTypeIPv4 is the value for IPv4 ARP packets
- ProtocolTypeIPv4 uint16 = 0x0800
+ ProtocolTypeIPv4 ProtocolType = 0x0800
// ProtocolTypeIPv6 is the value for IPv6 ARP packets,
// which shouldn't be used, this is defined for testing purposes
- ProtocolTypeIPv6 uint16 = 0x86dd
+ ProtocolTypeIPv6 ProtocolType = 0x86dd
// ProtocolTypeARP is the value for ARP packets with a protocol
// value of ARP itself
- ProtocolTypeARP uint16 = 0x0806
+ ProtocolTypeARP ProtocolType = 0x0806
)
const (
@@ -77,11 +85,11 @@ var (
type ARPPacket struct {
SendIPAddr netip.Addr
TgtIPAddr netip.Addr
- SendHwdAddr net.HardwareAddr
- TgtHwdAddr net.HardwareAddr
- HardwareType uint16
+ SendHwAddr net.HardwareAddr
+ TgtHwAddr net.HardwareAddr
+ HardwareType HardwareType
OpCode uint16
- ProtocolType uint16
+ ProtocolType ProtocolType
HardwareAddrLen uint8
ProtocolAddrLen uint8
}
@@ -109,8 +117,8 @@ func (pkt *ARPPacket) UnmarshalBinary(buf []byte) error {
return fmt.Errorf("%w: packet missing initial ARP fields", err)
}
- pkt.HardwareType = binary.BigEndian.Uint16(buf[0:2])
- pkt.ProtocolType = binary.BigEndian.Uint16(buf[2:4])
+ pkt.HardwareType = HardwareType(binary.BigEndian.Uint16(buf[0:2]))
+ pkt.ProtocolType = ProtocolType(binary.BigEndian.Uint16(buf[2:4]))
pkt.HardwareAddrLen = buf[4]
pkt.ProtocolAddrLen = buf[5]
pkt.OpCode = binary.BigEndian.Uint16(buf[6:8])
@@ -124,9 +132,9 @@ func (pkt *ARPPacket) UnmarshalBinary(buf []byte) error {
return fmt.Errorf("%w: packet too short for sender hardware address", err)
}
- sendHwdAddrBuf := make([]byte, hwdAddrLen)
- copy(sendHwdAddrBuf, buf[bytesRead:bytesRead+hwdAddrLen])
- pkt.SendHwdAddr = sendHwdAddrBuf
+ sendHwAddrBuf := make([]byte, hwdAddrLen)
+ copy(sendHwAddrBuf, buf[bytesRead:bytesRead+hwdAddrLen])
+ pkt.SendHwAddr = sendHwAddrBuf
bytesRead += hwdAddrLen
err = checkPacketLen(buf, bytesRead, ipAddrLen)
@@ -151,10 +159,10 @@ func (pkt *ARPPacket) UnmarshalBinary(buf []byte) error {
return fmt.Errorf("%w: packet too short for target hardware address", err)
}
- tgtHwdAddrBuf := make([]byte, hwdAddrLen)
- copy(tgtHwdAddrBuf, buf[bytesRead:bytesRead+hwdAddrLen])
+ tgtHwAddrBuf := make([]byte, hwdAddrLen)
+ copy(tgtHwAddrBuf, buf[bytesRead:bytesRead+hwdAddrLen])
- pkt.TgtHwdAddr = tgtHwdAddrBuf
+ pkt.TgtHwAddr = tgtHwAddrBuf
bytesRead += hwdAddrLen
err = checkPacketLen(buf, bytesRead, ipAddrLen)
diff --git a/src/maasagent/internal/ethernet/arp_test.go b/src/maasagent/internal/ethernet/arp_test.go
index 8b2607c..469465e 100644
--- a/src/maasagent/internal/ethernet/arp_test.go
+++ b/src/maasagent/internal/ethernet/arp_test.go
@@ -7,82 +7,77 @@ package ethernet
import (
"io"
+ "net/netip"
"testing"
"github.com/stretchr/testify/assert"
)
func TestUnmarshal(t *testing.T) {
- table := []unmarshalCase{
- {
- basePacketTestCase: basePacketTestCase{
- Name: "ValidRequestPacket",
- // generated from tcpdump
- In: []byte{
- 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x84, 0x39, 0xc0, 0x0b, 0x22, 0x25,
- 0xc0, 0xa8, 0x0a, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x0a, 0x19,
- },
+ t.Parallel()
+
+ testcases := map[string]struct {
+ in []byte
+ out *ARPPacket
+ err error
+ }{
+ "valid request packet": {
+ in: []byte{
+ 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x84, 0x39, 0xc0, 0x0b, 0x22, 0x25,
+ 0xc0, 0xa8, 0x0a, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x0a, 0x19,
},
- Out: &ARPPacket{
+ out: &ARPPacket{
HardwareType: HardwareTypeEthernet,
ProtocolType: ProtocolTypeIPv4,
HardwareAddrLen: 6,
ProtocolAddrLen: 4,
OpCode: OpRequest,
- SendHwdAddr: parseMACNoError("84:39:c0:0b:22:25"),
- SendIPAddr: parseAddrNoError("192.168.10.26"),
- TgtHwdAddr: parseMACNoError("00:00:00:00:00:00"),
- TgtIPAddr: parseAddrNoError("192.168.10.25"),
+ SendHwAddr: []byte{0x84, 0x39, 0xc0, 0x0b, 0x22, 0x25},
+ SendIPAddr: netip.MustParseAddr("192.168.10.26"),
+ TgtHwAddr: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x0},
+ TgtIPAddr: netip.MustParseAddr("192.168.10.25"),
},
},
- {
- basePacketTestCase: basePacketTestCase{
- Name: "ValidReplyPacket",
- // generated from tcpdump
- In: []byte{
- 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x02, 0x80, 0x61, 0x5f, 0x08, 0xfc, 0x16, 0xc0, 0xa8,
- 0x01, 0x6c, 0x24, 0x4b, 0xfe, 0xe1, 0xea, 0x26, 0xc0, 0xa8, 0x01, 0x50,
- },
+ "valid reply packet": {
+ in: []byte{
+ 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x02, 0x80, 0x61, 0x5f, 0x08, 0xfc, 0x16,
+ 0xc0, 0xa8, 0x01, 0x6c, 0x24, 0x4b, 0xfe, 0xe1, 0xea, 0x26, 0xc0, 0xa8, 0x01, 0x50,
},
- Out: &ARPPacket{
+ out: &ARPPacket{
HardwareType: HardwareTypeEthernet,
ProtocolType: ProtocolTypeIPv4,
HardwareAddrLen: 6,
ProtocolAddrLen: 4,
OpCode: OpReply,
- SendHwdAddr: parseMACNoError("80:61:5f:08:fc:16"),
- SendIPAddr: parseAddrNoError("192.168.1.108"),
- TgtHwdAddr: parseMACNoError("24:4b:fe:e1:ea:26"),
- TgtIPAddr: parseAddrNoError("192.168.1.80"),
+ SendHwAddr: []byte{0x80, 0x61, 0x5f, 0x08, 0xfc, 0x16},
+ SendIPAddr: netip.MustParseAddr("192.168.1.108"),
+ TgtHwAddr: []byte{0x24, 0x4b, 0xfe, 0xe1, 0xea, 0x26},
+ TgtIPAddr: netip.MustParseAddr("192.168.1.80"),
},
},
- {
- basePacketTestCase: basePacketTestCase{
- Name: "EmptyPacket",
- Err: io.ErrUnexpectedEOF,
- },
+ "empty packet": {
+ err: io.ErrUnexpectedEOF,
},
- {
- basePacketTestCase: basePacketTestCase{
- Name: "TooShortPacket",
- In: []byte{
- 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x84, 0x39, 0xc0, 0x0b, 0x22, 0x25,
- 0xc0, 0xa8,
- },
- Err: ErrMalformedARPPacket,
+ "too stort packet": {
+ in: []byte{
+ 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x84, 0x39, 0xc0, 0x0b, 0x22, 0x25,
+ 0xc0, 0xa8,
},
+ err: ErrMalformedARPPacket,
},
}
- for _, tcase := range table {
- t.Run(tcase.Name, func(tt *testing.T) {
- res := &ARPPacket{}
+ for name, tc := range testcases {
+ tc := tc
- err := res.UnmarshalBinary(tcase.In)
- assert.ErrorIsf(tt, err, tcase.Err, "expected Unmarshal to return an error of %s", tcase.Err)
+ t.Run(name, func(t *testing.T) {
+ t.Parallel()
+ res := &ARPPacket{}
- if tcase.Out != nil {
- compareARPPacket(tt, tcase.Out, res)
+ err := res.UnmarshalBinary(tc.in)
+ assert.ErrorIsf(t, err, tc.err, "expected Unmarshal to return an error of %s", tc.err)
+ if err == nil {
+ assert.Equal(t, tc.out, res)
}
})
}
diff --git a/src/maasagent/internal/ethernet/ethernet.go b/src/maasagent/internal/ethernet/ethernet.go
index 7128286..8356d54 100644
--- a/src/maasagent/internal/ethernet/ethernet.go
+++ b/src/maasagent/internal/ethernet/ethernet.go
@@ -16,22 +16,26 @@ const (
minEthernetLen = 14
)
+type EthernetType uint16
+
+//go:generate go run golang.org/x/tools/cmd/stringer -type=EthernetType -trimprefix=EthernetType
+
const (
// EthernetTypeLLC is a special ethernet type, if found the frame is truncated
- EthernetTypeLLC uint16 = 0
+ EthernetTypeLLC EthernetType = 0
// EthernetTypeIPv4 is the ethernet type for a frame containing an IPv4 packet
- EthernetTypeIPv4 uint16 = 0x0800
+ EthernetTypeIPv4 EthernetType = 0x0800
// EthernetTypeARP is the ethernet type for a frame containing an ARP packet
- EthernetTypeARP uint16 = 0x0806
+ EthernetTypeARP EthernetType = 0x0806
// EthernetTypeIPv6 is the ethernet type for a frame containing an IPv6 packet
- EthernetTypeIPv6 uint16 = 0x86dd
+ EthernetTypeIPv6 EthernetType = 0x86dd
// EthernetTypeVLAN is the ethernet type for a frame containing a VLAN tag,
// the VLAN tag bytes will indicate the actual type of packet the frame contains
- EthernetTypeVLAN uint16 = 0x8100
+ EthernetTypeVLAN EthernetType = 0x8100
// NonStdLenEthernetTypes is a magic number to find any non-standard types
// and mark them as EthernetTypeLLC
- NonStdLenEthernetTypes uint16 = 0x600
+ NonStdLenEthernetTypes EthernetType = 0x600
)
var (
@@ -51,7 +55,7 @@ type VLAN struct {
Priority uint8
DropEligible bool
ID uint16
- EthernetType uint16
+ EthernetType EthernetType
}
// UnmarshalBinary will take the ethernet frame's payload
@@ -68,7 +72,7 @@ func (v *VLAN) UnmarshalBinary(buf []byte) error {
// extract the next 12 bits for an ID
v.ID = binary.BigEndian.Uint16(buf[:2]) & 0x0fff
// last 2 bytes are ethernet type
- v.EthernetType = binary.BigEndian.Uint16(buf[2:])
+ v.EthernetType = EthernetType(binary.BigEndian.Uint16(buf[2:]))
return nil
}
@@ -79,7 +83,7 @@ type EthernetFrame struct {
DstMAC net.HardwareAddr
Payload []byte
Len uint16
- EthernetType uint16
+ EthernetType EthernetType
}
// ExtractARPPacket will extract an ARP packet from the ethernet frame's
@@ -131,14 +135,14 @@ func (e *EthernetFrame) UnmarshalBinary(buf []byte) error {
e.DstMAC = buf[0:6]
e.SrcMAC = buf[6:12]
- e.EthernetType = binary.BigEndian.Uint16(buf[12:14])
+ e.EthernetType = EthernetType(binary.BigEndian.Uint16(buf[12:14]))
e.Payload = buf[14:]
if e.EthernetType < NonStdLenEthernetTypes {
// see IEEE 802.3, non-standard ethernet may contain padding
// this calculation is used to truncate the payload to the length
// specified for that ethernet type
- e.Len = e.EthernetType
+ e.Len = uint16(e.EthernetType)
e.EthernetType = EthernetTypeLLC
cmp := len(e.Payload) - int(e.Len)
diff --git a/src/maasagent/internal/ethernet/ethernet_test.go b/src/maasagent/internal/ethernet/ethernet_test.go
index 64e5595..a3be96e 100644
--- a/src/maasagent/internal/ethernet/ethernet_test.go
+++ b/src/maasagent/internal/ethernet/ethernet_test.go
@@ -7,62 +7,69 @@ package ethernet
import (
"io"
+ "net/netip"
"testing"
"github.com/stretchr/testify/assert"
)
func TestVLANUnmarshal(t *testing.T) {
- table := []unmarshalVLANCase{
- {
- basePacketTestCase: basePacketTestCase{
- Name: "ValidVLANTag",
- In: []byte{0x00, 0x02, 0x08, 0x06},
- },
- Out: &VLAN{
+ t.Parallel()
+
+ testcases := map[string]struct {
+ in []byte
+ out *VLAN
+ err error
+ }{
+ "valid VLAN tag": {
+ in: []byte{0x00, 0x02, 0x08, 0x06},
+ out: &VLAN{
Priority: 0,
DropEligible: false,
ID: 2,
EthernetType: EthernetTypeARP,
},
},
- {
- basePacketTestCase: basePacketTestCase{
- Name: "InvalidVLANTag",
- In: []byte{0x00, 0x02},
- Err: ErrMalformedVLAN,
- },
+ "invalid VLAN tag": {
+ in: []byte{0x00, 0x02},
+ err: ErrMalformedVLAN,
},
}
- for _, tcase := range table {
- t.Run(tcase.Name, func(tt *testing.T) {
+ for name, tc := range testcases {
+ tc := tc
+
+ t.Run(name, func(t *testing.T) {
+ t.Parallel()
res := &VLAN{}
- err := res.UnmarshalBinary(tcase.In)
- assert.ErrorIsf(tt, err, tcase.Err, "expected UnmarshalVLAN to return an error of %s", tcase.Err)
+ err := res.UnmarshalBinary(tc.in)
+ assert.ErrorIsf(t, err, tc.err, "expected UnmarshalVLAN to return an error of %s", tc.err)
- if tcase.Out != nil {
- compareVLANs(tt, tcase.Out, res)
+ if err == nil {
+ assert.Equal(t, tc.out, res)
}
})
}
}
func TestEthernetUnmarshal(t *testing.T) {
- table := []unmarshalEthernetCase{
- {
- basePacketTestCase: basePacketTestCase{
- Name: "ValidEthernetFrameWithoutVLAN",
- In: []byte{
- 0x24, 0x4b, 0xfe, 0xe1, 0xea, 0x26, 0x80, 0x61, 0x5f, 0x08, 0xfc, 0x16, 0x08, 0x06, 0x00, 0x01,
- 0x08, 0x00, 0x06, 0x04, 0x00, 0x02, 0x80, 0x61, 0x5f, 0x08, 0xfc, 0x16, 0xc0, 0xa8, 0x01, 0x6c,
- 0x24, 0x4b, 0xfe, 0xe1, 0xea, 0x26, 0xc0, 0xa8, 0x01, 0x50,
- },
- },
- Out: &EthernetFrame{
- SrcMAC: parseMACNoError("80:61:5f:08:fc:16"),
- DstMAC: parseMACNoError("24:4b:fe:e1:ea:26"),
+ t.Parallel()
+
+ testcases := map[string]struct {
+ in []byte
+ out *EthernetFrame
+ err error
+ }{
+ "valid ethernet frame without VLAN": {
+ in: []byte{
+ 0x24, 0x4b, 0xfe, 0xe1, 0xea, 0x26, 0x80, 0x61, 0x5f, 0x08, 0xfc, 0x16, 0x08, 0x06, 0x00, 0x01,
+ 0x08, 0x00, 0x06, 0x04, 0x00, 0x02, 0x80, 0x61, 0x5f, 0x08, 0xfc, 0x16, 0xc0, 0xa8, 0x01, 0x6c,
+ 0x24, 0x4b, 0xfe, 0xe1, 0xea, 0x26, 0xc0, 0xa8, 0x01, 0x50,
+ },
+ out: &EthernetFrame{
+ SrcMAC: []byte{0x80, 0x61, 0x5f, 0x08, 0xfc, 0x16},
+ DstMAC: []byte{0x24, 0x4b, 0xfe, 0xe1, 0xea, 0x26},
EthernetType: EthernetTypeARP,
Payload: []byte{
0x00, 0x01,
@@ -71,19 +78,16 @@ func TestEthernetUnmarshal(t *testing.T) {
},
},
},
- {
- basePacketTestCase: basePacketTestCase{
- Name: "ValidEthernetFrameWithVLAN",
- In: []byte{
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x84, 0x39, 0xc0, 0x0b, 0x22, 0x25, 0x81, 0x00, 0x00, 0x02,
- 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x84, 0x39, 0xc0, 0x0b, 0x22, 0x25,
- 0xc0, 0xa8, 0x0a, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x0a, 0x19, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- },
- },
- Out: &EthernetFrame{
- SrcMAC: parseMACNoError("84:39:c0:0b:22:25"),
- DstMAC: parseMACNoError("ff:ff:ff:ff:ff:ff"),
+ "valid ethernet frame with VLAN": {
+ in: []byte{
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x84, 0x39, 0xc0, 0x0b, 0x22, 0x25, 0x81, 0x00, 0x00, 0x02,
+ 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x84, 0x39, 0xc0, 0x0b, 0x22, 0x25,
+ 0xc0, 0xa8, 0x0a, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x0a, 0x19, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ },
+ out: &EthernetFrame{
+ SrcMAC: []byte{0x84, 0x39, 0xc0, 0x0b, 0x22, 0x25},
+ DstMAC: []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
EthernetType: EthernetTypeVLAN,
Payload: []byte{
0x00, 0x02,
@@ -93,148 +97,148 @@ func TestEthernetUnmarshal(t *testing.T) {
},
},
},
- {
- basePacketTestCase: basePacketTestCase{
- Name: "NoEthernetFrame",
- Err: io.ErrUnexpectedEOF,
- },
- },
- {
- basePacketTestCase: basePacketTestCase{
- Name: "InvalidEthernetFrame",
- In: []byte{
- 0xff, 0xff, 0xff, 0xff, 0xff, 0x84, 0x39, 0xc0, 0x0b, 0x22, 0x25, 0x00, 0x02,
- 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x84, 0x39, 0xc0, 0x0b, 0x22, 0x25,
- 0xc0, 0xa8, 0x0a, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x0a, 0x19,
- },
- Err: ErrMalformedFrame,
+ "no ethernet frame": {err: io.ErrUnexpectedEOF},
+ "invalid ethernet frame": {
+ in: []byte{
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x84, 0x39, 0xc0, 0x0b, 0x22, 0x25, 0x00, 0x02,
+ 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x84, 0x39, 0xc0, 0x0b, 0x22, 0x25,
+ 0xc0, 0xa8, 0x0a, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x0a, 0x19,
},
- },
+
+ err: ErrMalformedFrame},
}
- for _, tcase := range table {
- t.Run(tcase.Name, func(tt *testing.T) {
- res := &EthernetFrame{}
+ for name, tc := range testcases {
+ tc := tc
- err := res.UnmarshalBinary(tcase.In)
- assert.ErrorIsf(tt, err, tcase.Err, "expected UnmarshalEthernet to return an error of %s", tcase.Err)
+ t.Run(name, func(t *testing.T) {
+ t.Parallel()
+
+ res := &EthernetFrame{}
+ err := res.UnmarshalBinary(tc.in)
+ assert.ErrorIsf(t, err, tc.err, "expected UnmarshalEthernet to return an error of %s", tc.err)
- if tcase.Out != nil {
- compareEthernetFrames(tt, tcase.Out, res)
+ if err == nil {
+ assert.Equal(t, tc.out, res)
}
})
}
}
func TestEthernetFrameExtractVLAN(t *testing.T) {
- table := []unmarshalVLANCase{
- {
- basePacketTestCase: basePacketTestCase{
- Name: "EthernetFrameIsVLAN",
- In: []byte{
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x84, 0x39, 0xc0, 0x0b, 0x22, 0x25, 0x81, 0x00, 0x00, 0x02,
- 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x84, 0x39, 0xc0, 0x0b, 0x22, 0x25,
- 0xc0, 0xa8, 0x0a, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x0a, 0x19, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- },
- },
- Out: &VLAN{
+ t.Parallel()
+
+ testcases := map[string]struct {
+ in []byte
+ out *VLAN
+ err error
+ }{
+ "ethernet frame is VLAN": {
+ in: []byte{
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x84, 0x39, 0xc0, 0x0b, 0x22, 0x25, 0x81, 0x00, 0x00, 0x02,
+ 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x84, 0x39, 0xc0, 0x0b, 0x22, 0x25,
+ 0xc0, 0xa8, 0x0a, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x0a, 0x19, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ },
+ out: &VLAN{
ID: 2,
EthernetType: EthernetTypeARP,
- },
- },
- {
- basePacketTestCase: basePacketTestCase{
- Name: "EthernetFrameIsNotVLAN",
- In: []byte{
- 0x24, 0x4b, 0xfe, 0xe1, 0xea, 0x26, 0x80, 0x61, 0x5f, 0x08, 0xfc, 0x16, 0x08, 0x06, 0x00, 0x01,
- 0x08, 0x00, 0x06, 0x04, 0x00, 0x02, 0x80, 0x61, 0x5f, 0x08, 0xfc, 0x16, 0xc0, 0xa8, 0x01, 0x6c,
- 0x24, 0x4b, 0xfe, 0xe1, 0xea, 0x26, 0xc0, 0xa8, 0x01, 0x50,
- },
- Err: ErrNotVLAN,
- },
+ }},
+ "ethernet frame is not VLAN": {
+ in: []byte{
+ 0x24, 0x4b, 0xfe, 0xe1, 0xea, 0x26, 0x80, 0x61, 0x5f, 0x08, 0xfc, 0x16, 0x08, 0x06, 0x00, 0x01,
+ 0x08, 0x00, 0x06, 0x04, 0x00, 0x02, 0x80, 0x61, 0x5f, 0x08, 0xfc, 0x16, 0xc0, 0xa8, 0x01, 0x6c,
+ 0x24, 0x4b, 0xfe, 0xe1, 0xea, 0x26, 0xc0, 0xa8, 0x01, 0x50,
+ },
+ err: ErrNotVLAN,
},
}
- for _, tcase := range table {
- t.Run(tcase.Name, func(tt *testing.T) {
+ for name, tc := range testcases {
+ tc := tc
+
+ t.Run(name, func(t *testing.T) {
+ t.Parallel()
eth := &EthernetFrame{}
- err := eth.UnmarshalBinary(tcase.In)
+ err := eth.UnmarshalBinary(tc.in)
if err != nil {
- tt.Fatal(err)
+ t.Fatal(err)
}
vlan, err := eth.ExtractVLAN()
- assert.ErrorIsf(tt, err, tcase.Err, "expected ExtractVLAN to return an error of: %s", tcase.Err)
+ assert.ErrorIsf(t, err, tc.err, "expected ExtractVLAN to return an error of: %s", tc.err)
- if tcase.Out != nil {
- compareVLANs(tt, tcase.Out, vlan)
+ if err == nil {
+ assert.Equal(t, tc.out, vlan)
}
})
}
}
func TestEthernetFrameExtractARP(t *testing.T) {
- table := []unmarshalCase{
- {
- basePacketTestCase: basePacketTestCase{
- Name: "EthernetFrameIsVLAN",
- In: []byte{
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x84, 0x39, 0xc0, 0x0b, 0x22, 0x25, 0x81, 0x00, 0x00, 0x02,
- 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x84, 0x39, 0xc0, 0x0b, 0x22, 0x25,
- 0xc0, 0xa8, 0x0a, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x0a, 0x19, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- },
- },
- Out: &ARPPacket{
+ t.Parallel()
+
+ testcases := map[string]struct {
+ in []byte
+ out *ARPPacket
+ err error
+ }{
+ "ethernet frame is VLAN": {
+ in: []byte{
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x84, 0x39, 0xc0, 0x0b, 0x22, 0x25, 0x81, 0x00, 0x00, 0x02,
+ 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x84, 0x39, 0xc0, 0x0b, 0x22, 0x25,
+ 0xc0, 0xa8, 0x0a, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x0a, 0x19, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ },
+ out: &ARPPacket{
HardwareType: HardwareTypeEthernet,
ProtocolType: ProtocolTypeIPv4,
HardwareAddrLen: 6,
ProtocolAddrLen: 4,
OpCode: OpRequest,
- SendHwdAddr: parseMACNoError("84:39:c0:0b:22:25"),
- SendIPAddr: parseAddrNoError("192.168.10.26"),
- TgtHwdAddr: parseMACNoError("00:00:00:00:00:00"),
- TgtIPAddr: parseAddrNoError("192.168.10.25"),
+ SendHwAddr: []byte{0x84, 0x39, 0xc0, 0x0b, 0x22, 0x25},
+ SendIPAddr: netip.MustParseAddr("192.168.10.26"),
+ TgtHwAddr: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ TgtIPAddr: netip.MustParseAddr("192.168.10.25"),
},
},
- {
- basePacketTestCase: basePacketTestCase{
- Name: "EthernetFrameIsNotVLAN",
- In: []byte{
- 0x24, 0x4b, 0xfe, 0xe1, 0xea, 0x26, 0x80, 0x61, 0x5f, 0x08, 0xfc, 0x16, 0x08, 0x06, 0x00, 0x01,
- 0x08, 0x00, 0x06, 0x04, 0x00, 0x02, 0x80, 0x61, 0x5f, 0x08, 0xfc, 0x16, 0xc0, 0xa8, 0x01, 0x6c,
- 0x24, 0x4b, 0xfe, 0xe1, 0xea, 0x26, 0xc0, 0xa8, 0x01, 0x50,
- },
+ "ethernet frame is not VLAN": {
+ in: []byte{
+ 0x24, 0x4b, 0xfe, 0xe1, 0xea, 0x26, 0x80, 0x61, 0x5f, 0x08, 0xfc, 0x16, 0x08, 0x06, 0x00, 0x01,
+ 0x08, 0x00, 0x06, 0x04, 0x00, 0x02, 0x80, 0x61, 0x5f, 0x08, 0xfc, 0x16, 0xc0, 0xa8, 0x01, 0x6c,
+ 0x24, 0x4b, 0xfe, 0xe1, 0xea, 0x26, 0xc0, 0xa8, 0x01, 0x50,
},
- Out: &ARPPacket{
+ out: &ARPPacket{
HardwareType: HardwareTypeEthernet,
ProtocolType: ProtocolTypeIPv4,
HardwareAddrLen: 6,
ProtocolAddrLen: 4,
OpCode: OpReply,
- SendHwdAddr: parseMACNoError("80:61:5f:08:fc:16"),
- SendIPAddr: parseAddrNoError("192.168.1.108"),
- TgtHwdAddr: parseMACNoError("24:4b:fe:e1:ea:26"),
- TgtIPAddr: parseAddrNoError("192.168.1.80"),
+ SendHwAddr: []byte{0x80, 0x61, 0x5f, 0x08, 0xfc, 0x16},
+ SendIPAddr: netip.MustParseAddr("192.168.1.108"),
+ TgtHwAddr: []byte{0x24, 0x4b, 0xfe, 0xe1, 0xea, 0x26},
+ TgtIPAddr: netip.MustParseAddr("192.168.1.80"),
},
},
}
- for _, tcase := range table {
- t.Run(tcase.Name, func(tt *testing.T) {
+ for name, tc := range testcases {
+ tc := tc
+
+ t.Run(name, func(t *testing.T) {
+ t.Parallel()
eth := &EthernetFrame{}
- err := eth.UnmarshalBinary(tcase.In)
+ err := eth.UnmarshalBinary(tc.in)
if err != nil {
- tt.Fatal(err)
+ t.Fatal(err)
}
pkt, err := eth.ExtractARPPacket()
- assert.ErrorIsf(tt, err, tcase.Err, "expected ExtractARPPacket to return an error of: %s", tcase.Err)
+ assert.ErrorIsf(t, err, tc.err, "expected ExtractARPPacket to return an error of: %s", tc.err)
- if tcase.Out != nil {
- compareARPPacket(tt, tcase.Out, pkt)
+ if err == nil {
+ assert.Equal(t, tc.out, pkt)
}
})
}
diff --git a/src/maasagent/internal/ethernet/ethernettype_string.go b/src/maasagent/internal/ethernet/ethernettype_string.go
new file mode 100644
index 0000000..59f8c94
--- /dev/null
+++ b/src/maasagent/internal/ethernet/ethernettype_string.go
@@ -0,0 +1,45 @@
+// Code generated by "stringer -type=EthernetType -trimprefix=EthernetType"; DO NOT EDIT.
+
+package ethernet
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[EthernetTypeLLC-0]
+ _ = x[EthernetTypeIPv4-2048]
+ _ = x[EthernetTypeARP-2054]
+ _ = x[EthernetTypeIPv6-34525]
+ _ = x[EthernetTypeVLAN-33024]
+ _ = x[NonStdLenEthernetTypes-1536]
+}
+
+const (
+ _EthernetType_name_0 = "LLC"
+ _EthernetType_name_1 = "NonStdLenEthernetTypes"
+ _EthernetType_name_2 = "IPv4"
+ _EthernetType_name_3 = "ARP"
+ _EthernetType_name_4 = "VLAN"
+ _EthernetType_name_5 = "IPv6"
+)
+
+func (i EthernetType) String() string {
+ switch {
+ case i == 0:
+ return _EthernetType_name_0
+ case i == 1536:
+ return _EthernetType_name_1
+ case i == 2048:
+ return _EthernetType_name_2
+ case i == 2054:
+ return _EthernetType_name_3
+ case i == 33024:
+ return _EthernetType_name_4
+ case i == 34525:
+ return _EthernetType_name_5
+ default:
+ return "EthernetType(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+}
diff --git a/src/maasagent/internal/ethernet/hardwaretype_string.go b/src/maasagent/internal/ethernet/hardwaretype_string.go
new file mode 100644
index 0000000..4b3fc04
--- /dev/null
+++ b/src/maasagent/internal/ethernet/hardwaretype_string.go
@@ -0,0 +1,51 @@
+// Code generated by "stringer -type=HardwareType -trimprefix=HardwareType"; DO NOT EDIT.
+
+package ethernet
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[HardwareTypeReserved-0]
+ _ = x[HardwareTypeEthernet-1]
+ _ = x[HardwareTypeExpEth-2]
+ _ = x[HardwareTypeAX25-3]
+ _ = x[HardwareTypeChaos-4]
+ _ = x[HardwareTypeIEEE802-5]
+ _ = x[HardwareTypeFiberChannel-18]
+ _ = x[HardwareTypeSerialLine-19]
+ _ = x[HardwareTypeHIPARP-28]
+ _ = x[HardwareTypeIPARPISO7163-29]
+ _ = x[HardwareTypeARPSec-30]
+ _ = x[HardwareTypeIPSec-31]
+ _ = x[HardwareTypeInfiniBand-32]
+}
+
+const (
+ _HardwareType_name_0 = "ReservedEthernetExpEthAX25ChaosIEEE802"
+ _HardwareType_name_1 = "FiberChannelSerialLine"
+ _HardwareType_name_2 = "HIPARPIPARPISO7163ARPSecIPSecInfiniBand"
+)
+
+var (
+ _HardwareType_index_0 = [...]uint8{0, 8, 16, 22, 26, 31, 38}
+ _HardwareType_index_1 = [...]uint8{0, 12, 22}
+ _HardwareType_index_2 = [...]uint8{0, 6, 18, 24, 29, 39}
+)
+
+func (i HardwareType) String() string {
+ switch {
+ case i <= 5:
+ return _HardwareType_name_0[_HardwareType_index_0[i]:_HardwareType_index_0[i+1]]
+ case 18 <= i && i <= 19:
+ i -= 18
+ return _HardwareType_name_1[_HardwareType_index_1[i]:_HardwareType_index_1[i+1]]
+ case 28 <= i && i <= 32:
+ i -= 28
+ return _HardwareType_name_2[_HardwareType_index_2[i]:_HardwareType_index_2[i+1]]
+ default:
+ return "HardwareType(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+}
diff --git a/src/maasagent/internal/ethernet/helpers_test.go b/src/maasagent/internal/ethernet/helpers_test.go
deleted file mode 100644
index a1529b4..0000000
--- a/src/maasagent/internal/ethernet/helpers_test.go
+++ /dev/null
@@ -1,135 +0,0 @@
-package ethernet
-
-/*
- Copyright 2023 Canonical Ltd. This software is licensed under the
- GNU Affero General Public License version 3 (see the file LICENSE).
-*/
-
-import (
- "net"
- "net/netip"
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-type basePacketTestCase struct {
- Name string
- Err error
- In []byte
-}
-
-type unmarshalVLANCase struct {
- Out *VLAN
- basePacketTestCase
-}
-
-type unmarshalEthernetCase struct {
- Out *EthernetFrame
- basePacketTestCase
-}
-
-type unmarshalCase struct {
- Out *ARPPacket
- basePacketTestCase
-}
-
-func parseMACNoError(s string) net.HardwareAddr {
- addr, _ := net.ParseMAC(s)
- return addr
-}
-
-func parseAddrNoError(s string) netip.Addr {
- addr, _ := netip.ParseAddr(s)
- return addr
-}
-
-func ethernetTypeToString(t uint16) string {
- switch t {
- case EthernetTypeLLC:
- return "LLC"
- case EthernetTypeIPv4:
- return "IPv4"
- case EthernetTypeARP:
- return "ARP"
- case EthernetTypeIPv6:
- return "IPv6"
- case EthernetTypeVLAN:
- return "VLAN"
- }
-
- return "unknown"
-}
-
-func hardwareTypeToString(t uint16) string {
- switch t {
- case HardwareTypeReserved:
- return "Reserved"
- case HardwareTypeEthernet:
- return "Ethernet"
- case HardwareTypeExpEth:
- return "Experimetnal Ethernet"
- case HardwareTypeAX25:
- return "AX25"
- case HardwareTypeChaos:
- return "Chaos"
- case HardwareTypeIEEE802:
- return "802"
- case HardwareTypeFiberChannel:
- return "Fiber Channel"
- case HardwareTypeSerialLine:
- return "Serial Line"
- case HardwareTypeHIPARP:
- return "HIPARP"
- case HardwareTypeIPARPISO7163:
- return "IP-ARP"
- case HardwareTypeARPSec:
- return "ARP-Sec"
- case HardwareTypeIPSec:
- return "IP-Sec"
- case HardwareTypeInfiniBand:
- return "InfiniBand"
- }
-
- return "unknown"
-}
-
-func protocolTypeToString(t uint16) string {
- switch t {
- case ProtocolTypeIPv4:
- return "IPv4"
- case ProtocolTypeIPv6:
- return "IPv6"
- case ProtocolTypeARP:
- return "ARP"
- }
-
- return "unknown"
-}
-
-func compareVLANs(t *testing.T, expected, actual *VLAN) {
- assert.Equalf(t, expected.Priority, actual.Priority, "expected Priority to be %d", int(expected.Priority))
- assert.Equalf(t, expected.DropEligible, actual.DropEligible, "exptected DropEligible to be %v", expected.DropEligible)
- assert.Equalf(t, expected.ID, actual.ID, "expected ID to be %d", int(expected.ID))
- assert.Equalf(t, expected.EthernetType, actual.EthernetType, "expected EthernetType to be %s", ethernetTypeToString(expected.EthernetType))
-}
-
-func compareEthernetFrames(t *testing.T, expected, actual *EthernetFrame) {
- assert.Equalf(t, expected.SrcMAC, actual.SrcMAC, "expected SrcMAC to be %s", expected.SrcMAC)
- assert.Equalf(t, expected.DstMAC, actual.DstMAC, "expected DstMAC to be %s", expected.DstMAC)
- assert.Equalf(t, expected.EthernetType, actual.EthernetType, "expected EthernetType to be %s", ethernetTypeToString(expected.EthernetType))
- assert.Equalf(t, expected.Len, actual.Len, "expected a length of %d", int(expected.Len))
- assert.Equalf(t, expected.Payload, actual.Payload, "expected a payload of %x", expected.Payload)
-}
-
-func compareARPPacket(t *testing.T, expected, actual *ARPPacket) {
- assert.Equalf(t, expected.HardwareType, actual.HardwareType, "expected a HardwareType of %s", hardwareTypeToString(expected.HardwareType))
- assert.Equalf(t, expected.ProtocolType, actual.ProtocolType, "expected a ProtocolType of %s", protocolTypeToString(expected.ProtocolType))
- assert.Equalf(t, expected.HardwareAddrLen, actual.HardwareAddrLen, "expected a HardwareAddrLen of %d", int(expected.HardwareAddrLen))
- assert.Equalf(t, expected.ProtocolAddrLen, actual.ProtocolAddrLen, "expected a ProtocolAddrLen of %d", int(expected.ProtocolAddrLen))
- assert.Equalf(t, expected.OpCode, actual.OpCode, "expected a ProtocolLen of %d", int(expected.OpCode))
- assert.Equalf(t, expected.SendHwdAddr, actual.SendHwdAddr, "expected a SendHwdAddr of %s", expected.SendHwdAddr)
- assert.Equalf(t, expected.SendIPAddr, actual.SendIPAddr, "expected a SendIPAddr of %s", expected.SendIPAddr)
- assert.Equalf(t, expected.TgtHwdAddr, actual.TgtHwdAddr, "expected a TgtHwdAddr of %s", expected.TgtHwdAddr)
- assert.Equalf(t, expected.TgtIPAddr, actual.TgtIPAddr, "expected a TgtIPAddr of %s", expected.TgtIPAddr)
-}
diff --git a/src/maasagent/internal/ethernet/protocoltype_string.go b/src/maasagent/internal/ethernet/protocoltype_string.go
new file mode 100644
index 0000000..6d3ba87
--- /dev/null
+++ b/src/maasagent/internal/ethernet/protocoltype_string.go
@@ -0,0 +1,33 @@
+// Code generated by "stringer -type=ProtocolType -trimprefix=ProtocolType"; DO NOT EDIT.
+
+package ethernet
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[ProtocolTypeIPv4-2048]
+ _ = x[ProtocolTypeIPv6-34525]
+ _ = x[ProtocolTypeARP-2054]
+}
+
+const (
+ _ProtocolType_name_0 = "IPv4"
+ _ProtocolType_name_1 = "ARP"
+ _ProtocolType_name_2 = "IPv6"
+)
+
+func (i ProtocolType) String() string {
+ switch {
+ case i == 2048:
+ return _ProtocolType_name_0
+ case i == 2054:
+ return _ProtocolType_name_1
+ case i == 34525:
+ return _ProtocolType_name_2
+ default:
+ return "ProtocolType(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+}
diff --git a/src/maasagent/internal/netmon/event_test.go b/src/maasagent/internal/netmon/event_test.go
index 1064c6b..06c4664 100644
--- a/src/maasagent/internal/netmon/event_test.go
+++ b/src/maasagent/internal/netmon/event_test.go
@@ -7,166 +7,120 @@ import (
"github.com/stretchr/testify/assert"
)
-type eventStringCase struct {
- Name string
- Out string
- In Event
-}
-
func TestEventString(t *testing.T) {
- table := []eventStringCase{
- {
- Name: "EventNew",
- In: EventNew,
- Out: eventNewStr,
- },
- {
- Name: "EventRefreshed",
- In: EventRefreshed,
- Out: eventRefreshedStr,
- },
- {
- Name: "EventMoved",
- In: EventMoved,
- Out: eventMovedStr,
- },
- {
- Name: "Unknown",
- In: Event(0xff),
- Out: "UNKNOWN",
- },
- }
-
- for _, tcase := range table {
- t.Run(tcase.Name, func(tt *testing.T) {
- assert.Equalf(tt, tcase.Out, tcase.In.String(), "expected a string of %s", tcase.Out)
- })
- }
-}
-
-type eventValidStringCase struct {
- Err error
- eventStringCase
-}
+ t.Parallel()
-func TestEventValidString(t *testing.T) {
- table := []eventValidStringCase{
- {
- eventStringCase: eventStringCase{
- Name: "EventNew",
- In: EventNew,
- Out: eventNewStr,
- },
- },
- {
- eventStringCase: eventStringCase{
- Name: "EventRefreshed",
- In: EventRefreshed,
- Out: eventRefreshedStr,
- },
- },
- {
- eventStringCase: eventStringCase{
- Name: "EventMoved",
- In: EventMoved,
- Out: eventMovedStr,
- },
- },
- {
- eventStringCase: eventStringCase{
- Name: "Unknown",
- In: Event(0xff),
- },
- Err: errInvalidEvent,
+ testcases := map[string]struct {
+ in Event
+ out string
+ err error
+ }{
+ "event new": {
+ in: EventNew,
+ out: eventNewStr,
+ },
+ "event refreshed": {
+ in: EventRefreshed,
+ out: eventRefreshedStr,
+ },
+ "event moved": {
+ in: EventMoved,
+ out: eventMovedStr,
+ },
+ "unknown": {
+ in: Event(0xff),
+ out: "UNKNOWN",
+ err: errInvalidEvent,
},
}
- for _, tcase := range table {
- t.Run(tcase.Name, func(tt *testing.T) {
- str, err := tcase.In.ValidString()
- assert.Equalf(tt, tcase.Out, str, "expected a string of %s", tcase.Out)
- assert.ErrorIs(tt, err, tcase.Err)
+ for name, tc := range testcases {
+ tc := tc
+
+ t.Run(name, func(t *testing.T) {
+ t.Parallel()
+ assert.Equalf(t, tc.out, tc.in.String(), "expected a string of %s", tc.out)
+ _, err := tc.in.ValidString()
+ if err != nil {
+ assert.ErrorIsf(t, err, tc.err, "expected ValidString to return an error of %s", tc.err)
+ }
})
}
}
-type eventMarshalJSONCase struct {
- Err error
- Name string
- Out []byte
- In Event
-}
-
func TestMarshalJSON(t *testing.T) {
- table := []eventMarshalJSONCase{
- {
- Name: "EventNew",
- In: EventNew,
- Out: []byte("\"" + eventNewStr + "\""),
- },
- {
- Name: "EventRefreshed",
- In: EventRefreshed,
- Out: []byte("\"" + eventRefreshedStr + "\""),
- },
- {
- Name: "EventMoved",
- In: EventMoved,
- Out: []byte("\"" + eventMovedStr + "\""),
- },
- {
- Name: "Uknown",
- In: Event(0xff),
- Err: errInvalidEvent,
+ t.Parallel()
+
+ testcases := map[string]struct {
+ in Event
+ out []byte
+ err error
+ }{
+ "event new": {
+ in: EventNew,
+ out: []byte("\"" + eventNewStr + "\""),
+ },
+ "event refreshed": {
+ in: EventRefreshed,
+ out: []byte("\"" + eventRefreshedStr + "\""),
+ },
+ "event moved": {
+ in: EventMoved,
+ out: []byte("\"" + eventMovedStr + "\""),
+ },
+ "unknown": {
+ in: Event(0xff),
+ err: errInvalidEvent,
},
}
- for _, tcase := range table {
- t.Run(tcase.Name, func(tt *testing.T) {
- b, err := tcase.In.MarshalJSON()
- assert.Equalf(tt, b, tcase.Out, "expected event to marshal to %s", tcase.Out)
- assert.ErrorIs(tt, err, tcase.Err)
+ for name, tc := range testcases {
+ tc := tc
+
+ t.Run(name, func(t *testing.T) {
+ t.Parallel()
+ b, err := tc.in.MarshalJSON()
+ assert.Equalf(t, b, tc.out, "expected event to marshal to %s", tc.out)
+ assert.ErrorIs(t, err, tc.err)
})
}
}
-type eventUnmarshalJSONCase struct {
- Name string
- Err error
- In []byte
- Out Event
-}
-
func TestEventUnmarshalJSON(t *testing.T) {
- table := []eventUnmarshalJSONCase{
- {
- Name: "EventNew",
- In: []byte("\"NEW\""),
- Out: EventNew,
- },
- {
- Name: "EventRefreshed",
- In: []byte("\"REFRESHED\""),
- Out: EventRefreshed,
- },
- {
- Name: "EventMoved",
- In: []byte("\"MOVED\""),
- Out: EventMoved,
- },
- {
- Name: "Empty",
- Err: &json.SyntaxError{},
+ t.Parallel()
+
+ testcases := map[string]struct {
+ in []byte
+ out Event
+ err error
+ }{
+ "event new": {
+ in: []byte("\"NEW\""),
+ out: EventNew,
+ },
+ "event refreshed": {
+ in: []byte("\"REFRESHED\""),
+ out: EventRefreshed,
+ },
+ "event moved": {
+ in: []byte("\"MOVED\""),
+ out: EventMoved,
+ },
+ "unknown": {
+ err: &json.SyntaxError{},
},
}
- for _, tcase := range table {
- t.Run(tcase.Name, func(tt *testing.T) {
+ for name, tc := range testcases {
+ tc := tc
+
+ t.Run(name, func(t *testing.T) {
+ t.Parallel()
var e Event
- err := e.UnmarshalJSON(tcase.In)
- assert.Equalf(tt, tcase.Out, e, "expected event to equal %s", tcase.Out)
- if tcase.Err != nil {
- assert.ErrorAs(tt, err, &tcase.Err)
+ err := e.UnmarshalJSON(tc.in)
+ assert.Equalf(t, tc.out, e, "expected event to equal %s", tc.out)
+ if tc.err != nil {
+ assert.ErrorAs(t, err, &tc.err)
}
})
}
diff --git a/src/maasagent/internal/netmon/service.go b/src/maasagent/internal/netmon/service.go
index a7116cb..580a5ca 100644
--- a/src/maasagent/internal/netmon/service.go
+++ b/src/maasagent/internal/netmon/service.go
@@ -95,7 +95,7 @@ func (s *Service) updateBindings(pkt *ethernet.ARPPacket, vid *uint16, timestamp
discoveredBindings := []Binding{
{
IP: pkt.SendIPAddr,
- MAC: pkt.SendHwdAddr,
+ MAC: pkt.SendHwAddr,
VID: vid,
Time: timestamp,
},
@@ -104,7 +104,7 @@ func (s *Service) updateBindings(pkt *ethernet.ARPPacket, vid *uint16, timestamp
if pkt.OpCode == ethernet.OpReply {
discoveredBindings = append(discoveredBindings, Binding{
IP: pkt.TgtIPAddr,
- MAC: pkt.TgtHwdAddr,
+ MAC: pkt.TgtHwAddr,
VID: vid,
Time: timestamp,
})
diff --git a/src/maasagent/internal/netmon/service_test.go b/src/maasagent/internal/netmon/service_test.go
index 94e0762..f5fbf5f 100644
--- a/src/maasagent/internal/netmon/service_test.go
+++ b/src/maasagent/internal/netmon/service_test.go
@@ -22,106 +22,95 @@ func uint16Pointer(v uint16) *uint16 {
return &v
}
-type isValidARPPacketCase struct {
- In *ethernet.ARPPacket
- Name string
- Out bool
-}
-
func TestIsValidARPPacket(t *testing.T) {
- table := []isValidARPPacketCase{
- {
- Name: "ValidARPPacket",
- In: ðernet.ARPPacket{
+ t.Parallel()
+
+ testcases := map[string]struct {
+ in *ethernet.ARPPacket
+ out bool
+ }{
+ "valid ARP packet": {
+ in: ðernet.ARPPacket{
HardwareType: ethernet.HardwareTypeEthernet,
ProtocolType: ethernet.ProtocolTypeIPv4,
HardwareAddrLen: 6,
ProtocolAddrLen: 4,
},
- Out: true,
+ out: true,
},
- {
- Name: "InvalidHardwareTypeARPPacket",
- In: ðernet.ARPPacket{
+ "invalid hardware type ARP packet": {
+ in: ðernet.ARPPacket{
HardwareType: ethernet.HardwareTypeChaos,
ProtocolType: ethernet.ProtocolTypeIPv4,
HardwareAddrLen: 6,
ProtocolAddrLen: 4,
},
- Out: false,
+ out: false,
},
- {
- Name: "InvalidProtocolTypeARPPacket",
- In: ðernet.ARPPacket{
+ "invalid protocol type ARP packet": {
+ in: ðernet.ARPPacket{
HardwareType: ethernet.HardwareTypeEthernet,
ProtocolType: ethernet.ProtocolTypeIPv6,
HardwareAddrLen: 6,
ProtocolAddrLen: 4,
},
- Out: false,
+ out: false,
},
- {
- Name: "InvalidHardwareAddrLenARPPacket",
- In: ðernet.ARPPacket{
+ "invalid hardware address length ARP packet": {
+ in: ðernet.ARPPacket{
HardwareType: ethernet.HardwareTypeEthernet,
ProtocolType: ethernet.ProtocolTypeIPv4,
HardwareAddrLen: 8,
ProtocolAddrLen: 4,
},
- Out: false,
+ out: false,
},
- {
- Name: "InvalidProtocolAddrLenARPPacket",
- In: ðernet.ARPPacket{
+ "invalid protocol address lenth ARP packet": {
+ in: ðernet.ARPPacket{
HardwareType: ethernet.HardwareTypeEthernet,
ProtocolType: ethernet.ProtocolTypeIPv4,
HardwareAddrLen: 6,
ProtocolAddrLen: 16,
},
- Out: false,
+ out: false,
},
}
- for _, tcase := range table {
- t.Run(tcase.Name, func(tt *testing.T) {
- assert.Equalf(tt, tcase.Out, isValidARPPacket(tcase.In), "expected the result to be %v", tcase.Out)
- })
- }
-}
-type updateBindingsArgs struct {
- Pkt *ethernet.ARPPacket
- VID *uint16
- Time time.Time
-}
+ for name, tc := range testcases {
+ tc := tc
-type updateBindingsCase struct {
- Name string
- BindingsFixture map[string]Binding
- In updateBindingsArgs
- Out []Result
+ t.Run(name, func(t *testing.T) {
+ t.Parallel()
+ assert.Equalf(t, tc.out, isValidARPPacket(tc.in),
+ "expected the result to be %v", tc.out)
+ })
+ }
}
func TestUpdateBindings(t *testing.T) {
+ t.Parallel()
+
timestamp := time.Now()
- testIP1 := net.ParseIP("10.0.0.1").To4()
- testIP2 := net.ParseIP("10.0.0.2").To4()
- table := []updateBindingsCase{
- {
- Name: "NewRequestPacket",
- In: updateBindingsArgs{
- Pkt: ðernet.ARPPacket{
- HardwareType: ethernet.HardwareTypeEthernet,
- ProtocolType: ethernet.ProtocolTypeIPv4,
- HardwareAddrLen: 6,
- ProtocolAddrLen: 4,
- OpCode: ethernet.OpRequest,
- SendHwdAddr: net.HardwareAddr{0xc0, 0xff, 0xee, 0x15, 0xc0, 0x01},
- SendIPAddr: netip.AddrFrom4([4]byte{testIP1[0], testIP1[1], testIP1[2], testIP1[3]}),
- TgtIPAddr: netip.AddrFrom4([4]byte{testIP2[0], testIP2[1], testIP2[2], testIP2[3]}),
+
+ type in struct {
+ p func(p *ethernet.ARPPacket)
+ vid *uint16
+ time time.Time
+ bindingsFixture map[string]Binding
+ }
+
+ testcases := map[string]struct {
+ in in
+ out []Result
+ }{
+ "new request packet": {
+ in: in{
+ p: func(p *ethernet.ARPPacket) {
+ p.SendHwAddr = net.HardwareAddr{0xc0, 0xff, 0xee, 0x15, 0xc0, 0x01}
},
- Time: timestamp,
+ time: timestamp,
},
- Out: []Result{
+ out: []Result{
{
IP: "10.0.0.1",
MAC: "c0:ff:ee:15:c0:01",
@@ -130,23 +119,16 @@ func TestUpdateBindings(t *testing.T) {
},
},
},
- {
- Name: "NewReplyPacket",
- In: updateBindingsArgs{
- Pkt: ðernet.ARPPacket{
- HardwareType: ethernet.HardwareTypeEthernet,
- ProtocolType: ethernet.ProtocolTypeIPv4,
- HardwareAddrLen: 6,
- ProtocolAddrLen: 4,
- OpCode: ethernet.OpReply,
- SendHwdAddr: net.HardwareAddr{0xc0, 0xff, 0xee, 0x15, 0xc0, 0x01},
- SendIPAddr: netip.AddrFrom4([4]byte{testIP1[0], testIP1[1], testIP1[2], testIP1[3]}),
- TgtHwdAddr: net.HardwareAddr{0xc0, 0xff, 0xee, 0x15, 0xc0, 0x1d},
- TgtIPAddr: netip.AddrFrom4([4]byte{testIP2[0], testIP2[1], testIP2[2], testIP2[3]}),
+ "new reply packet": {
+ in: in{
+ p: func(p *ethernet.ARPPacket) {
+ p.OpCode = ethernet.OpReply
+ p.SendHwAddr = net.HardwareAddr{0xc0, 0xff, 0xee, 0x15, 0xc0, 0x01}
+ p.TgtHwAddr = net.HardwareAddr{0xc0, 0xff, 0xee, 0x15, 0xc0, 0x1d}
},
- Time: timestamp,
+ time: timestamp,
},
- Out: []Result{
+ out: []Result{
{
IP: "10.0.0.1",
MAC: "c0:ff:ee:15:c0:01",
@@ -161,23 +143,15 @@ func TestUpdateBindings(t *testing.T) {
},
},
},
- {
- Name: "NewVLANPacket",
- In: updateBindingsArgs{
- Pkt: ðernet.ARPPacket{
- HardwareType: ethernet.HardwareTypeEthernet,
- ProtocolType: ethernet.ProtocolTypeIPv4,
- HardwareAddrLen: 6,
- ProtocolAddrLen: 4,
- OpCode: ethernet.OpRequest,
- SendHwdAddr: net.HardwareAddr{0xc0, 0xff, 0xee, 0x15, 0xc0, 0x01},
- SendIPAddr: netip.AddrFrom4([4]byte{testIP1[0], testIP1[1], testIP1[2], testIP1[3]}),
- TgtIPAddr: netip.AddrFrom4([4]byte{testIP2[0], testIP2[1], testIP2[2], testIP2[3]}),
+ "new VLAN packet": {
+ in: in{
+ p: func(p *ethernet.ARPPacket) {
+ p.SendHwAddr = net.HardwareAddr{0xc0, 0xff, 0xee, 0x15, 0xc0, 0x01}
},
- VID: uint16Pointer(2),
- Time: timestamp,
+ vid: uint16Pointer(2),
+ time: timestamp,
},
- Out: []Result{
+ out: []Result{
{
IP: "10.0.0.1",
MAC: "c0:ff:ee:15:c0:01",
@@ -187,29 +161,21 @@ func TestUpdateBindings(t *testing.T) {
},
},
},
- {
- Name: "Refresh",
- BindingsFixture: map[string]Binding{
- "0_10.0.0.1": {
- IP: netip.AddrFrom4([4]byte{testIP1[0], testIP1[1], testIP1[2], testIP1[3]}),
- MAC: net.HardwareAddr{0xc0, 0xff, 0xee, 0x15, 0xc0, 0x01},
- Time: timestamp,
+ "refresh": {
+ in: in{
+ p: func(p *ethernet.ARPPacket) {
+ p.SendHwAddr = net.HardwareAddr{0xc0, 0xff, 0xee, 0x15, 0xc0, 0x01}
},
- },
- In: updateBindingsArgs{
- Pkt: ðernet.ARPPacket{
- HardwareType: ethernet.HardwareTypeEthernet,
- ProtocolType: ethernet.ProtocolTypeIPv4,
- HardwareAddrLen: 6,
- ProtocolAddrLen: 4,
- OpCode: ethernet.OpRequest,
- SendHwdAddr: net.HardwareAddr{0xc0, 0xff, 0xee, 0x15, 0xc0, 0x01},
- SendIPAddr: netip.AddrFrom4([4]byte{testIP1[0], testIP1[1], testIP1[2], testIP1[3]}),
- TgtIPAddr: netip.AddrFrom4([4]byte{testIP2[0], testIP2[1], testIP2[2], testIP2[3]}),
+ time: timestamp.Add(seenAgainThreshold + time.Second),
+ bindingsFixture: map[string]Binding{
+ "0_10.0.0.1": {
+ IP: netip.MustParseAddr("10.0.0.1"),
+ MAC: net.HardwareAddr{0xc0, 0xff, 0xee, 0x15, 0xc0, 0x01},
+ Time: timestamp,
+ },
},
- Time: timestamp.Add(seenAgainThreshold + time.Second),
},
- Out: []Result{
+ out: []Result{
{
IP: "10.0.0.1",
MAC: "c0:ff:ee:15:c0:01",
@@ -218,29 +184,21 @@ func TestUpdateBindings(t *testing.T) {
},
},
},
- {
- Name: "Move",
- BindingsFixture: map[string]Binding{
- "0_10.0.0.1": {
- IP: netip.AddrFrom4([4]byte{testIP1[0], testIP1[1], testIP1[2], testIP1[3]}),
- MAC: net.HardwareAddr{0xc0, 0xff, 0xee, 0x15, 0xc0, 0x01},
- Time: timestamp,
+ "move": {
+ in: in{
+ p: func(p *ethernet.ARPPacket) {
+ p.SendHwAddr = net.HardwareAddr{0xc0, 0xff, 0xee, 0x15, 0xc0, 0x1d}
},
- },
- In: updateBindingsArgs{
- Pkt: ðernet.ARPPacket{
- HardwareType: ethernet.HardwareTypeEthernet,
- ProtocolType: ethernet.ProtocolTypeIPv4,
- HardwareAddrLen: 6,
- ProtocolAddrLen: 4,
- OpCode: ethernet.OpRequest,
- SendHwdAddr: net.HardwareAddr{0xc0, 0xff, 0xee, 0x15, 0xc0, 0x1d},
- SendIPAddr: netip.AddrFrom4([4]byte{testIP1[0], testIP1[1], testIP1[2], testIP1[3]}),
- TgtIPAddr: netip.AddrFrom4([4]byte{testIP2[0], testIP2[1], testIP2[2], testIP2[3]}),
+ time: timestamp,
+ bindingsFixture: map[string]Binding{
+ "0_10.0.0.1": {
+ IP: netip.MustParseAddr("10.0.0.1"),
+ MAC: net.HardwareAddr{0xc0, 0xff, 0xee, 0x15, 0xc0, 0x01},
+ Time: timestamp,
+ },
},
- Time: timestamp,
},
- Out: []Result{
+ out: []Result{
{
IP: "10.0.0.1",
MAC: "c0:ff:ee:15:c0:1d",
@@ -251,43 +209,60 @@ func TestUpdateBindings(t *testing.T) {
},
}
- for _, tcase := range table {
- t.Run(tcase.Name, func(tt *testing.T) {
+ for name, tc := range testcases {
+ tc := tc
+
+ t.Run(name, func(t *testing.T) {
+ t.Parallel()
+ packet := testARPPacket()
+ if tc.in.p != nil {
+ tc.in.p(packet)
+ }
svc := NewService("lo")
- if tcase.BindingsFixture != nil {
- svc.bindings = tcase.BindingsFixture
+ if tc.in.bindingsFixture != nil {
+ svc.bindings = tc.in.bindingsFixture
}
- res := svc.updateBindings(tcase.In.Pkt, tcase.In.VID, tcase.In.Time)
- for i, expected := range tcase.Out {
+ res := svc.updateBindings(packet, tc.in.vid, tc.in.time)
+ for i, expected := range tc.out {
var expectedVID int
if expected.VID != nil {
expectedVID = int(*expected.VID)
}
- assert.Equalf(tt, expected.IP, res[i].IP, "expected Result at index of %d to have the IP %s", i, expected.IP)
- assert.Equalf(tt, expected.MAC, res[i].MAC, "expected Result at index of %d to have the MAC %s", i, expected.MAC)
- assert.Equalf(tt, expected.VID, res[i].VID, "expected Result at index of %d to have the VID %d", i, expectedVID)
- assert.Equalf(tt, expected.Time, res[i].Time, "expected Result at index of %d to have the Time of %d", i, int(expected.Time))
- assert.Equalf(tt, expected.Event, res[i].Event, "expected Result at index of %d to have the Event of %s", i, expected.Event)
+ assert.Equalf(t, expected.IP, res[i].IP, "expected Result at index of %d to have the IP %s", i, expected.IP)
+ assert.Equalf(t, expected.MAC, res[i].MAC, "expected Result at index of %d to have the MAC %s", i, expected.MAC)
+ assert.Equalf(t, expected.VID, res[i].VID, "expected Result at index of %d to have the VID %d", i, expectedVID)
+ assert.Equalf(t, expected.Time, res[i].Time, "expected Result at index of %d to have the Time of %d", i, int(expected.Time))
+ assert.Equalf(t, expected.Event, res[i].Event, "expected Result at index of %d to have the Event of %s", i, expected.Event)
}
})
}
}
-type handlePacketCase struct {
- Err error
- In pcap.Packet
- Name string
- Out []Result
+func testARPPacket() *ethernet.ARPPacket {
+ return ðernet.ARPPacket{
+ HardwareType: ethernet.HardwareTypeEthernet,
+ ProtocolType: ethernet.ProtocolTypeIPv4,
+ HardwareAddrLen: 6,
+ ProtocolAddrLen: 4,
+ OpCode: ethernet.OpRequest,
+ SendIPAddr: netip.MustParseAddr("10.0.0.1"),
+ TgtIPAddr: netip.MustParseAddr("10.0.0.2"),
+ }
}
func TestServiceHandlePacket(t *testing.T) {
+ t.Parallel()
+
timestamp := time.Now()
- table := []handlePacketCase{
- {
- Name: "ValidRequestPacket",
- In: pcap.Packet{
+ testcases := map[string]struct {
+ in pcap.Packet
+ out []Result
+ err error
+ }{
+ "valid request packet": {
+ in: pcap.Packet{
// generated from tcpdump
B: []byte{
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x84, 0x39, 0xc0, 0x0b, 0x22, 0x25, 0x81, 0x00, 0x00, 0x02,
@@ -299,7 +274,7 @@ func TestServiceHandlePacket(t *testing.T) {
Timestamp: timestamp,
},
},
- Out: []Result{
+ out: []Result{
{
IP: "192.168.10.26",
MAC: "84:39:c0:0b:22:25",
@@ -309,16 +284,15 @@ func TestServiceHandlePacket(t *testing.T) {
},
},
},
- {
- Name: "ValidReplyPacket",
- In: pcap.Packet{
+ "valid reply packet": {
+ in: pcap.Packet{
B: []byte{
0x24, 0x4b, 0xfe, 0xe1, 0xea, 0x26, 0x80, 0x61, 0x5f, 0x08, 0xfc, 0x16, 0x08, 0x06, 0x00, 0x01,
0x08, 0x00, 0x06, 0x04, 0x00, 0x02, 0x80, 0x61, 0x5f, 0x08, 0xfc, 0x16, 0xc0, 0xa8, 0x01, 0x6c,
0x24, 0x4b, 0xfe, 0xe1, 0xea, 0x26, 0xc0, 0xa8, 0x01, 0x50,
},
},
- Out: []Result{
+ out: []Result{
{
IP: "192.168.1.108",
MAC: "80:61:5f:08:fc:16",
@@ -335,13 +309,11 @@ func TestServiceHandlePacket(t *testing.T) {
},
},
},
- {
- Name: "EmptyPacket",
- Err: ErrEmptyPacket,
+ "empty packet": {
+ err: ErrEmptyPacket,
},
- {
- Name: "MalformedPacket",
- In: pcap.Packet{
+ "malformed packet": {
+ in: pcap.Packet{
B: []byte{
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x84, 0x39, 0xc0, 0x0b, 0x22,
0x08, 0x06, 0x00, 0x01, 0x08, 0x06, 0x04, 0x00, 0x01, 0x84,
@@ -349,37 +321,37 @@ func TestServiceHandlePacket(t *testing.T) {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
},
- // should return nil, nil
},
- {
- Name: "ShortPacket",
- In: pcap.Packet{
+ "short packet": {
+ in: pcap.Packet{
B: []byte{
0x24, 0x4b, 0xfe, 0xe1, 0xea, 0x26, 0x80, 0x61, 0x5f, 0x08, 0xfc, 0x16, 0x08, 0x06, 0x00, 0x01,
0x08, 0x00, 0x06, 0x04, 0x00, 0x02, 0x80, 0xfc, 0x16, 0xc0, 0xa8, 0x01, 0x6c,
0x24, 0x4b, 0xfe, 0xe1, 0xea, 0x26, 0xc0, 0xa8, 0x01, 0x50,
},
},
- Err: ethernet.ErrMalformedARPPacket,
+ err: ethernet.ErrMalformedARPPacket,
},
}
- svc := NewService("")
+ for name, tc := range testcases {
+ tc := tc
- for _, tcase := range table {
- t.Run(tcase.Name, func(tt *testing.T) {
- res, err := svc.handlePacket(tcase.In)
- assert.ErrorIsf(tt, err, tcase.Err, "expected handlePacket to return an error of: %s", tcase.Err)
+ t.Run(name, func(t *testing.T) {
+ t.Parallel()
+ svc := NewService("")
+ res, err := svc.handlePacket(tc.in)
+ assert.ErrorIsf(t, err, tc.err, "expected handlePacket to return an error of: %s", tc.err)
- if tcase.Out != nil {
- for i, expected := range tcase.Out {
- assert.Equalf(tt, expected.IP, res[i].IP, "expected result at index %d to have an IP address of %s", i, expected.IP)
- assert.Equalf(tt, expected.MAC, res[i].MAC, "expected result at index %d to have a MAC address of %s", i, expected.MAC)
- assert.Equalf(tt, expected.VID, res[i].VID, "expected result at index %d to have a VID of %v", i, expected.VID)
- assert.Equalf(tt, expected.Time, res[i].Time, "expected result at index %d to have a Time of %s", i, expected.Time)
+ if err == nil {
+ for i, expected := range tc.out {
+ assert.Equalf(t, expected.IP, res[i].IP, "expected result at index %d to have an IP address of %s", i, expected.IP)
+ assert.Equalf(t, expected.MAC, res[i].MAC, "expected result at index %d to have a MAC address of %s", i, expected.MAC)
+ assert.Equalf(t, expected.VID, res[i].VID, "expected result at index %d to have a VID of %v", i, expected.VID)
+ assert.Equalf(t, expected.Time, res[i].Time, "expected result at index %d to have a Time of %s", i, expected.Time)
}
} else {
- assert.Nil(tt, res)
+ assert.Nil(t, res)
}
})
}
diff --git a/src/maasagent/tools.go b/src/maasagent/tools.go
new file mode 100644
index 0000000..10ac085
--- /dev/null
+++ b/src/maasagent/tools.go
@@ -0,0 +1,7 @@
+//go:build tools
+
+package main
+
+import (
+ _ "golang.org/x/tools/cmd/stringer"
+)
Follow ups