Update generic etcd tests for cluster-scoped objects

pull/6/head
Jordan Liggitt 2015-05-18 23:17:51 -04:00
parent c5da035d51
commit a6401fa433
7 changed files with 146 additions and 66 deletions

View File

@ -57,6 +57,24 @@ func (t *Tester) ClusterScope() *Tester {
return t
}
// TestNamespace returns the namespace that will be used when creating contexts.
// Returns NamespaceNone for cluster-scoped objects.
func (t *Tester) TestNamespace() string {
if t.clusterScope {
return api.NamespaceNone
}
return "test"
}
// TestContext returns a namespaced context that will be used when making storage calls.
// Namespace is determined by TestNamespace()
func (t *Tester) TestContext() api.Context {
if t.clusterScope {
return api.NewContext()
}
return api.WithNamespace(api.NewContext(), t.TestNamespace())
}
func copyOrDie(obj runtime.Object) runtime.Object {
out, err := api.Scheme.Copy(obj)
if err != nil {
@ -70,7 +88,9 @@ func (t *Tester) TestCreate(valid runtime.Object, invalid ...runtime.Object) {
t.TestCreateGeneratesName(copyOrDie(valid))
t.TestCreateGeneratesNameReturnsServerTimeout(copyOrDie(valid))
if t.clusterScope {
t.TestCreateRejectsNamespace(copyOrDie(valid))
t.TestCreateDiscardsObjectNamespace(copyOrDie(valid))
t.TestCreateIgnoresContextNamespace(copyOrDie(valid))
t.TestCreateIgnoresMismatchedNamespace(copyOrDie(valid))
} else {
t.TestCreateRejectsMismatchedNamespace(copyOrDie(valid))
}
@ -87,7 +107,7 @@ func (t *Tester) TestCreateResetsUserData(valid runtime.Object) {
objectMeta.UID = "bad-uid"
objectMeta.CreationTimestamp = now
obj, err := t.storage.(rest.Creater).Create(api.NewDefaultContext(), valid)
obj, err := t.storage.(rest.Creater).Create(t.TestContext(), valid)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
@ -105,15 +125,11 @@ func (t *Tester) TestCreateHasMetadata(valid runtime.Object) {
t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, valid)
}
objectMeta.Name = "test"
objectMeta.Namespace = api.NamespaceDefault
context := api.NewDefaultContext()
if t.clusterScope {
objectMeta.Namespace = api.NamespaceNone
context = api.NewContext()
}
objectMeta.Name = ""
objectMeta.GenerateName = "test-"
objectMeta.Namespace = t.TestNamespace()
obj, err := t.storage.(rest.Creater).Create(context, valid)
obj, err := t.storage.(rest.Creater).Create(t.TestContext(), valid)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
@ -131,9 +147,10 @@ func (t *Tester) TestCreateGeneratesName(valid runtime.Object) {
t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, valid)
}
objectMeta.Name = ""
objectMeta.GenerateName = "test-"
_, err = t.storage.(rest.Creater).Create(api.NewDefaultContext(), valid)
_, err = t.storage.(rest.Creater).Create(t.TestContext(), valid)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
@ -148,9 +165,10 @@ func (t *Tester) TestCreateGeneratesNameReturnsServerTimeout(valid runtime.Objec
t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, valid)
}
objectMeta.Name = ""
objectMeta.GenerateName = "test-"
t.withStorageError(errors.NewAlreadyExists("kind", "thing"), func() {
_, err := t.storage.(rest.Creater).Create(api.NewDefaultContext(), valid)
_, err := t.storage.(rest.Creater).Create(t.TestContext(), valid)
if err == nil || !errors.IsServerTimeout(err) {
t.Fatalf("Unexpected error: %v", err)
}
@ -159,7 +177,7 @@ func (t *Tester) TestCreateGeneratesNameReturnsServerTimeout(valid runtime.Objec
func (t *Tester) TestCreateInvokesValidation(invalid ...runtime.Object) {
for i, obj := range invalid {
ctx := api.NewDefaultContext()
ctx := t.TestContext()
_, err := t.storage.(rest.Creater).Create(ctx, obj)
if !errors.IsInvalid(err) {
t.Errorf("%d: Expected to get an invalid resource error, got %v", i, err)
@ -175,27 +193,76 @@ func (t *Tester) TestCreateRejectsMismatchedNamespace(valid runtime.Object) {
objectMeta.Namespace = "not-default"
_, err = t.storage.(rest.Creater).Create(api.NewDefaultContext(), valid)
_, err = t.storage.(rest.Creater).Create(t.TestContext(), valid)
if err == nil {
t.Errorf("Expected an error, but we didn't get one")
} else if strings.Contains(err.Error(), "Controller.Namespace does not match the provided context") {
t.Errorf("Expected 'Controller.Namespace does not match the provided context' error, got '%v'", err)
} 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())
}
}
func (t *Tester) TestCreateRejectsNamespace(valid runtime.Object) {
func (t *Tester) TestCreateDiscardsObjectNamespace(valid runtime.Object) {
objectMeta, err := api.ObjectMetaFor(valid)
if err != nil {
t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, valid)
}
// Ignore non-empty namespace in object meta
objectMeta.Namespace = "not-default"
_, err = t.storage.(rest.Creater).Create(api.NewDefaultContext(), valid)
if err == nil {
t.Errorf("Expected an error, but we didn't get one")
} else if strings.Contains(err.Error(), "Controller.Namespace does not match the provided context") {
t.Errorf("Expected 'Controller.Namespace does not match the provided context' error, got '%v'", err)
// Ideally, we'd get an error back here, but at least verify the namespace wasn't persisted
created, err := t.storage.(rest.Creater).Create(t.TestContext(), copyOrDie(valid))
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
createdObjectMeta, err := api.ObjectMetaFor(created)
if err != nil {
t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, created)
}
if createdObjectMeta.Namespace != api.NamespaceNone {
t.Errorf("Expected empty namespace on created object, got '%v'", createdObjectMeta.Namespace)
}
}
func (t *Tester) TestCreateIgnoresContextNamespace(valid runtime.Object) {
// Ignore non-empty namespace in context
ctx := api.WithNamespace(api.NewContext(), "not-default2")
// Ideally, we'd get an error back here, but at least verify the namespace wasn't persisted
created, err := t.storage.(rest.Creater).Create(ctx, copyOrDie(valid))
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
createdObjectMeta, err := api.ObjectMetaFor(created)
if err != nil {
t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, created)
}
if createdObjectMeta.Namespace != api.NamespaceNone {
t.Errorf("Expected empty namespace on created object, got '%v'", createdObjectMeta.Namespace)
}
}
func (t *Tester) TestCreateIgnoresMismatchedNamespace(valid runtime.Object) {
objectMeta, err := api.ObjectMetaFor(valid)
if err != nil {
t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, valid)
}
// Ignore non-empty namespace in object meta
objectMeta.Namespace = "not-default"
ctx := api.WithNamespace(api.NewContext(), "not-default2")
// Ideally, we'd get an error back here, but at least verify the namespace wasn't persisted
created, err := t.storage.(rest.Creater).Create(ctx, copyOrDie(valid))
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
createdObjectMeta, err := api.ObjectMetaFor(created)
if err != nil {
t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, created)
}
if createdObjectMeta.Namespace != api.NamespaceNone {
t.Errorf("Expected empty namespace on created object, got '%v'", createdObjectMeta.Namespace)
}
}
@ -205,7 +272,7 @@ func (t *Tester) TestUpdate(valid runtime.Object, existing, older runtime.Object
}
func (t *Tester) TestUpdateFailsOnNotFound(valid runtime.Object) {
_, _, err := t.storage.(rest.Updater).Update(api.NewDefaultContext(), valid)
_, _, 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) {
@ -214,7 +281,7 @@ func (t *Tester) TestUpdateFailsOnNotFound(valid runtime.Object) {
}
func (t *Tester) TestUpdateFailsOnVersion(older runtime.Object) {
_, _, err := t.storage.(rest.Updater).Update(api.NewDefaultContext(), older)
_, _, err := t.storage.(rest.Updater).Update(t.TestContext(), older)
if err == nil {
t.Errorf("Expected an error, but we didn't get one")
} else if !errors.IsConflict(err) {
@ -228,7 +295,7 @@ func (t *Tester) TestDeleteInvokesValidation(invalid ...runtime.Object) {
if err != nil {
t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, obj)
}
ctx := api.NewDefaultContext()
ctx := t.TestContext()
_, err = t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, nil)
if !errors.IsInvalid(err) {
t.Errorf("%d: Expected to get an invalid resource error, got %v", i, err)
@ -250,7 +317,7 @@ func (t *Tester) TestDeleteNonExist(createFn func() runtime.Object) {
if err != nil {
t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, existing)
}
context := api.NewDefaultContext()
context := t.TestContext()
t.withStorageError(&etcd.EtcdError{ErrorCode: tools.EtcdErrorCodeNotFound}, func() {
_, err := t.storage.(rest.GracefulDeleter).Delete(context, objectMeta.Name, nil)
@ -271,7 +338,7 @@ func (t *Tester) TestDeleteNoGraceful(createFn func() runtime.Object, wasGracefu
if err != nil {
t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, existing)
}
ctx := api.WithNamespace(api.NewContext(), objectMeta.Namespace)
ctx := api.WithNamespace(t.TestContext(), objectMeta.Namespace)
_, err = t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, api.NewDeleteOptions(10))
if err != nil {
t.Errorf("unexpected error: %v", err)
@ -290,7 +357,7 @@ func (t *Tester) TestDeleteGracefulHasDefault(existing runtime.Object, expectedG
t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, existing)
}
ctx := api.WithNamespace(api.NewContext(), objectMeta.Namespace)
ctx := api.WithNamespace(t.TestContext(), objectMeta.Namespace)
_, err = t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, &api.DeleteOptions{})
if err != nil {
t.Errorf("unexpected error: %v", err)
@ -309,7 +376,7 @@ func (t *Tester) TestDeleteGracefulUsesZeroOnNil(existing runtime.Object, expect
t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, existing)
}
ctx := api.WithNamespace(api.NewContext(), objectMeta.Namespace)
ctx := api.WithNamespace(t.TestContext(), objectMeta.Namespace)
_, err = t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, nil)
if err != nil {
t.Errorf("unexpected error: %v", err)

View File

@ -88,9 +88,9 @@ func validChangedNode() *api.Node {
func TestCreate(t *testing.T) {
storage, fakeEtcdClient := newStorage(t)
test := resttest.New(t, storage, fakeEtcdClient.SetError)
test := resttest.New(t, storage, fakeEtcdClient.SetError).ClusterScope()
node := validNewNode()
node.ObjectMeta = api.ObjectMeta{}
node.ObjectMeta = api.ObjectMeta{GenerateName: "foo"}
test.TestCreate(
// valid
node,
@ -102,9 +102,9 @@ func TestCreate(t *testing.T) {
}
func TestDelete(t *testing.T) {
ctx := api.NewDefaultContext()
ctx := api.NewContext()
storage, fakeEtcdClient := newStorage(t)
test := resttest.New(t, storage, fakeEtcdClient.SetError)
test := resttest.New(t, storage, fakeEtcdClient.SetError).ClusterScope()
node := validChangedNode()
key, _ := storage.KeyFunc(ctx, node.Name)

View File

@ -71,15 +71,15 @@ func TestStorage(t *testing.T) {
func TestCreate(t *testing.T) {
fakeEtcdClient, helper := newHelper(t)
storage, _, _ := NewStorage(helper)
test := resttest.New(t, storage, fakeEtcdClient.SetError)
test := resttest.New(t, storage, fakeEtcdClient.SetError).ClusterScope()
namespace := validNewNamespace()
namespace.ObjectMeta = api.ObjectMeta{}
namespace.ObjectMeta = api.ObjectMeta{GenerateName: "foo"}
test.TestCreate(
// valid
namespace,
// invalid
&api.Namespace{
ObjectMeta: api.ObjectMeta{Namespace: "nope"},
ObjectMeta: api.ObjectMeta{Name: "bad value"},
},
)
}
@ -97,13 +97,13 @@ func TestCreateSetsFields(t *testing.T) {
fakeEtcdClient, helper := newHelper(t)
storage, _, _ := NewStorage(helper)
namespace := validNewNamespace()
_, err := storage.Create(api.NewDefaultContext(), namespace)
_, err := storage.Create(api.NewContext(), namespace)
if err != fakeEtcdClient.Err {
t.Fatalf("unexpected error: %v", err)
}
actual := &api.Namespace{}
ctx := api.NewDefaultContext()
ctx := api.NewContext()
key, err := storage.Etcd.KeyFunc(ctx, "foo")
if err != nil {
t.Fatalf("unexpected key error: %v", err)
@ -166,7 +166,7 @@ func TestListNamespaceList(t *testing.T) {
},
}
storage, _, _ := NewStorage(helper)
namespacesObj, err := storage.List(api.NewDefaultContext(), labels.Everything(), fields.Everything())
namespacesObj, err := storage.List(api.NewContext(), labels.Everything(), fields.Everything())
namespaces := namespacesObj.(*api.NamespaceList)
if err != nil {
t.Fatalf("unexpected error: %v", err)
@ -214,7 +214,7 @@ func TestListNamespaceListSelection(t *testing.T) {
},
}
storage, _, _ := NewStorage(helper)
ctx := api.NewDefaultContext()
ctx := api.NewContext()
table := []struct {
label, field string
expectedIDs util.StringSet
@ -285,7 +285,7 @@ func TestGet(t *testing.T) {
expect := validNewNamespace()
expect.Status.Phase = api.NamespaceActive
storage, fakeEtcdClient, _ := newStorage(t)
ctx := api.NewDefaultContext()
ctx := api.NewContext()
key, err := storage.Etcd.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
if err != nil {
@ -314,7 +314,7 @@ func TestDeleteNamespace(t *testing.T) {
fakeEtcdClient, helper := newHelper(t)
fakeEtcdClient.ChangeIndex = 1
storage, _, _ := NewStorage(helper)
ctx := api.NewDefaultContext()
ctx := api.NewContext()
key, err := storage.Etcd.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
@ -331,7 +331,7 @@ func TestDeleteNamespace(t *testing.T) {
},
},
}
_, err = storage.Delete(api.NewDefaultContext(), "foo", nil)
_, err = storage.Delete(api.NewContext(), "foo", nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
@ -362,7 +362,7 @@ func TestDeleteNamespaceWithIncompleteFinalizers(t *testing.T) {
},
}
storage, _, _ := NewStorage(helper)
_, err := storage.Delete(api.NewDefaultContext(), "foo", nil)
_, err := storage.Delete(api.NewContext(), "foo", nil)
if err == nil {
t.Fatalf("expected error: %v", err)
}
@ -392,7 +392,7 @@ func TestDeleteNamespaceWithCompleteFinalizers(t *testing.T) {
},
}
storage, _, _ := NewStorage(helper)
_, err := storage.Delete(api.NewDefaultContext(), "foo", nil)
_, err := storage.Delete(api.NewContext(), "foo", nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}

View File

@ -75,9 +75,9 @@ func validChangedPersistentVolume() *api.PersistentVolume {
func TestCreate(t *testing.T) {
storage, _, fakeEtcdClient, _ := newStorage(t)
test := resttest.New(t, storage, fakeEtcdClient.SetError)
test := resttest.New(t, storage, fakeEtcdClient.SetError).ClusterScope()
pv := validNewPersistentVolume("foo")
pv.ObjectMeta = api.ObjectMeta{}
pv.ObjectMeta = api.ObjectMeta{GenerateName: "foo"}
test.TestCreate(
// valid
pv,
@ -89,9 +89,9 @@ func TestCreate(t *testing.T) {
}
func TestDelete(t *testing.T) {
ctx := api.NewDefaultContext()
ctx := api.NewContext()
storage, _, fakeEtcdClient, _ := newStorage(t)
test := resttest.New(t, storage, fakeEtcdClient.SetError)
test := resttest.New(t, storage, fakeEtcdClient.SetError).ClusterScope()
pv := validChangedPersistentVolume()
key, _ := storage.KeyFunc(ctx, pv.Name)
@ -117,7 +117,7 @@ func TestDelete(t *testing.T) {
}
func TestEtcdListPersistentVolumes(t *testing.T) {
ctx := api.NewDefaultContext()
ctx := api.NewContext()
storage, _, fakeClient, _ := newStorage(t)
key := storage.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
@ -149,7 +149,7 @@ func TestEtcdListPersistentVolumes(t *testing.T) {
}
func TestEtcdGetPersistentVolumes(t *testing.T) {
ctx := api.NewDefaultContext()
ctx := api.NewContext()
storage, _, fakeClient, _ := newStorage(t)
persistentVolume := validNewPersistentVolume("foo")
name := persistentVolume.Name
@ -180,7 +180,7 @@ func TestEtcdGetPersistentVolumes(t *testing.T) {
}
func TestListEmptyPersistentVolumesList(t *testing.T) {
ctx := api.NewDefaultContext()
ctx := api.NewContext()
storage, _, fakeClient, _ := newStorage(t)
fakeClient.ChangeIndex = 1
key := storage.KeyRootFunc(ctx)
@ -204,7 +204,7 @@ func TestListEmptyPersistentVolumesList(t *testing.T) {
}
func TestListPersistentVolumesList(t *testing.T) {
ctx := api.NewDefaultContext()
ctx := api.NewContext()
storage, _, fakeClient, _ := newStorage(t)
fakeClient.ChangeIndex = 1
key := storage.KeyRootFunc(ctx)
@ -264,7 +264,7 @@ func TestPersistentVolumesDecode(t *testing.T) {
}
func TestEtcdUpdatePersistentVolumes(t *testing.T) {
ctx := api.NewDefaultContext()
ctx := api.NewContext()
storage, _, fakeClient, _ := newStorage(t)
persistentVolume := validChangedPersistentVolume()
@ -294,7 +294,7 @@ func TestEtcdUpdatePersistentVolumes(t *testing.T) {
}
func TestDeletePersistentVolumes(t *testing.T) {
ctx := api.NewDefaultContext()
ctx := api.NewContext()
storage, _, fakeClient, _ := newStorage(t)
persistentVolume := validNewPersistentVolume("foo")
name := persistentVolume.Name
@ -318,7 +318,7 @@ func TestDeletePersistentVolumes(t *testing.T) {
func TestEtcdUpdateStatus(t *testing.T) {
storage, statusStorage, fakeClient, helper := newStorage(t)
ctx := api.NewDefaultContext()
ctx := api.NewContext()
fakeClient.TestIndex = true
key, _ := storage.KeyFunc(ctx, "foo")

View File

@ -80,13 +80,18 @@ func TestUpdate(t *testing.T) {
fakeEtcdClient, helper := newHelper(t)
storage := NewREST(helper)
test := resttest.New(t, storage, fakeEtcdClient.SetError)
key := etcdtest.AddPrefix("podtemplates/default/foo")
key, err := storage.KeyFunc(test.TestContext(), "foo")
if err != nil {
t.Fatal(err)
}
key = etcdtest.AddPrefix(key)
fakeEtcdClient.ExpectNotFoundGet(key)
fakeEtcdClient.ChangeIndex = 2
pod := validNewPodTemplate("foo")
existing := validNewPodTemplate("exists")
obj, err := storage.Create(api.NewDefaultContext(), existing)
existing.Namespace = test.TestNamespace()
obj, err := storage.Create(test.TestContext(), existing)
if err != nil {
t.Fatalf("unable to create object: %v", err)
}

View File

@ -50,8 +50,7 @@ func TestCreate(t *testing.T) {
storage := NewStorage(helper)
test := resttest.New(t, storage, fakeEtcdClient.SetError)
secret := validNewSecret("foo")
secret.Name = ""
secret.GenerateName = "foo-"
secret.ObjectMeta = api.ObjectMeta{GenerateName: "foo-"}
test.TestCreate(
// valid
secret,
@ -72,13 +71,18 @@ func TestUpdate(t *testing.T) {
fakeEtcdClient, helper := newHelper(t)
storage := NewStorage(helper)
test := resttest.New(t, storage, fakeEtcdClient.SetError)
key := etcdtest.AddPrefix("secrets/default/foo")
key, err := storage.KeyFunc(test.TestContext(), "foo")
if err != nil {
t.Fatal(err)
}
key = etcdtest.AddPrefix(key)
fakeEtcdClient.ExpectNotFoundGet(key)
fakeEtcdClient.ChangeIndex = 2
secret := validNewSecret("foo")
existing := validNewSecret("exists")
obj, err := storage.Create(api.NewDefaultContext(), existing)
existing.Namespace = test.TestNamespace()
obj, err := storage.Create(test.TestContext(), existing)
if err != nil {
t.Fatalf("unable to create object: %v", err)
}

View File

@ -48,8 +48,7 @@ func TestCreate(t *testing.T) {
storage := NewStorage(helper)
test := resttest.New(t, storage, fakeEtcdClient.SetError)
serviceAccount := validNewServiceAccount("foo")
serviceAccount.Name = ""
serviceAccount.GenerateName = "foo-"
serviceAccount.ObjectMeta = api.ObjectMeta{GenerateName: "foo-"}
test.TestCreate(
// valid
serviceAccount,
@ -65,13 +64,18 @@ func TestUpdate(t *testing.T) {
fakeEtcdClient, helper := newHelper(t)
storage := NewStorage(helper)
test := resttest.New(t, storage, fakeEtcdClient.SetError)
key := etcdtest.AddPrefix("serviceaccounts/default/foo")
key, err := storage.KeyFunc(test.TestContext(), "foo")
if err != nil {
t.Fatal(err)
}
key = etcdtest.AddPrefix(key)
fakeEtcdClient.ExpectNotFoundGet(key)
fakeEtcdClient.ChangeIndex = 2
serviceAccount := validNewServiceAccount("foo")
existing := validNewServiceAccount("exists")
obj, err := storage.Create(api.NewDefaultContext(), existing)
existing.Namespace = test.TestNamespace()
obj, err := storage.Create(test.TestContext(), existing)
if err != nil {
t.Fatalf("unable to create object: %v", err)
}