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