...

Source file src/k8s.io/client-go/dynamic/dynamiclister/lister_test.go

Documentation: k8s.io/client-go/dynamic/dynamiclister

     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 dynamiclister_test
    18  
    19  import (
    20  	"reflect"
    21  	"testing"
    22  
    23  	"github.com/google/go-cmp/cmp"
    24  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    25  	"k8s.io/apimachinery/pkg/labels"
    26  	"k8s.io/apimachinery/pkg/runtime"
    27  	"k8s.io/apimachinery/pkg/runtime/schema"
    28  	"k8s.io/client-go/dynamic/dynamiclister"
    29  	"k8s.io/client-go/tools/cache"
    30  )
    31  
    32  func TestNamespaceGetMethod(t *testing.T) {
    33  	tests := []struct {
    34  		name            string
    35  		existingObjects []runtime.Object
    36  		namespaceToSync string
    37  		gvrToSync       schema.GroupVersionResource
    38  		objectToGet     string
    39  		expectedObject  *unstructured.Unstructured
    40  		expectError     bool
    41  	}{
    42  		{
    43  			name: "scenario 1: gets name-foo1 resource from the indexer from ns-foo namespace",
    44  			existingObjects: []runtime.Object{
    45  				newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"),
    46  				newUnstructured("group/version", "TheKind", "ns-foo", "name-foo1"),
    47  				newUnstructured("group/version", "TheKind", "ns-bar", "name-bar"),
    48  			},
    49  			namespaceToSync: "ns-foo",
    50  			gvrToSync:       schema.GroupVersionResource{Group: "group", Version: "version", Resource: "TheKinds"},
    51  			objectToGet:     "name-foo1",
    52  			expectedObject:  newUnstructured("group/version", "TheKind", "ns-foo", "name-foo1"),
    53  		},
    54  		{
    55  			name: "scenario 2: gets name-foo-non-existing resource from the indexer from ns-foo namespace",
    56  			existingObjects: []runtime.Object{
    57  				newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"),
    58  				newUnstructured("group/version", "TheKind", "ns-foo", "name-foo1"),
    59  				newUnstructured("group/version", "TheKind", "ns-bar", "name-bar"),
    60  			},
    61  			namespaceToSync: "ns-foo",
    62  			gvrToSync:       schema.GroupVersionResource{Group: "group", Version: "version", Resource: "TheKinds"},
    63  			objectToGet:     "name-foo-non-existing",
    64  			expectError:     true,
    65  		},
    66  	}
    67  
    68  	for _, test := range tests {
    69  		t.Run(test.name, func(t *testing.T) {
    70  			// test data
    71  			indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{})
    72  			for _, obj := range test.existingObjects {
    73  				err := indexer.Add(obj)
    74  				if err != nil {
    75  					t.Fatal(err)
    76  				}
    77  			}
    78  			// act
    79  			target := dynamiclister.New(indexer, test.gvrToSync).Namespace(test.namespaceToSync)
    80  			actualObject, err := target.Get(test.objectToGet)
    81  
    82  			// validate
    83  			if test.expectError {
    84  				if err == nil {
    85  					t.Fatal("expected to get an error but non was returned")
    86  				}
    87  				return
    88  			}
    89  			if err != nil {
    90  				t.Fatal(err)
    91  			}
    92  			if !reflect.DeepEqual(test.expectedObject, actualObject) {
    93  				t.Fatalf("unexpected object has been returned expected = %v actual = %v, diff = %v", test.expectedObject, actualObject, cmp.Diff(test.expectedObject, actualObject))
    94  			}
    95  		})
    96  	}
    97  }
    98  
    99  func TestNamespaceListMethod(t *testing.T) {
   100  	// test data
   101  	objs := []runtime.Object{
   102  		newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"),
   103  		newUnstructured("group/version", "TheKind", "ns-foo", "name-foo1"),
   104  		newUnstructured("group/version", "TheKind", "ns-bar", "name-bar"),
   105  	}
   106  	indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{})
   107  	for _, obj := range objs {
   108  		err := indexer.Add(obj)
   109  		if err != nil {
   110  			t.Fatal(err)
   111  		}
   112  	}
   113  	expectedOutput := []*unstructured.Unstructured{
   114  		newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"),
   115  		newUnstructured("group/version", "TheKind", "ns-foo", "name-foo1"),
   116  	}
   117  	namespaceToList := "ns-foo"
   118  
   119  	// act
   120  	target := dynamiclister.New(indexer, schema.GroupVersionResource{Group: "group", Version: "version", Resource: "TheKinds"}).Namespace(namespaceToList)
   121  	actualOutput, err := target.List(labels.Everything())
   122  
   123  	// validate
   124  	if err != nil {
   125  		t.Fatal(err)
   126  	}
   127  	assertListOrDie(expectedOutput, actualOutput, t)
   128  }
   129  
   130  func TestListerGetMethod(t *testing.T) {
   131  	tests := []struct {
   132  		name            string
   133  		existingObjects []runtime.Object
   134  		namespaceToSync string
   135  		gvrToSync       schema.GroupVersionResource
   136  		objectToGet     string
   137  		expectedObject  *unstructured.Unstructured
   138  		expectError     bool
   139  	}{
   140  		{
   141  			name: "scenario 1: gets name-foo1 resource from the indexer",
   142  			existingObjects: []runtime.Object{
   143  				newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"),
   144  				newUnstructured("group/version", "TheKind", "", "name-foo1"),
   145  				newUnstructured("group/version", "TheKind", "ns-bar", "name-bar"),
   146  			},
   147  			namespaceToSync: "",
   148  			gvrToSync:       schema.GroupVersionResource{Group: "group", Version: "version", Resource: "TheKinds"},
   149  			objectToGet:     "name-foo1",
   150  			expectedObject:  newUnstructured("group/version", "TheKind", "", "name-foo1"),
   151  		},
   152  		{
   153  			name: "scenario 2: doesn't get name-foo resource from the indexer from ns-foo namespace",
   154  			existingObjects: []runtime.Object{
   155  				newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"),
   156  				newUnstructured("group/version", "TheKind", "ns-foo", "name-foo1"),
   157  				newUnstructured("group/version", "TheKind", "ns-bar", "name-bar"),
   158  			},
   159  			namespaceToSync: "ns-foo",
   160  			gvrToSync:       schema.GroupVersionResource{Group: "group", Version: "version", Resource: "TheKinds"},
   161  			objectToGet:     "name-foo",
   162  			expectError:     true,
   163  		},
   164  	}
   165  
   166  	for _, test := range tests {
   167  		t.Run(test.name, func(t *testing.T) {
   168  			// test data
   169  			indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{})
   170  			for _, obj := range test.existingObjects {
   171  				err := indexer.Add(obj)
   172  				if err != nil {
   173  					t.Fatal(err)
   174  				}
   175  			}
   176  			// act
   177  			target := dynamiclister.New(indexer, test.gvrToSync)
   178  			actualObject, err := target.Get(test.objectToGet)
   179  
   180  			// validate
   181  			if test.expectError {
   182  				if err == nil {
   183  					t.Fatal("expected to get an error but non was returned")
   184  				}
   185  				return
   186  			}
   187  			if err != nil {
   188  				t.Fatal(err)
   189  			}
   190  			if !reflect.DeepEqual(test.expectedObject, actualObject) {
   191  				t.Fatalf("unexpected object has been returned expected = %v actual = %v, diff = %v", test.expectedObject, actualObject, cmp.Diff(test.expectedObject, actualObject))
   192  			}
   193  		})
   194  	}
   195  }
   196  
   197  func TestListerListMethod(t *testing.T) {
   198  	// test data
   199  	objs := []runtime.Object{
   200  		newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"),
   201  		newUnstructured("group/version", "TheKind", "ns-foo", "name-bar"),
   202  	}
   203  	indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{})
   204  	for _, obj := range objs {
   205  		err := indexer.Add(obj)
   206  		if err != nil {
   207  			t.Fatal(err)
   208  		}
   209  	}
   210  	expectedOutput := []*unstructured.Unstructured{
   211  		newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"),
   212  		newUnstructured("group/version", "TheKind", "ns-foo", "name-bar"),
   213  	}
   214  
   215  	// act
   216  	target := dynamiclister.New(indexer, schema.GroupVersionResource{Group: "group", Version: "version", Resource: "TheKinds"})
   217  	actualOutput, err := target.List(labels.Everything())
   218  
   219  	// validate
   220  	if err != nil {
   221  		t.Fatal(err)
   222  	}
   223  	assertListOrDie(expectedOutput, actualOutput, t)
   224  }
   225  
   226  func newUnstructured(apiVersion, kind, namespace, name string) *unstructured.Unstructured {
   227  	return &unstructured.Unstructured{
   228  		Object: map[string]interface{}{
   229  			"apiVersion": apiVersion,
   230  			"kind":       kind,
   231  			"metadata": map[string]interface{}{
   232  				"namespace": namespace,
   233  				"name":      name,
   234  			},
   235  		},
   236  	}
   237  }
   238  
   239  func assertListOrDie(expected, actual []*unstructured.Unstructured, t *testing.T) {
   240  	if len(actual) != len(expected) {
   241  		t.Fatalf("unexpected number of items returned, expected = %d, actual = %d", len(expected), len(actual))
   242  	}
   243  	for _, expectedObject := range expected {
   244  		found := false
   245  		for _, actualObject := range actual {
   246  			if actualObject.GetName() == expectedObject.GetName() {
   247  				if !reflect.DeepEqual(expectedObject, actualObject) {
   248  					t.Fatalf("unexpected object has been returned expected = %v actual = %v, diff = %v", expectedObject, actualObject, cmp.Diff(expectedObject, actualObject))
   249  				}
   250  				found = true
   251  			}
   252  		}
   253  		if !found {
   254  			t.Fatalf("the resource with the name = %s was not found in the returned output", expectedObject.GetName())
   255  		}
   256  	}
   257  }
   258  

View as plain text