pkg/client: refactor tests

This commit is contained in:
Johan Euphrosine 2014-06-07 04:38:16 -07:00
parent ba7fe835ce
commit fe589a3f64
3 changed files with 278 additions and 252 deletions

View File

@ -17,6 +17,7 @@ package client
import ( import (
"encoding/json" "encoding/json"
"net/http"
"net/http/httptest" "net/http/httptest"
"net/url" "net/url"
"reflect" "reflect"
@ -26,13 +27,6 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
) )
// TODO: This doesn't reduce typing enough to make it worth the less readable errors. Remove.
func expectNoError(t *testing.T, err error) {
if err != nil {
t.Errorf("Unexpected error: %#v", err)
}
}
// TODO: Move this to a common place, it's needed in multiple tests. // TODO: Move this to a common place, it's needed in multiple tests.
var apiPath = "/api/v1beta1" var apiPath = "/api/v1beta1"
@ -41,63 +35,68 @@ func makeUrl(suffix string) string {
} }
func TestListEmptyPods(t *testing.T) { func TestListEmptyPods(t *testing.T) {
fakeHandler := util.FakeHandler{ c := &TestClient{
StatusCode: 200, Request: Request{Method: "GET", Path: "/pods"},
ResponseBody: `{ "items": []}`, Response: Response{StatusCode: 200, Body: api.PodList{}},
} }
testServer := httptest.NewTLSServer(&fakeHandler) podList, err := c.Setup().ListPods(nil)
client := Client{ c.Validate(t, podList, err)
Host: testServer.URL,
}
podList, err := client.ListPods(nil)
fakeHandler.ValidateRequest(t, makeUrl("/pods"), "GET", nil)
if err != nil {
t.Errorf("Unexpected error in listing pods: %#v", err)
}
if len(podList.Items) != 0 {
t.Errorf("Unexpected items in pod list: %#v", podList)
}
testServer.Close()
} }
func TestListPods(t *testing.T) { func TestListPods(t *testing.T) {
expectedPodList := api.PodList{ c := &TestClient{
Items: []api.Pod{ Request: Request{Method: "GET", Path: "/pods"},
{ Response: Response{StatusCode: 200,
CurrentState: api.PodState{ Body: api.PodList{
Status: "Foobar", Items: []api.Pod{
}, {
Labels: map[string]string{ CurrentState: api.PodState{
"foo": "bar", Status: "Foobar",
"name": "baz", },
Labels: map[string]string{
"foo": "bar",
"name": "baz",
},
},
}, },
}, },
}, },
} }
body, _ := json.Marshal(expectedPodList) receivedPodList, err := c.Setup().ListPods(nil)
fakeHandler := util.FakeHandler{ c.Validate(t, receivedPodList, err)
StatusCode: 200,
ResponseBody: string(body),
}
testServer := httptest.NewTLSServer(&fakeHandler)
client := Client{
Host: testServer.URL,
}
receivedPodList, err := client.ListPods(nil)
fakeHandler.ValidateRequest(t, makeUrl("/pods"), "GET", nil)
if err != nil {
t.Errorf("Unexpected error in listing pods: %#v", err)
}
if !reflect.DeepEqual(expectedPodList, receivedPodList) {
t.Errorf("Unexpected pod list: %#v\nvs.\n%#v", receivedPodList, expectedPodList)
}
testServer.Close()
} }
func TestListPodsLabels(t *testing.T) { func TestListPodsLabels(t *testing.T) {
expectedPodList := api.PodList{ c := &TestClient{
Items: []api.Pod{ Request: Request{Method: "GET", Path: "/pods", Query: url.Values{"labels": []string{"foo=bar,name=baz"}}},
{ Response: Response{
StatusCode: 200,
Body: api.PodList{
Items: []api.Pod{
{
CurrentState: api.PodState{
Status: "Foobar",
},
Labels: map[string]string{
"foo": "bar",
"name": "baz",
},
},
},
},
},
}
selector := map[string]string{"foo": "bar", "name": "baz"}
receivedPodList, err := c.Setup().ListPods(selector)
c.Validate(t, receivedPodList, err)
}
func TestGetPod(t *testing.T) {
c := &TestClient{
Request: Request{Method: "GET", Path: "/pods/foo"},
Response: Response{
StatusCode: 200,
Body: api.Pod{
CurrentState: api.PodState{ CurrentState: api.PodState{
Status: "Foobar", Status: "Foobar",
}, },
@ -108,76 +107,17 @@ func TestListPodsLabels(t *testing.T) {
}, },
}, },
} }
body, _ := json.Marshal(expectedPodList) receivedPod, err := c.Setup().GetPod("foo")
fakeHandler := util.FakeHandler{ c.Validate(t, receivedPod, err)
StatusCode: 200,
ResponseBody: string(body),
}
testServer := httptest.NewTLSServer(&fakeHandler)
client := Client{
Host: testServer.URL,
}
selector := map[string]string{"foo": "bar", "name": "baz"}
receivedPodList, err := client.ListPods(selector)
fakeHandler.ValidateRequest(t, makeUrl("/pods"), "GET", nil)
selectorString := fakeHandler.RequestReceived.URL.Query().Get("labels")
selectorString, _ = url.QueryUnescape(selectorString)
parsedSelectorString := DecodeSelector(selectorString)
expectEqual(t, selector, parsedSelectorString)
if err != nil {
t.Errorf("Unexpected error in listing pods: %#v", err)
}
if !reflect.DeepEqual(expectedPodList, receivedPodList) {
t.Errorf("Unexpected pod list: %#v\nvs.\n%#v", receivedPodList, expectedPodList)
}
testServer.Close()
}
func TestGetPod(t *testing.T) {
expectedPod := api.Pod{
CurrentState: api.PodState{
Status: "Foobar",
},
Labels: map[string]string{
"foo": "bar",
"name": "baz",
},
}
body, _ := json.Marshal(expectedPod)
fakeHandler := util.FakeHandler{
StatusCode: 200,
ResponseBody: string(body),
}
testServer := httptest.NewTLSServer(&fakeHandler)
client := Client{
Host: testServer.URL,
}
receivedPod, err := client.GetPod("foo")
fakeHandler.ValidateRequest(t, makeUrl("/pods/foo"), "GET", nil)
if err != nil {
t.Errorf("Unexpected error: %#v", err)
}
if !reflect.DeepEqual(expectedPod, receivedPod) {
t.Errorf("Received pod: %#v\n doesn't match expected pod: %#v", receivedPod, expectedPod)
}
testServer.Close()
} }
func TestDeletePod(t *testing.T) { func TestDeletePod(t *testing.T) {
fakeHandler := util.FakeHandler{ c := &TestClient{
StatusCode: 200, Request: Request{Method: "DELETE", Path: "/pods/foo"},
ResponseBody: `{"success": true}`, Response: Response{StatusCode: 200},
} }
testServer := httptest.NewTLSServer(&fakeHandler) err := c.Setup().DeletePod("foo")
client := Client{ c.Validate(t, nil, err)
Host: testServer.URL,
}
err := client.DeletePod("foo")
fakeHandler.ValidateRequest(t, makeUrl("/pods/foo"), "DELETE", nil)
if err != nil {
t.Errorf("Unexpected error: %#v", err)
}
testServer.Close()
} }
func TestCreatePod(t *testing.T) { func TestCreatePod(t *testing.T) {
@ -190,24 +130,15 @@ func TestCreatePod(t *testing.T) {
"name": "baz", "name": "baz",
}, },
} }
body, _ := json.Marshal(requestPod) c := &TestClient{
fakeHandler := util.FakeHandler{ Request: Request{Method: "POST", Path: "/pods", Body: requestPod},
StatusCode: 200, Response: Response{
ResponseBody: string(body), StatusCode: 200,
Body: requestPod,
},
} }
testServer := httptest.NewTLSServer(&fakeHandler) receivedPod, err := c.Setup().CreatePod(requestPod)
client := Client{ c.Validate(t, receivedPod, err)
Host: testServer.URL,
}
receivedPod, err := client.CreatePod(requestPod)
fakeHandler.ValidateRequest(t, makeUrl("/pods"), "POST", nil)
if err != nil {
t.Errorf("Unexpected error: %#v", err)
}
if !reflect.DeepEqual(requestPod, receivedPod) {
t.Errorf("Received pod: %#v\n doesn't match expected pod: %#v", receivedPod, requestPod)
}
testServer.Close()
} }
func TestUpdatePod(t *testing.T) { func TestUpdatePod(t *testing.T) {
@ -221,144 +152,232 @@ func TestUpdatePod(t *testing.T) {
"name": "baz", "name": "baz",
}, },
} }
body, _ := json.Marshal(requestPod) c := &TestClient{
fakeHandler := util.FakeHandler{ Request: Request{Method: "PUT", Path: "/pods/foo"},
StatusCode: 200, Response: Response{StatusCode: 200, Body: requestPod},
ResponseBody: string(body),
}
testServer := httptest.NewTLSServer(&fakeHandler)
client := Client{
Host: testServer.URL,
}
receivedPod, err := client.UpdatePod(requestPod)
fakeHandler.ValidateRequest(t, makeUrl("/pods/foo"), "PUT", nil)
if err != nil {
t.Errorf("Unexpected error: %#v", err)
}
expectEqual(t, requestPod, receivedPod)
testServer.Close()
}
func expectEqual(t *testing.T, expected, observed interface{}) {
if !reflect.DeepEqual(expected, observed) {
t.Errorf("Unexpected inequality. Expected: %#v Observed: %#v", expected, observed)
} }
receivedPod, err := c.Setup().UpdatePod(requestPod)
c.Validate(t, receivedPod, err)
} }
func TestGetController(t *testing.T) { func TestGetController(t *testing.T) {
expectedController := api.ReplicationController{ c := &TestClient{
JSONBase: api.JSONBase{ Request: Request{Method: "GET", Path: "/replicationControllers/foo"},
ID: "foo", Response: Response{
}, StatusCode: 200,
DesiredState: api.ReplicationControllerState{ Body: api.ReplicationController{
Replicas: 2, JSONBase: api.JSONBase{
}, ID: "foo",
Labels: map[string]string{ },
"foo": "bar", DesiredState: api.ReplicationControllerState{
"name": "baz", Replicas: 2,
},
Labels: map[string]string{
"foo": "bar",
"name": "baz",
},
},
}, },
} }
body, _ := json.Marshal(expectedController) receivedController, err := c.Setup().GetReplicationController("foo")
fakeHandler := util.FakeHandler{ c.Validate(t, receivedController, err)
StatusCode: 200,
ResponseBody: string(body),
}
testServer := httptest.NewTLSServer(&fakeHandler)
client := Client{
Host: testServer.URL,
}
receivedController, err := client.GetReplicationController("foo")
expectNoError(t, err)
if !reflect.DeepEqual(expectedController, receivedController) {
t.Errorf("Unexpected controller, expected: %#v, received %#v", expectedController, receivedController)
}
fakeHandler.ValidateRequest(t, makeUrl("/replicationControllers/foo"), "GET", nil)
testServer.Close()
} }
func TestUpdateController(t *testing.T) { func TestUpdateController(t *testing.T) {
expectedController := api.ReplicationController{ requestController := api.ReplicationController{
JSONBase: api.JSONBase{ JSONBase: api.JSONBase{
ID: "foo", ID: "foo",
}, },
DesiredState: api.ReplicationControllerState{ }
Replicas: 2, c := &TestClient{
}, Request: Request{Method: "PUT", Path: "/replicationControllers/foo"},
Labels: map[string]string{ Response: Response{
"foo": "bar", StatusCode: 200,
"name": "baz", Body: api.ReplicationController{
JSONBase: api.JSONBase{
ID: "foo",
},
DesiredState: api.ReplicationControllerState{
Replicas: 2,
},
Labels: map[string]string{
"foo": "bar",
"name": "baz",
},
},
}, },
} }
body, _ := json.Marshal(expectedController) receivedController, err := c.Setup().UpdateReplicationController(requestController)
fakeHandler := util.FakeHandler{ c.Validate(t, receivedController, err)
StatusCode: 200,
ResponseBody: string(body),
}
testServer := httptest.NewTLSServer(&fakeHandler)
client := Client{
Host: testServer.URL,
}
receivedController, err := client.UpdateReplicationController(api.ReplicationController{
JSONBase: api.JSONBase{
ID: "foo",
},
})
expectNoError(t, err)
if !reflect.DeepEqual(expectedController, receivedController) {
t.Errorf("Unexpected controller, expected: %#v, received %#v", expectedController, receivedController)
}
fakeHandler.ValidateRequest(t, makeUrl("/replicationControllers/foo"), "PUT", nil)
testServer.Close()
} }
func TestDeleteController(t *testing.T) { func TestDeleteController(t *testing.T) {
fakeHandler := util.FakeHandler{ c := &TestClient{
StatusCode: 200, Request: Request{Method: "DELETE", Path: "/replicationControllers/foo"},
ResponseBody: `{"success": true}`, Response: Response{StatusCode: 200},
} }
testServer := httptest.NewTLSServer(&fakeHandler) err := c.Setup().DeleteReplicationController("foo")
client := Client{ c.Validate(t, nil, err)
Host: testServer.URL,
}
err := client.DeleteReplicationController("foo")
fakeHandler.ValidateRequest(t, makeUrl("/replicationControllers/foo"), "DELETE", nil)
if err != nil {
t.Errorf("Unexpected error: %#v", err)
}
testServer.Close()
} }
func TestCreateController(t *testing.T) { func TestCreateController(t *testing.T) {
expectedController := api.ReplicationController{ requestController := api.ReplicationController{
JSONBase: api.JSONBase{ JSONBase: api.JSONBase{
ID: "foo", ID: "foo",
}, },
DesiredState: api.ReplicationControllerState{ }
Replicas: 2, c := &TestClient{
}, Request: Request{Method: "POST", Path: "/replicationControllers", Body: requestController},
Labels: map[string]string{ Response: Response{
"foo": "bar", StatusCode: 200,
"name": "baz", Body: api.ReplicationController{
JSONBase: api.JSONBase{
ID: "foo",
},
DesiredState: api.ReplicationControllerState{
Replicas: 2,
},
Labels: map[string]string{
"foo": "bar",
"name": "baz",
},
},
}, },
} }
body, _ := json.Marshal(expectedController) receivedController, err := c.Setup().CreateReplicationController(requestController)
fakeHandler := util.FakeHandler{ c.Validate(t, receivedController, err)
StatusCode: 200, }
ResponseBody: string(body),
} func body(obj interface{}, raw *string) *string {
testServer := httptest.NewTLSServer(&fakeHandler) if obj != nil {
client := Client{ bs, _ := json.Marshal(obj)
Host: testServer.URL, body := string(bs)
} return &body
receivedController, err := client.CreateReplicationController(api.ReplicationController{ }
JSONBase: api.JSONBase{ return raw
ID: "foo", }
},
}) type Request struct {
expectNoError(t, err) Method string
if !reflect.DeepEqual(expectedController, receivedController) { Path string
t.Errorf("Unexpected controller, expected: %#v, received %#v", expectedController, receivedController) Header string
} Query url.Values
fakeHandler.ValidateRequest(t, makeUrl("/replicationControllers"), "POST", nil) Body interface{}
testServer.Close() RawBody *string
}
type Response struct {
StatusCode int
Body interface{}
RawBody *string
}
type TestClient struct {
*Client
Request Request
Response Response
Error bool
server *httptest.Server
handler *util.FakeHandler
Target interface{}
}
func (c *TestClient) Setup() *TestClient {
c.handler = &util.FakeHandler{
StatusCode: c.Response.StatusCode,
}
if responseBody := body(c.Response.Body, c.Response.RawBody); responseBody != nil {
c.handler.ResponseBody = *responseBody
}
c.server = httptest.NewTLSServer(c.handler)
if c.Client == nil {
c.Client = &Client{}
}
c.Client.Host = c.server.URL
return c
}
func (c *TestClient) Validate(t *testing.T, received interface{}, err error) {
defer c.server.Close()
if c.Error {
if err == nil {
t.Errorf("error expeced for %#v, got none", c.Request)
}
return
}
if err != nil {
t.Errorf("no error expected for %#v, got: %v", c.Request, err)
}
requestBody := body(c.Request.Body, c.Request.RawBody)
c.handler.ValidateRequest(t, makeUrl(c.Request.Path), c.Request.Method, requestBody)
if expected, received := c.Request.Query.Encode(), c.handler.RequestReceived.URL.Query().Encode(); expected != received {
t.Errorf("bad query for request %#v: expected %s, got %s", c.Request, expected, received)
}
if c.Request.Header != "" {
if c.handler.RequestReceived.Header.Get(c.Request.Header) == "" {
t.Errorf("header %q not found in request %#v", c.Request.Header, c.handler.RequestReceived)
}
}
if expected, received := requestBody, c.handler.RequestBody; expected != nil && *expected != received {
t.Errorf("bad body for request %#v: expected %s, got %s", c.Request, expected, received)
}
if c.Response.Body != nil && !reflect.DeepEqual(c.Response.Body, received) {
t.Errorf("bad response for request %#v: expeced %s, got %s", c.Request, c.Response.Body, received)
}
}
func TestGetService(t *testing.T) {
c := &TestClient{
Request: Request{Method: "GET", Path: "/services/1"},
Response: Response{StatusCode: 200, Body: &api.Service{JSONBase: api.JSONBase{ID: "service-1"}}},
}
response, err := c.Setup().GetService("1")
c.Validate(t, &response, err)
}
func TestCreateService(t *testing.T) {
c := (&TestClient{
Request: Request{Method: "POST", Path: "/services", Body: &api.Service{JSONBase: api.JSONBase{ID: "service-1"}}},
Response: Response{StatusCode: 200, Body: &api.Service{JSONBase: api.JSONBase{ID: "service-1"}}},
}).Setup()
response, err := c.Setup().CreateService(api.Service{JSONBase: api.JSONBase{ID: "service-1"}})
c.Validate(t, &response, err)
}
func TestUpdateService(t *testing.T) {
c := &TestClient{
Request: Request{Method: "PUT", Path: "/services/service-1", Body: &api.Service{JSONBase: api.JSONBase{ID: "service-1"}}},
Response: Response{StatusCode: 200, Body: &api.Service{JSONBase: api.JSONBase{ID: "service-1"}}},
}
response, err := c.Setup().UpdateService(api.Service{JSONBase: api.JSONBase{ID: "service-1"}})
c.Validate(t, &response, err)
}
func TestDeleteService(t *testing.T) {
c := &TestClient{
Request: Request{Method: "DELETE", Path: "/services/1"},
Response: Response{StatusCode: 200},
}
err := c.Setup().DeleteService("1")
c.Validate(t, nil, err)
}
func TestMakeRequest(t *testing.T) {
testClients := []TestClient{
{Request: Request{Method: "GET", Path: "/good"}, Response: Response{StatusCode: 200}},
{Request: Request{Method: "GET", Path: "/bad%ZZ"}, Error: true},
{Client: &Client{Auth: &AuthInfo{"foo", "bar"}}, Request: Request{Method: "GET", Path: "/auth", Header: "Authorization"}, Response: Response{StatusCode: 200}},
{Client: &Client{httpClient: http.DefaultClient}, Request: Request{Method: "GET", Path: "/nocertificate"}, Error: true},
{Request: Request{Method: "GET", Path: "/error"}, Response: Response{StatusCode: 500}, Error: true},
{Request: Request{Method: "POST", Path: "/faildecode"}, Response: Response{StatusCode: 200, Body: "aaaaa"}, Target: &struct{}{}, Error: true},
{Request: Request{Method: "GET", Path: "/failread"}, Response: Response{StatusCode: 200, Body: "aaaaa"}, Target: &struct{}{}, Error: true},
}
for _, c := range testClients {
response, err := c.Setup().rawRequest(c.Request.Method, c.Request.Path[1:], nil, c.Target)
c.Validate(t, response, err)
}
} }

