k8s.io/client-go@v0.31.1/metadata/metadatalister/lister_test.go (about) 1 /* 2 Copyright 2018 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package metadatalister 18 19 import ( 20 "reflect" 21 "testing" 22 23 "github.com/google/go-cmp/cmp" 24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 "k8s.io/apimachinery/pkg/labels" 26 "k8s.io/apimachinery/pkg/runtime" 27 "k8s.io/apimachinery/pkg/runtime/schema" 28 "k8s.io/client-go/tools/cache" 29 ) 30 31 func TestNamespaceGetMethod(t *testing.T) { 32 tests := []struct { 33 name string 34 existingObjects []runtime.Object 35 namespaceToSync string 36 gvrToSync schema.GroupVersionResource 37 objectToGet string 38 expectedObject *metav1.PartialObjectMetadata 39 expectError bool 40 }{ 41 { 42 name: "scenario 1: gets name-foo1 resource from the indexer from ns-foo namespace", 43 existingObjects: []runtime.Object{ 44 newPartialObjectMetadata("group/version", "TheKind", "ns-foo", "name-foo"), 45 newPartialObjectMetadata("group/version", "TheKind", "ns-foo", "name-foo1"), 46 newPartialObjectMetadata("group/version", "TheKind", "ns-bar", "name-bar"), 47 }, 48 namespaceToSync: "ns-foo", 49 gvrToSync: schema.GroupVersionResource{Group: "group", Version: "version", Resource: "TheKinds"}, 50 objectToGet: "name-foo1", 51 expectedObject: newPartialObjectMetadata("group/version", "TheKind", "ns-foo", "name-foo1"), 52 }, 53 { 54 name: "scenario 2: gets name-foo-non-existing resource from the indexer from ns-foo namespace", 55 existingObjects: []runtime.Object{ 56 newPartialObjectMetadata("group/version", "TheKind", "ns-foo", "name-foo"), 57 newPartialObjectMetadata("group/version", "TheKind", "ns-foo", "name-foo1"), 58 newPartialObjectMetadata("group/version", "TheKind", "ns-bar", "name-bar"), 59 }, 60 namespaceToSync: "ns-foo", 61 gvrToSync: schema.GroupVersionResource{Group: "group", Version: "version", Resource: "TheKinds"}, 62 objectToGet: "name-foo-non-existing", 63 expectError: true, 64 }, 65 } 66 67 for _, test := range tests { 68 t.Run(test.name, func(t *testing.T) { 69 // test data 70 indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{}) 71 for _, obj := range test.existingObjects { 72 err := indexer.Add(obj) 73 if err != nil { 74 t.Fatal(err) 75 } 76 } 77 // act 78 target := New(indexer, test.gvrToSync).Namespace(test.namespaceToSync) 79 actualObject, err := target.Get(test.objectToGet) 80 81 // validate 82 if test.expectError { 83 if err == nil { 84 t.Fatal("expected to get an error but non was returned") 85 } 86 return 87 } 88 if err != nil { 89 t.Fatal(err) 90 } 91 if !reflect.DeepEqual(test.expectedObject, actualObject) { 92 t.Fatalf("unexpected object has been returned expected = %v actual = %v, diff = %v", test.expectedObject, actualObject, cmp.Diff(test.expectedObject, actualObject)) 93 } 94 }) 95 } 96 } 97 98 func TestNamespaceListMethod(t *testing.T) { 99 // test data 100 objs := []runtime.Object{ 101 newPartialObjectMetadata("group/version", "TheKind", "ns-foo", "name-foo"), 102 newPartialObjectMetadata("group/version", "TheKind", "ns-foo", "name-foo1"), 103 newPartialObjectMetadata("group/version", "TheKind", "ns-bar", "name-bar"), 104 } 105 indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{}) 106 for _, obj := range objs { 107 err := indexer.Add(obj) 108 if err != nil { 109 t.Fatal(err) 110 } 111 } 112 expectedOutput := []*metav1.PartialObjectMetadata{ 113 newPartialObjectMetadata("group/version", "TheKind", "ns-foo", "name-foo"), 114 newPartialObjectMetadata("group/version", "TheKind", "ns-foo", "name-foo1"), 115 } 116 namespaceToList := "ns-foo" 117 118 // act 119 target := New(indexer, schema.GroupVersionResource{Group: "group", Version: "version", Resource: "TheKinds"}).Namespace(namespaceToList) 120 actualOutput, err := target.List(labels.Everything()) 121 122 // validate 123 if err != nil { 124 t.Fatal(err) 125 } 126 assertListOrDie(expectedOutput, actualOutput, t) 127 } 128 129 func TestListerGetMethod(t *testing.T) { 130 tests := []struct { 131 name string 132 existingObjects []runtime.Object 133 namespaceToSync string 134 gvrToSync schema.GroupVersionResource 135 objectToGet string 136 expectedObject *metav1.PartialObjectMetadata 137 expectError bool 138 }{ 139 { 140 name: "scenario 1: gets name-foo1 resource from the indexer", 141 existingObjects: []runtime.Object{ 142 newPartialObjectMetadata("group/version", "TheKind", "ns-foo", "name-foo"), 143 newPartialObjectMetadata("group/version", "TheKind", "", "name-foo1"), 144 newPartialObjectMetadata("group/version", "TheKind", "ns-bar", "name-bar"), 145 }, 146 namespaceToSync: "", 147 gvrToSync: schema.GroupVersionResource{Group: "group", Version: "version", Resource: "TheKinds"}, 148 objectToGet: "name-foo1", 149 expectedObject: newPartialObjectMetadata("group/version", "TheKind", "", "name-foo1"), 150 }, 151 { 152 name: "scenario 2: doesn't get name-foo resource from the indexer from ns-foo namespace", 153 existingObjects: []runtime.Object{ 154 newPartialObjectMetadata("group/version", "TheKind", "ns-foo", "name-foo"), 155 newPartialObjectMetadata("group/version", "TheKind", "ns-foo", "name-foo1"), 156 newPartialObjectMetadata("group/version", "TheKind", "ns-bar", "name-bar"), 157 }, 158 namespaceToSync: "ns-foo", 159 gvrToSync: schema.GroupVersionResource{Group: "group", Version: "version", Resource: "TheKinds"}, 160 objectToGet: "name-foo", 161 expectError: true, 162 }, 163 } 164 165 for _, test := range tests { 166 t.Run(test.name, func(t *testing.T) { 167 // test data 168 indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{}) 169 for _, obj := range test.existingObjects { 170 err := indexer.Add(obj) 171 if err != nil { 172 t.Fatal(err) 173 } 174 } 175 // act 176 target := New(indexer, test.gvrToSync) 177 actualObject, err := target.Get(test.objectToGet) 178 179 // validate 180 if test.expectError { 181 if err == nil { 182 t.Fatal("expected to get an error but non was returned") 183 } 184 return 185 } 186 if err != nil { 187 t.Fatal(err) 188 } 189 if !reflect.DeepEqual(test.expectedObject, actualObject) { 190 t.Fatalf("unexpected object has been returned expected = %v actual = %v, diff = %v", test.expectedObject, actualObject, cmp.Diff(test.expectedObject, actualObject)) 191 } 192 }) 193 } 194 } 195 196 func TestListerListMethod(t *testing.T) { 197 // test data 198 objs := []runtime.Object{ 199 newPartialObjectMetadata("group/version", "TheKind", "ns-foo", "name-foo"), 200 newPartialObjectMetadata("group/version", "TheKind", "ns-foo", "name-bar"), 201 } 202 indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{}) 203 for _, obj := range objs { 204 err := indexer.Add(obj) 205 if err != nil { 206 t.Fatal(err) 207 } 208 } 209 expectedOutput := []*metav1.PartialObjectMetadata{ 210 newPartialObjectMetadata("group/version", "TheKind", "ns-foo", "name-foo"), 211 newPartialObjectMetadata("group/version", "TheKind", "ns-foo", "name-bar"), 212 } 213 214 // act 215 target := New(indexer, schema.GroupVersionResource{Group: "group", Version: "version", Resource: "TheKinds"}) 216 actualOutput, err := target.List(labels.Everything()) 217 218 // validate 219 if err != nil { 220 t.Fatal(err) 221 } 222 assertListOrDie(expectedOutput, actualOutput, t) 223 } 224 225 func assertListOrDie(expected, actual []*metav1.PartialObjectMetadata, t *testing.T) { 226 if len(actual) != len(expected) { 227 t.Fatalf("unexpected number of items returned, expected = %d, actual = %d", len(expected), len(actual)) 228 } 229 for _, expectedObject := range expected { 230 found := false 231 for _, actualObject := range actual { 232 if actualObject.GetName() == expectedObject.GetName() { 233 if !reflect.DeepEqual(expectedObject, actualObject) { 234 t.Fatalf("unexpected object has been returned expected = %v actual = %v, diff = %v", expectedObject, actualObject, cmp.Diff(expectedObject, actualObject)) 235 } 236 found = true 237 } 238 } 239 if !found { 240 t.Fatalf("the resource with the name = %s was not found in the returned output", expectedObject.GetName()) 241 } 242 } 243 } 244 245 func newPartialObjectMetadata(apiVersion, kind, namespace, name string) *metav1.PartialObjectMetadata { 246 return &metav1.PartialObjectMetadata{ 247 TypeMeta: metav1.TypeMeta{ 248 APIVersion: apiVersion, 249 Kind: kind, 250 }, 251 ObjectMeta: metav1.ObjectMeta{ 252 Namespace: namespace, 253 Name: name, 254 }, 255 } 256 }