github.com/xgoffin/jenkins-library@v1.154.0/cmd/gitopsUpdateDeployment_test.go (about)

     1  package cmd
     2  
     3  import (
     4  	"errors"
     5  	"github.com/SAP/jenkins-library/pkg/piperutils"
     6  	"github.com/go-git/go-git/v5"
     7  	"github.com/go-git/go-git/v5/plumbing"
     8  	"github.com/stretchr/testify/assert"
     9  	"io"
    10  	"os"
    11  	"path/filepath"
    12  	"strings"
    13  	"testing"
    14  )
    15  
    16  func TestBuildRegistryPlusImage(t *testing.T) {
    17  	t.Parallel()
    18  	t.Run("build full image", func(t *testing.T) {
    19  		t.Parallel()
    20  		registryImage, err := buildRegistryPlusImage(&gitopsUpdateDeploymentOptions{
    21  			ContainerRegistryURL:  "https://myregistry.com/registry/containers",
    22  			ContainerImageNameTag: "myFancyContainer:1337",
    23  		})
    24  		assert.NoError(t, err)
    25  		assert.Equal(t, "myregistry.com/myFancyContainer:1337", registryImage)
    26  	})
    27  
    28  	t.Run("without registry", func(t *testing.T) {
    29  		t.Parallel()
    30  		registryImage, err := buildRegistryPlusImage(&gitopsUpdateDeploymentOptions{
    31  			ContainerRegistryURL:  "",
    32  			ContainerImageNameTag: "myFancyContainer:1337",
    33  		})
    34  		assert.NoError(t, err)
    35  		assert.Equal(t, "myFancyContainer:1337", registryImage)
    36  	})
    37  	t.Run("without faulty URL", func(t *testing.T) {
    38  		t.Parallel()
    39  		_, err := buildRegistryPlusImage(&gitopsUpdateDeploymentOptions{
    40  			ContainerRegistryURL:  "//myregistry.com/registry/containers",
    41  			ContainerImageNameTag: "myFancyContainer:1337",
    42  		})
    43  		assert.EqualError(t, err, "registry URL could not be extracted: invalid registry url")
    44  	})
    45  }
    46  
    47  func TestBuildRegistryPlusImageWithoutTag(t *testing.T) {
    48  	t.Parallel()
    49  	t.Run("build full image", func(t *testing.T) {
    50  		t.Parallel()
    51  		registryImage, tag, err := buildRegistryPlusImageAndTagSeparately(&gitopsUpdateDeploymentOptions{
    52  			ContainerRegistryURL:  "https://myregistry.com/registry/containers",
    53  			ContainerImageNameTag: "myFancyContainer:1337",
    54  		})
    55  		assert.NoError(t, err)
    56  		assert.Equal(t, "myregistry.com/myFancyContainer", registryImage)
    57  		assert.Equal(t, "1337", tag)
    58  	})
    59  
    60  	t.Run("without registry", func(t *testing.T) {
    61  		t.Parallel()
    62  		registryImage, tag, err := buildRegistryPlusImageAndTagSeparately(&gitopsUpdateDeploymentOptions{
    63  			ContainerRegistryURL:  "",
    64  			ContainerImageNameTag: "myFancyContainer:1337",
    65  		})
    66  		assert.NoError(t, err)
    67  		assert.Equal(t, "myFancyContainer", registryImage)
    68  		assert.Equal(t, "1337", tag)
    69  	})
    70  	t.Run("without faulty URL", func(t *testing.T) {
    71  		t.Parallel()
    72  		_, _, err := buildRegistryPlusImageAndTagSeparately(&gitopsUpdateDeploymentOptions{
    73  			ContainerRegistryURL:  "//myregistry.com/registry/containers",
    74  			ContainerImageNameTag: "myFancyContainer:1337",
    75  		})
    76  		assert.EqualError(t, err, "registry URL could not be extracted: invalid registry url")
    77  	})
    78  }
    79  
    80  func TestRunGitopsUpdateDeploymentWithKubectl(t *testing.T) {
    81  	var validConfiguration = &gitopsUpdateDeploymentOptions{
    82  		BranchName:            "main",
    83  		CommitMessage:         "This is the commit message",
    84  		ServerURL:             "https://github.com",
    85  		Username:              "admin3",
    86  		Password:              "validAccessToken",
    87  		FilePath:              "dir1/dir2/depl.yaml",
    88  		ContainerName:         "myContainer",
    89  		ContainerRegistryURL:  "https://myregistry.com/registry/containers",
    90  		ContainerImageNameTag: "myFancyContainer:1337",
    91  		Tool:                  "kubectl",
    92  	}
    93  
    94  	t.Parallel()
    95  	t.Run("successful run", func(t *testing.T) {
    96  		t.Parallel()
    97  		gitUtilsMock := &gitUtilsMock{}
    98  		runnerMock := &gitOpsExecRunnerMock{}
    99  		runnerMock.expectedYaml = expectedYaml
   100  
   101  		err := runGitopsUpdateDeployment(validConfiguration, runnerMock, gitUtilsMock, &filesMock{})
   102  		assert.NoError(t, err)
   103  		assert.Equal(t, validConfiguration.BranchName, gitUtilsMock.changedBranch)
   104  		assert.Len(t, gitUtilsMock.savedFiles, 1)
   105  		assert.Equal(t, expectedYaml, gitUtilsMock.savedFiles[0])
   106  		assert.Equal(t, "This is the commit message", gitUtilsMock.commitMessage)
   107  		assert.Equal(t, "kubectl", runnerMock.executable)
   108  		assert.Equal(t, "patch", runnerMock.params[0])
   109  		assert.Equal(t, "--local", runnerMock.params[1])
   110  		assert.Equal(t, "--output=yaml", runnerMock.params[2])
   111  		assert.Equal(t, `--patch={"spec":{"template":{"spec":{"containers":[{"name":"myContainer","image":"myregistry.com/myFancyContainer:1337"}]}}}}`, runnerMock.params[3])
   112  		assert.True(t, strings.Contains(runnerMock.params[4], filepath.Join("dir1/dir2/depl.yaml")))
   113  	})
   114  
   115  	t.Run("default commit message", func(t *testing.T) {
   116  		t.Parallel()
   117  		var configuration = *validConfiguration
   118  		configuration.CommitMessage = ""
   119  
   120  		gitUtilsMock := &gitUtilsMock{}
   121  		runnerMock := &gitOpsExecRunnerMock{}
   122  		runnerMock.expectedYaml = expectedYaml
   123  
   124  		err := runGitopsUpdateDeployment(&configuration, runnerMock, gitUtilsMock, &filesMock{})
   125  		assert.NoError(t, err)
   126  		assert.Equal(t, validConfiguration.BranchName, gitUtilsMock.changedBranch)
   127  		assert.Len(t, gitUtilsMock.savedFiles, 1)
   128  		assert.Equal(t, expectedYaml, gitUtilsMock.savedFiles[0])
   129  		assert.Equal(t, "Updated myregistry.com/myFancyContainer to version 1337", gitUtilsMock.commitMessage)
   130  		assert.Equal(t, "kubectl", runnerMock.executable)
   131  		assert.Equal(t, "patch", runnerMock.params[0])
   132  		assert.Equal(t, "--local", runnerMock.params[1])
   133  		assert.Equal(t, "--output=yaml", runnerMock.params[2])
   134  		assert.Equal(t, `--patch={"spec":{"template":{"spec":{"containers":[{"name":"myContainer","image":"myregistry.com/myFancyContainer:1337"}]}}}}`, runnerMock.params[3])
   135  		assert.True(t, strings.Contains(runnerMock.params[4], filepath.Join("dir1/dir2/depl.yaml")))
   136  	})
   137  
   138  	t.Run("ChartPath not used for kubectl", func(t *testing.T) {
   139  		t.Parallel()
   140  		var configuration = *validConfiguration
   141  		configuration.ChartPath = "chartPath"
   142  
   143  		gitUtilsMock := &gitUtilsMock{}
   144  		runnerMock := &gitOpsExecRunnerMock{}
   145  		runnerMock.expectedYaml = expectedYaml
   146  
   147  		err := runGitopsUpdateDeployment(&configuration, runnerMock, gitUtilsMock, &filesMock{})
   148  		assert.NoError(t, err)
   149  		assert.Equal(t, configuration.BranchName, gitUtilsMock.changedBranch)
   150  		assert.Len(t, gitUtilsMock.savedFiles, 1)
   151  		assert.Equal(t, expectedYaml, gitUtilsMock.savedFiles[0])
   152  		assert.Equal(t, "kubectl", runnerMock.executable)
   153  		assert.Equal(t, "patch", runnerMock.params[0])
   154  		assert.Equal(t, "--local", runnerMock.params[1])
   155  		assert.Equal(t, "--output=yaml", runnerMock.params[2])
   156  		assert.Equal(t, `--patch={"spec":{"template":{"spec":{"containers":[{"name":"myContainer","image":"myregistry.com/myFancyContainer:1337"}]}}}}`, runnerMock.params[3])
   157  		assert.True(t, strings.Contains(runnerMock.params[4], filepath.Join("dir1/dir2/depl.yaml")))
   158  	})
   159  
   160  	t.Run("HelmValues not used for kubectl", func(t *testing.T) {
   161  		t.Parallel()
   162  		var configuration = *validConfiguration
   163  		configuration.HelmValues = []string{"HelmValues"}
   164  
   165  		gitUtilsMock := &gitUtilsMock{}
   166  		runnerMock := &gitOpsExecRunnerMock{}
   167  		runnerMock.expectedYaml = expectedYaml
   168  
   169  		err := runGitopsUpdateDeployment(&configuration, runnerMock, gitUtilsMock, &filesMock{})
   170  		assert.NoError(t, err)
   171  		assert.Equal(t, configuration.BranchName, gitUtilsMock.changedBranch)
   172  		assert.Len(t, gitUtilsMock.savedFiles, 1)
   173  		assert.Equal(t, expectedYaml, gitUtilsMock.savedFiles[0])
   174  		assert.Equal(t, "kubectl", runnerMock.executable)
   175  		assert.Equal(t, "patch", runnerMock.params[0])
   176  		assert.Equal(t, "--local", runnerMock.params[1])
   177  		assert.Equal(t, "--output=yaml", runnerMock.params[2])
   178  		assert.Equal(t, `--patch={"spec":{"template":{"spec":{"containers":[{"name":"myContainer","image":"myregistry.com/myFancyContainer:1337"}]}}}}`, runnerMock.params[3])
   179  		assert.True(t, strings.Contains(runnerMock.params[4], filepath.Join("dir1/dir2/depl.yaml")))
   180  	})
   181  
   182  	t.Run("DeploymentName not used for kubectl", func(t *testing.T) {
   183  		t.Parallel()
   184  		var configuration = *validConfiguration
   185  		configuration.DeploymentName = "DeploymentName"
   186  
   187  		gitUtilsMock := &gitUtilsMock{}
   188  		runnerMock := &gitOpsExecRunnerMock{}
   189  		runnerMock.expectedYaml = expectedYaml
   190  
   191  		err := runGitopsUpdateDeployment(&configuration, runnerMock, gitUtilsMock, &filesMock{})
   192  		assert.NoError(t, err)
   193  		assert.Equal(t, configuration.BranchName, gitUtilsMock.changedBranch)
   194  		assert.Len(t, gitUtilsMock.savedFiles, 1)
   195  		assert.Equal(t, expectedYaml, gitUtilsMock.savedFiles[0])
   196  		assert.Equal(t, "kubectl", runnerMock.executable)
   197  		assert.Equal(t, "patch", runnerMock.params[0])
   198  		assert.Equal(t, "--local", runnerMock.params[1])
   199  		assert.Equal(t, "--output=yaml", runnerMock.params[2])
   200  		assert.Equal(t, `--patch={"spec":{"template":{"spec":{"containers":[{"name":"myContainer","image":"myregistry.com/myFancyContainer:1337"}]}}}}`, runnerMock.params[3])
   201  		assert.True(t, strings.Contains(runnerMock.params[4], filepath.Join("dir1/dir2/depl.yaml")))
   202  	})
   203  	t.Run("successful run with glob", func(t *testing.T) {
   204  		t.Parallel()
   205  		gitUtilsMock := &gitUtilsMock{}
   206  		runnerMock := &gitOpsExecRunnerMock{}
   207  		fsMock := &filesMock{}
   208  		runnerMock.expectedYaml = expectedYaml
   209  		var configuration = *validConfiguration
   210  		configuration.FilePath = "glob/kubectl/**/*.yaml"
   211  
   212  		err := runGitopsUpdateDeployment(&configuration, runnerMock, gitUtilsMock, fsMock)
   213  		assert.NoError(t, err)
   214  		assert.Equal(t, validConfiguration.BranchName, gitUtilsMock.changedBranch)
   215  		assert.Len(t, gitUtilsMock.savedFiles, 2)
   216  		assert.Equal(t, expectedYaml, gitUtilsMock.savedFiles[0])
   217  		assert.Equal(t, expectedYaml, gitUtilsMock.savedFiles[1])
   218  
   219  		assert.Equal(t, "kubectl", runnerMock.executable)
   220  		assert.Equal(t, "patch", runnerMock.params[0])
   221  		assert.Equal(t, "--local", runnerMock.params[1])
   222  		assert.Equal(t, "--output=yaml", runnerMock.params[2])
   223  		assert.Equal(t, `--patch={"spec":{"template":{"spec":{"containers":[{"name":"myContainer","image":"myregistry.com/myFancyContainer:1337"}]}}}}`, runnerMock.params[3])
   224  		assert.True(t, strings.Contains(runnerMock.params[4], filepath.Join("glob/kubectl/dir1/depl.yaml")))
   225  
   226  		assert.Equal(t, "patch", runnerMock.params[5])
   227  		assert.Equal(t, "--local", runnerMock.params[6])
   228  		assert.Equal(t, "--output=yaml", runnerMock.params[7])
   229  		assert.Equal(t, `--patch={"spec":{"template":{"spec":{"containers":[{"name":"myContainer","image":"myregistry.com/myFancyContainer:1337"}]}}}}`, runnerMock.params[8])
   230  		assert.True(t, strings.Contains(runnerMock.params[9], filepath.Join("glob/kubectl/dir2/depl.yaml")))
   231  	})
   232  
   233  	t.Run("missing ContainerName", func(t *testing.T) {
   234  		t.Parallel()
   235  		var configuration = *validConfiguration
   236  		configuration.ContainerName = ""
   237  
   238  		gitUtilsMock := &gitUtilsMock{}
   239  		runnerMock := &gitOpsExecRunnerMock{}
   240  
   241  		err := runGitopsUpdateDeployment(&configuration, runnerMock, gitUtilsMock, &filesMock{})
   242  		assert.EqualError(t, err, "missing required fields for kubectl: the following parameters are necessary for kubectl: [containerName]")
   243  	})
   244  
   245  	t.Run("error on kubectl execution", func(t *testing.T) {
   246  		t.Parallel()
   247  		runner := &gitOpsExecRunnerMock{failOnRunExecutable: true}
   248  
   249  		err := runGitopsUpdateDeployment(validConfiguration, runner, &gitUtilsMock{}, &filesMock{})
   250  		assert.EqualError(t, err, "error on kubectl execution: failed to apply kubectl command: failed to apply kubectl command: error happened")
   251  	})
   252  
   253  	t.Run("invalid URL", func(t *testing.T) {
   254  		t.Parallel()
   255  		var configuration = *validConfiguration
   256  		configuration.ContainerRegistryURL = "//myregistry.com/registry/containers"
   257  
   258  		err := runGitopsUpdateDeployment(&configuration, &gitOpsExecRunnerMock{}, &gitUtilsMock{}, &filesMock{})
   259  		assert.EqualError(t, err, "error on kubectl execution: failed to apply kubectl command: registry URL could not be extracted: invalid registry url")
   260  	})
   261  
   262  	t.Run("error on plain clone", func(t *testing.T) {
   263  		t.Parallel()
   264  		gitUtils := &gitUtilsMock{failOnClone: true}
   265  
   266  		err := runGitopsUpdateDeployment(validConfiguration, &gitOpsExecRunnerMock{expectedYaml: expectedYaml}, gitUtils, &filesMock{})
   267  		assert.EqualError(t, err, "repository could not get prepared: failed to plain clone repository: error on clone")
   268  	})
   269  
   270  	t.Run("error on change branch", func(t *testing.T) {
   271  		t.Parallel()
   272  		gitUtils := &gitUtilsMock{failOnChangeBranch: true}
   273  
   274  		err := runGitopsUpdateDeployment(validConfiguration, &gitOpsExecRunnerMock{}, gitUtils, &filesMock{})
   275  		assert.EqualError(t, err, "repository could not get prepared: failed to change branch: error on change branch")
   276  	})
   277  
   278  	t.Run("error on commit changes", func(t *testing.T) {
   279  		t.Parallel()
   280  		gitUtils := &gitUtilsMock{failOnCommit: true}
   281  
   282  		err := runGitopsUpdateDeployment(validConfiguration, &gitOpsExecRunnerMock{}, gitUtils, &filesMock{})
   283  		assert.EqualError(t, err, "failed to commit and push changes: committing changes failed: error on commit")
   284  	})
   285  
   286  	t.Run("error on push commits", func(t *testing.T) {
   287  		t.Parallel()
   288  		gitUtils := &gitUtilsMock{failOnPush: true}
   289  
   290  		err := runGitopsUpdateDeployment(validConfiguration, &gitOpsExecRunnerMock{}, gitUtils, &filesMock{})
   291  		assert.EqualError(t, err, "failed to commit and push changes: pushing changes failed: error on push")
   292  	})
   293  
   294  	t.Run("error on temp dir creation", func(t *testing.T) {
   295  		t.Parallel()
   296  		fileUtils := &filesMock{failOnCreation: true}
   297  
   298  		err := runGitopsUpdateDeployment(validConfiguration, &gitOpsExecRunnerMock{}, &gitUtilsMock{}, fileUtils)
   299  		assert.EqualError(t, err, "failed to create temporary directory: error appeared")
   300  	})
   301  
   302  	t.Run("error on file write", func(t *testing.T) {
   303  		t.Parallel()
   304  		fileUtils := &filesMock{failOnWrite: true}
   305  
   306  		err := runGitopsUpdateDeployment(validConfiguration, &gitOpsExecRunnerMock{expectedYaml: expectedYaml}, &gitUtilsMock{}, fileUtils)
   307  		assert.EqualError(t, err, "failed to write file: error appeared")
   308  	})
   309  
   310  	t.Run("error on temp dir deletion", func(t *testing.T) {
   311  		t.Parallel()
   312  		fileUtils := &filesMock{failOnDeletion: true}
   313  
   314  		err := runGitopsUpdateDeployment(validConfiguration, &gitOpsExecRunnerMock{}, &gitUtilsMock{}, fileUtils)
   315  		assert.NoError(t, err)
   316  		_ = piperutils.Files{}.RemoveAll(fileUtils.path)
   317  	})
   318  }
   319  
   320  func TestRunGitopsUpdateDeploymentWithInvalid(t *testing.T) {
   321  	t.Parallel()
   322  	t.Run("invalid deploy tool is not supported", func(t *testing.T) {
   323  		var configuration = &gitopsUpdateDeploymentOptions{
   324  			BranchName:            "main",
   325  			CommitMessage:         "This is the commit message",
   326  			ServerURL:             "https://github.com",
   327  			Username:              "admin3",
   328  			Password:              "validAccessToken",
   329  			FilePath:              "dir1/dir2/depl.yaml",
   330  			ContainerName:         "myContainer",
   331  			ContainerRegistryURL:  "https://myregistry.com",
   332  			ContainerImageNameTag: "registry/containers/myFancyContainer:1337",
   333  			Tool:                  "invalid",
   334  			ChartPath:             "./helm",
   335  			DeploymentName:        "myFancyDeployment",
   336  			HelmValues:            []string{"./helm/additionalValues.yaml"},
   337  		}
   338  
   339  		err := runGitopsUpdateDeployment(configuration, &gitOpsExecRunnerMock{}, &gitUtilsMock{}, &filesMock{})
   340  		assert.EqualError(t, err, "tool invalid is not supported")
   341  	})
   342  }
   343  
   344  func TestRunGitopsUpdateDeploymentWithHelm(t *testing.T) {
   345  	var validConfiguration = &gitopsUpdateDeploymentOptions{
   346  		BranchName:            "main",
   347  		CommitMessage:         "This is the commit message",
   348  		ServerURL:             "https://github.com",
   349  		Username:              "admin3",
   350  		Password:              "validAccessToken",
   351  		FilePath:              "dir1/dir2/depl.yaml",
   352  		ContainerRegistryURL:  "https://myregistry.com",
   353  		ContainerImageNameTag: "registry/containers/myFancyContainer:1337",
   354  		Tool:                  "helm",
   355  		ChartPath:             "./helm",
   356  		DeploymentName:        "myFancyDeployment",
   357  		HelmValues:            []string{"./helm/additionalValues.yaml"},
   358  	}
   359  
   360  	t.Parallel()
   361  	t.Run("successful run", func(t *testing.T) {
   362  		t.Parallel()
   363  		gitUtilsMock := &gitUtilsMock{}
   364  		runnerMock := &gitOpsExecRunnerMock{}
   365  		runnerMock.expectedYaml = expectedYaml
   366  
   367  		err := runGitopsUpdateDeployment(validConfiguration, runnerMock, gitUtilsMock, &filesMock{})
   368  		assert.NoError(t, err)
   369  		assert.Equal(t, validConfiguration.BranchName, gitUtilsMock.changedBranch)
   370  		assert.Len(t, gitUtilsMock.savedFiles, 1)
   371  		assert.Equal(t, "---\n"+expectedYaml, gitUtilsMock.savedFiles[0])
   372  		assert.Equal(t, "This is the commit message", gitUtilsMock.commitMessage)
   373  		assert.Equal(t, "helm", runnerMock.executable)
   374  		assert.Equal(t, "template", runnerMock.params[0])
   375  		assert.Equal(t, "myFancyDeployment", runnerMock.params[1])
   376  		assert.Equal(t, filepath.Join(gitUtilsMock.temporaryDirectory, "helm"), runnerMock.params[2])
   377  		assert.Equal(t, "--set=image.repository=myregistry.com/registry/containers/myFancyContainer", runnerMock.params[3])
   378  		assert.Equal(t, "--set=image.tag=1337", runnerMock.params[4])
   379  		assert.Equal(t, "--values", runnerMock.params[5])
   380  		assert.Equal(t, "./helm/additionalValues.yaml", runnerMock.params[6])
   381  	})
   382  
   383  	t.Run("default commit message", func(t *testing.T) {
   384  		t.Parallel()
   385  		var configuration = *validConfiguration
   386  		configuration.CommitMessage = ""
   387  
   388  		gitUtilsMock := &gitUtilsMock{}
   389  		runnerMock := &gitOpsExecRunnerMock{}
   390  		runnerMock.expectedYaml = expectedYaml
   391  
   392  		err := runGitopsUpdateDeployment(&configuration, runnerMock, gitUtilsMock, &filesMock{})
   393  		assert.NoError(t, err)
   394  		assert.Equal(t, configuration.BranchName, gitUtilsMock.changedBranch)
   395  		assert.Len(t, gitUtilsMock.savedFiles, 1)
   396  		assert.Equal(t, "---\n"+expectedYaml, gitUtilsMock.savedFiles[0])
   397  		assert.Equal(t, "Updated myregistry.com/registry/containers/myFancyContainer to version 1337", gitUtilsMock.commitMessage)
   398  		assert.Equal(t, "helm", runnerMock.executable)
   399  		assert.Equal(t, "template", runnerMock.params[0])
   400  		assert.Equal(t, "myFancyDeployment", runnerMock.params[1])
   401  		assert.Equal(t, filepath.Join(gitUtilsMock.temporaryDirectory, "helm"), runnerMock.params[2])
   402  		assert.Equal(t, "--set=image.repository=myregistry.com/registry/containers/myFancyContainer", runnerMock.params[3])
   403  		assert.Equal(t, "--set=image.tag=1337", runnerMock.params[4])
   404  		assert.Equal(t, "--values", runnerMock.params[5])
   405  		assert.Equal(t, "./helm/additionalValues.yaml", runnerMock.params[6])
   406  	})
   407  
   408  	t.Run("ContainerName not used for helm", func(t *testing.T) {
   409  		t.Parallel()
   410  		var configuration = *validConfiguration
   411  		configuration.ContainerName = "containerName"
   412  
   413  		gitUtilsMock := &gitUtilsMock{}
   414  		runnerMock := &gitOpsExecRunnerMock{}
   415  		runnerMock.expectedYaml = expectedYaml
   416  
   417  		err := runGitopsUpdateDeployment(&configuration, runnerMock, gitUtilsMock, &filesMock{})
   418  		assert.NoError(t, err)
   419  		assert.Equal(t, configuration.BranchName, gitUtilsMock.changedBranch)
   420  		assert.Len(t, gitUtilsMock.savedFiles, 1)
   421  		assert.Equal(t, "---\n"+expectedYaml, gitUtilsMock.savedFiles[0])
   422  		assert.Equal(t, "helm", runnerMock.executable)
   423  		assert.Equal(t, "template", runnerMock.params[0])
   424  		assert.Equal(t, "myFancyDeployment", runnerMock.params[1])
   425  		assert.Equal(t, filepath.Join(gitUtilsMock.temporaryDirectory, "helm"), runnerMock.params[2])
   426  		assert.Equal(t, "--set=image.repository=myregistry.com/registry/containers/myFancyContainer", runnerMock.params[3])
   427  		assert.Equal(t, "--set=image.tag=1337", runnerMock.params[4])
   428  		assert.Equal(t, "--values", runnerMock.params[5])
   429  		assert.Equal(t, "./helm/additionalValues.yaml", runnerMock.params[6])
   430  	})
   431  
   432  	t.Run("HelmValues is optional", func(t *testing.T) {
   433  		t.Parallel()
   434  		var configuration = *validConfiguration
   435  		configuration.HelmValues = nil
   436  
   437  		gitUtilsMock := &gitUtilsMock{}
   438  		runnerMock := &gitOpsExecRunnerMock{}
   439  		runnerMock.expectedYaml = expectedYaml
   440  
   441  		err := runGitopsUpdateDeployment(&configuration, runnerMock, gitUtilsMock, &filesMock{})
   442  		assert.NoError(t, err)
   443  		assert.Equal(t, configuration.BranchName, gitUtilsMock.changedBranch)
   444  		assert.Len(t, gitUtilsMock.savedFiles, 1)
   445  		assert.Equal(t, "---\n"+expectedYaml, gitUtilsMock.savedFiles[0])
   446  		assert.Equal(t, "helm", runnerMock.executable)
   447  		assert.Equal(t, "template", runnerMock.params[0])
   448  		assert.Equal(t, "myFancyDeployment", runnerMock.params[1])
   449  		assert.Equal(t, filepath.Join(gitUtilsMock.temporaryDirectory, "helm"), runnerMock.params[2])
   450  		assert.Equal(t, "--set=image.repository=myregistry.com/registry/containers/myFancyContainer", runnerMock.params[3])
   451  		assert.Equal(t, "--set=image.tag=1337", runnerMock.params[4])
   452  	})
   453  	t.Run("successful run with glob", func(t *testing.T) {
   454  		t.Parallel()
   455  		gitUtilsMock := &gitUtilsMock{}
   456  		runnerMock := &gitOpsExecRunnerMock{}
   457  		fsMock := &filesMock{}
   458  		runnerMock.expectedYaml = expectedYaml
   459  		var configuration = *validConfiguration
   460  		configuration.ChartPath = "glob/helm/dir*/helm"
   461  		configuration.HelmValues = nil
   462  
   463  		err := runGitopsUpdateDeployment(&configuration, runnerMock, gitUtilsMock, fsMock)
   464  		assert.NoError(t, err)
   465  		assert.Equal(t, validConfiguration.BranchName, gitUtilsMock.changedBranch)
   466  		assert.Len(t, gitUtilsMock.savedFiles, 1)
   467  		assert.Equal(t, "---\n"+expectedYaml+"---\n"+expectedYaml, gitUtilsMock.savedFiles[0])
   468  		assert.Equal(t, "This is the commit message", gitUtilsMock.commitMessage)
   469  		assert.Equal(t, "helm", runnerMock.executable)
   470  
   471  		assert.Equal(t, "template", runnerMock.params[0])
   472  		assert.Equal(t, "myFancyDeployment", runnerMock.params[1])
   473  		assert.Equal(t, filepath.Join(gitUtilsMock.temporaryDirectory, "glob/helm/dir1/helm"), runnerMock.params[2])
   474  		assert.Equal(t, "--set=image.repository=myregistry.com/registry/containers/myFancyContainer", runnerMock.params[3])
   475  		assert.Equal(t, "--set=image.tag=1337", runnerMock.params[4])
   476  
   477  		assert.Equal(t, "template", runnerMock.params[5])
   478  		assert.Equal(t, "myFancyDeployment", runnerMock.params[6])
   479  		assert.Equal(t, filepath.Join(gitUtilsMock.temporaryDirectory, "glob/helm/dir2/helm"), runnerMock.params[7])
   480  		assert.Equal(t, "--set=image.repository=myregistry.com/registry/containers/myFancyContainer", runnerMock.params[8])
   481  		assert.Equal(t, "--set=image.tag=1337", runnerMock.params[9])
   482  	})
   483  
   484  	t.Run("erroneous URL", func(t *testing.T) {
   485  		t.Parallel()
   486  		var configuration = *validConfiguration
   487  		configuration.ContainerRegistryURL = "://myregistry.com"
   488  
   489  		err := runGitopsUpdateDeployment(&configuration, &gitOpsExecRunnerMock{}, &gitUtilsMock{}, &filesMock{})
   490  		assert.EqualError(t, err, `failed to apply helm command: failed to extract registry URL, image name, and image tag: registry URL could not be extracted: invalid registry url: parse "://myregistry.com": missing protocol scheme`)
   491  	})
   492  
   493  	t.Run("missing ChartPath", func(t *testing.T) {
   494  		t.Parallel()
   495  		var configuration = *validConfiguration
   496  		configuration.ChartPath = ""
   497  
   498  		err := runGitopsUpdateDeployment(&configuration, &gitOpsExecRunnerMock{}, &gitUtilsMock{}, &filesMock{})
   499  		assert.EqualError(t, err, "missing required fields for helm: the following parameters are necessary for helm: [chartPath]")
   500  	})
   501  
   502  	t.Run("missing DeploymentName", func(t *testing.T) {
   503  		t.Parallel()
   504  		var configuration = *validConfiguration
   505  		configuration.DeploymentName = ""
   506  
   507  		err := runGitopsUpdateDeployment(&configuration, &gitOpsExecRunnerMock{}, &gitUtilsMock{}, &filesMock{})
   508  		assert.EqualError(t, err, "missing required fields for helm: the following parameters are necessary for helm: [deploymentName]")
   509  	})
   510  
   511  	t.Run("missing DeploymentName and ChartPath", func(t *testing.T) {
   512  		t.Parallel()
   513  		var configuration = *validConfiguration
   514  		configuration.DeploymentName = ""
   515  		configuration.ChartPath = ""
   516  
   517  		err := runGitopsUpdateDeployment(&configuration, &gitOpsExecRunnerMock{}, &gitUtilsMock{}, &filesMock{})
   518  		assert.EqualError(t, err, "missing required fields for helm: the following parameters are necessary for helm: [chartPath deploymentName]")
   519  	})
   520  
   521  	t.Run("erroneous tag", func(t *testing.T) {
   522  		t.Parallel()
   523  		var configuration = *validConfiguration
   524  		configuration.ContainerImageNameTag = "registry/containers/myFancyContainer:"
   525  
   526  		err := runGitopsUpdateDeployment(&configuration, &gitOpsExecRunnerMock{}, &gitUtilsMock{}, &filesMock{})
   527  		assert.EqualError(t, err, "failed to apply helm command: failed to extract registry URL, image name, and image tag: tag could not be extracted")
   528  	})
   529  
   530  	t.Run("erroneous image name", func(t *testing.T) {
   531  		t.Parallel()
   532  		var configuration = *validConfiguration
   533  		configuration.ContainerImageNameTag = ":1.0.1"
   534  
   535  		err := runGitopsUpdateDeployment(&configuration, &gitOpsExecRunnerMock{}, &gitUtilsMock{}, &filesMock{})
   536  		assert.EqualError(t, err, "failed to apply helm command: failed to extract registry URL, image name, and image tag: image name could not be extracted")
   537  	})
   538  
   539  	t.Run("error on helm execution", func(t *testing.T) {
   540  		t.Parallel()
   541  		runner := &gitOpsExecRunnerMock{failOnRunExecutable: true}
   542  
   543  		err := runGitopsUpdateDeployment(validConfiguration, runner, &gitUtilsMock{}, &filesMock{})
   544  		assert.EqualError(t, err, "failed to apply helm command: failed to execute helm command: error happened")
   545  	})
   546  
   547  	t.Run("error on plain clone", func(t *testing.T) {
   548  		t.Parallel()
   549  		gitUtils := &gitUtilsMock{failOnClone: true}
   550  
   551  		err := runGitopsUpdateDeployment(validConfiguration, &gitOpsExecRunnerMock{}, gitUtils, &filesMock{})
   552  		assert.EqualError(t, err, "repository could not get prepared: failed to plain clone repository: error on clone")
   553  	})
   554  
   555  	t.Run("error on change branch", func(t *testing.T) {
   556  		t.Parallel()
   557  		gitUtils := &gitUtilsMock{failOnChangeBranch: true}
   558  
   559  		err := runGitopsUpdateDeployment(validConfiguration, &gitOpsExecRunnerMock{}, gitUtils, &filesMock{})
   560  		assert.EqualError(t, err, "repository could not get prepared: failed to change branch: error on change branch")
   561  	})
   562  
   563  	t.Run("error on commit changes", func(t *testing.T) {
   564  		t.Parallel()
   565  		gitUtils := &gitUtilsMock{failOnCommit: true}
   566  
   567  		err := runGitopsUpdateDeployment(validConfiguration, &gitOpsExecRunnerMock{}, gitUtils, &filesMock{})
   568  		assert.EqualError(t, err, "failed to commit and push changes: committing changes failed: error on commit")
   569  	})
   570  
   571  	t.Run("error on push commits", func(t *testing.T) {
   572  		t.Parallel()
   573  		gitUtils := &gitUtilsMock{failOnPush: true}
   574  
   575  		err := runGitopsUpdateDeployment(validConfiguration, &gitOpsExecRunnerMock{}, gitUtils, &filesMock{})
   576  		assert.EqualError(t, err, "failed to commit and push changes: pushing changes failed: error on push")
   577  	})
   578  
   579  	t.Run("error on temp dir creation", func(t *testing.T) {
   580  		t.Parallel()
   581  		fileUtils := &filesMock{failOnCreation: true}
   582  
   583  		err := runGitopsUpdateDeployment(validConfiguration, &gitOpsExecRunnerMock{}, &gitUtilsMock{}, fileUtils)
   584  		assert.EqualError(t, err, "failed to create temporary directory: error appeared")
   585  	})
   586  
   587  	t.Run("error on file write", func(t *testing.T) {
   588  		t.Parallel()
   589  		fileUtils := &filesMock{failOnWrite: true}
   590  
   591  		err := runGitopsUpdateDeployment(validConfiguration, &gitOpsExecRunnerMock{}, &gitUtilsMock{}, fileUtils)
   592  		assert.EqualError(t, err, "failed to write file: error appeared")
   593  	})
   594  
   595  	t.Run("error on temp dir deletion", func(t *testing.T) {
   596  		t.Parallel()
   597  		fileUtils := &filesMock{failOnDeletion: true}
   598  
   599  		err := runGitopsUpdateDeployment(validConfiguration, &gitOpsExecRunnerMock{}, &gitUtilsMock{}, fileUtils)
   600  		assert.NoError(t, err)
   601  		_ = piperutils.Files{}.RemoveAll(fileUtils.path)
   602  	})
   603  }
   604  
   605  func TestRunGitopsUpdateDeploymentWithKustomize(t *testing.T) {
   606  	var validConfiguration = &gitopsUpdateDeploymentOptions{
   607  		BranchName:            "main",
   608  		CommitMessage:         "This is the commit message",
   609  		ServerURL:             "https://github.com",
   610  		Username:              "admin3",
   611  		Password:              "validAccessToken",
   612  		FilePath:              "kustomization.yaml",
   613  		ContainerRegistryURL:  "https://myregistry.com",
   614  		ContainerImageNameTag: "registry/containers/myFancyContainer:1337",
   615  		Tool:                  "kustomize",
   616  		DeploymentName:        "myFancyDeployment",
   617  	}
   618  
   619  	t.Parallel()
   620  	t.Run("successful run", func(t *testing.T) {
   621  		t.Parallel()
   622  		gitUtilsMock := &gitUtilsMock{}
   623  		runnerMock := &gitOpsExecRunnerMock{}
   624  		fsMock := &filesMock{}
   625  		runnerMock.expectedYaml = expectedKustomize
   626  
   627  		err := runGitopsUpdateDeployment(validConfiguration, runnerMock, gitUtilsMock, fsMock)
   628  		assert.NoError(t, err)
   629  		assert.Equal(t, validConfiguration.BranchName, gitUtilsMock.changedBranch)
   630  		assert.Len(t, gitUtilsMock.savedFiles, 1)
   631  		assert.Equal(t, expectedKustomize, gitUtilsMock.savedFiles[0])
   632  		assert.Equal(t, "This is the commit message", gitUtilsMock.commitMessage)
   633  		assert.Equal(t, "kustomize", runnerMock.executable)
   634  		assert.Equal(t, "edit", runnerMock.params[0])
   635  		assert.Equal(t, "set", runnerMock.params[1])
   636  		assert.Equal(t, "image", runnerMock.params[2])
   637  		assert.Equal(t, "myFancyDeployment=registry/containers/myFancyContainer:1337", runnerMock.params[3])
   638  	})
   639  	t.Run("successful run with glob", func(t *testing.T) {
   640  		t.Parallel()
   641  		gitUtilsMock := &gitUtilsMock{}
   642  		runnerMock := &gitOpsExecRunnerMock{}
   643  		fsMock := &filesMock{}
   644  		runnerMock.expectedYaml = expectedKustomize
   645  		var configuration = *validConfiguration
   646  		configuration.FilePath = "glob/kustomize/**/*.yaml"
   647  
   648  		err := runGitopsUpdateDeployment(&configuration, runnerMock, gitUtilsMock, fsMock)
   649  		assert.NoError(t, err)
   650  		assert.Equal(t, validConfiguration.BranchName, gitUtilsMock.changedBranch)
   651  		assert.Len(t, gitUtilsMock.savedFiles, 2)
   652  		assert.Equal(t, expectedKustomize, gitUtilsMock.savedFiles[0])
   653  		assert.Equal(t, expectedKustomize, gitUtilsMock.savedFiles[1])
   654  		assert.Equal(t, "This is the commit message", gitUtilsMock.commitMessage)
   655  		assert.Equal(t, "kustomize", runnerMock.executable)
   656  		assert.Equal(t, "edit", runnerMock.params[0])
   657  		assert.Equal(t, "set", runnerMock.params[1])
   658  		assert.Equal(t, "image", runnerMock.params[2])
   659  		assert.Equal(t, "myFancyDeployment=registry/containers/myFancyContainer:1337", runnerMock.params[3])
   660  		assert.Equal(t, "edit", runnerMock.params[4])
   661  		assert.Equal(t, "set", runnerMock.params[5])
   662  		assert.Equal(t, "image", runnerMock.params[6])
   663  		assert.Equal(t, "myFancyDeployment=registry/containers/myFancyContainer:1337", runnerMock.params[7])
   664  	})
   665  
   666  	t.Run("error on kustomize execution", func(t *testing.T) {
   667  		t.Parallel()
   668  		runner := &gitOpsExecRunnerMock{failOnRunExecutable: true}
   669  
   670  		err := runGitopsUpdateDeployment(validConfiguration, runner, &gitUtilsMock{}, &filesMock{})
   671  		assert.EqualError(t, err, "failed to apply kustomize command: failed to execute kustomize command: error happened")
   672  	})
   673  
   674  	t.Run("missing FilePath", func(t *testing.T) {
   675  		t.Parallel()
   676  		var configuration = *validConfiguration
   677  		configuration.FilePath = ""
   678  
   679  		err := runGitopsUpdateDeployment(&configuration, &gitOpsExecRunnerMock{}, &gitUtilsMock{}, &filesMock{})
   680  		assert.EqualError(t, err, "missing required fields for kustomize: the following parameters are necessary for kustomize: [filePath]")
   681  	})
   682  
   683  	t.Run("missing DeploymentName", func(t *testing.T) {
   684  		t.Parallel()
   685  		var configuration = *validConfiguration
   686  		configuration.DeploymentName = ""
   687  
   688  		err := runGitopsUpdateDeployment(&configuration, &gitOpsExecRunnerMock{}, &gitUtilsMock{}, &filesMock{})
   689  		assert.EqualError(t, err, "missing required fields for kustomize: the following parameters are necessary for kustomize: [deploymentName]")
   690  	})
   691  }
   692  
   693  func TestRunGitopsUpdateDeploymentWithGlobbing(t *testing.T) {
   694  	var validConfiguration = &gitopsUpdateDeploymentOptions{
   695  		Tool:           toolKubectl,
   696  		ContainerName:  "yes",
   697  		DeploymentName: "myFancyDeployment",
   698  	}
   699  
   700  	t.Run("globbing fails", func(t *testing.T) {
   701  		t.Parallel()
   702  		gitUtilsMock := &gitUtilsMock{}
   703  		runnerMock := &gitOpsExecRunnerMock{}
   704  		fsMock := &filesMock{failOnGlob: true}
   705  
   706  		err := runGitopsUpdateDeployment(validConfiguration, runnerMock, gitUtilsMock, fsMock)
   707  		assert.EqualError(t, err, "unable to expand globbing pattern: error appeared")
   708  	})
   709  	t.Run("globbing finds 0 files", func(t *testing.T) {
   710  		t.Parallel()
   711  		gitUtilsMock := &gitUtilsMock{skipClone: true}
   712  		runnerMock := &gitOpsExecRunnerMock{}
   713  		fsMock := &filesMock{}
   714  		var config = *validConfiguration
   715  		config.FilePath = "xxx"
   716  
   717  		err := runGitopsUpdateDeployment(&config, runnerMock, gitUtilsMock, fsMock)
   718  		assert.EqualError(t, err, "no matching files found for provided globbing pattern")
   719  	})
   720  }
   721  
   722  type gitOpsExecRunnerMock struct {
   723  	out                 io.Writer
   724  	params              []string
   725  	executable          string
   726  	failOnRunExecutable bool
   727  	dir                 string
   728  	expectedYaml        string
   729  }
   730  
   731  func (e *gitOpsExecRunnerMock) Stdout(out io.Writer) {
   732  	e.out = out
   733  }
   734  
   735  func (gitOpsExecRunnerMock) Stderr(io.Writer) {
   736  	panic("implement me")
   737  }
   738  
   739  func (e *gitOpsExecRunnerMock) SetDir(d string) {
   740  	e.dir = d
   741  }
   742  
   743  func (e *gitOpsExecRunnerMock) RunExecutable(executable string, params ...string) error {
   744  	if e.failOnRunExecutable {
   745  		return errors.New("error happened")
   746  	}
   747  	e.executable = executable
   748  	e.params = append(e.params, params...)
   749  	if executable == "kustomize" {
   750  		return fileUtils.FileWrite(filepath.Join(e.dir, "kustomization.yaml"), []byte(e.expectedYaml), 0755)
   751  
   752  	} else {
   753  		_, err := e.out.Write([]byte(e.expectedYaml))
   754  		return err
   755  	}
   756  }
   757  
   758  type filesMock struct {
   759  	failOnCreation bool
   760  	failOnDeletion bool
   761  	failOnWrite    bool
   762  	failOnGlob     bool
   763  	path           string
   764  }
   765  
   766  func (f filesMock) FileWrite(path string, content []byte, perm os.FileMode) error {
   767  	if f.failOnWrite {
   768  		return errors.New("error appeared")
   769  	}
   770  	return piperutils.Files{}.FileWrite(path, content, perm)
   771  }
   772  
   773  func (f filesMock) TempDir(dir string, pattern string) (name string, err error) {
   774  	if f.failOnCreation {
   775  		return "", errors.New("error appeared")
   776  	}
   777  	return piperutils.Files{}.TempDir(dir, pattern)
   778  }
   779  
   780  func (f *filesMock) RemoveAll(path string) error {
   781  	if f.failOnDeletion {
   782  		f.path = path
   783  		return errors.New("error appeared")
   784  	}
   785  	return piperutils.Files{}.RemoveAll(path)
   786  }
   787  
   788  func (f *filesMock) Glob(pattern string) (matches []string, err error) {
   789  	if f.failOnGlob {
   790  		return nil, errors.New("error appeared")
   791  	}
   792  	return piperutils.Files{}.Glob(pattern)
   793  }
   794  
   795  type gitUtilsMock struct {
   796  	savedFiles         []string
   797  	changedBranch      string
   798  	commitMessage      string
   799  	temporaryDirectory string
   800  	failOnClone        bool
   801  	failOnChangeBranch bool
   802  	failOnCommit       bool
   803  	failOnPush         bool
   804  	skipClone          bool
   805  }
   806  
   807  func (gitUtilsMock) GetWorktree() (*git.Worktree, error) {
   808  	return nil, nil
   809  }
   810  
   811  func (v *gitUtilsMock) ChangeBranch(branchName string) error {
   812  	if v.failOnChangeBranch {
   813  		return errors.New("error on change branch")
   814  	}
   815  	v.changedBranch = branchName
   816  	return nil
   817  }
   818  
   819  func (v *gitUtilsMock) CommitFiles(newFiles []string, commitMessage string, _ string) (plumbing.Hash, error) {
   820  	if v.failOnCommit {
   821  		return [20]byte{}, errors.New("error on commit")
   822  	}
   823  
   824  	v.commitMessage = commitMessage
   825  
   826  	for _, newFile := range newFiles {
   827  		filepath := filepath.Join(v.temporaryDirectory, newFile)
   828  		fileContent, err := piperutils.Files{}.FileRead(filepath)
   829  		if err != nil {
   830  			return [20]byte{}, errors.New("could not find file " + filepath)
   831  		}
   832  		v.savedFiles = append(v.savedFiles, string(fileContent))
   833  	}
   834  	return [20]byte{123}, nil
   835  }
   836  
   837  func (v gitUtilsMock) PushChangesToRepository(string, string) error {
   838  	if v.failOnPush {
   839  		return errors.New("error on push")
   840  	}
   841  	return nil
   842  }
   843  
   844  func (v *gitUtilsMock) PlainClone(_, _, _, directory string) error {
   845  	if v.skipClone {
   846  		return nil
   847  	}
   848  	if v.failOnClone {
   849  		return errors.New("error on clone")
   850  	}
   851  	v.temporaryDirectory = directory
   852  
   853  	err := piperutils.Files{}.MkdirAll(filepath.Join(directory, "dir1/dir2"), 0755)
   854  	if err != nil {
   855  		return err
   856  	}
   857  	err = piperutils.Files{}.FileWrite(filepath.Join(directory, "dir1/dir2/depl.yaml"), []byte(existingYaml), 0755)
   858  	err = piperutils.Files{}.MkdirAll(filepath.Join(directory, "glob/kubectl/dir1"), 0755)
   859  	err = piperutils.Files{}.MkdirAll(filepath.Join(directory, "glob/kubectl/dir2"), 0755)
   860  	err = piperutils.Files{}.FileWrite(filepath.Join(directory, "glob/kubectl/dir1/depl.yaml"), []byte(existingYaml), 0755)
   861  	err = piperutils.Files{}.FileWrite(filepath.Join(directory, "glob/kubectl/dir2/depl.yaml"), []byte(existingYaml), 0755)
   862  
   863  	err = piperutils.Files{}.MkdirAll(filepath.Join(directory, "helm"), 0755)
   864  	err = piperutils.Files{}.MkdirAll(filepath.Join(directory, "glob/helm/dir1/helm"), 0755)
   865  	err = piperutils.Files{}.MkdirAll(filepath.Join(directory, "glob/helm/dir2/helm"), 0755)
   866  
   867  	err = piperutils.Files{}.FileWrite(filepath.Join(directory, "kustomization.yaml"), []byte(existingKustomize), 0755)
   868  	err = piperutils.Files{}.MkdirAll(filepath.Join(directory, "glob/kustomize/dir1"), 0755)
   869  	err = piperutils.Files{}.MkdirAll(filepath.Join(directory, "glob/kustomize/dir2"), 0755)
   870  	err = piperutils.Files{}.FileWrite(filepath.Join(directory, "glob/kustomize/dir1/kustomization.yaml"), []byte(existingKustomize), 0755)
   871  	err = piperutils.Files{}.FileWrite(filepath.Join(directory, "glob/kustomize/dir2/kustomization.yaml"), []byte(existingKustomize), 0755)
   872  	return nil
   873  }
   874  
   875  var existingYaml = `apiVersion: apps/v1
   876  kind: Deployment
   877  metadata:
   878    name: myFancyApp
   879    labels:
   880      tier: application
   881  spec:
   882    replicas: 4
   883    selector:
   884      matchLabels:
   885        run: myContainer
   886    template:
   887      metadata:
   888        labels:
   889          run: myContainer
   890      spec:
   891        containers:
   892        - image: myregistry.com/myFancyContainer:1336
   893          name: myContainer`
   894  
   895  var expectedYaml = `apiVersion: apps/v1
   896  kind: Deployment
   897  metadata:
   898    name: myFancyApp
   899    labels:
   900      tier: application
   901  spec:
   902    replicas: 4
   903    selector:
   904      matchLabels:
   905        run: myContainer
   906    template:
   907      metadata:
   908        labels:
   909          run: myContainer
   910      spec:
   911        containers:
   912        - image: myregistry.com/myFancyContainer:1337
   913          name: myContainer`
   914  
   915  var existingKustomize = `apiVersion: kustomize.config.k8s.io/v1beta1
   916  kind: Kustomization
   917  
   918  images:
   919  - name: myFancyDeployment
   920    newTag: "0"
   921  `
   922  var expectedKustomize = `apiVersion: kustomize.config.k8s.io/v1beta1
   923  kind: Kustomization
   924  
   925  images:
   926  - name: myFancyDeployment
   927    newName: registry/containers/myFancyContainer
   928    newTag: "1337"
   929  `