View File

@ -27,6 +27,13 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
) )
// TODO: This doesn't reduce typing enough to make it worth the less readable errors. Remove.
func expectNoError(t *testing.T, err error) {
if err != nil {
t.Errorf("Unexpected error: %#v", err)
}
}
func TestHTTPContainerInfo(t *testing.T) { func TestHTTPContainerInfo(t *testing.T) {
body := `{"items":[]}` body := `{"items":[]}`
fakeHandler := util.FakeHandler{ fakeHandler := util.FakeHandler{

View File

@ -54,10 +54,10 @@ func (f *FakeHandler) ServeHTTP(response http.ResponseWriter, request *http.Requ
func (f FakeHandler) ValidateRequest(t TestInterface, expectedPath, expectedMethod string, body *string) { func (f FakeHandler) ValidateRequest(t TestInterface, expectedPath, expectedMethod string, body *string) {
if f.RequestReceived.URL.Path != expectedPath { if f.RequestReceived.URL.Path != expectedPath {
t.Errorf("Unexpected request path: %s", f.RequestReceived.URL.Path) t.Errorf("Unexpected request path for request %#v, received: %q, expected: %q", f.RequestReceived, f.RequestReceived.URL.Path, expectedPath)
} }
if f.RequestReceived.Method != expectedMethod { if f.RequestReceived.Method != expectedMethod {
t.Errorf("Unexpected method: %s", f.RequestReceived.Method) t.Errorf("Unexpected method: %q, expected: %q", f.RequestReceived.Method, expectedMethod)
} }
if body != nil { if body != nil {
if *body != f.RequestBody { if *body != f.RequestBody {