1
16
17 package pod
18
19 import (
20 "context"
21 "fmt"
22 "testing"
23
24 "reflect"
25
26 "github.com/google/go-cmp/cmp"
27 v1 "k8s.io/api/core/v1"
28 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
29 "k8s.io/apimachinery/pkg/types"
30 "k8s.io/client-go/kubernetes/fake"
31 )
32
33 func TestPatchPodStatus(t *testing.T) {
34 ns := "ns"
35 name := "name"
36 uid := types.UID("myuid")
37 client := &fake.Clientset{}
38 client.CoreV1().Pods(ns).Create(context.TODO(), &v1.Pod{
39 ObjectMeta: metav1.ObjectMeta{
40 Namespace: ns,
41 Name: name,
42 },
43 }, metav1.CreateOptions{})
44
45 testCases := []struct {
46 description string
47 mutate func(input v1.PodStatus) v1.PodStatus
48 expectUnchanged bool
49 expectedPatchBytes []byte
50 }{
51 {
52 "no change",
53 func(input v1.PodStatus) v1.PodStatus { return input },
54 true,
55 []byte(fmt.Sprintf(`{"metadata":{"uid":"myuid"}}`)),
56 },
57 {
58 "message change",
59 func(input v1.PodStatus) v1.PodStatus {
60 input.Message = "random message"
61 return input
62 },
63 false,
64 []byte(fmt.Sprintf(`{"metadata":{"uid":"myuid"},"status":{"message":"random message"}}`)),
65 },
66 {
67 "pod condition change",
68 func(input v1.PodStatus) v1.PodStatus {
69 input.Conditions[0].Status = v1.ConditionFalse
70 return input
71 },
72 false,
73 []byte(fmt.Sprintf(`{"metadata":{"uid":"myuid"},"status":{"$setElementOrder/conditions":[{"type":"Ready"},{"type":"PodScheduled"}],"conditions":[{"status":"False","type":"Ready"}]}}`)),
74 },
75 {
76 "additional init container condition",
77 func(input v1.PodStatus) v1.PodStatus {
78 input.InitContainerStatuses = []v1.ContainerStatus{
79 {
80 Name: "init-container",
81 Ready: true,
82 },
83 }
84 return input
85 },
86 false,
87 []byte(fmt.Sprintf(`{"metadata":{"uid":"myuid"},"status":{"initContainerStatuses":[{"image":"","imageID":"","lastState":{},"name":"init-container","ready":true,"restartCount":0,"state":{}}]}}`)),
88 },
89 }
90 for _, tc := range testCases {
91 t.Run(tc.description, func(t *testing.T) {
92 _, patchBytes, unchanged, err := PatchPodStatus(context.TODO(), client, ns, name, uid, getPodStatus(), tc.mutate(getPodStatus()))
93 if err != nil {
94 t.Errorf("unexpected error: %v", err)
95 }
96 if unchanged != tc.expectUnchanged {
97 t.Errorf("unexpected change: %t", unchanged)
98 }
99 if !reflect.DeepEqual(patchBytes, tc.expectedPatchBytes) {
100 t.Errorf("expect patchBytes: %q, got: %q\n", tc.expectedPatchBytes, patchBytes)
101 }
102 })
103 }
104 }
105
106 func getPodStatus() v1.PodStatus {
107 return v1.PodStatus{
108 Phase: v1.PodRunning,
109 Conditions: []v1.PodCondition{
110 {
111 Type: v1.PodReady,
112 Status: v1.ConditionTrue,
113 },
114 {
115 Type: v1.PodScheduled,
116 Status: v1.ConditionTrue,
117 },
118 },
119 ContainerStatuses: []v1.ContainerStatus{
120 {
121 Name: "container1",
122 Ready: true,
123 },
124 {
125 Name: "container2",
126 Ready: true,
127 },
128 },
129 Message: "Message",
130 }
131 }
132
133 func TestReplaceOrAppendPodCondition(t *testing.T) {
134 cType := v1.PodConditionType("ExampleType")
135 testCases := []struct {
136 description string
137 conditions []v1.PodCondition
138 condition v1.PodCondition
139 wantConditions []v1.PodCondition
140 }{
141 {
142 description: "append",
143 conditions: []v1.PodCondition{},
144 condition: v1.PodCondition{
145 Type: cType,
146 Status: v1.ConditionTrue,
147 },
148 wantConditions: []v1.PodCondition{
149 {
150 Type: cType,
151 Status: v1.ConditionTrue,
152 },
153 },
154 },
155 {
156 description: "replace",
157 conditions: []v1.PodCondition{
158 {
159 Type: cType,
160 Status: v1.ConditionTrue,
161 },
162 },
163 condition: v1.PodCondition{
164 Type: cType,
165 Status: v1.ConditionFalse,
166 },
167 wantConditions: []v1.PodCondition{
168 {
169 Type: cType,
170 Status: v1.ConditionFalse,
171 },
172 },
173 },
174 }
175 for _, tc := range testCases {
176 t.Run(tc.description, func(t *testing.T) {
177 gotConditions := ReplaceOrAppendPodCondition(tc.conditions, &tc.condition)
178 if diff := cmp.Diff(tc.wantConditions, gotConditions); diff != "" {
179 t.Errorf("Unexpected conditions: %s", diff)
180 }
181 })
182 }
183 }
184
View as plain text