...

Source file src/k8s.io/kubernetes/pkg/controller/endpointslicemirroring/utils_test.go

Documentation: k8s.io/kubernetes/pkg/controller/endpointslicemirroring

     1  /*
     2  Copyright 2020 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 endpointslicemirroring
    18  
    19  import (
    20  	"fmt"
    21  	"testing"
    22  
    23  	"github.com/stretchr/testify/assert"
    24  	v1 "k8s.io/api/core/v1"
    25  	discovery "k8s.io/api/discovery/v1"
    26  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    27  	"k8s.io/apimachinery/pkg/runtime"
    28  	"k8s.io/apimachinery/pkg/runtime/schema"
    29  	"k8s.io/apimachinery/pkg/util/rand"
    30  	"k8s.io/client-go/kubernetes/fake"
    31  	k8stesting "k8s.io/client-go/testing"
    32  	"k8s.io/utils/pointer"
    33  )
    34  
    35  func TestNewEndpointSlice(t *testing.T) {
    36  	portName := "foo"
    37  	protocol := v1.ProtocolTCP
    38  
    39  	ports := []discovery.EndpointPort{{Name: &portName, Protocol: &protocol}}
    40  	addrType := discovery.AddressTypeIPv4
    41  	gvk := schema.GroupVersionKind{Version: "v1", Kind: "Endpoints"}
    42  
    43  	endpoints := v1.Endpoints{
    44  		ObjectMeta: metav1.ObjectMeta{
    45  			Name:      "foo",
    46  			Namespace: "test",
    47  		},
    48  		Subsets: []v1.EndpointSubset{{
    49  			Ports: []v1.EndpointPort{{Port: 80}},
    50  		}},
    51  	}
    52  	ownerRef := metav1.NewControllerRef(&endpoints, gvk)
    53  
    54  	testCases := []struct {
    55  		name          string
    56  		tweakEndpoint func(ep *v1.Endpoints)
    57  		expectedSlice discovery.EndpointSlice
    58  	}{
    59  		{
    60  			name: "create slice from endpoints",
    61  			tweakEndpoint: func(ep *v1.Endpoints) {
    62  			},
    63  			expectedSlice: discovery.EndpointSlice{
    64  				ObjectMeta: metav1.ObjectMeta{
    65  					Labels: map[string]string{
    66  						discovery.LabelServiceName: endpoints.Name,
    67  						discovery.LabelManagedBy:   controllerName,
    68  					},
    69  					Annotations:     map[string]string{},
    70  					GenerateName:    fmt.Sprintf("%s-", endpoints.Name),
    71  					Namespace:       endpoints.Namespace,
    72  					OwnerReferences: []metav1.OwnerReference{*ownerRef},
    73  				},
    74  				Ports:       ports,
    75  				AddressType: addrType,
    76  				Endpoints:   []discovery.Endpoint{},
    77  			},
    78  		},
    79  		{
    80  			name: "create slice from endpoints with annotations",
    81  			tweakEndpoint: func(ep *v1.Endpoints) {
    82  				annotations := map[string]string{"foo": "bar"}
    83  				ep.Annotations = annotations
    84  			},
    85  			expectedSlice: discovery.EndpointSlice{
    86  				ObjectMeta: metav1.ObjectMeta{
    87  					Labels: map[string]string{
    88  						discovery.LabelServiceName: endpoints.Name,
    89  						discovery.LabelManagedBy:   controllerName,
    90  					},
    91  					Annotations:     map[string]string{"foo": "bar"},
    92  					GenerateName:    fmt.Sprintf("%s-", endpoints.Name),
    93  					Namespace:       endpoints.Namespace,
    94  					OwnerReferences: []metav1.OwnerReference{*ownerRef},
    95  				},
    96  				Ports:       ports,
    97  				AddressType: addrType,
    98  				Endpoints:   []discovery.Endpoint{},
    99  			},
   100  		},
   101  		{
   102  			name: "create slice from endpoints with labels",
   103  			tweakEndpoint: func(ep *v1.Endpoints) {
   104  				labels := map[string]string{"foo": "bar"}
   105  				ep.Labels = labels
   106  			},
   107  			expectedSlice: discovery.EndpointSlice{
   108  				ObjectMeta: metav1.ObjectMeta{
   109  					Labels: map[string]string{
   110  						"foo":                      "bar",
   111  						discovery.LabelServiceName: endpoints.Name,
   112  						discovery.LabelManagedBy:   controllerName,
   113  					},
   114  					Annotations:     map[string]string{},
   115  					GenerateName:    fmt.Sprintf("%s-", endpoints.Name),
   116  					Namespace:       endpoints.Namespace,
   117  					OwnerReferences: []metav1.OwnerReference{*ownerRef},
   118  				},
   119  				Ports:       ports,
   120  				AddressType: addrType,
   121  				Endpoints:   []discovery.Endpoint{},
   122  			},
   123  		},
   124  		{
   125  			name: "create slice from endpoints with labels and annotations",
   126  			tweakEndpoint: func(ep *v1.Endpoints) {
   127  				labels := map[string]string{"foo": "bar"}
   128  				ep.Labels = labels
   129  				annotations := map[string]string{"foo2": "bar2"}
   130  				ep.Annotations = annotations
   131  			},
   132  			expectedSlice: discovery.EndpointSlice{
   133  				ObjectMeta: metav1.ObjectMeta{
   134  					Labels: map[string]string{
   135  						"foo":                      "bar",
   136  						discovery.LabelServiceName: endpoints.Name,
   137  						discovery.LabelManagedBy:   controllerName,
   138  					},
   139  					Annotations:     map[string]string{"foo2": "bar2"},
   140  					GenerateName:    fmt.Sprintf("%s-", endpoints.Name),
   141  					Namespace:       endpoints.Namespace,
   142  					OwnerReferences: []metav1.OwnerReference{*ownerRef},
   143  				},
   144  				Ports:       ports,
   145  				AddressType: addrType,
   146  				Endpoints:   []discovery.Endpoint{},
   147  			},
   148  		},
   149  		{
   150  			name: "create slice from endpoints with labels and annotations triggertime",
   151  			tweakEndpoint: func(ep *v1.Endpoints) {
   152  				labels := map[string]string{"foo": "bar"}
   153  				ep.Labels = labels
   154  				annotations := map[string]string{
   155  					"foo2":                            "bar2",
   156  					v1.EndpointsLastChangeTriggerTime: "date",
   157  				}
   158  				ep.Annotations = annotations
   159  			},
   160  			expectedSlice: discovery.EndpointSlice{
   161  				ObjectMeta: metav1.ObjectMeta{
   162  					Labels: map[string]string{
   163  						"foo":                      "bar",
   164  						discovery.LabelServiceName: endpoints.Name,
   165  						discovery.LabelManagedBy:   controllerName,
   166  					},
   167  					Annotations:     map[string]string{"foo2": "bar2"},
   168  					GenerateName:    fmt.Sprintf("%s-", endpoints.Name),
   169  					Namespace:       endpoints.Namespace,
   170  					OwnerReferences: []metav1.OwnerReference{*ownerRef},
   171  				},
   172  				Ports:       ports,
   173  				AddressType: addrType,
   174  				Endpoints:   []discovery.Endpoint{},
   175  			},
   176  		},
   177  	}
   178  	for _, tc := range testCases {
   179  		t.Run(tc.name, func(t *testing.T) {
   180  			ep := endpoints.DeepCopy()
   181  			tc.tweakEndpoint(ep)
   182  			generatedSlice := newEndpointSlice(ep, ports, addrType, "")
   183  			assert.EqualValues(t, tc.expectedSlice, *generatedSlice)
   184  			if len(endpoints.Labels) > 1 {
   185  				t.Errorf("Expected Endpoints labels to not be modified, got %+v", endpoints.Labels)
   186  			}
   187  		})
   188  	}
   189  }
   190  
   191  func TestAddressToEndpoint(t *testing.T) {
   192  	//name: "simple + gate enabled",
   193  	epAddress := v1.EndpointAddress{
   194  		IP:       "10.1.2.3",
   195  		Hostname: "foo",
   196  		NodeName: pointer.String("node-abc"),
   197  		TargetRef: &v1.ObjectReference{
   198  			APIVersion: "v1",
   199  			Kind:       "Pod",
   200  			Namespace:  "default",
   201  			Name:       "foo",
   202  		},
   203  	}
   204  	ready := true
   205  	expectedEndpoint := discovery.Endpoint{
   206  		Addresses: []string{"10.1.2.3"},
   207  		Hostname:  pointer.String("foo"),
   208  		Conditions: discovery.EndpointConditions{
   209  			Ready: pointer.BoolPtr(true),
   210  		},
   211  		TargetRef: &v1.ObjectReference{
   212  			APIVersion: "v1",
   213  			Kind:       "Pod",
   214  			Namespace:  "default",
   215  			Name:       "foo",
   216  		},
   217  		NodeName: pointer.String("node-abc"),
   218  	}
   219  
   220  	ep := addressToEndpoint(epAddress, ready)
   221  	assert.EqualValues(t, expectedEndpoint, *ep)
   222  }
   223  
   224  // Test helpers
   225  
   226  func newClientset() *fake.Clientset {
   227  	client := fake.NewSimpleClientset()
   228  
   229  	client.PrependReactor("create", "endpointslices", k8stesting.ReactionFunc(func(action k8stesting.Action) (bool, runtime.Object, error) {
   230  		endpointSlice := action.(k8stesting.CreateAction).GetObject().(*discovery.EndpointSlice)
   231  
   232  		if endpointSlice.ObjectMeta.GenerateName != "" {
   233  			endpointSlice.ObjectMeta.Name = fmt.Sprintf("%s-%s", endpointSlice.ObjectMeta.GenerateName, rand.String(8))
   234  			endpointSlice.ObjectMeta.GenerateName = ""
   235  		}
   236  		endpointSlice.ObjectMeta.Generation = 1
   237  
   238  		return false, endpointSlice, nil
   239  	}))
   240  	client.PrependReactor("update", "endpointslices", k8stesting.ReactionFunc(func(action k8stesting.Action) (bool, runtime.Object, error) {
   241  		endpointSlice := action.(k8stesting.CreateAction).GetObject().(*discovery.EndpointSlice)
   242  		endpointSlice.ObjectMeta.Generation++
   243  		return false, endpointSlice, nil
   244  	}))
   245  
   246  	return client
   247  }
   248  

View as plain text