From ff545feae39d8769d10bfda7f806208b6ecf881c Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Mon, 1 Jun 2015 11:38:23 +0100 Subject: [PATCH] Add some unit tests for multi-subnet --- ipam/allocator_test.go | 70 +++++++++++++++++++++++++----------------- ipam/http_test.go | 56 +++++++++++++++++---------------- 2 files changed, 72 insertions(+), 54 deletions(-) diff --git a/ipam/allocator_test.go b/ipam/allocator_test.go index cfca9867..05531b08 100644 --- a/ipam/allocator_test.go +++ b/ipam/allocator_test.go @@ -24,36 +24,49 @@ func TestAllocFree(t *testing.T) { container1 = "abcdef" container2 = "baddf00d" container3 = "b01df00d" - universe = "10.0.3.0/28" - testAddr1 = "10.0.3.1" // first address allocated should be .1 because .0 is network addr - spaceSize = 14 // 16 IP addresses in /28, minus .0 and .15 + universe = "10.0.3.0/26" + subnet1 = "10.0.3.0/28" + subnet2 = "10.0.3.32/28" + testAddr1 = "10.0.3.1" + testAddr2 = "10.0.3.33" + spaceSize = 62 // 64 IP addresses in /26, minus .0 and .63 ) alloc := makeAllocatorWithMockGossip(t, "01:00:00:01:00:00", universe, 1) defer alloc.Stop() + _, cidr1, _ := address.ParseCIDR(subnet1) + _, cidr2, _ := address.ParseCIDR(subnet2) alloc.claimRingForTesting() - addr1, _ := alloc.Allocate(container1, nil) + addr1, _ := alloc.Allocate(container1, cidr1, nil) wt.AssertEqualString(t, addr1.String(), testAddr1, "address") + addr2, err := alloc.Allocate(container1, cidr2, nil) + wt.AssertNoErr(t, err) + wt.AssertEqualString(t, addr2.String(), testAddr2, "address") + CheckAllExpectedMessagesSent(alloc) + // Ask for another address for a different container and check it's different - addr2, _ := alloc.Allocate(container2, nil) - if addr2.String() == testAddr1 { - t.Fatalf("Expected different address but got %s", addr2.String()) + addr1b, _ := alloc.Allocate(container2, cidr1, nil) + if addr1b.String() == testAddr1 { + t.Fatalf("Expected different address but got %s", addr1b.String()) } - // Ask for the first container again and we should get the same address again - addr1a, _ := alloc.Allocate(container1, nil) + // Ask for the first container again and we should get the same addresses again + addr1a, _ := alloc.Allocate(container1, cidr1, nil) wt.AssertEqualString(t, addr1a.String(), testAddr1, "address") + addr2a, _ := alloc.Allocate(container1, cidr2, nil) + wt.AssertEqualString(t, addr2a.String(), testAddr2, "address") - // Now free the first one, and we should get it back when we ask + // Now free the first container, and we should get its addresses back wt.AssertSuccess(t, alloc.Free(container1)) - addr3, _ := alloc.Allocate(container3, nil) + addr3, _ := alloc.Allocate(container3, cidr1, nil) wt.AssertEqualString(t, addr3.String(), testAddr1, "address") + addr4, _ := alloc.Allocate(container3, cidr2, nil) + wt.AssertEqualString(t, addr4.String(), testAddr2, "address") alloc.ContainerDied(container2) alloc.ContainerDied(container3) - alloc.String() // force sync-up after async call wt.AssertEquals(t, alloc.NumFreeAddresses(), address.Offset(spaceSize)) } @@ -80,7 +93,7 @@ func TestBootstrap(t *testing.T) { ExpectBroadcastMessage(alloc1, nil) // alloc1 will try to form consensus done := make(chan bool) go func() { - alloc1.Allocate("somecontainer", nil) + alloc1.Allocate("somecontainer", alloc1.defaultSubnet, nil) done <- true }() time.Sleep(100 * time.Millisecond) @@ -128,15 +141,16 @@ func TestAllocatorClaim(t *testing.T) { defer alloc.Stop() alloc.claimRingForTesting() - addr1, _ := alloc.Allocate(container1, nil) - alloc.Allocate(container2, nil) + addr1, _ := alloc.Allocate(container1, alloc.defaultSubnet, nil) + alloc.Allocate(container2, alloc.defaultSubnet, nil) // Now free the first one, and try to claim it wt.AssertSuccess(t, alloc.Free(container1)) t.Log(alloc) err := alloc.Claim(container3, addr1, nil) wt.AssertNoErr(t, err) - addr3, _ := alloc.Allocate(container3, nil) + // Check we get this address back if we try an allocate + addr3, _ := alloc.Allocate(container3, alloc.defaultSubnet, nil) wt.AssertEqualString(t, addr3.String(), testAddr1, "address") } @@ -175,9 +189,9 @@ func TestCancel(t *testing.T) { alloc1.OnGossipBroadcast(alloc2.Encode()) // Get some IPs, so each allocator has some space - res1, _ := alloc1.Allocate("foo", nil) + res1, _ := alloc1.Allocate("foo", alloc1.defaultSubnet, nil) common.Debug.Printf("res1 = %s", res1.String()) - res2, _ := alloc2.Allocate("bar", nil) + res2, _ := alloc2.Allocate("bar", alloc2.defaultSubnet, nil) common.Debug.Printf("res2 = %s", res2.String()) if res1 == res2 { wt.Fatalf(t, "Error: got same ips!") @@ -189,12 +203,12 @@ func TestCancel(t *testing.T) { // Use up all the IPs that alloc1 owns, so the allocation after this will prompt a request to alloc2 for i := 0; alloc1.NumFreeAddresses() > 0; i++ { - alloc1.Allocate(fmt.Sprintf("tmp%d", i), nil) + alloc1.Allocate(fmt.Sprintf("tmp%d", i), alloc1.defaultSubnet, nil) } cancelChan := make(chan bool, 1) doneChan := make(chan bool) go func() { - _, ok := alloc1.Allocate("baz", cancelChan) + _, ok := alloc1.Allocate("baz", alloc1.defaultSubnet, cancelChan) doneChan <- ok == nil }() @@ -221,12 +235,12 @@ func TestGossipShutdown(t *testing.T) { defer alloc.Stop() alloc.claimRingForTesting() - addr1, _ := alloc.Allocate(container1, nil) + addr1, _ := alloc.Allocate(container1, alloc.defaultSubnet, nil) wt.AssertEqualString(t, addr1.String(), testAddr1, "address") alloc.Shutdown() - _, err := alloc.Allocate(container2, nil) // trying to allocate after shutdown should fail + _, err := alloc.Allocate(container2, alloc.defaultSubnet, nil) // trying to allocate after shutdown should fail wt.AssertFalse(t, err == nil, "no address") CheckAllExpectedMessagesSent(alloc) @@ -241,10 +255,10 @@ func TestTransfer(t *testing.T) { alloc2 := allocs[1] alloc3 := allocs[2] // This will be 'master' and get the first range - _, err := alloc2.Allocate("foo", nil) + _, err := alloc2.Allocate("foo", alloc2.defaultSubnet, nil) wt.AssertTrue(t, err == nil, "Failed to get address") - _, err = alloc3.Allocate("bar", nil) + _, err = alloc3.Allocate("bar", alloc3.defaultSubnet, nil) wt.AssertTrue(t, err == nil, "Failed to get address") router.GossipBroadcast(alloc2.Gossip()) @@ -258,7 +272,7 @@ func TestTransfer(t *testing.T) { wt.AssertEquals(t, alloc1.NumFreeAddresses(), address.Offset(1022)) - _, err = alloc1.Allocate("foo", nil) + _, err = alloc1.Allocate("foo", alloc1.defaultSubnet, nil) wt.AssertTrue(t, err == nil, "Failed to get address") alloc1.Stop() } @@ -274,7 +288,7 @@ func TestFakeRouterSimple(t *testing.T) { alloc1 := allocs[0] //alloc2 := allocs[1] - addr, _ := alloc1.Allocate("foo", nil) + addr, _ := alloc1.Allocate("foo", alloc1.defaultSubnet, nil) println("Got addr", addr) } @@ -332,7 +346,7 @@ func TestAllocatorFuzz(t *testing.T) { allocIndex := rand.Int31n(nodes) alloc := allocs[allocIndex] //common.Info.Printf("Allocate: asking allocator %d", allocIndex) - addr, err := alloc.Allocate(name, nil) + addr, err := alloc.Allocate(name, alloc.defaultSubnet, nil) if err != nil { panic(fmt.Sprintf("Could not allocate addr")) @@ -394,7 +408,7 @@ func TestAllocatorFuzz(t *testing.T) { //common.Info.Printf("Asking for %s on allocator %d again", addr, res.alloc) - newAddr, _ := alloc.Allocate(res.name, nil) + newAddr, _ := alloc.Allocate(res.name, alloc.defaultSubnet, nil) oldAddr, _ := address.ParseIP(addr) if newAddr != oldAddr { panic(fmt.Sprintf("Got different address for repeat request for %s: %s != %s", res.name, newAddr, oldAddr)) diff --git a/ipam/http_test.go b/ipam/http_test.go index f1a828d1..c66b2d85 100644 --- a/ipam/http_test.go +++ b/ipam/http_test.go @@ -59,45 +59,49 @@ func listenHTTP(alloc *Allocator) int { return httpListener.Addr().(*net.TCPAddr).Port } -func allocURL(port int, containerID string) string { +func identURL(port int, containerID string) string { return fmt.Sprintf("http://localhost:%d/ip/%s", port, containerID) } +func allocURL(port int, cidr string, containerID string) string { + return fmt.Sprintf("http://localhost:%d/ip/%s/%s", port, containerID, cidr) +} + func TestHttp(t *testing.T) { var ( containerID = "deadbeef" container2 = "baddf00d" container3 = "b01df00d" - testAddr1 = "10.0.3.9" - netSuffix = "/29" - testCIDR1 = "10.0.3.8" + netSuffix + universe = "10.0.0.0/8" + testAddr1 = "10.0.3.9/29" + testCIDR1 = "10.0.3.8/29" + testCIDR2 = "10.2.0.0/16" + testAddr2 = "10.2.0.1/16" ) - alloc := makeAllocatorWithMockGossip(t, "08:00:27:01:c3:9a", testCIDR1, 1) + alloc := makeAllocatorWithMockGossip(t, "08:00:27:01:c3:9a", universe, 1) port := listenHTTP(alloc) alloc.claimRingForTesting() - // Ask the http server for a new address - cidr1 := HTTPPost(t, allocURL(port, containerID)) - wt.AssertEqualString(t, cidr1, testAddr1+netSuffix, "address") - check := HTTPGet(t, allocURL(port, containerID)) - wt.AssertEqualString(t, check, cidr1, "address") + cidr1a := HTTPPost(t, allocURL(port, testCIDR1, containerID)) + wt.AssertEqualString(t, cidr1a, testAddr1, "address") - // Ask the http server for another address and check it's different - cidr2 := HTTPPost(t, allocURL(port, container2)) - wt.AssertFalse(t, cidr2 == testAddr1+netSuffix, "address") + cidr2a := HTTPPost(t, allocURL(port, testCIDR2, containerID)) + wt.AssertEqualString(t, cidr2a, testAddr2, "address") - // Ask for the first container again and we should get the same address again - cidr1a := HTTPPost(t, allocURL(port, containerID)) - wt.AssertEqualString(t, cidr1a, testAddr1+netSuffix, "address") - // Now free the first one, and we should get it back when we ask - doHTTP("DELETE", allocURL(port, containerID)) - resp, err := doHTTP("GET", allocURL(port, containerID)) - wt.AssertNoErr(t, err) - wt.AssertStatus(t, resp.StatusCode, http.StatusNotFound, "http response") + // Ask the http server for a pair of addresses for another container and check they're different + cidr1b := HTTPPost(t, allocURL(port, testCIDR1, container2)) + wt.AssertFalse(t, cidr1b == testAddr1, "address") + cidr2b := HTTPPost(t, allocURL(port, testCIDR2, container2)) + wt.AssertFalse(t, cidr2b == testAddr2, "address") - cidr3 := HTTPPost(t, allocURL(port, container3)) - wt.AssertEqualString(t, cidr3, testAddr1+netSuffix, "address") + // Now free the first container, and we should get it back when we ask + doHTTP("DELETE", identURL(port, containerID)) + + cidr1c := HTTPPost(t, allocURL(port, testCIDR1, container3)) + wt.AssertEqualString(t, cidr1c, testAddr1, "address") + cidr2c := HTTPPost(t, allocURL(port, testCIDR2, container3)) + wt.AssertEqualString(t, cidr2c, testAddr2, "address") // Would like to shut down the http server at the end of this test // but it's complicated. @@ -115,7 +119,7 @@ func TestBadHttp(t *testing.T) { port := listenHTTP(alloc) alloc.claimRingForTesting() - cidr1 := HTTPPost(t, allocURL(port, containerID)) + cidr1 := HTTPPost(t, allocURL(port, testCIDR1, containerID)) parts := strings.Split(cidr1, "/") testAddr1 := parts[0] // Verb that's not handled @@ -142,7 +146,7 @@ func impTestHTTPCancel(t *testing.T) { common.InitDefaultLogging(true) var ( containerID = "deadbeef" - testCIDR1 = "10.0.3.5/29" + testCIDR1 = "10.0.3.0/29" ) alloc := makeAllocatorWithMockGossip(t, "08:00:27:01:c3:9a", testCIDR1, 1) @@ -155,7 +159,7 @@ func impTestHTTPCancel(t *testing.T) { // Ask the http server for a new address done := make(chan *http.Response) - req, _ := http.NewRequest("POST", allocURL(port, containerID), nil) + req, _ := http.NewRequest("POST", allocURL(port, testCIDR1, containerID), nil) go func() { res, _ := http.DefaultClient.Do(req) done <- res