github.com/hashicorp/packer@v1.14.3/command/fmt_test.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: BUSL-1.1 3 4 package command 5 6 import ( 7 "bytes" 8 "fmt" 9 "os" 10 "path/filepath" 11 "strings" 12 "testing" 13 14 "github.com/google/go-cmp/cmp" 15 packersdk "github.com/hashicorp/packer-plugin-sdk/packer" 16 "github.com/stretchr/testify/assert" 17 ) 18 19 func TestFmt(t *testing.T) { 20 s := &strings.Builder{} 21 ui := &packersdk.BasicUi{ 22 Writer: s, 23 } 24 c := &FormatCommand{ 25 Meta: testMeta(t), 26 } 27 28 c.Ui = ui 29 30 args := []string{"-check=true", filepath.Join(testFixture("fmt"), "formatted.pkr.hcl")} 31 if code := c.Run(args); code != 0 { 32 fatalCommand(t, c.Meta) 33 } 34 expected := "" 35 assert.Equal(t, expected, strings.TrimSpace(s.String())) 36 } 37 38 func TestFmt_unformattedPKRVarsTemplate(t *testing.T) { 39 c := &FormatCommand{ 40 Meta: testMeta(t), 41 } 42 43 args := []string{"-check=true", filepath.Join(testFixture("fmt"), "unformatted.pkrvars.hcl")} 44 if code := c.Run(args); code != 3 { 45 fatalCommand(t, c.Meta) 46 } 47 } 48 49 func TestFmt_unfomattedTemlateDirectory(t *testing.T) { 50 c := &FormatCommand{ 51 Meta: testMeta(t), 52 } 53 54 args := []string{"-check=true", filepath.Join(testFixture("fmt"), "")} 55 56 if code := c.Run(args); code != 3 { 57 fatalCommand(t, c.Meta) 58 } 59 } 60 61 const ( 62 unformattedHCL = ` 63 ami_filter_name ="amzn2-ami-hvm-*-x86_64-gp2" 64 ami_filter_owners =[ "137112412989" ] 65 66 ` 67 formattedHCL = ` 68 ami_filter_name = "amzn2-ami-hvm-*-x86_64-gp2" 69 ami_filter_owners = ["137112412989"] 70 71 ` 72 ) 73 74 func TestFmt_Recursive(t *testing.T) { 75 76 tests := []struct { 77 name string 78 formatArgs []string // arguments passed to format 79 alreadyPresentContent map[string]string 80 fileCheck 81 }{ 82 { 83 name: "nested formats recursively", 84 formatArgs: []string{"-recursive=true"}, 85 alreadyPresentContent: map[string]string{ 86 "foo/bar/baz.pkr.hcl": unformattedHCL, 87 "foo/bar/baz/woo.pkrvars.hcl": unformattedHCL, 88 "potato": unformattedHCL, 89 "foo/bar/potato": unformattedHCL, 90 "bar.pkr.hcl": unformattedHCL, 91 "-": unformattedHCL, 92 }, 93 fileCheck: fileCheck{ 94 expectedContent: map[string]string{ 95 "foo/bar/baz.pkr.hcl": formattedHCL, 96 "foo/bar/baz/woo.pkrvars.hcl": formattedHCL, 97 "potato": unformattedHCL, 98 "foo/bar/potato": unformattedHCL, 99 "bar.pkr.hcl": formattedHCL, 100 "-": unformattedHCL, 101 }}, 102 }, 103 { 104 name: "nested no recursive format", 105 formatArgs: []string{}, 106 alreadyPresentContent: map[string]string{ 107 "foo/bar/baz.pkr.hcl": unformattedHCL, 108 "foo/bar/baz/woo.pkrvars.hcl": unformattedHCL, 109 "bar.pkr.hcl": unformattedHCL, 110 "-": unformattedHCL, 111 }, 112 fileCheck: fileCheck{ 113 expectedContent: map[string]string{ 114 "foo/bar/baz.pkr.hcl": unformattedHCL, 115 "foo/bar/baz/woo.pkrvars.hcl": unformattedHCL, 116 "bar.pkr.hcl": formattedHCL, 117 "-": unformattedHCL, 118 }}, 119 }, 120 } 121 122 c := &FormatCommand{ 123 Meta: testMeta(t), 124 } 125 126 testDir := "test-fixtures/fmt" 127 128 for _, tt := range tests { 129 t.Run(tt.name, func(t *testing.T) { 130 tempDirectory := mustString(os.MkdirTemp(testDir, "test-dir-*")) 131 defer os.RemoveAll(tempDirectory) 132 133 createFiles(tempDirectory, tt.alreadyPresentContent) 134 135 testArgs := append(tt.formatArgs, tempDirectory) 136 if code := c.Run(testArgs); code != 0 { 137 ui := c.Meta.Ui.(*packersdk.BasicUi) 138 out := ui.Writer.(*bytes.Buffer) 139 err := ui.ErrorWriter.(*bytes.Buffer) 140 t.Fatalf( 141 "Bad exit code for test case: %s.\n\nStdout:\n\n%s\n\nStderr:\n\n%s", 142 tt.name, 143 out.String(), 144 err.String()) 145 } 146 147 tt.fileCheck.verify(t, tempDirectory) 148 }) 149 } 150 } 151 152 func Test_fmt_pipe(t *testing.T) { 153 154 tc := []struct { 155 piped string 156 command []string 157 env []string 158 expected string 159 }{ 160 {unformattedHCL, []string{"fmt", "-"}, nil, formattedHCL}, 161 {formattedHCL, []string{"fmt", "-"}, nil, formattedHCL}, 162 } 163 164 for _, tc := range tc { 165 t.Run(fmt.Sprintf("echo %q | packer %s", tc.piped, tc.command), func(t *testing.T) { 166 p := helperCommand(t, tc.command...) 167 p.Stdin = strings.NewReader(tc.piped) 168 p.Env = append(p.Env, tc.env...) 169 t.Logf("Path: %s", p.Path) 170 bs, err := p.Output() 171 if err != nil { 172 t.Fatalf("Error occurred running command %v: %s", err, bs) 173 } 174 if diff := cmp.Diff(tc.expected, string(bs)); diff != "" { 175 t.Fatalf("Error in diff: %s", diff) 176 } 177 }) 178 } 179 } 180 181 const malformedTemplate = "test-fixtures/fmt_errs/malformed.pkr.hcl" 182 183 func TestFmtParseError(t *testing.T) { 184 p := helperCommand(t, "fmt", malformedTemplate) 185 outs, err := p.CombinedOutput() 186 if err == nil { 187 t.Errorf("Expected failure to format file, but command did not fail") 188 } 189 strLogs := string(outs) 190 191 if !strings.Contains(strLogs, "An argument or block definition is required here.") { 192 t.Errorf("Expected some diags about parse error, found none") 193 } 194 }