1/* 2Copyright 2014 The Kubernetes Authors. 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15*/ 16 17package versioned 18 19import ( 20 "reflect" 21 "testing" 22 23 v1 "k8s.io/api/core/v1" 24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25) 26 27func TestGeneratePod(t *testing.T) { 28 tests := []struct { 29 name string 30 params map[string]interface{} 31 expected *v1.Pod 32 expectErr bool 33 }{ 34 { 35 name: "test1", 36 params: map[string]interface{}{ 37 "name": "foo", 38 "image": "someimage", 39 "port": "", 40 }, 41 expected: &v1.Pod{ 42 ObjectMeta: metav1.ObjectMeta{ 43 Name: "foo", 44 Labels: map[string]string{"run": "foo"}, 45 }, 46 Spec: v1.PodSpec{ 47 Containers: []v1.Container{ 48 { 49 Name: "foo", 50 Image: "someimage", 51 }, 52 }, 53 DNSPolicy: v1.DNSClusterFirst, 54 RestartPolicy: v1.RestartPolicyAlways, 55 }, 56 }, 57 }, 58 { 59 name: "test2", 60 params: map[string]interface{}{ 61 "name": "foo", 62 "image": "someimage", 63 "env": []string{"a", "c"}, 64 }, 65 66 expected: nil, 67 expectErr: true, 68 }, 69 { 70 name: "test3", 71 params: map[string]interface{}{ 72 "name": "foo", 73 "image": "someimage", 74 "image-pull-policy": "Always", 75 "env": []string{"a=b", "c=d"}, 76 }, 77 expected: &v1.Pod{ 78 ObjectMeta: metav1.ObjectMeta{ 79 Name: "foo", 80 Labels: map[string]string{"run": "foo"}, 81 }, 82 Spec: v1.PodSpec{ 83 Containers: []v1.Container{ 84 { 85 Name: "foo", 86 Image: "someimage", 87 ImagePullPolicy: v1.PullAlways, 88 Env: []v1.EnvVar{ 89 { 90 Name: "a", 91 Value: "b", 92 }, 93 { 94 Name: "c", 95 Value: "d", 96 }, 97 }, 98 }, 99 }, 100 DNSPolicy: v1.DNSClusterFirst, 101 RestartPolicy: v1.RestartPolicyAlways, 102 }, 103 }, 104 }, 105 { 106 name: "test4", 107 params: map[string]interface{}{ 108 "name": "foo", 109 "image": "someimage", 110 "port": "80", 111 }, 112 expected: &v1.Pod{ 113 ObjectMeta: metav1.ObjectMeta{ 114 Name: "foo", 115 Labels: map[string]string{"run": "foo"}, 116 }, 117 Spec: v1.PodSpec{ 118 Containers: []v1.Container{ 119 { 120 Name: "foo", 121 Image: "someimage", 122 Ports: []v1.ContainerPort{ 123 { 124 ContainerPort: 80, 125 }, 126 }, 127 }, 128 }, 129 DNSPolicy: v1.DNSClusterFirst, 130 RestartPolicy: v1.RestartPolicyAlways, 131 }, 132 }, 133 }, 134 { 135 name: "test5", 136 params: map[string]interface{}{ 137 "name": "foo", 138 "image": "someimage", 139 "port": "80", 140 "hostport": "80", 141 }, 142 expected: &v1.Pod{ 143 ObjectMeta: metav1.ObjectMeta{ 144 Name: "foo", 145 Labels: map[string]string{"run": "foo"}, 146 }, 147 Spec: v1.PodSpec{ 148 Containers: []v1.Container{ 149 { 150 Name: "foo", 151 Image: "someimage", 152 Ports: []v1.ContainerPort{ 153 { 154 ContainerPort: 80, 155 HostPort: 80, 156 }, 157 }, 158 }, 159 }, 160 DNSPolicy: v1.DNSClusterFirst, 161 RestartPolicy: v1.RestartPolicyAlways, 162 }, 163 }, 164 }, 165 { 166 name: "test6", 167 params: map[string]interface{}{ 168 "name": "foo", 169 "image": "someimage", 170 "hostport": "80", 171 }, 172 expected: nil, 173 expectErr: true, 174 }, 175 { 176 name: "test7", 177 params: map[string]interface{}{ 178 "name": "foo", 179 "image": "someimage", 180 "replicas": "1", 181 "labels": "foo=bar,baz=blah", 182 }, 183 expected: &v1.Pod{ 184 ObjectMeta: metav1.ObjectMeta{ 185 Name: "foo", 186 Labels: map[string]string{"foo": "bar", "baz": "blah"}, 187 }, 188 Spec: v1.PodSpec{ 189 Containers: []v1.Container{ 190 { 191 Name: "foo", 192 Image: "someimage", 193 }, 194 }, 195 DNSPolicy: v1.DNSClusterFirst, 196 RestartPolicy: v1.RestartPolicyAlways, 197 }, 198 }, 199 }, 200 { 201 name: "test8", 202 params: map[string]interface{}{ 203 "name": "foo", 204 "image": "someimage", 205 "replicas": "1", 206 "labels": "foo=bar,baz=blah", 207 "stdin": "true", 208 }, 209 expected: &v1.Pod{ 210 ObjectMeta: metav1.ObjectMeta{ 211 Name: "foo", 212 Labels: map[string]string{"foo": "bar", "baz": "blah"}, 213 }, 214 Spec: v1.PodSpec{ 215 Containers: []v1.Container{ 216 { 217 Name: "foo", 218 Image: "someimage", 219 Stdin: true, 220 StdinOnce: true, 221 }, 222 }, 223 DNSPolicy: v1.DNSClusterFirst, 224 RestartPolicy: v1.RestartPolicyAlways, 225 }, 226 }, 227 }, 228 { 229 name: "test9", 230 params: map[string]interface{}{ 231 "name": "foo", 232 "image": "someimage", 233 "replicas": "1", 234 "labels": "foo=bar,baz=blah", 235 "stdin": "true", 236 "leave-stdin-open": "true", 237 }, 238 expected: &v1.Pod{ 239 ObjectMeta: metav1.ObjectMeta{ 240 Name: "foo", 241 Labels: map[string]string{"foo": "bar", "baz": "blah"}, 242 }, 243 Spec: v1.PodSpec{ 244 Containers: []v1.Container{ 245 { 246 Name: "foo", 247 Image: "someimage", 248 Stdin: true, 249 StdinOnce: false, 250 }, 251 }, 252 DNSPolicy: v1.DNSClusterFirst, 253 RestartPolicy: v1.RestartPolicyAlways, 254 }, 255 }, 256 }, 257 { 258 name: "test10: privileged mode", 259 params: map[string]interface{}{ 260 "name": "foo", 261 "image": "someimage", 262 "replicas": "1", 263 "privileged": "true", 264 }, 265 expected: &v1.Pod{ 266 ObjectMeta: metav1.ObjectMeta{ 267 Name: "foo", 268 Labels: map[string]string{"run": "foo"}, 269 }, 270 Spec: v1.PodSpec{ 271 Containers: []v1.Container{ 272 { 273 Name: "foo", 274 Image: "someimage", 275 SecurityContext: securityContextWithPrivilege(true), 276 }, 277 }, 278 DNSPolicy: v1.DNSClusterFirst, 279 RestartPolicy: v1.RestartPolicyAlways, 280 }, 281 }, 282 }, 283 { 284 name: "test11: check annotations", 285 params: map[string]interface{}{ 286 "name": "foo", 287 "image": "someimage", 288 "replicas": "1", 289 "labels": "foo=bar,baz=blah", 290 "annotations": []string{"foo=bar1", "baz=blah1"}, 291 }, 292 expected: &v1.Pod{ 293 ObjectMeta: metav1.ObjectMeta{ 294 Name: "foo", 295 Labels: map[string]string{"foo": "bar", "baz": "blah"}, 296 Annotations: map[string]string{"foo": "bar1", "baz": "blah1"}, 297 }, 298 Spec: v1.PodSpec{ 299 Containers: []v1.Container{ 300 { 301 Name: "foo", 302 Image: "someimage", 303 }, 304 }, 305 DNSPolicy: v1.DNSClusterFirst, 306 RestartPolicy: v1.RestartPolicyAlways, 307 }, 308 }, 309 }, 310 } 311 generator := BasicPod{} 312 for _, tt := range tests { 313 t.Run(tt.name, func(t *testing.T) { 314 obj, err := generator.Generate(tt.params) 315 if !tt.expectErr && err != nil { 316 t.Errorf("unexpected error: %v", err) 317 } 318 if tt.expectErr && err != nil { 319 return 320 } 321 if !reflect.DeepEqual(obj.(*v1.Pod), tt.expected) { 322 t.Errorf("\nexpected:\n%#v\nsaw:\n%#v", tt.expected, obj.(*v1.Pod)) 323 } 324 }) 325 } 326} 327 328func TestParseEnv(t *testing.T) { 329 tests := []struct { 330 name string 331 envArray []string 332 expected []v1.EnvVar 333 expectErr bool 334 test string 335 }{ 336 { 337 name: "test1", 338 envArray: []string{ 339 "THIS_ENV=isOK", 340 "this.dotted.env=isOKToo", 341 "HAS_COMMAS=foo,bar", 342 "HAS_EQUALS=jJnro54iUu75xNy==", 343 }, 344 expected: []v1.EnvVar{ 345 { 346 Name: "THIS_ENV", 347 Value: "isOK", 348 }, 349 { 350 Name: "this.dotted.env", 351 Value: "isOKToo", 352 }, 353 { 354 Name: "HAS_COMMAS", 355 Value: "foo,bar", 356 }, 357 { 358 Name: "HAS_EQUALS", 359 Value: "jJnro54iUu75xNy==", 360 }, 361 }, 362 expectErr: false, 363 test: "test case 1", 364 }, 365 { 366 name: "test2", 367 envArray: []string{ 368 "WITH_OUT_EQUALS", 369 }, 370 expected: []v1.EnvVar{}, 371 expectErr: true, 372 test: "test case 2", 373 }, 374 { 375 name: "test3", 376 envArray: []string{ 377 "WITH_OUT_VALUES=", 378 }, 379 expected: []v1.EnvVar{ 380 { 381 Name: "WITH_OUT_VALUES", 382 Value: "", 383 }, 384 }, 385 expectErr: false, 386 test: "test case 3", 387 }, 388 { 389 name: "test4", 390 envArray: []string{ 391 "=WITH_OUT_NAME", 392 }, 393 expected: []v1.EnvVar{}, 394 expectErr: true, 395 test: "test case 4", 396 }, 397 } 398 399 for _, tt := range tests { 400 t.Run(tt.name, func(t *testing.T) { 401 envs, err := parseEnvs(tt.envArray) 402 if !tt.expectErr && err != nil { 403 t.Errorf("unexpected error: %v (%s)", err, tt.test) 404 } 405 if tt.expectErr && err != nil { 406 return 407 } 408 if !reflect.DeepEqual(envs, tt.expected) { 409 t.Errorf("\nexpected:\n%#v\nsaw:\n%#v (%s)", tt.expected, envs, tt.test) 410 } 411 }) 412 } 413} 414 415func securityContextWithPrivilege(privileged bool) *v1.SecurityContext { 416 return &v1.SecurityContext{ 417 Privileged: &privileged, 418 } 419} 420