diff --git a/pkg/api/rest/resttest/resttest.go b/pkg/api/rest/resttest/resttest.go index f8c1716ef6a..74a6cb3d804 100644 --- a/pkg/api/rest/resttest/resttest.go +++ b/pkg/api/rest/resttest/resttest.go @@ -17,6 +17,8 @@ limitations under the License. package resttest import ( + "fmt" + "reflect" "strings" "testing" @@ -24,6 +26,9 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/conversion" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/util" @@ -91,6 +96,9 @@ func copyOrDie(obj runtime.Object) runtime.Object { return out } +type AssignFunc func(objs []runtime.Object) []runtime.Object +type SetRVFunc func(resourceVersion uint64) + // Test creating an object. func (t *Tester) TestCreate(valid runtime.Object, invalid ...runtime.Object) { t.testCreateHasMetadata(copyOrDie(valid)) @@ -113,6 +121,7 @@ func (t *Tester) TestUpdate(valid runtime.Object, existing, older runtime.Object } // 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) @@ -122,6 +131,7 @@ func (t *Tester) TestDelete(createFn func() runtime.Object, wasGracefulFn func() } // 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.testDeleteGracefulUsesZeroOnNil(createFn(), 0) @@ -137,6 +147,14 @@ func (t *Tester) TestGet(obj runtime.Object) { } } +// Test listing object. +func (t *Tester) TestList(obj runtime.Object, assignFn AssignFunc, setRVFn SetRVFunc) { + t.testListError() + t.testListFound(obj, assignFn) + t.testListNotFound(assignFn, setRVFn) + t.testListMatchLabels(obj, assignFn) +} + // ============================================================================= // Creation tests. @@ -478,3 +496,128 @@ func (t *Tester) testGetNotFound(obj runtime.Object) { t.Errorf("unexpected error returned: %#v", err) } } + +// ============================================================================= +// List tests. + +func listToItems(listObj runtime.Object) ([]runtime.Object, error) { + v, err := conversion.EnforcePtr(listObj) + if err != nil { + return nil, fmt.Errorf("unexpected error: %v", err) + } + items := v.FieldByName("Items") + if !items.IsValid() { + return nil, fmt.Errorf("unexpected Items field in %v", listObj) + } + if items.Type().Kind() != reflect.Slice { + return nil, fmt.Errorf("unexpected Items field type: %v", items.Type().Kind()) + } + result := make([]runtime.Object, items.Len()) + for i := 0; i < items.Len(); i++ { + result[i] = items.Index(i).Addr().Interface().(runtime.Object) + } + return result, nil +} + +func (t *Tester) testListError() { + ctx := t.TestContext() + + storageError := fmt.Errorf("test error") + t.withStorageError(storageError, func() { + _, err := t.storage.(rest.Lister).List(ctx, labels.Everything(), fields.Everything()) + if err != storageError { + t.Errorf("unexpected error: %v", err) + } + }) +} + +func (t *Tester) testListFound(obj runtime.Object, assignFn AssignFunc) { + ctx := t.TestContext() + + foo1 := copyOrDie(obj) + foo1Meta := t.getObjectMetaOrFail(foo1) + foo1Meta.Name = "foo1" + foo1Meta.Namespace = api.NamespaceValue(ctx) + foo2 := copyOrDie(obj) + foo2Meta := t.getObjectMetaOrFail(foo2) + foo2Meta.Name = "foo2" + foo2Meta.Namespace = api.NamespaceValue(ctx) + + existing := assignFn([]runtime.Object{foo1, foo2}) + + listObj, err := t.storage.(rest.Lister).List(ctx, labels.Everything(), fields.Everything()) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + items, err := listToItems(listObj) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if len(items) != len(existing) { + t.Errorf("unexpected number of items: %v", len(items)) + } + if !api.Semantic.DeepEqual(existing, items) { + t.Errorf("expected: %#v, got: %#v", existing, items) + } +} + +func (t *Tester) testListMatchLabels(obj runtime.Object, assignFn AssignFunc) { + ctx := t.TestContext() + testLabels := map[string]string{"key": "value"} + + foo1 := copyOrDie(obj) + foo1Meta := t.getObjectMetaOrFail(foo1) + foo1Meta.Name = "foo1" + foo1Meta.Namespace = api.NamespaceValue(ctx) + foo2 := copyOrDie(obj) + foo2Meta := t.getObjectMetaOrFail(foo2) + foo2Meta.Name = "foo2" + foo2Meta.Namespace = api.NamespaceValue(ctx) + foo2Meta.Labels = testLabels + + existing := assignFn([]runtime.Object{foo1, foo2}) + filtered := []runtime.Object{existing[1]} + + selector := labels.SelectorFromSet(labels.Set(testLabels)) + listObj, err := t.storage.(rest.Lister).List(ctx, selector, fields.Everything()) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + items, err := listToItems(listObj) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if len(items) != len(filtered) { + t.Errorf("unexpected number of items: %v", len(items)) + } + if !api.Semantic.DeepEqual(filtered, items) { + t.Errorf("expected: %#v, got: %#v", filtered, items) + } +} + +func (t *Tester) testListNotFound(assignFn AssignFunc, setRVFn SetRVFunc) { + ctx := t.TestContext() + + setRVFn(uint64(123)) + _ = assignFn([]runtime.Object{}) + + listObj, err := t.storage.(rest.Lister).List(ctx, labels.Everything(), fields.Everything()) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + items, err := listToItems(listObj) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if len(items) != 0 { + t.Errorf("unexpected items: %v", items) + } + + meta, err := api.ListMetaFor(listObj) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if meta.ResourceVersion != "123" { + t.Errorf("unexpected resource version: %d", meta.ResourceVersion) + } +} diff --git a/pkg/registry/controller/etcd/etcd_test.go b/pkg/registry/controller/etcd/etcd_test.go index c826400d35e..d5535eaad6a 100644 --- a/pkg/registry/controller/etcd/etcd_test.go +++ b/pkg/registry/controller/etcd/etcd_test.go @@ -30,6 +30,7 @@ import ( "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" etcdgeneric "k8s.io/kubernetes/pkg/registry/generic/etcd" + "k8s.io/kubernetes/pkg/registry/registrytest" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/storage" etcdstorage "k8s.io/kubernetes/pkg/storage/etcd" @@ -101,12 +102,6 @@ func makeControllerKey(ctx api.Context, id string) (string, error) { return etcdgeneric.NamespaceKeyFunc(ctx, controllerPrefix, id) } -// makeControllerListKey constructs etcd paths to the root of the resource, -// not a specific controller resource -func makeControllerListKey(ctx api.Context) string { - return etcdgeneric.NamespaceKeyRootFunc(ctx, controllerPrefix) -} - func TestEtcdCreateController(t *testing.T) { ctx := api.NewDefaultContext() storage, fakeClient := newStorage(t) @@ -319,6 +314,21 @@ func TestEtcdGetController(t *testing.T) { test.TestGet(©) } +func TestEtcdListControllers(t *testing.T) { + storage, fakeClient := newStorage(t) + test := resttest.New(t, storage, fakeClient.SetError) + key := etcdtest.AddPrefix(storage.KeyRootFunc(test.TestContext())) + copy := validController + test.TestList( + ©, + func(objects []runtime.Object) []runtime.Object { + return registrytest.SetObjectsForKey(fakeClient, key, objects) + }, + func(resourceVersion uint64) { + registrytest.SetResourceVersion(fakeClient, resourceVersion) + }) +} + func TestEtcdUpdateController(t *testing.T) { ctx := api.NewDefaultContext() storage, fakeClient := newStorage(t) @@ -368,96 +378,6 @@ func TestEtcdDeleteController(t *testing.T) { } } -func TestEtcdListControllers(t *testing.T) { - storage, fakeClient := newStorage(t) - ctx := api.NewDefaultContext() - key := makeControllerListKey(ctx) - key = etcdtest.AddPrefix(key) - controller := validController - controller.Name = "bar" - fakeClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{ - Node: &etcd.Node{ - Nodes: []*etcd.Node{ - { - Value: runtime.EncodeOrDie(latest.Codec, &validController), - }, - { - Value: runtime.EncodeOrDie(latest.Codec, &controller), - }, - }, - }, - }, - E: nil, - } - objList, err := storage.List(ctx, labels.Everything(), fields.Everything()) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - controllers, _ := objList.(*api.ReplicationControllerList) - if len(controllers.Items) != 2 || controllers.Items[0].Name != validController.Name || controllers.Items[1].Name != controller.Name { - t.Errorf("Unexpected controller list: %#v", controllers) - } -} - -func TestEtcdListControllersNotFound(t *testing.T) { - storage, fakeClient := newStorage(t) - ctx := api.NewDefaultContext() - key := makeControllerListKey(ctx) - key = etcdtest.AddPrefix(key) - - fakeClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{}, - E: tools.EtcdErrorNotFound, - } - objList, err := storage.List(ctx, labels.Everything(), fields.Everything()) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - controllers, _ := objList.(*api.ReplicationControllerList) - if len(controllers.Items) != 0 { - t.Errorf("Unexpected controller list: %#v", controllers) - } -} - -func TestEtcdListControllersLabelsMatch(t *testing.T) { - storage, fakeClient := newStorage(t) - ctx := api.NewDefaultContext() - key := makeControllerListKey(ctx) - key = etcdtest.AddPrefix(key) - - controller := validController - controller.Labels = map[string]string{"k": "v"} - controller.Name = "bar" - - fakeClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{ - Node: &etcd.Node{ - Nodes: []*etcd.Node{ - { - Value: runtime.EncodeOrDie(latest.Codec, &validController), - }, - { - Value: runtime.EncodeOrDie(latest.Codec, &controller), - }, - }, - }, - }, - E: nil, - } - testLabels := labels.SelectorFromSet(labels.Set(controller.Labels)) - objList, err := storage.List(ctx, testLabels, fields.Everything()) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - controllers, _ := objList.(*api.ReplicationControllerList) - if len(controllers.Items) != 1 || controllers.Items[0].Name != controller.Name || - !testLabels.Matches(labels.Set(controllers.Items[0].Labels)) { - t.Errorf("Unexpected controller list: %#v for query with labels %#v", - controllers, testLabels) - } -} - func TestEtcdWatchController(t *testing.T) { ctx := api.NewDefaultContext() storage, fakeClient := newStorage(t) diff --git a/pkg/registry/endpoint/etcd/etcd_test.go b/pkg/registry/endpoint/etcd/etcd_test.go index dc521545e79..a8b7d3e5902 100644 --- a/pkg/registry/endpoint/etcd/etcd_test.go +++ b/pkg/registry/endpoint/etcd/etcd_test.go @@ -22,8 +22,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/rest/resttest" - "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/storage" etcdstorage "k8s.io/kubernetes/pkg/storage/etcd" @@ -113,46 +112,6 @@ func TestDelete(t *testing.T) { test.TestDelete(createFn, gracefulSetFn) } -func TestEtcdListEndpoints(t *testing.T) { - ctx := api.NewDefaultContext() - storage, fakeClient := newStorage(t) - key := storage.KeyRootFunc(ctx) - key = etcdtest.AddPrefix(key) - fakeClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{ - Node: &etcd.Node{ - Nodes: []*etcd.Node{ - { - Value: runtime.EncodeOrDie(latest.Codec, &api.Endpoints{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "127.0.0.1"}}, - Ports: []api.EndpointPort{{Port: 8345, Protocol: "TCP"}}, - }}, - }), - }, - { - Value: runtime.EncodeOrDie(latest.Codec, &api.Endpoints{ - ObjectMeta: api.ObjectMeta{Name: "bar"}, - }), - }, - }, - }, - }, - E: nil, - } - - endpointsObj, err := storage.List(ctx, labels.Everything(), fields.Everything()) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - endpoints := endpointsObj.(*api.EndpointsList) - - if len(endpoints.Items) != 2 || endpoints.Items[0].Name != "foo" || endpoints.Items[1].Name != "bar" { - t.Errorf("Unexpected endpoints list: %#v", endpoints) - } -} - func TestEtcdGetEndpoints(t *testing.T) { storage, fakeClient := newStorage(t) test := resttest.New(t, storage, fakeClient.SetError) @@ -160,70 +119,19 @@ func TestEtcdGetEndpoints(t *testing.T) { test.TestGet(endpoints) } -func TestListEmptyEndpointsList(t *testing.T) { - ctx := api.NewDefaultContext() +func TestEtcdListEndpoints(t *testing.T) { storage, fakeClient := newStorage(t) - fakeClient.ChangeIndex = 1 - key := storage.KeyRootFunc(ctx) - key = etcdtest.AddPrefix(key) - fakeClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{}, - E: fakeClient.NewError(tools.EtcdErrorCodeNotFound), - } - - endpoints, err := storage.List(ctx, labels.Everything(), fields.Everything()) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - if len(endpoints.(*api.EndpointsList).Items) != 0 { - t.Errorf("Unexpected non-zero pod list: %#v", endpoints) - } - if endpoints.(*api.EndpointsList).ResourceVersion != "1" { - t.Errorf("Unexpected resource version: %#v", endpoints) - } -} - -func TestListEndpointsList(t *testing.T) { - ctx := api.NewDefaultContext() - storage, fakeClient := newStorage(t) - fakeClient.ChangeIndex = 1 - key := storage.KeyRootFunc(ctx) - key = etcdtest.AddPrefix(key) - fakeClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{ - Node: &etcd.Node{ - Nodes: []*etcd.Node{ - { - Value: runtime.EncodeOrDie(latest.Codec, &api.Endpoints{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - }), - }, - { - Value: runtime.EncodeOrDie(latest.Codec, &api.Endpoints{ - ObjectMeta: api.ObjectMeta{Name: "bar"}, - }), - }, - }, - }, + test := resttest.New(t, storage, fakeClient.SetError) + endpoints := validNewEndpoints() + key := etcdtest.AddPrefix(storage.KeyRootFunc(test.TestContext())) + test.TestList( + endpoints, + func(objects []runtime.Object) []runtime.Object { + return registrytest.SetObjectsForKey(fakeClient, key, objects) }, - } - - endpointsObj, err := storage.List(ctx, labels.Everything(), fields.Everything()) - endpoints := endpointsObj.(*api.EndpointsList) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - if len(endpoints.Items) != 2 { - t.Errorf("Unexpected endpoints list: %#v", endpoints) - } - if endpoints.Items[0].Name != "foo" { - t.Errorf("Unexpected endpoints: %#v", endpoints.Items[0]) - } - if endpoints.Items[1].Name != "bar" { - t.Errorf("Unexpected endpoints: %#v", endpoints.Items[1]) - } + func(resourceVersion uint64) { + registrytest.SetResourceVersion(fakeClient, resourceVersion) + }) } func TestEndpointsDecode(t *testing.T) { diff --git a/pkg/registry/horizontalpodautoscaler/etcd/etcd_test.go b/pkg/registry/horizontalpodautoscaler/etcd/etcd_test.go index 09a7d92496c..6aa97a06c16 100644 --- a/pkg/registry/horizontalpodautoscaler/etcd/etcd_test.go +++ b/pkg/registry/horizontalpodautoscaler/etcd/etcd_test.go @@ -25,8 +25,7 @@ import ( "k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/expapi" "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/storage" etcdstorage "k8s.io/kubernetes/pkg/storage/etcd" @@ -143,68 +142,17 @@ func TestGet(t *testing.T) { test.TestGet(autoscaler) } -func TestEmptyList(t *testing.T) { - ctx := api.NewDefaultContext() - registry, fakeClient, _ := newStorage(t) - fakeClient.ChangeIndex = 1 - key := registry.KeyRootFunc(ctx) - key = etcdtest.AddPrefix(key) - fakeClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{}, - E: fakeClient.NewError(tools.EtcdErrorCodeNotFound), - } - autoscalerList, err := registry.List(ctx, labels.Everything(), fields.Everything()) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - if len(autoscalerList.(*expapi.HorizontalPodAutoscalerList).Items) != 0 { - t.Errorf("Unexpected non-zero autoscaler list: %#v", autoscalerList) - } - if autoscalerList.(*expapi.HorizontalPodAutoscalerList).ResourceVersion != "1" { - t.Errorf("Unexpected resource version: %#v", autoscalerList) - } -} - func TestList(t *testing.T) { - ctx := api.NewDefaultContext() - registry, fakeClient, _ := newStorage(t) - fakeClient.ChangeIndex = 1 - key := registry.KeyRootFunc(ctx) - key = etcdtest.AddPrefix(key) - fakeClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{ - Node: &etcd.Node{ - Nodes: []*etcd.Node{ - { - Value: runtime.EncodeOrDie(testapi.Codec(), &expapi.HorizontalPodAutoscaler{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - }), - }, - { - Value: runtime.EncodeOrDie(testapi.Codec(), &expapi.HorizontalPodAutoscaler{ - ObjectMeta: api.ObjectMeta{Name: "bar"}, - }), - }, - }, - }, + storage, fakeEtcdClient, _ := newStorage(t) + test := resttest.New(t, storage, fakeEtcdClient.SetError) + key := etcdtest.AddPrefix(storage.KeyRootFunc(test.TestContext())) + autoscaler := validNewHorizontalPodAutoscaler("foo") + test.TestList( + autoscaler, + func(objects []runtime.Object) []runtime.Object { + return registrytest.SetObjectsForKey(fakeEtcdClient, key, objects) }, - } - obj, err := registry.List(ctx, labels.Everything(), fields.Everything()) - if err != nil { - t.Fatalf("Unexpected error %v", err) - } - autoscalerList := obj.(*expapi.HorizontalPodAutoscalerList) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - if len(autoscalerList.Items) != 2 { - t.Errorf("Unexpected HorizontalPodAutoscaler list: %#v", autoscalerList) - } - if autoscalerList.Items[0].Name != "foo" { - t.Errorf("Unexpected HorizontalPodAutoscaler: %#v", autoscalerList.Items[0]) - } - if autoscalerList.Items[1].Name != "bar" { - t.Errorf("Unexpected HorizontalPodAutoscaler: %#v", autoscalerList.Items[1]) - } + func(resourceVersion uint64) { + registrytest.SetResourceVersion(fakeEtcdClient, resourceVersion) + }) } diff --git a/pkg/registry/minion/etcd/etcd_test.go b/pkg/registry/minion/etcd/etcd_test.go index fcaed9bd7a3..1cb2ca4c87f 100644 --- a/pkg/registry/minion/etcd/etcd_test.go +++ b/pkg/registry/minion/etcd/etcd_test.go @@ -27,6 +27,7 @@ import ( "k8s.io/kubernetes/pkg/api/rest/resttest" "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/storage" etcdstorage "k8s.io/kubernetes/pkg/storage/etcd" @@ -130,85 +131,6 @@ func TestDelete(t *testing.T) { test.TestDelete(createFn, gracefulSetFn) } -func TestEtcdListNodes(t *testing.T) { - ctx := api.NewContext() - storage, fakeClient := newStorage(t) - key := storage.KeyRootFunc(ctx) - key = etcdtest.AddPrefix(key) - fakeClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{ - Node: &etcd.Node{ - Nodes: []*etcd.Node{ - { - Value: runtime.EncodeOrDie(latest.Codec, &api.Node{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - }), - }, - { - Value: runtime.EncodeOrDie(latest.Codec, &api.Node{ - ObjectMeta: api.ObjectMeta{Name: "bar"}, - }), - }, - }, - }, - }, - E: nil, - } - nodesObj, err := storage.List(ctx, labels.Everything(), fields.Everything()) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - - nodes := nodesObj.(*api.NodeList) - if len(nodes.Items) != 2 || nodes.Items[0].Name != "foo" || nodes.Items[1].Name != "bar" { - t.Errorf("Unexpected nodes list: %#v", nodes) - } -} - -func TestEtcdListNodesMatch(t *testing.T) { - ctx := api.NewContext() - storage, fakeClient := newStorage(t) - key := storage.KeyRootFunc(ctx) - key = etcdtest.AddPrefix(key) - fakeClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{ - Node: &etcd.Node{ - Nodes: []*etcd.Node{ - { - Value: runtime.EncodeOrDie(latest.Codec, &api.Node{ - ObjectMeta: api.ObjectMeta{Name: "foo", - Labels: map[string]string{ - "name": "foo", - }, - }, - }), - }, - { - Value: runtime.EncodeOrDie(latest.Codec, &api.Node{ - ObjectMeta: api.ObjectMeta{Name: "bar", - Labels: map[string]string{ - "name": "bar", - }, - }, - }), - }, - }, - }, - }, - E: nil, - } - label := labels.SelectorFromSet(labels.Set{"name": "bar"}) - nodesObj, err := storage.List(ctx, label, fields.Everything()) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - - nodes := nodesObj.(*api.NodeList) - if len(nodes.Items) != 1 || nodes.Items[0].Name != "bar" { - t.Errorf("Unexpected nodes list: %#v", nodes) - } -} - func TestEtcdGetNode(t *testing.T) { storage, fakeClient := newStorage(t) test := resttest.New(t, storage, fakeClient.SetError).ClusterScope() @@ -216,6 +138,21 @@ func TestEtcdGetNode(t *testing.T) { test.TestGet(node) } +func TestEtcdListNodes(t *testing.T) { + storage, fakeClient := newStorage(t) + test := resttest.New(t, storage, fakeClient.SetError).ClusterScope() + key := etcdtest.AddPrefix(storage.KeyRootFunc(test.TestContext())) + node := validNewNode() + test.TestList( + node, + func(objects []runtime.Object) []runtime.Object { + return registrytest.SetObjectsForKey(fakeClient, key, objects) + }, + func(resourceVersion uint64) { + registrytest.SetResourceVersion(fakeClient, resourceVersion) + }) +} + func TestEtcdUpdateEndpoints(t *testing.T) { ctx := api.NewContext() storage, fakeClient := newStorage(t) diff --git a/pkg/registry/namespace/etcd/etcd_test.go b/pkg/registry/namespace/etcd/etcd_test.go index 7af0c234a59..5bcfb9c3b12 100644 --- a/pkg/registry/namespace/etcd/etcd_test.go +++ b/pkg/registry/namespace/etcd/etcd_test.go @@ -22,9 +22,8 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/rest/resttest" - "k8s.io/kubernetes/pkg/fields" - "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/namespace" + "k8s.io/kubernetes/pkg/registry/registrytest" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/storage" etcdstorage "k8s.io/kubernetes/pkg/storage/etcd" @@ -124,144 +123,6 @@ func TestCreateSetsFields(t *testing.T) { } } -func TestListEmptyNamespaceList(t *testing.T) { - fakeEtcdClient, etcdStorage := newEtcdStorage(t) - fakeEtcdClient.ChangeIndex = 1 - key := etcdtest.AddPrefix("/namespaces") - fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{}, - E: fakeEtcdClient.NewError(tools.EtcdErrorCodeNotFound), - } - - storage, _, _ := NewStorage(etcdStorage) - namespaces, err := storage.List(api.NewContext(), labels.Everything(), fields.Everything()) - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - if len(namespaces.(*api.NamespaceList).Items) != 0 { - t.Errorf("Unexpected non-zero namespace list: %#v", namespaces) - } - if namespaces.(*api.NamespaceList).ResourceVersion != "1" { - t.Errorf("Unexpected resource version: %#v", namespaces) - } -} - -func TestListNamespaceList(t *testing.T) { - fakeEtcdClient, etcdStorage := newEtcdStorage(t) - key := etcdtest.AddPrefix("/namespaces") - fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{ - Node: &etcd.Node{ - Nodes: []*etcd.Node{ - { - Value: runtime.EncodeOrDie(latest.Codec, &api.Namespace{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - }), - }, - { - Value: runtime.EncodeOrDie(latest.Codec, &api.Namespace{ - ObjectMeta: api.ObjectMeta{Name: "bar"}, - }), - }, - }, - }, - }, - } - storage, _, _ := NewStorage(etcdStorage) - namespacesObj, err := storage.List(api.NewContext(), labels.Everything(), fields.Everything()) - namespaces := namespacesObj.(*api.NamespaceList) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - if len(namespaces.Items) != 2 { - t.Errorf("Unexpected namespaces list: %#v", namespaces) - } - if namespaces.Items[0].Name != "foo" || namespaces.Items[0].Status.Phase != api.NamespaceActive { - t.Errorf("Unexpected namespace: %#v", namespaces.Items[0]) - } - if namespaces.Items[1].Name != "bar" { - t.Errorf("Unexpected namespace: %#v", namespaces.Items[1]) - } -} - -func TestListNamespaceListSelection(t *testing.T) { - fakeEtcdClient, etcdStorage := newEtcdStorage(t) - key := etcdtest.AddPrefix("/namespaces") - fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{ - Node: &etcd.Node{ - Nodes: []*etcd.Node{ - {Value: runtime.EncodeOrDie(latest.Codec, &api.Namespace{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - })}, - {Value: runtime.EncodeOrDie(latest.Codec, &api.Namespace{ - ObjectMeta: api.ObjectMeta{Name: "bar"}, - })}, - {Value: runtime.EncodeOrDie(latest.Codec, &api.Namespace{ - ObjectMeta: api.ObjectMeta{Name: "baz"}, - Status: api.NamespaceStatus{Phase: api.NamespaceTerminating}, - })}, - {Value: runtime.EncodeOrDie(latest.Codec, &api.Namespace{ - ObjectMeta: api.ObjectMeta{ - Name: "qux", - Labels: map[string]string{"label": "qux"}, - }, - })}, - {Value: runtime.EncodeOrDie(latest.Codec, &api.Namespace{ - ObjectMeta: api.ObjectMeta{Name: "zot"}, - })}, - }, - }, - }, - } - storage, _, _ := NewStorage(etcdStorage) - ctx := api.NewContext() - table := []struct { - label, field string - expectedIDs util.StringSet - }{ - { - expectedIDs: util.NewStringSet("foo", "bar", "baz", "qux", "zot"), - }, { - field: "name=zot", - expectedIDs: util.NewStringSet("zot"), - }, { - label: "label=qux", - expectedIDs: util.NewStringSet("qux"), - }, { - field: "status.phase=Terminating", - expectedIDs: util.NewStringSet("baz"), - }, - } - - for index, item := range table { - label, err := labels.Parse(item.label) - if err != nil { - t.Errorf("unexpected error: %v", err) - continue - } - field, err := fields.ParseSelector(item.field) - if err != nil { - t.Errorf("unexpected error: %v", err) - continue - } - namespacesObj, err := storage.List(ctx, label, field) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - namespaces := namespacesObj.(*api.NamespaceList) - - set := util.NewStringSet() - for i := range namespaces.Items { - set.Insert(namespaces.Items[i].Name) - } - if e, a := len(item.expectedIDs), len(set); e != a { - t.Errorf("%v: Expected %v, got %v", index, item.expectedIDs, set) - } - } -} - func TestNamespaceDecode(t *testing.T) { _, etcdStorage := newEtcdStorage(t) storage, _, _ := NewStorage(etcdStorage) @@ -290,6 +151,21 @@ func TestGet(t *testing.T) { test.TestGet(namespace) } +func TestList(t *testing.T) { + storage, fakeEtcdClient, _ := newStorage(t) + test := resttest.New(t, storage, fakeEtcdClient.SetError).ClusterScope() + key := etcdtest.AddPrefix(storage.KeyRootFunc(test.TestContext())) + namespace := validNewNamespace() + test.TestList( + namespace, + func(objects []runtime.Object) []runtime.Object { + return registrytest.SetObjectsForKey(fakeEtcdClient, key, objects) + }, + func(resourceVersion uint64) { + registrytest.SetResourceVersion(fakeEtcdClient, resourceVersion) + }) +} + func TestDeleteNamespace(t *testing.T) { fakeEtcdClient, etcdStorage := newEtcdStorage(t) fakeEtcdClient.ChangeIndex = 1 diff --git a/pkg/registry/persistentvolume/etcd/etcd_test.go b/pkg/registry/persistentvolume/etcd/etcd_test.go index 07da7b165b8..4c15274f834 100644 --- a/pkg/registry/persistentvolume/etcd/etcd_test.go +++ b/pkg/registry/persistentvolume/etcd/etcd_test.go @@ -23,8 +23,7 @@ import ( "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/rest/resttest" - "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/storage" etcdstorage "k8s.io/kubernetes/pkg/storage/etcd" @@ -116,38 +115,6 @@ func TestDelete(t *testing.T) { test.TestDelete(createFn, gracefulSetFn) } -func TestEtcdListPersistentVolumes(t *testing.T) { - ctx := api.NewContext() - storage, _, fakeClient, _ := newStorage(t) - key := storage.KeyRootFunc(ctx) - key = etcdtest.AddPrefix(key) - fakeClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{ - Node: &etcd.Node{ - Nodes: []*etcd.Node{ - { - Value: runtime.EncodeOrDie(latest.Codec, validNewPersistentVolume("foo")), - }, - { - Value: runtime.EncodeOrDie(latest.Codec, validNewPersistentVolume("bar")), - }, - }, - }, - }, - E: nil, - } - - pvObj, err := storage.List(ctx, labels.Everything(), fields.Everything()) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - pvs := pvObj.(*api.PersistentVolumeList) - - if len(pvs.Items) != 2 || pvs.Items[0].Name != "foo" || pvs.Items[1].Name != "bar" { - t.Errorf("Unexpected persistentVolume list: %#v", pvs) - } -} - func TestEtcdGetPersistentVolumes(t *testing.T) { storage, _, fakeClient, _ := newStorage(t) test := resttest.New(t, storage, fakeClient.SetError).ClusterScope() @@ -155,70 +122,19 @@ func TestEtcdGetPersistentVolumes(t *testing.T) { test.TestGet(persistentVolume) } -func TestListEmptyPersistentVolumesList(t *testing.T) { - ctx := api.NewContext() +func TestEtcdListPersistentVolumes(t *testing.T) { storage, _, fakeClient, _ := newStorage(t) - fakeClient.ChangeIndex = 1 - key := storage.KeyRootFunc(ctx) - key = etcdtest.AddPrefix(key) - fakeClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{}, - E: fakeClient.NewError(tools.EtcdErrorCodeNotFound), - } - - persistentVolume, err := storage.List(ctx, labels.Everything(), fields.Everything()) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - if len(persistentVolume.(*api.PersistentVolumeList).Items) != 0 { - t.Errorf("Unexpected non-zero pod list: %#v", persistentVolume) - } - if persistentVolume.(*api.PersistentVolumeList).ResourceVersion != "1" { - t.Errorf("Unexpected resource version: %#v", persistentVolume) - } -} - -func TestListPersistentVolumesList(t *testing.T) { - ctx := api.NewContext() - storage, _, fakeClient, _ := newStorage(t) - fakeClient.ChangeIndex = 1 - key := storage.KeyRootFunc(ctx) - key = etcdtest.AddPrefix(key) - fakeClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{ - Node: &etcd.Node{ - Nodes: []*etcd.Node{ - { - Value: runtime.EncodeOrDie(latest.Codec, &api.PersistentVolume{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - }), - }, - { - Value: runtime.EncodeOrDie(latest.Codec, &api.PersistentVolume{ - ObjectMeta: api.ObjectMeta{Name: "bar"}, - }), - }, - }, - }, + test := resttest.New(t, storage, fakeClient.SetError).ClusterScope() + key := etcdtest.AddPrefix(storage.KeyRootFunc(test.TestContext())) + persistentVolume := validNewPersistentVolume("foo") + test.TestList( + persistentVolume, + func(objects []runtime.Object) []runtime.Object { + return registrytest.SetObjectsForKey(fakeClient, key, objects) }, - } - - persistentVolumeObj, err := storage.List(ctx, labels.Everything(), fields.Everything()) - persistentVolumeList := persistentVolumeObj.(*api.PersistentVolumeList) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - if len(persistentVolumeList.Items) != 2 { - t.Errorf("Unexpected persistentVolume list: %#v", persistentVolumeList) - } - if persistentVolumeList.Items[0].Name != "foo" { - t.Errorf("Unexpected persistentVolume: %#v", persistentVolumeList.Items[0]) - } - if persistentVolumeList.Items[1].Name != "bar" { - t.Errorf("Unexpected persistentVolume: %#v", persistentVolumeList.Items[1]) - } + func(resourceVersion uint64) { + registrytest.SetResourceVersion(fakeClient, resourceVersion) + }) } func TestPersistentVolumesDecode(t *testing.T) { diff --git a/pkg/registry/persistentvolumeclaim/etcd/etcd_test.go b/pkg/registry/persistentvolumeclaim/etcd/etcd_test.go index e6fecd389e5..367a0c2ac9c 100644 --- a/pkg/registry/persistentvolumeclaim/etcd/etcd_test.go +++ b/pkg/registry/persistentvolumeclaim/etcd/etcd_test.go @@ -23,8 +23,7 @@ import ( "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/rest/resttest" - "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/storage" etcdstorage "k8s.io/kubernetes/pkg/storage/etcd" @@ -114,38 +113,6 @@ func TestDelete(t *testing.T) { test.TestDelete(createFn, gracefulSetFn) } -func TestEtcdListPersistentVolumeClaims(t *testing.T) { - ctx := api.NewDefaultContext() - registry, _, fakeClient, _ := newStorage(t) - key := registry.KeyRootFunc(ctx) - key = etcdtest.AddPrefix(key) - fakeClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{ - Node: &etcd.Node{ - Nodes: []*etcd.Node{ - { - Value: runtime.EncodeOrDie(latest.Codec, validNewPersistentVolumeClaim("foo", api.NamespaceDefault)), - }, - { - Value: runtime.EncodeOrDie(latest.Codec, validNewPersistentVolumeClaim("bar", api.NamespaceDefault)), - }, - }, - }, - }, - E: nil, - } - - pvObj, err := registry.List(ctx, labels.Everything(), fields.Everything()) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - pvs := pvObj.(*api.PersistentVolumeClaimList) - - if len(pvs.Items) != 2 || pvs.Items[0].Name != "foo" || pvs.Items[1].Name != "bar" { - t.Errorf("Unexpected persistentVolume list: %#v", pvs) - } -} - func TestEtcdGetPersistentVolumeClaims(t *testing.T) { storage, _, fakeClient, _ := newStorage(t) test := resttest.New(t, storage, fakeClient.SetError) @@ -153,70 +120,19 @@ func TestEtcdGetPersistentVolumeClaims(t *testing.T) { test.TestGet(claim) } -func TestListEmptyPersistentVolumeClaimsList(t *testing.T) { - ctx := api.NewDefaultContext() - registry, _, fakeClient, _ := newStorage(t) - fakeClient.ChangeIndex = 1 - key := registry.KeyRootFunc(ctx) - key = etcdtest.AddPrefix(key) - fakeClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{}, - E: fakeClient.NewError(tools.EtcdErrorCodeNotFound), - } - - persistentVolume, err := registry.List(ctx, labels.Everything(), fields.Everything()) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - if len(persistentVolume.(*api.PersistentVolumeClaimList).Items) != 0 { - t.Errorf("Unexpected non-zero pod list: %#v", persistentVolume) - } - if persistentVolume.(*api.PersistentVolumeClaimList).ResourceVersion != "1" { - t.Errorf("Unexpected resource version: %#v", persistentVolume) - } -} - -func TestListPersistentVolumeClaimsList(t *testing.T) { - ctx := api.NewDefaultContext() - registry, _, fakeClient, _ := newStorage(t) - fakeClient.ChangeIndex = 1 - key := registry.KeyRootFunc(ctx) - key = etcdtest.AddPrefix(key) - fakeClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{ - Node: &etcd.Node{ - Nodes: []*etcd.Node{ - { - Value: runtime.EncodeOrDie(latest.Codec, &api.PersistentVolumeClaim{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - }), - }, - { - Value: runtime.EncodeOrDie(latest.Codec, &api.PersistentVolumeClaim{ - ObjectMeta: api.ObjectMeta{Name: "bar"}, - }), - }, - }, - }, +func TestEtcdListPersistentVolumeClaims(t *testing.T) { + storage, _, fakeClient, _ := newStorage(t) + test := resttest.New(t, storage, fakeClient.SetError) + key := etcdtest.AddPrefix(storage.KeyRootFunc(test.TestContext())) + claim := validNewPersistentVolumeClaim("foo", api.NamespaceDefault) + test.TestList( + claim, + func(objects []runtime.Object) []runtime.Object { + return registrytest.SetObjectsForKey(fakeClient, key, objects) }, - } - - persistentVolumeObj, err := registry.List(ctx, labels.Everything(), fields.Everything()) - persistentVolumeList := persistentVolumeObj.(*api.PersistentVolumeClaimList) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - if len(persistentVolumeList.Items) != 2 { - t.Errorf("Unexpected persistentVolume list: %#v", persistentVolumeList) - } - if persistentVolumeList.Items[0].Name != "foo" { - t.Errorf("Unexpected persistentVolume: %#v", persistentVolumeList.Items[0]) - } - if persistentVolumeList.Items[1].Name != "bar" { - t.Errorf("Unexpected persistentVolume: %#v", persistentVolumeList.Items[1]) - } + func(resourceVersion uint64) { + registrytest.SetResourceVersion(fakeClient, resourceVersion) + }) } func TestPersistentVolumeClaimsDecode(t *testing.T) { diff --git a/pkg/registry/pod/etcd/etcd_test.go b/pkg/registry/pod/etcd/etcd_test.go index e05f3065e9f..980fb3e466e 100644 --- a/pkg/registry/pod/etcd/etcd_test.go +++ b/pkg/registry/pod/etcd/etcd_test.go @@ -31,6 +31,7 @@ import ( "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/pod" + "k8s.io/kubernetes/pkg/registry/registrytest" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/securitycontext" "k8s.io/kubernetes/pkg/storage" @@ -182,193 +183,6 @@ func TestCreateSetsFields(t *testing.T) { } } -func TestListError(t *testing.T) { - fakeEtcdClient, etcdStorage := newEtcdStorage(t) - fakeEtcdClient.Err = fmt.Errorf("test error") - storage := NewStorage(etcdStorage, nil).Pod - pods, err := storage.List(api.NewDefaultContext(), labels.Everything(), fields.Everything()) - if err != fakeEtcdClient.Err { - t.Fatalf("Expected %#v, Got %#v", fakeEtcdClient.Err, err) - } - if pods != nil { - t.Errorf("Unexpected non-nil pod list: %#v", pods) - } -} - -func TestListEmptyPodList(t *testing.T) { - fakeEtcdClient, etcdStorage := newEtcdStorage(t) - fakeEtcdClient.ChangeIndex = 1 - ctx := api.NewContext() - storage := NewStorage(etcdStorage, nil).Pod - key := storage.Etcd.KeyRootFunc(ctx) - key = etcdtest.AddPrefix(key) - - fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{}, - E: fakeEtcdClient.NewError(tools.EtcdErrorCodeNotFound), - } - pods, err := storage.List(api.NewContext(), labels.Everything(), fields.Everything()) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - if len(pods.(*api.PodList).Items) != 0 { - t.Errorf("Unexpected non-zero pod list: %#v", pods) - } - if pods.(*api.PodList).ResourceVersion != "1" { - t.Errorf("Unexpected resource version: %#v", pods) - } -} - -func TestListPodList(t *testing.T) { - fakeEtcdClient, etcdStorage := newEtcdStorage(t) - ctx := api.NewDefaultContext() - storage := NewStorage(etcdStorage, nil).Pod - key := storage.Etcd.KeyRootFunc(ctx) - key = etcdtest.AddPrefix(key) - fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{ - Node: &etcd.Node{ - Nodes: []*etcd.Node{ - { - Value: runtime.EncodeOrDie(latest.Codec, &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - Spec: api.PodSpec{NodeName: "machine"}, - Status: api.PodStatus{Phase: api.PodRunning}, - }), - }, - { - Value: runtime.EncodeOrDie(latest.Codec, &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "bar"}, - Spec: api.PodSpec{NodeName: "machine"}, - }), - }, - }, - }, - }, - } - - podsObj, err := storage.List(api.NewDefaultContext(), labels.Everything(), fields.Everything()) - pods := podsObj.(*api.PodList) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - if len(pods.Items) != 2 { - t.Errorf("Unexpected pod list: %#v", pods) - } - if pods.Items[0].Name != "foo" || pods.Items[0].Status.Phase != api.PodRunning || pods.Items[0].Spec.NodeName != "machine" { - t.Errorf("Unexpected pod: %#v", pods.Items[0]) - } - if pods.Items[1].Name != "bar" || pods.Items[1].Spec.NodeName != "machine" { - t.Errorf("Unexpected pod: %#v", pods.Items[1]) - } -} - -func TestListPodListSelection(t *testing.T) { - fakeEtcdClient, etcdStorage := newEtcdStorage(t) - ctx := api.NewDefaultContext() - storage := NewStorage(etcdStorage, nil).Pod - rootKey := etcdtest.AddPrefix("pods/default") - key := etcdtest.AddPrefix("pods/default/zot") - fakeEtcdClient.Data[rootKey] = tools.EtcdResponseWithError{ - R: &etcd.Response{ - Node: &etcd.Node{ - Nodes: []*etcd.Node{ - {Value: runtime.EncodeOrDie(latest.Codec, &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - })}, - {Value: runtime.EncodeOrDie(latest.Codec, &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "bar"}, - Spec: api.PodSpec{NodeName: "barhost"}, - })}, - {Value: runtime.EncodeOrDie(latest.Codec, &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "baz"}, - Status: api.PodStatus{Phase: api.PodFailed}, - })}, - {Value: runtime.EncodeOrDie(latest.Codec, &api.Pod{ - ObjectMeta: api.ObjectMeta{ - Name: "qux", - Labels: map[string]string{"label": "qux"}, - }, - })}, - {Value: runtime.EncodeOrDie(latest.Codec, &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "zot"}, - })}, - }, - }, - }, - } - fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{ - Node: &etcd.Node{ - Value: runtime.EncodeOrDie(latest.Codec, &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "zot"}, - }), - }, - }, - } - - table := []struct { - label, field string - expectedIDs util.StringSet - }{ - { - expectedIDs: util.NewStringSet("foo", "bar", "baz", "qux", "zot"), - }, { - field: "metadata.name=zot", - expectedIDs: util.NewStringSet("zot"), - }, { - label: "label=qux", - expectedIDs: util.NewStringSet("qux"), - }, { - field: "status.phase=Failed", - expectedIDs: util.NewStringSet("baz"), - }, { - field: "spec.nodeName=barhost", - expectedIDs: util.NewStringSet("bar"), - }, { - field: "spec.nodeName=", - expectedIDs: util.NewStringSet("foo", "baz", "qux", "zot"), - }, { - field: "spec.nodeName!=", - expectedIDs: util.NewStringSet("bar"), - }, - } - - for index, item := range table { - label, err := labels.Parse(item.label) - if err != nil { - t.Errorf("unexpected error: %v", err) - continue - } - field, err := fields.ParseSelector(item.field) - if err != nil { - t.Errorf("unexpected error: %v", err) - continue - } - podsObj, err := storage.List(ctx, label, field) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - pods := podsObj.(*api.PodList) - - set := util.NewStringSet() - for i := range pods.Items { - set.Insert(pods.Items[i].Name) - } - if e, a := len(item.expectedIDs), len(set); e != a { - t.Errorf("%v: Expected %v, got %v", index, item.expectedIDs, set) - } - /*for _, pod := range pods.Items { - if !item.expectedIDs.Has(pod.Name) { - t.Errorf("%v: Unexpected pod %v", index, pod.Name) - } - t.Logf("%v: Got pod Name: %v", index, pod.Name) - }*/ - } -} - func TestPodDecode(t *testing.T) { _, etcdStorage := newEtcdStorage(t) storage := NewStorage(etcdStorage, nil).Pod @@ -642,6 +456,22 @@ func TestEtcdGet(t *testing.T) { test.TestGet(pod) } +func TestEtcdList(t *testing.T) { + fakeEtcdClient, etcdStorage := newEtcdStorage(t) + storage := NewStorage(etcdStorage, nil).Pod + test := resttest.New(t, storage, fakeEtcdClient.SetError) + key := etcdtest.AddPrefix(storage.Etcd.KeyRootFunc(test.TestContext())) + pod := validNewPod() + test.TestList( + pod, + func(objects []runtime.Object) []runtime.Object { + return registrytest.SetObjectsForKey(fakeEtcdClient, key, objects) + }, + func(resourceVersion uint64) { + registrytest.SetResourceVersion(fakeEtcdClient, resourceVersion) + }) +} + func TestEtcdCreate(t *testing.T) { registry, bindingRegistry, _, fakeClient, _ := newStorage(t) ctx := api.NewDefaultContext() @@ -1184,90 +1014,6 @@ func TestEtcdDeletePodMultipleContainers(t *testing.T) { } } -func TestEtcdEmptyList(t *testing.T) { - registry, _, _, fakeClient, _ := newStorage(t) - ctx := api.NewDefaultContext() - key := registry.KeyRootFunc(ctx) - key = etcdtest.AddPrefix(key) - fakeClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{ - Node: &etcd.Node{ - Nodes: []*etcd.Node{}, - }, - }, - E: nil, - } - - obj, err := registry.List(ctx, labels.Everything(), fields.Everything()) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - pods := obj.(*api.PodList) - if len(pods.Items) != 0 { - t.Errorf("Unexpected pod list: %#v", pods) - } -} - -func TestEtcdListNotFound(t *testing.T) { - registry, _, _, fakeClient, _ := newStorage(t) - ctx := api.NewDefaultContext() - key := registry.KeyRootFunc(ctx) - key = etcdtest.AddPrefix(key) - fakeClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{}, - E: tools.EtcdErrorNotFound, - } - obj, err := registry.List(ctx, labels.Everything(), fields.Everything()) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - pods := obj.(*api.PodList) - if len(pods.Items) != 0 { - t.Errorf("Unexpected pod list: %#v", pods) - } -} - -func TestEtcdList(t *testing.T) { - registry, _, _, fakeClient, _ := newStorage(t) - ctx := api.NewDefaultContext() - key := registry.KeyRootFunc(ctx) - key = etcdtest.AddPrefix(key) - fakeClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{ - Node: &etcd.Node{ - Nodes: []*etcd.Node{ - { - Value: runtime.EncodeOrDie(latest.Codec, &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - Spec: api.PodSpec{NodeName: "machine"}, - }), - }, - { - Value: runtime.EncodeOrDie(latest.Codec, &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "bar"}, - Spec: api.PodSpec{NodeName: "machine"}, - }), - }, - }, - }, - }, - E: nil, - } - obj, err := registry.List(ctx, labels.Everything(), fields.Everything()) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - pods := obj.(*api.PodList) - - if len(pods.Items) != 2 || pods.Items[0].Name != "foo" || pods.Items[1].Name != "bar" { - t.Errorf("Unexpected pod list: %#v", pods) - } - if pods.Items[0].Spec.NodeName != "machine" || - pods.Items[1].Spec.NodeName != "machine" { - t.Errorf("Failed to populate host name.") - } -} - func TestEtcdWatchPods(t *testing.T) { registry, _, _, fakeClient, _ := newStorage(t) ctx := api.NewDefaultContext() diff --git a/pkg/registry/registrytest/etcd.go b/pkg/registry/registrytest/etcd.go new file mode 100644 index 00000000000..98627d89c9e --- /dev/null +++ b/pkg/registry/registrytest/etcd.go @@ -0,0 +1,56 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package registrytest + +import ( + "github.com/coreos/go-etcd/etcd" + + "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/tools" +) + +func SetResourceVersion(fakeClient *tools.FakeEtcdClient, resourceVersion uint64) { + fakeClient.ChangeIndex = resourceVersion +} + +func SetObjectsForKey(fakeClient *tools.FakeEtcdClient, key string, objects []runtime.Object) []runtime.Object { + result := make([]runtime.Object, len(objects)) + if len(objects) > 0 { + nodes := make([]*etcd.Node, len(objects)) + for i, obj := range objects { + encoded := runtime.EncodeOrDie(latest.Codec, obj) + decoded, _ := latest.Codec.Decode([]byte(encoded)) + nodes[i] = &etcd.Node{Value: encoded} + result[i] = decoded + } + fakeClient.Data[key] = tools.EtcdResponseWithError{ + R: &etcd.Response{ + Node: &etcd.Node{ + Nodes: nodes, + }, + }, + E: nil, + } + } else { + fakeClient.Data[key] = tools.EtcdResponseWithError{ + R: &etcd.Response{}, + E: fakeClient.NewError(tools.EtcdErrorCodeNotFound), + } + } + return result +} diff --git a/pkg/registry/resourcequota/etcd/etcd_test.go b/pkg/registry/resourcequota/etcd/etcd_test.go index 05198ebdf93..51fcd0d4b87 100644 --- a/pkg/registry/resourcequota/etcd/etcd_test.go +++ b/pkg/registry/resourcequota/etcd/etcd_test.go @@ -29,6 +29,7 @@ import ( "k8s.io/kubernetes/pkg/api/rest/resttest" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/registry/registrytest" "k8s.io/kubernetes/pkg/registry/resourcequota" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/storage" @@ -146,155 +147,6 @@ func TestCreateSetsFields(t *testing.T) { } } -func TestListError(t *testing.T) { - fakeEtcdClient, etcdStorage := newEtcdStorage(t) - fakeEtcdClient.Err = fmt.Errorf("test error") - storage, _ := NewStorage(etcdStorage) - resourcequotas, err := storage.List(api.NewDefaultContext(), labels.Everything(), fields.Everything()) - if err != fakeEtcdClient.Err { - t.Fatalf("Expected %#v, Got %#v", fakeEtcdClient.Err, err) - } - if resourcequotas != nil { - t.Errorf("Unexpected non-nil resourcequota list: %#v", resourcequotas) - } -} - -func TestListEmptyResourceQuotaList(t *testing.T) { - fakeEtcdClient, etcdStorage := newEtcdStorage(t) - fakeEtcdClient.ChangeIndex = 1 - storage, _ := NewStorage(etcdStorage) - ctx := api.NewContext() - key := storage.Etcd.KeyRootFunc(ctx) - key = etcdtest.AddPrefix(key) - - fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{}, - E: fakeEtcdClient.NewError(tools.EtcdErrorCodeNotFound), - } - - resourcequotas, err := storage.List(api.NewContext(), labels.Everything(), fields.Everything()) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - if len(resourcequotas.(*api.ResourceQuotaList).Items) != 0 { - t.Errorf("Unexpected non-zero resourcequota list: %#v", resourcequotas) - } - if resourcequotas.(*api.ResourceQuotaList).ResourceVersion != "1" { - t.Errorf("Unexpected resource version: %#v", resourcequotas) - } -} - -func TestListResourceQuotaList(t *testing.T) { - fakeEtcdClient, etcdStorage := newEtcdStorage(t) - storage, _ := NewStorage(etcdStorage) - ctx := api.NewDefaultContext() - key := storage.Etcd.KeyRootFunc(ctx) - key = etcdtest.AddPrefix(key) - fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{ - Node: &etcd.Node{ - Nodes: []*etcd.Node{ - { - Value: runtime.EncodeOrDie(latest.Codec, &api.ResourceQuota{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - }), - }, - { - Value: runtime.EncodeOrDie(latest.Codec, &api.ResourceQuota{ - ObjectMeta: api.ObjectMeta{Name: "bar"}, - }), - }, - }, - }, - }, - } - resourcequotasObj, err := storage.List(api.NewDefaultContext(), labels.Everything(), fields.Everything()) - resourcequotas := resourcequotasObj.(*api.ResourceQuotaList) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - if len(resourcequotas.Items) != 2 { - t.Errorf("Unexpected resourcequota list: %#v", resourcequotas) - } - if resourcequotas.Items[0].Name != "foo" { - t.Errorf("Unexpected resourcequota: %#v", resourcequotas.Items[0]) - } - if resourcequotas.Items[1].Name != "bar" { - t.Errorf("Unexpected resourcequota: %#v", resourcequotas.Items[1]) - } -} - -func TestListResourceQuotaListSelection(t *testing.T) { - fakeEtcdClient, etcdStorage := newEtcdStorage(t) - storage, _ := NewStorage(etcdStorage) - ctx := api.NewDefaultContext() - key := storage.Etcd.KeyRootFunc(ctx) - key = etcdtest.AddPrefix(key) - fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{ - Node: &etcd.Node{ - Nodes: []*etcd.Node{ - {Value: runtime.EncodeOrDie(latest.Codec, &api.ResourceQuota{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - })}, - {Value: runtime.EncodeOrDie(latest.Codec, &api.ResourceQuota{ - ObjectMeta: api.ObjectMeta{ - Name: "qux", - Labels: map[string]string{"label": "qux"}, - }, - })}, - {Value: runtime.EncodeOrDie(latest.Codec, &api.ResourceQuota{ - ObjectMeta: api.ObjectMeta{Name: "zot"}, - })}, - }, - }, - }, - } - - table := []struct { - label, field string - expectedIDs util.StringSet - }{ - { - expectedIDs: util.NewStringSet("foo", "qux", "zot"), - }, { - field: "name=zot", - expectedIDs: util.NewStringSet("zot"), - }, { - label: "label=qux", - expectedIDs: util.NewStringSet("qux"), - }, - } - - for index, item := range table { - label, err := labels.Parse(item.label) - if err != nil { - t.Errorf("unexpected error: %v", err) - continue - } - field, err := fields.ParseSelector(item.field) - if err != nil { - t.Errorf("unexpected error: %v", err) - continue - } - resourcequotasObj, err := storage.List(ctx, label, field) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - resourcequotas := resourcequotasObj.(*api.ResourceQuotaList) - - set := util.NewStringSet() - for i := range resourcequotas.Items { - set.Insert(resourcequotas.Items[i].Name) - } - if e, a := len(item.expectedIDs), len(set); e != a { - t.Errorf("%v: Expected %v, got %v", index, item.expectedIDs, set) - } - } -} - func TestResourceQuotaDecode(t *testing.T) { _, etcdStorage := newEtcdStorage(t) storage, _ := NewStorage(etcdStorage) @@ -350,6 +202,22 @@ func TestEtcdGet(t *testing.T) { test.TestGet(resourcequota) } +func TestEtcdList(t *testing.T) { + fakeEtcdClient, etcdStorage := newEtcdStorage(t) + storage, _ := NewStorage(etcdStorage) + test := resttest.New(t, storage, fakeEtcdClient.SetError) + key := etcdtest.AddPrefix(storage.Etcd.KeyRootFunc(test.TestContext())) + resourcequota := validNewResourceQuota() + test.TestList( + resourcequota, + func(objects []runtime.Object) []runtime.Object { + return registrytest.SetObjectsForKey(fakeEtcdClient, key, objects) + }, + func(resourceVersion uint64) { + registrytest.SetResourceVersion(fakeEtcdClient, resourceVersion) + }) +} + func TestEtcdCreateFailsWithoutNamespace(t *testing.T) { registry, _, fakeClient, _ := newStorage(t) fakeClient.TestIndex = true @@ -436,84 +304,6 @@ func TestEtcdUpdateStatus(t *testing.T) { } } -func TestEtcdEmptyList(t *testing.T) { - registry, _, fakeClient, _ := newStorage(t) - ctx := api.NewDefaultContext() - key := registry.KeyRootFunc(ctx) - key = etcdtest.AddPrefix(key) - fakeClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{ - Node: &etcd.Node{ - Nodes: []*etcd.Node{}, - }, - }, - E: nil, - } - - obj, err := registry.List(ctx, labels.Everything(), fields.Everything()) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - resourcequotas := obj.(*api.ResourceQuotaList) - if len(resourcequotas.Items) != 0 { - t.Errorf("Unexpected resourcequota list: %#v", resourcequotas) - } -} - -func TestEtcdListNotFound(t *testing.T) { - registry, _, fakeClient, _ := newStorage(t) - ctx := api.NewDefaultContext() - key := registry.KeyRootFunc(ctx) - key = etcdtest.AddPrefix(key) - fakeClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{}, - E: tools.EtcdErrorNotFound, - } - obj, err := registry.List(ctx, labels.Everything(), fields.Everything()) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - resourcequotas := obj.(*api.ResourceQuotaList) - if len(resourcequotas.Items) != 0 { - t.Errorf("Unexpected resourcequota list: %#v", resourcequotas) - } -} - -func TestEtcdList(t *testing.T) { - registry, _, fakeClient, _ := newStorage(t) - ctx := api.NewDefaultContext() - key := registry.KeyRootFunc(ctx) - key = etcdtest.AddPrefix(key) - fakeClient.Data[key] = tools.EtcdResponseWithError{ - R: &etcd.Response{ - Node: &etcd.Node{ - Nodes: []*etcd.Node{ - { - Value: runtime.EncodeOrDie(latest.Codec, &api.ResourceQuota{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - }), - }, - { - Value: runtime.EncodeOrDie(latest.Codec, &api.ResourceQuota{ - ObjectMeta: api.ObjectMeta{Name: "bar"}, - }), - }, - }, - }, - }, - E: nil, - } - obj, err := registry.List(ctx, labels.Everything(), fields.Everything()) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - resourcequotas := obj.(*api.ResourceQuotaList) - - if len(resourcequotas.Items) != 2 || resourcequotas.Items[0].Name != "foo" || resourcequotas.Items[1].Name != "bar" { - t.Errorf("Unexpected resourcequota list: %#v", resourcequotas) - } -} - func TestEtcdWatchResourceQuotas(t *testing.T) { registry, _, fakeClient, _ := newStorage(t) ctx := api.NewDefaultContext() diff --git a/pkg/tools/fake_etcd_client.go b/pkg/tools/fake_etcd_client.go index 22b8a59e763..d719573d6dc 100644 --- a/pkg/tools/fake_etcd_client.go +++ b/pkg/tools/fake_etcd_client.go @@ -142,7 +142,7 @@ func (f *FakeEtcdClient) Get(key string, sort, recursive bool) (*etcd.Response, } f.t.Logf("returning %v: %#v %#v", key, result.R, result.E) - // Sort response, note this will alter resutl.R. + // Sort response, note this will alter result.R. if result.R.Node != nil && result.R.Node.Nodes != nil && sort { f.sortResponse(result.R.Node.Nodes) }