test(kube): add test for upgrade

pull/1657/head
Adam Reese 8 years ago
parent 74361b1f3a
commit fb9ef50bc8

@ -18,17 +18,15 @@ package kube
import (
"bytes"
"encoding/json"
"io"
"io/ioutil"
"net/http"
"strings"
"testing"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/api/unversioned"
api "k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/api/validation"
"k8s.io/kubernetes/pkg/client/restclient/fake"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
@ -36,34 +34,106 @@ import (
"k8s.io/kubernetes/pkg/runtime"
)
func TestUpdateResource(t *testing.T) {
func objBody(codec runtime.Codec, obj runtime.Object) io.ReadCloser {
return ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(codec, obj))))
}
tests := []struct {
name string
namespace string
modified *resource.Info
currentObj runtime.Object
err bool
errMessage string
}{
{
name: "no changes when updating resources",
modified: createFakeInfo("nginx", nil),
currentObj: createFakePod("nginx", nil),
err: true,
errMessage: "Looks like there are no changes for nginx",
func newPod(name string) api.Pod {
return api.Pod{
ObjectMeta: api.ObjectMeta{Name: name},
Spec: api.PodSpec{
Containers: []api.Container{{
Name: "app:v4",
Image: "abc/app:v4",
Ports: []api.ContainerPort{{Name: "http", ContainerPort: 80}},
}},
},
//{
//name: "valid update input",
//modified: createFakeInfo("nginx", map[string]string{"app": "nginx"}),
//currentObj: createFakePod("nginx", nil),
//},
}
}
for _, tt := range tests {
err := updateResource(tt.modified, tt.currentObj)
if err != nil && err.Error() != tt.errMessage {
t.Errorf("%q. expected error message: %v, got %v", tt.name, tt.errMessage, err)
func newPodList(names ...string) api.PodList {
var list api.PodList
for _, name := range names {
list.Items = append(list.Items, newPod(name))
}
return list
}
func notFoundBody() *unversioned.Status {
return &unversioned.Status{
Code: http.StatusNotFound,
Status: unversioned.StatusFailure,
Reason: unversioned.StatusReasonNotFound,
Message: " \"\" not found",
Details: &unversioned.StatusDetails{},
}
}
func newResponse(code int, obj runtime.Object) (*http.Response, error) {
header := http.Header{}
header.Set("Content-Type", runtime.ContentTypeJSON)
body := ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), obj))))
return &http.Response{StatusCode: code, Header: header, Body: body}, nil
}
func TestUpdate(t *testing.T) {
listA := newPodList("starfish", "otter", "squid")
listB := newPodList("starfish", "otter", "dolphin")
listB.Items[0].Spec.Containers[0].Ports = []api.ContainerPort{{Name: "https", ContainerPort: 443}}
actions := make(map[string]string)
f, tf, codec, ns := cmdtesting.NewAPIFactory()
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
p, m := req.URL.Path, req.Method
actions[p] = m
switch {
case p == "/namespaces/test/pods/starfish" && m == "GET":
return newResponse(200, &listA.Items[0])
case p == "/namespaces/test/pods/otter" && m == "GET":
return newResponse(200, &listA.Items[1])
case p == "/namespaces/test/pods/dolphin" && m == "GET":
return newResponse(404, notFoundBody())
case p == "/namespaces/test/pods/starfish" && m == "PATCH":
data, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Fatalf("could not dump request: %s", err)
}
req.Body.Close()
expected := `{"spec":{"containers":[{"name":"app:v4","ports":[{"containerPort":443,"name":"https","protocol":"TCP"},{"$patch":"delete","containerPort":80}]}]}}`
if string(data) != expected {
t.Errorf("expected patch %s, got %s", expected, string(data))
}
return newResponse(200, &listB.Items[0])
case p == "/namespaces/test/pods" && m == "POST":
return newResponse(200, &listB.Items[1])
case p == "/namespaces/test/pods/squid" && m == "DELETE":
return newResponse(200, &listB.Items[1])
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
}),
}
c := &Client{Factory: f}
if err := c.Update("test", objBody(codec, &listA), objBody(codec, &listB)); err != nil {
t.Fatal(err)
}
expectedActions := map[string]string{
"/namespaces/test/pods/dolphin": "GET",
"/namespaces/test/pods/otter": "GET",
"/namespaces/test/pods/starfish": "PATCH",
"/namespaces/test/pods": "POST",
"/namespaces/test/pods/squid": "DELETE",
}
for k, v := range expectedActions {
if m, ok := actions[k]; !ok || m != v {
t.Errorf("expected a %s request to %s", k, v)
}
}
}
@ -319,52 +389,3 @@ spec:
ports:
- containerPort: 80
`
func createFakePod(name string, labels map[string]string) runtime.Object {
objectMeta := createObjectMeta(name, labels)
object := &api.Pod{
ObjectMeta: objectMeta,
}
return object
}
func createFakeInfo(name string, labels map[string]string) *resource.Info {
pod := createFakePod(name, labels)
marshaledObj, _ := json.Marshal(pod)
mapping := &meta.RESTMapping{
Resource: name,
Scope: meta.RESTScopeNamespace,
GroupVersionKind: unversioned.GroupVersionKind{
Kind: "Pod",
Version: "v1",
}}
client := &fake.RESTClient{
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
header := http.Header{}
header.Set("Content-Type", runtime.ContentTypeJSON)
return &http.Response{
StatusCode: 200,
Header: header,
Body: ioutil.NopCloser(bytes.NewReader(marshaledObj)),
}, nil
})}
info := resource.NewInfo(client, mapping, "default", "nginx", false)
info.Object = pod
return info
}
func createObjectMeta(name string, labels map[string]string) api.ObjectMeta {
objectMeta := api.ObjectMeta{Name: name, Namespace: "default"}
if labels != nil {
objectMeta.Labels = labels
}
return objectMeta
}

Loading…
Cancel
Save