github.com/GoogleCloudPlatform/testgrid@v0.0.174/metadata/job_test.go (about) 1 /* 2 Copyright 2019 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 metadata 18 19 import ( 20 "encoding/json" 21 "reflect" 22 "testing" 23 ) 24 25 func TestMeta(t *testing.T) { 26 world := "world" 27 olam := "olam" 28 const key = "target-key" 29 cases := []struct { 30 name string 31 in Metadata 32 call func(actual Metadata) (interface{}, bool) 33 val interface{} 34 present bool 35 }{ 36 { 37 name: "can match string", 38 in: Metadata{ 39 key: world, 40 }, 41 call: func(actual Metadata) (interface{}, bool) { 42 return actual.String(key) 43 }, 44 val: &world, 45 present: true, 46 }, 47 { 48 name: "detect value is not a string", 49 in: Metadata{ 50 key: Metadata{"super": "fancy"}, 51 }, 52 call: func(actual Metadata) (interface{}, bool) { 53 return actual.String(key) 54 }, 55 val: (*string)(nil), 56 present: true, 57 }, 58 { 59 name: "can match metadata", 60 in: Metadata{ 61 key: Metadata{ 62 "super": "fancy", 63 "one": 1, 64 }, 65 }, 66 call: func(actual Metadata) (interface{}, bool) { 67 return actual.Meta(key) 68 }, 69 val: &Metadata{ 70 "super": "fancy", 71 "one": 1.0, // LOL json 72 }, 73 present: true, 74 }, 75 { 76 name: "detect value is not metadata", 77 in: Metadata{ 78 key: "not metadata", 79 }, 80 call: func(actual Metadata) (interface{}, bool) { 81 return actual.Meta(key) 82 }, 83 val: (*Metadata)(nil), 84 present: true, 85 }, 86 { 87 name: "detect key absence for string", 88 in: Metadata{ 89 "random-key": "hello", 90 }, 91 call: func(actual Metadata) (interface{}, bool) { 92 return actual.String(key) 93 }, 94 val: (*string)(nil), 95 }, 96 { 97 name: "detect key absence for metadata", 98 in: Metadata{ 99 "random-key": Metadata{}, 100 }, 101 call: func(actual Metadata) (interface{}, bool) { 102 return actual.Meta(key) 103 }, 104 val: (*Metadata)(nil), 105 }, 106 { 107 name: "get list of strings", 108 in: Metadata{ 109 key: []string{world, olam}, 110 }, 111 call: func(actual Metadata) (interface{}, bool) { 112 return actual.MultiString(key) 113 }, 114 val: []string{world, olam}, 115 present: true, 116 }, 117 { 118 name: "get list of strings from list of interfaces", 119 in: Metadata{ 120 key: []interface{}{world, olam}, 121 }, 122 call: func(actual Metadata) (interface{}, bool) { 123 return actual.MultiString(key) 124 }, 125 val: []string{world, olam}, 126 present: true, 127 }, 128 { 129 name: "non string in list of interfaces", 130 in: Metadata{ 131 key: []interface{}{world, 1337}, 132 }, 133 call: func(actual Metadata) (interface{}, bool) { 134 return actual.MultiString(key) 135 }, 136 val: []string{}, 137 present: true, 138 }, 139 { 140 name: "not list of strings", 141 in: Metadata{ 142 key: []int{42, 1337}, 143 }, 144 call: func(actual Metadata) (interface{}, bool) { 145 return actual.MultiString(key) 146 }, 147 val: []string{}, 148 present: true, 149 }, 150 { 151 name: "given empty list", 152 in: Metadata{ 153 key: []interface{}{}, 154 }, 155 call: func(actual Metadata) (interface{}, bool) { 156 return actual.MultiString(key) 157 }, 158 val: []string{}, 159 present: true, 160 }, 161 { 162 name: "return empty list if key absence", 163 in: Metadata{ 164 "random-key": []string{world}, 165 }, 166 call: func(actual Metadata) (interface{}, bool) { 167 return actual.MultiString(key) 168 }, 169 val: []string{}, 170 }, 171 } 172 173 for _, tc := range cases { 174 t.Run(tc.name, func(t *testing.T) { 175 out, err := json.Marshal(tc.in) 176 if err != nil { 177 t.Errorf("marshal: %v", err) 178 } 179 var actual Metadata 180 if err := json.Unmarshal(out, &actual); err != nil { 181 t.Errorf("unmarshal: %v", err) 182 } 183 val, present := tc.call(actual) 184 if !reflect.DeepEqual(val, tc.val) { 185 t.Errorf("%#v != expected %#v", val, tc.val) // Remember json doesn't have ints 186 } 187 if present != tc.present { 188 t.Errorf("present %t != expected %t", present, tc.present) 189 } 190 }) 191 } 192 } 193 194 func TestVersion(t *testing.T) { 195 cases := []struct { 196 name string 197 started Started 198 finished Finished 199 expected string 200 }{ 201 { 202 name: "missing by default", 203 expected: Missing, 204 }, 205 { 206 name: "DEPRECATED: finished job version over started", 207 started: Started{ 208 DeprecatedJobVersion: "wrong", 209 }, 210 finished: Finished{ 211 DeprecatedJobVersion: "right", 212 }, 213 expected: "right", 214 }, 215 { 216 name: "DEPRECATED: job version over repo version", 217 started: Started{ 218 DeprecatedJobVersion: "yes-job", 219 DeprecatedRepoVersion: "no-repo", 220 }, 221 expected: "yes-job", 222 }, 223 { 224 name: "DEPRECATED: started repo version over finished", 225 started: Started{ 226 DeprecatedRepoVersion: "right", 227 }, 228 finished: Finished{ 229 DeprecatedRepoVersion: "wrong-finish", 230 }, 231 expected: "right", 232 }, 233 { 234 name: "job-version over repo-commit", 235 started: Started{ 236 RepoCommit: "nope", 237 }, 238 finished: Finished{ 239 Metadata: Metadata{ 240 JobVersion: "yes", 241 }, 242 }, 243 expected: "yes", 244 }, 245 { 246 name: "find repo-commit", 247 started: Started{ 248 RepoCommit: "yay", 249 }, 250 expected: "yay", 251 }, 252 { 253 name: "truncate to 9 chars", 254 started: Started{ 255 RepoCommit: "12345678900000000", 256 }, 257 expected: "123456789", 258 }, 259 { 260 name: "drop part before the first +", 261 started: Started{ 262 RepoCommit: "ignore+hello+yes", 263 }, 264 expected: "hello+yes", 265 }, 266 { 267 name: "trucate part after +", 268 started: Started{ 269 RepoCommit: "deadbeef+12345678900000000", 270 }, 271 expected: "123456789", 272 }, 273 } 274 275 for _, tc := range cases { 276 t.Run(tc.name, func(t *testing.T) { 277 if actual := Version(tc.started, tc.finished); actual != tc.expected { 278 t.Errorf("actual %s != expected %s", actual, tc.expected) 279 } 280 }) 281 } 282 } 283 284 func TestSetVersion(t *testing.T) { 285 cases := []struct { 286 name string 287 repoCommit string 288 jobVersion string 289 started bool 290 finished bool 291 expected string 292 }{ 293 { 294 name: "basically works", 295 repoCommit: "repo", 296 jobVersion: "job", 297 started: true, 298 finished: true, 299 expected: "job", 300 }, 301 { 302 name: "missing by default", 303 started: true, 304 finished: true, 305 expected: Missing, 306 }, 307 { 308 name: "can pass in nothing", 309 repoCommit: "ignore", 310 jobVersion: "me", 311 expected: Missing, 312 }, 313 { 314 name: "match repo commit when job version not set", 315 repoCommit: "deadbeef", 316 started: true, 317 finished: true, 318 expected: "deadbeef", 319 }, 320 { 321 name: "match repo commit when just started", 322 repoCommit: "aaa", 323 jobVersion: "ignore", 324 started: true, 325 expected: "aaa", 326 }, 327 } 328 329 for _, tc := range cases { 330 t.Run(tc.name, func(t *testing.T) { 331 var s Started 332 var f Finished 333 var ps *Started 334 var pf *Finished 335 if tc.started { 336 ps = &s 337 } 338 if tc.finished { 339 pf = &f 340 } 341 SetVersion(ps, pf, tc.repoCommit, tc.jobVersion) 342 if actual := Version(s, f); actual != tc.expected { 343 t.Errorf("actual %s != expected %s", actual, tc.expected) 344 } 345 }) 346 } 347 348 }