mirror of https://github.com/k3s-io/k3s
Merge pull request #13509 from wojtek-t/refactor_etcd_delete_test
Refactor registry etcd delete testspull/6/head
commit
fcbf63f3f3
|
@ -42,6 +42,7 @@ type Tester struct {
|
|||
clusterScope bool
|
||||
createOnUpdate bool
|
||||
generatesName bool
|
||||
returnDeletedObject bool
|
||||
}
|
||||
|
||||
type injectErrorFunc func(err error)
|
||||
|
@ -75,6 +76,11 @@ func (t *Tester) GeneratesName() *Tester {
|
|||
return t
|
||||
}
|
||||
|
||||
func (t *Tester) ReturnDeletedObject() *Tester {
|
||||
t.returnDeletedObject = true
|
||||
return t
|
||||
}
|
||||
|
||||
// TestNamespace returns the namespace that will be used when creating contexts.
|
||||
// Returns NamespaceNone for cluster-scoped objects.
|
||||
func (t *Tester) TestNamespace() string {
|
||||
|
@ -125,6 +131,7 @@ type EmitFunc func(runtime.Object, string) error
|
|||
type GetFunc func(api.Context, runtime.Object) (runtime.Object, error)
|
||||
type InitWatchFunc func()
|
||||
type InjectErrFunc func(err error)
|
||||
type IsErrorFunc func(err error) bool
|
||||
type SetFunc func(api.Context, runtime.Object) error
|
||||
type SetRVFunc func(uint64)
|
||||
type UpdateFunc func(runtime.Object) runtime.Object
|
||||
|
@ -160,50 +167,45 @@ func (t *Tester) TestUpdate(valid runtime.Object, setFn SetFunc, setRVFn SetRVFu
|
|||
}
|
||||
|
||||
// Test deleting an object.
|
||||
// TODO(wojtek-t): Change it to use AssignFunc instead.
|
||||
func (t *Tester) TestDelete(createFn func() runtime.Object, wasGracefulFn func() bool, invalid ...runtime.Object) {
|
||||
t.TestDeleteNonExist(createFn)
|
||||
t.TestDeleteNoGraceful(createFn, wasGracefulFn)
|
||||
t.TestDeleteInvokesValidation(invalid...)
|
||||
// TODO: Test delete namespace mismatch rejection
|
||||
// once #5684 is fixed.
|
||||
func (t *Tester) TestDelete(valid runtime.Object, setFn SetFunc, getFn GetFunc, isNotFoundFn IsErrorFunc) {
|
||||
t.testDeleteNonExist(copyOrDie(valid))
|
||||
t.testDeleteNoGraceful(copyOrDie(valid), setFn, getFn, isNotFoundFn)
|
||||
}
|
||||
|
||||
// Test graceful deletion.
|
||||
// TODO(wojtek-t): Change it to use AssignFunc instead.
|
||||
func (t *Tester) TestDeleteGraceful(createFn func() runtime.Object, expectedGrace int64, wasGracefulFn func() bool) {
|
||||
t.TestDeleteGracefulHasDefault(createFn(), expectedGrace, wasGracefulFn)
|
||||
t.TestDeleteGracefulWithValue(createFn(), expectedGrace, wasGracefulFn)
|
||||
t.TestDeleteGracefulUsesZeroOnNil(createFn(), 0)
|
||||
t.TestDeleteGracefulExtend(createFn(), expectedGrace, wasGracefulFn)
|
||||
t.TestDeleteGracefulImmediate(createFn(), expectedGrace, wasGracefulFn)
|
||||
// Test gracefully deleting an object.
|
||||
func (t *Tester) TestDeleteGraceful(valid runtime.Object, setFn SetFunc, getFn GetFunc, expectedGrace int64) {
|
||||
t.testDeleteGracefulHasDefault(copyOrDie(valid), setFn, getFn, expectedGrace)
|
||||
t.testDeleteGracefulWithValue(copyOrDie(valid), setFn, getFn, expectedGrace)
|
||||
t.testDeleteGracefulUsesZeroOnNil(copyOrDie(valid), setFn, expectedGrace)
|
||||
t.testDeleteGracefulExtend(copyOrDie(valid), setFn, getFn, expectedGrace)
|
||||
t.testDeleteGracefulImmediate(copyOrDie(valid), setFn, getFn, expectedGrace)
|
||||
}
|
||||
|
||||
// Test getting object.
|
||||
func (t *Tester) TestGet(obj runtime.Object) {
|
||||
t.testGetFound(obj)
|
||||
t.testGetNotFound(obj)
|
||||
t.testGetMimatchedNamespace(obj)
|
||||
func (t *Tester) TestGet(valid runtime.Object) {
|
||||
t.testGetFound(copyOrDie(valid))
|
||||
t.testGetNotFound(copyOrDie(valid))
|
||||
t.testGetMimatchedNamespace(copyOrDie(valid))
|
||||
if !t.clusterScope {
|
||||
t.testGetDifferentNamespace(obj)
|
||||
t.testGetDifferentNamespace(copyOrDie(valid))
|
||||
}
|
||||
}
|
||||
|
||||
// Test listing objects.
|
||||
func (t *Tester) TestList(obj runtime.Object, assignFn AssignFunc, setRVFn SetRVFunc) {
|
||||
func (t *Tester) TestList(valid runtime.Object, assignFn AssignFunc, setRVFn SetRVFunc) {
|
||||
t.testListError()
|
||||
t.testListFound(obj, assignFn)
|
||||
t.testListFound(copyOrDie(valid), assignFn)
|
||||
t.testListNotFound(assignFn, setRVFn)
|
||||
t.testListMatchLabels(obj, assignFn)
|
||||
t.testListMatchLabels(copyOrDie(valid), assignFn)
|
||||
}
|
||||
|
||||
// Test watching objects.
|
||||
func (t *Tester) TestWatch(
|
||||
obj runtime.Object, initWatchFn InitWatchFunc, injectErrFn InjectErrFunc, emitFn EmitFunc,
|
||||
valid runtime.Object, initWatchFn InitWatchFunc, injectErrFn InjectErrFunc, emitFn EmitFunc,
|
||||
labelsPass, labelsFail []labels.Set, fieldsPass, fieldsFail []fields.Set, actions []string) {
|
||||
t.testWatch(initWatchFn, injectErrFn)
|
||||
t.testWatchLabels(copyOrDie(obj), initWatchFn, emitFn, labelsPass, labelsFail, actions)
|
||||
t.testWatchFields(copyOrDie(obj), initWatchFn, emitFn, fieldsPass, fieldsFail, actions)
|
||||
t.testWatchLabels(copyOrDie(valid), initWatchFn, emitFn, labelsPass, labelsFail, actions)
|
||||
t.testWatchFields(copyOrDie(valid), initWatchFn, emitFn, fieldsPass, fieldsFail, actions)
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
@ -512,26 +514,40 @@ func (t *Tester) testUpdateRejectsMismatchedNamespace(obj runtime.Object, setFn
|
|||
// =============================================================================
|
||||
// Deletion tests.
|
||||
|
||||
func (t *Tester) TestDeleteInvokesValidation(invalid ...runtime.Object) {
|
||||
for i, obj := range invalid {
|
||||
objectMeta := t.getObjectMetaOrFail(obj)
|
||||
func (t *Tester) testDeleteNoGraceful(obj runtime.Object, setFn SetFunc, getFn GetFunc, isNotFoundFn IsErrorFunc) {
|
||||
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)
|
||||
|
||||
foo := copyOrDie(obj)
|
||||
t.setObjectMeta(foo, "foo1")
|
||||
if err := setFn(ctx, foo); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
objectMeta := t.getObjectMetaOrFail(foo)
|
||||
obj, err := t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, api.NewDeleteOptions(10))
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if !t.returnDeletedObject {
|
||||
if status, ok := obj.(*api.Status); !ok {
|
||||
t.Errorf("expected status of delete, got %v", status)
|
||||
} else if status.Status != api.StatusSuccess {
|
||||
t.Errorf("expected success, got: %v", status.Status)
|
||||
}
|
||||
}
|
||||
|
||||
_, err = getFn(ctx, foo)
|
||||
if err == nil || !isNotFoundFn(err) {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tester) TestDeleteNonExist(createFn func() runtime.Object) {
|
||||
existing := createFn()
|
||||
objectMeta := t.getObjectMetaOrFail(existing)
|
||||
context := t.TestContext()
|
||||
func (t *Tester) testDeleteNonExist(obj runtime.Object) {
|
||||
objectMeta := t.getObjectMetaOrFail(obj)
|
||||
|
||||
t.withStorageError(&etcd.EtcdError{ErrorCode: tools.EtcdErrorCodeNotFound}, func() {
|
||||
_, err := t.storage.(rest.GracefulDeleter).Delete(context, objectMeta.Name, nil)
|
||||
_, err := t.storage.(rest.GracefulDeleter).Delete(t.TestContext(), objectMeta.Name, nil)
|
||||
if err == nil || !errors.IsNotFound(err) {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -539,100 +555,77 @@ func (t *Tester) TestDeleteNonExist(createFn func() runtime.Object) {
|
|||
// =============================================================================
|
||||
// Graceful Deletion tests.
|
||||
|
||||
func (t *Tester) TestDeleteNoGraceful(createFn func() runtime.Object, wasGracefulFn func() bool) {
|
||||
existing := createFn()
|
||||
objectMeta := t.getObjectMetaOrFail(existing)
|
||||
ctx := api.WithNamespace(t.TestContext(), objectMeta.Namespace)
|
||||
_, err := t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, api.NewDeleteOptions(10))
|
||||
if err != nil {
|
||||
func (t *Tester) testDeleteGracefulHasDefault(obj runtime.Object, setFn SetFunc, getFn GetFunc, expectedGrace int64) {
|
||||
ctx := t.TestContext()
|
||||
|
||||
foo := copyOrDie(obj)
|
||||
t.setObjectMeta(foo, "foo1")
|
||||
if err := setFn(ctx, foo); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if _, err := t.storage.(rest.Getter).Get(ctx, objectMeta.Name); !errors.IsNotFound(err) {
|
||||
t.Errorf("unexpected error, object should not exist: %v", err)
|
||||
}
|
||||
if wasGracefulFn() {
|
||||
t.Errorf("resource should not support graceful delete")
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tester) TestDeleteGracefulHasDefault(existing runtime.Object, expectedGrace int64, wasGracefulFn func() bool) {
|
||||
objectMeta := t.getObjectMetaOrFail(existing)
|
||||
ctx := api.WithNamespace(t.TestContext(), objectMeta.Namespace)
|
||||
objectMeta := t.getObjectMetaOrFail(foo)
|
||||
_, err := t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, &api.DeleteOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if !wasGracefulFn() {
|
||||
t.Errorf("did not gracefully delete resource")
|
||||
return
|
||||
if _, err := getFn(ctx, foo); err != nil {
|
||||
t.Fatalf("did not gracefully delete resource", err)
|
||||
}
|
||||
|
||||
object, err := t.storage.(rest.Getter).Get(ctx, objectMeta.Name)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error, object should exist: %v", err)
|
||||
return
|
||||
t.Fatalf("unexpected error, object should exist: %v", err)
|
||||
}
|
||||
objectMeta, err = api.ObjectMetaFor(object)
|
||||
if err != nil {
|
||||
t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, object)
|
||||
}
|
||||
if objectMeta.DeletionTimestamp == nil {
|
||||
t.Errorf("did not set deletion timestamp")
|
||||
}
|
||||
if objectMeta.DeletionGracePeriodSeconds == nil {
|
||||
t.Fatalf("did not set deletion grace period seconds")
|
||||
}
|
||||
if *objectMeta.DeletionGracePeriodSeconds != expectedGrace {
|
||||
t.Errorf("actual grace period does not match expected: %d", *objectMeta.DeletionGracePeriodSeconds)
|
||||
objectMeta = t.getObjectMetaOrFail(object)
|
||||
if objectMeta.DeletionTimestamp == nil || objectMeta.DeletionGracePeriodSeconds == nil || *objectMeta.DeletionGracePeriodSeconds != expectedGrace {
|
||||
t.Errorf("unexpected deleted meta: %#v", objectMeta)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tester) TestDeleteGracefulWithValue(existing runtime.Object, expectedGrace int64, wasGracefulFn func() bool) {
|
||||
objectMeta, err := api.ObjectMetaFor(existing)
|
||||
if err != nil {
|
||||
t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, existing)
|
||||
}
|
||||
func (t *Tester) testDeleteGracefulWithValue(obj runtime.Object, setFn SetFunc, getFn GetFunc, expectedGrace int64) {
|
||||
ctx := t.TestContext()
|
||||
|
||||
ctx := api.WithNamespace(t.TestContext(), objectMeta.Namespace)
|
||||
_, err = t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, api.NewDeleteOptions(expectedGrace+2))
|
||||
foo := copyOrDie(obj)
|
||||
t.setObjectMeta(foo, "foo2")
|
||||
if err := setFn(ctx, foo); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
objectMeta := t.getObjectMetaOrFail(foo)
|
||||
_, err := t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, api.NewDeleteOptions(expectedGrace+2))
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if !wasGracefulFn() {
|
||||
t.Errorf("did not gracefully delete resource")
|
||||
if _, err := getFn(ctx, foo); err != nil {
|
||||
t.Fatalf("did not gracefully delete resource", err)
|
||||
}
|
||||
|
||||
object, err := t.storage.(rest.Getter).Get(ctx, objectMeta.Name)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error, object should exist: %v", err)
|
||||
}
|
||||
objectMeta, err = api.ObjectMetaFor(object)
|
||||
if err != nil {
|
||||
t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, object)
|
||||
}
|
||||
if objectMeta.DeletionTimestamp == nil {
|
||||
t.Errorf("did not set deletion timestamp")
|
||||
}
|
||||
if objectMeta.DeletionGracePeriodSeconds == nil {
|
||||
t.Fatalf("did not set deletion grace period seconds")
|
||||
}
|
||||
if *objectMeta.DeletionGracePeriodSeconds != expectedGrace+2 {
|
||||
t.Errorf("actual grace period does not match expected: %d", *objectMeta.DeletionGracePeriodSeconds)
|
||||
objectMeta = t.getObjectMetaOrFail(object)
|
||||
if objectMeta.DeletionTimestamp == nil || objectMeta.DeletionGracePeriodSeconds == nil || *objectMeta.DeletionGracePeriodSeconds != expectedGrace+2 {
|
||||
t.Errorf("unexpected deleted meta: %#v", objectMeta)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tester) TestDeleteGracefulExtend(existing runtime.Object, expectedGrace int64, wasGracefulFn func() bool) {
|
||||
objectMeta, err := api.ObjectMetaFor(existing)
|
||||
if err != nil {
|
||||
t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, existing)
|
||||
}
|
||||
func (t *Tester) testDeleteGracefulExtend(obj runtime.Object, setFn SetFunc, getFn GetFunc, expectedGrace int64) {
|
||||
ctx := t.TestContext()
|
||||
|
||||
ctx := api.WithNamespace(t.TestContext(), objectMeta.Namespace)
|
||||
_, err = t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, api.NewDeleteOptions(expectedGrace))
|
||||
foo := copyOrDie(obj)
|
||||
t.setObjectMeta(foo, "foo3")
|
||||
if err := setFn(ctx, foo); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
objectMeta := t.getObjectMetaOrFail(foo)
|
||||
_, err := t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, api.NewDeleteOptions(expectedGrace))
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if !wasGracefulFn() {
|
||||
t.Errorf("did not gracefully delete resource")
|
||||
if _, err := getFn(ctx, foo); err != nil {
|
||||
t.Fatalf("did not gracefully delete resource", err)
|
||||
}
|
||||
|
||||
// second delete duration is ignored
|
||||
_, err = t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, api.NewDeleteOptions(expectedGrace+2))
|
||||
if err != nil {
|
||||
|
@ -642,35 +635,29 @@ func (t *Tester) TestDeleteGracefulExtend(existing runtime.Object, expectedGrace
|
|||
if err != nil {
|
||||
t.Errorf("unexpected error, object should exist: %v", err)
|
||||
}
|
||||
objectMeta, err = api.ObjectMetaFor(object)
|
||||
if err != nil {
|
||||
t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, object)
|
||||
}
|
||||
if objectMeta.DeletionTimestamp == nil {
|
||||
t.Errorf("did not set deletion timestamp")
|
||||
}
|
||||
if objectMeta.DeletionGracePeriodSeconds == nil {
|
||||
t.Fatalf("did not set deletion grace period seconds")
|
||||
}
|
||||
if *objectMeta.DeletionGracePeriodSeconds != expectedGrace {
|
||||
t.Errorf("actual grace period does not match expected: %d", *objectMeta.DeletionGracePeriodSeconds)
|
||||
objectMeta = t.getObjectMetaOrFail(object)
|
||||
if objectMeta.DeletionTimestamp == nil || objectMeta.DeletionGracePeriodSeconds == nil || *objectMeta.DeletionGracePeriodSeconds != expectedGrace {
|
||||
t.Errorf("unexpected deleted meta: %#v", objectMeta)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tester) TestDeleteGracefulImmediate(existing runtime.Object, expectedGrace int64, wasGracefulFn func() bool) {
|
||||
objectMeta, err := api.ObjectMetaFor(existing)
|
||||
if err != nil {
|
||||
t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, existing)
|
||||
}
|
||||
func (t *Tester) testDeleteGracefulImmediate(obj runtime.Object, setFn SetFunc, getFn GetFunc, expectedGrace int64) {
|
||||
ctx := t.TestContext()
|
||||
|
||||
ctx := api.WithNamespace(t.TestContext(), objectMeta.Namespace)
|
||||
_, err = t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, api.NewDeleteOptions(expectedGrace))
|
||||
foo := copyOrDie(obj)
|
||||
t.setObjectMeta(foo, "foo4")
|
||||
if err := setFn(ctx, foo); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
objectMeta := t.getObjectMetaOrFail(foo)
|
||||
_, err := t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, api.NewDeleteOptions(expectedGrace))
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if !wasGracefulFn() {
|
||||
t.Errorf("did not gracefully delete resource")
|
||||
if _, err := getFn(ctx, foo); err != nil {
|
||||
t.Fatalf("did not gracefully delete resource", err)
|
||||
}
|
||||
|
||||
// second delete is immediate, resource is deleted
|
||||
out, err := t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, api.NewDeleteOptions(0))
|
||||
if err != nil {
|
||||
|
@ -680,19 +667,21 @@ func (t *Tester) TestDeleteGracefulImmediate(existing runtime.Object, expectedGr
|
|||
if !errors.IsNotFound(err) {
|
||||
t.Errorf("unexpected error, object should be deleted immediately: %v", err)
|
||||
}
|
||||
objectMeta, err = api.ObjectMetaFor(out)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
return
|
||||
}
|
||||
objectMeta = t.getObjectMetaOrFail(out)
|
||||
if objectMeta.DeletionTimestamp == nil || objectMeta.DeletionGracePeriodSeconds == nil || *objectMeta.DeletionGracePeriodSeconds != 0 {
|
||||
t.Errorf("unexpected deleted meta: %#v", objectMeta)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tester) TestDeleteGracefulUsesZeroOnNil(existing runtime.Object, expectedGrace int64) {
|
||||
objectMeta := t.getObjectMetaOrFail(existing)
|
||||
ctx := api.WithNamespace(t.TestContext(), objectMeta.Namespace)
|
||||
func (t *Tester) testDeleteGracefulUsesZeroOnNil(obj runtime.Object, setFn SetFunc, expectedGrace int64) {
|
||||
ctx := t.TestContext()
|
||||
|
||||
foo := copyOrDie(obj)
|
||||
t.setObjectMeta(foo, "foo5")
|
||||
if err := setFn(ctx, foo); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
objectMeta := t.getObjectMetaOrFail(foo)
|
||||
_, err := t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, nil)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
|
|
|
@ -19,16 +19,12 @@ package etcd
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/coreos/go-etcd/etcd"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/rest/resttest"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"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) {
|
||||
|
@ -127,6 +123,12 @@ func TestUpdate(t *testing.T) {
|
|||
)
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
test.TestDelete(validNewController())
|
||||
}
|
||||
|
||||
func TestGenerationNumber(t *testing.T) {
|
||||
storage, _ := newStorage(t)
|
||||
modifiedSno := *validNewController()
|
||||
|
@ -218,59 +220,3 @@ func TestWatch(t *testing.T) {
|
|||
},
|
||||
)
|
||||
}
|
||||
|
||||
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)
|
||||
obj, err := storage.Delete(ctx, validController.Name, nil)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if status, ok := obj.(*api.Status); !ok {
|
||||
t.Errorf("Expected status of delete, got %#v", status)
|
||||
} else if status.Status != api.StatusSuccess {
|
||||
t.Errorf("Expected success, got %#v", status.Status)
|
||||
}
|
||||
if len(fakeClient.DeletedKeys) != 1 {
|
||||
t.Errorf("Expected 1 delete, found %#v", fakeClient.DeletedKeys)
|
||||
}
|
||||
if fakeClient.DeletedKeys[0] != key {
|
||||
t.Errorf("Unexpected key: %s, expected %s", fakeClient.DeletedKeys[0], key)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
key, _ := storage.KeyFunc(ctx, validController.Name)
|
||||
key = etcdtest.AddPrefix(key)
|
||||
|
||||
createFn := func() runtime.Object {
|
||||
rc := *validNewController()
|
||||
rc.ResourceVersion = "1"
|
||||
fakeClient.Data[key] = tools.EtcdResponseWithError{
|
||||
R: &etcd.Response{
|
||||
Node: &etcd.Node{
|
||||
Value: runtime.EncodeOrDie(testapi.Codec(), &rc),
|
||||
ModifiedIndex: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
return &rc
|
||||
}
|
||||
gracefulSetFn := func() bool {
|
||||
// If the controller is still around after trying to delete either the delete
|
||||
// failed, or we're deleting it gracefully.
|
||||
if fakeClient.Data[key].R.Node != nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
test.TestDelete(createFn, gracefulSetFn)
|
||||
}
|
||||
|
|
|
@ -19,17 +19,13 @@ package etcd
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/coreos/go-etcd/etcd"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/rest/resttest"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
"k8s.io/kubernetes/pkg/expapi"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"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) {
|
||||
|
@ -121,6 +117,12 @@ func TestUpdate(t *testing.T) {
|
|||
)
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
test.TestDelete(validNewDaemon())
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
|
@ -158,59 +160,3 @@ func TestWatch(t *testing.T) {
|
|||
},
|
||||
)
|
||||
}
|
||||
|
||||
func TestEtcdDeleteDaemon(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, fakeClient := newStorage(t)
|
||||
key, err := storage.KeyFunc(ctx, validDaemon.Name)
|
||||
key = etcdtest.AddPrefix(key)
|
||||
|
||||
fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), validDaemon), 0)
|
||||
obj, err := storage.Delete(ctx, validDaemon.Name, nil)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if status, ok := obj.(*api.Status); !ok {
|
||||
t.Errorf("Expected status of delete, got %#v", status)
|
||||
} else if status.Status != api.StatusSuccess {
|
||||
t.Errorf("Expected success, got %#v", status.Status)
|
||||
}
|
||||
if len(fakeClient.DeletedKeys) != 1 {
|
||||
t.Errorf("Expected 1 delete, found %#v", fakeClient.DeletedKeys)
|
||||
}
|
||||
if fakeClient.DeletedKeys[0] != key {
|
||||
t.Errorf("Unexpected key: %s, expected %s", fakeClient.DeletedKeys[0], key)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
key, _ := storage.KeyFunc(ctx, validDaemon.Name)
|
||||
key = etcdtest.AddPrefix(key)
|
||||
|
||||
createFn := func() runtime.Object {
|
||||
dc := validNewDaemon()
|
||||
dc.ResourceVersion = "1"
|
||||
fakeClient.Data[key] = tools.EtcdResponseWithError{
|
||||
R: &etcd.Response{
|
||||
Node: &etcd.Node{
|
||||
Value: runtime.EncodeOrDie(testapi.Codec(), dc),
|
||||
ModifiedIndex: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
return dc
|
||||
}
|
||||
gracefulSetFn := func() bool {
|
||||
// If the daemon is still around after trying to delete either the delete
|
||||
// failed, or we're deleting it gracefully.
|
||||
if fakeClient.Data[key].R.Node != nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
test.TestDelete(createFn, gracefulSetFn)
|
||||
}
|
||||
|
|
|
@ -19,17 +19,13 @@ package etcd
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/coreos/go-etcd/etcd"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/rest/resttest"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
"k8s.io/kubernetes/pkg/expapi"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"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) {
|
||||
|
@ -122,6 +118,12 @@ func TestUpdate(t *testing.T) {
|
|||
)
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
test.TestDelete(validNewDeployment())
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
|
@ -157,58 +159,3 @@ func TestWatch(t *testing.T) {
|
|||
},
|
||||
)
|
||||
}
|
||||
|
||||
func TestEtcdDelete(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, fakeClient := newStorage(t)
|
||||
key, err := storage.KeyFunc(ctx, validDeployment.Name)
|
||||
key = etcdtest.AddPrefix(key)
|
||||
|
||||
fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), validNewDeployment()), 0)
|
||||
obj, err := storage.Delete(ctx, validDeployment.Name, nil)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if status, ok := obj.(*api.Status); !ok {
|
||||
t.Errorf("Expected status of delete, got %#v", status)
|
||||
} else if status.Status != api.StatusSuccess {
|
||||
t.Errorf("Expected success, got %#v", status.Status)
|
||||
}
|
||||
if len(fakeClient.DeletedKeys) != 1 {
|
||||
t.Errorf("Expected 1 delete, found %#v", fakeClient.DeletedKeys)
|
||||
}
|
||||
if fakeClient.DeletedKeys[0] != key {
|
||||
t.Errorf("Unexpected key: %s, expected %s", fakeClient.DeletedKeys[0], key)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
key, _ := storage.KeyFunc(ctx, validDeployment.Name)
|
||||
key = etcdtest.AddPrefix(key)
|
||||
|
||||
createFn := func() runtime.Object {
|
||||
dc := validNewDeployment()
|
||||
dc.ResourceVersion = "1"
|
||||
fakeClient.Data[key] = tools.EtcdResponseWithError{
|
||||
R: &etcd.Response{
|
||||
Node: &etcd.Node{
|
||||
Value: runtime.EncodeOrDie(testapi.Codec(), dc),
|
||||
ModifiedIndex: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
return dc
|
||||
}
|
||||
gracefulSetFn := func() bool {
|
||||
// If the deployment is still around after trying to delete either the delete
|
||||
// failed, or we're deleting it gracefully.
|
||||
if fakeClient.Data[key].R.Node != nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
test.TestDelete(createFn, gracefulSetFn)
|
||||
}
|
||||
|
|
|
@ -20,15 +20,11 @@ import (
|
|||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/rest/resttest"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/tools"
|
||||
"k8s.io/kubernetes/pkg/tools/etcdtest"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
|
||||
"github.com/coreos/go-etcd/etcd"
|
||||
)
|
||||
|
||||
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
|
||||
|
@ -93,31 +89,9 @@ func TestUpdate(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
|
||||
endpoints := validChangedEndpoints()
|
||||
key, _ := storage.KeyFunc(ctx, endpoints.Name)
|
||||
key = etcdtest.AddPrefix(key)
|
||||
createFn := func() runtime.Object {
|
||||
fakeClient.Data[key] = tools.EtcdResponseWithError{
|
||||
R: &etcd.Response{
|
||||
Node: &etcd.Node{
|
||||
Value: runtime.EncodeOrDie(testapi.Codec(), endpoints),
|
||||
ModifiedIndex: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
return endpoints
|
||||
}
|
||||
gracefulSetFn := func() bool {
|
||||
if fakeClient.Data[key].R.Node == nil {
|
||||
return false
|
||||
}
|
||||
return fakeClient.Data[key].R.Node.TTL == 30
|
||||
}
|
||||
test.TestDelete(createFn, gracefulSetFn)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
test.TestDelete(validNewEndpoints())
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
|
@ -132,43 +106,25 @@ func TestList(t *testing.T) {
|
|||
test.TestList(validNewEndpoints())
|
||||
}
|
||||
|
||||
func TestEndpointsDecode(t *testing.T) {
|
||||
storage, _ := newStorage(t)
|
||||
expected := validNewEndpoints()
|
||||
body, err := testapi.Codec().Encode(expected)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
actual := storage.New()
|
||||
if err := testapi.Codec().DecodeInto(body, actual); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if !api.Semantic.DeepEqual(expected, actual) {
|
||||
t.Errorf("mismatch: %s", util.ObjectDiff(expected, actual))
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteEndpoints(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
func TestWatch(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
endpoints := validNewEndpoints()
|
||||
name := endpoints.Name
|
||||
key, _ := storage.KeyFunc(ctx, name)
|
||||
key = etcdtest.AddPrefix(key)
|
||||
fakeClient.ChangeIndex = 1
|
||||
fakeClient.Data[key] = tools.EtcdResponseWithError{
|
||||
R: &etcd.Response{
|
||||
Node: &etcd.Node{
|
||||
Value: runtime.EncodeOrDie(testapi.Codec(), endpoints),
|
||||
ModifiedIndex: 1,
|
||||
CreatedIndex: 1,
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
test.TestWatch(
|
||||
validNewEndpoints(),
|
||||
// matching labels
|
||||
[]labels.Set{},
|
||||
// not matching labels
|
||||
[]labels.Set{
|
||||
{"foo": "bar"},
|
||||
},
|
||||
// matching fields
|
||||
[]fields.Set{
|
||||
{"metadata.name": "foo"},
|
||||
},
|
||||
}
|
||||
_, err := storage.Delete(ctx, name, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
// not matching fields
|
||||
[]fields.Set{
|
||||
{"metadata.name": "bar"},
|
||||
{"name": "foo"},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
@ -21,17 +21,14 @@ import (
|
|||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/resource"
|
||||
"k8s.io/kubernetes/pkg/api/rest/resttest"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
"k8s.io/kubernetes/pkg/expapi"
|
||||
// Ensure that expapi/v1 package is initialized.
|
||||
_ "k8s.io/kubernetes/pkg/expapi/v1"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/tools"
|
||||
"k8s.io/kubernetes/pkg/tools/etcdtest"
|
||||
|
||||
"github.com/coreos/go-etcd/etcd"
|
||||
)
|
||||
|
||||
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
|
||||
|
@ -85,30 +82,9 @@ func TestUpdate(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
autoscaler := validNewHorizontalPodAutoscaler("foo2")
|
||||
key, _ := storage.KeyFunc(ctx, "foo2")
|
||||
key = etcdtest.AddPrefix(key)
|
||||
createFn := func() runtime.Object {
|
||||
fakeClient.Data[key] = tools.EtcdResponseWithError{
|
||||
R: &etcd.Response{
|
||||
Node: &etcd.Node{
|
||||
Value: runtime.EncodeOrDie(testapi.Codec(), autoscaler),
|
||||
ModifiedIndex: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
return autoscaler
|
||||
}
|
||||
gracefulSetFn := func() bool {
|
||||
if fakeClient.Data[key].R.Node == nil {
|
||||
return false
|
||||
}
|
||||
return fakeClient.Data[key].R.Node.TTL == 30
|
||||
}
|
||||
test.TestDelete(createFn, gracefulSetFn)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
test.TestDelete(validNewHorizontalPodAutoscaler("foo"))
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
|
@ -122,3 +98,24 @@ func TestList(t *testing.T) {
|
|||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
test.TestList(validNewHorizontalPodAutoscaler("foo"))
|
||||
}
|
||||
|
||||
func TestWatch(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
test.TestWatch(
|
||||
validNewHorizontalPodAutoscaler("foo"),
|
||||
// matching labels
|
||||
[]labels.Set{},
|
||||
// not matching labels
|
||||
[]labels.Set{
|
||||
{"foo": "bar"},
|
||||
},
|
||||
// matching fields
|
||||
[]fields.Set{},
|
||||
// not matching fields
|
||||
[]fields.Set{
|
||||
{"metadata.name": "bar"},
|
||||
{"name": "foo"},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
@ -74,13 +74,20 @@ func (autoscalerStrategy) AllowUnconditionalUpdate() bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// MatchAutoscaler returns a generic matcher for a given label and field selector.
|
||||
func MatchAutoscaler(label labels.Selector, field fields.Selector) generic.Matcher {
|
||||
return generic.MatcherFunc(func(obj runtime.Object) (bool, error) {
|
||||
autoscaler, ok := obj.(*expapi.HorizontalPodAutoscaler)
|
||||
if !ok {
|
||||
return false, fmt.Errorf("not a horizontal pod autoscaler")
|
||||
}
|
||||
return label.Matches(labels.Set(autoscaler.Labels)), nil
|
||||
})
|
||||
func AutoscalerToSelectableFields(limitRange *expapi.HorizontalPodAutoscaler) fields.Set {
|
||||
return fields.Set{}
|
||||
}
|
||||
|
||||
func MatchAutoscaler(label labels.Selector, field fields.Selector) generic.Matcher {
|
||||
return &generic.SelectionPredicate{
|
||||
Label: label,
|
||||
Field: field,
|
||||
GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
hpa, ok := obj.(*expapi.HorizontalPodAutoscaler)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("given object is not a horizontal pod autoscaler.")
|
||||
}
|
||||
return labels.Set(hpa.ObjectMeta.Labels), AutoscalerToSelectableFields(hpa), nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@ import (
|
|||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/resource"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/tools"
|
||||
|
@ -97,6 +99,12 @@ func TestUpdate(t *testing.T) {
|
|||
)
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
test.TestDelete(validNewLimitRange())
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
|
@ -108,3 +116,24 @@ func TestList(t *testing.T) {
|
|||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
test.TestList(validNewLimitRange())
|
||||
}
|
||||
|
||||
func TestWatch(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
test.TestWatch(
|
||||
validNewLimitRange(),
|
||||
// matching labels
|
||||
[]labels.Set{},
|
||||
// not matching labels
|
||||
[]labels.Set{
|
||||
{"foo": "bar"},
|
||||
},
|
||||
// matching fields
|
||||
[]fields.Set{},
|
||||
// not matching fields
|
||||
[]fields.Set{
|
||||
{"metadata.name": "bar"},
|
||||
{"name": "foo"},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
@ -22,16 +22,11 @@ import (
|
|||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/resource"
|
||||
"k8s.io/kubernetes/pkg/api/rest/resttest"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/tools"
|
||||
"k8s.io/kubernetes/pkg/tools/etcdtest"
|
||||
|
||||
"github.com/coreos/go-etcd/etcd"
|
||||
)
|
||||
|
||||
type fakeConnectionInfoGetter struct {
|
||||
|
@ -67,12 +62,6 @@ func validNewNode() *api.Node {
|
|||
}
|
||||
}
|
||||
|
||||
func validChangedNode() *api.Node {
|
||||
node := validNewNode()
|
||||
node.ResourceVersion = "1"
|
||||
return node
|
||||
}
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd).ClusterScope()
|
||||
|
@ -104,31 +93,9 @@ func TestUpdate(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
ctx := api.NewContext()
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeClient.SetError).ClusterScope()
|
||||
|
||||
node := validChangedNode()
|
||||
key, _ := storage.KeyFunc(ctx, node.Name)
|
||||
key = etcdtest.AddPrefix(key)
|
||||
createFn := func() runtime.Object {
|
||||
fakeClient.Data[key] = tools.EtcdResponseWithError{
|
||||
R: &etcd.Response{
|
||||
Node: &etcd.Node{
|
||||
Value: runtime.EncodeOrDie(testapi.Codec(), node),
|
||||
ModifiedIndex: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
return node
|
||||
}
|
||||
gracefulSetFn := func() bool {
|
||||
if fakeClient.Data[key].R.Node == nil {
|
||||
return false
|
||||
}
|
||||
return fakeClient.Data[key].R.Node.TTL == 30
|
||||
}
|
||||
test.TestDelete(createFn, gracefulSetFn)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd).ClusterScope()
|
||||
test.TestDelete(validNewNode())
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
|
@ -143,7 +110,7 @@ func TestList(t *testing.T) {
|
|||
test.TestList(validNewNode())
|
||||
}
|
||||
|
||||
func TestWatchNodes(t *testing.T) {
|
||||
func TestWatch(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd).ClusterScope()
|
||||
test.TestWatch(
|
||||
|
@ -167,23 +134,3 @@ func TestWatchNodes(t *testing.T) {
|
|||
},
|
||||
)
|
||||
}
|
||||
|
||||
func TestEtcdDeleteNode(t *testing.T) {
|
||||
ctx := api.NewContext()
|
||||
storage, fakeClient := newStorage(t)
|
||||
node := validNewNode()
|
||||
key, _ := storage.KeyFunc(ctx, node.Name)
|
||||
key = etcdtest.AddPrefix(key)
|
||||
fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), node), 0)
|
||||
_, err := storage.Delete(ctx, node.Name, nil)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if len(fakeClient.DeletedKeys) != 1 {
|
||||
t.Errorf("Expected 1 delete, found %#v", fakeClient.DeletedKeys)
|
||||
}
|
||||
if fakeClient.DeletedKeys[0] != key {
|
||||
t.Errorf("Unexpected key: %s, expected %s", fakeClient.DeletedKeys[0], key)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@ import (
|
|||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/tools"
|
||||
|
@ -59,15 +61,6 @@ func TestCreate(t *testing.T) {
|
|||
)
|
||||
}
|
||||
|
||||
func expectNamespace(t *testing.T, out runtime.Object) (*api.Namespace, bool) {
|
||||
namespace, ok := out.(*api.Namespace)
|
||||
if !ok || namespace == nil {
|
||||
t.Errorf("Expected an api.Namespace object, was %#v", out)
|
||||
return nil, false
|
||||
}
|
||||
return namespace, true
|
||||
}
|
||||
|
||||
func TestCreateSetsFields(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
namespace := validNewNamespace()
|
||||
|
@ -93,24 +86,10 @@ func TestCreateSetsFields(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestNamespaceDecode(t *testing.T) {
|
||||
storage, _ := newStorage(t)
|
||||
expected := validNewNamespace()
|
||||
expected.Status.Phase = api.NamespaceActive
|
||||
expected.Spec.Finalizers = []api.FinalizerName{api.FinalizerKubernetes}
|
||||
body, err := testapi.Codec().Encode(expected)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
actual := storage.New()
|
||||
if err := testapi.Codec().DecodeInto(body, actual); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if !api.Semantic.DeepEqual(expected, actual) {
|
||||
t.Errorf("mismatch: %s", util.ObjectDiff(expected, actual))
|
||||
}
|
||||
func TestDelete(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd).ClusterScope().ReturnDeletedObject()
|
||||
test.TestDelete(validNewNamespace())
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
|
@ -125,31 +104,27 @@ func TestList(t *testing.T) {
|
|||
test.TestList(validNewNamespace())
|
||||
}
|
||||
|
||||
func TestDeleteNamespace(t *testing.T) {
|
||||
func TestWatch(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
fakeClient.ChangeIndex = 1
|
||||
ctx := api.NewContext()
|
||||
key, err := 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.Namespace{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd).ClusterScope()
|
||||
test.TestWatch(
|
||||
validNewNamespace(),
|
||||
// matching labels
|
||||
[]labels.Set{},
|
||||
// not matching labels
|
||||
[]labels.Set{
|
||||
{"foo": "bar"},
|
||||
},
|
||||
Status: api.NamespaceStatus{Phase: api.NamespaceActive},
|
||||
}),
|
||||
ModifiedIndex: 1,
|
||||
CreatedIndex: 1,
|
||||
// matching fields
|
||||
[]fields.Set{
|
||||
{"metadata.name": "foo"},
|
||||
{"name": "foo"},
|
||||
},
|
||||
// not matching fields
|
||||
[]fields.Set{
|
||||
{"metadata.name": "bar"},
|
||||
},
|
||||
}
|
||||
_, err = storage.Delete(api.NewContext(), "foo", nil)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
func TestDeleteNamespaceWithIncompleteFinalizers(t *testing.T) {
|
||||
|
|
|
@ -143,10 +143,11 @@ func MatchNamespace(label labels.Selector, field fields.Selector) generic.Matche
|
|||
}
|
||||
|
||||
// NamespaceToSelectableFields returns a label set that represents the object
|
||||
// TODO: fields are not labels, and the validation rules for them do not apply.
|
||||
func NamespaceToSelectableFields(namespace *api.Namespace) labels.Set {
|
||||
return labels.Set{
|
||||
"name": namespace.Name,
|
||||
"metadata.name": namespace.Name,
|
||||
"status.phase": string(namespace.Status.Phase),
|
||||
// This is a bug, but we need to support it for backward compatibility.
|
||||
"name": namespace.Name,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,15 +21,14 @@ import (
|
|||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/resource"
|
||||
"k8s.io/kubernetes/pkg/api/rest/resttest"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/tools"
|
||||
"k8s.io/kubernetes/pkg/tools/etcdtest"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
|
||||
"github.com/coreos/go-etcd/etcd"
|
||||
)
|
||||
|
||||
func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient) {
|
||||
|
@ -101,31 +100,9 @@ func TestUpdate(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
ctx := api.NewContext()
|
||||
storage, _, fakeClient := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeClient.SetError).ClusterScope()
|
||||
|
||||
pv := validChangedPersistentVolume()
|
||||
key, _ := storage.KeyFunc(ctx, pv.Name)
|
||||
key = etcdtest.AddPrefix(key)
|
||||
createFn := func() runtime.Object {
|
||||
fakeClient.Data[key] = tools.EtcdResponseWithError{
|
||||
R: &etcd.Response{
|
||||
Node: &etcd.Node{
|
||||
Value: runtime.EncodeOrDie(testapi.Codec(), pv),
|
||||
ModifiedIndex: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
return pv
|
||||
}
|
||||
gracefulSetFn := func() bool {
|
||||
if fakeClient.Data[key].R.Node == nil {
|
||||
return false
|
||||
}
|
||||
return fakeClient.Data[key].R.Node.TTL == 30
|
||||
}
|
||||
test.TestDelete(createFn, gracefulSetFn)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd).ClusterScope().ReturnDeletedObject()
|
||||
test.TestDelete(validNewPersistentVolume("foo"))
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
|
@ -140,48 +117,30 @@ func TestList(t *testing.T) {
|
|||
test.TestList(validNewPersistentVolume("foo"))
|
||||
}
|
||||
|
||||
func TestPersistentVolumesDecode(t *testing.T) {
|
||||
storage, _, _ := newStorage(t)
|
||||
expected := validNewPersistentVolume("foo")
|
||||
body, err := testapi.Codec().Encode(expected)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
actual := storage.New()
|
||||
if err := testapi.Codec().DecodeInto(body, actual); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if !api.Semantic.DeepEqual(expected, actual) {
|
||||
t.Errorf("mismatch: %s", util.ObjectDiff(expected, actual))
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeletePersistentVolumes(t *testing.T) {
|
||||
ctx := api.NewContext()
|
||||
func TestWatch(t *testing.T) {
|
||||
storage, _, fakeClient := newStorage(t)
|
||||
persistentVolume := validNewPersistentVolume("foo")
|
||||
name := persistentVolume.Name
|
||||
key, _ := storage.KeyFunc(ctx, name)
|
||||
key = etcdtest.AddPrefix(key)
|
||||
fakeClient.ChangeIndex = 1
|
||||
fakeClient.Data[key] = tools.EtcdResponseWithError{
|
||||
R: &etcd.Response{
|
||||
Node: &etcd.Node{
|
||||
Value: runtime.EncodeOrDie(testapi.Codec(), persistentVolume),
|
||||
ModifiedIndex: 1,
|
||||
CreatedIndex: 1,
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd).ClusterScope()
|
||||
test.TestWatch(
|
||||
validNewPersistentVolume("foo"),
|
||||
// matching labels
|
||||
[]labels.Set{},
|
||||
// not matching labels
|
||||
[]labels.Set{
|
||||
{"foo": "bar"},
|
||||
},
|
||||
// matching fields
|
||||
[]fields.Set{
|
||||
{"metadata.name": "foo"},
|
||||
{"name": "foo"},
|
||||
},
|
||||
}
|
||||
_, err := storage.Delete(ctx, name, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
// not matching fields
|
||||
[]fields.Set{
|
||||
{"metadata.name": "bar"},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func TestEtcdUpdateStatus(t *testing.T) {
|
||||
func TestUpdateStatus(t *testing.T) {
|
||||
storage, statusStorage, fakeClient := newStorage(t)
|
||||
fakeClient.TestIndex = true
|
||||
|
||||
|
|
|
@ -103,9 +103,10 @@ func MatchPersistentVolumes(label labels.Selector, field fields.Selector) generi
|
|||
}
|
||||
|
||||
// PersistentVolumeToSelectableFields returns a label set that represents the object
|
||||
// TODO: fields are not labels, and the validation rules for them do not apply.
|
||||
func PersistentVolumeToSelectableFields(persistentvolume *api.PersistentVolume) labels.Set {
|
||||
return labels.Set{
|
||||
"metadata.name": persistentvolume.Name,
|
||||
// This is a bug, but we need to support it for backward compatibility.
|
||||
"name": persistentvolume.Name,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,15 +21,14 @@ import (
|
|||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/resource"
|
||||
"k8s.io/kubernetes/pkg/api/rest/resttest"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/tools"
|
||||
"k8s.io/kubernetes/pkg/tools/etcdtest"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
|
||||
"github.com/coreos/go-etcd/etcd"
|
||||
)
|
||||
|
||||
func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient) {
|
||||
|
@ -59,12 +58,6 @@ func validNewPersistentVolumeClaim(name, ns string) *api.PersistentVolumeClaim {
|
|||
return pv
|
||||
}
|
||||
|
||||
func validChangedPersistentVolumeClaim() *api.PersistentVolumeClaim {
|
||||
pv := validNewPersistentVolumeClaim("foo", api.NamespaceDefault)
|
||||
pv.ResourceVersion = "1"
|
||||
return pv
|
||||
}
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
storage, _, fakeClient := newStorage(t)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
|
@ -100,31 +93,9 @@ func TestUpdate(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, _, fakeClient := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
|
||||
pv := validChangedPersistentVolumeClaim()
|
||||
key, _ := storage.KeyFunc(ctx, pv.Name)
|
||||
key = etcdtest.AddPrefix(key)
|
||||
createFn := func() runtime.Object {
|
||||
fakeClient.Data[key] = tools.EtcdResponseWithError{
|
||||
R: &etcd.Response{
|
||||
Node: &etcd.Node{
|
||||
Value: runtime.EncodeOrDie(testapi.Codec(), pv),
|
||||
ModifiedIndex: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
return pv
|
||||
}
|
||||
gracefulSetFn := func() bool {
|
||||
if fakeClient.Data[key].R.Node == nil {
|
||||
return false
|
||||
}
|
||||
return fakeClient.Data[key].R.Node.TTL == 30
|
||||
}
|
||||
test.TestDelete(createFn, gracefulSetFn)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd).ReturnDeletedObject()
|
||||
test.TestDelete(validNewPersistentVolumeClaim("foo", api.NamespaceDefault))
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
|
@ -139,78 +110,30 @@ func TestList(t *testing.T) {
|
|||
test.TestList(validNewPersistentVolumeClaim("foo", api.NamespaceDefault))
|
||||
}
|
||||
|
||||
func TestPersistentVolumeClaimsDecode(t *testing.T) {
|
||||
storage, _, _ := newStorage(t)
|
||||
expected := validNewPersistentVolumeClaim("foo", api.NamespaceDefault)
|
||||
body, err := testapi.Codec().Encode(expected)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
actual := storage.New()
|
||||
if err := testapi.Codec().DecodeInto(body, actual); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if !api.Semantic.DeepEqual(expected, actual) {
|
||||
t.Errorf("mismatch: %s", util.ObjectDiff(expected, actual))
|
||||
}
|
||||
}
|
||||
|
||||
func TestEtcdUpdatePersistentVolumeClaims(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
func TestWatch(t *testing.T) {
|
||||
storage, _, fakeClient := newStorage(t)
|
||||
persistentVolume := validChangedPersistentVolumeClaim()
|
||||
|
||||
key, _ := storage.KeyFunc(ctx, "foo")
|
||||
key = etcdtest.AddPrefix(key)
|
||||
fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), validNewPersistentVolumeClaim("foo", api.NamespaceDefault)), 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.PersistentVolumeClaim
|
||||
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)
|
||||
}
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
test.TestWatch(
|
||||
validNewPersistentVolumeClaim("foo", api.NamespaceDefault),
|
||||
// matching labels
|
||||
[]labels.Set{},
|
||||
// not matching labels
|
||||
[]labels.Set{
|
||||
{"foo": "bar"},
|
||||
},
|
||||
// matching fields
|
||||
[]fields.Set{
|
||||
{"metadata.name": "foo"},
|
||||
{"name": "foo"},
|
||||
},
|
||||
// not matching fields
|
||||
[]fields.Set{
|
||||
{"metadata.name": "bar"},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func TestDeletePersistentVolumeClaims(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, _, fakeClient := newStorage(t)
|
||||
pvClaim := validNewPersistentVolumeClaim("foo", api.NamespaceDefault)
|
||||
name := pvClaim.Name
|
||||
key, _ := storage.KeyFunc(ctx, name)
|
||||
key = etcdtest.AddPrefix(key)
|
||||
fakeClient.ChangeIndex = 1
|
||||
fakeClient.Data[key] = tools.EtcdResponseWithError{
|
||||
R: &etcd.Response{
|
||||
Node: &etcd.Node{
|
||||
Value: runtime.EncodeOrDie(testapi.Codec(), pvClaim),
|
||||
ModifiedIndex: 1,
|
||||
CreatedIndex: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
_, err := storage.Delete(ctx, name, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEtcdUpdateStatus(t *testing.T) {
|
||||
func TestUpdateStatus(t *testing.T) {
|
||||
storage, statusStorage, fakeClient := newStorage(t)
|
||||
ctx := api.NewDefaultContext()
|
||||
fakeClient.TestIndex = true
|
||||
|
|
|
@ -103,9 +103,10 @@ func MatchPersistentVolumeClaim(label labels.Selector, field fields.Selector) ge
|
|||
}
|
||||
|
||||
// PersistentVolumeClaimToSelectableFields returns a label set that represents the object
|
||||
// TODO: fields are not labels, and the validation rules for them do not apply.
|
||||
func PersistentVolumeClaimToSelectableFields(persistentvolumeclaim *api.PersistentVolumeClaim) labels.Set {
|
||||
return labels.Set{
|
||||
"metadata.name": persistentvolumeclaim.Name,
|
||||
// This is a bug, but we need to support it for backward compatibility.
|
||||
"name": persistentvolumeclaim.Name,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ import (
|
|||
"k8s.io/kubernetes/pkg/api/errors"
|
||||
etcderrors "k8s.io/kubernetes/pkg/api/errors/etcd"
|
||||
"k8s.io/kubernetes/pkg/api/rest"
|
||||
"k8s.io/kubernetes/pkg/api/rest/resttest"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
|
@ -122,50 +121,12 @@ func TestUpdate(t *testing.T) {
|
|||
|
||||
func TestDelete(t *testing.T) {
|
||||
storage, _, _, fakeClient := newStorage(t)
|
||||
ctx := api.NewDefaultContext()
|
||||
key, _ := storage.Etcd.KeyFunc(ctx, "foo")
|
||||
key = etcdtest.AddPrefix(key)
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd).ReturnDeletedObject()
|
||||
test.TestDelete(validNewPod())
|
||||
|
||||
expectedNode := "some-node"
|
||||
createFn := func() runtime.Object {
|
||||
pod := validChangedPod()
|
||||
pod.Spec.NodeName = expectedNode
|
||||
fakeClient.Data[key] = tools.EtcdResponseWithError{
|
||||
R: &etcd.Response{
|
||||
Node: &etcd.Node{
|
||||
Value: runtime.EncodeOrDie(testapi.Codec(), pod),
|
||||
ModifiedIndex: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
return pod
|
||||
}
|
||||
gracefulSetFn := func() bool {
|
||||
if fakeClient.Data[key].R.Node == nil {
|
||||
return false
|
||||
}
|
||||
obj, err := testapi.Codec().Decode([]byte(fakeClient.Data[key].R.Node.Value))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
pod := obj.(*api.Pod)
|
||||
t.Logf("found object %#v", pod.ObjectMeta)
|
||||
return pod.DeletionTimestamp != nil && pod.DeletionGracePeriodSeconds != nil && *pod.DeletionGracePeriodSeconds != 0
|
||||
}
|
||||
test.TestDeleteGraceful(createFn, 30, gracefulSetFn)
|
||||
|
||||
expectedNode = ""
|
||||
test.TestDelete(createFn, gracefulSetFn)
|
||||
}
|
||||
|
||||
func expectPod(t *testing.T, out runtime.Object) (*api.Pod, bool) {
|
||||
pod, ok := out.(*api.Pod)
|
||||
if !ok || pod == nil {
|
||||
t.Errorf("Expected an api.Pod object, was %#v", out)
|
||||
return nil, false
|
||||
}
|
||||
return pod, true
|
||||
scheduledPod := validNewPod()
|
||||
scheduledPod.Spec.NodeName = "some-node"
|
||||
test.TestDeleteGraceful(scheduledPod, 30)
|
||||
}
|
||||
|
||||
func TestCreateRegistryError(t *testing.T) {
|
||||
|
@ -200,24 +161,6 @@ func TestCreateSetsFields(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestPodDecode(t *testing.T) {
|
||||
storage, _, _, _ := newStorage(t)
|
||||
expected := validNewPod()
|
||||
body, err := testapi.Codec().Encode(expected)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
actual := storage.New()
|
||||
if err := testapi.Codec().DecodeInto(body, actual); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if !api.Semantic.DeepEqual(expected, actual) {
|
||||
t.Errorf("mismatch: %s", util.ObjectDiff(expected, actual))
|
||||
}
|
||||
}
|
||||
|
||||
func TestResourceLocation(t *testing.T) {
|
||||
expectedIP := "1.2.3.4"
|
||||
testCases := []struct {
|
||||
|
@ -854,49 +797,3 @@ func TestEtcdUpdateStatus(t *testing.T) {
|
|||
t.Errorf("unexpected object: %s", util.ObjectDiff(&expected, podOut))
|
||||
}
|
||||
}
|
||||
|
||||
func TestEtcdDeletePod(t *testing.T) {
|
||||
storage, _, _, fakeClient := newStorage(t)
|
||||
ctx := api.NewDefaultContext()
|
||||
fakeClient.TestIndex = true
|
||||
|
||||
key, _ := storage.KeyFunc(ctx, "foo")
|
||||
key = etcdtest.AddPrefix(key)
|
||||
fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Spec: api.PodSpec{NodeName: "machine"},
|
||||
}), 0)
|
||||
_, err := storage.Delete(ctx, "foo", api.NewDeleteOptions(0))
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if len(fakeClient.DeletedKeys) != 1 {
|
||||
t.Errorf("Expected 1 delete, found %#v", fakeClient.DeletedKeys)
|
||||
} else if fakeClient.DeletedKeys[0] != key {
|
||||
t.Errorf("Unexpected key: %s, expected %s", fakeClient.DeletedKeys[0], key)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEtcdDeletePodMultipleContainers(t *testing.T) {
|
||||
storage, _, _, fakeClient := newStorage(t)
|
||||
ctx := api.NewDefaultContext()
|
||||
fakeClient.TestIndex = true
|
||||
key, _ := storage.KeyFunc(ctx, "foo")
|
||||
key = etcdtest.AddPrefix(key)
|
||||
fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Spec: api.PodSpec{NodeName: "machine"},
|
||||
}), 0)
|
||||
_, err := storage.Delete(ctx, "foo", api.NewDeleteOptions(0))
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if len(fakeClient.DeletedKeys) != 1 {
|
||||
t.Errorf("Expected 1 delete, found %#v", fakeClient.DeletedKeys)
|
||||
}
|
||||
if fakeClient.DeletedKeys[0] != key {
|
||||
t.Errorf("Unexpected key: %s, expected %s", fakeClient.DeletedKeys[0], key)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ import (
|
|||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/tools"
|
||||
|
@ -87,6 +89,12 @@ func TestUpdate(t *testing.T) {
|
|||
)
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd).ReturnDeletedObject()
|
||||
test.TestDelete(validNewPodTemplate("foo"))
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
|
@ -98,3 +106,24 @@ func TestList(t *testing.T) {
|
|||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
test.TestList(validNewPodTemplate("foo"))
|
||||
}
|
||||
|
||||
func TestWatch(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
test.TestWatch(
|
||||
validNewPodTemplate("foo"),
|
||||
// matching labels
|
||||
[]labels.Set{},
|
||||
// not matching labels
|
||||
[]labels.Set{
|
||||
{"foo": "bar"},
|
||||
},
|
||||
// matching fields
|
||||
[]fields.Set{},
|
||||
// not matching fields
|
||||
[]fields.Set{
|
||||
{"metadata.name": "bar"},
|
||||
{"name": "foo"},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
@ -73,13 +73,20 @@ func (podTemplateStrategy) AllowUnconditionalUpdate() bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// MatchPodTemplate returns a generic matcher for a given label and field selector.
|
||||
func MatchPodTemplate(label labels.Selector, field fields.Selector) generic.Matcher {
|
||||
return generic.MatcherFunc(func(obj runtime.Object) (bool, error) {
|
||||
podObj, ok := obj.(*api.PodTemplate)
|
||||
if !ok {
|
||||
return false, fmt.Errorf("not a pod template")
|
||||
}
|
||||
return label.Matches(labels.Set(podObj.Labels)), nil
|
||||
})
|
||||
func PodTemplateToSelectableFields(podTemplate *api.PodTemplate) fields.Set {
|
||||
return fields.Set{}
|
||||
}
|
||||
|
||||
func MatchPodTemplate(label labels.Selector, field fields.Selector) generic.Matcher {
|
||||
return &generic.SelectionPredicate{
|
||||
Label: label,
|
||||
Field: field,
|
||||
GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
pt, ok := obj.(*api.PodTemplate)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("given object is not a pod template.")
|
||||
}
|
||||
return labels.Set(pt.ObjectMeta.Labels), PodTemplateToSelectableFields(pt), nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,6 +75,11 @@ func (t *Tester) GeneratesName() *Tester {
|
|||
return t
|
||||
}
|
||||
|
||||
func (t *Tester) ReturnDeletedObject() *Tester {
|
||||
t.tester = t.tester.ReturnDeletedObject()
|
||||
return t
|
||||
}
|
||||
|
||||
func (t *Tester) TestCreate(valid runtime.Object, invalid ...runtime.Object) {
|
||||
t.tester.TestCreate(
|
||||
valid,
|
||||
|
@ -99,6 +104,24 @@ func (t *Tester) TestUpdate(valid runtime.Object, validUpdateFunc UpdateFunc, in
|
|||
)
|
||||
}
|
||||
|
||||
func (t *Tester) TestDelete(valid runtime.Object) {
|
||||
t.tester.TestDelete(
|
||||
valid,
|
||||
t.setObject,
|
||||
t.getObject,
|
||||
isNotFoundEtcdError,
|
||||
)
|
||||
}
|
||||
|
||||
func (t *Tester) TestDeleteGraceful(valid runtime.Object, expectedGrace int64) {
|
||||
t.tester.TestDeleteGraceful(
|
||||
valid,
|
||||
t.setObject,
|
||||
t.getObject,
|
||||
expectedGrace,
|
||||
)
|
||||
}
|
||||
|
||||
func (t *Tester) TestGet(valid runtime.Object) {
|
||||
t.tester.TestGet(valid)
|
||||
}
|
||||
|
@ -219,3 +242,11 @@ func (t *Tester) emitObject(obj runtime.Object, action string) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func isNotFoundEtcdError(err error) bool {
|
||||
etcdError, ok := err.(*etcd.EtcdError)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return etcdError.ErrorCode == tools.EtcdErrorCodeNotFound
|
||||
}
|
||||
|
|
|
@ -30,8 +30,6 @@ import (
|
|||
"k8s.io/kubernetes/pkg/tools"
|
||||
"k8s.io/kubernetes/pkg/tools/etcdtest"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
|
||||
"github.com/coreos/go-etcd/etcd"
|
||||
)
|
||||
|
||||
func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient) {
|
||||
|
@ -74,15 +72,6 @@ func TestCreate(t *testing.T) {
|
|||
)
|
||||
}
|
||||
|
||||
func expectResourceQuota(t *testing.T, out runtime.Object) (*api.ResourceQuota, bool) {
|
||||
resourcequota, ok := out.(*api.ResourceQuota)
|
||||
if !ok || resourcequota == nil {
|
||||
t.Errorf("Expected an api.ResourceQuota object, was %#v", out)
|
||||
return nil, false
|
||||
}
|
||||
return resourcequota, true
|
||||
}
|
||||
|
||||
func TestCreateRegistryError(t *testing.T) {
|
||||
storage, _, fakeClient := newStorage(t)
|
||||
fakeClient.Err = fmt.Errorf("test error")
|
||||
|
@ -116,49 +105,10 @@ func TestCreateSetsFields(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestResourceQuotaDecode(t *testing.T) {
|
||||
storage, _, _ := newStorage(t)
|
||||
expected := validNewResourceQuota()
|
||||
body, err := testapi.Codec().Encode(expected)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
actual := storage.New()
|
||||
if err := testapi.Codec().DecodeInto(body, actual); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if !api.Semantic.DeepEqual(expected, actual) {
|
||||
t.Errorf("mismatch: %s", util.ObjectDiff(expected, actual))
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteResourceQuota(t *testing.T) {
|
||||
func TestDelete(t *testing.T) {
|
||||
storage, _, fakeClient := newStorage(t)
|
||||
fakeClient.ChangeIndex = 1
|
||||
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.ResourceQuota{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
Status: api.ResourceQuotaStatus{},
|
||||
}),
|
||||
ModifiedIndex: 1,
|
||||
CreatedIndex: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
_, err := storage.Delete(api.NewDefaultContext(), "foo", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd).ReturnDeletedObject()
|
||||
test.TestDelete(validNewResourceQuota())
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
|
@ -195,7 +145,7 @@ func TestWatch(t *testing.T) {
|
|||
)
|
||||
}
|
||||
|
||||
func TestEtcdUpdateStatus(t *testing.T) {
|
||||
func TestUpdateStatus(t *testing.T) {
|
||||
storage, status, fakeClient := newStorage(t)
|
||||
ctx := api.NewDefaultContext()
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@ import (
|
|||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/tools"
|
||||
|
@ -78,6 +80,12 @@ func TestUpdate(t *testing.T) {
|
|||
)
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
test.TestDelete(validNewSecret("foo"))
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
|
@ -89,3 +97,24 @@ func TestList(t *testing.T) {
|
|||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
test.TestList(validNewSecret("foo"))
|
||||
}
|
||||
|
||||
func TestWatch(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
test.TestWatch(
|
||||
validNewSecret("foo"),
|
||||
// matching labels
|
||||
[]labels.Set{},
|
||||
// not matching labels
|
||||
[]labels.Set{
|
||||
{"foo": "bar"},
|
||||
},
|
||||
// matching fields
|
||||
[]fields.Set{},
|
||||
// not matching fields
|
||||
[]fields.Set{
|
||||
{"metadata.name": "bar"},
|
||||
{"name": "foo"},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
@ -106,6 +106,12 @@ func TestUpdate(t *testing.T) {
|
|||
)
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd).AllowCreateOnUpdate()
|
||||
test.TestDelete(validService())
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd).AllowCreateOnUpdate()
|
||||
|
|
|
@ -20,6 +20,8 @@ import (
|
|||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/tools"
|
||||
|
@ -71,6 +73,12 @@ func TestUpdate(t *testing.T) {
|
|||
)
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd).ReturnDeletedObject()
|
||||
test.TestDelete(validNewServiceAccount("foo"))
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
|
@ -82,3 +90,26 @@ func TestList(t *testing.T) {
|
|||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
test.TestList(validNewServiceAccount("foo"))
|
||||
}
|
||||
|
||||
func TestWatch(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
test.TestWatch(
|
||||
validNewServiceAccount("foo"),
|
||||
// matching labels
|
||||
[]labels.Set{},
|
||||
// not matching labels
|
||||
[]labels.Set{
|
||||
{"foo": "bar"},
|
||||
},
|
||||
// matching fields
|
||||
[]fields.Set{
|
||||
{"metadata.name": "foo"},
|
||||
},
|
||||
// not matching fields
|
||||
[]fields.Set{
|
||||
{"metadata.name": "bar"},
|
||||
{"name": "foo"},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
@ -20,17 +20,14 @@ import (
|
|||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/rest/resttest"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
"k8s.io/kubernetes/pkg/expapi"
|
||||
// Ensure that expapi/v1 package is initialized.
|
||||
_ "k8s.io/kubernetes/pkg/expapi/v1"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/tools"
|
||||
"k8s.io/kubernetes/pkg/tools/etcdtest"
|
||||
|
||||
"github.com/coreos/go-etcd/etcd"
|
||||
)
|
||||
|
||||
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
|
||||
|
@ -81,30 +78,9 @@ func TestUpdate(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
rsrc := validNewThirdPartyResource("foo2")
|
||||
key, _ := storage.KeyFunc(ctx, "foo2")
|
||||
key = etcdtest.AddPrefix(key)
|
||||
createFn := func() runtime.Object {
|
||||
fakeClient.Data[key] = tools.EtcdResponseWithError{
|
||||
R: &etcd.Response{
|
||||
Node: &etcd.Node{
|
||||
Value: runtime.EncodeOrDie(testapi.Codec(), rsrc),
|
||||
ModifiedIndex: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
return rsrc
|
||||
}
|
||||
gracefulSetFn := func() bool {
|
||||
if fakeClient.Data[key].R.Node == nil {
|
||||
return false
|
||||
}
|
||||
return fakeClient.Data[key].R.Node.TTL == 30
|
||||
}
|
||||
test.TestDeleteNoGraceful(createFn, gracefulSetFn)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
test.TestDelete(validNewThirdPartyResource("foo"))
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
|
@ -118,3 +94,24 @@ func TestList(t *testing.T) {
|
|||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
test.TestList(validNewThirdPartyResource("foo"))
|
||||
}
|
||||
|
||||
func TestWatch(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||
test.TestWatch(
|
||||
validNewThirdPartyResource("foo"),
|
||||
// matching labels
|
||||
[]labels.Set{},
|
||||
// not matching labels
|
||||
[]labels.Set{
|
||||
{"foo": "bar"},
|
||||
},
|
||||
// matching fields
|
||||
[]fields.Set{},
|
||||
// not matching fields
|
||||
[]fields.Set{
|
||||
{"metadata.name": "bar"},
|
||||
{"name": "foo"},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue