Files
kustomize/plugin/builtin/patchstrategicmergetransformer/PatchStrategicMergeTransformer_test.go
Karl Isenberg 43868688d5 Use require for Error and NoError
Assert keeps going after failure, but require immediately fails
the tests, making it easier to find the output related to the test
failure, rather than having to comb through a bunch of subsequent
assertion failures. For equality tests, we may or may not want to
continue, but for error checks we almost always want to immediately
fail the test. Exceptions can be changed as-needed.
2024-03-20 13:19:18 -07:00

1210 lines
26 KiB
Go

// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package main_test
import (
"fmt"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
)
func errorContains(err error, possibilities ...string) bool {
for _, x := range possibilities {
if strings.Contains(err.Error(), x) {
return true
}
}
return false
}
const (
target = `
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
spec:
replica: 2
template:
metadata:
labels:
old-label: old-value
spec:
containers:
- name: nginx
image: nginx
`
targetWithNamespace = `
apiVersion: apps/v1
metadata:
name: myDeploy
namespace: namespace1
kind: Deployment
spec:
replica: 2
template:
metadata:
labels:
old-label: old-value
spec:
containers:
- name: nginx
image: nginx
`
targetNoschema = `
apiVersion: example.com/v1
kind: Foo
metadata:
name: my-foo
spec:
bar:
A: X
B: Y
`
)
func TestPatchStrategicMergeTransformerMissingFile(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t).
PrepBuiltin("PatchStrategicMergeTransformer")
defer th.Reset()
_, err := th.RunTransformer(`
apiVersion: builtin
kind: PatchStrategicMergeTransformer
metadata:
name: notImportantHere
paths:
- patch.yaml
`, target)
if assert.Error(t, err) && !errorContains(err,
"'/patch.yaml' doesn't exist",
"cannot unmarshal string") {
t.Fatalf("unexpected err: %v", err)
}
}
func TestBadPatchStrategicMergeTransformer(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t).
PrepBuiltin("PatchStrategicMergeTransformer")
defer th.Reset()
_, err := th.RunTransformer(`
apiVersion: builtin
kind: PatchStrategicMergeTransformer
metadata:
name: notImportantHere
patches: 'thisIsNotAPatch'
`, target)
if assert.Error(t, err) && !errorContains(err,
"cannot unmarshal string into Go value of type map[string]interface {}",
"fails configuration: missing Resource metadata") {
t.Fatalf("unexpected err: %v", err)
}
}
func TestBothEmptyPatchStrategicMergeTransformer(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t).
PrepBuiltin("PatchStrategicMergeTransformer")
defer th.Reset()
_, err := th.RunTransformer(`
apiVersion: builtin
kind: PatchStrategicMergeTransformer
metadata:
name: notImportantHere
`, target)
if assert.Error(t, err) && !errorContains(
err, "empty file path and empty patch content") {
t.Fatalf("unexpected err: %v", err)
}
}
func TestPatchStrategicMergeTransformerFromFiles(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t).
PrepBuiltin("PatchStrategicMergeTransformer")
defer th.Reset()
th.WriteF("/patch.yaml", `
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
spec:
template:
metadata:
labels:
new-label: new-value
replica: 3
`)
th.RunTransformerAndCheckResult(`
apiVersion: builtin
kind: PatchStrategicMergeTransformer
metadata:
name: notImportantHere
paths:
- patch.yaml
`,
target, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
replica: 3
template:
metadata:
labels:
new-label: new-value
old-label: old-value
spec:
containers:
- image: nginx
name: nginx
`)
}
func TestPatchStrategicMergeTransformerWithInlineJSON(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t).
PrepBuiltin("PatchStrategicMergeTransformer")
defer th.Reset()
th.RunTransformerAndCheckResult(`
apiVersion: builtin
kind: PatchStrategicMergeTransformer
metadata:
name: notImportantHere
patches: '{"apiVersion": "apps/v1", "metadata": {"name": "myDeploy"}, "kind": "Deployment", "spec": {"replica": 3}}'
`,
target, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
replica: 3
template:
metadata:
labels:
old-label: old-value
spec:
containers:
- image: nginx
name: nginx
`)
}
func TestPatchStrategicMergeTransformerWithInlineYAML(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t).
PrepBuiltin("PatchStrategicMergeTransformer")
defer th.Reset()
th.RunTransformerAndCheckResult(`
apiVersion: builtin
kind: PatchStrategicMergeTransformer
metadata:
name: notImportantHere
patches: |-
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
spec:
replica: 3
---
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
spec:
template:
spec:
containers:
- name: nginx
image: nginx:latest
`,
target, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
replica: 3
template:
metadata:
labels:
old-label: old-value
spec:
containers:
- image: nginx:latest
name: nginx
`)
}
func TestPatchStrategicMergeTransformerMultiplePatches(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t).
PrepBuiltin("PatchStrategicMergeTransformer")
defer th.Reset()
th.WriteF("patch1.yaml", `
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
spec:
template:
spec:
containers:
- name: nginx
image: nginx:latest
env:
- name: SOMEENV
value: BAR
`)
th.WriteF("patch2.yaml", `
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
spec:
template:
spec:
containers:
- name: nginx
env:
- name: ANOTHERENV
value: HELLO
- name: busybox
image: busybox
`)
th.RunTransformerAndCheckResult(`
apiVersion: builtin
kind: PatchStrategicMergeTransformer
metadata:
name: notImportantHere
paths:
- patch1.yaml
- patch2.yaml
`,
target, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
replica: 2
template:
metadata:
labels:
old-label: old-value
spec:
containers:
- env:
- name: ANOTHERENV
value: HELLO
- name: SOMEENV
value: BAR
image: nginx:latest
name: nginx
- image: busybox
name: busybox
`)
}
func TestStrategicMergeTransformerWrongNamespace(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t).
PrepBuiltin("PatchStrategicMergeTransformer")
defer th.Reset()
th.WriteF("patch.yaml", `
apiVersion: apps/v1
metadata:
name: myDeploy
namespace: namespace2
kind: Deployment
spec:
template:
spec:
containers:
- name: nginx
image: nginx:latest
env:
- name: SOMEENV
value: BAR
`)
_, err := th.RunTransformer(`
apiVersion: builtin
kind: PatchStrategicMergeTransformer
metadata:
name: notImportantHere
paths:
- patch.yaml
`, targetWithNamespace)
if assert.Error(t, err) && !errorContains(
err, "failed to find unique target for patch") {
t.Fatalf("expected error to contain %q but get %v", "failed to find target for patch", err)
}
}
// issue #2734 -- https://github.com/kubernetes-sigs/kustomize/issues/2734
// kyaml cleans up things some folks prefer it didnt
// 1. [] -- see initContainers and imagePullSecrets
// 2. {} -- see emptyDir
// 3. null -- see creationTimestamp
const anUncleanDeploymentResource = `apiVersion: apps/v1
kind: Deployment
metadata:
name: sas-crunchy-data-postgres-operator
spec:
replicas: 1
template:
metadata:
creationTimestamp: null
spec:
serviceAccountName: postgres-operator
containers:
- name: apiserver
image: sas-crunchy-data-operator-api-server
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8443
envFrom: []
volumeMounts:
- name: security-ssh
mountPath: /security-ssh
- mountPath: /tmp
name: tmp
imagePullSecrets: []
initContainers: []
volumes:
- emptyDir: {}
name: security-ssh
- emptyDir: {}
name: tmp
`
// This is the preffered result (and what we get with kustomize 3.7.0)
const expectedCleanedDeployment = `apiVersion: apps/v1
kind: Deployment
metadata:
labels:
workload.sas.com/class: stateless
name: sas-crunchy-data-postgres-operator
spec:
replicas: 1
template:
metadata:
creationTimestamp: null
labels:
workload.sas.com/class: stateless
spec:
containers:
- envFrom: []
image: sas-crunchy-data-operator-api-server
imagePullPolicy: IfNotPresent
name: apiserver
ports:
- containerPort: 8443
volumeMounts:
- mountPath: /security-ssh
name: security-ssh
- mountPath: /tmp
name: tmp
imagePullSecrets: []
initContainers: []
serviceAccountName: postgres-operator
tolerations:
- effect: NoSchedule
key: workload.sas.com/class
operator: Equal
value: stateful
volumes:
- emptyDir: {}
name: security-ssh
- emptyDir: {}
name: tmp
`
func TestPatchStrategicMergeTransformerCleanupItems(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t).
PrepBuiltin("PatchStrategicMergeTransformer")
defer th.Reset()
th.WriteF("/patch.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: sas-crunchy-data-postgres-operator
labels:
workload.sas.com/class: stateless
spec:
template:
metadata:
labels:
workload.sas.com/class: stateless
spec:
tolerations:
- effect: NoSchedule
key: workload.sas.com/class
operator: Equal
value: stateful
`)
th.RunTransformerAndCheckResult(`
apiVersion: builtin
kind: PatchStrategicMergeTransformer
metadata:
name: notImportantHere
paths:
- patch.yaml
`,
anUncleanDeploymentResource,
expectedCleanedDeployment) // prefer expectedCleanedDeployment
}
func TestStrategicMergeTransformerNoSchema(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t).
PrepBuiltin("PatchStrategicMergeTransformer")
defer th.Reset()
th.WriteF("patch.yaml", `
apiVersion: example.com/v1
kind: Foo
metadata:
name: my-foo
spec:
bar:
B:
C: Z
`)
th.RunTransformerAndCheckResult(`
apiVersion: builtin
kind: PatchStrategicMergeTransformer
metadata:
name: notImportantHere
paths:
- patch.yaml
`,
targetNoschema,
`
apiVersion: example.com/v1
kind: Foo
metadata:
name: my-foo
spec:
bar:
A: X
C: Z
`)
}
func TestStrategicMergeTransformerNoSchemaMultiPatches(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t).
PrepBuiltin("PatchStrategicMergeTransformer")
defer th.Reset()
// This patch wants to delete "B".
th.WriteF("patch1.yaml", `
apiVersion: example.com/v1
kind: Foo
metadata:
name: my-foo
spec:
bar:
B:
C: Z
`)
th.WriteF("patch2.yaml", `
apiVersion: example.com/v1
kind: Foo
metadata:
name: my-foo
spec:
bar:
C: Z
D: W
baz:
hello: world
`)
resMap, err := th.RunTransformer(`
apiVersion: builtin
kind: PatchStrategicMergeTransformer
metadata:
name: notImportantHere
paths:
- patch1.yaml
- patch2.yaml
`, `apiVersion: example.com/v1
kind: Foo
metadata:
name: my-foo
spec:
bar:
A: X
B: Y
`)
require.NoError(t, err)
th.AssertActualEqualsExpectedNoIdAnnotations(
resMap, `
apiVersion: example.com/v1
kind: Foo
metadata:
name: my-foo
spec:
bar:
A: X
C: Z
D: W
baz:
hello: world
`)
resMap, err = th.RunTransformer(`
apiVersion: builtin
kind: PatchStrategicMergeTransformer
metadata:
name: notImportantHere
paths:
- patch2.yaml
`, `apiVersion: example.com/v1
kind: Foo
metadata:
name: my-foo
spec:
bar:
A: X
B: Y
`)
require.NoError(t, err)
th.AssertActualEqualsExpectedNoIdAnnotations(
// This time only patch2 is applied.
resMap, `
apiVersion: example.com/v1
kind: Foo
metadata:
name: my-foo
spec:
bar:
A: X
B: "Y"
C: Z
D: W
baz:
hello: world
`)
}
// simple utility function to add an namespace in a resource
// used as base, patch or expected result. Simply looks
// for specs: in order to add namespace: xxxx before this line
func addNamespace(namespace string, base string) string {
res := strings.Replace(base,
"\nspec:\n",
"\n namespace: "+namespace+"\nspec:\n",
1)
return res
}
// compareExpectedError compares the expectedError and the actualError return by GetFieldValue
func compareExpectedError(t *testing.T, name string, err error, errorMsg string) {
if assert.Error(t, err, name) && !errorContains(err, errorMsg) {
t.Fatalf("%q; - expected error: \"%s\", got error: \"%v\"",
name, errorMsg, err.Error())
}
}
const Deployment string = "Deployment"
const MyCRD string = "MyCRD"
// baseResource produces a base object which used to test
// patch transformation
// Also the structure is matching the Deployment syntax
// the kind can be replaced to allow testing using CRD
// without access to the schema
func baseResource(kind string) string {
res := `
apiVersion: apps/v1
kind: %s
metadata:
name: deploy1
spec:
template:
metadata:
labels:
old-label: old-value
spec:
containers:
- name: nginx
image: nginx`
return fmt.Sprintf(res, kind)
}
// addContainerAndEnvPatch produces a patch object which adds
// an entry in the env slice of the first/nginx container
// as well as adding a label in the metadata
// Note that for SMP/WithSchema merge, the name:nginx entry
// is mandatory
func addLabelAndEnvPatch(kind string) string {
res := `
apiVersion: apps/v1
kind: %s
metadata:
name: deploy1
spec:
template:
metadata:
labels:
some-label: some-value
spec:
containers:
- name: nginx
env:
- name: SOMEENV
value: SOMEVALUE`
return fmt.Sprintf(res, kind)
}
// addContainerAndEnvPatch produces a patch object which adds
// an entry in the env slice of the first/nginx container
// as well as adding a second container in the container list
// Note that for SMP/WithSchema merge, the name:nginx entry
// is mandatory
func addContainerAndEnvPatch(kind string) string {
res := `
apiVersion: apps/v1
kind: %s
metadata:
name: deploy1
spec:
template:
spec:
containers:
- name: nginx
env:
- name: ANOTHERENV
value: ANOTHERVALUE
- name: anothercontainer
image: anotherimage`
return fmt.Sprintf(res, kind)
}
// addContainerAndEnvPatch produces a patch object which replaces
// the value of the image field in the first/nginx container
// Note that for SMP/WithSchema merge, the name:nginx entry
// is mandatory
func changeImagePatch(kind string, newImage string) string {
res := `
apiVersion: apps/v1
kind: %s
metadata:
name: deploy1
spec:
template:
spec:
containers:
- name: nginx
image: %s`
return fmt.Sprintf(res, kind, newImage)
}
// utility method building the expected output of a SMP
func expectedResultSMP() string {
return `apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy1
spec:
template:
metadata:
labels:
old-label: old-value
some-label: some-value
spec:
containers:
- env:
- name: SOMEENV
value: SOMEVALUE
image: nginx
name: nginx
`
}
// utility method building the expected output of a JMP.
// imagename parameter allows to build a result consistent
// with the JMP behavior which basically overrides the
// entire "containers" list.
func expectedResultJMP(imagename string) string {
res := `apiVersion: apps/v1
kind: MyCRD
metadata:
name: deploy1
spec:
template:
metadata:
labels:
old-label: old-value
some-label: some-value
spec:
containers:
- env:
- name: SOMEENV
value: SOMEVALUE
name: nginx
`
if imagename == "" {
return res
}
res = `apiVersion: apps/v1
kind: MyCRD
metadata:
name: deploy1
spec:
template:
metadata:
labels:
old-label: old-value
some-label: some-value
spec:
containers:
- image: %s
name: nginx
`
return fmt.Sprintf(res, imagename)
}
// utility method to build the expected result of a multipatch
// the order of the patches still have influence especially
// in the insertion location within arrays.
func expectedResultMultiPatch(kind string, reversed bool) string {
res := `apiVersion: apps/v1
kind: %s
metadata:
name: deploy1
spec:
template:
metadata:
labels:
old-label: old-value
some-label: some-value
spec:
containers:
- env:
- name: ANOTHERENV
value: ANOTHERVALUE
- name: SOMEENV
value: SOMEVALUE
image: nginx:latest
name: nginx
- image: anotherimage
name: anothercontainer
`
reversedres := `apiVersion: apps/v1
kind: %s
metadata:
name: deploy1
spec:
template:
metadata:
labels:
old-label: old-value
some-label: some-value
spec:
containers:
- env:
- name: SOMEENV
value: SOMEVALUE
- name: ANOTHERENV
value: ANOTHERVALUE
image: nginx:latest
name: nginx
- image: anotherimage
name: anothercontainer
`
if reversed {
return fmt.Sprintf(reversedres, kind)
}
return fmt.Sprintf(res, kind)
}
func toConfig(patches ...string) string {
config := `
apiVersion: builtin
kind: PatchStrategicMergeTransformer
metadata:
name: notImportantHere
paths:
`
for idx := range patches {
config = fmt.Sprintf("%s\n- ./patch%d.yaml", config, idx)
}
return config
}
// TestSinglePatch validates the single patch use cases
// regarless of the schema availibility, which in turns
// relies on StrategicMergePatch or simple JSON Patch.
func TestSinglePatch(t *testing.T) {
tests := []struct {
name string
base string
patch string
expected string
errorExpected bool
errorMsg string
}{
{
name: "withschema",
base: baseResource(Deployment),
patch: addLabelAndEnvPatch(Deployment),
errorExpected: false,
expected: expectedResultSMP(),
},
{
name: "noschema",
base: baseResource(MyCRD),
patch: addLabelAndEnvPatch(MyCRD),
errorExpected: false,
expected: expectedResultJMP(""),
},
}
th := kusttest_test.MakeEnhancedHarness(t).
PrepBuiltin("PatchStrategicMergeTransformer")
defer th.Reset()
for _, test := range tests {
th.ResetLoaderRoot(fmt.Sprintf("/%s", test.name))
th.WriteF(fmt.Sprintf("/%s/patch%d.yaml", test.name, 0), test.patch)
if test.errorExpected {
_, err := th.RunTransformer(toConfig(test.patch), test.base)
compareExpectedError(t, test.name, err, test.errorMsg)
} else {
th.RunTransformerAndCheckResult(
toConfig(test.patch), test.base, test.expected)
}
}
}
type testRecord struct {
base string
patch []string
expected string
errorExpected bool
errorMsg string
}
// TestMultiplePatches checks that the patches are applied
// properly, that the same result is obtained,
// regardless of the order of the patches and regardless
// of the schema availability (SMP vs JSON)
func TestMultiplePatches(t *testing.T) {
tests := map[string]testRecord{
"withschema-label-image-container": {
base: baseResource(Deployment),
patch: []string{
addLabelAndEnvPatch(Deployment),
changeImagePatch(Deployment, "nginx:latest"),
addContainerAndEnvPatch(Deployment),
},
expected: expectedResultMultiPatch(Deployment, false),
},
"withschema-image-container-label": {
base: baseResource(Deployment),
patch: []string{
changeImagePatch(Deployment, "nginx:latest"),
addContainerAndEnvPatch(Deployment),
addLabelAndEnvPatch(Deployment),
},
expected: expectedResultMultiPatch(Deployment, true),
},
"withschema-container-label-image": {
base: baseResource(Deployment),
patch: []string{
addContainerAndEnvPatch(Deployment),
addLabelAndEnvPatch(Deployment),
changeImagePatch(Deployment, "nginx:latest"),
},
expected: expectedResultMultiPatch(Deployment, true),
},
"noschema-1.7.9-label-latest": {
base: baseResource(MyCRD),
patch: []string{
changeImagePatch(MyCRD, "nginx:1.7.9"),
addLabelAndEnvPatch(MyCRD),
changeImagePatch(MyCRD, "nginx:latest"),
},
errorExpected: false,
// Theses patches aren't commutable (you get a different result
// if they are ordered differently). This is allowed without error.
expected: expectedResultJMP("nginx:latest"),
},
"noschema-latest-label-1.7.9": {
base: baseResource(MyCRD),
patch: []string{
changeImagePatch(MyCRD, "nginx:latest"),
addLabelAndEnvPatch(MyCRD),
changeImagePatch(MyCRD, "nginx:1.7.9"),
},
errorExpected: false,
// Theses patches aren't commutable (you get a different result
// if they are ordered differently). This is allowed without error.
expected: expectedResultJMP("nginx:1.7.9"),
},
}
th := kusttest_test.MakeEnhancedHarness(t).
PrepBuiltin("PatchStrategicMergeTransformer")
defer th.Reset()
for name, test := range tests {
t.Run(name, func(t *testing.T) {
th.ResetLoaderRoot(fmt.Sprintf("/%s", name))
for idx, patch := range test.patch {
th.WriteF(fmt.Sprintf("/%s/patch%d.yaml", name, idx), patch)
}
if test.errorExpected {
_, err := th.RunTransformer(toConfig(test.patch...), test.base)
compareExpectedError(t, name, err, test.errorMsg)
} else {
th.RunTransformerAndCheckResult(
toConfig(test.patch...), test.base, test.expected)
}
})
}
}
// TestMultipleNamespaces before the same patch
// on two objects have the same name but in a different namespaces
func TestMultipleNamespaces(t *testing.T) {
tests := []struct {
name string
base []string
patch []string
expected []string
errorExpected bool
errorMsg string
}{
{
name: "withschema-ns1-ns2",
base: []string{
addNamespace("ns1", baseResource(Deployment)),
addNamespace("ns2", baseResource(Deployment)),
},
patch: []string{
addNamespace("ns1", addLabelAndEnvPatch(Deployment)),
addNamespace("ns2", addLabelAndEnvPatch(Deployment)),
},
errorExpected: false,
expected: []string{
addNamespace("ns1", expectedResultSMP()),
addNamespace("ns2", expectedResultSMP()),
},
},
{
name: "noschema-ns1-ns2",
base: []string{
addNamespace("ns1", baseResource(MyCRD)),
addNamespace("ns2", baseResource(MyCRD)),
},
patch: []string{
addNamespace("ns1", addLabelAndEnvPatch(MyCRD)),
addNamespace("ns2", addLabelAndEnvPatch(MyCRD)),
},
errorExpected: false,
expected: []string{
addNamespace("ns1", expectedResultJMP("")),
addNamespace("ns2", expectedResultJMP("")),
},
},
{
name: "withschema-ns1-ns2",
base: []string{addNamespace("ns1", baseResource(Deployment))},
patch: []string{addNamespace("ns2", changeImagePatch(Deployment, "nginx:1.7.9"))},
errorExpected: true,
errorMsg: "failed to find unique target for patch",
},
{
name: "withschema-nil-ns2",
base: []string{baseResource(Deployment)},
patch: []string{addNamespace("ns2", changeImagePatch(Deployment, "nginx:1.7.9"))},
errorExpected: true,
errorMsg: "failed to find unique target for patch",
},
{
name: "withschema-ns1-nil",
base: []string{addNamespace("ns1", baseResource(Deployment))},
patch: []string{changeImagePatch(Deployment, "nginx:1.7.9")},
errorExpected: true,
errorMsg: "failed to find unique target for patch",
},
{
name: "noschema-ns1-ns2",
base: []string{addNamespace("ns1", baseResource(MyCRD))},
patch: []string{addNamespace("ns2", changeImagePatch(MyCRD, "nginx:1.7.9"))},
errorExpected: true,
errorMsg: "failed to find unique target for patch",
},
{
name: "noschema-nil-ns2",
base: []string{baseResource(MyCRD)},
patch: []string{addNamespace("ns2", changeImagePatch(MyCRD, "nginx:1.7.9"))},
errorExpected: true,
errorMsg: "failed to find unique target for patch",
},
{
name: "noschema-ns1-nil",
base: []string{addNamespace("ns1", baseResource(MyCRD))},
patch: []string{changeImagePatch(MyCRD, "nginx:1.7.9")},
errorExpected: true,
errorMsg: "failed to find unique target for patch",
},
}
th := kusttest_test.MakeEnhancedHarness(t).
PrepBuiltin("PatchStrategicMergeTransformer")
defer th.Reset()
for _, test := range tests {
th.ResetLoaderRoot(fmt.Sprintf("/%s", test.name))
for idx, patch := range test.patch {
th.WriteF(fmt.Sprintf("/%s/patch%d.yaml", test.name, idx), patch)
}
if test.errorExpected {
_, err := th.RunTransformer(
toConfig(test.patch...), strings.Join(test.base, "\n---\n"))
compareExpectedError(t, test.name, err, test.errorMsg)
} else {
th.RunTransformerAndCheckResult(
toConfig(test.patch...),
strings.Join(test.base, "\n---\n"),
strings.Join(test.expected, "---\n"))
}
}
}
func TestPatchStrategicMergeTransformerPatchDelete1(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t).
PrepBuiltin("PatchStrategicMergeTransformer")
defer th.Reset()
th.WriteF("patch.yaml", `
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
spec:
replica: 2
template:
$patch: delete
metadata:
labels:
old-label: old-value
spec:
containers:
- name: nginx
image: nginx
`)
rm := th.LoadAndRunTransformer(`
apiVersion: builtin
kind: PatchStrategicMergeTransformer
metadata:
name: notImportantHere
paths:
- patch.yaml
`, target)
th.AssertActualEqualsExpectedNoIdAnnotations(rm, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
replica: 2
`)
}
func TestPatchStrategicMergeTransformerPatchDelete2(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t).
PrepBuiltin("PatchStrategicMergeTransformer")
defer th.Reset()
th.WriteF("patch.yaml", `
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
spec:
$patch: delete
replica: 2
template:
metadata:
labels:
old-label: old-value
spec:
containers:
- name: nginx
image: nginx
`)
rm := th.LoadAndRunTransformer(`
apiVersion: builtin
kind: PatchStrategicMergeTransformer
metadata:
name: notImportantHere
paths:
- patch.yaml
`, target)
th.AssertActualEqualsExpectedNoIdAnnotations(rm, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
`)
}
func TestPatchStrategicMergeTransformerPatchDelete3(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t).
PrepBuiltin("PatchStrategicMergeTransformer")
defer th.Reset()
th.WriteF("patch.yaml", `
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
$patch: delete
`)
rm := th.LoadAndRunTransformer(`
apiVersion: builtin
kind: PatchStrategicMergeTransformer
metadata:
name: notImportantHere
paths:
- patch.yaml
`, target)
th.AssertActualEqualsExpected(rm, ``)
}