k8s.io/kubernetes@v1.29.3/pkg/kubelet/pod/mirror_client_test.go (about)

     1  /*
     2  Copyright 2015 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 pod
    18  
    19  import (
    20  	"context"
    21  	"errors"
    22  	"testing"
    23  
    24  	"github.com/stretchr/testify/assert"
    25  	"github.com/stretchr/testify/require"
    26  	v1 "k8s.io/api/core/v1"
    27  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    28  	"k8s.io/apimachinery/pkg/types"
    29  	"k8s.io/client-go/kubernetes/fake"
    30  	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
    31  	kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
    32  	"k8s.io/utils/pointer"
    33  )
    34  
    35  func TestParsePodFullName(t *testing.T) {
    36  	type nameTuple struct {
    37  		Name      string
    38  		Namespace string
    39  	}
    40  	successfulCases := map[string]nameTuple{
    41  		"bar_foo":         {Name: "bar", Namespace: "foo"},
    42  		"bar.org_foo.com": {Name: "bar.org", Namespace: "foo.com"},
    43  		"bar-bar_foo":     {Name: "bar-bar", Namespace: "foo"},
    44  	}
    45  	failedCases := []string{"barfoo", "bar_foo_foo", "", "bar_", "_foo"}
    46  
    47  	for podFullName, expected := range successfulCases {
    48  		name, namespace, err := kubecontainer.ParsePodFullName(podFullName)
    49  		if err != nil {
    50  			t.Errorf("unexpected error when parsing the full name: %v", err)
    51  			continue
    52  		}
    53  		if name != expected.Name || namespace != expected.Namespace {
    54  			t.Errorf("expected name %q, namespace %q; got name %q, namespace %q",
    55  				expected.Name, expected.Namespace, name, namespace)
    56  		}
    57  	}
    58  	for _, podFullName := range failedCases {
    59  		_, _, err := kubecontainer.ParsePodFullName(podFullName)
    60  		if err == nil {
    61  			t.Errorf("expected error when parsing the full name, got none")
    62  		}
    63  	}
    64  }
    65  
    66  func TestCreateMirrorPod(t *testing.T) {
    67  	const (
    68  		testNodeName = "test-node-name"
    69  		testNodeUID  = types.UID("test-node-uid-1234")
    70  		testPodName  = "test-pod-name"
    71  		testPodNS    = "test-pod-ns"
    72  		testPodHash  = "123456789"
    73  	)
    74  	testcases := []struct {
    75  		desc          string
    76  		node          *v1.Node
    77  		nodeErr       error
    78  		expectSuccess bool
    79  	}{{
    80  		desc:          "cannot get node",
    81  		nodeErr:       errors.New("expected: cannot get node"),
    82  		expectSuccess: false,
    83  	}, {
    84  		desc: "node missing UID",
    85  		node: &v1.Node{
    86  			ObjectMeta: metav1.ObjectMeta{
    87  				Name: testNodeName,
    88  			},
    89  		},
    90  		expectSuccess: false,
    91  	}, {
    92  		desc: "successfully fetched node",
    93  		node: &v1.Node{
    94  			ObjectMeta: metav1.ObjectMeta{
    95  				Name: testNodeName,
    96  				UID:  testNodeUID,
    97  			},
    98  		},
    99  		expectSuccess: true,
   100  	}}
   101  
   102  	for _, test := range testcases {
   103  		t.Run(test.desc, func(t *testing.T) {
   104  			clientset := fake.NewSimpleClientset()
   105  			nodeGetter := &fakeNodeGetter{
   106  				t:              t,
   107  				expectNodeName: testNodeName,
   108  				node:           test.node,
   109  				err:            test.nodeErr,
   110  			}
   111  			mc := NewBasicMirrorClient(clientset, testNodeName, nodeGetter)
   112  
   113  			pod := &v1.Pod{
   114  				ObjectMeta: metav1.ObjectMeta{
   115  					Name:      testPodName,
   116  					Namespace: testPodNS,
   117  					Annotations: map[string]string{
   118  						kubetypes.ConfigHashAnnotationKey: testPodHash,
   119  					},
   120  				},
   121  			}
   122  
   123  			err := mc.CreateMirrorPod(pod)
   124  			if !test.expectSuccess {
   125  				assert.Error(t, err)
   126  				return
   127  			}
   128  
   129  			createdPod, err := clientset.CoreV1().Pods(testPodNS).Get(context.TODO(), testPodName, metav1.GetOptions{})
   130  			require.NoError(t, err)
   131  
   132  			// Validate created pod
   133  			assert.Equal(t, testPodHash, createdPod.Annotations[kubetypes.ConfigMirrorAnnotationKey])
   134  			assert.Len(t, createdPod.OwnerReferences, 1)
   135  			expectedOwnerRef := metav1.OwnerReference{
   136  				APIVersion: "v1",
   137  				Kind:       "Node",
   138  				Name:       testNodeName,
   139  				UID:        testNodeUID,
   140  				Controller: pointer.Bool(true),
   141  			}
   142  			assert.Equal(t, expectedOwnerRef, createdPod.OwnerReferences[0])
   143  		})
   144  	}
   145  }
   146  
   147  type fakeNodeGetter struct {
   148  	t              *testing.T
   149  	expectNodeName string
   150  
   151  	node *v1.Node
   152  	err  error
   153  }
   154  
   155  func (f *fakeNodeGetter) Get(nodeName string) (*v1.Node, error) {
   156  	require.Equal(f.t, f.expectNodeName, nodeName)
   157  	return f.node, f.err
   158  }