Commit 45ca956f authored by k8s-merge-robot's avatar k8s-merge-robot

Merge pull request #13201 from wojtek-t/refactor_etcd_update_test

Auto commit by PR queue bot
parents f1acdbe3 836be0c4
...@@ -36,10 +36,11 @@ import ( ...@@ -36,10 +36,11 @@ import (
type Tester struct { type Tester struct {
*testing.T *testing.T
storage rest.Storage storage rest.Storage
storageError injectErrorFunc storageError injectErrorFunc
clusterScope bool clusterScope bool
generatesName bool createOnUpdate bool
generatesName bool
} }
type injectErrorFunc func(err error) type injectErrorFunc func(err error)
...@@ -63,6 +64,11 @@ func (t *Tester) ClusterScope() *Tester { ...@@ -63,6 +64,11 @@ func (t *Tester) ClusterScope() *Tester {
return t return t
} }
func (t *Tester) AllowCreateOnUpdate() *Tester {
t.createOnUpdate = true
return t
}
func (t *Tester) GeneratesName() *Tester { func (t *Tester) GeneratesName() *Tester {
t.generatesName = true t.generatesName = true
return t return t
...@@ -94,6 +100,17 @@ func (t *Tester) getObjectMetaOrFail(obj runtime.Object) *api.ObjectMeta { ...@@ -94,6 +100,17 @@ func (t *Tester) getObjectMetaOrFail(obj runtime.Object) *api.ObjectMeta {
return meta return meta
} }
func (t *Tester) setObjectMeta(obj runtime.Object, name string) {
meta := t.getObjectMetaOrFail(obj)
meta.Name = name
if t.clusterScope {
meta.Namespace = api.NamespaceNone
} else {
meta.Namespace = api.NamespaceValue(t.TestContext())
}
meta.GenerateName = ""
}
func copyOrDie(obj runtime.Object) runtime.Object { func copyOrDie(obj runtime.Object) runtime.Object {
out, err := api.Scheme.Copy(obj) out, err := api.Scheme.Copy(obj)
if err != nil { if err != nil {
...@@ -106,6 +123,7 @@ type AssignFunc func([]runtime.Object) []runtime.Object ...@@ -106,6 +123,7 @@ type AssignFunc func([]runtime.Object) []runtime.Object
type GetFunc func(api.Context, runtime.Object) (runtime.Object, error) type GetFunc func(api.Context, runtime.Object) (runtime.Object, error)
type SetFunc func(api.Context, runtime.Object) error type SetFunc func(api.Context, runtime.Object) error
type SetRVFunc func(uint64) type SetRVFunc func(uint64)
type UpdateFunc func(runtime.Object) runtime.Object
// Test creating an object. // Test creating an object.
func (t *Tester) TestCreate(valid runtime.Object, setFn SetFunc, getFn GetFunc, invalid ...runtime.Object) { func (t *Tester) TestCreate(valid runtime.Object, setFn SetFunc, getFn GetFunc, invalid ...runtime.Object) {
...@@ -127,9 +145,14 @@ func (t *Tester) TestCreate(valid runtime.Object, setFn SetFunc, getFn GetFunc, ...@@ -127,9 +145,14 @@ func (t *Tester) TestCreate(valid runtime.Object, setFn SetFunc, getFn GetFunc,
} }
// Test updating an object. // Test updating an object.
func (t *Tester) TestUpdate(valid runtime.Object, existing, older runtime.Object) { func (t *Tester) TestUpdate(valid runtime.Object, setFn SetFunc, setRVFn SetRVFunc, getFn GetFunc, updateFn UpdateFunc, invalidUpdateFn ...UpdateFunc) {
t.testUpdateFailsOnNotFound(copyOrDie(valid)) t.testUpdateEquals(copyOrDie(valid), setFn, getFn, updateFn)
t.testUpdateFailsOnVersion(copyOrDie(older)) t.testUpdateFailsOnVersionTooOld(copyOrDie(valid), setFn, setRVFn)
t.testUpdateOnNotFound(copyOrDie(valid))
if !t.clusterScope {
t.testUpdateRejectsMismatchedNamespace(copyOrDie(valid), setFn)
}
t.testUpdateInvokesValidation(copyOrDie(valid), setFn, invalidUpdateFn...)
} }
// Test deleting an object. // Test deleting an object.
...@@ -177,10 +200,7 @@ func (t *Tester) testCreateAlreadyExisting(obj runtime.Object, setFn SetFunc) { ...@@ -177,10 +200,7 @@ func (t *Tester) testCreateAlreadyExisting(obj runtime.Object, setFn SetFunc) {
ctx := t.TestContext() ctx := t.TestContext()
foo := copyOrDie(obj) foo := copyOrDie(obj)
fooMeta := t.getObjectMetaOrFail(foo) t.setObjectMeta(foo, "foo1")
fooMeta.Name = "foo1"
fooMeta.Namespace = api.NamespaceValue(ctx)
fooMeta.GenerateName = ""
if err := setFn(ctx, foo); err != nil { if err := setFn(ctx, foo); err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
...@@ -195,10 +215,7 @@ func (t *Tester) testCreateEquals(obj runtime.Object, getFn GetFunc) { ...@@ -195,10 +215,7 @@ func (t *Tester) testCreateEquals(obj runtime.Object, getFn GetFunc) {
ctx := t.TestContext() ctx := t.TestContext()
foo := copyOrDie(obj) foo := copyOrDie(obj)
fooMeta := t.getObjectMetaOrFail(foo) t.setObjectMeta(foo, "foo2")
fooMeta.Name = "foo2"
fooMeta.Namespace = api.NamespaceValue(ctx)
fooMeta.GenerateName = ""
created, err := t.storage.(rest.Creater).Create(ctx, foo) created, err := t.storage.(rest.Creater).Create(ctx, foo)
if err != nil { if err != nil {
...@@ -357,16 +374,56 @@ func (t *Tester) testCreateResetsUserData(valid runtime.Object) { ...@@ -357,16 +374,56 @@ func (t *Tester) testCreateResetsUserData(valid runtime.Object) {
// ============================================================================= // =============================================================================
// Update tests. // Update tests.
func (t *Tester) testUpdateFailsOnNotFound(valid runtime.Object) { func (t *Tester) testUpdateEquals(obj runtime.Object, setFn SetFunc, getFn GetFunc, updateFn UpdateFunc) {
_, _, err := t.storage.(rest.Updater).Update(t.TestContext(), valid) ctx := t.TestContext()
if err == nil {
t.Errorf("Expected an error, but we didn't get one") foo := copyOrDie(obj)
} else if !errors.IsNotFound(err) { t.setObjectMeta(foo, "foo2")
t.Errorf("Expected NotFound error, got '%v'", err) if err := setFn(ctx, foo); err != nil {
t.Errorf("unexpected error: %v", err)
}
toUpdate, err := getFn(ctx, foo)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
toUpdate = updateFn(toUpdate)
updated, created, err := t.storage.(rest.Updater).Update(ctx, toUpdate)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if created {
t.Errorf("unexpected creation")
}
got, err := getFn(ctx, foo)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
// Set resource version which might be unset in created object.
updatedMeta := t.getObjectMetaOrFail(updated)
gotMeta := t.getObjectMetaOrFail(got)
updatedMeta.ResourceVersion = gotMeta.ResourceVersion
if e, a := updated, got; !api.Semantic.DeepEqual(e, a) {
t.Errorf("unexpected obj: %#v, expected %#v", e, a)
} }
} }
func (t *Tester) testUpdateFailsOnVersion(older runtime.Object) { func (t *Tester) testUpdateFailsOnVersionTooOld(obj runtime.Object, setFn SetFunc, setRVFn SetRVFunc) {
ctx := t.TestContext()
foo := copyOrDie(obj)
t.setObjectMeta(foo, "foo3")
setRVFn(10)
if err := setFn(ctx, foo); err != nil {
t.Errorf("unexpected error: %v", err)
}
older := copyOrDie(foo)
olderMeta := t.getObjectMetaOrFail(older)
olderMeta.ResourceVersion = "8"
_, _, err := t.storage.(rest.Updater).Update(t.TestContext(), older) _, _, err := t.storage.(rest.Updater).Update(t.TestContext(), older)
if err == nil { if err == nil {
t.Errorf("Expected an error, but we didn't get one") t.Errorf("Expected an error, but we didn't get one")
...@@ -375,6 +432,70 @@ func (t *Tester) testUpdateFailsOnVersion(older runtime.Object) { ...@@ -375,6 +432,70 @@ func (t *Tester) testUpdateFailsOnVersion(older runtime.Object) {
} }
} }
func (t *Tester) testUpdateInvokesValidation(obj runtime.Object, setFn SetFunc, invalidUpdateFn ...UpdateFunc) {
ctx := t.TestContext()
foo := copyOrDie(obj)
t.setObjectMeta(foo, "foo4")
if err := setFn(ctx, foo); err != nil {
t.Errorf("unexpected error: %v", err)
}
for _, update := range invalidUpdateFn {
toUpdate := update(copyOrDie(foo))
got, created, err := t.storage.(rest.Updater).Update(t.TestContext(), toUpdate)
if got != nil || created {
t.Errorf("expected nil object and no creation")
}
if !errors.IsInvalid(err) && !errors.IsBadRequest(err) {
t.Errorf("expected invalid or bad request error, got %v", err)
}
}
}
func (t *Tester) testUpdateOnNotFound(obj runtime.Object) {
t.setObjectMeta(obj, "foo")
_, created, err := t.storage.(rest.Updater).Update(t.TestContext(), obj)
if t.createOnUpdate {
if err != nil {
t.Errorf("creation allowed on updated, but got an error: %v", err)
}
if !created {
t.Errorf("creation allowed on update, but object not created")
}
} else {
if err == nil {
t.Errorf("Expected an error, but we didn't get one")
} else if !errors.IsNotFound(err) {
t.Errorf("Expected NotFound error, got '%v'", err)
}
}
}
func (t *Tester) testUpdateRejectsMismatchedNamespace(obj runtime.Object, setFn SetFunc) {
ctx := t.TestContext()
foo := copyOrDie(obj)
t.setObjectMeta(foo, "foo1")
if err := setFn(ctx, foo); err != nil {
t.Errorf("unexpected error: %v", err)
}
objectMeta := t.getObjectMetaOrFail(obj)
objectMeta.Name = "foo1"
objectMeta.Namespace = "not-default"
obj, updated, err := t.storage.(rest.Updater).Update(t.TestContext(), obj)
if obj != nil || updated {
t.Errorf("expected nil object and not updated")
}
if err == nil {
t.Errorf("expected an error, but didn't get one")
} else if !strings.Contains(err.Error(), "does not match the namespace sent on the request") {
t.Errorf("expected 'does not match the namespace sent on the request' error, got '%v'", err.Error())
}
}
// ============================================================================= // =============================================================================
// Deletion tests. // Deletion tests.
...@@ -621,9 +742,7 @@ func (t *Tester) testGetDifferentNamespace(obj runtime.Object) { ...@@ -621,9 +742,7 @@ func (t *Tester) testGetDifferentNamespace(obj runtime.Object) {
func (t *Tester) testGetFound(obj runtime.Object) { func (t *Tester) testGetFound(obj runtime.Object) {
ctx := t.TestContext() ctx := t.TestContext()
objMeta := t.getObjectMetaOrFail(obj) t.setObjectMeta(obj, "foo1")
objMeta.Name = "foo1"
objMeta.Namespace = api.NamespaceValue(ctx)
existing, err := t.storage.(rest.Creater).Create(ctx, obj) existing, err := t.storage.(rest.Creater).Create(ctx, obj)
if err != nil { if err != nil {
...@@ -666,9 +785,7 @@ func (t *Tester) testGetMimatchedNamespace(obj runtime.Object) { ...@@ -666,9 +785,7 @@ func (t *Tester) testGetMimatchedNamespace(obj runtime.Object) {
func (t *Tester) testGetNotFound(obj runtime.Object) { func (t *Tester) testGetNotFound(obj runtime.Object) {
ctx := t.TestContext() ctx := t.TestContext()
objMeta := t.getObjectMetaOrFail(obj) t.setObjectMeta(obj, "foo2")
objMeta.Name = "foo2"
objMeta.Namespace = api.NamespaceValue(ctx)
_, err := t.storage.(rest.Creater).Create(ctx, obj) _, err := t.storage.(rest.Creater).Create(ctx, obj)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
...@@ -717,13 +834,9 @@ func (t *Tester) testListFound(obj runtime.Object, assignFn AssignFunc) { ...@@ -717,13 +834,9 @@ func (t *Tester) testListFound(obj runtime.Object, assignFn AssignFunc) {
ctx := t.TestContext() ctx := t.TestContext()
foo1 := copyOrDie(obj) foo1 := copyOrDie(obj)
foo1Meta := t.getObjectMetaOrFail(foo1) t.setObjectMeta(foo1, "foo1")
foo1Meta.Name = "foo1"
foo1Meta.Namespace = api.NamespaceValue(ctx)
foo2 := copyOrDie(obj) foo2 := copyOrDie(obj)
foo2Meta := t.getObjectMetaOrFail(foo2) t.setObjectMeta(foo2, "foo2")
foo2Meta.Name = "foo2"
foo2Meta.Namespace = api.NamespaceValue(ctx)
existing := assignFn([]runtime.Object{foo1, foo2}) existing := assignFn([]runtime.Object{foo1, foo2})
...@@ -748,9 +861,7 @@ func (t *Tester) testListMatchLabels(obj runtime.Object, assignFn AssignFunc) { ...@@ -748,9 +861,7 @@ func (t *Tester) testListMatchLabels(obj runtime.Object, assignFn AssignFunc) {
testLabels := map[string]string{"key": "value"} testLabels := map[string]string{"key": "value"}
foo1 := copyOrDie(obj) foo1 := copyOrDie(obj)
foo1Meta := t.getObjectMetaOrFail(foo1) t.setObjectMeta(foo1, "foo1")
foo1Meta.Name = "foo1"
foo1Meta.Namespace = api.NamespaceValue(ctx)
foo2 := copyOrDie(obj) foo2 := copyOrDie(obj)
foo2Meta := t.getObjectMetaOrFail(foo2) foo2Meta := t.getObjectMetaOrFail(foo2)
foo2Meta.Name = "foo2" foo2Meta.Name = "foo2"
......
...@@ -17,13 +17,11 @@ limitations under the License. ...@@ -17,13 +17,11 @@ limitations under the License.
package etcd package etcd
import ( import (
"strconv"
"testing" "testing"
"time" "time"
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/rest/resttest" "k8s.io/kubernetes/pkg/api/rest/resttest"
"k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/fields"
...@@ -57,125 +55,104 @@ func createController(storage *REST, rc api.ReplicationController, t *testing.T) ...@@ -57,125 +55,104 @@ func createController(storage *REST, rc api.ReplicationController, t *testing.T)
return *newRc, nil return *newRc, nil
} }
var validPodTemplate = api.PodTemplate{ func validNewController() *api.ReplicationController {
Template: api.PodTemplateSpec{ return &api.ReplicationController{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Labels: map[string]string{"a": "b"}, Name: "foo",
Namespace: api.NamespaceDefault,
}, },
Spec: api.PodSpec{ Spec: api.ReplicationControllerSpec{
Containers: []api.Container{ Selector: map[string]string{"a": "b"},
{ Template: &api.PodTemplateSpec{
Name: "test", ObjectMeta: api.ObjectMeta{
Image: "test_image", Labels: map[string]string{"a": "b"},
ImagePullPolicy: api.PullIfNotPresent, },
Spec: api.PodSpec{
Containers: []api.Container{
{
Name: "test",
Image: "test_image",
ImagePullPolicy: api.PullIfNotPresent,
},
},
RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst,
}, },
}, },
RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst,
}, },
}, }
}
var validControllerSpec = api.ReplicationControllerSpec{
Selector: validPodTemplate.Template.Labels,
Template: &validPodTemplate.Template,
} }
var validController = api.ReplicationController{ var validController = *validNewController()
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "default"},
Spec: validControllerSpec,
}
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError) test := resttest.New(t, storage, fakeClient.SetError)
controller := validNewController()
controller.ObjectMeta = api.ObjectMeta{}
test.TestCreate( test.TestCreate(
// valid // valid
&api.ReplicationController{ controller,
Spec: api.ReplicationControllerSpec{
Replicas: 2,
Selector: map[string]string{"a": "b"},
Template: &validPodTemplate.Template,
},
},
func(ctx api.Context, obj runtime.Object) error { func(ctx api.Context, obj runtime.Object) error {
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj) return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
}, },
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) { func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj) return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
}, },
// invalid // invalid (invalid selector)
&api.ReplicationController{ &api.ReplicationController{
Spec: api.ReplicationControllerSpec{ Spec: api.ReplicationControllerSpec{
Replicas: 2, Replicas: 2,
Selector: map[string]string{}, Selector: map[string]string{},
Template: &validPodTemplate.Template, Template: validController.Spec.Template,
}, },
}, },
) )
} }
func TestEtcdControllerValidatesUpdate(t *testing.T) { func TestUpdate(t *testing.T) {
ctx := api.NewDefaultContext() storage, fakeClient := newStorage(t)
storage, _ := newStorage(t) test := resttest.New(t, storage, fakeClient.SetError)
test.TestUpdate(
updateController, err := createController(storage, validController, t) // valid
if err != nil { validNewController(),
t.Errorf("Failed to create controller, cannot proceed with test.") func(ctx api.Context, obj runtime.Object) error {
} return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
updaters := []func(rc api.ReplicationController) (runtime.Object, bool, error){
func(rc api.ReplicationController) (runtime.Object, bool, error) {
rc.UID = "newUID"
return storage.Update(ctx, &rc)
}, },
func(rc api.ReplicationController) (runtime.Object, bool, error) { func(resourceVersion uint64) {
rc.Name = "" registrytest.SetResourceVersion(fakeClient, resourceVersion)
return storage.Update(ctx, &rc)
}, },
func(rc api.ReplicationController) (runtime.Object, bool, error) { func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
rc.Spec.Selector = map[string]string{} return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
return storage.Update(ctx, &rc)
}, },
} // updateFunc
for _, u := range updaters { func(obj runtime.Object) runtime.Object {
c, updated, err := u(updateController) object := obj.(*api.ReplicationController)
if c != nil || updated { object.Spec.Replicas = object.Spec.Replicas + 1
t.Errorf("Expected nil object and not created") return object
} },
if !errors.IsInvalid(err) && !errors.IsBadRequest(err) { // invalid updateFunc
t.Errorf("Expected invalid or bad request error, got %v of type %T", err, err) func(obj runtime.Object) runtime.Object {
} object := obj.(*api.ReplicationController)
} object.UID = "newUID"
} return object
},
func TestEtcdControllerValidatesNamespaceOnUpdate(t *testing.T) { func(obj runtime.Object) runtime.Object {
storage, _ := newStorage(t) object := obj.(*api.ReplicationController)
ns := "newnamespace" object.Name = ""
return object
// The update should fail if the namespace on the controller is set to something },
// other than the namespace on the given context, even if the namespace on the func(obj runtime.Object) runtime.Object {
// controller is valid. object := obj.(*api.ReplicationController)
updateController, err := createController(storage, validController, t) object.Spec.Selector = map[string]string{}
return object
newNamespaceController := validController },
newNamespaceController.Namespace = ns )
_, err = createController(storage, newNamespaceController, t)
c, updated, err := storage.Update(api.WithNamespace(api.NewContext(), ns), &updateController)
if c != nil || updated {
t.Errorf("Expected nil object and not created")
}
// TODO: Be more paranoid about the type of error and make sure it has the substring
// "namespace" in it, once #5684 is fixed. Ideally this would be a NewBadRequest.
if err == nil {
t.Errorf("Expected an error, but we didn't get one")
}
} }
func TestGenerationNumber(t *testing.T) { func TestGenerationNumber(t *testing.T) {
storage, _ := newStorage(t) storage, _ := newStorage(t)
modifiedSno := validController modifiedSno := *validNewController()
modifiedSno.Generation = 100 modifiedSno.Generation = 100
modifiedSno.Status.ObservedGeneration = 10 modifiedSno.Status.ObservedGeneration = 10
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
...@@ -225,17 +202,15 @@ func TestGenerationNumber(t *testing.T) { ...@@ -225,17 +202,15 @@ func TestGenerationNumber(t *testing.T) {
func TestEtcdGetController(t *testing.T) { func TestEtcdGetController(t *testing.T) {
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError) test := resttest.New(t, storage, fakeClient.SetError)
copy := validController test.TestGet(validNewController())
test.TestGet(&copy)
} }
func TestEtcdListControllers(t *testing.T) { func TestEtcdListControllers(t *testing.T) {
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError) test := resttest.New(t, storage, fakeClient.SetError)
key := etcdtest.AddPrefix(storage.KeyRootFunc(test.TestContext())) key := etcdtest.AddPrefix(storage.KeyRootFunc(test.TestContext()))
copy := validController
test.TestList( test.TestList(
&copy, validNewController(),
func(objects []runtime.Object) []runtime.Object { func(objects []runtime.Object) []runtime.Object {
return registrytest.SetObjectsForKey(fakeClient, key, objects) return registrytest.SetObjectsForKey(fakeClient, key, objects)
}, },
...@@ -244,38 +219,13 @@ func TestEtcdListControllers(t *testing.T) { ...@@ -244,38 +219,13 @@ func TestEtcdListControllers(t *testing.T) {
}) })
} }
func TestEtcdUpdateController(t *testing.T) {
ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t)
key, _ := storage.KeyFunc(ctx, validController.Name)
key = etcdtest.AddPrefix(key)
// set a key, then retrieve the current resource version and try updating it
resp, _ := fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), &validController), 0)
update := validController
update.ResourceVersion = strconv.FormatUint(resp.Node.ModifiedIndex, 10)
update.Spec.Replicas = validController.Spec.Replicas + 1
_, created, err := storage.Update(ctx, &update)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if created {
t.Errorf("expected an update but created flag was returned")
}
ctrl, err := storage.Get(ctx, validController.Name)
updatedController, _ := ctrl.(*api.ReplicationController)
if updatedController.Spec.Replicas != validController.Spec.Replicas+1 {
t.Errorf("Unexpected controller: %#v", ctrl)
}
}
func TestEtcdDeleteController(t *testing.T) { func TestEtcdDeleteController(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
key, _ := storage.KeyFunc(ctx, validController.Name) key, _ := storage.KeyFunc(ctx, validController.Name)
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), &validController), 0) fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), validNewController()), 0)
obj, err := storage.Delete(ctx, validController.Name, nil) obj, err := storage.Delete(ctx, validController.Name, nil)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
...@@ -491,7 +441,7 @@ func TestDelete(t *testing.T) { ...@@ -491,7 +441,7 @@ func TestDelete(t *testing.T) {
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
createFn := func() runtime.Object { createFn := func() runtime.Object {
rc := validController rc := *validNewController()
rc.ResourceVersion = "1" rc.ResourceVersion = "1"
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
......
...@@ -80,6 +80,33 @@ func TestCreate(t *testing.T) { ...@@ -80,6 +80,33 @@ func TestCreate(t *testing.T) {
) )
} }
func TestUpdate(t *testing.T) {
storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError).AllowCreateOnUpdate()
test.TestUpdate(
// valid
validNewEndpoints(),
func(ctx api.Context, obj runtime.Object) error {
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
},
func(resourceVersion uint64) {
registrytest.SetResourceVersion(fakeClient, resourceVersion)
},
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
},
// updateFunc
func(obj runtime.Object) runtime.Object {
object := obj.(*api.Endpoints)
object.Subsets = []api.EndpointSubset{{
Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}, {IP: "5.6.7.8"}},
Ports: []api.EndpointPort{{Port: 80, Protocol: "TCP"}},
}}
return object
},
)
}
func TestDelete(t *testing.T) { func TestDelete(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
...@@ -148,36 +175,6 @@ func TestEndpointsDecode(t *testing.T) { ...@@ -148,36 +175,6 @@ func TestEndpointsDecode(t *testing.T) {
} }
} }
func TestEtcdUpdateEndpoints(t *testing.T) {
ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t)
endpoints := validChangedEndpoints()
key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), validNewEndpoints()), 0)
_, _, err := storage.Update(ctx, endpoints)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
response, err := fakeClient.Get(key, false, false)
if err != nil {
t.Fatalf("Unexpected error %v", err)
}
var endpointsOut api.Endpoints
err = testapi.Codec().DecodeInto([]byte(response.Node.Value), &endpointsOut)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
endpoints.ObjectMeta.ResourceVersion = endpointsOut.ObjectMeta.ResourceVersion
if !api.Semantic.DeepEqual(endpoints, &endpointsOut) {
t.Errorf("Unexpected endpoints: %#v, expected %#v", &endpointsOut, endpoints)
}
}
func TestDeleteEndpoints(t *testing.T) { func TestDeleteEndpoints(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
......
...@@ -78,26 +78,24 @@ func TestCreate(t *testing.T) { ...@@ -78,26 +78,24 @@ func TestCreate(t *testing.T) {
func TestUpdate(t *testing.T) { func TestUpdate(t *testing.T) {
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError) test := resttest.New(t, storage, fakeClient.SetError)
key, err := storage.KeyFunc(test.TestContext(), "foo")
if err != nil {
t.Fatal(err)
}
key = etcdtest.AddPrefix(key)
fakeClient.ExpectNotFoundGet(key)
fakeClient.ChangeIndex = 2
autoscaler := validNewHorizontalPodAutoscaler("foo")
existing := validNewHorizontalPodAutoscaler("exists")
existing.Namespace = test.TestNamespace()
obj, err := storage.Create(test.TestContext(), existing)
if err != nil {
t.Fatalf("unable to create object: %v", err)
}
older := obj.(*expapi.HorizontalPodAutoscaler)
older.ResourceVersion = "1"
test.TestUpdate( test.TestUpdate(
autoscaler, // valid
existing, validNewHorizontalPodAutoscaler("foo"),
older, func(ctx api.Context, obj runtime.Object) error {
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
},
func(resourceVersion uint64) {
registrytest.SetResourceVersion(fakeClient, resourceVersion)
},
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
},
// updateFunc
func(obj runtime.Object) runtime.Object {
object := obj.(*expapi.HorizontalPodAutoscaler)
object.Spec.MaxCount = object.Spec.MaxCount + 1
return object
},
) )
} }
......
...@@ -76,3 +76,39 @@ func TestCreate(t *testing.T) { ...@@ -76,3 +76,39 @@ func TestCreate(t *testing.T) {
}, },
) )
} }
func TestUpdate(t *testing.T) {
storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError).AllowCreateOnUpdate()
test.TestUpdate(
// valid
validNewLimitRange(),
func(ctx api.Context, obj runtime.Object) error {
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
},
func(resourceVersion uint64) {
registrytest.SetResourceVersion(fakeClient, resourceVersion)
},
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
},
// updateFunc
func(obj runtime.Object) runtime.Object {
object := obj.(*api.LimitRange)
object.Spec.Limits = []api.LimitRangeItem{
{
Type: api.LimitTypePod,
Max: api.ResourceList{
api.ResourceCPU: resource.MustParse("1000"),
api.ResourceMemory: resource.MustParse("100000"),
},
Min: api.ResourceList{
api.ResourceCPU: resource.MustParse("10"),
api.ResourceMemory: resource.MustParse("1000"),
},
},
}
return object
},
)
}
...@@ -95,6 +95,30 @@ func TestCreate(t *testing.T) { ...@@ -95,6 +95,30 @@ func TestCreate(t *testing.T) {
) )
} }
func TestUpdate(t *testing.T) {
storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError).ClusterScope()
test.TestUpdate(
// valid
validNewNode(),
func(ctx api.Context, obj runtime.Object) error {
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
},
func(resourceVersion uint64) {
registrytest.SetResourceVersion(fakeClient, resourceVersion)
},
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
},
// updateFunc
func(obj runtime.Object) runtime.Object {
object := obj.(*api.Node)
object.Spec.Unschedulable = !object.Spec.Unschedulable
return object
},
)
}
func TestDelete(t *testing.T) { func TestDelete(t *testing.T) {
ctx := api.NewContext() ctx := api.NewContext()
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
...@@ -145,36 +169,6 @@ func TestEtcdListNodes(t *testing.T) { ...@@ -145,36 +169,6 @@ func TestEtcdListNodes(t *testing.T) {
}) })
} }
func TestEtcdUpdateEndpoints(t *testing.T) {
ctx := api.NewContext()
storage, fakeClient := newStorage(t)
node := validChangedNode()
key, _ := storage.KeyFunc(ctx, node.Name)
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), validNewNode()), 0)
_, _, err := storage.Update(ctx, node)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
response, err := fakeClient.Get(key, false, false)
if err != nil {
t.Fatalf("Unexpected error %v", err)
}
var nodeOut api.Node
err = testapi.Codec().DecodeInto([]byte(response.Node.Value), &nodeOut)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
node.ObjectMeta.ResourceVersion = nodeOut.ObjectMeta.ResourceVersion
if !api.Semantic.DeepEqual(node, &nodeOut) {
t.Errorf("Unexpected node: %#v, expected %#v", &nodeOut, node)
}
}
func TestEtcdDeleteNode(t *testing.T) { func TestEtcdDeleteNode(t *testing.T) {
ctx := api.NewContext() ctx := api.NewContext()
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
......
...@@ -89,6 +89,32 @@ func TestCreate(t *testing.T) { ...@@ -89,6 +89,32 @@ func TestCreate(t *testing.T) {
) )
} }
func TestUpdate(t *testing.T) {
storage, _, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError).ClusterScope()
test.TestUpdate(
// valid
validNewPersistentVolume("foo"),
func(ctx api.Context, obj runtime.Object) error {
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
},
func(resourceVersion uint64) {
registrytest.SetResourceVersion(fakeClient, resourceVersion)
},
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
},
// updateFunc
func(obj runtime.Object) runtime.Object {
object := obj.(*api.PersistentVolume)
object.Spec.Capacity = api.ResourceList{
api.ResourceName(api.ResourceStorage): resource.MustParse("20G"),
}
return object
},
)
}
func TestDelete(t *testing.T) { func TestDelete(t *testing.T) {
ctx := api.NewContext() ctx := api.NewContext()
storage, _, fakeClient := newStorage(t) storage, _, fakeClient := newStorage(t)
...@@ -157,36 +183,6 @@ func TestPersistentVolumesDecode(t *testing.T) { ...@@ -157,36 +183,6 @@ func TestPersistentVolumesDecode(t *testing.T) {
} }
} }
func TestEtcdUpdatePersistentVolumes(t *testing.T) {
ctx := api.NewContext()
storage, _, fakeClient := newStorage(t)
persistentVolume := validChangedPersistentVolume()
key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), validNewPersistentVolume("foo")), 0)
_, _, err := storage.Update(ctx, persistentVolume)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
response, err := fakeClient.Get(key, false, false)
if err != nil {
t.Fatalf("Unexpected error %v", err)
}
var persistentVolumeOut api.PersistentVolume
err = testapi.Codec().DecodeInto([]byte(response.Node.Value), &persistentVolumeOut)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
persistentVolume.ObjectMeta.ResourceVersion = persistentVolumeOut.ObjectMeta.ResourceVersion
if !api.Semantic.DeepEqual(persistentVolume, &persistentVolumeOut) {
t.Errorf("Unexpected persistentVolume: %#v, expected %#v", &persistentVolumeOut, persistentVolume)
}
}
func TestDeletePersistentVolumes(t *testing.T) { func TestDeletePersistentVolumes(t *testing.T) {
ctx := api.NewContext() ctx := api.NewContext()
storage, _, fakeClient := newStorage(t) storage, _, fakeClient := newStorage(t)
......
...@@ -86,6 +86,34 @@ func TestCreate(t *testing.T) { ...@@ -86,6 +86,34 @@ func TestCreate(t *testing.T) {
) )
} }
func TestUpdate(t *testing.T) {
storage, _, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError)
test.TestUpdate(
// valid
validNewPersistentVolumeClaim("foo", api.NamespaceDefault),
func(ctx api.Context, obj runtime.Object) error {
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
},
func(resourceVersion uint64) {
registrytest.SetResourceVersion(fakeClient, resourceVersion)
},
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
},
// updateFunc
func(obj runtime.Object) runtime.Object {
object := obj.(*api.PersistentVolumeClaim)
object.Spec.Resources = api.ResourceRequirements{
Requests: api.ResourceList{
api.ResourceName(api.ResourceStorage): resource.MustParse("20G"),
},
}
return object
},
)
}
func TestDelete(t *testing.T) { func TestDelete(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
storage, _, fakeClient := newStorage(t) storage, _, fakeClient := newStorage(t)
......
...@@ -112,6 +112,30 @@ func TestCreate(t *testing.T) { ...@@ -112,6 +112,30 @@ func TestCreate(t *testing.T) {
) )
} }
func TestUpdate(t *testing.T) {
storage, _, _, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError)
test.TestUpdate(
// valid
validNewPod(),
func(ctx api.Context, obj runtime.Object) error {
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
},
func(resourceVersion uint64) {
registrytest.SetResourceVersion(fakeClient, resourceVersion)
},
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
},
// updateFunc
func(obj runtime.Object) runtime.Object {
object := obj.(*api.Pod)
object.Labels = map[string]string{"a": "b"}
return object
},
)
}
func TestDelete(t *testing.T) { func TestDelete(t *testing.T) {
storage, _, _, fakeClient := newStorage(t) storage, _, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
...@@ -199,37 +223,6 @@ func TestPodDecode(t *testing.T) { ...@@ -199,37 +223,6 @@ func TestPodDecode(t *testing.T) {
} }
} }
func TestUpdateWithConflictingNamespace(t *testing.T) {
storage, _, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext()
key, _ := storage.Etcd.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(testapi.Codec(), &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "default"},
Spec: api.PodSpec{NodeName: "machine"},
}),
ModifiedIndex: 1,
},
},
}
pod := validChangedPod()
pod.Namespace = "not-default"
obj, created, err := storage.Update(api.NewDefaultContext(), pod)
if obj != nil || created {
t.Error("Expected a nil channel, but we got a value or created")
}
if err == nil {
t.Errorf("Expected an error, but we didn't get one")
} else if strings.Index(err.Error(), "the namespace of the provided object does not match the namespace sent on the request") == -1 {
t.Errorf("Expected 'Pod.Namespace does not match the provided context' error, got '%v'", err.Error())
}
}
func TestResourceLocation(t *testing.T) { func TestResourceLocation(t *testing.T) {
expectedIP := "1.2.3.4" expectedIP := "1.2.3.4"
testCases := []struct { testCases := []struct {
...@@ -691,33 +684,6 @@ func TestEtcdCreateBinding(t *testing.T) { ...@@ -691,33 +684,6 @@ func TestEtcdCreateBinding(t *testing.T) {
} }
} }
func TestEtcdUpdateNotFound(t *testing.T) {
storage, _, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext()
fakeClient.TestIndex = true
key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{},
E: tools.EtcdErrorNotFound,
}
podIn := api.Pod{
ObjectMeta: api.ObjectMeta{
Name: "foo",
ResourceVersion: "1",
Labels: map[string]string{
"foo": "bar",
},
},
}
_, _, err := storage.Update(ctx, &podIn)
if err == nil {
t.Errorf("unexpected non-error")
}
}
func TestEtcdUpdateNotScheduled(t *testing.T) { func TestEtcdUpdateNotScheduled(t *testing.T) {
storage, _, _, fakeClient := newStorage(t) storage, _, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
......
...@@ -24,7 +24,6 @@ import ( ...@@ -24,7 +24,6 @@ import (
"k8s.io/kubernetes/pkg/registry/registrytest" "k8s.io/kubernetes/pkg/registry/registrytest"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools"
"k8s.io/kubernetes/pkg/tools/etcdtest"
) )
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) { func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
...@@ -83,27 +82,23 @@ func TestCreate(t *testing.T) { ...@@ -83,27 +82,23 @@ func TestCreate(t *testing.T) {
func TestUpdate(t *testing.T) { func TestUpdate(t *testing.T) {
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError) test := resttest.New(t, storage, fakeClient.SetError)
key, err := storage.KeyFunc(test.TestContext(), "foo")
if err != nil {
t.Fatal(err)
}
key = etcdtest.AddPrefix(key)
fakeClient.ExpectNotFoundGet(key)
fakeClient.ChangeIndex = 2
pod := validNewPodTemplate("foo")
existing := validNewPodTemplate("exists")
existing.Namespace = test.TestNamespace()
obj, err := storage.Create(test.TestContext(), existing)
if err != nil {
t.Fatalf("unable to create object: %v", err)
}
older := obj.(*api.PodTemplate)
older.ResourceVersion = "1"
test.TestUpdate( test.TestUpdate(
pod, //valid
existing, validNewPodTemplate("foo"),
older, func(ctx api.Context, obj runtime.Object) error {
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
},
func(resourceVersion uint64) {
registrytest.SetResourceVersion(fakeClient, resourceVersion)
},
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
},
// updateFunc
func(obj runtime.Object) runtime.Object {
object := obj.(*api.PodTemplate)
object.Template.Spec.NodeSelector = map[string]string{"a": "b"}
return object
},
) )
} }
...@@ -24,7 +24,6 @@ import ( ...@@ -24,7 +24,6 @@ import (
"k8s.io/kubernetes/pkg/registry/registrytest" "k8s.io/kubernetes/pkg/registry/registrytest"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools"
"k8s.io/kubernetes/pkg/tools/etcdtest"
) )
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) { func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
...@@ -74,27 +73,23 @@ func TestCreate(t *testing.T) { ...@@ -74,27 +73,23 @@ func TestCreate(t *testing.T) {
func TestUpdate(t *testing.T) { func TestUpdate(t *testing.T) {
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError) test := resttest.New(t, storage, fakeClient.SetError)
key, err := storage.KeyFunc(test.TestContext(), "foo")
if err != nil {
t.Fatal(err)
}
key = etcdtest.AddPrefix(key)
fakeClient.ExpectNotFoundGet(key)
fakeClient.ChangeIndex = 2
secret := validNewSecret("foo")
existing := validNewSecret("exists")
existing.Namespace = test.TestNamespace()
obj, err := storage.Create(test.TestContext(), existing)
if err != nil {
t.Fatalf("unable to create object: %v", err)
}
older := obj.(*api.Secret)
older.ResourceVersion = "1"
test.TestUpdate( test.TestUpdate(
secret, // valid
existing, validNewSecret("foo"),
older, func(ctx api.Context, obj runtime.Object) error {
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
},
func(resourceVersion uint64) {
registrytest.SetResourceVersion(fakeClient, resourceVersion)
},
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
},
// updateFunc
func(obj runtime.Object) runtime.Object {
object := obj.(*api.Secret)
object.Data["othertest"] = []byte("otherdata")
return object
},
) )
} }
...@@ -86,3 +86,36 @@ func TestCreate(t *testing.T) { ...@@ -86,3 +86,36 @@ func TestCreate(t *testing.T) {
}, },
) )
} }
func TestUpdate(t *testing.T) {
storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError).AllowCreateOnUpdate()
test.TestUpdate(
// valid
validService(),
func(ctx api.Context, obj runtime.Object) error {
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
},
func(resourceVersion uint64) {
registrytest.SetResourceVersion(fakeClient, resourceVersion)
},
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
},
// updateFunc
func(obj runtime.Object) runtime.Object {
object := obj.(*api.Service)
object.Spec = api.ServiceSpec{
Selector: map[string]string{"bar": "baz2"},
SessionAffinity: api.ServiceAffinityNone,
Type: api.ServiceTypeClusterIP,
Ports: []api.ServicePort{{
Port: 6502,
Protocol: api.ProtocolTCP,
TargetPort: util.NewIntOrStringFromInt(6502),
}},
}
return object
},
)
}
...@@ -24,7 +24,6 @@ import ( ...@@ -24,7 +24,6 @@ import (
"k8s.io/kubernetes/pkg/registry/registrytest" "k8s.io/kubernetes/pkg/registry/registrytest"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools"
"k8s.io/kubernetes/pkg/tools/etcdtest"
) )
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) { func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
...@@ -67,27 +66,23 @@ func TestCreate(t *testing.T) { ...@@ -67,27 +66,23 @@ func TestCreate(t *testing.T) {
func TestUpdate(t *testing.T) { func TestUpdate(t *testing.T) {
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError) test := resttest.New(t, storage, fakeClient.SetError)
key, err := storage.KeyFunc(test.TestContext(), "foo")
if err != nil {
t.Fatal(err)
}
key = etcdtest.AddPrefix(key)
fakeClient.ExpectNotFoundGet(key)
fakeClient.ChangeIndex = 2
serviceAccount := validNewServiceAccount("foo")
existing := validNewServiceAccount("exists")
existing.Namespace = test.TestNamespace()
obj, err := storage.Create(test.TestContext(), existing)
if err != nil {
t.Fatalf("unable to create object: %v", err)
}
older := obj.(*api.ServiceAccount)
older.ResourceVersion = "1"
test.TestUpdate( test.TestUpdate(
serviceAccount, // valid
existing, validNewServiceAccount("foo"),
older, func(ctx api.Context, obj runtime.Object) error {
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
},
func(resourceVersion uint64) {
registrytest.SetResourceVersion(fakeClient, resourceVersion)
},
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
},
// updateFunc
func(obj runtime.Object) runtime.Object {
object := obj.(*api.ServiceAccount)
// TODO: Update this serviceAccount
return object
},
) )
} }
...@@ -80,26 +80,24 @@ func TestCreate(t *testing.T) { ...@@ -80,26 +80,24 @@ func TestCreate(t *testing.T) {
func TestUpdate(t *testing.T) { func TestUpdate(t *testing.T) {
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError) test := resttest.New(t, storage, fakeClient.SetError)
key, err := storage.KeyFunc(test.TestContext(), "foo")
if err != nil {
t.Fatal(err)
}
key = etcdtest.AddPrefix(key)
fakeClient.ExpectNotFoundGet(key)
fakeClient.ChangeIndex = 2
rsrc := validNewThirdPartyResource("foo")
existing := validNewThirdPartyResource("exists")
existing.Namespace = test.TestNamespace()
obj, err := storage.Create(test.TestContext(), existing)
if err != nil {
t.Fatalf("unable to create object: %v", err)
}
older := obj.(*expapi.ThirdPartyResource)
older.ResourceVersion = "1"
test.TestUpdate( test.TestUpdate(
rsrc, // valid
existing, validNewThirdPartyResource("foo"),
older, func(ctx api.Context, obj runtime.Object) error {
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
},
func(resourceVersion uint64) {
registrytest.SetResourceVersion(fakeClient, resourceVersion)
},
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
},
// updateFunc
func(obj runtime.Object) runtime.Object {
object := obj.(*expapi.ThirdPartyResource)
object.Description = "new description"
return object
},
) )
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment