api/t/network: represent MAC addrs as byte slices

Make invalid states unrepresentable by moving away from stringly-typed
MAC address values in API structs. As go.dev/issue/29678 has not yet
been implemented, provide our own HardwareAddr byte-slice type which
implements TextMarshaler and TextUnmarshaler to retain compatibility
with the API wire format.

When stdlib's net.HardwareAddr type implements TextMarshaler and
TextUnmarshaler and GODEBUG=netmarshal becomes the default, we should be
able to make the type a straight alias for stdlib net.HardwareAddr as a
non-breaking change.

Signed-off-by: Cory Snider <csnider@mirantis.com>
This commit is contained in:
Cory Snider
2025-10-30 15:57:47 -04:00
parent 72f6cec125
commit 19f4c27d81
21 changed files with 235 additions and 75 deletions

View File

@@ -1816,7 +1816,7 @@ func TestAdvertiseAddresses(t *testing.T) {
// The original defer will stop ctr2Id.
ctr2NewMAC := container.Inspect(ctx, t, c, ctr2Id).NetworkSettings.Networks[netName].MacAddress
assert.Check(t, ctr2OrigMAC != ctr2NewMAC, "expected restarted ctr2 to have a different MAC address")
assert.Check(t, !slices.Equal(ctr2OrigMAC, ctr2NewMAC), "expected restarted ctr2 to have a different MAC address")
ctr1Neighs = container.ExecT(ctx, t, c, ctr1Id, []string{"ip", "neigh", "show"})
assert.Assert(t, is.Equal(ctr1Neighs.ExitCode, 0))
@@ -1843,9 +1843,6 @@ func TestAdvertiseAddresses(t *testing.T) {
// Check ARP/NA messages received for ctr2's new address (all unsolicited).
ctr2NewHwAddr, err := net.ParseMAC(ctr2NewMAC)
assert.NilError(t, err)
checkPkts := func(pktDesc string, pkts []network.TimestampedPkt, matchIP netip.Addr, unpack func(pkt network.TimestampedPkt) (sh net.HardwareAddr, sp netip.Addr, err error)) {
t.Helper()
var count int
@@ -1860,7 +1857,7 @@ func TestAdvertiseAddresses(t *testing.T) {
continue
}
t.Logf("%s %d: %s '%s' is at '%s'", pktDesc, i+1, p.ReceivedAt.Format("15:04:05.000"), pa, ha)
if pa != matchIP || slices.Compare(ha, ctr2NewHwAddr) != 0 {
if pa != matchIP || slices.Compare(ha, net.HardwareAddr(ctr2NewMAC)) != 0 {
continue
}
count++

View File

@@ -5,6 +5,7 @@ import (
"encoding/json"
"net/http"
"net/netip"
"slices"
"testing"
containertypes "github.com/moby/moby/api/types/container"
@@ -82,7 +83,7 @@ func TestMACAddrOnRestart(t *testing.T) {
ctr2Inspect := container.Inspect(ctx, t, c, ctr2Name)
ctr2MAC := ctr2Inspect.NetworkSettings.Networks[netName].MacAddress
assert.Check(t, ctr1MAC != ctr2MAC,
assert.Check(t, !slices.Equal(ctr1MAC, ctr2MAC),
"expected containers to have different MAC addresses; got %q for both", ctr1MAC)
}
@@ -120,7 +121,7 @@ func TestCfgdMACAddrOnRestart(t *testing.T) {
inspect := container.Inspect(ctx, t, c, ctr1Name)
gotMAC := inspect.NetworkSettings.Networks[netName].MacAddress
assert.Check(t, is.Equal(wantMAC, gotMAC))
assert.Check(t, is.Equal(wantMAC, gotMAC.String()))
startAndCheck := func() {
t.Helper()
@@ -128,7 +129,7 @@ func TestCfgdMACAddrOnRestart(t *testing.T) {
assert.Assert(t, is.Nil(err))
inspect = container.Inspect(ctx, t, c, ctr1Name)
gotMAC = inspect.NetworkSettings.Networks[netName].MacAddress
assert.Check(t, is.Equal(wantMAC, gotMAC))
assert.Check(t, is.Equal(wantMAC, gotMAC.String()))
}
// Restart the container, check that the MAC address is restored.
@@ -301,7 +302,7 @@ func TestWatchtowerCreate(t *testing.T) {
inspect := container.Inspect(ctx, t, c, ctrName)
netSettings := inspect.NetworkSettings.Networks[netName]
assert.Check(t, is.Equal(netSettings.IPAddress, netip.MustParseAddr(ctrIP)))
assert.Check(t, is.Equal(netSettings.MacAddress, ctrMAC))
assert.Check(t, is.Equal(netSettings.MacAddress.String(), ctrMAC))
}
type legacyCreateRequest struct {