istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pkg/kube/inject/app_probe_test.go (about) 1 // Copyright Istio Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 package inject 15 16 import ( 17 "reflect" 18 "testing" 19 20 corev1 "k8s.io/api/core/v1" 21 "k8s.io/apimachinery/pkg/util/intstr" 22 23 "istio.io/api/annotation" 24 "istio.io/istio/pkg/test" 25 "istio.io/istio/pkg/test/util/assert" 26 ) 27 28 func TestFindSidecar(t *testing.T) { 29 proxy := corev1.Container{Name: "istio-proxy"} 30 app := corev1.Container{Name: "app"} 31 for _, tc := range []struct { 32 name string 33 containers *corev1.Pod 34 want *corev1.Container 35 }{ 36 { 37 name: "only-sidecar", 38 containers: &corev1.Pod{Spec: corev1.PodSpec{Containers: []corev1.Container{proxy}}}, 39 want: &proxy, 40 }, 41 { 42 name: "app-and-sidecar", 43 containers: &corev1.Pod{Spec: corev1.PodSpec{Containers: []corev1.Container{app, proxy}}}, 44 want: &proxy, 45 }, 46 { 47 name: "no-sidecar", 48 containers: &corev1.Pod{Spec: corev1.PodSpec{Containers: []corev1.Container{app}}}, 49 want: nil, 50 }, 51 { 52 name: "init-sidecar", 53 containers: &corev1.Pod{Spec: corev1.PodSpec{InitContainers: []corev1.Container{proxy}, Containers: []corev1.Container{app}}}, 54 want: &proxy, 55 }, 56 } { 57 t.Run(tc.name, func(t *testing.T) { 58 assert.Equal(t, FindSidecar(tc.containers), tc.want) 59 }) 60 } 61 } 62 63 func TestShouldRewriteAppHTTPProbers(t *testing.T) { 64 for _, tc := range []struct { 65 name string 66 specSetting bool 67 annotations map[string]string 68 expected bool 69 }{ 70 { 71 name: "RewriteAppHTTPProbe-set-in-annotations", 72 specSetting: false, 73 annotations: nil, 74 expected: false, 75 }, 76 { 77 name: "RewriteAppHTTPProbe-set-in-annotations", 78 specSetting: true, 79 annotations: nil, 80 expected: true, 81 }, 82 { 83 name: "RewriteAppHTTPProbe-set-in-sidecar-injection-spec", 84 specSetting: false, 85 annotations: map[string]string{}, 86 expected: false, 87 }, 88 { 89 name: "RewriteAppHTTPProbe-set-in-sidecar-injection-spec", 90 specSetting: true, 91 annotations: map[string]string{}, 92 expected: true, 93 }, 94 { 95 name: "RewriteAppHTTPProbe-set-in-annotations", 96 specSetting: false, 97 annotations: map[string]string{annotation.SidecarRewriteAppHTTPProbers.Name: "true"}, 98 expected: true, 99 }, 100 { 101 name: "RewriteAppHTTPProbe-set-in-sidecar-injection-spec-&-annotations", 102 specSetting: true, 103 annotations: map[string]string{annotation.SidecarRewriteAppHTTPProbers.Name: "true"}, 104 expected: true, 105 }, 106 { 107 name: "RewriteAppHTTPProbe-set-in-annotations", 108 specSetting: false, 109 annotations: map[string]string{annotation.SidecarRewriteAppHTTPProbers.Name: "false"}, 110 expected: false, 111 }, 112 { 113 name: "RewriteAppHTTPProbe-set-in-sidecar-injection-spec-&-annotations", 114 specSetting: true, 115 annotations: map[string]string{annotation.SidecarRewriteAppHTTPProbers.Name: "false"}, 116 expected: false, 117 }, 118 } { 119 got := ShouldRewriteAppHTTPProbers(tc.annotations, tc.specSetting) 120 want := tc.expected 121 if got != want { 122 t.Errorf("[%v] failed, want %v, got %v", tc.name, want, got) 123 } 124 } 125 } 126 127 func TestDumpAppGRPCProbers(t *testing.T) { 128 svc := "foo" 129 for _, tc := range []struct { 130 name string 131 pod *corev1.Pod 132 expected string 133 }{ 134 { 135 name: "simple gRPC liveness probe", 136 pod: &corev1.Pod{Spec: corev1.PodSpec{ 137 Containers: []corev1.Container{ 138 { 139 Name: "foo", 140 LivenessProbe: &corev1.Probe{ 141 ProbeHandler: corev1.ProbeHandler{ 142 GRPC: &corev1.GRPCAction{ 143 Port: 1234, 144 }, 145 }, 146 }, 147 }, 148 }, 149 }}, 150 expected: ` 151 { 152 "/app-health/foo/livez": { 153 "grpc": { 154 "port": 1234, 155 "service": null 156 } 157 } 158 }`, 159 }, 160 { 161 name: "gRPC readiness probe with service", 162 pod: &corev1.Pod{Spec: corev1.PodSpec{ 163 Containers: []corev1.Container{ 164 { 165 Name: "bar", 166 ReadinessProbe: &corev1.Probe{ 167 ProbeHandler: corev1.ProbeHandler{ 168 GRPC: &corev1.GRPCAction{ 169 Port: 1234, 170 Service: &svc, 171 }, 172 }, 173 }, 174 }, 175 }, 176 }}, 177 expected: ` 178 { 179 "/app-health/bar/readyz": { 180 "grpc": { 181 "port": 1234, 182 "service": "foo" 183 } 184 } 185 }`, 186 }, 187 { 188 name: "gRPC startup probe with service and timeout", 189 pod: &corev1.Pod{Spec: corev1.PodSpec{ 190 Containers: []corev1.Container{ 191 { 192 Name: "foo", 193 StartupProbe: &corev1.Probe{ 194 ProbeHandler: corev1.ProbeHandler{ 195 GRPC: &corev1.GRPCAction{ 196 Port: 1234, 197 Service: &svc, 198 }, 199 }, 200 TimeoutSeconds: 10, 201 }, 202 }, 203 }, 204 }}, 205 expected: ` 206 { 207 "/app-health/foo/startupz": { 208 "grpc": { 209 "port": 1234, 210 "service": "foo" 211 }, 212 "timeoutSeconds": 10 213 } 214 }`, 215 }, 216 } { 217 got := DumpAppProbers(tc.pod, 15020) 218 test.JSONEquals(t, got, tc.expected) 219 } 220 } 221 222 func TestPatchRewriteProbe(t *testing.T) { 223 svc := "foo" 224 annotations := map[string]string{} 225 statusPort := intstr.FromInt32(15020) 226 for _, tc := range []struct { 227 name string 228 pod *corev1.Pod 229 annotations map[string]string 230 expected *corev1.Pod 231 }{ 232 { 233 name: "pod with no probes", 234 pod: &corev1.Pod{ 235 Spec: corev1.PodSpec{ 236 Containers: []corev1.Container{ 237 { 238 Name: "foo", 239 }, 240 }, 241 }, 242 }, 243 expected: &corev1.Pod{ 244 Spec: corev1.PodSpec{ 245 Containers: []corev1.Container{ 246 { 247 Name: "foo", 248 }, 249 }, 250 }, 251 }, 252 }, 253 { 254 name: "pod with a gRPC liveness probe", 255 pod: &corev1.Pod{ 256 Spec: corev1.PodSpec{ 257 Containers: []corev1.Container{ 258 { 259 Name: "foo", 260 LivenessProbe: &corev1.Probe{ 261 ProbeHandler: corev1.ProbeHandler{ 262 GRPC: &corev1.GRPCAction{ 263 Port: 1234, 264 }, 265 }, 266 }, 267 }, 268 }, 269 }, 270 }, 271 expected: &corev1.Pod{ 272 Spec: corev1.PodSpec{ 273 Containers: []corev1.Container{ 274 { 275 Name: "foo", 276 LivenessProbe: &corev1.Probe{ 277 ProbeHandler: corev1.ProbeHandler{ 278 HTTPGet: &corev1.HTTPGetAction{ 279 Path: "/app-health/foo/livez", 280 Port: statusPort, 281 }, 282 }, 283 }, 284 }, 285 }, 286 }, 287 }, 288 }, 289 { 290 name: "pod with gRPC liveness,readiness,startup probes", 291 pod: &corev1.Pod{ 292 Spec: corev1.PodSpec{ 293 Containers: []corev1.Container{ 294 { 295 Name: "foo", 296 LivenessProbe: &corev1.Probe{ 297 ProbeHandler: corev1.ProbeHandler{ 298 GRPC: &corev1.GRPCAction{ 299 Port: 1234, 300 Service: &svc, 301 }, 302 }, 303 }, 304 ReadinessProbe: &corev1.Probe{ 305 ProbeHandler: corev1.ProbeHandler{ 306 GRPC: &corev1.GRPCAction{ 307 Port: 1235, 308 Service: &svc, 309 }, 310 }, 311 TimeoutSeconds: 10, 312 }, 313 }, 314 { 315 Name: "bar", 316 StartupProbe: &corev1.Probe{ 317 ProbeHandler: corev1.ProbeHandler{ 318 GRPC: &corev1.GRPCAction{ 319 Port: 1236, 320 }, 321 }, 322 TimeoutSeconds: 20, 323 PeriodSeconds: 10, 324 InitialDelaySeconds: 10, 325 }, 326 }, 327 }, 328 }, 329 }, 330 expected: &corev1.Pod{ 331 Spec: corev1.PodSpec{ 332 Containers: []corev1.Container{ 333 { 334 Name: "foo", 335 LivenessProbe: &corev1.Probe{ 336 ProbeHandler: corev1.ProbeHandler{ 337 HTTPGet: &corev1.HTTPGetAction{ 338 Path: "/app-health/foo/livez", 339 Port: statusPort, 340 }, 341 }, 342 }, 343 ReadinessProbe: &corev1.Probe{ 344 ProbeHandler: corev1.ProbeHandler{ 345 HTTPGet: &corev1.HTTPGetAction{ 346 Path: "/app-health/foo/readyz", 347 Port: statusPort, 348 }, 349 }, 350 TimeoutSeconds: 10, 351 }, 352 }, 353 { 354 Name: "bar", 355 StartupProbe: &corev1.Probe{ 356 ProbeHandler: corev1.ProbeHandler{ 357 HTTPGet: &corev1.HTTPGetAction{ 358 Path: "/app-health/bar/startupz", 359 Port: statusPort, 360 }, 361 }, 362 TimeoutSeconds: 20, 363 PeriodSeconds: 10, 364 InitialDelaySeconds: 10, 365 }, 366 }, 367 }, 368 }, 369 }, 370 }, 371 } { 372 patchRewriteProbe(annotations, tc.pod, 15020) 373 if !reflect.DeepEqual(tc.pod, tc.expected) { 374 t.Errorf("[%v] failed, want %v, got %v", tc.name, tc.expected, tc.pod) 375 } 376 } 377 }