Files
kustomize/api/krusty/gvknpatch_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

848 lines
15 KiB
Go

// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package krusty_test
import (
"testing"
"github.com/stretchr/testify/require"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
)
// Regression test for https://github.com/kubernetes-sigs/kustomize/issues/3280
// GVKN shouldn't change with default options
func TestKeepOriginalGVKN(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteF("deployment.yaml", `
apiVersion: v1
kind: Deployment
metadata:
name: old-name
spec:
template:
spec:
containers:
- name: nginx
image: nginx
`)
th.WriteF("patch.yaml", `
apiVersion: v1
kind: StatefulSet
metadata:
name: new-name
`)
th.WriteK(".", `
resources:
- deployment.yaml
patches:
- path: patch.yaml
target:
kind: Deployment
`)
m := th.Run(".", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: Deployment
metadata:
name: old-name
spec:
template:
spec:
containers:
- image: nginx
name: nginx
`)
}
// https://github.com/kubernetes-sigs/kustomize/issues/3280
// These tests document behavior that will change
func TestChangeName(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteF("deployment.yaml", `
apiVersion: v1
kind: Deployment
metadata:
name: old-name
spec:
template:
spec:
containers:
- name: nginx
image: nginx
`)
th.WriteF("patch.yaml", `
apiVersion: v1
kind: Deployment
metadata:
name: new-name
`)
th.WriteK(".", `
resources:
- deployment.yaml
patches:
- path: patch.yaml
target:
kind: Deployment
options:
allowNameChange: true
`)
options := th.MakeDefaultOptions()
m := th.Run(".", options)
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: Deployment
metadata:
name: new-name
spec:
template:
spec:
containers:
- image: nginx
name: nginx
`)
}
func TestChangeKind(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteF("deployment.yaml", `
apiVersion: v1
kind: Deployment
metadata:
name: old-name
spec:
template:
spec:
containers:
- name: nginx
image: nginx
`)
th.WriteF("patch.yaml", `
apiVersion: v1
kind: StatefulSet
metadata:
name: old-name
`)
th.WriteK(".", `
resources:
- deployment.yaml
patches:
- path: patch.yaml
target:
kind: Deployment
options:
allowKindChange: true
`)
options := th.MakeDefaultOptions()
m := th.Run(".", options)
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: StatefulSet
metadata:
name: old-name
spec:
template:
spec:
containers:
- image: nginx
name: nginx
`)
}
func TestChangeNameAndKind(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteF("deployment.yaml", `
apiVersion: v1
kind: Deployment
metadata:
name: old-name
spec:
template:
spec:
containers:
- name: nginx
image: nginx
`)
th.WriteF("patch.yaml", `
apiVersion: v1
kind: StatefulSet
metadata:
name: new-name
`)
th.WriteK(".", `
resources:
- deployment.yaml
patches:
- path: patch.yaml
target:
kind: Deployment
options:
allowNameChange: true
allowKindChange: true
`)
options := th.MakeDefaultOptions()
m := th.Run(".", options)
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: StatefulSet
metadata:
name: new-name
spec:
template:
spec:
containers:
- image: nginx
name: nginx
`)
}
// Should be able to refer to a resource with either its
// original GVKN or its current one
func TestPatchOriginalName(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteF("base/deployment.yaml", `
apiVersion: v1
kind: Deployment
metadata:
name: old-name
spec:
template:
spec:
containers:
- name: nginx
image: nginx
`)
th.WriteF("base/patch.yaml", `
apiVersion: v1
kind: Deployment
metadata:
name: new-name
`)
th.WriteK("base", `
resources:
- deployment.yaml
patches:
- path: patch.yaml
target:
kind: Deployment
options:
allowNameChange: true
`)
th.WriteK("overlay", `
resources:
- ../base
patchesStrategicMerge:
- depPatch.yaml
`)
th.WriteF("overlay/depPatch.yaml", `
apiVersion: v1
kind: Deployment
metadata:
name: old-name
spec:
replicas: 999
`)
options := th.MakeDefaultOptions()
m := th.Run("overlay", options)
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: Deployment
metadata:
name: new-name
spec:
replicas: 999
template:
spec:
containers:
- image: nginx
name: nginx
`)
}
func TestPatchNewName(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteF("base/deployment.yaml", `
apiVersion: v1
kind: Deployment
metadata:
name: old-name
spec:
template:
spec:
containers:
- name: nginx
image: nginx
`)
th.WriteF("base/patch.yaml", `
apiVersion: v1
kind: Deployment
metadata:
name: new-name
`)
th.WriteK("base", `
resources:
- deployment.yaml
patches:
- path: patch.yaml
target:
kind: Deployment
options:
allowNameChange: true
`)
th.WriteK("overlay", `
resources:
- ../base
patchesStrategicMerge:
- depPatch.yaml
`)
th.WriteF("overlay/depPatch.yaml", `
apiVersion: v1
kind: Deployment
metadata:
name: new-name
spec:
replicas: 999
`)
options := th.MakeDefaultOptions()
m := th.Run("overlay", options)
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: Deployment
metadata:
name: new-name
spec:
replicas: 999
template:
spec:
containers:
- image: nginx
name: nginx
`)
}
func TestPatchOriginalNameAndKind(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteF("base/deployment.yaml", `
apiVersion: v1
kind: Deployment
metadata:
name: old-name
spec:
template:
spec:
containers:
- name: nginx
image: nginx
`)
th.WriteF("base/patch.yaml", `
apiVersion: v1
kind: StatefulSet
metadata:
name: new-name
`)
th.WriteK("base", `
resources:
- deployment.yaml
patches:
- path: patch.yaml
target:
kind: Deployment
options:
allowNameChange: true
allowKindChange: true
`)
th.WriteK("overlay", `
resources:
- ../base
patchesStrategicMerge:
- depPatch.yaml
`)
th.WriteF("overlay/depPatch.yaml", `
apiVersion: v1
kind: Deployment
metadata:
name: old-name
spec:
replicas: 999
`)
options := th.MakeDefaultOptions()
m := th.Run("overlay", options)
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: StatefulSet
metadata:
name: new-name
spec:
replicas: 999
template:
spec:
containers:
- image: nginx
name: nginx
`)
}
func TestPatchNewNameAndKind(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteF("base/deployment.yaml", `
apiVersion: v1
kind: Deployment
metadata:
name: old-name
spec:
template:
spec:
containers:
- name: nginx
image: nginx
`)
th.WriteF("base/patch.yaml", `
apiVersion: v1
kind: StatefulSet
metadata:
name: new-name
`)
th.WriteK("base", `
resources:
- deployment.yaml
patches:
- path: patch.yaml
target:
kind: Deployment
options:
allowNameChange: true
allowKindChange: true
`)
th.WriteK("overlay", `
resources:
- ../base
patchesStrategicMerge:
- depPatch.yaml
`)
th.WriteF("overlay/depPatch.yaml", `
apiVersion: v1
kind: StatefulSet
metadata:
name: new-name
spec:
replicas: 999
`)
options := th.MakeDefaultOptions()
m := th.Run("overlay", options)
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: StatefulSet
metadata:
name: new-name
spec:
replicas: 999
template:
spec:
containers:
- image: nginx
name: nginx
`)
}
// Use original name, but new kind
// Should fail, even after #3280 is done, because this ID is invalid
func TestPatchOriginalNameAndNewKind(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteF("base/deployment.yaml", `
apiVersion: v1
kind: Deployment
metadata:
name: old-name
spec:
template:
spec:
containers:
- name: nginx
image: nginx
`)
th.WriteF("base/patch.yaml", `
apiVersion: v1
kind: StatefulSet
metadata:
name: new-name
`)
th.WriteK("base", `
resources:
- deployment.yaml
patches:
- path: patch.yaml
target:
kind: Deployment
options:
allowNameChange: true
allowKindChange: true
`)
th.WriteK("overlay", `
resources:
- ../base
patchesStrategicMerge:
- depPatch.yaml
`)
th.WriteF("overlay/depPatch.yaml", `
apiVersion: v1
kind: Deployment
metadata:
name: new-name
spec:
replicas: 999
`)
options := th.MakeDefaultOptions()
// depPatch cannot find target with kind `Deployment` and name `new-name`
// because the resource never had this GVKN
require.Error(t, th.RunWithErr("overlay", options))
}
// Here is a structure of a kustomization of two components, component1
// and component2, that both use a shared deployment definition, which
// component2 adjusts by changing the kind via a patch. This test case
// checks that it does not have a conflicting definition.
// Currently documents broken behavior.
//
// root
// / \
// component1/overlay component2/overlay
// | |
// component1/base component2/base
// \ /
// base
//
// This is the directory layout:
//
// ├── component1
// │ ├── base
// │ │ └── kustomization.yaml
// │ └── overlay
// │ └── kustomization.yaml
// ├── component2
// │ ├── base
// │ │ └── kustomization.yaml
// │ └── overlay
// │ └── kustomization.yaml
// ├── shared
// │ ├── kustomization.yaml
// │ └── deployment.yaml
// ├── kustomization.yaml
func TestBaseReuseNameAndKindConflict(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK("shared", `
resources:
- deployment.yaml
`)
th.WriteF("shared/deployment.yaml", `
apiVersion: v1
kind: Deployment
metadata:
name: my-deploy
spec:
template:
spec:
containers:
- name: nginx
image: nginx
`)
th.WriteK("component1/base", `
resources:
- ../../shared
`)
th.WriteK("component1/overlay", `
resources:
- ../base
namePrefix: overlay-
`)
th.WriteK("component2/base", `
resources:
- ../../shared
patches:
- path: patch.yaml
target:
kind: Deployment
name: my-deploy
options:
allowNameChange: true
allowKindChange: true
`)
th.WriteF("component2/base/patch.yaml", `
apiVersion: v1
kind: StatefulSet
metadata:
name: my-stateful-set
`)
th.WriteK("component2/overlay", `
resources:
- ../base
namePrefix: overlay-
`)
th.WriteK(".", `
resources:
- component1/overlay
- component2/overlay
`)
options := th.MakeDefaultOptions()
m := th.Run(".", options)
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: Deployment
metadata:
name: overlay-my-deploy
spec:
template:
spec:
containers:
- image: nginx
name: nginx
---
apiVersion: v1
kind: StatefulSet
metadata:
name: overlay-my-stateful-set
spec:
template:
spec:
containers:
- image: nginx
name: nginx
`)
}
func TestNameReferenceAfterGvknChange(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteF("configMap.yaml", `
apiVersion: v1
kind: ConfigMap
metadata:
name: old-name
`)
th.WriteF("patch.yaml", `
apiVersion: v1
kind: ConfigMap
metadata:
name: new-name
`)
th.WriteF("deployment.yaml", `
apiVersion: v1
kind: Deployment
metadata:
name: deploy
spec:
template:
spec:
containers:
- env:
- valueFrom:
configMapKeyRef:
name: old-name
key: somekey
envFrom:
- configMapRef:
name: old-name
key: somekey
`)
th.WriteK(".", `
resources:
- configMap.yaml
- deployment.yaml
patches:
- path: patch.yaml
target:
kind: ConfigMap
options:
allowNameChange: true
`)
m := th.Run(".", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: ConfigMap
metadata:
name: new-name
---
apiVersion: v1
kind: Deployment
metadata:
name: deploy
spec:
template:
spec:
containers:
- env:
- valueFrom:
configMapKeyRef:
key: somekey
name: new-name
envFrom:
- configMapRef:
key: somekey
name: new-name
`)
}
func TestNameReferenceAfterJsonPatch(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteF("resources.yaml", `
apiVersion: v1
data:
bar: bar
kind: ConfigMap
metadata:
name: cm
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: foo
spec:
selector:
matchLabels:
foo: foo
template:
metadata:
labels:
foo: foo
spec:
containers:
- name: foo
image: example
volumeMounts:
- mountPath: /path
name: myvol
volumes:
- configMap:
name: cm
name: myvol
`)
th.WriteK(".", `
namePrefix: foo-
resources:
- resources.yaml
patches:
- target:
group: apps
version: v1
name: foo
patch: |
- op: replace
path: /kind
value: Deployment
`)
m := th.Run(".", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `apiVersion: v1
data:
bar: bar
kind: ConfigMap
metadata:
name: foo-cm
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: foo-foo
spec:
selector:
matchLabels:
foo: foo
template:
metadata:
labels:
foo: foo
spec:
containers:
- image: example
name: foo
volumeMounts:
- mountPath: /path
name: myvol
volumes:
- configMap:
name: foo-cm
name: myvol
`)
}
func TestNameReferenceAfterJsonPatchConfigMapGenerator(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteF("statefulset.yaml", `
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: foo
spec:
selector:
matchLabels:
foo: foo
template:
metadata:
labels:
foo: foo
spec:
containers:
- name: foo
image: example
volumeMounts:
- mountPath: /path
name: myvol
volumes:
- configMap:
name: cm
name: myvol
`)
th.WriteK(".", `
resources:
- statefulset.yaml
patches:
- target:
group: apps
version: v1
name: foo
patch: |
- op: replace
path: /kind
value: Deployment
configMapGenerator:
- name: cm
literals:
- bar=bar
`)
m := th.Run(".", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `apiVersion: apps/v1
kind: Deployment
metadata:
name: foo
spec:
selector:
matchLabels:
foo: foo
template:
metadata:
labels:
foo: foo
spec:
containers:
- image: example
name: foo
volumeMounts:
- mountPath: /path
name: myvol
volumes:
- configMap:
name: cm-8hm8224gfd
name: myvol
---
apiVersion: v1
data:
bar: bar
kind: ConfigMap
metadata:
name: cm-8hm8224gfd
`)
}