github.com/GoogleContainerTools/skaffold@v1.39.18/pkg/skaffold/kubernetes/manifest/images_test.go (about)

     1  /*
     2  Copyright 2019 The Skaffold Authors
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package manifest
    18  
    19  import (
    20  	"context"
    21  	"testing"
    22  
    23  	apimachinery "k8s.io/apimachinery/pkg/runtime/schema"
    24  
    25  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/graph"
    26  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest"
    27  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/warnings"
    28  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/yaml"
    29  	"github.com/GoogleContainerTools/skaffold/testutil"
    30  )
    31  
    32  func TestGetImages(t *testing.T) {
    33  	manifests := ManifestList{[]byte(`
    34  apiVersion: v1
    35  kind: Pod
    36  metadata:
    37    name: getting-started
    38  spec:
    39    containers:
    40    - image: ["invalid-image-ref"]
    41    - image: not valid
    42    - image: gcr.io/k8s-skaffold/example:latest
    43      name: latest
    44    - image: skaffold/other
    45      name: other
    46    - image: gcr.io/k8s-skaffold/example@sha256:81daf011d63b68cfa514ddab7741a1adddd59d3264118dfb0fd9266328bb8883
    47      name: digest
    48  `)}
    49  	expectedImages := []graph.Artifact{
    50  		{
    51  			ImageName: "gcr.io/k8s-skaffold/example",
    52  			Tag:       "gcr.io/k8s-skaffold/example:latest",
    53  		}, {
    54  			ImageName: "skaffold/other",
    55  			Tag:       "skaffold/other",
    56  		}, {
    57  			ImageName: "gcr.io/k8s-skaffold/example",
    58  			Tag:       "gcr.io/k8s-skaffold/example@sha256:81daf011d63b68cfa514ddab7741a1adddd59d3264118dfb0fd9266328bb8883",
    59  		},
    60  	}
    61  
    62  	actual, err := manifests.GetImages(NewResourceSelectorImages(TransformAllowlist, TransformDenylist))
    63  	testutil.CheckErrorAndDeepEqual(t, false, err, expectedImages, actual)
    64  }
    65  
    66  func TestReplaceRemoteManifestImages(t *testing.T) {
    67  	manifests := ManifestList{[]byte(`
    68  apiVersion: v1
    69  kind: Pod
    70  metadata:
    71    name: getting-started
    72  spec:
    73    containers:
    74    - image: gcr.io/k8s-skaffold/example
    75      name: not-tagged
    76    - image: gcr.io/k8s-skaffold/example:latest
    77      name: latest
    78    - image: gcr.io/different-repo/example:latest
    79      name: different-repo
    80    - image: gcr.io/k8s-skaffold/example:v1
    81      name: ignored-tag
    82    - image: skaffold/other
    83      name: other
    84    - image: gcr.io/k8s-skaffold/example@sha256:81daf011d63b68cfa514ddab7741a1adddd59d3264118dfb0fd9266328bb8883
    85      name: digest
    86    - image: ko://github.com/GoogleContainerTools/skaffold/cmd/skaffold
    87    - image: unknown
    88  `)}
    89  
    90  	builds := []graph.Artifact{{
    91  		ImageName: "example",
    92  		Tag:       "gcr.io/k8s-skaffold/example:TAG",
    93  	}, {
    94  		ImageName: "skaffold/other",
    95  		Tag:       "skaffold/other:OTHER_TAG",
    96  	}, {
    97  		ImageName: "github.com/GoogleContainerTools/skaffold/cmd/skaffold",
    98  		Tag:       "gcr.io/k8s-skaffold/github.com/googlecontainertools/skaffold/cmd/skaffold:TAG",
    99  	}}
   100  
   101  	expected := ManifestList{[]byte(`
   102  apiVersion: v1
   103  kind: Pod
   104  metadata:
   105    name: getting-started
   106  spec:
   107    containers:
   108    - image: gcr.io/k8s-skaffold/example:TAG
   109      name: not-tagged
   110    - image: gcr.io/k8s-skaffold/example:TAG
   111      name: latest
   112    - image: gcr.io/k8s-skaffold/example:TAG
   113      name: different-repo
   114    - image: gcr.io/k8s-skaffold/example:TAG
   115      name: ignored-tag
   116    - image: skaffold/other:OTHER_TAG
   117      name: other
   118    - image: gcr.io/k8s-skaffold/example:TAG
   119      name: digest
   120    - image: gcr.io/k8s-skaffold/github.com/googlecontainertools/skaffold/cmd/skaffold:TAG
   121    - image: unknown
   122  `)}
   123  
   124  	testutil.Run(t, "", func(t *testutil.T) {
   125  		fakeWarner := &warnings.Collect{}
   126  		t.Override(&warnings.Printf, fakeWarner.Warnf)
   127  
   128  		resultManifest, err := manifests.ReplaceRemoteManifestImages(context.TODO(), builds, NewResourceSelectorImages(TransformAllowlist, TransformDenylist))
   129  
   130  		t.CheckNoError(err)
   131  		t.CheckDeepEqual(expected.String(), resultManifest.String(), testutil.YamlObj(t.T))
   132  	})
   133  }
   134  
   135  func TestReplaceImages(t *testing.T) {
   136  	manifests := ManifestList{[]byte(`
   137  apiVersion: v1
   138  kind: Pod
   139  metadata:
   140    name: getting-started
   141  spec:
   142    containers:
   143    - image: gcr.io/k8s-skaffold/example
   144      name: not-tagged
   145    - image: gcr.io/k8s-skaffold/example:latest
   146      name: latest
   147    - image: gcr.io/k8s-skaffold/example:v1
   148      name: ignored-tag
   149    - image: skaffold/other
   150      name: other
   151    - image: gcr.io/k8s-skaffold/example@sha256:81daf011d63b68cfa514ddab7741a1adddd59d3264118dfb0fd9266328bb8883
   152      name: digest
   153    - image: skaffold/usedbyfqn:TAG
   154    - image: ko://github.com/GoogleContainerTools/skaffold/cmd/skaffold
   155    - image: not valid
   156    - image: unknown
   157  `)}
   158  
   159  	builds := []graph.Artifact{{
   160  		ImageName: "gcr.io/k8s-skaffold/example",
   161  		Tag:       "gcr.io/k8s-skaffold/example:TAG",
   162  	}, {
   163  		ImageName: "skaffold/other",
   164  		Tag:       "skaffold/other:OTHER_TAG",
   165  	}, {
   166  		ImageName: "skaffold/unused",
   167  		Tag:       "skaffold/unused:TAG",
   168  	}, {
   169  		ImageName: "skaffold/usedbyfqn",
   170  		Tag:       "skaffold/usedbyfqn:TAG",
   171  	}, {
   172  		ImageName: "github.com/GoogleContainerTools/skaffold/cmd/skaffold",
   173  		Tag:       "gcr.io/k8s-skaffold/github.com/googlecontainertools/skaffold/cmd/skaffold:TAG",
   174  	}}
   175  
   176  	expected := ManifestList{[]byte(`
   177  apiVersion: v1
   178  kind: Pod
   179  metadata:
   180    name: getting-started
   181  spec:
   182    containers:
   183    - image: gcr.io/k8s-skaffold/example:TAG
   184      name: not-tagged
   185    - image: gcr.io/k8s-skaffold/example:TAG
   186      name: latest
   187    - image: gcr.io/k8s-skaffold/example:TAG
   188      name: ignored-tag
   189    - image: skaffold/other:OTHER_TAG
   190      name: other
   191    - image: gcr.io/k8s-skaffold/example@sha256:81daf011d63b68cfa514ddab7741a1adddd59d3264118dfb0fd9266328bb8883
   192      name: digest
   193    - image: skaffold/usedbyfqn:TAG
   194    - image: gcr.io/k8s-skaffold/github.com/googlecontainertools/skaffold/cmd/skaffold:TAG
   195    - image: not valid
   196    - image: unknown
   197  `)}
   198  
   199  	testutil.Run(t, "", func(t *testutil.T) {
   200  		fakeWarner := &warnings.Collect{}
   201  		t.Override(&warnings.Printf, fakeWarner.Warnf)
   202  
   203  		resultManifest, err := manifests.ReplaceImages(context.TODO(), builds, NewResourceSelectorImages(TransformAllowlist, TransformDenylist))
   204  
   205  		t.CheckNoError(err)
   206  		t.CheckDeepEqual(expected.String(), resultManifest.String(), testutil.YamlObj(t.T))
   207  	})
   208  }
   209  
   210  func TestReplaceImagesOnConfigConnectorResources(t *testing.T) {
   211  	manifests := ManifestList{[]byte(`
   212  apiVersion: storage.cnrm.cloud.google.com/v1beta1
   213  kind: StorageBucket
   214  metadata:
   215    name: image-name
   216    labels:
   217      app.kubernetes.io/name: image-name
   218      this.should.not.change: image-name
   219      image: image-name
   220  spec:
   221    location: EU
   222    image: this-should-not-change
   223  `)}
   224  
   225  	builds := []graph.Artifact{{
   226  		ImageName: "image-name",
   227  		Tag:       "gcr.io/k8s-skaffold/image-name:TAG",
   228  	}}
   229  
   230  	expected := ManifestList{[]byte(`
   231  apiVersion: storage.cnrm.cloud.google.com/v1beta1
   232  kind: StorageBucket
   233  metadata:
   234    name: image-name
   235    labels:
   236      app.kubernetes.io/name: image-name
   237      this.should.not.change: image-name
   238      image: gcr.io/k8s-skaffold/image-name:TAG
   239  spec:
   240    location: EU
   241    image: this-should-not-change
   242  `)}
   243  
   244  	testutil.Run(t, "", func(t *testutil.T) {
   245  		fakeWarner := &warnings.Collect{}
   246  		t.Override(&warnings.Printf, fakeWarner.Warnf)
   247  
   248  		resultManifest, err := manifests.ReplaceImages(context.TODO(), builds, NewResourceSelectorImages(TransformAllowlist, TransformDenylist))
   249  
   250  		t.CheckNoError(err)
   251  
   252  		expectedYaml := make(map[string]interface{})
   253  		yaml.Unmarshal(expected[0], &expectedYaml)
   254  		resultYaml := make(map[string]interface{})
   255  		yaml.Unmarshal(resultManifest[0], &resultYaml)
   256  
   257  		t.CheckMapsMatch(expectedYaml, resultYaml)
   258  	})
   259  }
   260  
   261  func TestReplaceImagesOnConfigConnectorResourcesUsingNonDefaultField(t *testing.T) {
   262  	manifests := ManifestList{[]byte(`
   263  apiVersion: storage.cnrm.cloud.google.com/v1beta1
   264  kind: StorageBucket
   265  metadata:
   266    name: image-name
   267    labels:
   268      app.kubernetes.io/name: image-name
   269      this.should.not.change: image-name
   270      image: image-name
   271  spec:
   272    template:
   273      spec:
   274        restartPolicy: image-name
   275    image: this-should-not-change
   276  `)}
   277  
   278  	builds := []graph.Artifact{{
   279  		ImageName: "image-name",
   280  		Tag:       "gcr.io/k8s-skaffold/image-name:TAG",
   281  	}}
   282  
   283  	expected := ManifestList{[]byte(`
   284  apiVersion: storage.cnrm.cloud.google.com/v1beta1
   285  kind: StorageBucket
   286  metadata:
   287    name: image-name
   288    labels:
   289      app.kubernetes.io/name: image-name
   290      this.should.not.change: image-name
   291      image: image-name
   292  spec:
   293    template:
   294      spec:
   295        restartPolicy: gcr.io/k8s-skaffold/image-name:TAG
   296    image: this-should-not-change
   297  `)}
   298  
   299  	testutil.Run(t, "", func(t *testutil.T) {
   300  		fakeWarner := &warnings.Collect{}
   301  		t.Override(&warnings.Printf, fakeWarner.Warnf)
   302  
   303  		newTransformAllowlist := make(map[apimachinery.GroupKind]latest.ResourceFilter)
   304  		for k, v := range TransformAllowlist {
   305  			newTransformAllowlist[k] = v
   306  		}
   307  		newTransformAllowlist[apimachinery.GroupKind{Group: "storage.cnrm.cloud.google.com", Kind: "StorageBucket"}] =
   308  			latest.ResourceFilter{GroupKind: "StorageBucket.storage.cnrm.cloud.google.com", Image: []string{".spec.template.spec.restartPolicy"}}
   309  		resultManifest, err := manifests.ReplaceImages(context.TODO(), builds, NewResourceSelectorImages(newTransformAllowlist, TransformDenylist))
   310  
   311  		t.CheckNoError(err)
   312  
   313  		expectedYaml := make(map[string]interface{})
   314  		yaml.Unmarshal(expected[0], &expectedYaml)
   315  		resultYaml := make(map[string]interface{})
   316  		yaml.Unmarshal(resultManifest[0], &resultYaml)
   317  
   318  		t.CheckMapsMatch(expectedYaml, resultYaml)
   319  	})
   320  }
   321  
   322  func TestReplaceImagesOnConfigConnectorResourcesUsingWildcardAndNonDefaultField(t *testing.T) {
   323  	manifests := ManifestList{[]byte(`
   324  apiVersion: storage.cnrm.cloud.google.com/v1beta1
   325  kind: StorageBucket
   326  metadata:
   327    name: image-name
   328    labels:
   329      app.kubernetes.io/name: image-name
   330      this.should.not.change: image-name
   331      image: image-name
   332  spec:
   333    template:
   334      spec:
   335        restartPolicy: image-name
   336    image: this-should-not-change
   337  `)}
   338  
   339  	builds := []graph.Artifact{{
   340  		ImageName: "image-name",
   341  		Tag:       "gcr.io/k8s-skaffold/image-name:TAG",
   342  	}}
   343  
   344  	expected := ManifestList{[]byte(`
   345  apiVersion: storage.cnrm.cloud.google.com/v1beta1
   346  kind: StorageBucket
   347  metadata:
   348    name: image-name
   349    labels:
   350      app.kubernetes.io/name: image-name
   351      this.should.not.change: image-name
   352      image: gcr.io/k8s-skaffold/image-name:TAG
   353  spec:
   354    template:
   355      spec:
   356        restartPolicy: gcr.io/k8s-skaffold/image-name:TAG
   357    image: this-should-not-change
   358  `)}
   359  
   360  	testutil.Run(t, "", func(t *testutil.T) {
   361  		fakeWarner := &warnings.Collect{}
   362  		t.Override(&warnings.Printf, fakeWarner.Warnf)
   363  
   364  		newTransformAllowlist := make(map[apimachinery.GroupKind]latest.ResourceFilter)
   365  		for k, v := range TransformAllowlist {
   366  			newTransformAllowlist[k] = v
   367  		}
   368  		newTransformAllowlist[apimachinery.GroupKind{Group: "storage.cnrm.cloud.google.com", Kind: "StorageBucket"}] =
   369  			latest.ResourceFilter{GroupKind: "StorageBucket.storage.cnrm.cloud.google.com", Image: []string{".*", ".spec.template.spec.restartPolicy"}}
   370  		resultManifest, err := manifests.ReplaceImages(context.TODO(), builds, NewResourceSelectorImages(newTransformAllowlist, TransformDenylist))
   371  
   372  		t.CheckNoError(err)
   373  
   374  		expectedYaml := make(map[string]interface{})
   375  		yaml.Unmarshal(expected[0], &expectedYaml)
   376  		resultYaml := make(map[string]interface{})
   377  		yaml.Unmarshal(resultManifest[0], &resultYaml)
   378  
   379  		t.CheckMapsMatch(expectedYaml, resultYaml)
   380  	})
   381  }
   382  
   383  func TestReplaceImagesOnConfigConnectorDeniedResources(t *testing.T) {
   384  	manifests := ManifestList{[]byte(`
   385  apiVersion: storage.cnrm.cloud.google.com/v1beta1
   386  kind: StorageBucket
   387  metadata:
   388    name: image-name
   389    labels:
   390      app.kubernetes.io/name: image-name
   391      this.should.not.change: image-name
   392      image: image-name
   393  spec:
   394    location: EU
   395    image: image-name
   396  `)}
   397  
   398  	builds := []graph.Artifact{{
   399  		ImageName: "image-name",
   400  		Tag:       "gcr.io/k8s-skaffold/image-name:TAG",
   401  	}}
   402  
   403  	expected := ManifestList{[]byte(`
   404  apiVersion: storage.cnrm.cloud.google.com/v1beta1
   405  kind: StorageBucket
   406  metadata:
   407    name: image-name
   408    labels:
   409      app.kubernetes.io/name: image-name
   410      this.should.not.change: image-name
   411      image: image-name
   412  spec:
   413    location: EU
   414    image: gcr.io/k8s-skaffold/image-name:TAG
   415  `)}
   416  
   417  	testutil.Run(t, "", func(t *testutil.T) {
   418  		fakeWarner := &warnings.Collect{}
   419  		t.Override(&warnings.Printf, fakeWarner.Warnf)
   420  
   421  		newTransformDenylist := make(map[apimachinery.GroupKind]latest.ResourceFilter)
   422  		for k, v := range TransformDenylist {
   423  			newTransformDenylist[k] = v
   424  		}
   425  		newTransformDenylist[apimachinery.GroupKind{Group: "storage.cnrm.cloud.google.com", Kind: "StorageBucket"}] =
   426  			latest.ResourceFilter{GroupKind: "StorageBucket.storage.cnrm.cloud.google.com", Image: []string{".metadata.labels.image"}}
   427  		resultManifest, err := manifests.ReplaceImages(context.TODO(), builds, NewResourceSelectorImages(TransformAllowlist, newTransformDenylist))
   428  
   429  		t.CheckNoError(err)
   430  
   431  		expectedYaml := make(map[string]interface{})
   432  		yaml.Unmarshal(expected[0], &expectedYaml)
   433  		resultYaml := make(map[string]interface{})
   434  		yaml.Unmarshal(resultManifest[0], &resultYaml)
   435  
   436  		t.CheckMapsMatch(expectedYaml, resultYaml)
   437  	})
   438  }
   439  
   440  func TestReplaceImagesOnConfigConnectorAllDeniedResources(t *testing.T) {
   441  	manifests := ManifestList{[]byte(`
   442  apiVersion: storage.cnrm.cloud.google.com/v1beta1
   443  kind: StorageBucket
   444  metadata:
   445    name: image-name
   446    labels:
   447      app.kubernetes.io/name: image-name
   448      this.should.not.change: image-name
   449      image: image-name
   450  spec:
   451    location: EU
   452    image: image-name
   453  `)}
   454  
   455  	builds := []graph.Artifact{{
   456  		ImageName: "image-name",
   457  		Tag:       "gcr.io/k8s-skaffold/image-name:TAG",
   458  	}}
   459  
   460  	expected := ManifestList{[]byte(`
   461  apiVersion: storage.cnrm.cloud.google.com/v1beta1
   462  kind: StorageBucket
   463  metadata:
   464    name: image-name
   465    labels:
   466      app.kubernetes.io/name: image-name
   467      this.should.not.change: image-name
   468      image: image-name
   469  spec:
   470    location: EU
   471    image: image-name
   472  `)}
   473  
   474  	testutil.Run(t, "", func(t *testutil.T) {
   475  		fakeWarner := &warnings.Collect{}
   476  		t.Override(&warnings.Printf, fakeWarner.Warnf)
   477  
   478  		newTransformDenylist := make(map[apimachinery.GroupKind]latest.ResourceFilter)
   479  		for k, v := range TransformDenylist {
   480  			newTransformDenylist[k] = v
   481  		}
   482  		newTransformDenylist[apimachinery.GroupKind{Group: "storage.cnrm.cloud.google.com", Kind: "StorageBucket"}] =
   483  			latest.ResourceFilter{GroupKind: "StorageBucket.storage.cnrm.cloud.google.com", Image: []string{".*"}}
   484  		resultManifest, err := manifests.ReplaceImages(context.TODO(), builds, NewResourceSelectorImages(TransformAllowlist, newTransformDenylist))
   485  
   486  		t.CheckNoError(err)
   487  
   488  		expectedYaml := make(map[string]interface{})
   489  		yaml.Unmarshal(expected[0], &expectedYaml)
   490  		resultYaml := make(map[string]interface{})
   491  		yaml.Unmarshal(resultManifest[0], &resultYaml)
   492  
   493  		t.CheckMapsMatch(expectedYaml, resultYaml)
   494  	})
   495  }
   496  
   497  func TestReplaceImagesOnPredefinedAllowedResourcesUsingNonDefaultField(t *testing.T) {
   498  	manifests := ManifestList{[]byte(`
   499  apiVersion: batch/v1
   500  kind: Job
   501  metadata:
   502    name: image-name
   503    labels:
   504      app.kubernetes.io/name: image-name
   505      this.should.not.change: image-name
   506      image: image-name
   507  spec:
   508    template:
   509      spec:
   510        restartPolicy: image-name
   511    image: this-should-not-change
   512  `)}
   513  
   514  	builds := []graph.Artifact{{
   515  		ImageName: "image-name",
   516  		Tag:       "gcr.io/k8s-skaffold/image-name:TAG",
   517  	}}
   518  
   519  	expected := ManifestList{[]byte(`
   520  apiVersion: batch/v1
   521  kind: Job
   522  metadata:
   523    name: image-name
   524    labels:
   525      app.kubernetes.io/name: image-name
   526      this.should.not.change: image-name
   527      image: image-name
   528  spec:
   529    template:
   530      spec:
   531        restartPolicy: gcr.io/k8s-skaffold/image-name:TAG
   532    image: this-should-not-change
   533  `)}
   534  
   535  	testutil.Run(t, "", func(t *testutil.T) {
   536  		fakeWarner := &warnings.Collect{}
   537  		t.Override(&warnings.Printf, fakeWarner.Warnf)
   538  
   539  		newTransformAllowlist := make(map[apimachinery.GroupKind]latest.ResourceFilter)
   540  		for k, v := range TransformAllowlist {
   541  			newTransformAllowlist[k] = v
   542  		}
   543  		newTransformAllowlist[apimachinery.GroupKind{Group: "batch", Kind: "Job"}] =
   544  			latest.ResourceFilter{GroupKind: "Job.batch", Image: []string{".spec.template.spec.restartPolicy"}}
   545  		resultManifest, err := manifests.ReplaceImages(context.TODO(), builds, NewResourceSelectorImages(newTransformAllowlist, TransformDenylist))
   546  
   547  		t.CheckNoError(err)
   548  
   549  		expectedYaml := make(map[string]interface{})
   550  		yaml.Unmarshal(expected[0], &expectedYaml)
   551  		resultYaml := make(map[string]interface{})
   552  		yaml.Unmarshal(resultManifest[0], &resultYaml)
   553  
   554  		t.CheckMapsMatch(expectedYaml, resultYaml)
   555  	})
   556  }
   557  
   558  func TestReplaceImagesOnPredefinedAllowedResources(t *testing.T) {
   559  	manifests := ManifestList{[]byte(`
   560  apiVersion: batch/v1
   561  kind: Job
   562  metadata:
   563    name: image-name
   564    labels:
   565      app.kubernetes.io/name: image-name
   566      this.should.not.change: image-name
   567      image: image-name
   568  spec:
   569    template:
   570      spec:
   571        restartPolicy: image-name
   572    image: this-should-not-change
   573  `)}
   574  
   575  	builds := []graph.Artifact{{
   576  		ImageName: "image-name",
   577  		Tag:       "gcr.io/k8s-skaffold/image-name:TAG",
   578  	}}
   579  
   580  	expected := ManifestList{[]byte(`
   581  apiVersion: batch/v1
   582  kind: Job
   583  metadata:
   584    name: image-name
   585    labels:
   586      app.kubernetes.io/name: image-name
   587      this.should.not.change: image-name
   588      image: gcr.io/k8s-skaffold/image-name:TAG
   589  spec:
   590    template:
   591      spec:
   592        restartPolicy: image-name
   593    image: this-should-not-change
   594  `)}
   595  
   596  	testutil.Run(t, "", func(t *testutil.T) {
   597  		fakeWarner := &warnings.Collect{}
   598  		t.Override(&warnings.Printf, fakeWarner.Warnf)
   599  
   600  		resultManifest, err := manifests.ReplaceImages(context.TODO(), builds, NewResourceSelectorImages(TransformAllowlist, TransformDenylist))
   601  
   602  		t.CheckNoError(err)
   603  
   604  		expectedYaml := make(map[string]interface{})
   605  		yaml.Unmarshal(expected[0], &expectedYaml)
   606  		resultYaml := make(map[string]interface{})
   607  		yaml.Unmarshal(resultManifest[0], &resultYaml)
   608  
   609  		t.CheckMapsMatch(expectedYaml, resultYaml)
   610  	})
   611  }
   612  
   613  func TestReplaceImagesOnPredefinedDeniedResources(t *testing.T) {
   614  	manifests := ManifestList{[]byte(`
   615  apiVersion: batch/v1
   616  kind: Job
   617  metadata:
   618    name: image-name
   619    labels:
   620      app.kubernetes.io/name: image-name
   621      this.should.not.change: image-name
   622      image: image-name
   623  spec:
   624    template:
   625      spec:
   626        restartPolicy: image-name
   627    image: image-name
   628  `)}
   629  
   630  	builds := []graph.Artifact{{
   631  		ImageName: "image-name",
   632  		Tag:       "gcr.io/k8s-skaffold/image-name:TAG",
   633  	}}
   634  
   635  	expected := ManifestList{[]byte(`
   636  apiVersion: batch/v1
   637  kind: Job
   638  metadata:
   639    name: image-name
   640    labels:
   641      app.kubernetes.io/name: image-name
   642      this.should.not.change: image-name
   643      image: image-name
   644  spec:
   645    template:
   646      spec:
   647        restartPolicy: image-name
   648    image: gcr.io/k8s-skaffold/image-name:TAG
   649  `)}
   650  
   651  	testutil.Run(t, "", func(t *testutil.T) {
   652  		fakeWarner := &warnings.Collect{}
   653  		t.Override(&warnings.Printf, fakeWarner.Warnf)
   654  
   655  		newTransformDenylist := make(map[apimachinery.GroupKind]latest.ResourceFilter)
   656  		for k, v := range TransformDenylist {
   657  			newTransformDenylist[k] = v
   658  		}
   659  		newTransformDenylist[apimachinery.GroupKind{Group: "batch", Kind: "Job"}] =
   660  			latest.ResourceFilter{GroupKind: "Job.batch", Image: []string{".metadata.labels.image"}}
   661  		resultManifest, err := manifests.ReplaceImages(context.TODO(), builds, NewResourceSelectorImages(TransformAllowlist, newTransformDenylist))
   662  
   663  		t.CheckNoError(err)
   664  
   665  		expectedYaml := make(map[string]interface{})
   666  		yaml.Unmarshal(expected[0], &expectedYaml)
   667  		resultYaml := make(map[string]interface{})
   668  		yaml.Unmarshal(resultManifest[0], &resultYaml)
   669  
   670  		t.CheckMapsMatch(expectedYaml, resultYaml)
   671  	})
   672  }
   673  
   674  func TestReplaceEmptyManifest(t *testing.T) {
   675  	manifests := ManifestList{[]byte(""), []byte("  ")}
   676  	expected := ManifestList{}
   677  
   678  	resultManifest, err := manifests.ReplaceImages(context.TODO(), nil, NewResourceSelectorImages(TransformAllowlist, TransformDenylist))
   679  
   680  	testutil.CheckErrorAndDeepEqual(t, false, err, expected.String(), resultManifest.String())
   681  }
   682  
   683  func TestReplaceInvalidManifest(t *testing.T) {
   684  	manifests := ManifestList{[]byte("INVALID")}
   685  
   686  	_, err := manifests.ReplaceImages(context.TODO(), nil, NewResourceSelectorImages(TransformAllowlist, TransformDenylist))
   687  
   688  	testutil.CheckError(t, true, err)
   689  }
   690  
   691  func TestReplaceNonStringImageField(t *testing.T) {
   692  	manifests := ManifestList{[]byte(`
   693  apiVersion: v1
   694  image:
   695  - value1
   696  - value2
   697  `)}
   698  
   699  	output, err := manifests.ReplaceImages(context.TODO(), nil, NewResourceSelectorImages(TransformAllowlist, TransformDenylist))
   700  
   701  	testutil.CheckErrorAndDeepEqual(t, false, err, manifests.String(), output.String(), testutil.YamlObj(t))
   702  }