github.com/xgoffin/jenkins-library@v1.154.0/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  }