// 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/kio/filters/testyaml" "sigs.k8s.io/kustomize/kyaml/openapi" "sigs.k8s.io/kustomize/kyaml/testutil" ) // TestCmd_files verifies the fmt command formats the files func TestFmtCommand_files(t *testing.T) { f1, err := ioutil.TempFile("", "cmdfmt*.yaml") if !assert.NoError(t, err) { return } defer os.RemoveAll(f1.Name()) err = ioutil.WriteFile(f1.Name(), testyaml.UnformattedYaml1, 0600) if !assert.NoError(t, err) { return } f2, err := ioutil.TempFile("", "cmdfmt*.yaml") if !assert.NoError(t, err) { return } defer os.RemoveAll(f2.Name()) err = ioutil.WriteFile(f2.Name(), testyaml.UnformattedYaml2, 0600) if !assert.NoError(t, err) { return } // fmt the files r := commands.GetFmtRunner("") r.Command.SetArgs([]string{f1.Name(), f2.Name()}) err = r.Command.Execute() if !assert.NoError(t, err) { return } // verify the contents b, err := ioutil.ReadFile(f1.Name()) if !assert.NoError(t, err) { return } if !assert.Equal(t, string(testyaml.FormattedYaml1), string(b)) { return } b, err = ioutil.ReadFile(f2.Name()) if !assert.NoError(t, err) { return } if !assert.Equal(t, string(testyaml.FormattedYaml2), string(b)) { return } } func TestFmtCommand_stdin(t *testing.T) { out := &bytes.Buffer{} r := commands.GetFmtRunner("") r.Command.SetOut(out) r.Command.SetIn(bytes.NewReader(testyaml.UnformattedYaml1)) // fmt the input err := r.Command.Execute() assert.NoError(t, err) // verify the output assert.Contains(t, out.String(), string(testyaml.FormattedYaml1)) } // TestCmd_filesAndstdin verifies that if both files and stdin input are provided, only // the files are formatted and the input is ignored func TestFmtCmd_filesAndStdin(t *testing.T) { f1, err := ioutil.TempFile("", "cmdfmt*.yaml") if !assert.NoError(t, err) { return } err = ioutil.WriteFile(f1.Name(), testyaml.UnformattedYaml1, 0600) if !assert.NoError(t, err) { return } f2, err := ioutil.TempFile("", "cmdfmt*.yaml") if !assert.NoError(t, err) { return } err = ioutil.WriteFile(f2.Name(), testyaml.UnformattedYaml2, 0600) if !assert.NoError(t, err) { return } out := &bytes.Buffer{} in := &bytes.Buffer{} r := commands.GetFmtRunner("") r.Command.SetOut(out) r.Command.SetIn(in) // fmt the files r = commands.GetFmtRunner("") r.Command.SetArgs([]string{f1.Name(), f2.Name()}) err = r.Command.Execute() if !assert.NoError(t, err) { return } // verify the output b, err := ioutil.ReadFile(f1.Name()) if !assert.NoError(t, err) { return } if !assert.Equal(t, string(testyaml.FormattedYaml1), string(b)) { return } b, err = ioutil.ReadFile(f2.Name()) if !assert.NoError(t, err) { return } if !assert.Equal(t, string(testyaml.FormattedYaml2), string(b)) { return } err = r.Command.Execute() if !assert.NoError(t, err) { return } if !assert.Equal(t, "", out.String()) { return } } // TestCmd_files verifies the fmt command formats the files func TestCmd_failFiles(t *testing.T) { // fmt the files r := commands.GetFmtRunner("") r.Command.SetArgs([]string{"notrealfile"}) r.Command.SilenceUsage = true r.Command.SilenceErrors = true err := r.Command.Execute() testutil.AssertErrorContains(t, err, "notrealfile:") } // TestCmd_files verifies the fmt command formats the files func TestCmd_failFileContents(t *testing.T) { out := &bytes.Buffer{} r := commands.GetFmtRunner("") r.Command.SetOut(out) r.Command.SetIn(strings.NewReader(`{`)) // fmt the input err := r.Command.Execute() // expect an error assert.EqualError(t, err, "yaml: line 1: did not find expected node content") } func TestFmtSubPackages(t *testing.T) { var tests = []struct { name string dataset string packagePath string args []string expected string }{ { name: "fmt-recurse-subpackages", dataset: "dataset-with-setters", args: []string{"-R"}, expected: `${baseDir}/ formatted resource files in the package ${baseDir}/mysql/ formatted resource files in the package ${baseDir}/mysql/nosetters/ formatted resource files in the package ${baseDir}/mysql/storage/ formatted resource files in the package `, }, { name: "fmt-top-level-pkg-no-recurse-subpackages", dataset: "dataset-without-setters", packagePath: "mysql", expected: `${baseDir}/mysql/ formatted resource files in the package `, }, { name: "fmt-nested-pkg-no-recurse-subpackages", dataset: "dataset-without-setters", packagePath: "mysql/storage", expected: `${baseDir}/mysql/storage/ formatted resource files in the package `, }, } 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.GetFmtRunner("") 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.Replace( strings.Replace(actual.String(), "\\", "/", -1), "//", "/", -1) expected := strings.Replace(test.expected, "${baseDir}", baseDir, -1) expectedNormalized := strings.Replace(expected, "\\", "/", -1) if !assert.Contains(t, strings.TrimSpace(actualNormalized), strings.TrimSpace(expectedNormalized)) { t.FailNow() } }) } }