sigs.k8s.io/prow@v0.0.0-20240503223140-c5e374dc7eb1/hack/prowimagebuilder/main_test.go (about) 1 /* 2 Copyright 2022 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 main 18 19 import ( 20 "errors" 21 "fmt" 22 "os" 23 "path" 24 "strings" 25 "testing" 26 27 "github.com/google/go-cmp/cmp" 28 "github.com/google/go-cmp/cmp/cmpopts" 29 "sigs.k8s.io/prow/pkg/flagutil" 30 ) 31 32 func TestImageAllowed(t *testing.T) { 33 tests := []struct { 34 name string 35 images flagutil.Strings 36 image string 37 want bool 38 }{ 39 { 40 name: "not-specified", 41 images: flagutil.Strings{}, 42 image: "whatever", 43 want: true, 44 }, 45 { 46 name: "included", 47 images: flagutil.NewStringsBeenSet("cmd/awesome"), 48 image: "cmd/awesome", 49 want: true, 50 }, 51 { 52 name: "not-included", 53 images: flagutil.NewStringsBeenSet("cmd/awesome"), 54 image: "cmd/otherawesome", 55 want: false, 56 }, 57 } 58 59 for _, tc := range tests { 60 tc := tc 61 t.Run(tc.name, func(t *testing.T) { 62 o := options{ 63 images: tc.images, 64 } 65 got := o.imageAllowed(tc.image) 66 if got != tc.want { 67 t.Errorf("Unexpected. Want: %v, got: %v", tc.want, got) 68 } 69 }) 70 } 71 } 72 73 func TestRunCmdInDir(t *testing.T) { 74 dir := t.TempDir() 75 tests := []struct { 76 name string 77 dir string 78 cmd string 79 args []string 80 wantOut string 81 wantErr bool 82 }{ 83 { 84 name: "echo", 85 cmd: "echo", 86 args: []string{"abc"}, 87 wantOut: "abc", 88 wantErr: false, 89 }, 90 { 91 name: "dir-not-exist", 92 dir: "dir-not-exist", 93 cmd: "echo", 94 args: []string{"abc"}, 95 wantOut: "", 96 wantErr: true, 97 }, 98 { 99 name: "dir-exist", 100 dir: dir, 101 cmd: "echo", 102 args: []string{"abc"}, 103 wantOut: "abc", 104 wantErr: false, 105 }, 106 { 107 name: "failed", 108 cmd: "echo-abc", 109 args: []string{"abc"}, 110 wantOut: "", 111 wantErr: true, 112 }, 113 } 114 115 for _, tc := range tests { 116 tc := tc 117 t.Run(tc.name, func(t *testing.T) { 118 got, gotErr := runCmdInDir(tc.dir, nil, tc.cmd, tc.args...) 119 if (gotErr != nil && !tc.wantErr) || (gotErr == nil && tc.wantErr) { 120 t.Fatalf("Error mismatch. Want: %v, got: %v", tc.wantErr, gotErr) 121 } 122 if want, got := strings.TrimSpace(tc.wantOut), strings.TrimSpace(got); want != got { 123 t.Fatalf("Output mismatch. Want: %q, got: %q", want, got) 124 } 125 }) 126 } 127 } 128 129 func TestRunCmd(t *testing.T) { 130 gotOut, gotErr := runCmd(nil, "echo", "abc") 131 if gotErr != nil { 132 t.Fatalf("Should not error, got: %v", gotErr) 133 } 134 if want, got := "abc", strings.TrimSpace(gotOut); want != got { 135 t.Fatalf("Output mismatch. Want: %q, got: %q", want, got) 136 } 137 } 138 139 func TestLoadImageDefs(t *testing.T) { 140 dir := t.TempDir() 141 file := path.Join(dir, "temp.yaml") 142 body := `images: 143 - dir: cmd/admission 144 - dir: cmd/clonerefs 145 arch: all` 146 147 wantDefs := []imageDef{ 148 {Dir: "cmd/admission"}, 149 {Dir: "cmd/clonerefs", Arch: "all"}, 150 } 151 152 if err := os.WriteFile(file, []byte(body), 0644); err != nil { 153 t.Fatalf("Failed write file: %v", err) 154 } 155 defs, err := loadImageDefs(file) 156 if err != nil { 157 t.Fatalf("Failed loading image defs: %v", err) 158 } 159 if diff := cmp.Diff(defs, wantDefs, cmpopts.IgnoreUnexported(imageDef{})); diff != "" { 160 t.Fatalf("Output mismatch. Want(-), got(+):\n%s", diff) 161 } 162 } 163 164 func TestAllTags(t *testing.T) { 165 date, gitHash := "20220222", "a1b2c3d4" 166 oldRunCmdInDirFunc := runCmdInDirFunc 167 runCmdInDirFunc = func(dir string, additionalEnv []string, cmd string, args ...string) (string, error) { 168 switch cmd { 169 case "date": 170 return date, nil 171 case "git": 172 return gitHash, nil 173 default: 174 return "", errors.New("not supported command") 175 } 176 } 177 defer func() { 178 runCmdInDirFunc = oldRunCmdInDirFunc 179 }() 180 181 tests := []struct { 182 name string 183 arch string 184 want []string 185 }{ 186 { 187 name: "base", 188 arch: "linux/amd64", 189 want: []string{ 190 "latest", 191 "latest-root", 192 "20220222-a1b2c3d4", 193 "ko-20220222-a1b2c3d4", 194 }, 195 }, 196 { 197 name: "other", 198 arch: "linux/s390x", 199 want: []string{ 200 "latest", 201 "latest-root", 202 "20220222-a1b2c3d4", 203 "ko-20220222-a1b2c3d4", 204 "latest-s390x", 205 "latest-root-s390x", 206 "20220222-a1b2c3d4-s390x", 207 "ko-20220222-a1b2c3d4-s390x", 208 }, 209 }, 210 { 211 name: "all", 212 arch: "all", 213 want: []string{ 214 "latest", 215 "latest-root", 216 "20220222-a1b2c3d4", 217 "ko-20220222-a1b2c3d4", 218 "latest-arm64", 219 "latest-root-arm64", 220 "20220222-a1b2c3d4-arm64", 221 "ko-20220222-a1b2c3d4-arm64", 222 "latest-s390x", 223 "latest-root-s390x", 224 "20220222-a1b2c3d4-s390x", 225 "ko-20220222-a1b2c3d4-s390x", 226 "latest-ppc64le", 227 "latest-root-ppc64le", 228 "20220222-a1b2c3d4-ppc64le", 229 "ko-20220222-a1b2c3d4-ppc64le", 230 }, 231 }, 232 { 233 // Not supported arches are caught in the invoker of this function, 234 // not here. 235 name: "not-supported", 236 arch: "not/supported", 237 want: []string{ 238 "latest", 239 "latest-root", 240 "20220222-a1b2c3d4", 241 "ko-20220222-a1b2c3d4", 242 }, 243 }, 244 } 245 246 for _, tc := range tests { 247 tc := tc 248 t.Run(tc.name, func(t *testing.T) { 249 got, _ := allTags(tc.arch) 250 if diff := cmp.Diff(tc.want, got); diff != "" { 251 t.Errorf("Tags mismatching. Want(-), got(+):\n%s", diff) 252 } 253 }) 254 } 255 } 256 257 func TestGitTag(t *testing.T) { 258 tests := []struct { 259 name string 260 date string 261 gitHash string 262 cmdErr error 263 want string 264 wantErr bool 265 }{ 266 { 267 name: "base", 268 date: "20220222", 269 gitHash: "a1b2c3d4", 270 want: "20220222-a1b2c3d4", 271 }, 272 { 273 name: "err", 274 date: "20220222", 275 gitHash: "a1b2c3d4", 276 cmdErr: errors.New("error for test"), 277 want: "", 278 wantErr: true, 279 }, 280 } 281 282 for _, tc := range tests { 283 tc := tc 284 t.Run(tc.name, func(t *testing.T) { 285 oldRunCmdInDirFunc := runCmdInDirFunc 286 runCmdInDirFunc = func(dir string, additionalEnv []string, cmd string, args ...string) (string, error) { 287 switch cmd { 288 case "date": 289 return tc.date, tc.cmdErr 290 case "git": 291 return tc.gitHash, tc.cmdErr 292 default: 293 return "", errors.New("not supported command") 294 } 295 } 296 defer func() { 297 runCmdInDirFunc = oldRunCmdInDirFunc 298 }() 299 300 got, gotErr := gitTag() 301 if (gotErr != nil && !tc.wantErr) || (gotErr == nil && tc.wantErr) { 302 t.Fatalf("Error mismatch. Want: %v, got: %v", tc.wantErr, gotErr) 303 } 304 if want, got := strings.TrimSpace(tc.want), strings.TrimSpace(got); want != got { 305 t.Fatalf("Output mismatch. Want: %q, got: %q", want, got) 306 } 307 }) 308 } 309 } 310 311 func TestBuildAndPush(t *testing.T) { 312 date, gitHash := "20220222", "a1b2c3d4" 313 314 tests := []struct { 315 name string 316 id imageDef 317 koDockerRepo string 318 push bool 319 want []string 320 wantErr bool 321 }{ 322 { 323 name: "base", 324 id: imageDef{ 325 Dir: "cmd/awesome", 326 Arch: "linux/amd64", 327 }, 328 koDockerRepo: "local.test", 329 want: []string{ 330 "publish", 331 "--tarball=_bin/awesome.tar", 332 "--push=false", 333 "--tags=latest", 334 "--tags=latest-root", 335 "--tags=20220222-a1b2c3d4", 336 "--tags=ko-20220222-a1b2c3d4", 337 "--base-import-paths", 338 "--platform=linux/amd64", 339 "./cmd/awesome", 340 }, 341 }, 342 { 343 name: "push", 344 id: imageDef{ 345 Dir: "cmd/awesome", 346 Arch: "linux/amd64", 347 }, 348 koDockerRepo: "local.test", 349 push: true, 350 want: []string{ 351 "publish", 352 "--push=true", 353 "--tags=latest", 354 "--tags=latest-root", 355 "--tags=20220222-a1b2c3d4", 356 "--tags=ko-20220222-a1b2c3d4", 357 "--base-import-paths", 358 "--platform=linux/amd64", 359 "./cmd/awesome", 360 }, 361 }, 362 { 363 name: "all", 364 id: imageDef{ 365 Dir: "cmd/awesome", 366 Arch: "all", 367 }, 368 koDockerRepo: "local.test", 369 push: true, 370 want: []string{ 371 "publish", 372 "--push=true", 373 "--tags=latest", 374 "--tags=latest-root", 375 "--tags=20220222-a1b2c3d4", 376 "--tags=ko-20220222-a1b2c3d4", 377 "--tags=latest-arm64", 378 "--tags=latest-root-arm64", 379 "--tags=20220222-a1b2c3d4-arm64", 380 "--tags=ko-20220222-a1b2c3d4-arm64", 381 "--tags=latest-s390x", 382 "--tags=latest-root-s390x", 383 "--tags=20220222-a1b2c3d4-s390x", 384 "--tags=ko-20220222-a1b2c3d4-s390x", 385 "--tags=latest-ppc64le", 386 "--tags=latest-root-ppc64le", 387 "--tags=20220222-a1b2c3d4-ppc64le", 388 "--tags=ko-20220222-a1b2c3d4-ppc64le", 389 "--base-import-paths", 390 "--platform=all", 391 "./cmd/awesome", 392 }, 393 }, 394 { 395 name: "unsupported-arch", 396 id: imageDef{ 397 Dir: "cmd/awesome", 398 Arch: "not/supported", 399 }, 400 koDockerRepo: "local.test", 401 wantErr: true, 402 }, 403 } 404 405 for _, tc := range tests { 406 tc := tc 407 t.Run(tc.name, func(t *testing.T) { 408 var gotPublishArgs []string 409 410 oldRunCmdInDirFunc := runCmdInDirFunc 411 runCmdInDirFunc = func(dir string, additionalEnv []string, cmd string, args ...string) (string, error) { 412 switch cmd { 413 case "date": 414 return date, nil 415 case "git": 416 return gitHash, nil 417 case "_bin/ko": 418 gotPublishArgs = args 419 return fmt.Sprintf("cmd: %s, args: %v", cmd, args), nil 420 default: 421 return "", errors.New("not supported command") 422 } 423 } 424 defer func() { 425 runCmdInDirFunc = oldRunCmdInDirFunc 426 }() 427 428 err := buildAndPush(&tc.id, []string{tc.koDockerRepo}, tc.push) 429 if !tc.wantErr && err != nil { 430 t.Fatalf("Expect error but got nil") 431 } 432 if tc.wantErr { 433 if err == nil { 434 t.Fatalf("Failed unexpected: %v", err) 435 } 436 return 437 } 438 439 if diff := cmp.Diff(tc.want, gotPublishArgs); diff != "" { 440 t.Fatalf("Command mismatch. Want(-), got(+):\n%s", diff) 441 } 442 }) 443 } 444 }