package addrset import ( "encoding/binary" "fmt" "math/big" "net/netip" "testing" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" ) func TestIPv4Pool(t *testing.T) { var ( // It shouldn't matter that host bits are set in the pool Prefix. subnet = netip.MustParsePrefix("10.20.30.40/16") as = New(subnet) addr netip.Addr err error ) assert.Check(t, is.Len(as.bitmaps, 0)) assert.Check(t, uint128Equal(as.Len())(0, 0)) // Add the first and last addresses in the range. // Expect a single bitmap of 65536 bits, with two bits set. err = as.Add(netip.MustParseAddr("10.20.0.0")) assert.Assert(t, err) err = as.Add(netip.MustParseAddr("10.20.255.255")) assert.Assert(t, err) assert.Check(t, is.Len(as.bitmaps, 1)) bm := as.bitmaps[subnet.Masked()] assert.Check(t, is.Equal(bm.Bits(), uint64(65536))) assert.Check(t, is.Equal(bm.Unselected(), uint64(65534))) assert.Check(t, uint128Equal(as.Len())(0, 2)) assert.Check(t, uint128Equal(as.AddrsInPrefix(netip.MustParsePrefix("0.0.0.0/1")))(0, 2)) assert.Check(t, uint128Equal(as.AddrsInPrefix(netip.MustParsePrefix("128.0.0.0/1")))(0, 0)) assert.Check(t, uint128Equal(as.AddrsInPrefix(netip.MustParsePrefix("10.0.0.0/8")))(0, 2)) assert.Check(t, uint128Equal(as.AddrsInPrefix(subnet))(0, 2)) assert.Check(t, uint128Equal(as.AddrsInPrefix(netip.MustParsePrefix("10.20.0.0/24")))(0, 1)) assert.Check(t, uint128Equal(as.AddrsInPrefix(netip.MustParsePrefix("10.20.1.0/24")))(0, 0)) assert.Check(t, uint128Equal(as.AddrsInPrefix(netip.MustParsePrefix("10.20.255.0/24")))(0, 1)) assert.Check(t, uint128Equal(as.AddrsInPrefix(netip.MustParsePrefix("10.21.0.0/24")))(0, 0)) // Add an address that's already present. Expect an error. err = as.Add(netip.MustParseAddr("10.20.255.255")) assert.Check(t, is.ErrorIs(err, ErrAllocated)) // Remove an address that isn't in the set. Expect no error. err = as.Remove(netip.MustParseAddr("10.20.30.40")) assert.Check(t, err) assert.Check(t, uint128Equal(as.Len())(0, 2)) // Remove all addresses, expect to end up with no bitmap. err = as.Remove(netip.MustParseAddr("10.20.0.0")) assert.Check(t, err) err = as.Remove(netip.MustParseAddr("10.20.255.255")) assert.Check(t, err) assert.Check(t, is.Len(as.bitmaps, 0)) assert.Check(t, uint128Equal(as.Len())(0, 0)) // Remove an address that isn't in the set (now there's no bitmap). Expect no error. err = as.Remove(netip.MustParseAddr("10.20.30.40")) assert.Check(t, err) // Add any two addresses to the set, with serial=true. Expect the first two addresses. addr, err = as.AddAny(true) assert.Check(t, err) assert.Check(t, is.Equal(addr, netip.MustParseAddr("10.20.0.0"))) addr, err = as.AddAny(true) assert.Check(t, err) assert.Check(t, is.Equal(addr, netip.MustParseAddr("10.20.0.1"))) assert.Check(t, uint128Equal(as.Len())(0, 2)) assert.Check(t, uint128Equal(as.AddrsInPrefix(subnet))(0, 2)) assert.Check(t, uint128Equal(as.AddrsInPrefix(netip.MustParsePrefix("10.20.0.0/24")))(0, 2)) assert.Check(t, uint128Equal(as.AddrsInPrefix(netip.MustParsePrefix("10.20.1.0/24")))(0, 0)) // Add any address in a range. It shouldn't matter that host bits are set in the // range. Expect the first address in that range. addr, err = as.AddAnyInRange(netip.MustParsePrefix("10.20.30.40/24"), true) assert.Check(t, err) assert.Check(t, is.Equal(addr, netip.MustParseAddr("10.20.30.0"))) assert.Check(t, uint128Equal(as.Len())(0, 3)) assert.Check(t, uint128Equal(as.AddrsInPrefix(subnet))(0, 3)) assert.Check(t, uint128Equal(as.AddrsInPrefix(netip.MustParsePrefix("10.20.0.0/24")))(0, 2)) assert.Check(t, uint128Equal(as.AddrsInPrefix(netip.MustParsePrefix("10.20.1.0/24")))(0, 0)) assert.Check(t, uint128Equal(as.AddrsInPrefix(netip.MustParsePrefix("10.20.30.0/24")))(0, 1)) } func TestIPv6Pool(t *testing.T) { var ( subnet = netip.MustParsePrefix("fddd::dddd/56") as = New(subnet) addr netip.Addr err error ) assert.Check(t, is.Len(as.bitmaps, 0)) // Add the first and last addresses in the range. // Expect two bitmaps of 1<