github.com/hugorut/terraform@v1.1.3/src/command/meta_test.go (about) 1 package command 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 "path/filepath" 8 "reflect" 9 "testing" 10 11 "github.com/google/go-cmp/cmp" 12 13 "github.com/hugorut/terraform/src/backend" 14 "github.com/hugorut/terraform/src/backend/local" 15 "github.com/hugorut/terraform/src/terraform" 16 ) 17 18 func TestMetaColorize(t *testing.T) { 19 var m *Meta 20 var args, args2 []string 21 22 // Test basic, color 23 m = new(Meta) 24 m.Color = true 25 args = []string{"foo", "bar"} 26 args2 = []string{"foo", "bar"} 27 args = m.process(args) 28 if !reflect.DeepEqual(args, args2) { 29 t.Fatalf("bad: %#v", args) 30 } 31 if m.Colorize().Disable { 32 t.Fatal("should not be disabled") 33 } 34 35 // Test basic, no change 36 m = new(Meta) 37 args = []string{"foo", "bar"} 38 args2 = []string{"foo", "bar"} 39 args = m.process(args) 40 if !reflect.DeepEqual(args, args2) { 41 t.Fatalf("bad: %#v", args) 42 } 43 if !m.Colorize().Disable { 44 t.Fatal("should be disabled") 45 } 46 47 // Test disable #1 48 m = new(Meta) 49 m.Color = true 50 args = []string{"foo", "-no-color", "bar"} 51 args2 = []string{"foo", "bar"} 52 args = m.process(args) 53 if !reflect.DeepEqual(args, args2) { 54 t.Fatalf("bad: %#v", args) 55 } 56 if !m.Colorize().Disable { 57 t.Fatal("should be disabled") 58 } 59 60 // Test disable #2 61 // Verify multiple -no-color options are removed from args slice. 62 // E.g. an additional -no-color arg could be added by TF_CLI_ARGS. 63 m = new(Meta) 64 m.Color = true 65 args = []string{"foo", "-no-color", "bar", "-no-color"} 66 args2 = []string{"foo", "bar"} 67 args = m.process(args) 68 if !reflect.DeepEqual(args, args2) { 69 t.Fatalf("bad: %#v", args) 70 } 71 if !m.Colorize().Disable { 72 t.Fatal("should be disabled") 73 } 74 } 75 76 func TestMetaInputMode(t *testing.T) { 77 test = false 78 defer func() { test = true }() 79 80 m := new(Meta) 81 args := []string{} 82 83 fs := m.extendedFlagSet("foo") 84 if err := fs.Parse(args); err != nil { 85 t.Fatalf("err: %s", err) 86 } 87 88 if m.InputMode() != terraform.InputModeStd { 89 t.Fatalf("bad: %#v", m.InputMode()) 90 } 91 } 92 93 func TestMetaInputMode_envVar(t *testing.T) { 94 test = false 95 defer func() { test = true }() 96 old := os.Getenv(InputModeEnvVar) 97 defer os.Setenv(InputModeEnvVar, old) 98 99 m := new(Meta) 100 args := []string{} 101 102 fs := m.extendedFlagSet("foo") 103 if err := fs.Parse(args); err != nil { 104 t.Fatalf("err: %s", err) 105 } 106 107 off := terraform.InputMode(0) 108 on := terraform.InputModeStd 109 cases := []struct { 110 EnvVar string 111 Expected terraform.InputMode 112 }{ 113 {"false", off}, 114 {"0", off}, 115 {"true", on}, 116 {"1", on}, 117 } 118 119 for _, tc := range cases { 120 os.Setenv(InputModeEnvVar, tc.EnvVar) 121 if m.InputMode() != tc.Expected { 122 t.Fatalf("expected InputMode: %#v, got: %#v", tc.Expected, m.InputMode()) 123 } 124 } 125 } 126 127 func TestMetaInputMode_disable(t *testing.T) { 128 test = false 129 defer func() { test = true }() 130 131 m := new(Meta) 132 args := []string{"-input=false"} 133 134 fs := m.extendedFlagSet("foo") 135 if err := fs.Parse(args); err != nil { 136 t.Fatalf("err: %s", err) 137 } 138 139 if m.InputMode() > 0 { 140 t.Fatalf("bad: %#v", m.InputMode()) 141 } 142 } 143 144 func TestMeta_initStatePaths(t *testing.T) { 145 m := new(Meta) 146 m.initStatePaths() 147 148 if m.statePath != DefaultStateFilename { 149 t.Fatalf("bad: %#v", m) 150 } 151 if m.stateOutPath != DefaultStateFilename { 152 t.Fatalf("bad: %#v", m) 153 } 154 if m.backupPath != DefaultStateFilename+DefaultBackupExtension { 155 t.Fatalf("bad: %#v", m) 156 } 157 158 m = new(Meta) 159 m.statePath = "foo" 160 m.initStatePaths() 161 162 if m.stateOutPath != "foo" { 163 t.Fatalf("bad: %#v", m) 164 } 165 if m.backupPath != "foo"+DefaultBackupExtension { 166 t.Fatalf("bad: %#v", m) 167 } 168 169 m = new(Meta) 170 m.stateOutPath = "foo" 171 m.initStatePaths() 172 173 if m.statePath != DefaultStateFilename { 174 t.Fatalf("bad: %#v", m) 175 } 176 if m.backupPath != "foo"+DefaultBackupExtension { 177 t.Fatalf("bad: %#v", m) 178 } 179 } 180 181 func TestMeta_Env(t *testing.T) { 182 td := tempDir(t) 183 os.MkdirAll(td, 0755) 184 defer os.RemoveAll(td) 185 defer testChdir(t, td)() 186 187 m := new(Meta) 188 189 env, err := m.Workspace() 190 if err != nil { 191 t.Fatal(err) 192 } 193 194 if env != backend.DefaultStateName { 195 t.Fatalf("expected env %q, got env %q", backend.DefaultStateName, env) 196 } 197 198 testEnv := "test_env" 199 if err := m.SetWorkspace(testEnv); err != nil { 200 t.Fatal("error setting env:", err) 201 } 202 203 env, _ = m.Workspace() 204 if env != testEnv { 205 t.Fatalf("expected env %q, got env %q", testEnv, env) 206 } 207 208 if err := m.SetWorkspace(backend.DefaultStateName); err != nil { 209 t.Fatal("error setting env:", err) 210 } 211 212 env, _ = m.Workspace() 213 if env != backend.DefaultStateName { 214 t.Fatalf("expected env %q, got env %q", backend.DefaultStateName, env) 215 } 216 } 217 218 func TestMeta_Workspace_override(t *testing.T) { 219 defer func(value string) { 220 os.Setenv(WorkspaceNameEnvVar, value) 221 }(os.Getenv(WorkspaceNameEnvVar)) 222 223 m := new(Meta) 224 225 testCases := map[string]struct { 226 workspace string 227 err error 228 }{ 229 "": { 230 "default", 231 nil, 232 }, 233 "development": { 234 "development", 235 nil, 236 }, 237 "invalid name": { 238 "", 239 errInvalidWorkspaceNameEnvVar, 240 }, 241 } 242 243 for name, tc := range testCases { 244 t.Run(name, func(t *testing.T) { 245 os.Setenv(WorkspaceNameEnvVar, name) 246 workspace, err := m.Workspace() 247 if workspace != tc.workspace { 248 t.Errorf("Unexpected workspace\n got: %s\nwant: %s\n", workspace, tc.workspace) 249 } 250 if err != tc.err { 251 t.Errorf("Unexpected error\n got: %s\nwant: %s\n", err, tc.err) 252 } 253 }) 254 } 255 } 256 257 func TestMeta_Workspace_invalidSelected(t *testing.T) { 258 td := tempDir(t) 259 os.MkdirAll(td, 0755) 260 defer os.RemoveAll(td) 261 defer testChdir(t, td)() 262 263 // this is an invalid workspace name 264 workspace := "test workspace" 265 266 // create the workspace directories 267 if err := os.MkdirAll(filepath.Join(local.DefaultWorkspaceDir, workspace), 0755); err != nil { 268 t.Fatal(err) 269 } 270 271 // create the workspace file to select it 272 if err := os.MkdirAll(DefaultDataDir, 0755); err != nil { 273 t.Fatal(err) 274 } 275 if err := ioutil.WriteFile(filepath.Join(DefaultDataDir, local.DefaultWorkspaceFile), []byte(workspace), 0644); err != nil { 276 t.Fatal(err) 277 } 278 279 m := new(Meta) 280 281 ws, err := m.Workspace() 282 if ws != workspace { 283 t.Errorf("Unexpected workspace\n got: %s\nwant: %s\n", ws, workspace) 284 } 285 if err != nil { 286 t.Errorf("Unexpected error: %s", err) 287 } 288 } 289 290 func TestMeta_process(t *testing.T) { 291 test = false 292 defer func() { test = true }() 293 294 // Create a temporary directory for our cwd 295 d := tempDir(t) 296 os.MkdirAll(d, 0755) 297 defer os.RemoveAll(d) 298 defer testChdir(t, d)() 299 300 // At one point it was the responsibility of this process function to 301 // insert fake additional -var-file options into the command line 302 // if the automatic tfvars files were present. This is no longer the 303 // responsibility of process (it happens in collectVariableValues instead) 304 // but we're still testing with these files in place to verify that 305 // they _aren't_ being interpreted by process, since that could otherwise 306 // cause them to be added more than once and mess up the precedence order. 307 defaultVarsfile := "terraform.tfvars" 308 err := ioutil.WriteFile( 309 filepath.Join(d, defaultVarsfile), 310 []byte(""), 311 0644) 312 if err != nil { 313 t.Fatalf("err: %s", err) 314 } 315 fileFirstAlphabetical := "a-file.auto.tfvars" 316 err = ioutil.WriteFile( 317 filepath.Join(d, fileFirstAlphabetical), 318 []byte(""), 319 0644) 320 if err != nil { 321 t.Fatalf("err: %s", err) 322 } 323 fileLastAlphabetical := "z-file.auto.tfvars" 324 err = ioutil.WriteFile( 325 filepath.Join(d, fileLastAlphabetical), 326 []byte(""), 327 0644) 328 if err != nil { 329 t.Fatalf("err: %s", err) 330 } 331 // Regular tfvars files will not be autoloaded 332 fileIgnored := "ignored.tfvars" 333 err = ioutil.WriteFile( 334 filepath.Join(d, fileIgnored), 335 []byte(""), 336 0644) 337 if err != nil { 338 t.Fatalf("err: %s", err) 339 } 340 341 tests := []struct { 342 GivenArgs []string 343 FilteredArgs []string 344 ExtraCheck func(*testing.T, *Meta) 345 }{ 346 { 347 []string{}, 348 []string{}, 349 func(t *testing.T, m *Meta) { 350 if got, want := m.color, true; got != want { 351 t.Errorf("wrong m.color value %#v; want %#v", got, want) 352 } 353 if got, want := m.Color, true; got != want { 354 t.Errorf("wrong m.Color value %#v; want %#v", got, want) 355 } 356 }, 357 }, 358 { 359 []string{"-no-color"}, 360 []string{}, 361 func(t *testing.T, m *Meta) { 362 if got, want := m.color, false; got != want { 363 t.Errorf("wrong m.color value %#v; want %#v", got, want) 364 } 365 if got, want := m.Color, false; got != want { 366 t.Errorf("wrong m.Color value %#v; want %#v", got, want) 367 } 368 }, 369 }, 370 } 371 372 for _, test := range tests { 373 t.Run(fmt.Sprintf("%s", test.GivenArgs), func(t *testing.T) { 374 m := new(Meta) 375 m.Color = true // this is the default also for normal use, overridden by -no-color 376 args := test.GivenArgs 377 args = m.process(args) 378 379 if !cmp.Equal(test.FilteredArgs, args) { 380 t.Errorf("wrong filtered arguments\n%s", cmp.Diff(test.FilteredArgs, args)) 381 } 382 383 if test.ExtraCheck != nil { 384 test.ExtraCheck(t, m) 385 } 386 }) 387 } 388 }