2014-07-13 05:21:46 +02:00
|
|
|
package command
|
|
|
|
|
|
|
|
import (
|
2018-11-08 00:45:06 +01:00
|
|
|
"fmt"
|
2014-10-01 17:37:57 +02:00
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2014-07-13 05:21:46 +02:00
|
|
|
"reflect"
|
|
|
|
"testing"
|
2014-10-08 19:29:54 +02:00
|
|
|
|
2018-11-08 00:45:06 +01:00
|
|
|
"github.com/google/go-cmp/cmp"
|
|
|
|
|
2021-05-17 17:42:17 +02:00
|
|
|
"github.com/hashicorp/terraform/internal/backend"
|
|
|
|
"github.com/hashicorp/terraform/internal/backend/local"
|
2021-05-17 21:46:19 +02:00
|
|
|
"github.com/hashicorp/terraform/internal/terraform"
|
2014-07-13 05:21:46 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestMetaColorize(t *testing.T) {
|
|
|
|
var m *Meta
|
|
|
|
var args, args2 []string
|
|
|
|
|
2014-07-17 18:34:32 +02:00
|
|
|
// Test basic, color
|
2014-07-13 05:21:46 +02:00
|
|
|
m = new(Meta)
|
2014-07-17 18:34:32 +02:00
|
|
|
m.Color = true
|
2014-07-13 05:21:46 +02:00
|
|
|
args = []string{"foo", "bar"}
|
|
|
|
args2 = []string{"foo", "bar"}
|
2020-04-01 21:01:08 +02:00
|
|
|
args = m.process(args)
|
2014-07-13 05:21:46 +02:00
|
|
|
if !reflect.DeepEqual(args, args2) {
|
|
|
|
t.Fatalf("bad: %#v", args)
|
|
|
|
}
|
|
|
|
if m.Colorize().Disable {
|
|
|
|
t.Fatal("should not be disabled")
|
|
|
|
}
|
|
|
|
|
2014-07-17 18:34:32 +02:00
|
|
|
// Test basic, no change
|
|
|
|
m = new(Meta)
|
|
|
|
args = []string{"foo", "bar"}
|
|
|
|
args2 = []string{"foo", "bar"}
|
2020-04-01 21:01:08 +02:00
|
|
|
args = m.process(args)
|
2014-07-17 18:34:32 +02:00
|
|
|
if !reflect.DeepEqual(args, args2) {
|
|
|
|
t.Fatalf("bad: %#v", args)
|
|
|
|
}
|
|
|
|
if !m.Colorize().Disable {
|
|
|
|
t.Fatal("should be disabled")
|
|
|
|
}
|
|
|
|
|
2014-07-13 05:21:46 +02:00
|
|
|
// Test disable #1
|
|
|
|
m = new(Meta)
|
2014-09-09 05:41:10 +02:00
|
|
|
m.Color = true
|
2014-07-13 05:21:46 +02:00
|
|
|
args = []string{"foo", "-no-color", "bar"}
|
|
|
|
args2 = []string{"foo", "bar"}
|
2020-04-01 21:01:08 +02:00
|
|
|
args = m.process(args)
|
2014-07-13 05:21:46 +02:00
|
|
|
if !reflect.DeepEqual(args, args2) {
|
|
|
|
t.Fatalf("bad: %#v", args)
|
|
|
|
}
|
|
|
|
if !m.Colorize().Disable {
|
|
|
|
t.Fatal("should be disabled")
|
|
|
|
}
|
2020-08-13 20:10:09 +02:00
|
|
|
|
|
|
|
// Test disable #2
|
|
|
|
// Verify multiple -no-color options are removed from args slice.
|
|
|
|
// E.g. an additional -no-color arg could be added by TF_CLI_ARGS.
|
|
|
|
m = new(Meta)
|
|
|
|
m.Color = true
|
|
|
|
args = []string{"foo", "-no-color", "bar", "-no-color"}
|
|
|
|
args2 = []string{"foo", "bar"}
|
|
|
|
args = m.process(args)
|
|
|
|
if !reflect.DeepEqual(args, args2) {
|
|
|
|
t.Fatalf("bad: %#v", args)
|
|
|
|
}
|
|
|
|
if !m.Colorize().Disable {
|
|
|
|
t.Fatal("should be disabled")
|
2014-07-13 05:21:46 +02:00
|
|
|
}
|
|
|
|
}
|
2014-09-29 20:11:35 +02:00
|
|
|
|
2014-10-08 19:29:54 +02:00
|
|
|
func TestMetaInputMode(t *testing.T) {
|
2014-09-29 20:24:16 +02:00
|
|
|
test = false
|
|
|
|
defer func() { test = true }()
|
|
|
|
|
2014-09-29 20:11:35 +02:00
|
|
|
m := new(Meta)
|
|
|
|
args := []string{}
|
|
|
|
|
2018-11-21 15:35:27 +01:00
|
|
|
fs := m.extendedFlagSet("foo")
|
2014-09-29 20:11:35 +02:00
|
|
|
if err := fs.Parse(args); err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
2019-10-08 21:08:27 +02:00
|
|
|
if m.InputMode() != terraform.InputModeStd {
|
2014-10-08 19:29:54 +02:00
|
|
|
t.Fatalf("bad: %#v", m.InputMode())
|
2014-09-29 20:11:35 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-30 16:59:14 +02:00
|
|
|
func TestMetaInputMode_envVar(t *testing.T) {
|
|
|
|
test = false
|
|
|
|
defer func() { test = true }()
|
|
|
|
old := os.Getenv(InputModeEnvVar)
|
|
|
|
defer os.Setenv(InputModeEnvVar, old)
|
|
|
|
|
|
|
|
m := new(Meta)
|
|
|
|
args := []string{}
|
|
|
|
|
2018-11-21 15:35:27 +01:00
|
|
|
fs := m.extendedFlagSet("foo")
|
2015-04-30 16:59:14 +02:00
|
|
|
if err := fs.Parse(args); err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
off := terraform.InputMode(0)
|
2019-10-08 21:08:27 +02:00
|
|
|
on := terraform.InputModeStd
|
2015-04-30 16:59:14 +02:00
|
|
|
cases := []struct {
|
|
|
|
EnvVar string
|
|
|
|
Expected terraform.InputMode
|
|
|
|
}{
|
|
|
|
{"false", off},
|
|
|
|
{"0", off},
|
|
|
|
{"true", on},
|
|
|
|
{"1", on},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range cases {
|
|
|
|
os.Setenv(InputModeEnvVar, tc.EnvVar)
|
|
|
|
if m.InputMode() != tc.Expected {
|
|
|
|
t.Fatalf("expected InputMode: %#v, got: %#v", tc.Expected, m.InputMode())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-08 19:29:54 +02:00
|
|
|
func TestMetaInputMode_disable(t *testing.T) {
|
2014-09-29 20:24:16 +02:00
|
|
|
test = false
|
|
|
|
defer func() { test = true }()
|
|
|
|
|
2014-09-29 20:11:35 +02:00
|
|
|
m := new(Meta)
|
|
|
|
args := []string{"-input=false"}
|
|
|
|
|
2018-11-21 15:35:27 +01:00
|
|
|
fs := m.extendedFlagSet("foo")
|
2014-09-29 20:11:35 +02:00
|
|
|
if err := fs.Parse(args); err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
2014-10-08 19:29:54 +02:00
|
|
|
if m.InputMode() > 0 {
|
|
|
|
t.Fatalf("bad: %#v", m.InputMode())
|
2014-09-29 20:11:35 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-12 03:05:23 +02:00
|
|
|
func TestMeta_initStatePaths(t *testing.T) {
|
|
|
|
m := new(Meta)
|
|
|
|
m.initStatePaths()
|
|
|
|
|
|
|
|
if m.statePath != DefaultStateFilename {
|
|
|
|
t.Fatalf("bad: %#v", m)
|
|
|
|
}
|
|
|
|
if m.stateOutPath != DefaultStateFilename {
|
|
|
|
t.Fatalf("bad: %#v", m)
|
|
|
|
}
|
2015-09-11 20:56:20 +02:00
|
|
|
if m.backupPath != DefaultStateFilename+DefaultBackupExtension {
|
2014-10-12 03:05:23 +02:00
|
|
|
t.Fatalf("bad: %#v", m)
|
|
|
|
}
|
|
|
|
|
|
|
|
m = new(Meta)
|
|
|
|
m.statePath = "foo"
|
|
|
|
m.initStatePaths()
|
|
|
|
|
|
|
|
if m.stateOutPath != "foo" {
|
|
|
|
t.Fatalf("bad: %#v", m)
|
|
|
|
}
|
2015-09-11 20:56:20 +02:00
|
|
|
if m.backupPath != "foo"+DefaultBackupExtension {
|
2014-10-12 03:05:23 +02:00
|
|
|
t.Fatalf("bad: %#v", m)
|
|
|
|
}
|
|
|
|
|
|
|
|
m = new(Meta)
|
|
|
|
m.stateOutPath = "foo"
|
|
|
|
m.initStatePaths()
|
|
|
|
|
|
|
|
if m.statePath != DefaultStateFilename {
|
|
|
|
t.Fatalf("bad: %#v", m)
|
|
|
|
}
|
2015-09-11 20:56:20 +02:00
|
|
|
if m.backupPath != "foo"+DefaultBackupExtension {
|
2014-10-12 03:05:23 +02:00
|
|
|
t.Fatalf("bad: %#v", m)
|
|
|
|
}
|
|
|
|
}
|
2015-04-30 21:05:39 +02:00
|
|
|
|
2017-02-28 19:13:03 +01:00
|
|
|
func TestMeta_Env(t *testing.T) {
|
|
|
|
td := tempDir(t)
|
|
|
|
os.MkdirAll(td, 0755)
|
|
|
|
defer os.RemoveAll(td)
|
|
|
|
defer testChdir(t, td)()
|
|
|
|
|
|
|
|
m := new(Meta)
|
|
|
|
|
2020-06-16 18:23:15 +02:00
|
|
|
env, err := m.Workspace()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2017-02-28 19:13:03 +01:00
|
|
|
|
|
|
|
if env != backend.DefaultStateName {
|
|
|
|
t.Fatalf("expected env %q, got env %q", backend.DefaultStateName, env)
|
|
|
|
}
|
|
|
|
|
|
|
|
testEnv := "test_env"
|
2017-05-31 02:13:43 +02:00
|
|
|
if err := m.SetWorkspace(testEnv); err != nil {
|
2017-02-28 19:13:03 +01:00
|
|
|
t.Fatal("error setting env:", err)
|
|
|
|
}
|
|
|
|
|
2020-06-16 18:23:15 +02:00
|
|
|
env, _ = m.Workspace()
|
2017-02-28 19:13:03 +01:00
|
|
|
if env != testEnv {
|
|
|
|
t.Fatalf("expected env %q, got env %q", testEnv, env)
|
|
|
|
}
|
|
|
|
|
2017-05-31 02:13:43 +02:00
|
|
|
if err := m.SetWorkspace(backend.DefaultStateName); err != nil {
|
2017-02-28 19:13:03 +01:00
|
|
|
t.Fatal("error setting env:", err)
|
|
|
|
}
|
|
|
|
|
2020-06-16 18:23:15 +02:00
|
|
|
env, _ = m.Workspace()
|
2017-02-28 19:13:03 +01:00
|
|
|
if env != backend.DefaultStateName {
|
|
|
|
t.Fatalf("expected env %q, got env %q", backend.DefaultStateName, env)
|
|
|
|
}
|
|
|
|
}
|
2017-03-08 05:09:48 +01:00
|
|
|
|
2020-06-16 18:23:15 +02:00
|
|
|
func TestMeta_Workspace_override(t *testing.T) {
|
|
|
|
defer func(value string) {
|
|
|
|
os.Setenv(WorkspaceNameEnvVar, value)
|
|
|
|
}(os.Getenv(WorkspaceNameEnvVar))
|
|
|
|
|
|
|
|
m := new(Meta)
|
|
|
|
|
|
|
|
testCases := map[string]struct {
|
|
|
|
workspace string
|
|
|
|
err error
|
|
|
|
}{
|
|
|
|
"": {
|
|
|
|
"default",
|
|
|
|
nil,
|
|
|
|
},
|
|
|
|
"development": {
|
|
|
|
"development",
|
|
|
|
nil,
|
|
|
|
},
|
|
|
|
"invalid name": {
|
|
|
|
"",
|
2020-12-01 18:34:50 +01:00
|
|
|
errInvalidWorkspaceNameEnvVar,
|
2020-06-16 18:23:15 +02:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for name, tc := range testCases {
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
os.Setenv(WorkspaceNameEnvVar, name)
|
|
|
|
workspace, err := m.Workspace()
|
|
|
|
if workspace != tc.workspace {
|
|
|
|
t.Errorf("Unexpected workspace\n got: %s\nwant: %s\n", workspace, tc.workspace)
|
|
|
|
}
|
|
|
|
if err != tc.err {
|
|
|
|
t.Errorf("Unexpected error\n got: %s\nwant: %s\n", err, tc.err)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-18 16:10:44 +02:00
|
|
|
func TestMeta_Workspace_invalidSelected(t *testing.T) {
|
|
|
|
td := tempDir(t)
|
|
|
|
os.MkdirAll(td, 0755)
|
|
|
|
defer os.RemoveAll(td)
|
|
|
|
defer testChdir(t, td)()
|
|
|
|
|
|
|
|
// this is an invalid workspace name
|
|
|
|
workspace := "test workspace"
|
|
|
|
|
|
|
|
// create the workspace directories
|
|
|
|
if err := os.MkdirAll(filepath.Join(local.DefaultWorkspaceDir, workspace), 0755); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// create the workspace file to select it
|
|
|
|
if err := os.MkdirAll(DefaultDataDir, 0755); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if err := ioutil.WriteFile(filepath.Join(DefaultDataDir, local.DefaultWorkspaceFile), []byte(workspace), 0644); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
m := new(Meta)
|
|
|
|
|
|
|
|
ws, err := m.Workspace()
|
|
|
|
if ws != workspace {
|
|
|
|
t.Errorf("Unexpected workspace\n got: %s\nwant: %s\n", ws, workspace)
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("Unexpected error: %s", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-08 05:09:48 +01:00
|
|
|
func TestMeta_process(t *testing.T) {
|
|
|
|
test = false
|
|
|
|
defer func() { test = true }()
|
|
|
|
|
|
|
|
// Create a temporary directory for our cwd
|
|
|
|
d := tempDir(t)
|
2017-07-06 17:33:32 +02:00
|
|
|
os.MkdirAll(d, 0755)
|
|
|
|
defer os.RemoveAll(d)
|
|
|
|
defer testChdir(t, d)()
|
2017-03-08 05:09:48 +01:00
|
|
|
|
2018-11-08 00:45:06 +01:00
|
|
|
// At one point it was the responsibility of this process function to
|
|
|
|
// insert fake additional -var-file options into the command line
|
|
|
|
// if the automatic tfvars files were present. This is no longer the
|
|
|
|
// responsibility of process (it happens in collectVariableValues instead)
|
|
|
|
// but we're still testing with these files in place to verify that
|
|
|
|
// they _aren't_ being interpreted by process, since that could otherwise
|
|
|
|
// cause them to be added more than once and mess up the precedence order.
|
2017-06-22 03:22:07 +02:00
|
|
|
defaultVarsfile := "terraform.tfvars"
|
2017-07-06 17:33:32 +02:00
|
|
|
err := ioutil.WriteFile(
|
2017-06-22 03:22:07 +02:00
|
|
|
filepath.Join(d, defaultVarsfile),
|
2017-03-08 05:09:48 +01:00
|
|
|
[]byte(""),
|
|
|
|
0644)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
2017-06-22 03:22:07 +02:00
|
|
|
fileFirstAlphabetical := "a-file.auto.tfvars"
|
2017-03-08 05:09:48 +01:00
|
|
|
err = ioutil.WriteFile(
|
2017-06-22 03:22:07 +02:00
|
|
|
filepath.Join(d, fileFirstAlphabetical),
|
|
|
|
[]byte(""),
|
|
|
|
0644)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
fileLastAlphabetical := "z-file.auto.tfvars"
|
|
|
|
err = ioutil.WriteFile(
|
|
|
|
filepath.Join(d, fileLastAlphabetical),
|
2017-03-08 05:09:48 +01:00
|
|
|
[]byte(""),
|
|
|
|
0644)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
2017-06-22 04:05:05 +02:00
|
|
|
// Regular tfvars files will not be autoloaded
|
|
|
|
fileIgnored := "ignored.tfvars"
|
|
|
|
err = ioutil.WriteFile(
|
|
|
|
filepath.Join(d, fileIgnored),
|
|
|
|
[]byte(""),
|
|
|
|
0644)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
2017-03-08 05:09:48 +01:00
|
|
|
|
2018-11-08 00:45:06 +01:00
|
|
|
tests := []struct {
|
|
|
|
GivenArgs []string
|
|
|
|
FilteredArgs []string
|
|
|
|
ExtraCheck func(*testing.T, *Meta)
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
[]string{},
|
|
|
|
[]string{},
|
|
|
|
func(t *testing.T, m *Meta) {
|
|
|
|
if got, want := m.color, true; got != want {
|
|
|
|
t.Errorf("wrong m.color value %#v; want %#v", got, want)
|
|
|
|
}
|
|
|
|
if got, want := m.Color, true; got != want {
|
|
|
|
t.Errorf("wrong m.Color value %#v; want %#v", got, want)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
[]string{"-no-color"},
|
|
|
|
[]string{},
|
|
|
|
func(t *testing.T, m *Meta) {
|
|
|
|
if got, want := m.color, false; got != want {
|
|
|
|
t.Errorf("wrong m.color value %#v; want %#v", got, want)
|
|
|
|
}
|
|
|
|
if got, want := m.Color, false; got != want {
|
|
|
|
t.Errorf("wrong m.Color value %#v; want %#v", got, want)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, test := range tests {
|
|
|
|
t.Run(fmt.Sprintf("%s", test.GivenArgs), func(t *testing.T) {
|
|
|
|
m := new(Meta)
|
|
|
|
m.Color = true // this is the default also for normal use, overridden by -no-color
|
|
|
|
args := test.GivenArgs
|
2020-04-01 21:01:08 +02:00
|
|
|
args = m.process(args)
|
2018-11-08 00:45:06 +01:00
|
|
|
|
|
|
|
if !cmp.Equal(test.FilteredArgs, args) {
|
|
|
|
t.Errorf("wrong filtered arguments\n%s", cmp.Diff(test.FilteredArgs, args))
|
|
|
|
}
|
|
|
|
|
|
|
|
if test.ExtraCheck != nil {
|
|
|
|
test.ExtraCheck(t, m)
|
|
|
|
}
|
|
|
|
})
|
2017-03-08 05:09:48 +01:00
|
|
|
}
|
|
|
|
}
|