// Copyright 2019 The Kubernetes Authors. // SPDX-License-Identifier: Apache-2.0 package commands_test import ( "bytes" "io/ioutil" "os" "path/filepath" "strings" "testing" "github.com/stretchr/testify/assert" "sigs.k8s.io/kustomize/cmd/config/internal/commands" "sigs.k8s.io/kustomize/kyaml/copyutil" "sigs.k8s.io/kustomize/kyaml/openapi" ) // TODO(pwittrock): write tests for reading / writing ResourceLists func TestCmd_files(t *testing.T) { d, err := ioutil.TempDir("", "kustomize-cat-test") if !assert.NoError(t, err) { return } defer os.RemoveAll(d) err = ioutil.WriteFile(filepath.Join(d, "f1.yaml"), []byte(` kind: Deployment metadata: labels: app: nginx2 name: foo annotations: app: nginx2 spec: replicas: 1 --- kind: Service metadata: name: foo annotations: app: nginx spec: selector: app: nginx `), 0600) if !assert.NoError(t, err) { return } err = ioutil.WriteFile(filepath.Join(d, "f2.yaml"), []byte(` apiVersion: v1 kind: Abstraction metadata: name: foo configFn: container: image: gcr.io/example/reconciler:v1 annotations: config.kubernetes.io/local-config: "true" spec: replicas: 3 --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx name: bar annotations: app: nginx spec: replicas: 3 `), 0600) if !assert.NoError(t, err) { return } // fmt the files b := &bytes.Buffer{} r := commands.GetCatRunner("") r.Command.SetArgs([]string{d}) r.Command.SetOut(b) if !assert.NoError(t, r.Command.Execute()) { return } if !assert.Equal(t, `kind: Deployment metadata: labels: app: nginx2 name: foo annotations: app: nginx2 spec: replicas: 1 --- kind: Service metadata: name: foo annotations: app: nginx spec: selector: app: nginx --- apiVersion: apps/v1 kind: Deployment metadata: name: bar labels: app: nginx annotations: app: nginx spec: replicas: 3 `, b.String()) { return } } func TestCmd_filesWithReconcilers(t *testing.T) { d, err := ioutil.TempDir("", "kustomize-cat-test") if !assert.NoError(t, err) { return } defer os.RemoveAll(d) err = ioutil.WriteFile(filepath.Join(d, "f1.yaml"), []byte(` kind: Deployment metadata: labels: app: nginx2 name: foo annotations: app: nginx2 spec: replicas: 1 --- kind: Service metadata: name: foo annotations: app: nginx spec: selector: app: nginx `), 0600) if !assert.NoError(t, err) { return } err = ioutil.WriteFile(filepath.Join(d, "f2.yaml"), []byte(` apiVersion: v1 kind: Abstraction metadata: name: foo configFn: container: image: gcr.io/example/image:version annotations: config.kubernetes.io/local-config: "true" spec: replicas: 3 --- kind: Deployment metadata: labels: app: nginx name: bar annotations: app: nginx spec: replicas: 3`), 0600) if !assert.NoError(t, err) { return } // fmt the files b := &bytes.Buffer{} r := commands.GetCatRunner("") r.Command.SetArgs([]string{d, "--include-local"}) r.Command.SetOut(b) if !assert.NoError(t, r.Command.Execute()) { return } if !assert.Equal(t, `kind: Deployment metadata: labels: app: nginx2 name: foo annotations: app: nginx2 spec: replicas: 1 --- kind: Service metadata: name: foo annotations: app: nginx spec: selector: app: nginx --- apiVersion: v1 kind: Abstraction metadata: name: foo annotations: config.kubernetes.io/local-config: "true" configFn: container: image: gcr.io/example/image:version spec: replicas: 3 --- kind: Deployment metadata: labels: app: nginx name: bar annotations: app: nginx spec: replicas: 3 `, b.String()) { return } } func TestCmd_filesWithoutNonReconcilers(t *testing.T) { d, err := ioutil.TempDir("", "kustomize-cat-test") if !assert.NoError(t, err) { return } defer os.RemoveAll(d) err = ioutil.WriteFile(filepath.Join(d, "f1.yaml"), []byte(` kind: Deployment metadata: labels: app: nginx2 name: foo annotations: app: nginx2 spec: replicas: 1 --- kind: Service metadata: name: foo annotations: app: nginx spec: selector: app: nginx `), 0600) if !assert.NoError(t, err) { return } err = ioutil.WriteFile(filepath.Join(d, "f2.yaml"), []byte(` apiVersion: v1 kind: Abstraction metadata: name: foo annotations: config.kubernetes.io/local-config: "true" configFn: container: image: gcr.io/example/reconciler:v1 spec: replicas: 3 --- kind: Deployment metadata: labels: app: nginx name: bar annotations: app: nginx spec: replicas: 3 `), 0600) if !assert.NoError(t, err) { return } // fmt the files b := &bytes.Buffer{} r := commands.GetCatRunner("") r.Command.SetArgs([]string{d, "--include-local", "--exclude-non-local"}) r.Command.SetOut(b) if !assert.NoError(t, r.Command.Execute()) { return } if !assert.Equal(t, `apiVersion: v1 kind: Abstraction metadata: name: foo annotations: config.kubernetes.io/local-config: "true" configFn: container: image: gcr.io/example/reconciler:v1 spec: replicas: 3 `, b.String()) { return } } func TestCmd_outputTruncateFile(t *testing.T) { d, err := ioutil.TempDir("", "kustomize-cat-test") if !assert.NoError(t, err) { return } defer os.RemoveAll(d) err = ioutil.WriteFile(filepath.Join(d, "f1.yaml"), []byte(` kind: Deployment metadata: labels: app: nginx2 name: foo annotations: app: nginx2 spec: replicas: 1 --- kind: Service metadata: name: foo annotations: app: nginx spec: selector: app: nginx `), 0600) if !assert.NoError(t, err) { return } err = ioutil.WriteFile(filepath.Join(d, "f2.yaml"), []byte(` apiVersion: v1 kind: Abstraction metadata: name: foo configFn: container: image: gcr.io/example/reconciler:v1 annotations: config.kubernetes.io/local-config: "true" spec: replicas: 3 --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx name: bar annotations: app: nginx spec: replicas: 3`), 0600) if !assert.NoError(t, err) { return } f, err := ioutil.TempFile("", "kustomize-cat-test-dest") if !assert.NoError(t, err) { return } defer os.RemoveAll(d) // fmt the files b := &bytes.Buffer{} r := commands.GetCatRunner("") r.Command.SetArgs([]string{d, "--dest", f.Name()}) r.Command.SetOut(b) if !assert.NoError(t, r.Command.Execute()) { return } if !assert.Equal(t, ``, b.String()) { return } actual, err := ioutil.ReadFile(f.Name()) if !assert.NoError(t, err) { return } if !assert.Equal(t, `kind: Deployment metadata: labels: app: nginx2 name: foo annotations: app: nginx2 spec: replicas: 1 --- kind: Service metadata: name: foo annotations: app: nginx spec: selector: app: nginx --- apiVersion: apps/v1 kind: Deployment metadata: name: bar labels: app: nginx annotations: app: nginx spec: replicas: 3 `, string(actual)) { return } } func TestCmd_outputCreateFile(t *testing.T) { d, err := ioutil.TempDir("", "kustomize-cat-test") if !assert.NoError(t, err) { return } defer os.RemoveAll(d) err = ioutil.WriteFile(filepath.Join(d, "f1.yaml"), []byte(` kind: Deployment metadata: labels: app: nginx2 name: foo annotations: app: nginx2 spec: replicas: 1 --- kind: Service metadata: name: foo annotations: app: nginx spec: selector: app: nginx `), 0600) if !assert.NoError(t, err) { return } err = ioutil.WriteFile(filepath.Join(d, "f2.yaml"), []byte(` apiVersion: v1 kind: Abstraction metadata: name: foo configFn: container: image: gcr.io/example/reconciler:v1 annotations: config.kubernetes.io/local-config: "true" spec: replicas: 3 --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx name: bar annotations: app: nginx spec: replicas: 3`), 0600) if !assert.NoError(t, err) { return } d2, err := ioutil.TempDir("", "kustomize-cat-test-dest") if !assert.NoError(t, err) { return } defer os.RemoveAll(d2) f := filepath.Join(d2, "output.yaml") // fmt the files b := &bytes.Buffer{} r := commands.GetCatRunner("") r.Command.SetArgs([]string{d, "--dest", f}) r.Command.SetOut(b) if !assert.NoError(t, r.Command.Execute()) { return } if !assert.Equal(t, ``, b.String()) { return } actual, err := ioutil.ReadFile(f) if !assert.NoError(t, err) { return } if !assert.Equal(t, `kind: Deployment metadata: labels: app: nginx2 name: foo annotations: app: nginx2 spec: replicas: 1 --- kind: Service metadata: name: foo annotations: app: nginx spec: selector: app: nginx --- apiVersion: apps/v1 kind: Deployment metadata: name: bar labels: app: nginx annotations: app: nginx spec: replicas: 3 `, string(actual)) { return } } func TestCatSubPackages(t *testing.T) { var tests = []struct { name string dataset string packagePath string args []string expected string }{ { name: "cat-recurse-subpackages", dataset: "dataset-without-setters", expected: ` # Copyright 2019 The Kubernetes Authors. # SPDX-License-Identifier: Apache-2.0 apiVersion: apps/v1 kind: Deployment metadata: name: mysql-deployment namespace: myspace spec: replicas: 3 template: spec: containers: - name: mysql image: mysql:1.7.9 --- # Copyright 2019 The Kubernetes Authors. # SPDX-License-Identifier: Apache-2.0 apiVersion: apps/v1 kind: Deployment metadata: name: storage-deployment namespace: myspace spec: replicas: 4 template: spec: containers: - name: storage image: storage:1.7.7 `, }, { name: "cat-top-level-pkg-no-recurse-subpackages", dataset: "dataset-without-setters", args: []string{"-R=false"}, packagePath: "mysql", expected: `# Copyright 2019 The Kubernetes Authors. # SPDX-License-Identifier: Apache-2.0 apiVersion: apps/v1 kind: Deployment metadata: name: mysql-deployment namespace: myspace spec: replicas: 3 template: spec: containers: - name: mysql image: mysql:1.7.9 `, }, { name: "cat-nested-pkg-no-recurse-subpackages", dataset: "dataset-without-setters", packagePath: "mysql/storage", args: []string{"-R=false"}, expected: `# Copyright 2019 The Kubernetes Authors. # SPDX-License-Identifier: Apache-2.0 apiVersion: apps/v1 kind: Deployment metadata: name: storage-deployment namespace: myspace spec: replicas: 4 template: spec: containers: - name: storage image: storage:1.7.7 `, }, } for i := range tests { test := tests[i] t.Run(test.name, func(t *testing.T) { // reset the openAPI afterward openapi.ResetOpenAPI() defer openapi.ResetOpenAPI() sourceDir := filepath.Join("test", "testdata", test.dataset) baseDir, err := ioutil.TempDir("", "") if !assert.NoError(t, err) { t.FailNow() } copyutil.CopyDir(sourceDir, baseDir) defer os.RemoveAll(baseDir) runner := commands.GetCatRunner("") actual := &bytes.Buffer{} runner.Command.SetOut(actual) runner.Command.SetArgs(append([]string{filepath.Join(baseDir, test.packagePath)}, test.args...)) err = runner.Command.Execute() if !assert.NoError(t, err) { t.FailNow() } // normalize path format for windows actualNormalized := strings.ReplaceAll( strings.ReplaceAll(actual.String(), "\\", "/"), "//", "/") expected := strings.ReplaceAll(test.expected, "${baseDir}", baseDir) expectedNormalized := strings.ReplaceAll(expected, "\\", "/") if !assert.Equal(t, expectedNormalized, actualNormalized) { t.FailNow() } }) } }