165 lines
4.7 KiB
Go
165 lines
4.7 KiB
Go
package ipam
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"math/rand"
|
|
"net/http"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gorilla/mux"
|
|
|
|
"github.com/weaveworks/weave/common"
|
|
wt "github.com/weaveworks/weave/testing"
|
|
)
|
|
|
|
func HTTPPost(t *testing.T, url string) string {
|
|
resp, err := http.Post(url, "", nil)
|
|
wt.AssertNoErr(t, err)
|
|
wt.AssertStatus(t, resp.StatusCode, http.StatusOK, "http response")
|
|
defer resp.Body.Close()
|
|
body, _ := ioutil.ReadAll(resp.Body)
|
|
return string(body)
|
|
}
|
|
|
|
func doHTTP(method string, url string) (resp *http.Response, err error) {
|
|
req, _ := http.NewRequest(method, url, nil)
|
|
return http.DefaultClient.Do(req)
|
|
}
|
|
|
|
func listenHTTP(port int, alloc *Allocator) {
|
|
router := mux.NewRouter()
|
|
router.HandleFunc("/status", func(w http.ResponseWriter, r *http.Request) {
|
|
io.WriteString(w, fmt.Sprintln(alloc))
|
|
})
|
|
alloc.HandleHTTP(router)
|
|
|
|
srv := &http.Server{
|
|
Addr: fmt.Sprintf(":%d", port),
|
|
Handler: router,
|
|
}
|
|
if err := srv.ListenAndServe(); err != nil {
|
|
common.Error.Fatal("Unable to create http listener: ", err)
|
|
}
|
|
}
|
|
|
|
func allocURL(port int, containerID string) string {
|
|
return fmt.Sprintf("http://localhost:%d/ip/%s", port, containerID)
|
|
}
|
|
|
|
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
|
|
)
|
|
|
|
alloc := makeAllocatorWithMockGossip(t, "08:00:27:01:c3:9a", testCIDR1, 1)
|
|
port := rand.Intn(10000) + 32768
|
|
fmt.Println("Http test on port", port)
|
|
go listenHTTP(port, alloc)
|
|
|
|
time.Sleep(100 * time.Millisecond) // Allow for http server to get going
|
|
|
|
alloc.claimRingForTesting()
|
|
// Ask the http server for a new address
|
|
cidr1 := HTTPPost(t, allocURL(port, containerID))
|
|
wt.AssertEqualString(t, cidr1, testAddr1+netSuffix, "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")
|
|
|
|
// 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))
|
|
cidr3 := HTTPPost(t, allocURL(port, container3))
|
|
wt.AssertEqualString(t, cidr3, testAddr1+netSuffix, "address")
|
|
|
|
// Would like to shut down the http server at the end of this test
|
|
// but it's complicated.
|
|
// See https://groups.google.com/forum/#!topic/golang-nuts/vLHWa5sHnCE
|
|
}
|
|
|
|
func TestBadHttp(t *testing.T) {
|
|
var (
|
|
containerID = "deadbeef"
|
|
testCIDR1 = "10.0.0.0/8"
|
|
)
|
|
|
|
alloc := makeAllocatorWithMockGossip(t, "08:00:27:01:c3:9a", testCIDR1, 1)
|
|
defer alloc.Stop()
|
|
port := rand.Intn(10000) + 32768
|
|
fmt.Println("BadHttp test on port", port)
|
|
go listenHTTP(port, alloc)
|
|
|
|
alloc.claimRingForTesting()
|
|
cidr1 := HTTPPost(t, allocURL(port, containerID))
|
|
parts := strings.Split(cidr1, "/")
|
|
testAddr1 := parts[0]
|
|
// Verb that's not handled
|
|
resp, err := doHTTP("HEAD", fmt.Sprintf("http://localhost:%d/ip/%s/%s", port, containerID, testAddr1))
|
|
wt.AssertNoErr(t, err)
|
|
wt.AssertStatus(t, resp.StatusCode, http.StatusNotFound, "http response")
|
|
// Mis-spelled URL
|
|
resp, err = doHTTP("POST", fmt.Sprintf("http://localhost:%d/xip/%s/", port, containerID))
|
|
wt.AssertNoErr(t, err)
|
|
wt.AssertStatus(t, resp.StatusCode, http.StatusNotFound, "http response")
|
|
// Malformed URL
|
|
resp, err = doHTTP("POST", fmt.Sprintf("http://localhost:%d/ip/%s/foo/bar/baz", port, containerID))
|
|
wt.AssertNoErr(t, err)
|
|
wt.AssertStatus(t, resp.StatusCode, http.StatusNotFound, "http response")
|
|
}
|
|
|
|
func TestHTTPCancel(t *testing.T) {
|
|
wt.RunWithTimeout(t, 2*time.Second, func() {
|
|
impTestHTTPCancel(t)
|
|
})
|
|
}
|
|
|
|
func impTestHTTPCancel(t *testing.T) {
|
|
common.InitDefaultLogging(true)
|
|
var (
|
|
containerID = "deadbeef"
|
|
testCIDR1 = "10.0.3.5/29"
|
|
)
|
|
|
|
alloc := makeAllocatorWithMockGossip(t, "08:00:27:01:c3:9a", testCIDR1, 1)
|
|
defer alloc.Stop()
|
|
alloc.claimRingForTesting()
|
|
port := rand.Intn(10000) + 32768
|
|
fmt.Println("Http test on port", port)
|
|
go listenHTTP(port, alloc)
|
|
|
|
time.Sleep(100 * time.Millisecond) // Allow for http server to get going
|
|
|
|
// Stop the alloc so nothing actually works
|
|
unpause := alloc.pause()
|
|
|
|
// Ask the http server for a new address
|
|
done := make(chan *http.Response)
|
|
req, _ := http.NewRequest("POST", allocURL(port, containerID), nil)
|
|
go func() {
|
|
res, _ := http.DefaultClient.Do(req)
|
|
done <- res
|
|
}()
|
|
|
|
time.Sleep(100 * time.Millisecond)
|
|
fmt.Println("Cancelling allocate")
|
|
http.DefaultTransport.(*http.Transport).CancelRequest(req)
|
|
unpause()
|
|
res := <-done
|
|
if res != nil {
|
|
wt.Fatalf(t, "Error: Allocate returned non-nil")
|
|
}
|
|
}
|