sub/ipalloc/ipalloc_test.go

178 lines
3.5 KiB
Go

package ipalloc
import (
"log"
"net/netip"
"testing"
)
func TestSplitPrefix(t *testing.T) {
tests := []struct{ in, lo, hi string }{
{"0.0.0.0/0", "0.0.0.0/1", "128.0.0.0/1"},
{"0.0.0.0/29", "0.0.0.0/30", "0.0.0.4/30"},
{"0.0.0.0/31", "0.0.0.0/32", "0.0.0.1/32"},
{"0.0.0.1/0", "0.0.0.0/1", "128.0.0.0/1"},
}
for _, test := range tests {
lo, hi := splitPrefix(netip.MustParsePrefix(test.in))
if lo != netip.MustParsePrefix(test.lo) || hi != netip.MustParsePrefix(test.hi) {
t.Fatal(test.in, lo, hi)
}
}
}
func TestTreeAlloc(t *testing.T) {
tests := []struct {
bits int
best string
}{
{32, "0.0.0.0/32"},
{32, "0.0.0.1/32"},
{1, "128.0.0.0/1"},
{2, "64.0.0.0/2"},
{31, "0.0.0.2/31"},
{32, "0.0.0.4/32"},
}
root := &tree{prefix: netip.MustParsePrefix("0.0.0.0/0")}
for _, test := range tests {
best := root.Alloc(test.bits)
if best == nil {
t.Fatal(root, test.bits)
}
if best.prefix != netip.MustParsePrefix(test.best) {
t.Fatal(root, test.bits, best.prefix.String())
}
}
}
func TestTreeDealloc(t *testing.T) {
tests := []struct {
bits int
best string
}{
{32, "0.0.0.0/32"},
{32, "0.0.0.1/32"},
{1, "128.0.0.0/1"},
{2, "64.0.0.0/2"},
{31, "0.0.0.2/31"},
{32, "0.0.0.4/32"},
}
root := &tree{prefix: netip.MustParsePrefix("0.0.0.0/0")}
for _, test := range tests {
best := root.Alloc(test.bits)
if best == nil {
t.Fatal(root, test.bits)
}
if best.prefix != netip.MustParsePrefix(test.best) {
t.Fatal(root, test.bits, best.prefix.String())
}
}
deallocs := []string{
"0.0.0.0/32",
"0.0.0.1/32",
"128.0.0.0/1",
"64.0.0.0/2",
"0.0.0.2/31",
"0.0.0.4/32",
}
for _, test := range deallocs {
if err := root.Dealloc(netip.MustParsePrefix(test)); err != nil {
t.Fatal(test, err)
}
}
if !root.Leaf() {
root.Walk(func(t *tree) bool {
log.Println(t.prefix, t.Leaf())
return true
})
t.Fatalf("root not empty: %#v", root)
}
first := root.Alloc(2).prefix
root.Alloc(2)
root.Dealloc(first)
if first != root.Alloc(2).prefix {
root.Walk(func(t *tree) bool {
log.Println(t.prefix, t.Leaf())
return true
})
t.Fatal(first)
}
}
func TestFindBest(t *testing.T) {
tests := []struct {
bits int
best string
}{
{32, "0.0.0.0/32"},
{32, "0.0.0.1/32"},
{1, "128.0.0.0/1"},
{2, "64.0.0.0/2"},
{31, "0.0.0.2/31"},
{32, "0.0.0.4/32"},
}
root := &tree{prefix: netip.MustParsePrefix("0.0.0.0/0")}
for _, test := range tests {
best := root.Alloc(test.bits)
if best == nil {
t.Fatal(root, test.bits)
}
if best.prefix != netip.MustParsePrefix(test.best) {
t.Fatal(root, test.bits, best.prefix.String())
}
}
best := [][2]string{
{"128.0.0.0/32", "128.0.0.0/1"},
{"128.0.0.1/32", "128.0.0.0/1"},
}
for _, test := range best {
best := root.FindBest(netip.MustParsePrefix(test[0]))
want := netip.MustParsePrefix(test[1])
if best.prefix != want {
t.Fatal(best, want)
}
}
}
func TestInsert(t *testing.T) {
tests := []string{
"0.0.0.1/32",
"0.0.0.0/32",
"128.0.0.0/1",
"64.0.0.0/2",
"0.0.0.4/32",
"0.0.0.2/31",
}
root := &tree{prefix: netip.MustParsePrefix("0.0.0.0/0")}
for _, test := range tests {
p := netip.MustParsePrefix(test)
insert := root.Insert(p)
if insert == nil {
t.Fatal(root, test)
}
match := root.Find(p)
if match.prefix != p {
t.Fatal("unable to find", p, "in", root)
}
}
for _, test := range tests {
p := netip.MustParsePrefix(test)
insert := root.Insert(p)
if insert != nil {
t.Fatal(root, test)
}
}
}