github.com/Azure/aad-pod-identity@v1.8.17/pkg/k8s/client_test.go (about) 1 package k8s 2 3 import ( 4 "bytes" 5 "context" 6 "encoding/json" 7 "fmt" 8 "io" 9 "net/http" 10 "strings" 11 "sync" 12 "testing" 13 14 v1 "k8s.io/api/core/v1" 15 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 16 "k8s.io/apimachinery/pkg/runtime" 17 "k8s.io/apimachinery/pkg/runtime/schema" 18 "k8s.io/apimachinery/pkg/runtime/serializer" 19 "k8s.io/client-go/kubernetes" 20 "k8s.io/client-go/kubernetes/fake" 21 fakerest "k8s.io/client-go/rest/fake" 22 ) 23 24 func TestGetSecret(t *testing.T) { 25 secretName := "clientSecret" 26 27 fakeClient := fake.NewSimpleClientset() 28 29 secret := &v1.Secret{ObjectMeta: metav1.ObjectMeta{Name: secretName}} 30 _, err := fakeClient.CoreV1().Secrets("default").Create(context.TODO(), secret, metav1.CreateOptions{}) 31 if err != nil { 32 t.Fatalf("Error creating secret: %v", err) 33 } 34 35 kubeClient := &KubeClient{ClientSet: fakeClient} 36 37 secretRef := &v1.SecretReference{ 38 Name: secretName, 39 Namespace: "default", 40 } 41 retrievedSecret, err := kubeClient.GetSecret(secretRef) 42 if err != nil { 43 t.Fatalf("Error getting secret: %v", err) 44 } 45 if retrievedSecret.ObjectMeta.Name != secretName { 46 t.Fatalf("Incorrect secret name: %v", retrievedSecret.ObjectMeta.Name) 47 } 48 } 49 50 type TestClientSet struct { 51 mu *sync.Mutex 52 podList []v1.Pod 53 } 54 55 func (t *TestClientSet) GetTestClientSet() (kubernetes.Interface, *fakerest.RESTClient) { 56 TestGroupVersion := schema.GroupVersion{Group: "", Version: "v1"} 57 fakeClient := fake.NewSimpleClientset() 58 59 scheme := runtime.NewScheme() 60 scheme.AddKnownTypes(TestGroupVersion, &v1.PodList{}) 61 62 fakeRestClient := &fakerest.RESTClient{ 63 NegotiatedSerializer: serializer.WithoutConversionCodecFactory{ 64 CodecFactory: serializer.NewCodecFactory(scheme)}, 65 Resp: &http.Response{ 66 StatusCode: http.StatusOK, 67 Body: t.SerializeObject(&metav1.APIVersions{Versions: []string{"version1"}}), 68 }, 69 Client: fakerest.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { 70 header := http.Header{} 71 header.Set("Content-Type", runtime.ContentTypeJSON) 72 return &http.Response{StatusCode: http.StatusOK, Header: header, Body: t.GetPodList()}, nil 73 }), 74 } 75 return fakeClient, fakeRestClient 76 } 77 78 func (t *TestClientSet) AddPod(name, ns, ip string) { 79 t.mu.Lock() 80 defer t.mu.Unlock() 81 82 pod := &v1.Pod{ 83 TypeMeta: metav1.TypeMeta{ 84 Kind: "Pod", 85 APIVersion: "v1", 86 }, 87 ObjectMeta: metav1.ObjectMeta{ 88 Name: name, 89 Namespace: ns, 90 }, 91 Status: v1.PodStatus{ 92 PodIP: ip, 93 }, 94 } 95 t.podList = append(t.podList, *pod) 96 } 97 98 func (t *TestClientSet) DeletePod(name, ns string) { 99 for i, p := range t.podList { 100 if strings.EqualFold(name, p.Name) && strings.EqualFold(ns, p.Namespace) { 101 t.podList = append(t.podList[:i], t.podList[i+1:]...) 102 break 103 } 104 } 105 } 106 107 func (t *TestClientSet) SerializeObject(o interface{}) io.ReadCloser { 108 output, err := json.MarshalIndent(o, "", "") 109 if err != nil { 110 panic(err) 111 } 112 return io.NopCloser(bytes.NewReader([]byte(output))) 113 } 114 115 func (t *TestClientSet) GetPodList() io.ReadCloser { 116 t.mu.Lock() 117 defer t.mu.Unlock() 118 119 podList := &v1.PodList{} 120 podList.Items = append(podList.Items, t.podList...) 121 podList.TypeMeta = metav1.TypeMeta{ 122 Kind: "PodList", 123 APIVersion: "v1", 124 } 125 126 return t.SerializeObject(podList) 127 } 128 129 /* 130 func TestGetPodInfo(t *testing.T) { 131 132 testClientSet := &TestClientSet{mu: &sync.Mutex{}} 133 client, restClient := testClientSet.GetTestClientSet() 134 135 optionsModifier := func(options *metav1.ListOptions) {} 136 podListWatch := cache.NewFilteredListWatchFromClient( 137 restClient, 138 "pods", 139 v1.NamespaceAll, 140 optionsModifier, 141 ) 142 kubeClient := &KubeClient{ClientSet: client, PodListWatch: podListWatch} 143 144 // Test a single pod 145 testPodName := "testpodname" 146 testPodNs := "default" 147 testPodIP := "10.0.0.8" 148 testClientSet.AddPod(testPodName, testPodNs, testPodIP) 149 podNs, podName, _, _, err := kubeClient.GetPodInfo(testPodIP) 150 if err != nil { 151 t.Fatalf("Error getting pod: %v", err) 152 } 153 if podName != testPodName { 154 t.Fatalf("Incorrect pod name: %v", podName) 155 } 156 if podNs != testPodNs { 157 t.Fatalf("Incorrect pod ns: %v", podNs) 158 } 159 160 // Delete test 161 testPodIP = "10.0.0.8" 162 testClientSet.DeletePod(testPodName, testPodNs) 163 podNs, podName, _, _, err = kubeClient.GetPodInfo(testPodIP) 164 if err == nil { 165 t.Fatal("Pod still in pod list") 166 } 167 } 168 169 func TestPodListRetries(t *testing.T) { 170 // this test is to solely test the retry and sleep logic works as expected 171 podIP := "10.0.0.8" 172 testClientSet := &TestClientSet{mu: &sync.Mutex{}} 173 client, restClient := testClientSet.GetTestClientSet() 174 175 testPodName := "testpodname" 176 testPodNs := "default" 177 testPodIP := "10.0.0.8" 178 179 optionsModifier := func(options *metav1.ListOptions) {} 180 podListWatch := cache.NewFilteredListWatchFromClient( 181 restClient, 182 "pods", 183 v1.NamespaceAll, 184 optionsModifier, 185 ) 186 187 kubeClient := &KubeClient{ClientSet: client, PodListWatch: podListWatch} 188 189 time.AfterFunc(time.Duration(1200*time.Millisecond), func() { 190 testClientSet.AddPod(testPodName, testPodNs, testPodIP) 191 }) 192 193 start := time.Now() 194 podNs, podName, _, _, err := kubeClient.GetPodInfo(podIP) 195 elapsed := time.Since(start) 196 197 if err != nil { 198 t.Fatalf("Error getting pod: %v", err) 199 } 200 if podName != testPodName { 201 t.Fatalf("Incorrect pod name: %v", podName) 202 } 203 if podNs != testPodNs { 204 t.Fatalf("Incorrect pod ns: %v", podNs) 205 } 206 // check the retries actually work as the pod object is created only after 1.2s 207 if elapsed < 1200*time.Millisecond { 208 t.Fatalf("Retry logic not working as expected. Elapsed time: %v", elapsed) 209 } 210 } 211 */ 212 func TestGetReplicaSet(t *testing.T) { 213 pod := &v1.Pod{} 214 rsIndex := 1 215 for i := 0; i < 3; i++ { 216 owner := metav1.OwnerReference{} 217 owner.Name = "test" + fmt.Sprintf("%d", i) 218 if i == rsIndex { 219 owner.Kind = "ReplicaSet" 220 } else { 221 owner.Kind = "Kind" + fmt.Sprintf("%d", i) 222 } 223 pod.OwnerReferences = append(pod.OwnerReferences, owner) 224 } 225 226 c := &KubeClient{} 227 rsName := c.getReplicasetName(*pod) 228 if rsName != "test1" { 229 t.Fatalf("Expected rsName: test1. Got: %s", rsName) 230 } 231 }