...
1
16
17 package patchnode
18
19 import (
20 "bytes"
21 "encoding/json"
22 "net/http"
23 "net/http/httptest"
24 "testing"
25
26 v1 "k8s.io/api/core/v1"
27 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28 clientset "k8s.io/client-go/kubernetes"
29 restclient "k8s.io/client-go/rest"
30
31 kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
32 )
33
34 func TestAnnotateCRISocket(t *testing.T) {
35 tests := []struct {
36 name string
37 currentCRISocketAnnotation string
38 newCRISocketAnnotation string
39 expectedPatch string
40 }{
41 {
42 name: "CRI-socket annotation missing",
43 currentCRISocketAnnotation: "",
44 newCRISocketAnnotation: "unix:///run/containerd/containerd.sock",
45 expectedPatch: `{"metadata":{"annotations":{"kubeadm.alpha.kubernetes.io/cri-socket":"unix:///run/containerd/containerd.sock"}}}`,
46 },
47 {
48 name: "CRI-socket annotation already exists",
49 currentCRISocketAnnotation: "unix:///run/containerd/containerd.sock",
50 newCRISocketAnnotation: "unix:///run/containerd/containerd.sock",
51 expectedPatch: `{}`,
52 },
53 {
54 name: "CRI-socket annotation needs to be updated",
55 currentCRISocketAnnotation: "unix:///foo/bar",
56 newCRISocketAnnotation: "unix:///run/containerd/containerd.sock",
57 expectedPatch: `{"metadata":{"annotations":{"kubeadm.alpha.kubernetes.io/cri-socket":"unix:///run/containerd/containerd.sock"}}}`,
58 },
59 }
60
61 for _, tc := range tests {
62 t.Run(tc.name, func(t *testing.T) {
63
64 nodename := "node01"
65 node := &v1.Node{
66 ObjectMeta: metav1.ObjectMeta{
67 Name: nodename,
68 Labels: map[string]string{
69 v1.LabelHostname: nodename,
70 },
71 Annotations: map[string]string{},
72 },
73 }
74
75 if tc.currentCRISocketAnnotation != "" {
76 node.ObjectMeta.Annotations[kubeadmconstants.AnnotationKubeadmCRISocket] = tc.currentCRISocketAnnotation
77 }
78
79 jsonNode, err := json.Marshal(node)
80 if err != nil {
81 t.Fatalf("unexpected encoding error: %v", err)
82 }
83
84 var patchRequest string
85 s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
86 w.Header().Set("Content-Type", "application/json")
87
88 if req.URL.Path != "/api/v1/nodes/"+nodename {
89 t.Errorf("request for unexpected HTTP resource: %v", req.URL.Path)
90 http.Error(w, "", http.StatusNotFound)
91 return
92 }
93
94 switch req.Method {
95 case "GET":
96 case "PATCH":
97 buf := new(bytes.Buffer)
98 buf.ReadFrom(req.Body)
99 patchRequest = buf.String()
100 default:
101 t.Errorf("request for unexpected HTTP verb: %v", req.Method)
102 http.Error(w, "", http.StatusNotFound)
103 return
104 }
105
106 w.WriteHeader(http.StatusOK)
107 w.Write(jsonNode)
108 }))
109 defer s.Close()
110
111 cs, err := clientset.NewForConfig(&restclient.Config{Host: s.URL})
112 if err != nil {
113 t.Fatalf("unexpected error building clientset: %v", err)
114 }
115
116 if err := AnnotateCRISocket(cs, nodename, tc.newCRISocketAnnotation); err != nil {
117 t.Errorf("unexpected error: %v", err)
118 }
119
120 if tc.expectedPatch != patchRequest {
121 t.Errorf("expected patch %v, got %v", tc.expectedPatch, patchRequest)
122 }
123 })
124 }
125 }
126
View as plain text