| /* |
| Copyright 2018 The Kubernetes Authors. |
| |
| 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 dynamiclister_test |
| |
| import ( |
| "reflect" |
| "testing" |
| |
| "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" |
| "k8s.io/apimachinery/pkg/labels" |
| "k8s.io/apimachinery/pkg/runtime" |
| "k8s.io/apimachinery/pkg/runtime/schema" |
| "k8s.io/apimachinery/pkg/util/diff" |
| "k8s.io/client-go/dynamic/dynamiclister" |
| "k8s.io/client-go/tools/cache" |
| ) |
| |
| func TestNamespaceGetMethod(t *testing.T) { |
| tests := []struct { |
| name string |
| existingObjects []runtime.Object |
| namespaceToSync string |
| gvrToSync schema.GroupVersionResource |
| objectToGet string |
| expectedObject *unstructured.Unstructured |
| expectError bool |
| }{ |
| { |
| name: "scenario 1: gets name-foo1 resource from the indexer from ns-foo namespace", |
| existingObjects: []runtime.Object{ |
| newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"), |
| newUnstructured("group/version", "TheKind", "ns-foo", "name-foo1"), |
| newUnstructured("group/version", "TheKind", "ns-bar", "name-bar"), |
| }, |
| namespaceToSync: "ns-foo", |
| gvrToSync: schema.GroupVersionResource{Group: "group", Version: "version", Resource: "TheKinds"}, |
| objectToGet: "name-foo1", |
| expectedObject: newUnstructured("group/version", "TheKind", "ns-foo", "name-foo1"), |
| }, |
| { |
| name: "scenario 2: gets name-foo-non-existing resource from the indexer from ns-foo namespace", |
| existingObjects: []runtime.Object{ |
| newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"), |
| newUnstructured("group/version", "TheKind", "ns-foo", "name-foo1"), |
| newUnstructured("group/version", "TheKind", "ns-bar", "name-bar"), |
| }, |
| namespaceToSync: "ns-foo", |
| gvrToSync: schema.GroupVersionResource{Group: "group", Version: "version", Resource: "TheKinds"}, |
| objectToGet: "name-foo-non-existing", |
| expectError: true, |
| }, |
| } |
| |
| for _, test := range tests { |
| t.Run(test.name, func(t *testing.T) { |
| // test data |
| indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{}) |
| for _, obj := range test.existingObjects { |
| err := indexer.Add(obj) |
| if err != nil { |
| t.Fatal(err) |
| } |
| } |
| // act |
| target := dynamiclister.New(indexer, test.gvrToSync).Namespace(test.namespaceToSync) |
| actualObject, err := target.Get(test.objectToGet) |
| |
| // validate |
| if test.expectError { |
| if err == nil { |
| t.Fatal("expected to get an error but non was returned") |
| } |
| return |
| } |
| if err != nil { |
| t.Fatal(err) |
| } |
| if !reflect.DeepEqual(test.expectedObject, actualObject) { |
| t.Fatalf("unexpected object has been returned expected = %v actual = %v, diff = %v", test.expectedObject, actualObject, diff.ObjectDiff(test.expectedObject, actualObject)) |
| } |
| }) |
| } |
| } |
| |
| func TestNamespaceListMethod(t *testing.T) { |
| // test data |
| objs := []runtime.Object{ |
| newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"), |
| newUnstructured("group/version", "TheKind", "ns-foo", "name-foo1"), |
| newUnstructured("group/version", "TheKind", "ns-bar", "name-bar"), |
| } |
| indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{}) |
| for _, obj := range objs { |
| err := indexer.Add(obj) |
| if err != nil { |
| t.Fatal(err) |
| } |
| } |
| expectedOutput := []*unstructured.Unstructured{ |
| newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"), |
| newUnstructured("group/version", "TheKind", "ns-foo", "name-foo1"), |
| } |
| namespaceToList := "ns-foo" |
| |
| // act |
| target := dynamiclister.New(indexer, schema.GroupVersionResource{Group: "group", Version: "version", Resource: "TheKinds"}).Namespace(namespaceToList) |
| actualOutput, err := target.List(labels.Everything()) |
| |
| // validate |
| if err != nil { |
| t.Fatal(err) |
| } |
| assertListOrDie(expectedOutput, actualOutput, t) |
| } |
| |
| func TestListerGetMethod(t *testing.T) { |
| tests := []struct { |
| name string |
| existingObjects []runtime.Object |
| namespaceToSync string |
| gvrToSync schema.GroupVersionResource |
| objectToGet string |
| expectedObject *unstructured.Unstructured |
| expectError bool |
| }{ |
| { |
| name: "scenario 1: gets name-foo1 resource from the indexer", |
| existingObjects: []runtime.Object{ |
| newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"), |
| newUnstructured("group/version", "TheKind", "", "name-foo1"), |
| newUnstructured("group/version", "TheKind", "ns-bar", "name-bar"), |
| }, |
| namespaceToSync: "", |
| gvrToSync: schema.GroupVersionResource{Group: "group", Version: "version", Resource: "TheKinds"}, |
| objectToGet: "name-foo1", |
| expectedObject: newUnstructured("group/version", "TheKind", "", "name-foo1"), |
| }, |
| { |
| name: "scenario 2: doesn't get name-foo resource from the indexer from ns-foo namespace", |
| existingObjects: []runtime.Object{ |
| newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"), |
| newUnstructured("group/version", "TheKind", "ns-foo", "name-foo1"), |
| newUnstructured("group/version", "TheKind", "ns-bar", "name-bar"), |
| }, |
| namespaceToSync: "ns-foo", |
| gvrToSync: schema.GroupVersionResource{Group: "group", Version: "version", Resource: "TheKinds"}, |
| objectToGet: "name-foo", |
| expectError: true, |
| }, |
| } |
| |
| for _, test := range tests { |
| t.Run(test.name, func(t *testing.T) { |
| // test data |
| indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{}) |
| for _, obj := range test.existingObjects { |
| err := indexer.Add(obj) |
| if err != nil { |
| t.Fatal(err) |
| } |
| } |
| // act |
| target := dynamiclister.New(indexer, test.gvrToSync) |
| actualObject, err := target.Get(test.objectToGet) |
| |
| // validate |
| if test.expectError { |
| if err == nil { |
| t.Fatal("expected to get an error but non was returned") |
| } |
| return |
| } |
| if err != nil { |
| t.Fatal(err) |
| } |
| if !reflect.DeepEqual(test.expectedObject, actualObject) { |
| t.Fatalf("unexpected object has been returned expected = %v actual = %v, diff = %v", test.expectedObject, actualObject, diff.ObjectDiff(test.expectedObject, actualObject)) |
| } |
| }) |
| } |
| } |
| |
| func TestListerListMethod(t *testing.T) { |
| // test data |
| objs := []runtime.Object{ |
| newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"), |
| newUnstructured("group/version", "TheKind", "ns-foo", "name-bar"), |
| } |
| indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{}) |
| for _, obj := range objs { |
| err := indexer.Add(obj) |
| if err != nil { |
| t.Fatal(err) |
| } |
| } |
| expectedOutput := []*unstructured.Unstructured{ |
| newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"), |
| newUnstructured("group/version", "TheKind", "ns-foo", "name-bar"), |
| } |
| |
| // act |
| target := dynamiclister.New(indexer, schema.GroupVersionResource{Group: "group", Version: "version", Resource: "TheKinds"}) |
| actualOutput, err := target.List(labels.Everything()) |
| |
| // validate |
| if err != nil { |
| t.Fatal(err) |
| } |
| assertListOrDie(expectedOutput, actualOutput, t) |
| } |
| |
| func newUnstructured(apiVersion, kind, namespace, name string) *unstructured.Unstructured { |
| return &unstructured.Unstructured{ |
| Object: map[string]interface{}{ |
| "apiVersion": apiVersion, |
| "kind": kind, |
| "metadata": map[string]interface{}{ |
| "namespace": namespace, |
| "name": name, |
| }, |
| }, |
| } |
| } |
| |
| func assertListOrDie(expected, actual []*unstructured.Unstructured, t *testing.T) { |
| if len(actual) != len(expected) { |
| t.Fatalf("unexpected number of items returned, expected = %d, actual = %d", len(expected), len(actual)) |
| } |
| for _, expectedObject := range expected { |
| found := false |
| for _, actualObject := range actual { |
| if actualObject.GetName() == expectedObject.GetName() { |
| if !reflect.DeepEqual(expectedObject, actualObject) { |
| t.Fatalf("unexpected object has been returned expected = %v actual = %v, diff = %v", expectedObject, actualObject, diff.ObjectDiff(expectedObject, actualObject)) |
| } |
| found = true |
| } |
| } |
| if !found { |
| t.Fatalf("the resource with the name = %s was not found in the returned output", expectedObject.GetName()) |
| } |
| } |
| } |