github.com/jaylevin/jenkins-library@v1.230.4/cmd/kanikoExecute_test.go (about) 1 package cmd 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "io/ioutil" 8 "net/http" 9 "path/filepath" 10 "strings" 11 "testing" 12 13 piperhttp "github.com/SAP/jenkins-library/pkg/http" 14 "github.com/SAP/jenkins-library/pkg/mock" 15 "github.com/SAP/jenkins-library/pkg/telemetry" 16 "github.com/stretchr/testify/assert" 17 ) 18 19 type kanikoMockClient struct { 20 httpMethod string 21 httpStatusCode int 22 urlsCalled []string 23 requestBody io.Reader 24 responseBody string 25 errorMessage string 26 } 27 28 func (c *kanikoMockClient) SetOptions(opts piperhttp.ClientOptions) {} 29 30 func (c *kanikoMockClient) SendRequest(method, url string, body io.Reader, header http.Header, cookies []*http.Cookie) (*http.Response, error) { 31 c.httpMethod = method 32 c.urlsCalled = append(c.urlsCalled, url) 33 c.requestBody = body 34 if len(c.errorMessage) > 0 { 35 return nil, fmt.Errorf(c.errorMessage) 36 } 37 return &http.Response{StatusCode: c.httpStatusCode, Body: ioutil.NopCloser(bytes.NewReader([]byte(c.responseBody)))}, nil 38 } 39 40 func TestRunKanikoExecute(t *testing.T) { 41 42 // required due to config resolution during build settings retrieval 43 // ToDo: proper mocking 44 openFileBak := configOptions.openFile 45 defer func() { 46 configOptions.openFile = openFileBak 47 }() 48 49 configOptions.openFile = configOpenFileMock 50 51 t.Run("success case", func(t *testing.T) { 52 config := &kanikoExecuteOptions{ 53 BuildOptions: []string{"--skip-tls-verify-pull"}, 54 ContainerImage: "myImage:tag", 55 ContainerPreparationCommand: "rm -f /kaniko/.docker/config.json", 56 CustomTLSCertificateLinks: []string{"https://test.url/cert.crt"}, 57 DockerfilePath: "Dockerfile", 58 DockerConfigJSON: "path/to/docker/config.json", 59 BuildSettingsInfo: `{"mavenExecuteBuild":[{"dockerImage":"maven"}]}`, 60 } 61 62 runner := &mock.ExecMockRunner{} 63 commonPipelineEnvironment := kanikoExecuteCommonPipelineEnvironment{} 64 65 certClient := &kanikoMockClient{ 66 responseBody: "testCert", 67 } 68 fileUtils := &mock.FilesMock{} 69 fileUtils.AddFile("path/to/docker/config.json", []byte(`{"auths":{"custom":"test"}}`)) 70 fileUtils.AddFile("/kaniko/ssl/certs/ca-certificates.crt", []byte(``)) 71 72 err := runKanikoExecute(config, &telemetry.CustomData{}, &commonPipelineEnvironment, runner, certClient, fileUtils) 73 74 assert.NoError(t, err) 75 76 assert.Equal(t, "rm", runner.Calls[0].Exec) 77 assert.Equal(t, []string{"-f", "/kaniko/.docker/config.json"}, runner.Calls[0].Params) 78 79 assert.Equal(t, config.CustomTLSCertificateLinks, certClient.urlsCalled) 80 c, err := fileUtils.FileRead("/kaniko/.docker/config.json") 81 assert.NoError(t, err) 82 assert.Equal(t, `{"auths":{"custom":"test"}}`, string(c)) 83 84 assert.Equal(t, "/kaniko/executor", runner.Calls[1].Exec) 85 cwd, _ := fileUtils.Getwd() 86 assert.Equal(t, []string{"--dockerfile", "Dockerfile", "--context", cwd, "--skip-tls-verify-pull", "--destination", "myImage:tag"}, runner.Calls[1].Params) 87 88 assert.Contains(t, commonPipelineEnvironment.custom.buildSettingsInfo, `"mavenExecuteBuild":[{"dockerImage":"maven"}]`) 89 assert.Contains(t, commonPipelineEnvironment.custom.buildSettingsInfo, `"kanikoExecute":[{"dockerImage":"gcr.io/kaniko-project/executor:debug"}]`) 90 91 assert.Equal(t, "myImage:tag", commonPipelineEnvironment.container.imageNameTag) 92 assert.Equal(t, "https://index.docker.io", commonPipelineEnvironment.container.registryURL) 93 assert.Equal(t, []string{"myImage"}, commonPipelineEnvironment.container.imageNames) 94 assert.Equal(t, []string{"myImage:tag"}, commonPipelineEnvironment.container.imageNameTags) 95 96 assert.Equal(t, "", commonPipelineEnvironment.container.imageDigest) 97 assert.Empty(t, commonPipelineEnvironment.container.imageDigests) 98 }) 99 100 t.Run("success case - pass image digest to cpe if activated", func(t *testing.T) { 101 config := &kanikoExecuteOptions{ 102 BuildOptions: []string{"--skip-tls-verify-pull"}, 103 ContainerImage: "myImage:tag", 104 ContainerPreparationCommand: "rm -f /kaniko/.docker/config.json", 105 CustomTLSCertificateLinks: []string{"https://test.url/cert.crt"}, 106 DockerfilePath: "Dockerfile", 107 DockerConfigJSON: "path/to/docker/config.json", 108 BuildSettingsInfo: `{"mavenExecuteBuild":[{"dockerImage":"maven"}]}`, 109 ReadImageDigest: true, 110 } 111 112 runner := &mock.ExecMockRunner{} 113 commonPipelineEnvironment := kanikoExecuteCommonPipelineEnvironment{} 114 115 certClient := &kanikoMockClient{ 116 responseBody: "testCert", 117 } 118 fileUtils := &mock.FilesMock{} 119 fileUtils.AddFile("path/to/docker/config.json", []byte(`{"auths":{"custom":"test"}}`)) 120 fileUtils.AddFile("/kaniko/ssl/certs/ca-certificates.crt", []byte(``)) 121 fileUtils.AddFile("/tmp/*-kanikoExecutetest/digest.txt", []byte(`sha256:468dd1253cc9f498fc600454bb8af96d880fec3f9f737e7057692adfe9f7d5b0`)) 122 123 err := runKanikoExecute(config, &telemetry.CustomData{}, &commonPipelineEnvironment, runner, certClient, fileUtils) 124 125 assert.NoError(t, err) 126 127 assert.Equal(t, "rm", runner.Calls[0].Exec) 128 assert.Equal(t, []string{"-f", "/kaniko/.docker/config.json"}, runner.Calls[0].Params) 129 130 assert.Equal(t, config.CustomTLSCertificateLinks, certClient.urlsCalled) 131 c, err := fileUtils.FileRead("/kaniko/.docker/config.json") 132 assert.NoError(t, err) 133 assert.Equal(t, `{"auths":{"custom":"test"}}`, string(c)) 134 135 assert.Equal(t, "/kaniko/executor", runner.Calls[1].Exec) 136 cwd, _ := fileUtils.Getwd() 137 assert.Equal(t, []string{"--dockerfile", "Dockerfile", "--context", cwd, "--skip-tls-verify-pull", "--destination", "myImage:tag", "--digest-file", "/tmp/*-kanikoExecutetest/digest.txt"}, runner.Calls[1].Params) 138 139 assert.Contains(t, commonPipelineEnvironment.custom.buildSettingsInfo, `"mavenExecuteBuild":[{"dockerImage":"maven"}]`) 140 assert.Contains(t, commonPipelineEnvironment.custom.buildSettingsInfo, `"kanikoExecute":[{"dockerImage":"gcr.io/kaniko-project/executor:debug"}]`) 141 142 assert.Equal(t, "myImage:tag", commonPipelineEnvironment.container.imageNameTag) 143 assert.Equal(t, "https://index.docker.io", commonPipelineEnvironment.container.registryURL) 144 assert.Equal(t, []string{"myImage"}, commonPipelineEnvironment.container.imageNames) 145 assert.Equal(t, []string{"myImage:tag"}, commonPipelineEnvironment.container.imageNameTags) 146 147 assert.Equal(t, "sha256:468dd1253cc9f498fc600454bb8af96d880fec3f9f737e7057692adfe9f7d5b0", commonPipelineEnvironment.container.imageDigest) 148 assert.Equal(t, []string{"sha256:468dd1253cc9f498fc600454bb8af96d880fec3f9f737e7057692adfe9f7d5b0"}, commonPipelineEnvironment.container.imageDigests) 149 }) 150 151 t.Run("success case - image params", func(t *testing.T) { 152 config := &kanikoExecuteOptions{ 153 BuildOptions: []string{"--skip-tls-verify-pull"}, 154 ContainerImageName: "myImage", 155 ContainerImageTag: "1.2.3-a+x", 156 ContainerRegistryURL: "https://my.registry.com:50000", 157 ContainerPreparationCommand: "rm -f /kaniko/.docker/config.json", 158 CustomTLSCertificateLinks: []string{"https://test.url/cert.crt"}, 159 DockerfilePath: "Dockerfile", 160 DockerConfigJSON: "path/to/docker/config.json", 161 } 162 163 runner := &mock.ExecMockRunner{} 164 commonPipelineEnvironment := kanikoExecuteCommonPipelineEnvironment{} 165 166 certClient := &kanikoMockClient{ 167 responseBody: "testCert", 168 } 169 fileUtils := &mock.FilesMock{} 170 fileUtils.AddFile("path/to/docker/config.json", []byte(`{"auths":{"custom":"test"}}`)) 171 fileUtils.AddFile("/kaniko/ssl/certs/ca-certificates.crt", []byte(``)) 172 173 err := runKanikoExecute(config, &telemetry.CustomData{}, &commonPipelineEnvironment, runner, certClient, fileUtils) 174 175 assert.NoError(t, err) 176 177 assert.Equal(t, "rm", runner.Calls[0].Exec) 178 assert.Equal(t, []string{"-f", "/kaniko/.docker/config.json"}, runner.Calls[0].Params) 179 180 assert.Equal(t, config.CustomTLSCertificateLinks, certClient.urlsCalled) 181 c, err := fileUtils.FileRead("/kaniko/.docker/config.json") 182 assert.NoError(t, err) 183 assert.Equal(t, `{"auths":{"custom":"test"}}`, string(c)) 184 185 assert.Equal(t, "/kaniko/executor", runner.Calls[1].Exec) 186 cwd, _ := fileUtils.Getwd() 187 assert.Equal(t, []string{"--dockerfile", "Dockerfile", "--context", cwd, "--skip-tls-verify-pull", "--destination", "my.registry.com:50000/myImage:1.2.3-a-x"}, runner.Calls[1].Params) 188 189 assert.Equal(t, "myImage:1.2.3-a-x", commonPipelineEnvironment.container.imageNameTag) 190 assert.Equal(t, "https://my.registry.com:50000", commonPipelineEnvironment.container.registryURL) 191 assert.Equal(t, []string{"myImage"}, commonPipelineEnvironment.container.imageNames) 192 assert.Equal(t, []string{"myImage:1.2.3-a-x"}, commonPipelineEnvironment.container.imageNameTags) 193 194 assert.Equal(t, "", commonPipelineEnvironment.container.imageDigest) 195 assert.Empty(t, commonPipelineEnvironment.container.imageDigests) 196 }) 197 198 t.Run("success case - image params with custom destination", func(t *testing.T) { 199 config := &kanikoExecuteOptions{ 200 BuildOptions: []string{"--skip-tls-verify-pull", "--destination", "my.other.registry.com:50000/myImage:3.2.1-a-x"}, 201 ContainerPreparationCommand: "rm -f /kaniko/.docker/config.json", 202 CustomTLSCertificateLinks: []string{"https://test.url/cert.crt"}, 203 DockerfilePath: "Dockerfile", 204 DockerConfigJSON: "path/to/docker/config.json", 205 } 206 207 runner := &mock.ExecMockRunner{} 208 commonPipelineEnvironment := kanikoExecuteCommonPipelineEnvironment{} 209 210 certClient := &kanikoMockClient{ 211 responseBody: "testCert", 212 } 213 fileUtils := &mock.FilesMock{} 214 fileUtils.AddFile("path/to/docker/config.json", []byte(`{"auths":{"custom":"test"}}`)) 215 fileUtils.AddFile("/kaniko/ssl/certs/ca-certificates.crt", []byte(``)) 216 217 err := runKanikoExecute(config, &telemetry.CustomData{}, &commonPipelineEnvironment, runner, certClient, fileUtils) 218 219 assert.NoError(t, err) 220 221 assert.Equal(t, "rm", runner.Calls[0].Exec) 222 assert.Equal(t, []string{"-f", "/kaniko/.docker/config.json"}, runner.Calls[0].Params) 223 224 assert.Equal(t, config.CustomTLSCertificateLinks, certClient.urlsCalled) 225 c, err := fileUtils.FileRead("/kaniko/.docker/config.json") 226 assert.NoError(t, err) 227 assert.Equal(t, `{"auths":{"custom":"test"}}`, string(c)) 228 229 assert.Equal(t, "/kaniko/executor", runner.Calls[1].Exec) 230 cwd, _ := fileUtils.Getwd() 231 assert.Equal(t, []string{"--dockerfile", "Dockerfile", "--context", cwd, "--skip-tls-verify-pull", "--destination", "my.other.registry.com:50000/myImage:3.2.1-a-x"}, runner.Calls[1].Params) 232 233 assert.Equal(t, "myImage:3.2.1-a-x", commonPipelineEnvironment.container.imageNameTag) 234 assert.Equal(t, "https://my.other.registry.com:50000", commonPipelineEnvironment.container.registryURL) 235 assert.Equal(t, []string{"myImage"}, commonPipelineEnvironment.container.imageNames) 236 assert.Equal(t, []string{"myImage:3.2.1-a-x"}, commonPipelineEnvironment.container.imageNameTags) 237 238 assert.Equal(t, "", commonPipelineEnvironment.container.imageDigest) 239 assert.Empty(t, []string{}, commonPipelineEnvironment.container.imageDigests) 240 }) 241 242 t.Run("no error case - when cert update skipped", func(t *testing.T) { 243 config := &kanikoExecuteOptions{ 244 BuildOptions: []string{"--skip-tls-verify-pull"}, 245 ContainerImageName: "myImage", 246 ContainerImageTag: "1.2.3-a+x", 247 ContainerRegistryURL: "https://my.registry.com:50000", 248 ContainerPreparationCommand: "rm -f /kaniko/.docker/config.json", 249 CustomTLSCertificateLinks: []string{}, 250 DockerfilePath: "Dockerfile", 251 DockerConfigJSON: "path/to/docker/config.json", 252 } 253 254 runner := &mock.ExecMockRunner{} 255 commonPipelineEnvironment := kanikoExecuteCommonPipelineEnvironment{} 256 257 certClient := &kanikoMockClient{} 258 fileUtils := &mock.FilesMock{} 259 fileUtils.AddFile("path/to/docker/config.json", []byte(``)) 260 fileUtils.FileReadErrors = map[string]error{"/kaniko/ssl/certs/ca-certificates.crt": fmt.Errorf("read error")} 261 262 err := runKanikoExecute(config, &telemetry.CustomData{}, &commonPipelineEnvironment, runner, certClient, fileUtils) 263 264 assert.NoErrorf(t, err, "failed to update certificates: failed to load file '/kaniko/ssl/certs/ca-certificates.crt': read error") 265 }) 266 267 t.Run("success case - no push, no docker config.json", func(t *testing.T) { 268 config := &kanikoExecuteOptions{ 269 ContainerBuildOptions: "--skip-tls-verify-pull", 270 ContainerPreparationCommand: "rm -f /kaniko/.docker/config.json", 271 CustomTLSCertificateLinks: []string{"https://test.url/cert.crt"}, 272 DockerfilePath: "Dockerfile", 273 } 274 275 runner := &mock.ExecMockRunner{} 276 commonPipelineEnvironment := kanikoExecuteCommonPipelineEnvironment{} 277 278 certClient := &kanikoMockClient{ 279 responseBody: "testCert", 280 } 281 fileUtils := &mock.FilesMock{} 282 fileUtils.AddFile("/kaniko/ssl/certs/ca-certificates.crt", []byte(``)) 283 284 err := runKanikoExecute(config, &telemetry.CustomData{}, &commonPipelineEnvironment, runner, certClient, fileUtils) 285 286 assert.NoError(t, err) 287 288 c, err := fileUtils.FileRead("/kaniko/.docker/config.json") 289 assert.NoError(t, err) 290 assert.Equal(t, `{"auths":{}}`, string(c)) 291 292 cwd, _ := fileUtils.Getwd() 293 assert.Equal(t, []string{"--dockerfile", "Dockerfile", "--context", cwd, "--skip-tls-verify-pull", "--no-push"}, runner.Calls[1].Params) 294 }) 295 296 t.Run("success case - backward compatibility", func(t *testing.T) { 297 config := &kanikoExecuteOptions{ 298 ContainerBuildOptions: "--skip-tls-verify-pull", 299 ContainerImage: "myImage:tag", 300 ContainerPreparationCommand: "rm -f /kaniko/.docker/config.json", 301 CustomTLSCertificateLinks: []string{"https://test.url/cert.crt"}, 302 DockerfilePath: "Dockerfile", 303 DockerConfigJSON: "path/to/docker/config.json", 304 } 305 306 runner := &mock.ExecMockRunner{} 307 commonPipelineEnvironment := kanikoExecuteCommonPipelineEnvironment{} 308 309 certClient := &kanikoMockClient{ 310 responseBody: "testCert", 311 } 312 fileUtils := &mock.FilesMock{} 313 fileUtils.AddFile("path/to/docker/config.json", []byte(`{"auths":{"custom":"test"}}`)) 314 fileUtils.AddFile("/kaniko/ssl/certs/ca-certificates.crt", []byte(``)) 315 316 err := runKanikoExecute(config, &telemetry.CustomData{}, &commonPipelineEnvironment, runner, certClient, fileUtils) 317 318 assert.NoError(t, err) 319 cwd, _ := fileUtils.Getwd() 320 assert.Equal(t, []string{"--dockerfile", "Dockerfile", "--context", cwd, "--skip-tls-verify-pull", "--destination", "myImage:tag"}, runner.Calls[1].Params) 321 }) 322 323 t.Run("success case - multi image build with root image", func(t *testing.T) { 324 config := &kanikoExecuteOptions{ 325 ContainerImageName: "myImage", 326 ContainerImageTag: "myTag", 327 ContainerRegistryURL: "https://my.registry.com:50000", 328 ContainerMultiImageBuild: true, 329 } 330 331 runner := &mock.ExecMockRunner{} 332 commonPipelineEnvironment := kanikoExecuteCommonPipelineEnvironment{} 333 334 fileUtils := &mock.FilesMock{} 335 fileUtils.AddFile("Dockerfile", []byte("some content")) 336 fileUtils.AddFile("sub1/Dockerfile", []byte("some content")) 337 fileUtils.AddFile("sub2/Dockerfile", []byte("some content")) 338 339 err := runKanikoExecute(config, &telemetry.CustomData{}, &commonPipelineEnvironment, runner, nil, fileUtils) 340 341 assert.NoError(t, err) 342 343 assert.Equal(t, 3, len(runner.Calls)) 344 assert.Equal(t, "/kaniko/executor", runner.Calls[0].Exec) 345 assert.Equal(t, "/kaniko/executor", runner.Calls[1].Exec) 346 assert.Equal(t, "/kaniko/executor", runner.Calls[2].Exec) 347 348 cwd, _ := fileUtils.Getwd() 349 expectedParams := [][]string{ 350 {"--dockerfile", "Dockerfile", "--context", cwd, "--destination", "my.registry.com:50000/myImage:myTag"}, 351 {"--dockerfile", filepath.Join("sub1", "Dockerfile"), "--context", cwd, "--destination", "my.registry.com:50000/myImage-sub1:myTag"}, 352 {"--dockerfile", filepath.Join("sub2", "Dockerfile"), "--context", cwd, "--destination", "my.registry.com:50000/myImage-sub2:myTag"}, 353 } 354 // need to go this way since we cannot count on the correct order 355 for _, call := range runner.Calls { 356 found := false 357 for _, expected := range expectedParams { 358 if strings.Join(call.Params, " ") == strings.Join(expected, " ") { 359 found = true 360 break 361 } 362 } 363 assert.True(t, found, fmt.Sprintf("%v not found", call.Params)) 364 } 365 366 assert.Equal(t, "https://my.registry.com:50000", commonPipelineEnvironment.container.registryURL) 367 assert.Equal(t, "myImage:myTag", commonPipelineEnvironment.container.imageNameTag) 368 assert.Contains(t, commonPipelineEnvironment.container.imageNames, "myImage") 369 assert.Contains(t, commonPipelineEnvironment.container.imageNames, "myImage-sub1") 370 assert.Contains(t, commonPipelineEnvironment.container.imageNames, "myImage-sub2") 371 assert.Contains(t, commonPipelineEnvironment.container.imageNameTags, "myImage:myTag") 372 assert.Contains(t, commonPipelineEnvironment.container.imageNameTags, "myImage-sub1:myTag") 373 assert.Contains(t, commonPipelineEnvironment.container.imageNameTags, "myImage-sub2:myTag") 374 375 assert.Equal(t, "", commonPipelineEnvironment.container.imageDigest) 376 assert.Empty(t, commonPipelineEnvironment.container.imageDigests) 377 }) 378 379 t.Run("success case - multi image build excluding root image", func(t *testing.T) { 380 config := &kanikoExecuteOptions{ 381 ContainerImageName: "myImage", 382 ContainerImageTag: "myTag", 383 ContainerRegistryURL: "https://my.registry.com:50000", 384 ContainerMultiImageBuild: true, 385 ContainerMultiImageBuildExcludes: []string{"Dockerfile"}, 386 } 387 388 runner := &mock.ExecMockRunner{} 389 commonPipelineEnvironment := kanikoExecuteCommonPipelineEnvironment{} 390 391 fileUtils := &mock.FilesMock{} 392 fileUtils.AddFile("Dockerfile", []byte("some content")) 393 fileUtils.AddFile("sub1/Dockerfile", []byte("some content")) 394 fileUtils.AddFile("sub2/Dockerfile", []byte("some content")) 395 396 err := runKanikoExecute(config, &telemetry.CustomData{}, &commonPipelineEnvironment, runner, nil, fileUtils) 397 398 assert.NoError(t, err) 399 400 assert.Equal(t, 2, len(runner.Calls)) 401 assert.Equal(t, "/kaniko/executor", runner.Calls[0].Exec) 402 assert.Equal(t, "/kaniko/executor", runner.Calls[1].Exec) 403 404 cwd, _ := fileUtils.Getwd() 405 expectedParams := [][]string{ 406 {"--dockerfile", filepath.Join("sub1", "Dockerfile"), "--context", cwd, "--destination", "my.registry.com:50000/myImage-sub1:myTag"}, 407 {"--dockerfile", filepath.Join("sub2", "Dockerfile"), "--context", cwd, "--destination", "my.registry.com:50000/myImage-sub2:myTag"}, 408 } 409 // need to go this way since we cannot count on the correct order 410 for _, call := range runner.Calls { 411 found := false 412 for _, expected := range expectedParams { 413 if strings.Join(call.Params, " ") == strings.Join(expected, " ") { 414 found = true 415 break 416 } 417 } 418 assert.True(t, found, fmt.Sprintf("%v not found", call.Params)) 419 } 420 421 assert.Equal(t, "https://my.registry.com:50000", commonPipelineEnvironment.container.registryURL) 422 assert.Equal(t, "", commonPipelineEnvironment.container.imageNameTag) 423 assert.Contains(t, commonPipelineEnvironment.container.imageNames, "myImage-sub1") 424 assert.Contains(t, commonPipelineEnvironment.container.imageNames, "myImage-sub2") 425 assert.Contains(t, commonPipelineEnvironment.container.imageNameTags, "myImage-sub1:myTag") 426 assert.Contains(t, commonPipelineEnvironment.container.imageNameTags, "myImage-sub2:myTag") 427 }) 428 429 t.Run("error case - multi image build: no docker files", func(t *testing.T) { 430 config := &kanikoExecuteOptions{ 431 ContainerImageName: "myImage", 432 ContainerImageTag: "myTag", 433 ContainerRegistryURL: "https://my.registry.com:50000", 434 ContainerMultiImageBuild: true, 435 } 436 437 cpe := kanikoExecuteCommonPipelineEnvironment{} 438 runner := &mock.ExecMockRunner{} 439 440 fileUtils := &mock.FilesMock{} 441 442 err := runKanikoExecute(config, &telemetry.CustomData{}, &cpe, runner, nil, fileUtils) 443 444 assert.Error(t, err) 445 assert.Contains(t, fmt.Sprint(err), "failed to identify image list for multi image build") 446 }) 447 448 t.Run("error case - multi image build: no docker files to process", func(t *testing.T) { 449 config := &kanikoExecuteOptions{ 450 ContainerImageName: "myImage", 451 ContainerImageTag: "myTag", 452 ContainerRegistryURL: "https://my.registry.com:50000", 453 ContainerMultiImageBuild: true, 454 ContainerMultiImageBuildExcludes: []string{"Dockerfile"}, 455 } 456 457 cpe := kanikoExecuteCommonPipelineEnvironment{} 458 runner := &mock.ExecMockRunner{} 459 460 fileUtils := &mock.FilesMock{} 461 fileUtils.AddFile("Dockerfile", []byte("some content")) 462 463 err := runKanikoExecute(config, &telemetry.CustomData{}, &cpe, runner, nil, fileUtils) 464 465 assert.Error(t, err) 466 assert.Contains(t, fmt.Sprint(err), "no docker files to process, please check exclude list") 467 }) 468 469 t.Run("error case - multi image build: build failed", func(t *testing.T) { 470 config := &kanikoExecuteOptions{ 471 ContainerImageName: "myImage", 472 ContainerImageTag: "myTag", 473 ContainerRegistryURL: "https://my.registry.com:50000", 474 ContainerMultiImageBuild: true, 475 } 476 477 cpe := kanikoExecuteCommonPipelineEnvironment{} 478 runner := &mock.ExecMockRunner{} 479 runner.ShouldFailOnCommand = map[string]error{"/kaniko/executor": fmt.Errorf("execution failed")} 480 481 fileUtils := &mock.FilesMock{} 482 fileUtils.AddFile("Dockerfile", []byte("some content")) 483 484 err := runKanikoExecute(config, &telemetry.CustomData{}, &cpe, runner, nil, fileUtils) 485 486 assert.Error(t, err) 487 assert.Contains(t, fmt.Sprint(err), "failed to build image") 488 }) 489 490 t.Run("error case - Kaniko init failed", func(t *testing.T) { 491 config := &kanikoExecuteOptions{ 492 ContainerPreparationCommand: "rm -f /kaniko/.docker/config.json", 493 } 494 495 runner := &mock.ExecMockRunner{ 496 ShouldFailOnCommand: map[string]error{"rm": fmt.Errorf("rm failed")}, 497 } 498 commonPipelineEnvironment := kanikoExecuteCommonPipelineEnvironment{} 499 500 certClient := &kanikoMockClient{} 501 fileUtils := &mock.FilesMock{} 502 503 err := runKanikoExecute(config, &telemetry.CustomData{}, &commonPipelineEnvironment, runner, certClient, fileUtils) 504 505 assert.EqualError(t, err, "failed to initialize Kaniko container: rm failed") 506 }) 507 508 t.Run("error case - Kaniko execution failed", func(t *testing.T) { 509 config := &kanikoExecuteOptions{} 510 511 runner := &mock.ExecMockRunner{ 512 ShouldFailOnCommand: map[string]error{"/kaniko/executor": fmt.Errorf("kaniko run failed")}, 513 } 514 commonPipelineEnvironment := kanikoExecuteCommonPipelineEnvironment{} 515 516 certClient := &kanikoMockClient{} 517 fileUtils := &mock.FilesMock{} 518 519 err := runKanikoExecute(config, &telemetry.CustomData{}, &commonPipelineEnvironment, runner, certClient, fileUtils) 520 521 assert.EqualError(t, err, "execution of '/kaniko/executor' failed: kaniko run failed") 522 }) 523 524 t.Run("error case - cert update failed", func(t *testing.T) { 525 config := &kanikoExecuteOptions{ 526 BuildOptions: []string{"--skip-tls-verify-pull"}, 527 ContainerImageName: "myImage", 528 ContainerImageTag: "1.2.3-a+x", 529 ContainerRegistryURL: "https://my.registry.com:50000", 530 ContainerPreparationCommand: "rm -f /kaniko/.docker/config.json", 531 CustomTLSCertificateLinks: []string{"https://test.url/cert.crt"}, 532 DockerfilePath: "Dockerfile", 533 DockerConfigJSON: "path/to/docker/config.json", 534 } 535 536 runner := &mock.ExecMockRunner{} 537 commonPipelineEnvironment := kanikoExecuteCommonPipelineEnvironment{} 538 539 certClient := &kanikoMockClient{} 540 fileUtils := &mock.FilesMock{} 541 fileUtils.FileReadErrors = map[string]error{"/kaniko/ssl/certs/ca-certificates.crt": fmt.Errorf("read error")} 542 543 err := runKanikoExecute(config, &telemetry.CustomData{}, &commonPipelineEnvironment, runner, certClient, fileUtils) 544 545 assert.EqualError(t, err, "failed to update certificates: failed to load file '/kaniko/ssl/certs/ca-certificates.crt': read error") 546 }) 547 548 t.Run("error case - dockerconfig read failed", func(t *testing.T) { 549 config := &kanikoExecuteOptions{ 550 DockerConfigJSON: "path/to/docker/config.json", 551 } 552 553 runner := &mock.ExecMockRunner{} 554 commonPipelineEnvironment := kanikoExecuteCommonPipelineEnvironment{} 555 556 certClient := &kanikoMockClient{} 557 fileUtils := &mock.FilesMock{} 558 fileUtils.FileReadErrors = map[string]error{"path/to/docker/config.json": fmt.Errorf("read error")} 559 560 err := runKanikoExecute(config, &telemetry.CustomData{}, &commonPipelineEnvironment, runner, certClient, fileUtils) 561 562 assert.EqualError(t, err, "failed to read file 'path/to/docker/config.json': read error") 563 }) 564 565 t.Run("error case - dockerconfig write failed", func(t *testing.T) { 566 config := &kanikoExecuteOptions{ 567 DockerConfigJSON: "path/to/docker/config.json", 568 } 569 570 runner := &mock.ExecMockRunner{} 571 commonPipelineEnvironment := kanikoExecuteCommonPipelineEnvironment{} 572 573 certClient := &kanikoMockClient{} 574 fileUtils := &mock.FilesMock{} 575 fileUtils.AddFile("path/to/docker/config.json", []byte(`{"auths":{"custom":"test"}}`)) 576 fileUtils.FileWriteErrors = map[string]error{"/kaniko/.docker/config.json": fmt.Errorf("write error")} 577 578 err := runKanikoExecute(config, &telemetry.CustomData{}, &commonPipelineEnvironment, runner, certClient, fileUtils) 579 580 assert.EqualError(t, err, "failed to write file '/kaniko/.docker/config.json': write error") 581 }) 582 583 }