github.com/terraform-linters/tflint@v0.51.2-0.20240520175844-3750771571b6/integrationtest/autofix/autofix_test.go (about) 1 package main 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "io" 7 "io/fs" 8 "log" 9 "os" 10 "path/filepath" 11 "runtime" 12 "strings" 13 "testing" 14 15 "github.com/google/go-cmp/cmp" 16 "github.com/terraform-linters/tflint/cmd" 17 "github.com/terraform-linters/tflint/formatter" 18 "github.com/terraform-linters/tflint/tflint" 19 ) 20 21 func TestMain(m *testing.M) { 22 log.SetOutput(io.Discard) 23 os.Exit(m.Run()) 24 } 25 26 func TestIntegration(t *testing.T) { 27 cases := []struct { 28 Name string 29 Command string 30 Env map[string]string 31 Dir string 32 }{ 33 { 34 Name: "simple fix", 35 Command: "./tflint --format json --fix", 36 Dir: "simple", 37 }, 38 { 39 Name: "multiple fix in a file", 40 Command: "./tflint --format json --fix", 41 Dir: "multiple_fix", 42 }, 43 { 44 Name: "ignore by annotation", 45 Command: "./tflint --format json --fix", 46 Dir: "ignore_by_annotation", 47 }, 48 { 49 Name: "multiple fix by multiple rules", 50 Command: "./tflint --format json --fix", 51 Dir: "fix_by_multiple_rules", 52 }, 53 { 54 Name: "conflict fix by multiple rules", 55 Command: "./tflint --format json --fix", 56 Dir: "conflict_fix", 57 }, 58 { 59 Name: "fix in multiple files", 60 Command: "./tflint --format json --fix", 61 Dir: "multiple_files", 62 }, 63 { 64 Name: "calling modules", 65 Command: "./tflint --format json --fix", 66 Dir: "module", 67 }, 68 { 69 Name: "--chdir", 70 Command: "./tflint --chdir=dir --format json --fix", 71 Dir: "chdir", 72 }, 73 { 74 Name: "--chdir with conflict", 75 Command: "./tflint --chdir=dir --format json --fix", 76 Dir: "chdir_with_conflict", 77 }, 78 { 79 Name: "--filter", 80 Command: "./tflint --format json --fix --filter=main.tf", 81 Dir: "filter", 82 }, 83 } 84 85 // Disable the bundled plugin because the `os.Executable()` is go(1) in the tests 86 tflint.DisableBundledPlugin = true 87 defer func() { 88 tflint.DisableBundledPlugin = false 89 }() 90 91 dir, _ := os.Getwd() 92 for _, tc := range cases { 93 t.Run(tc.Name, func(t *testing.T) { 94 testDir := filepath.Join(dir, tc.Dir) 95 96 defer func() { 97 if err := os.Chdir(dir); err != nil { 98 t.Fatal(err) 99 } 100 }() 101 if err := os.Chdir(testDir); err != nil { 102 t.Fatal(err) 103 } 104 105 tfFiles := map[string][]byte{} 106 err := filepath.Walk(".", func(path string, info fs.FileInfo, err error) error { 107 if info.IsDir() { 108 return nil 109 } 110 if strings.HasSuffix(path, ".tf") { 111 sources, err := os.ReadFile(path) 112 if err != nil { 113 return err 114 } 115 tfFiles[path] = sources 116 } 117 return nil 118 }) 119 if err != nil { 120 t.Fatal(err) 121 } 122 defer func() { 123 // restore original files 124 for path := range tfFiles { 125 if err := os.WriteFile(path, tfFiles[path], 0644); err != nil { 126 t.Fatal(err) 127 } 128 } 129 }() 130 131 resultFile := "result.json" 132 if runtime.GOOS == "windows" && IsWindowsResultExist() { 133 resultFile = "result_windows.json" 134 } 135 136 if tc.Env != nil { 137 for k, v := range tc.Env { 138 t.Setenv(k, v) 139 } 140 } 141 142 outStream, errStream := new(bytes.Buffer), new(bytes.Buffer) 143 cli, err := cmd.NewCLI(outStream, errStream) 144 if err != nil { 145 t.Fatal(err) 146 } 147 args := strings.Split(tc.Command, " ") 148 149 cli.Run(args) 150 151 b, err := os.ReadFile(filepath.Join(testDir, resultFile)) 152 if err != nil { 153 t.Fatal(err) 154 } 155 156 var expected *formatter.JSONOutput 157 if err := json.Unmarshal(b, &expected); err != nil { 158 t.Fatal(err) 159 } 160 161 var got *formatter.JSONOutput 162 if err := json.Unmarshal(outStream.Bytes(), &got); err != nil { 163 t.Fatal(err) 164 } 165 166 if diff := cmp.Diff(got, expected); diff != "" { 167 t.Fatal(diff) 168 } 169 170 // test autofixed files 171 for path := range tfFiles { 172 _, err := os.Stat(path + ".fixed") 173 if os.IsNotExist(err) { 174 // should be unchanged 175 got, err := os.ReadFile(path) 176 if err != nil { 177 t.Fatal(err) 178 } 179 if diff := cmp.Diff(string(got), string(tfFiles[path])); diff != "" { 180 t.Fatal(diff) 181 } 182 } else if err == nil { 183 // should be changed 184 got, err := os.ReadFile(path) 185 if err != nil { 186 t.Fatal(err) 187 } 188 want, err := os.ReadFile(path + ".fixed") 189 if err != nil { 190 t.Fatal(err) 191 } 192 if diff := cmp.Diff(string(got), string(want)); diff != "" { 193 t.Fatal(diff) 194 } 195 } else { 196 t.Fatal(err) 197 } 198 } 199 }) 200 } 201 } 202 203 func IsWindowsResultExist() bool { 204 _, err := os.Stat("result_windows.json") 205 return !os.IsNotExist(err) 206 }