mirror of https://github.com/k3s-io/k3s
Refactoring of update etcd tests.
parent
e21bcb8e7a
commit
836be0c432
|
@ -36,10 +36,11 @@ import (
|
|||
|
||||
type Tester struct {
|
||||
*testing.T
|
||||
storage rest.Storage
|
||||
storageError injectErrorFunc
|
||||
clusterScope bool
|
||||
generatesName bool
|
||||
storage rest.Storage
|
||||
storageError injectErrorFunc
|
||||
clusterScope bool
|
||||
createOnUpdate bool
|
||||
generatesName bool
|
||||
}
|
||||
|
||||
type injectErrorFunc func(err error)
|
||||
|
@ -63,6 +64,11 @@ func (t *Tester) ClusterScope() *Tester {
|
|||
return t
|
||||
}
|
||||
|
||||
func (t *Tester) AllowCreateOnUpdate() *Tester {
|
||||
t.createOnUpdate = true
|
||||
return t
|
||||
}
|
||||
|
||||
func (t *Tester) GeneratesName() *Tester {
|
||||
t.generatesName = true
|
||||
return t
|
||||
|
@ -94,6 +100,17 @@ func (t *Tester) getObjectMetaOrFail(obj runtime.Object) *api.ObjectMeta {
|
|||
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 {
|
||||
out, err := api.Scheme.Copy(obj)
|
||||
if err != nil {
|
||||
|
@ -106,6 +123,7 @@ type AssignFunc func([]runtime.Object) []runtime.Object
|
|||
type GetFunc func(api.Context, runtime.Object) (runtime.Object, error)
|
||||
type SetFunc func(api.Context, runtime.Object) error
|
||||
type SetRVFunc func(uint64)
|
||||
type UpdateFunc func(runtime.Object) runtime.Object
|
||||
|
||||
// Test creating an 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,
|
|||
}
|
||||
|
||||
// Test updating an object.
|
||||
func (t *Tester) TestUpdate(valid runtime.Object, existing, older runtime.Object) {
|
||||
t.testUpdateFailsOnNotFound(copyOrDie(valid))
|
||||
t.testUpdateFailsOnVersion(copyOrDie(older))
|
||||
func (t *Tester) TestUpdate(valid runtime.Object, setFn SetFunc, setRVFn SetRVFunc, getFn GetFunc, updateFn UpdateFunc, invalidUpdateFn ...UpdateFunc) {
|
||||
t.testUpdateEquals(copyOrDie(valid), setFn, getFn, updateFn)
|
||||
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.
|
||||
|
@ -177,10 +200,7 @@ func (t *Tester) testCreateAlreadyExisting(obj runtime.Object, setFn SetFunc) {
|
|||
ctx := t.TestContext()
|
||||
|
||||
foo := copyOrDie(obj)
|
||||
fooMeta := t.getObjectMetaOrFail(foo)
|
||||
fooMeta.Name = "foo1"
|
||||
fooMeta.Namespace = api.NamespaceValue(ctx)
|
||||
fooMeta.GenerateName = ""
|
||||
t.setObjectMeta(foo, "foo1")
|
||||
if err := setFn(ctx, foo); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
@ -195,10 +215,7 @@ func (t *Tester) testCreateEquals(obj runtime.Object, getFn GetFunc) {
|
|||
ctx := t.TestContext()
|
||||
|
||||
foo := copyOrDie(obj)
|
||||
fooMeta := t.getObjectMetaOrFail(foo)
|
||||
fooMeta.Name = "foo2"
|
||||
fooMeta.Namespace = api.NamespaceValue(ctx)
|
||||
fooMeta.GenerateName = ""
|
||||
t.setObjectMeta(foo, "foo2")
|
||||
|
||||
created, err := t.storage.(rest.Creater).Create(ctx, foo)
|
||||
if err != nil {
|
||||
|
@ -357,16 +374,56 @@ func (t *Tester) testCreateResetsUserData(valid runtime.Object) {
|
|||
// =============================================================================
|
||||
// Update tests.
|
||||
|
||||
func (t *Tester) testUpdateFailsOnNotFound(valid runtime.Object) {
|
||||
_, _, err := t.storage.(rest.Updater).Update(t.TestContext(), valid)
|
||||
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) testUpdateEquals(obj runtime.Object, setFn SetFunc, getFn GetFunc, updateFn UpdateFunc) {
|
||||
ctx := t.TestContext()
|
||||
|
||||
foo := copyOrDie(obj)
|
||||
t.setObjectMeta(foo, "foo2")
|
||||
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)
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error, but we didn't get one")
|
||||
|
@ -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.
|
||||
|
||||
|
@ -621,9 +742,7 @@ func (t *Tester) testGetDifferentNamespace(obj runtime.Object) {
|
|||
|
||||
func (t *Tester) testGetFound(obj runtime.Object) {
|
||||
ctx := t.TestContext()
|
||||
objMeta := t.getObjectMetaOrFail(obj)
|
||||
objMeta.Name = "foo1"
|
||||
objMeta.Namespace = api.NamespaceValue(ctx)
|
||||
t.setObjectMeta(obj, "foo1")
|
||||
|
||||
existing, err := t.storage.(rest.Creater).Create(ctx, obj)
|
||||
if err != nil {
|
||||
|
@ -666,9 +785,7 @@ func (t *Tester) testGetMimatchedNamespace(obj runtime.Object) {
|
|||
|
||||
func (t *Tester) testGetNotFound(obj runtime.Object) {
|
||||
ctx := t.TestContext()
|
||||
objMeta := t.getObjectMetaOrFail(obj)
|
||||
objMeta.Name = "foo2"
|
||||
objMeta.Namespace = api.NamespaceValue(ctx)
|
||||
t.setObjectMeta(obj, "foo2")
|
||||
_, err := t.storage.(rest.Creater).Create(ctx, obj)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
|
@ -717,13 +834,9 @@ func (t *Tester) testListFound(obj runtime.Object, assignFn AssignFunc) {
|
|||
ctx := t.TestContext()
|
||||
|
||||
foo1 := copyOrDie(obj)
|
||||
foo1Meta := t.getObjectMetaOrFail(foo1)
|
||||
foo1Meta.Name = "foo1"
|
||||
foo1Meta.Namespace = api.NamespaceValue(ctx)
|
||||
t.setObjectMeta(foo1, "foo1")
|
||||
foo2 := copyOrDie(obj)
|
||||
foo2Meta := t.getObjectMetaOrFail(foo2)
|
||||
foo2Meta.Name = "foo2"
|
||||
foo2Meta.Namespace = api.NamespaceValue(ctx)
|
||||
t.setObjectMeta(foo2, "foo2")
|
||||
|
||||
existing := assignFn([]runtime.Object{foo1, foo2})
|
||||
|
||||
|
@ -748,9 +861,7 @@ func (t *Tester) testListMatchLabels(obj runtime.Object, assignFn AssignFunc) {
|
|||
testLabels := map[string]string{"key": "value"}
|
||||
|
||||
foo1 := copyOrDie(obj)
|
||||
foo1Meta := t.getObjectMetaOrFail(foo1)
|
||||
foo1Meta.Name = "foo1"
|
||||
foo1Meta.Namespace = api.NamespaceValue(ctx)
|
||||
t.setObjectMeta(foo1, "foo1")
|
||||
foo2 := copyOrDie(obj)
|
||||
foo2Meta := t.getObjectMetaOrFail(foo2)
|
||||
foo2Meta.Name = "foo2"
|
||||
|
|
|
@ -17,13 +17,11 @@ limitations under the License.
|
|||
package etcd
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/coreos/go-etcd/etcd"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/errors"
|
||||
"k8s.io/kubernetes/pkg/api/rest/resttest"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
|
@ -57,125 +55,104 @@ func createController(storage *REST, rc api.ReplicationController, t *testing.T)
|
|||
return *newRc, nil
|
||||
}
|
||||
|
||||
var validPodTemplate = api.PodTemplate{
|
||||
Template: api.PodTemplateSpec{
|
||||
func validNewController() *api.ReplicationController {
|
||||
return &api.ReplicationController{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: map[string]string{"a": "b"},
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
{
|
||||
Name: "test",
|
||||
Image: "test_image",
|
||||
ImagePullPolicy: api.PullIfNotPresent,
|
||||
Spec: api.ReplicationControllerSpec{
|
||||
Selector: map[string]string{"a": "b"},
|
||||
Template: &api.PodTemplateSpec{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: map[string]string{"a": "b"},
|
||||
},
|
||||
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{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "default"},
|
||||
Spec: validControllerSpec,
|
||||
}
|
||||
var validController = *validNewController()
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
controller := validNewController()
|
||||
controller.ObjectMeta = api.ObjectMeta{}
|
||||
test.TestCreate(
|
||||
// valid
|
||||
&api.ReplicationController{
|
||||
Spec: api.ReplicationControllerSpec{
|
||||
Replicas: 2,
|
||||
Selector: map[string]string{"a": "b"},
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
controller,
|
||||
func(ctx api.Context, obj runtime.Object) error {
|
||||
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
|
||||
},
|
||||
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
|
||||
},
|
||||
// invalid
|
||||
// invalid (invalid selector)
|
||||
&api.ReplicationController{
|
||||
Spec: api.ReplicationControllerSpec{
|
||||
Replicas: 2,
|
||||
Selector: map[string]string{},
|
||||
Template: &validPodTemplate.Template,
|
||||
Template: validController.Spec.Template,
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func TestEtcdControllerValidatesUpdate(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, _ := newStorage(t)
|
||||
|
||||
updateController, err := createController(storage, validController, t)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create controller, cannot proceed with test.")
|
||||
}
|
||||
|
||||
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 TestUpdate(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
test.TestUpdate(
|
||||
// valid
|
||||
validNewController(),
|
||||
func(ctx api.Context, obj runtime.Object) error {
|
||||
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
|
||||
},
|
||||
func(rc api.ReplicationController) (runtime.Object, bool, error) {
|
||||
rc.Name = ""
|
||||
return storage.Update(ctx, &rc)
|
||||
func(resourceVersion uint64) {
|
||||
registrytest.SetResourceVersion(fakeClient, resourceVersion)
|
||||
},
|
||||
func(rc api.ReplicationController) (runtime.Object, bool, error) {
|
||||
rc.Spec.Selector = map[string]string{}
|
||||
return storage.Update(ctx, &rc)
|
||||
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
|
||||
},
|
||||
}
|
||||
for _, u := range updaters {
|
||||
c, updated, err := u(updateController)
|
||||
if c != nil || updated {
|
||||
t.Errorf("Expected nil object and not created")
|
||||
}
|
||||
if !errors.IsInvalid(err) && !errors.IsBadRequest(err) {
|
||||
t.Errorf("Expected invalid or bad request error, got %v of type %T", err, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEtcdControllerValidatesNamespaceOnUpdate(t *testing.T) {
|
||||
storage, _ := newStorage(t)
|
||||
ns := "newnamespace"
|
||||
|
||||
// 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
|
||||
// controller is valid.
|
||||
updateController, err := createController(storage, validController, t)
|
||||
|
||||
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")
|
||||
}
|
||||
// updateFunc
|
||||
func(obj runtime.Object) runtime.Object {
|
||||
object := obj.(*api.ReplicationController)
|
||||
object.Spec.Replicas = object.Spec.Replicas + 1
|
||||
return object
|
||||
},
|
||||
// invalid updateFunc
|
||||
func(obj runtime.Object) runtime.Object {
|
||||
object := obj.(*api.ReplicationController)
|
||||
object.UID = "newUID"
|
||||
return object
|
||||
},
|
||||
func(obj runtime.Object) runtime.Object {
|
||||
object := obj.(*api.ReplicationController)
|
||||
object.Name = ""
|
||||
return object
|
||||
},
|
||||
func(obj runtime.Object) runtime.Object {
|
||||
object := obj.(*api.ReplicationController)
|
||||
object.Spec.Selector = map[string]string{}
|
||||
return object
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func TestGenerationNumber(t *testing.T) {
|
||||
storage, _ := newStorage(t)
|
||||
modifiedSno := validController
|
||||
modifiedSno := *validNewController()
|
||||
modifiedSno.Generation = 100
|
||||
modifiedSno.Status.ObservedGeneration = 10
|
||||
ctx := api.NewDefaultContext()
|
||||
|
@ -225,17 +202,15 @@ func TestGenerationNumber(t *testing.T) {
|
|||
func TestEtcdGetController(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
copy := validController
|
||||
test.TestGet(©)
|
||||
test.TestGet(validNewController())
|
||||
}
|
||||
|
||||
func TestEtcdListControllers(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
key := etcdtest.AddPrefix(storage.KeyRootFunc(test.TestContext()))
|
||||
copy := validController
|
||||
test.TestList(
|
||||
©,
|
||||
validNewController(),
|
||||
func(objects []runtime.Object) []runtime.Object {
|
||||
return registrytest.SetObjectsForKey(fakeClient, key, objects)
|
||||
},
|
||||
|
@ -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) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, fakeClient := newStorage(t)
|
||||
key, _ := storage.KeyFunc(ctx, validController.Name)
|
||||
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)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
|
@ -491,7 +441,7 @@ func TestDelete(t *testing.T) {
|
|||
key = etcdtest.AddPrefix(key)
|
||||
|
||||
createFn := func() runtime.Object {
|
||||
rc := validController
|
||||
rc := *validNewController()
|
||||
rc.ResourceVersion = "1"
|
||||
fakeClient.Data[key] = tools.EtcdResponseWithError{
|
||||
R: &etcd.Response{
|
||||
|
|
|
@ -22,7 +22,6 @@ import (
|
|||
|
||||
"github.com/coreos/go-etcd/etcd"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/errors"
|
||||
"k8s.io/kubernetes/pkg/api/latest"
|
||||
"k8s.io/kubernetes/pkg/api/rest/resttest"
|
||||
"k8s.io/kubernetes/pkg/expapi"
|
||||
|
@ -57,228 +56,133 @@ func createController(storage *REST, dc expapi.Daemon, t *testing.T) (expapi.Dae
|
|||
return *newDc, nil
|
||||
}
|
||||
|
||||
var validPodTemplate = api.PodTemplate{
|
||||
Template: api.PodTemplateSpec{
|
||||
func validNewDaemon() *expapi.Daemon {
|
||||
return &expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: map[string]string{"a": "b"},
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
{
|
||||
Name: "test",
|
||||
Image: "test_image",
|
||||
ImagePullPolicy: api.PullIfNotPresent,
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: map[string]string{"a": "b"},
|
||||
Template: &api.PodTemplateSpec{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: map[string]string{"a": "b"},
|
||||
},
|
||||
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 = expapi.DaemonSpec{
|
||||
Selector: validPodTemplate.Template.Labels,
|
||||
Template: &validPodTemplate.Template,
|
||||
}
|
||||
|
||||
var validController = expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "default"},
|
||||
Spec: validControllerSpec,
|
||||
}
|
||||
var validDaemon = *validNewDaemon()
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
controller := validNewDaemon()
|
||||
controller.ObjectMeta = api.ObjectMeta{}
|
||||
test.TestCreate(
|
||||
// valid
|
||||
&expapi.Daemon{
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: map[string]string{"a": "b"},
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
controller,
|
||||
func(ctx api.Context, obj runtime.Object) error {
|
||||
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
|
||||
},
|
||||
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
|
||||
},
|
||||
// invalid
|
||||
// invalid (invalid selector)
|
||||
&expapi.Daemon{
|
||||
Spec: expapi.DaemonSpec{
|
||||
Selector: map[string]string{},
|
||||
Template: &validPodTemplate.Template,
|
||||
Template: validDaemon.Spec.Template,
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// makeControllerKey constructs etcd paths to controller items enforcing namespace rules.
|
||||
func makeControllerKey(ctx api.Context, id string) (string, error) {
|
||||
return etcdgeneric.NamespaceKeyFunc(ctx, daemonPrefix, id)
|
||||
}
|
||||
|
||||
// makeControllerListKey constructs etcd paths to the root of the resource,
|
||||
// not a specific controller resource
|
||||
func makeControllerListKey(ctx api.Context) string {
|
||||
return etcdgeneric.NamespaceKeyRootFunc(ctx, daemonPrefix)
|
||||
func TestUpdate(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
test.TestUpdate(
|
||||
// valid
|
||||
validNewDaemon(),
|
||||
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.Daemon)
|
||||
object.Spec.Template.Spec.NodeSelector = map[string]string{"c": "d"}
|
||||
return object
|
||||
},
|
||||
// invalid updateFunc
|
||||
func(obj runtime.Object) runtime.Object {
|
||||
object := obj.(*expapi.Daemon)
|
||||
object.UID = "newUID"
|
||||
return object
|
||||
},
|
||||
func(obj runtime.Object) runtime.Object {
|
||||
object := obj.(*expapi.Daemon)
|
||||
object.Name = ""
|
||||
return object
|
||||
},
|
||||
func(obj runtime.Object) runtime.Object {
|
||||
object := obj.(*expapi.Daemon)
|
||||
object.Spec.Template.Spec.RestartPolicy = api.RestartPolicyOnFailure
|
||||
return object
|
||||
},
|
||||
func(obj runtime.Object) runtime.Object {
|
||||
object := obj.(*expapi.Daemon)
|
||||
object.Spec.Selector = map[string]string{}
|
||||
return object
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func TestEtcdGetController(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, fakeClient := newStorage(t)
|
||||
key, _ := makeControllerKey(ctx, validController.Name)
|
||||
key = etcdtest.AddPrefix(key)
|
||||
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &validController), 0)
|
||||
ctrl, err := storage.Get(ctx, validController.Name)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
controller, ok := ctrl.(*expapi.Daemon)
|
||||
if !ok {
|
||||
t.Errorf("Expected a controller, got %#v", ctrl)
|
||||
}
|
||||
if controller.Name != validController.Name {
|
||||
t.Errorf("Unexpected controller: %#v", controller)
|
||||
}
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
test.TestGet(validNewDaemon())
|
||||
}
|
||||
|
||||
func TestEtcdControllerValidatesUpdate(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, _ := newStorage(t)
|
||||
|
||||
updateController, err := createController(storage, validController, t)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create controller, cannot proceed with test.")
|
||||
}
|
||||
|
||||
updaters := []func(dc expapi.Daemon) (runtime.Object, bool, error){
|
||||
func(dc expapi.Daemon) (runtime.Object, bool, error) {
|
||||
dc.UID = "newUID"
|
||||
return storage.Update(ctx, &dc)
|
||||
},
|
||||
func(dc expapi.Daemon) (runtime.Object, bool, error) {
|
||||
dc.Name = ""
|
||||
return storage.Update(ctx, &dc)
|
||||
},
|
||||
func(dc expapi.Daemon) (runtime.Object, bool, error) {
|
||||
dc.Spec.Template.Spec.RestartPolicy = api.RestartPolicyOnFailure
|
||||
return storage.Update(ctx, &dc)
|
||||
},
|
||||
func(dc expapi.Daemon) (runtime.Object, bool, error) {
|
||||
dc.Spec.Selector = map[string]string{}
|
||||
return storage.Update(ctx, &dc)
|
||||
},
|
||||
}
|
||||
for _, u := range updaters {
|
||||
c, updated, err := u(updateController)
|
||||
if c != nil || updated {
|
||||
t.Errorf("Expected nil object and not created")
|
||||
}
|
||||
if !errors.IsInvalid(err) && !errors.IsBadRequest(err) {
|
||||
t.Errorf("Expected invalid or bad request error, got %v of type %T", err, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEtcdControllerValidatesNamespaceOnUpdate(t *testing.T) {
|
||||
storage, _ := newStorage(t)
|
||||
ns := "newnamespace"
|
||||
|
||||
// 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
|
||||
// controller is valid.
|
||||
updateController, err := createController(storage, validController, t)
|
||||
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
||||
// TestEtcdGetControllerDifferentNamespace ensures same-name controllers in different namespaces do not clash
|
||||
func TestEtcdGetControllerDifferentNamespace(t *testing.T) {
|
||||
func TestEtcdListControllers(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
|
||||
otherNs := "other"
|
||||
ctx1 := api.NewDefaultContext()
|
||||
ctx2 := api.WithNamespace(api.NewContext(), otherNs)
|
||||
|
||||
key1, _ := makeControllerKey(ctx1, validController.Name)
|
||||
key2, _ := makeControllerKey(ctx2, validController.Name)
|
||||
|
||||
key1 = etcdtest.AddPrefix(key1)
|
||||
key2 = etcdtest.AddPrefix(key2)
|
||||
|
||||
fakeClient.Set(key1, runtime.EncodeOrDie(latest.Codec, &validController), 0)
|
||||
otherNsController := validController
|
||||
otherNsController.Namespace = otherNs
|
||||
fakeClient.Set(key2, runtime.EncodeOrDie(latest.Codec, &otherNsController), 0)
|
||||
|
||||
obj, err := storage.Get(ctx1, validController.Name)
|
||||
ctrl1, _ := obj.(*expapi.Daemon)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if ctrl1.Name != "foo" {
|
||||
t.Errorf("Unexpected controller: %#v", ctrl1)
|
||||
}
|
||||
if ctrl1.Namespace != "default" {
|
||||
t.Errorf("Unexpected controller: %#v", ctrl1)
|
||||
}
|
||||
|
||||
obj, err = storage.Get(ctx2, validController.Name)
|
||||
ctrl2, _ := obj.(*expapi.Daemon)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if ctrl2.Name != "foo" {
|
||||
t.Errorf("Unexpected controller: %#v", ctrl2)
|
||||
}
|
||||
if ctrl2.Namespace != "other" {
|
||||
t.Errorf("Unexpected controller: %#v", ctrl2)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestEtcdGetControllerNotFound(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, fakeClient := newStorage(t)
|
||||
key, _ := makeControllerKey(ctx, validController.Name)
|
||||
key = etcdtest.AddPrefix(key)
|
||||
|
||||
fakeClient.Data[key] = tools.EtcdResponseWithError{
|
||||
R: &etcd.Response{
|
||||
Node: nil,
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
key := etcdtest.AddPrefix(storage.KeyRootFunc(test.TestContext()))
|
||||
test.TestList(
|
||||
validNewDaemon(),
|
||||
func(objects []runtime.Object) []runtime.Object {
|
||||
return registrytest.SetObjectsForKey(fakeClient, key, objects)
|
||||
},
|
||||
E: tools.EtcdErrorNotFound,
|
||||
}
|
||||
ctrl, err := storage.Get(ctx, validController.Name)
|
||||
if ctrl != nil {
|
||||
t.Errorf("Unexpected non-nil controller: %#v", ctrl)
|
||||
}
|
||||
if !errors.IsNotFound(err) {
|
||||
t.Errorf("Unexpected error returned: %#v", err)
|
||||
}
|
||||
func(resourceVersion uint64) {
|
||||
registrytest.SetResourceVersion(fakeClient, resourceVersion)
|
||||
})
|
||||
}
|
||||
|
||||
func TestEtcdDeleteController(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, fakeClient := newStorage(t)
|
||||
key, _ := makeControllerKey(ctx, validController.Name)
|
||||
key, err := storage.KeyFunc(ctx, validDaemon.Name)
|
||||
key = etcdtest.AddPrefix(key)
|
||||
|
||||
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &validController), 0)
|
||||
obj, err := storage.Delete(ctx, validController.Name, nil)
|
||||
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, validNewDaemon()), 0)
|
||||
obj, err := storage.Delete(ctx, validDaemon.Name, nil)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
@ -295,96 +199,6 @@ func TestEtcdDeleteController(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestEtcdListControllers(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
ctx := api.NewDefaultContext()
|
||||
key := makeControllerListKey(ctx)
|
||||
key = etcdtest.AddPrefix(key)
|
||||
controller := validController
|
||||
controller.Name = "bar"
|
||||
fakeClient.Data[key] = tools.EtcdResponseWithError{
|
||||
R: &etcd.Response{
|
||||
Node: &etcd.Node{
|
||||
Nodes: []*etcd.Node{
|
||||
{
|
||||
Value: runtime.EncodeOrDie(latest.Codec, &validController),
|
||||
},
|
||||
{
|
||||
Value: runtime.EncodeOrDie(latest.Codec, &controller),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
E: nil,
|
||||
}
|
||||
objList, err := storage.List(ctx, labels.Everything(), fields.Everything())
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
controllers, _ := objList.(*expapi.DaemonList)
|
||||
if len(controllers.Items) != 2 || controllers.Items[0].Name != validController.Name || controllers.Items[1].Name != controller.Name {
|
||||
t.Errorf("Unexpected controller list: %#v", controllers)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEtcdListControllersNotFound(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
ctx := api.NewDefaultContext()
|
||||
key := makeControllerListKey(ctx)
|
||||
key = etcdtest.AddPrefix(key)
|
||||
|
||||
fakeClient.Data[key] = tools.EtcdResponseWithError{
|
||||
R: &etcd.Response{},
|
||||
E: tools.EtcdErrorNotFound,
|
||||
}
|
||||
objList, err := storage.List(ctx, labels.Everything(), fields.Everything())
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
controllers, _ := objList.(*expapi.DaemonList)
|
||||
if len(controllers.Items) != 0 {
|
||||
t.Errorf("Unexpected controller list: %#v", controllers)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEtcdListControllersLabelsMatch(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
ctx := api.NewDefaultContext()
|
||||
key := makeControllerListKey(ctx)
|
||||
key = etcdtest.AddPrefix(key)
|
||||
|
||||
controller := validController
|
||||
controller.Labels = map[string]string{"k": "v"}
|
||||
controller.Name = "bar"
|
||||
|
||||
fakeClient.Data[key] = tools.EtcdResponseWithError{
|
||||
R: &etcd.Response{
|
||||
Node: &etcd.Node{
|
||||
Nodes: []*etcd.Node{
|
||||
{
|
||||
Value: runtime.EncodeOrDie(latest.Codec, &validController),
|
||||
},
|
||||
{
|
||||
Value: runtime.EncodeOrDie(latest.Codec, &controller),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
E: nil,
|
||||
}
|
||||
testLabels := labels.SelectorFromSet(labels.Set(controller.Labels))
|
||||
objList, err := storage.List(ctx, testLabels, fields.Everything())
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
controllers, _ := objList.(*expapi.DaemonList)
|
||||
if len(controllers.Items) != 1 || controllers.Items[0].Name != controller.Name ||
|
||||
!testLabels.Matches(labels.Set(controllers.Items[0].Labels)) {
|
||||
t.Errorf("Unexpected controller list: %#v for query with labels %#v",
|
||||
controllers, testLabels)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEtcdWatchController(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, fakeClient := newStorage(t)
|
||||
|
@ -414,12 +228,12 @@ func TestEtcdWatchController(t *testing.T) {
|
|||
|
||||
// Tests that we can watch for the creation of daemon controllers with specified labels.
|
||||
func TestEtcdWatchControllersMatch(t *testing.T) {
|
||||
ctx := api.WithNamespace(api.NewDefaultContext(), validController.Namespace)
|
||||
ctx := api.WithNamespace(api.NewDefaultContext(), validDaemon.Namespace)
|
||||
storage, fakeClient := newStorage(t)
|
||||
fakeClient.ExpectNotFoundGet(etcdgeneric.NamespaceKeyRootFunc(ctx, "/registry/pods"))
|
||||
|
||||
watching, err := storage.Watch(ctx,
|
||||
labels.SelectorFromSet(validController.Spec.Selector),
|
||||
labels.SelectorFromSet(validDaemon.Spec.Selector),
|
||||
fields.Everything(),
|
||||
"1",
|
||||
)
|
||||
|
@ -434,7 +248,7 @@ func TestEtcdWatchControllersMatch(t *testing.T) {
|
|||
controller := &expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Labels: validController.Spec.Selector,
|
||||
Labels: validDaemon.Spec.Selector,
|
||||
Namespace: "default",
|
||||
},
|
||||
}
|
||||
|
@ -458,7 +272,7 @@ func TestEtcdWatchControllersMatch(t *testing.T) {
|
|||
|
||||
// Tests that we can watch for daemon controllers with specified fields.
|
||||
func TestEtcdWatchControllersFields(t *testing.T) {
|
||||
ctx := api.WithNamespace(api.NewDefaultContext(), validController.Namespace)
|
||||
ctx := api.WithNamespace(api.NewDefaultContext(), validDaemon.Namespace)
|
||||
storage, fakeClient := newStorage(t)
|
||||
fakeClient.ExpectNotFoundGet(etcdgeneric.NamespaceKeyRootFunc(ctx, "/registry/pods"))
|
||||
|
||||
|
@ -480,7 +294,7 @@ func TestEtcdWatchControllersFields(t *testing.T) {
|
|||
controller := &expapi.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Labels: validController.Spec.Selector,
|
||||
Labels: validDaemon.Spec.Selector,
|
||||
Namespace: "default",
|
||||
},
|
||||
Status: expapi.DaemonStatus{
|
||||
|
@ -578,21 +392,21 @@ func TestDelete(t *testing.T) {
|
|||
ctx := api.NewDefaultContext()
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
key, _ := makeControllerKey(ctx, validController.Name)
|
||||
key, _ := storage.KeyFunc(ctx, validDaemon.Name)
|
||||
key = etcdtest.AddPrefix(key)
|
||||
|
||||
createFn := func() runtime.Object {
|
||||
dc := validController
|
||||
dc := validNewDaemon()
|
||||
dc.ResourceVersion = "1"
|
||||
fakeClient.Data[key] = tools.EtcdResponseWithError{
|
||||
R: &etcd.Response{
|
||||
Node: &etcd.Node{
|
||||
Value: runtime.EncodeOrDie(latest.Codec, &dc),
|
||||
Value: runtime.EncodeOrDie(latest.Codec, dc),
|
||||
ModifiedIndex: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
return &dc
|
||||
return dc
|
||||
}
|
||||
gracefulSetFn := func() bool {
|
||||
// If the controller is still around after trying to delete either the delete
|
||||
|
|
|
@ -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) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, fakeClient := newStorage(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) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, fakeClient := newStorage(t)
|
||||
|
|
|
@ -78,26 +78,24 @@ func TestCreate(t *testing.T) {
|
|||
func TestUpdate(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
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(
|
||||
autoscaler,
|
||||
existing,
|
||||
older,
|
||||
// valid
|
||||
validNewHorizontalPodAutoscaler("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.(*expapi.HorizontalPodAutoscaler)
|
||||
object.Spec.MaxCount = object.Spec.MaxCount + 1
|
||||
return object
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
|||
)
|
||||
}
|
||||
|
||||
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) {
|
||||
ctx := api.NewContext()
|
||||
storage, fakeClient := newStorage(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) {
|
||||
ctx := api.NewContext()
|
||||
storage, fakeClient := newStorage(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) {
|
||||
ctx := api.NewContext()
|
||||
storage, _, fakeClient := newStorage(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) {
|
||||
ctx := api.NewContext()
|
||||
storage, _, fakeClient := newStorage(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) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, _, fakeClient := newStorage(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) {
|
||||
storage, _, _, fakeClient := newStorage(t)
|
||||
ctx := api.NewDefaultContext()
|
||||
|
@ -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) {
|
||||
expectedIP := "1.2.3.4"
|
||||
testCases := []struct {
|
||||
|
@ -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) {
|
||||
storage, _, _, fakeClient := newStorage(t)
|
||||
ctx := api.NewDefaultContext()
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/tools"
|
||||
"k8s.io/kubernetes/pkg/tools/etcdtest"
|
||||
)
|
||||
|
||||
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
|
||||
|
@ -83,27 +82,23 @@ func TestCreate(t *testing.T) {
|
|||
func TestUpdate(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
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(
|
||||
pod,
|
||||
existing,
|
||||
older,
|
||||
//valid
|
||||
validNewPodTemplate("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.PodTemplate)
|
||||
object.Template.Spec.NodeSelector = map[string]string{"a": "b"}
|
||||
return object
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/tools"
|
||||
"k8s.io/kubernetes/pkg/tools/etcdtest"
|
||||
)
|
||||
|
||||
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
|
||||
|
@ -74,27 +73,23 @@ func TestCreate(t *testing.T) {
|
|||
func TestUpdate(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
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(
|
||||
secret,
|
||||
existing,
|
||||
older,
|
||||
// valid
|
||||
validNewSecret("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.Secret)
|
||||
object.Data["othertest"] = []byte("otherdata")
|
||||
return object
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
@ -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 (
|
|||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/tools"
|
||||
"k8s.io/kubernetes/pkg/tools/etcdtest"
|
||||
)
|
||||
|
||||
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
|
||||
|
@ -67,27 +66,23 @@ func TestCreate(t *testing.T) {
|
|||
func TestUpdate(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
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(
|
||||
serviceAccount,
|
||||
existing,
|
||||
older,
|
||||
// valid
|
||||
validNewServiceAccount("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.ServiceAccount)
|
||||
// TODO: Update this serviceAccount
|
||||
return object
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
@ -80,26 +80,24 @@ func TestCreate(t *testing.T) {
|
|||
func TestUpdate(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
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(
|
||||
rsrc,
|
||||
existing,
|
||||
older,
|
||||
// valid
|
||||
validNewThirdPartyResource("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.(*expapi.ThirdPartyResource)
|
||||
object.Description = "new description"
|
||||
return object
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue