package netutils
import (
"fmt"
"net"
"testing"
)
func TestAllocateSubnet(t *testing.T) {
sna, err := NewSubnetAllocator("10.1.0.0/16", 8, nil)
if err != nil {
t.Fatal("Failed to initialize subnet allocator: ", err)
}
sn, err := sna.GetNetwork()
if err != nil {
t.Fatal("Failed to get network: ", err)
}
if sn.String() != "10.1.0.0/24" {
t.Fatalf("Did not get expected subnet (n=%d, sn=%s)", 0, sn.String())
}
sn, err = sna.GetNetwork()
if err != nil {
t.Fatal("Failed to get network: ", err)
}
if sn.String() != "10.1.1.0/24" {
t.Fatalf("Did not get expected subnet (n=%d, sn=%s)", 1, sn.String())
}
sn, err = sna.GetNetwork()
if err != nil {
t.Fatal("Failed to get network: ", err)
}
if sn.String() != "10.1.2.0/24" {
t.Fatalf("Did not get expected subnet (n=%d, sn=%s)", 2, sn.String())
}
}
// 10.1.SSSSSSHH.HHHHHHHH
func TestAllocateSubnetLargeHostBits(t *testing.T) {
sna, err := NewSubnetAllocator("10.1.0.0/16", 10, nil)
if err != nil {
t.Fatal("Failed to initialize subnet allocator: ", err)
}
sn, err := sna.GetNetwork()
if err != nil {
t.Fatal("Failed to get network: ", err)
}
if sn.String() != "10.1.0.0/22" {
t.Fatalf("Did not get expected subnet (n=%d, sn=%s)", 0, sn.String())
}
sn, err = sna.GetNetwork()
if err != nil {
t.Fatal("Failed to get network: ", err)
}
if sn.String() != "10.1.4.0/22" {
t.Fatalf("Did not get expected subnet (n=%d, sn=%s)", 1, sn.String())
}
sn, err = sna.GetNetwork()
if err != nil {
t.Fatal("Failed to get network: ", err)
}
if sn.String() != "10.1.8.0/22" {
t.Fatalf("Did not get expected subnet (n=%d, sn=%s)", 2, sn.String())
}
sn, err = sna.GetNetwork()
if err != nil {
t.Fatal("Failed to get network: ", err)
}
if sn.String() != "10.1.12.0/22" {
t.Fatalf("Did not get expected subnet (n=%d, sn=%s)", 3, sn.String())
}
}
// 10.1.SSSSSSSS.SSHHHHHH
func TestAllocateSubnetLargeSubnetBits(t *testing.T) {
sna, err := NewSubnetAllocator("10.1.0.0/16", 6, nil)
if err != nil {
t.Fatal("Failed to initialize subnet allocator: ", err)
}
for n := 0; n < 256; n++ {
sn, err := sna.GetNetwork()
if err != nil {
t.Fatal("Failed to get network: ", err)
}
if sn.String() != fmt.Sprintf("10.1.%d.0/26", n) {
t.Fatalf("Did not get expected subnet (n=%d, sn=%s)", n, sn.String())
}
}
for n := 0; n < 256; n++ {
sn, err := sna.GetNetwork()
if err != nil {
t.Fatal("Failed to get network: ", err)
}
if sn.String() != fmt.Sprintf("10.1.%d.64/26", n) {
t.Fatalf("Did not get expected subnet (n=%d, sn=%s)", n+256, sn.String())
}
}
sn, err := sna.GetNetwork()
if err != nil {
t.Fatal("Failed to get network: ", err)
}
if sn.String() != "10.1.0.128/26" {
t.Fatalf("Did not get expected subnet (n=%d, sn=%s)", 512, sn.String())
}
}
// 10.000000SS.SSSSSSHH.HHHHHHHH
func TestAllocateSubnetOverlapping(t *testing.T) {
sna, err := NewSubnetAllocator("10.0.0.0/14", 10, nil)
if err != nil {
t.Fatal("Failed to initialize subnet allocator: ", err)
}
for n := 0; n < 4; n++ {
sn, err := sna.GetNetwork()
if err != nil {
t.Fatal("Failed to get network: ", err)
}
if sn.String() != fmt.Sprintf("10.%d.0.0/22", n) {
t.Fatalf("Did not get expected subnet (n=%d, sn=%s)", n, sn.String())
}
}
for n := 0; n < 4; n++ {
sn, err := sna.GetNetwork()
if err != nil {
t.Fatal("Failed to get network: ", err)
}
if sn.String() != fmt.Sprintf("10.%d.4.0/22", n) {
t.Fatalf("Did not get expected subnet (n=%d, sn=%s)", n+4, sn.String())
}
}
sn, err := sna.GetNetwork()
if err != nil {
t.Fatal("Failed to get network: ", err)
}
if sn.String() != "10.0.8.0/22" {
t.Fatalf("Did not get expected subnet (n=%d, sn=%s)", 8, sn.String())
}
}
// 10.1.HHHHHHHH.HHHHHHHH
func TestAllocateSubnetNoSubnetBits(t *testing.T) {
sna, err := NewSubnetAllocator("10.1.0.0/16", 16, nil)
if err != nil {
t.Fatal("Failed to initialize subnet allocator: ", err)
}
sn, err := sna.GetNetwork()
if err != nil {
t.Fatal("Failed to get network: ", err)
}
if sn.String() != "10.1.0.0/16" {
t.Fatalf("Did not get expected subnet (sn=%s)", sn.String())
}
sn, err = sna.GetNetwork()
if err == nil {
t.Fatalf("Unexpectedly succeeded in getting network (sn=%s)", sn.String())
}
}
func TestAllocateSubnetInvalidHostBitsOrCIDR(t *testing.T) {
_, err := NewSubnetAllocator("10.1.0.0/16", 18, nil)
if err == nil {
t.Fatal("Unexpectedly succeeded in initializing subnet allocator")
}
_, err = NewSubnetAllocator("10.1.0.0/16", 0, nil)
if err == nil {
t.Fatal("Unexpectedly succeeded in initializing subnet allocator")
}
_, err = NewSubnetAllocator("10.1.0.0/33", 16, nil)
if err == nil {
t.Fatal("Unexpectedly succeeded in initializing subnet allocator")
}
}
func TestAllocateSubnetInUse(t *testing.T) {
inUse := []string{"10.1.0.0/24", "10.1.2.0/24", "10.2.2.2/24", "Invalid"}
sna, err := NewSubnetAllocator("10.1.0.0/16", 8, inUse)
if err != nil {
t.Fatal("Failed to initialize IP allocator: ", err)
}
sn, err := sna.GetNetwork()
if err != nil {
t.Fatal("Failed to get network: ", err)
}
if sn.String() != "10.1.1.0/24" {
t.Fatalf("Did not get expected subnet (sn=%s)", sn.String())
}
sn, err = sna.GetNetwork()
if err != nil {
t.Fatal("Failed to get network: ", err)
}
if sn.String() != "10.1.3.0/24" {
t.Fatalf("Did not get expected subnet (sn=%s)", sn.String())
}
}
func TestAllocateReleaseSubnet(t *testing.T) {
sna, err := NewSubnetAllocator("10.1.0.0/16", 14, nil)
if err != nil {
t.Fatal("Failed to initialize IP allocator: ", err)
}
var releaseSn *net.IPNet
for i := 0; i < 4; i++ {
sn, err := sna.GetNetwork()
if err != nil {
t.Fatal("Failed to get network: ", err)
}
if sn.String() != fmt.Sprintf("10.1.%d.0/18", i*64) {
t.Fatalf("Did not get expected subnet (i=%d, sn=%s)", i, sn.String())
}
if i == 2 {
releaseSn = sn
}
}
sn, err := sna.GetNetwork()
if err == nil {
t.Fatalf("Unexpectedly succeeded in getting network (sn=%s)", sn.String())
}
if err := sna.ReleaseNetwork(releaseSn); err != nil {
t.Fatalf("Failed to release the subnet (releaseSn=%s): %v", releaseSn.String(), err)
}
sn, err = sna.GetNetwork()
if err != nil {
t.Fatal("Failed to get network: ", err)
}
if sn.String() != releaseSn.String() {
t.Fatalf("Did not get expected subnet (sn=%s)", sn.String())
}
sn, err = sna.GetNetwork()
if err == nil {
t.Fatalf("Unexpectedly succeeded in getting network (sn=%s)", sn.String())
}
}