azure-container-networking/ipam/manager_test.go

390 строки
10 KiB
Go

// Copyright 2017 Microsoft. All rights reserved.
// MIT License
package ipam
import (
"errors"
"fmt"
"net"
"testing"
"time"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/Azure/azure-container-networking/common"
"github.com/Azure/azure-container-networking/platform"
"github.com/Azure/azure-container-networking/store"
"github.com/Azure/azure-container-networking/testutils"
)
var (
anyInterface = "any"
anyPriority = 42
// Pools and addresses used by tests.
subnet1 = net.IPNet{IP: net.IPv4(10, 0, 1, 0), Mask: net.IPv4Mask(255, 255, 255, 0)}
addr11 = net.IPv4(10, 0, 1, 1)
addr12 = net.IPv4(10, 0, 1, 2)
addr13 = net.IPv4(10, 0, 1, 3)
subnet2 = net.IPNet{IP: net.IPv4(10, 0, 2, 0), Mask: net.IPv4Mask(255, 255, 255, 0)}
addr21 = net.IPv4(10, 0, 2, 1)
addr22 = net.IPv4(10, 0, 2, 2)
addr23 = net.IPv4(10, 0, 2, 3)
subnet3 = net.IPNet{IP: net.IPv4(10, 0, 3, 0), Mask: net.IPv4Mask(255, 255, 255, 0)}
addr31 = net.IPv4(10, 0, 3, 1)
addr32 = net.IPv4(10, 0, 3, 2)
addr33 = net.IPv4(10, 0, 3, 3)
)
// createAddressManager creates an address manager with a simple test configuration.
func createAddressManager(options map[string]interface{}) (AddressManager, error) {
var config common.PluginConfig
am, err := NewAddressManager()
if err != nil {
return nil, err
}
if err := am.Initialize(&config, false, options); err != nil {
return nil, err
}
if err := setupTestAddressSpace(am); err != nil {
return nil, err
}
return am, nil
}
// dumpAddressManager dumps the contents of an address manager.
func dumpAddressManager(am AddressManager) {
amImpl := am.(*addressManager)
fmt.Printf("AddressManager:%+v\n", amImpl)
for sk, sv := range amImpl.AddrSpaces {
fmt.Printf("AddressSpace %v:%+v\n", sk, sv)
for pk, pv := range sv.Pools {
fmt.Printf("\tPool %v:%+v\n", pk, pv)
for ak, av := range pv.Addresses {
fmt.Printf("\t\tAddress %v:%+v\n", ak, av)
}
}
}
}
// setupTestAddressSpace creates a simple address space used by various tests.
func setupTestAddressSpace(am AddressManager) error {
anyInterface := "any"
anyPriority := 42
amImpl := am.(*addressManager)
// Configure an empty global address space.
globalAs, err := amImpl.newAddressSpace(GlobalDefaultAddressSpaceId, GlobalScope)
if err != nil {
return err
}
if err := amImpl.setAddressSpace(globalAs); err != nil {
return err
}
// Configure a local address space.
localAs, err := amImpl.newAddressSpace(LocalDefaultAddressSpaceId, LocalScope)
if err != nil {
return err
}
// Add subnet1 with addresses addr11 and addr12.
ap, err := localAs.newAddressPool(anyInterface, anyPriority, &subnet1)
ap.newAddressRecord(&addr11)
ap.newAddressRecord(&addr12)
ap.newAddressRecord(&addr13)
ap.newAddressRecord(&addr22)
ap.newAddressRecord(&addr32)
// Add subnet2 with addr21.
ap, err = localAs.newAddressPool(anyInterface, anyPriority, &subnet2)
ap.newAddressRecord(&addr21)
amImpl.setAddressSpace(localAs)
return nil
}
// cleanupTestAddressSpace deletes any existing address spaces.
func cleanupTestAddressSpace(am AddressManager) error {
amImpl := am.(*addressManager)
// Configure an empty local address space.
localAs, err := amImpl.newAddressSpace(LocalDefaultAddressSpaceId, LocalScope)
if err != nil {
return err
}
if err := amImpl.setAddressSpace(localAs); err != nil {
return err
}
// Configure an empty global address space.
globalAs, err := amImpl.newAddressSpace(GlobalDefaultAddressSpaceId, GlobalScope)
if err != nil {
return err
}
if err := amImpl.setAddressSpace(globalAs); err != nil {
return err
}
return nil
}
//
// Address manager tests.
//
func TestManager(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Manager Suite")
}
var _ = Describe("Test Manager", func() {
Describe("Test Initialize", func() {
Context("When store is nil", func() {
It("Initialize return nil", func() {
var config common.PluginConfig
config.Store = nil
options := map[string]interface{}{}
options[common.OptEnvironment] = ""
am, err := NewAddressManager()
Expect(am).NotTo(BeNil())
Expect(err).NotTo(HaveOccurred())
err = am.Initialize(&config, false, options)
Expect(err).To(BeNil())
})
})
Context("When restore key not found", func() {
It("Initialize return nil", func() {
var config common.PluginConfig
storeMock := &testutils.KeyValueStoreMock{}
storeMock.ReadError = store.ErrKeyNotFound
config.Store = storeMock
options := map[string]interface{}{}
options[common.OptEnvironment] = ""
am, err := NewAddressManager()
Expect(am).NotTo(BeNil())
Expect(err).NotTo(HaveOccurred())
err = am.Initialize(&config, false, options)
Expect(err).To(BeNil())
})
})
Context("When restore return error", func() {
It("Initialize return error", func() {
var config common.PluginConfig
storeMock := &testutils.KeyValueStoreMock{}
storeMock.ReadError = errors.New("Error")
config.Store = storeMock
options := map[string]interface{}{}
options[common.OptEnvironment] = ""
am, err := NewAddressManager()
Expect(am).NotTo(BeNil())
Expect(err).NotTo(HaveOccurred())
err = am.Initialize(&config, false, options)
Expect(err).To(HaveOccurred())
})
})
Context("When StartSource fail", func() {
It("Initialize return error", func() {
var config common.PluginConfig
options := map[string]interface{}{}
options[common.OptEnvironment] = "Invalid"
am, err := NewAddressManager()
Expect(am).NotTo(BeNil())
Expect(err).NotTo(HaveOccurred())
err = am.Initialize(&config, false, options)
Expect(err).To(HaveOccurred())
})
})
})
Describe("Test restore", func() {
Context("When store is nil", func() {
It("restore return nil", func() {
am := &addressManager{
AddrSpaces: make(map[string]*addressSpace),
}
err := am.restore(false)
Expect(err).To(BeNil())
})
})
Context("Test Populate pointers", func() {
It("Should build addrsByID successfully", func() {
am := &addressManager{
AddrSpaces: make(map[string]*addressSpace),
}
timeReboot, _ := platform.GetLastRebootTime()
am.store = &testutils.KeyValueStoreMock{
ModificationTime: timeReboot.Add(time.Hour),
}
ap := &addressPool{
Id: "ap-test",
RefCount: 1,
Addresses: make(map[string]*addressRecord),
}
ap.Addresses["ar-test"] = &addressRecord{
ID: "ar-test",
InUse: true,
}
as := &addressSpace{
Id: "as-test",
Pools: make(map[string]*addressPool),
}
as.Pools["ap-test"] = ap
am.AddrSpaces["as-test"] = as
err := am.restore(false)
Expect(err).To(BeNil())
as = am.AddrSpaces["as-test"]
ap = as.Pools["ap-test"]
ar := ap.addrsByID["ar-test"]
Expect(ar.ID).To(Equal("ar-test"))
Expect(ap.RefCount).To(Equal(1))
Expect(ar.InUse).To(BeTrue())
})
})
Context("When GetModificationTime return error", func() {
It("Should not clear the RefCount and InUse", func() {
am := &addressManager{
AddrSpaces: make(map[string]*addressSpace),
}
am.store = &testutils.KeyValueStoreMock{
GetModificationTimeError: errors.New("Error"),
}
ap := &addressPool{
Id: "ap-test",
RefCount: 1,
Addresses: make(map[string]*addressRecord),
}
ap.Addresses["ar-test"] = &addressRecord{
ID: "ar-test",
InUse: true,
}
as := &addressSpace{
Id: "as-test",
Pools: make(map[string]*addressPool),
}
as.Pools["ap-test"] = ap
am.AddrSpaces["as-test"] = as
err := am.restore(false)
Expect(err).To(BeNil())
as = am.AddrSpaces["as-test"]
ap = as.Pools["ap-test"]
ar := ap.addrsByID["ar-test"]
Expect(ar.ID).To(Equal("ar-test"))
Expect(ap.RefCount).To(Equal(1))
Expect(ar.InUse).To(BeTrue())
})
})
})
Describe("Test save", func() {
Context("When store is nill", func() {
It("Should return nil", func() {
am := &addressManager{}
err := am.save()
Expect(err).NotTo(HaveOccurred())
})
})
})
Describe("Test StartSource", func() {
Context("When environment is azure", func() {
It("Should return azure source", func() {
am := &addressManager{}
options := map[string]interface{}{}
options[common.OptEnvironment] = common.OptEnvironmentAzure
err := am.StartSource(options)
Expect(err).NotTo(HaveOccurred())
Expect(am.source).NotTo(BeNil())
})
})
Context("When environment is mas", func() {
It("Should return mas", func() {
am := &addressManager{}
options := map[string]interface{}{}
options[common.OptEnvironment] = common.OptEnvironmentMAS
err := am.StartSource(options)
Expect(err).NotTo(HaveOccurred())
Expect(am.source).NotTo(BeNil())
})
})
Context("When environment is null", func() {
It("Should return null source", func() {
am := &addressManager{}
options := map[string]interface{}{}
options[common.OptEnvironment] = "null"
err := am.StartSource(options)
Expect(err).NotTo(HaveOccurred())
Expect(am.source).NotTo(BeNil())
})
})
Context("When environment is nil", func() {
It("Should return nil", func() {
am := &addressManager{}
options := map[string]interface{}{}
options[common.OptEnvironment] = ""
err := am.StartSource(options)
Expect(err).NotTo(HaveOccurred())
Expect(am.source).To(BeNil())
})
})
Context("When environment is nil", func() {
It("Should return nil", func() {
am := &addressManager{}
options := map[string]interface{}{}
options[common.OptEnvironment] = "Invalid"
err := am.StartSource(options)
Expect(err).To(HaveOccurred())
Expect(am.source).To(BeNil())
})
})
})
Describe("Test GetDefaultAddressSpaces", func() {
Context("When local and global are nil", func() {
It("Should return empty string", func() {
am := &addressManager{
AddrSpaces: make(map[string]*addressSpace),
}
localId, globalId := am.GetDefaultAddressSpaces()
Expect(localId).To(BeEmpty())
Expect(globalId).To(BeEmpty())
})
})
Context("When local and global are nil", func() {
It("Should return empty string", func() {
am := &addressManager{
AddrSpaces: make(map[string]*addressSpace),
}
am.AddrSpaces[LocalDefaultAddressSpaceId] = &addressSpace{Id: "localId"}
am.AddrSpaces[GlobalDefaultAddressSpaceId] = &addressSpace{Id: "globalId"}
localId, globalId := am.GetDefaultAddressSpaces()
Expect(localId).To(Equal("localId"))
Expect(globalId).To(Equal("globalId"))
})
})
})
})