mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
IPAM and Bitseq test cases
This commit contains test cases to verify the changes and to solidify the library. Signed-off-by: Abhinandan Prativadi <abhi@docker.com>
This commit is contained in:
parent
fe629b6eba
commit
a0085a47fd
2 changed files with 149 additions and 34 deletions
|
@ -192,6 +192,11 @@ func TestGetFirstAvailable(t *testing.T) {
|
|||
{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 7, 7, 0},
|
||||
|
||||
{&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0x0, count: 6}}, 8, 0, 0},
|
||||
{&sequence{block: 0xfffcffff, count: 1, next: &sequence{block: 0x0, count: 6}}, 4, 0, 16},
|
||||
{&sequence{block: 0xfffcffff, count: 1, next: &sequence{block: 0x0, count: 6}}, 1, 7, 15},
|
||||
{&sequence{block: 0xfffcffff, count: 1, next: &sequence{block: 0x0, count: 6}}, 1, 6, 10},
|
||||
{&sequence{block: 0xfffcfffe, count: 1, next: &sequence{block: 0x0, count: 6}}, 3, 7, 31},
|
||||
{&sequence{block: 0xfffcffff, count: 1, next: &sequence{block: 0xffffffff, count: 6}}, invalidPos, invalidPos, 31},
|
||||
}
|
||||
|
||||
for n, i := range input {
|
||||
|
@ -1238,7 +1243,7 @@ func TestIsCorrupted(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestSetRollover(t *testing.T) {
|
||||
func testSetRollover(t *testing.T, serial bool) {
|
||||
ds, err := randomLocalStore()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
@ -1253,7 +1258,7 @@ func TestSetRollover(t *testing.T) {
|
|||
|
||||
// Allocate first half of the bits
|
||||
for i := 0; i < numBits/2; i++ {
|
||||
_, err := hnd.SetAny(true)
|
||||
_, err := hnd.SetAny(serial)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected failure on allocation %d: %v\n%s", i, err, hnd)
|
||||
}
|
||||
|
@ -1276,12 +1281,12 @@ func TestSetRollover(t *testing.T) {
|
|||
}
|
||||
}
|
||||
if hnd.Unselected() != uint64(3*numBits/4) {
|
||||
t.Fatalf("Expected full sequence. Instead found %d free bits.\nSeed: %d.\n%s", hnd.unselected, seed, hnd)
|
||||
t.Fatalf("Unexpected free bits: found %d free bits.\nSeed: %d.\n%s", hnd.unselected, seed, hnd)
|
||||
}
|
||||
|
||||
//request to allocate for remaining half of the bits
|
||||
for i := 0; i < numBits/2; i++ {
|
||||
_, err := hnd.SetAny(true)
|
||||
_, err := hnd.SetAny(serial)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected failure on allocation %d: %v\nSeed: %d\n%s", i, err, seed, hnd)
|
||||
}
|
||||
|
@ -1294,7 +1299,7 @@ func TestSetRollover(t *testing.T) {
|
|||
}
|
||||
|
||||
for i := 0; i < numBits/4; i++ {
|
||||
_, err := hnd.SetAny(true)
|
||||
_, err := hnd.SetAny(serial)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected failure on allocation %d: %v\nSeed: %d\n%s", i, err, seed, hnd)
|
||||
}
|
||||
|
@ -1302,7 +1307,7 @@ func TestSetRollover(t *testing.T) {
|
|||
//Now requesting to allocate the unallocated random bits (qurter of the number of bits) should
|
||||
//leave no more bits that can be allocated.
|
||||
if hnd.Unselected() != 0 {
|
||||
t.Fatalf("Unexpected number of unselected bits %d, Expected %d", hnd.Unselected(), numBits/4)
|
||||
t.Fatalf("Unexpected number of unselected bits %d, Expected %d", hnd.Unselected(), 0)
|
||||
}
|
||||
|
||||
err = hnd.Destroy()
|
||||
|
@ -1310,3 +1315,47 @@ func TestSetRollover(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetRollover(t *testing.T) {
|
||||
testSetRollover(t, false)
|
||||
}
|
||||
|
||||
func TestSetRolloverSerial(t *testing.T) {
|
||||
testSetRollover(t, true)
|
||||
}
|
||||
|
||||
func TestGetFirstAvailableFromCurrent(t *testing.T) {
|
||||
input := []struct {
|
||||
mask *sequence
|
||||
bytePos uint64
|
||||
bitPos uint64
|
||||
start uint64
|
||||
curr uint64
|
||||
end uint64
|
||||
}{
|
||||
{&sequence{block: 0xffffffff, count: 2048}, invalidPos, invalidPos, 0, 0, 65536},
|
||||
{&sequence{block: 0x0, count: 8}, 0, 0, 0, 0, 256},
|
||||
{&sequence{block: 0x80000000, count: 8}, 1, 0, 0, 8, 256},
|
||||
{&sequence{block: 0xC0000000, count: 8}, 0, 2, 0, 2, 256},
|
||||
{&sequence{block: 0xE0000000, count: 8}, 0, 3, 0, 0, 256},
|
||||
{&sequence{block: 0xFFFB1FFF, count: 8}, 2, 0, 14, 0, 256},
|
||||
{&sequence{block: 0xFFFFFFFE, count: 8}, 3, 7, 0, 0, 256},
|
||||
|
||||
{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x00000000, count: 1, next: &sequence{block: 0xffffffff, count: 14}}}, 4, 0, 0, 32, 512},
|
||||
{&sequence{block: 0xfffeffff, count: 1, next: &sequence{block: 0xffffffff, count: 15}}, 1, 7, 0, 16, 512},
|
||||
{&sequence{block: 0xfffeffff, count: 15, next: &sequence{block: 0xffffffff, count: 1}}, 5, 7, 0, 16, 512},
|
||||
{&sequence{block: 0xfffeffff, count: 15, next: &sequence{block: 0xffffffff, count: 1}}, 9, 7, 0, 48, 512},
|
||||
{&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0xffffffef, count: 14}}, 19, 3, 0, 124, 512},
|
||||
{&sequence{block: 0xfffeffff, count: 15, next: &sequence{block: 0x0fffffff, count: 1}}, 60, 0, 0, 480, 512},
|
||||
{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xfffeffff, count: 14, next: &sequence{block: 0xffffffff, count: 1}}}, 17, 7, 0, 124, 512},
|
||||
{&sequence{block: 0xfffffffb, count: 1, next: &sequence{block: 0xffffffff, count: 14, next: &sequence{block: 0xffffffff, count: 1}}}, 3, 5, 0, 124, 512},
|
||||
{&sequence{block: 0xfffffffb, count: 1, next: &sequence{block: 0xfffeffff, count: 14, next: &sequence{block: 0xffffffff, count: 1}}}, 13, 7, 0, 80, 512},
|
||||
}
|
||||
|
||||
for n, i := range input {
|
||||
bytePos, bitPos, _ := getAvailableFromCurrent(i.mask, i.start, i.curr, i.end)
|
||||
if bytePos != i.bytePos || bitPos != i.bitPos {
|
||||
t.Fatalf("Error in (%d) getFirstAvailable(). Expected (%d, %d). Got (%d, %d)", n, i.bytePos, i.bitPos, bytePos, bitPos)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"math/rand"
|
||||
"net"
|
||||
"strconv"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -30,7 +31,10 @@ func init() {
|
|||
}
|
||||
|
||||
// OptionBoltdbWithRandomDBFile function returns a random dir for local store backend
|
||||
func randomLocalStore() (datastore.DataStore, error) {
|
||||
func randomLocalStore(needStore bool) (datastore.DataStore, error) {
|
||||
if !needStore {
|
||||
return nil, nil
|
||||
}
|
||||
tmp, err := ioutil.TempFile("", "libnetwork-")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error creating temp file: %v", err)
|
||||
|
@ -50,17 +54,13 @@ func randomLocalStore() (datastore.DataStore, error) {
|
|||
})
|
||||
}
|
||||
|
||||
func getAllocator() (*Allocator, error) {
|
||||
func getAllocator(store bool) (*Allocator, error) {
|
||||
ipamutils.InitNetworks(nil)
|
||||
ds, err := randomLocalStore()
|
||||
ds, err := randomLocalStore(store)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
a, err := NewAllocator(ds, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return a, nil
|
||||
return NewAllocator(ds, nil)
|
||||
}
|
||||
|
||||
func TestInt2IP2IntConversion(t *testing.T) {
|
||||
|
@ -170,7 +170,7 @@ func TestPoolDataMarshal(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSubnetsMarshal(t *testing.T) {
|
||||
a, err := getAllocator()
|
||||
a, err := getAllocator(true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -217,7 +217,7 @@ func TestSubnetsMarshal(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestAddSubnets(t *testing.T) {
|
||||
a, err := getAllocator()
|
||||
a, err := getAllocator(true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -286,7 +286,7 @@ func TestAddSubnets(t *testing.T) {
|
|||
func TestAddReleasePoolID(t *testing.T) {
|
||||
var k0, k1, k2 SubnetKey
|
||||
|
||||
a, err := getAllocator()
|
||||
a, err := getAllocator(true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -448,7 +448,7 @@ func TestAddReleasePoolID(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestPredefinedPool(t *testing.T) {
|
||||
a, err := getAllocator()
|
||||
a, err := getAllocator(true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -476,7 +476,7 @@ func TestPredefinedPool(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRemoveSubnet(t *testing.T) {
|
||||
a, err := getAllocator()
|
||||
a, err := getAllocator(true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -519,7 +519,7 @@ func TestRemoveSubnet(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetSameAddress(t *testing.T) {
|
||||
a, err := getAllocator()
|
||||
a, err := getAllocator(true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -549,7 +549,7 @@ func TestGetSameAddress(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetAddressSubPoolEqualPool(t *testing.T) {
|
||||
a, err := getAllocator()
|
||||
a, err := getAllocator(true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -566,7 +566,7 @@ func TestGetAddressSubPoolEqualPool(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRequestReleaseAddressFromSubPool(t *testing.T) {
|
||||
a, err := getAllocator()
|
||||
a, err := getAllocator(true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -697,8 +697,9 @@ func TestRequestReleaseAddressFromSubPool(t *testing.T) {
|
|||
|
||||
func TestSerializeRequestReleaseAddressFromSubPool(t *testing.T) {
|
||||
opts := map[string]string{
|
||||
ipamapi.AllocSerialPrefix: "true"}
|
||||
a, err := getAllocator()
|
||||
ipamapi.AllocSerialPrefix: "true",
|
||||
}
|
||||
a, err := getAllocator(false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -848,7 +849,7 @@ func TestRequestSyntaxCheck(t *testing.T) {
|
|||
err error
|
||||
)
|
||||
|
||||
a, err := getAllocator()
|
||||
a, err := getAllocator(true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -950,7 +951,7 @@ func TestRelease(t *testing.T) {
|
|||
subnet = "192.168.0.0/23"
|
||||
)
|
||||
|
||||
a, err := getAllocator()
|
||||
a, err := getAllocator(true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -1057,7 +1058,7 @@ func assertNRequests(t *testing.T, subnet string, numReq int, lastExpectedIP str
|
|||
)
|
||||
|
||||
lastIP := net.ParseIP(lastExpectedIP)
|
||||
a, err := getAllocator()
|
||||
a, err := getAllocator(true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -1088,24 +1089,24 @@ func benchmarkRequest(b *testing.B, a *Allocator, subnet string) {
|
|||
}
|
||||
|
||||
func benchMarkRequest(subnet string, b *testing.B) {
|
||||
a, _ := getAllocator()
|
||||
a, _ := getAllocator(true)
|
||||
for n := 0; n < b.N; n++ {
|
||||
benchmarkRequest(b, a, subnet)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkRequest_24(b *testing.B) {
|
||||
a, _ := getAllocator()
|
||||
a, _ := getAllocator(true)
|
||||
benchmarkRequest(b, a, "10.0.0.0/24")
|
||||
}
|
||||
|
||||
func BenchmarkRequest_16(b *testing.B) {
|
||||
a, _ := getAllocator()
|
||||
a, _ := getAllocator(true)
|
||||
benchmarkRequest(b, a, "10.0.0.0/16")
|
||||
}
|
||||
|
||||
func BenchmarkRequest_8(b *testing.B) {
|
||||
a, _ := getAllocator()
|
||||
a, _ := getAllocator(true)
|
||||
benchmarkRequest(b, a, "10.0.0.0/8")
|
||||
}
|
||||
|
||||
|
@ -1115,7 +1116,7 @@ func TestAllocateRandomDeallocate(t *testing.T) {
|
|||
}
|
||||
|
||||
func testAllocateRandomDeallocate(t *testing.T, pool, subPool string, num int) {
|
||||
ds, err := randomLocalStore()
|
||||
ds, err := randomLocalStore(true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -1184,7 +1185,7 @@ func testAllocateRandomDeallocate(t *testing.T, pool, subPool string, num int) {
|
|||
|
||||
func TestRetrieveFromStore(t *testing.T) {
|
||||
num := 200
|
||||
ds, err := randomLocalStore()
|
||||
ds, err := randomLocalStore(true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -1319,7 +1320,7 @@ func runParallelTests(t *testing.T, instance int) {
|
|||
// The first instance creates the allocator, gives the start
|
||||
// and finally checks the pools each instance was assigned
|
||||
if instance == first {
|
||||
allocator, err = getAllocator()
|
||||
allocator, err = getAllocator(true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -1362,6 +1363,71 @@ func runParallelTests(t *testing.T, instance int) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestRequestReleaseAddressDuplicate(t *testing.T) {
|
||||
a, err := getAllocator(false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
type IP struct {
|
||||
ip *net.IPNet
|
||||
ref int
|
||||
}
|
||||
ips := []IP{}
|
||||
allocatedIPs := []*net.IPNet{}
|
||||
a.addrSpaces["rosso"] = &addrSpace{
|
||||
id: dsConfigKey + "/" + "rosso",
|
||||
ds: a.addrSpaces[localAddressSpace].ds,
|
||||
alloc: a.addrSpaces[localAddressSpace].alloc,
|
||||
scope: a.addrSpaces[localAddressSpace].scope,
|
||||
subnets: map[SubnetKey]*PoolData{},
|
||||
}
|
||||
var wg sync.WaitGroup
|
||||
opts := map[string]string{
|
||||
ipamapi.AllocSerialPrefix: "true",
|
||||
}
|
||||
var l sync.Mutex
|
||||
|
||||
poolID, _, _, err := a.RequestPool("rosso", "198.168.0.0/23", "", nil, false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for err == nil {
|
||||
var c *net.IPNet
|
||||
if c, _, err = a.RequestAddress(poolID, nil, opts); err == nil {
|
||||
l.Lock()
|
||||
ips = append(ips, IP{c, 1})
|
||||
l.Unlock()
|
||||
allocatedIPs = append(allocatedIPs, c)
|
||||
if len(allocatedIPs) > 500 {
|
||||
i := rand.Intn(len(allocatedIPs) - 1)
|
||||
wg.Add(1)
|
||||
go func(ip *net.IPNet) {
|
||||
if err = a.ReleaseAddress(poolID, ip.IP); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
l.Lock()
|
||||
ips = append(ips, IP{ip, -1})
|
||||
l.Unlock()
|
||||
wg.Done()
|
||||
}(allocatedIPs[i])
|
||||
allocatedIPs = append(allocatedIPs[:i], allocatedIPs[i+1:]...)
|
||||
}
|
||||
}
|
||||
}
|
||||
wg.Wait()
|
||||
refMap := make(map[string]int)
|
||||
for _, ip := range ips {
|
||||
refMap[ip.ip.String()] = refMap[ip.ip.String()] + ip.ref
|
||||
if refMap[ip.ip.String()] < 0 {
|
||||
t.Fatalf("IP %s was previously released", ip.ip.String())
|
||||
}
|
||||
if refMap[ip.ip.String()] > 1 {
|
||||
t.Fatalf("IP %s was previously allocated", ip.ip.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParallelPredefinedRequest1(t *testing.T) {
|
||||
runParallelTests(t, 0)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue