Selaa lähdekoodia

Minor unit test change

Since bit allocation is no longer first available from
the start some verfications are removed/modified to
the change allocation model

Signed-off-by: Abhinandan Prativadi <abhi@docker.com>
Abhinandan Prativadi 8 vuotta sitten
vanhempi
commit
813a24a51c
2 muutettua tiedostoa jossa 326 lisäystä ja 10 poistoa
  1. 192 10
      libnetwork/bitseq/sequence_test.go
  2. 134 0
      libnetwork/ipam/allocator_test.go

+ 192 - 10
libnetwork/bitseq/sequence_test.go

@@ -1,4 +1,4 @@
-package bitseq
+SetAny(false)package bitseq
 
 import (
 	"fmt"
@@ -562,7 +562,7 @@ func TestSet(t *testing.T) {
 		t.Fatal("Expected failure, but succeeded")
 	}
 
-	os, err := hnd.SetAny()
+	os, err := hnd.SetAny(false)
 	if err != nil {
 		t.Fatalf("Unexpected failure: %v", err)
 	}
@@ -606,11 +606,11 @@ func TestSetUnset(t *testing.T) {
 
 	// set and unset all one by one
 	for hnd.Unselected() > 0 {
-		if _, err := hnd.SetAny(); err != nil {
+		if _, err := hnd.SetAny(false); err != nil {
 			t.Fatal(err)
 		}
 	}
-	if _, err := hnd.SetAny(); err != ErrNoBitAvailable {
+	if _, err := hnd.SetAny(false); err != ErrNoBitAvailable {
 		t.Fatal("Expected error. Got success")
 	}
 	if _, err := hnd.SetAnyInRange(10, 20); err != ErrNoBitAvailable {
@@ -638,12 +638,12 @@ func TestOffsetSetUnset(t *testing.T) {
 
 	// set and unset all one by one
 	for hnd.Unselected() > 0 {
-		if _, err := hnd.SetAny(); err != nil {
+		if _, err := hnd.SetAny(false); err != nil {
 			t.Fatal(err)
 		}
 	}
 
-	if _, err := hnd.SetAny(); err != ErrNoBitAvailable {
+	if _, err := hnd.SetAny(false); err != ErrNoBitAvailable {
 		t.Fatal("Expected error. Got success")
 	}
 
@@ -785,6 +785,126 @@ func TestSetInRange(t *testing.T) {
 	}
 }
 
+func TestSetInRangeSerial(t *testing.T) {
+	numBits := uint64(1024 * blockLen)
+	hnd, err := NewHandle("", nil, "", numBits)
+	if err != nil {
+		t.Fatal(err)
+	}
+	hnd.head = getTestSequence()
+
+	firstAv := uint64(100*blockLen + blockLen - 1)
+
+	if o, err := hnd.SetAnyInRange(4, 3); err == nil {
+		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
+	}
+
+	if o, err := hnd.SetAnyInRange(0, numBits); err == nil {
+		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
+	}
+
+	o, err := hnd.SetAnyInRange(100*uint64(blockLen), 101*uint64(blockLen))
+	if err != nil {
+		t.Fatalf("Unexpected failure: (%d, %v)", o, err)
+	}
+	if o != firstAv {
+		t.Fatalf("Unexpected ordinal: %d", o)
+	}
+
+	if o, err := hnd.SetAnyInRange(0, uint64(blockLen)); err == nil {
+		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
+	}
+
+	if o, err := hnd.SetAnyInRange(0, firstAv-1); err == nil {
+		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
+	}
+
+	if o, err := hnd.SetAnyInRange(111*uint64(blockLen), 161*uint64(blockLen)); err == nil {
+		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
+	}
+
+	o, err = hnd.SetAnyInRange(161*uint64(blockLen), 162*uint64(blockLen))
+	if err != nil {
+		t.Fatal(err)
+	}
+	if o != 161*uint64(blockLen)+30 {
+		t.Fatalf("Unexpected ordinal: %d", o)
+	}
+
+	o, err = hnd.SetAnyInRange(161*uint64(blockLen), 162*uint64(blockLen))
+	if err != nil {
+		t.Fatal(err)
+	}
+	if o != 161*uint64(blockLen)+31 {
+		t.Fatalf("Unexpected ordinal: %d", o)
+	}
+
+	o, err = hnd.SetAnyInRange(161*uint64(blockLen), 162*uint64(blockLen))
+	if err == nil {
+		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
+	}
+
+	if _, err := hnd.SetAnyInRange(0, numBits-1); err != nil {
+		t.Fatalf("Unexpected failure: %v", err)
+	}
+
+	// set one bit using the set range with 1 bit size range
+	if _, err := hnd.SetAnyInRange(uint64(163*blockLen-1), uint64(163*blockLen-1)); err != nil {
+		t.Fatal(err)
+	}
+
+	// create a non multiple of 32 mask
+	hnd, err = NewHandle("", nil, "", 30)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// set all bit in the first range
+	for hnd.Unselected() > 22 {
+		if o, err := hnd.SetAnyInRange(0, 7); err != nil {
+			t.Fatalf("Unexpected failure: (%d, %v)", o, err)
+		}
+	}
+	// try one more set, which should fail
+	o, err = hnd.SetAnyInRange(0, 7)
+	if err == nil {
+		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
+	}
+	if err != ErrNoBitAvailable {
+		t.Fatalf("Unexpected error: %v", err)
+	}
+
+	// set all bit in a second range
+	for hnd.Unselected() > 14 {
+		if o, err := hnd.SetAnyInRange(8, 15); err != nil {
+			t.Fatalf("Unexpected failure: (%d, %v)", o, err)
+		}
+	}
+
+	// try one more set, which should fail
+	o, err = hnd.SetAnyInRange(0, 15)
+	if err == nil {
+		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
+	}
+	if err != ErrNoBitAvailable {
+		t.Fatalf("Unexpected error: %v", err)
+	}
+
+	// set all bit in a range which includes the last bit
+	for hnd.Unselected() > 12 {
+		if o, err := hnd.SetAnyInRange(28, 29); err != nil {
+			t.Fatalf("Unexpected failure: (%d, %v)", o, err)
+		}
+	}
+	o, err = hnd.SetAnyInRange(28, 29)
+	if err == nil {
+		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
+	}
+	if err != ErrNoBitAvailable {
+		t.Fatalf("Unexpected error: %v", err)
+	}
+}
+
 // This one tests an allocation pattern which unveiled an issue in pushReservation
 // Specifically a failure in detecting when we are in the (B) case (the bit to set
 // belongs to the last block of the current sequence). Because of a bug, code
@@ -861,7 +981,7 @@ func TestMethods(t *testing.T) {
 	}
 
 	for i := 0; i < 192; i++ {
-		_, err := hnd.SetAny()
+		_, err := hnd.SetAny(false)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -941,7 +1061,7 @@ func TestAllocateRandomDeallocate(t *testing.T) {
 
 	// Allocate first half of the bits
 	for i := 0; i < numBits/2; i++ {
-		_, err := hnd.SetAny()
+		_, err := hnd.SetAny(false)
 		if err != nil {
 			t.Fatalf("Unexpected failure on allocation %d: %v\n%s", i, err, hnd)
 		}
@@ -971,7 +1091,7 @@ func TestAllocateRandomDeallocate(t *testing.T) {
 
 	// Request a quarter of bits
 	for i := 0; i < numBits/4; i++ {
-		_, err := hnd.SetAny()
+		_, err := hnd.SetAny(false)
 		if err != nil {
 			t.Fatalf("Unexpected failure on allocation %d: %v\nSeed: %d\n%s", i, err, seed, hnd)
 		}
@@ -989,6 +1109,68 @@ func TestAllocateRandomDeallocate(t *testing.T) {
 	}
 }
 
+func TestAllocateRandomDeallocateSerialize(t *testing.T) {
+	ds, err := randomLocalStore()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	numBlocks := uint32(8)
+	numBits := int(numBlocks * blockLen)
+	hnd, err := NewHandle("bitseq-test/data/", ds, "test1", uint64(numBits))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	expected := &sequence{block: 0xffffffff, count: uint64(numBlocks / 2), next: &sequence{block: 0x0, count: uint64(numBlocks / 2)}}
+
+	// Allocate first half of the bits
+	for i := 0; i < numBits/2; i++ {
+		_, err := hnd.SetAny(true)
+		if err != nil {
+			t.Fatalf("Unexpected failure on allocation %d: %v\n%s", i, err, hnd)
+		}
+	}
+	if hnd.Unselected() != uint64(numBits/2) {
+		t.Fatalf("Expected full sequence. Instead found %d free bits. %s", hnd.unselected, hnd)
+	}
+	if !hnd.head.equal(expected) {
+		t.Fatalf("Unexpected sequence. Got:\n%s", hnd)
+	}
+
+	seed := time.Now().Unix()
+	rand.Seed(seed)
+
+	// Deallocate half of the allocated bits following a random pattern
+	pattern := rand.Perm(numBits / 2)
+	for i := 0; i < numBits/4; i++ {
+		bit := pattern[i]
+		err := hnd.Unset(uint64(bit))
+		if err != nil {
+			t.Fatalf("Unexpected failure on deallocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd)
+		}
+	}
+	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)
+	}
+
+	// Request a quarter of bits
+	for i := 0; i < numBits/4; i++ {
+		_, err := hnd.SetAny(true)
+		if err != nil {
+			t.Fatalf("Unexpected failure on allocation %d: %v\nSeed: %d\n%s", i, err, seed, hnd)
+		}
+	}
+	if hnd.Unselected() != uint64(numBits/2) {
+		t.Fatalf("Expected half sequence. Instead found %d free bits.\nSeed: %d\n%s", hnd.unselected, seed, hnd)
+	}
+
+	err = hnd.Destroy()
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
 func TestRetrieveFromStore(t *testing.T) {
 	ds, err := randomLocalStore()
 	if err != nil {
@@ -1003,7 +1185,7 @@ func TestRetrieveFromStore(t *testing.T) {
 
 	// Allocate first half of the bits
 	for i := 0; i < numBits/2; i++ {
-		_, err := hnd.SetAny()
+		_, err := hnd.SetAny(false)
 		if err != nil {
 			t.Fatalf("Unexpected failure on allocation %d: %v\n%s", i, err, hnd)
 		}

+ 134 - 0
libnetwork/ipam/allocator_test.go

@@ -644,6 +644,7 @@ func TestRequestReleaseAddressFromSubPool(t *testing.T) {
 	unoExp, _ := types.ParseCIDR("10.2.2.0/16")
 	dueExp, _ := types.ParseCIDR("10.2.2.2/16")
 	treExp, _ := types.ParseCIDR("10.2.2.1/16")
+
 	if poolID, _, _, err = a.RequestPool("rosso", "10.2.0.0/16", "10.2.2.0/24", nil, false); err != nil {
 		t.Fatal(err)
 	}
@@ -694,6 +695,139 @@ func TestRequestReleaseAddressFromSubPool(t *testing.T) {
 	}
 }
 
+func TestSerializeRequestReleaseAddressFromSubPool(t *testing.T) {
+	opts := map[string]string{
+		ipamapi.AllocSerialPrefix: "true"}
+	a, err := getAllocator()
+	if err != nil {
+		t.Fatal(err)
+	}
+	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{},
+	}
+
+	poolID, _, _, err := a.RequestPool("rosso", "172.28.0.0/16", "172.28.30.0/24", nil, false)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	var ip *net.IPNet
+	expected := &net.IPNet{IP: net.IP{172, 28, 30, 255}, Mask: net.IPMask{255, 255, 0, 0}}
+	for err == nil {
+		var c *net.IPNet
+		if c, _, err = a.RequestAddress(poolID, nil, opts); err == nil {
+			ip = c
+		}
+	}
+	if err != ipamapi.ErrNoAvailableIPs {
+		t.Fatal(err)
+	}
+	if !types.CompareIPNet(expected, ip) {
+		t.Fatalf("Unexpected last IP from subpool. Expected: %s. Got: %v.", expected, ip)
+	}
+	rp := &net.IPNet{IP: net.IP{172, 28, 30, 97}, Mask: net.IPMask{255, 255, 0, 0}}
+	if err = a.ReleaseAddress(poolID, rp.IP); err != nil {
+		t.Fatal(err)
+	}
+	if ip, _, err = a.RequestAddress(poolID, nil, opts); err != nil {
+		t.Fatal(err)
+	}
+	if !types.CompareIPNet(rp, ip) {
+		t.Fatalf("Unexpected IP from subpool. Expected: %s. Got: %v.", rp, ip)
+	}
+
+	_, _, _, err = a.RequestPool("rosso", "10.0.0.0/8", "10.0.0.0/16", nil, false)
+	if err != nil {
+		t.Fatal(err)
+	}
+	poolID, _, _, err = a.RequestPool("rosso", "10.0.0.0/16", "10.0.0.0/24", nil, false)
+	if err != nil {
+		t.Fatal(err)
+	}
+	expected = &net.IPNet{IP: net.IP{10, 0, 0, 255}, Mask: net.IPMask{255, 255, 0, 0}}
+	for err == nil {
+		var c *net.IPNet
+		if c, _, err = a.RequestAddress(poolID, nil, opts); err == nil {
+			ip = c
+		}
+	}
+	if err != ipamapi.ErrNoAvailableIPs {
+		t.Fatal(err)
+	}
+	if !types.CompareIPNet(expected, ip) {
+		t.Fatalf("Unexpected last IP from subpool. Expected: %s. Got: %v.", expected, ip)
+	}
+	rp = &net.IPNet{IP: net.IP{10, 0, 0, 79}, Mask: net.IPMask{255, 255, 0, 0}}
+	if err = a.ReleaseAddress(poolID, rp.IP); err != nil {
+		t.Fatal(err)
+	}
+	if ip, _, err = a.RequestAddress(poolID, nil, opts); err != nil {
+		t.Fatal(err)
+	}
+	if !types.CompareIPNet(rp, ip) {
+		t.Fatalf("Unexpected IP from subpool. Expected: %s. Got: %v.", rp, ip)
+	}
+
+	// Request any addresses from subpool after explicit address request
+	unoExp, _ := types.ParseCIDR("10.2.2.0/16")
+	dueExp, _ := types.ParseCIDR("10.2.2.2/16")
+	treExp, _ := types.ParseCIDR("10.2.2.1/16")
+	quaExp, _ := types.ParseCIDR("10.2.2.3/16")
+	fivExp, _ := types.ParseCIDR("10.2.2.4/16")
+	if poolID, _, _, err = a.RequestPool("rosso", "10.2.0.0/16", "10.2.2.0/24", nil, false); err != nil {
+		t.Fatal(err)
+	}
+	tre, _, err := a.RequestAddress(poolID, treExp.IP, opts)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !types.CompareIPNet(tre, treExp) {
+		t.Fatalf("Unexpected address: %v", tre)
+	}
+
+	uno, _, err := a.RequestAddress(poolID, nil, opts)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !types.CompareIPNet(uno, unoExp) {
+		t.Fatalf("Unexpected address: %v", uno)
+	}
+
+	due, _, err := a.RequestAddress(poolID, nil, opts)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !types.CompareIPNet(due, dueExp) {
+		t.Fatalf("Unexpected address: %v", due)
+	}
+
+	if err = a.ReleaseAddress(poolID, uno.IP); err != nil {
+		t.Fatal(err)
+	}
+	uno, _, err = a.RequestAddress(poolID, nil, opts)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !types.CompareIPNet(uno, quaExp) {
+		t.Fatalf("Unexpected address: %v", uno)
+	}
+
+	if err = a.ReleaseAddress(poolID, tre.IP); err != nil {
+		t.Fatal(err)
+	}
+	tre, _, err = a.RequestAddress(poolID, nil, opts)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !types.CompareIPNet(tre, fivExp) {
+		t.Fatalf("Unexpected address: %v", tre)
+	}
+}
+
 func TestGetAddress(t *testing.T) {
 	input := []string{
 		/*"10.0.0.0/8", "10.0.0.0/9", "10.0.0.0/10",*/ "10.0.0.0/11", "10.0.0.0/12", "10.0.0.0/13", "10.0.0.0/14",