github.com/shashidharatd/test-infra@v0.0.0-20171006011030-71304e1ca560/prow/pjutil/pjutil_test.go (about) 1 /* 2 Copyright 2017 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package pjutil 18 19 import ( 20 "reflect" 21 "testing" 22 23 "k8s.io/test-infra/prow/kube" 24 ) 25 26 func TestEnvironmentForSpec(t *testing.T) { 27 var tests = []struct { 28 name string 29 spec kube.ProwJobSpec 30 expected map[string]string 31 }{ 32 { 33 name: "periodic job", 34 spec: kube.ProwJobSpec{ 35 Type: kube.PeriodicJob, 36 Job: "job-name", 37 }, 38 expected: map[string]string{ 39 "JOB_NAME": "job-name", 40 }, 41 }, 42 { 43 name: "postsubmit job", 44 spec: kube.ProwJobSpec{ 45 Type: kube.PostsubmitJob, 46 Job: "job-name", 47 Refs: kube.Refs{ 48 Org: "org-name", 49 Repo: "repo-name", 50 BaseRef: "base-ref", 51 BaseSHA: "base-sha", 52 }, 53 }, 54 expected: map[string]string{ 55 "JOB_NAME": "job-name", 56 "REPO_OWNER": "org-name", 57 "REPO_NAME": "repo-name", 58 "PULL_BASE_REF": "base-ref", 59 "PULL_BASE_SHA": "base-sha", 60 "PULL_REFS": "base-ref:base-sha", 61 }, 62 }, 63 { 64 name: "batch job", 65 spec: kube.ProwJobSpec{ 66 Type: kube.BatchJob, 67 Job: "job-name", 68 Refs: kube.Refs{ 69 Org: "org-name", 70 Repo: "repo-name", 71 BaseRef: "base-ref", 72 BaseSHA: "base-sha", 73 Pulls: []kube.Pull{{ 74 Number: 1, 75 Author: "author-name", 76 SHA: "pull-sha", 77 }, { 78 Number: 2, 79 Author: "other-author-name", 80 SHA: "second-pull-sha", 81 }}, 82 }, 83 }, 84 expected: map[string]string{ 85 "JOB_NAME": "job-name", 86 "REPO_OWNER": "org-name", 87 "REPO_NAME": "repo-name", 88 "PULL_BASE_REF": "base-ref", 89 "PULL_BASE_SHA": "base-sha", 90 "PULL_REFS": "base-ref:base-sha,1:pull-sha,2:second-pull-sha", 91 }, 92 }, 93 { 94 name: "presubmit job", 95 spec: kube.ProwJobSpec{ 96 Type: kube.PresubmitJob, 97 Job: "job-name", 98 Refs: kube.Refs{ 99 Org: "org-name", 100 Repo: "repo-name", 101 BaseRef: "base-ref", 102 BaseSHA: "base-sha", 103 Pulls: []kube.Pull{{ 104 Number: 1, 105 Author: "author-name", 106 SHA: "pull-sha", 107 }}, 108 }, 109 }, 110 expected: map[string]string{ 111 "JOB_NAME": "job-name", 112 "REPO_OWNER": "org-name", 113 "REPO_NAME": "repo-name", 114 "PULL_BASE_REF": "base-ref", 115 "PULL_BASE_SHA": "base-sha", 116 "PULL_REFS": "base-ref:base-sha,1:pull-sha", 117 "PULL_NUMBER": "1", 118 "PULL_PULL_SHA": "pull-sha", 119 }, 120 }, 121 } 122 123 for _, test := range tests { 124 if actual, expected := EnvForSpec(test.spec), test.expected; !reflect.DeepEqual(actual, expected) { 125 t.Errorf("%s: got environment:\n\t%v\n\tbut expected:\n\t%v", test.name, actual, expected) 126 } 127 } 128 } 129 130 func TestProwJobToPod(t *testing.T) { 131 tests := []struct { 132 podName string 133 buildID string 134 pjSpec kube.ProwJobSpec 135 136 expected *kube.Pod 137 }{ 138 { 139 podName: "pod", 140 buildID: "blabla", 141 pjSpec: kube.ProwJobSpec{ 142 Type: kube.PresubmitJob, 143 Job: "job-name", 144 Refs: kube.Refs{ 145 Org: "org-name", 146 Repo: "repo-name", 147 BaseRef: "base-ref", 148 BaseSHA: "base-sha", 149 Pulls: []kube.Pull{{ 150 Number: 1, 151 Author: "author-name", 152 SHA: "pull-sha", 153 }}, 154 }, 155 PodSpec: kube.PodSpec{ 156 Containers: []kube.Container{ 157 { 158 Image: "tester", 159 Env: []kube.EnvVar{ 160 {Name: "MY_ENV", Value: "rocks"}, 161 }, 162 }, 163 }, 164 }, 165 }, 166 167 expected: &kube.Pod{ 168 Metadata: kube.ObjectMeta{ 169 Name: "pod", 170 Labels: map[string]string{ 171 kube.CreatedByProw: "true", 172 "type": "presubmit", 173 }, 174 Annotations: map[string]string{ 175 "job": "job-name", 176 }, 177 }, 178 Spec: kube.PodSpec{ 179 RestartPolicy: "Never", 180 Containers: []kube.Container{ 181 { 182 Name: "pod-0", 183 Image: "tester", 184 Env: []kube.EnvVar{ 185 {Name: "MY_ENV", Value: "rocks"}, 186 {Name: "BUILD_NUMBER", Value: "blabla"}, 187 {Name: "JOB_NAME", Value: "job-name"}, 188 {Name: "PULL_BASE_REF", Value: "base-ref"}, 189 {Name: "REPO_OWNER", Value: "org-name"}, 190 {Name: "REPO_NAME", Value: "repo-name"}, 191 {Name: "PULL_BASE_SHA", Value: "base-sha"}, 192 {Name: "PULL_REFS", Value: "base-ref:base-sha,1:pull-sha"}, 193 {Name: "PULL_NUMBER", Value: "1"}, 194 {Name: "PULL_PULL_SHA", Value: "pull-sha"}, 195 }, 196 }, 197 }, 198 }, 199 }, 200 }, 201 } 202 203 for i, test := range tests { 204 t.Logf("test run #%d", i) 205 pj := kube.ProwJob{Metadata: kube.ObjectMeta{Name: test.podName}, Spec: test.pjSpec} 206 got := ProwJobToPod(pj, test.buildID) 207 // TODO: For now I am just comparing fields manually, eventually we 208 // should port the semantic.DeepEqual helper from the api-machinery 209 // repo, which is basically a fork of the reflect package. 210 // if !semantic.DeepEqual(got, test.expected) { 211 // t.Errorf("got pod:\n%#v\n\nexpected pod:\n%#v\n", got, test.expected) 212 // } 213 var foundCreatedByLabel, foundTypeLabel, foundJobAnnotation bool 214 for key, value := range got.Metadata.Labels { 215 if key == kube.CreatedByProw && value == "true" { 216 foundCreatedByLabel = true 217 } 218 if key == "type" && value == string(pj.Spec.Type) { 219 foundTypeLabel = true 220 } 221 } 222 for key, value := range got.Metadata.Annotations { 223 if key == "job" && value == pj.Spec.Job { 224 foundJobAnnotation = true 225 } 226 } 227 if !foundCreatedByLabel { 228 t.Errorf("expected a created-by-prow=true label in %v", got.Metadata.Labels) 229 } 230 if !foundTypeLabel { 231 t.Errorf("expected a type=%s label in %v", pj.Spec.Type, got.Metadata.Labels) 232 } 233 if !foundJobAnnotation { 234 t.Errorf("expected a job=%s annotation in %v", pj.Spec.Job, got.Metadata.Annotations) 235 } 236 237 expectedContainer := test.expected.Spec.Containers[i] 238 gotContainer := got.Spec.Containers[i] 239 240 dumpGotEnv := false 241 for _, expectedEnv := range expectedContainer.Env { 242 found := false 243 for _, gotEnv := range gotContainer.Env { 244 if expectedEnv.Name == gotEnv.Name && expectedEnv.Value == gotEnv.Value { 245 found = true 246 break 247 } 248 } 249 if !found { 250 dumpGotEnv = true 251 t.Errorf("could not find expected env %s=%s", expectedEnv.Name, expectedEnv.Value) 252 } 253 } 254 if dumpGotEnv { 255 t.Errorf("expected env:\n%#v\ngot:\n%#v\n", expectedContainer.Env, gotContainer.Env) 256 } 257 if expectedContainer.Image != gotContainer.Image { 258 t.Errorf("expected image: %s, got: %s", expectedContainer.Image, gotContainer.Image) 259 } 260 if test.expected.Spec.RestartPolicy != got.Spec.RestartPolicy { 261 t.Errorf("expected restart policy: %s, got: %s", test.expected.Spec.RestartPolicy, got.Spec.RestartPolicy) 262 } 263 } 264 } 265 266 func TestPartitionPending(t *testing.T) { 267 tests := []struct { 268 pjs []kube.ProwJob 269 270 pending map[string]struct{} 271 nonPending map[string]struct{} 272 }{ 273 { 274 pjs: []kube.ProwJob{ 275 { 276 Metadata: kube.ObjectMeta{ 277 Name: "foo", 278 }, 279 Status: kube.ProwJobStatus{ 280 State: kube.TriggeredState, 281 }, 282 }, 283 { 284 Metadata: kube.ObjectMeta{ 285 Name: "bar", 286 }, 287 Status: kube.ProwJobStatus{ 288 State: kube.PendingState, 289 }, 290 }, 291 { 292 Metadata: kube.ObjectMeta{ 293 Name: "baz", 294 }, 295 Status: kube.ProwJobStatus{ 296 State: kube.SuccessState, 297 }, 298 }, 299 { 300 Metadata: kube.ObjectMeta{ 301 Name: "error", 302 }, 303 Status: kube.ProwJobStatus{ 304 State: kube.ErrorState, 305 }, 306 }, 307 { 308 Metadata: kube.ObjectMeta{ 309 Name: "bak", 310 }, 311 Status: kube.ProwJobStatus{ 312 State: kube.PendingState, 313 }, 314 }, 315 }, 316 pending: map[string]struct{}{ 317 "bar": {}, "bak": {}, 318 }, 319 nonPending: map[string]struct{}{ 320 "foo": {}, "baz": {}, "error": {}, 321 }, 322 }, 323 } 324 325 for i, test := range tests { 326 t.Logf("test run #%d", i) 327 pendingCh, nonPendingCh := PartitionPending(test.pjs) 328 for job := range pendingCh { 329 if _, ok := test.pending[job.Metadata.Name]; !ok { 330 t.Errorf("didn't find pending job %#v", job) 331 } 332 } 333 for job := range nonPendingCh { 334 if _, ok := test.nonPending[job.Metadata.Name]; !ok { 335 t.Errorf("didn't find non-pending job %#v", job) 336 } 337 } 338 } 339 }