Files
opentf/command/output_test.go
Alisdair McDiarmid 2e62e03b64 cli: Remove dead code for output -module flag
The -module flag to terraform output has been unimplemented since 0.12.
This commit removes some dead code and the specific error message for
this flag.

The website documentation for output does not mention this flag, so it
is unchanged.
2021-01-27 14:02:59 -05:00

467 lines
9.9 KiB
Go

package command
import (
"os"
"path/filepath"
"strings"
"testing"
"github.com/mitchellh/cli"
"github.com/zclconf/go-cty/cty"
"github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/states"
)
func TestOutput(t *testing.T) {
originalState := states.BuildState(func(s *states.SyncState) {
s.SetOutputValue(
addrs.OutputValue{Name: "foo"}.Absolute(addrs.RootModuleInstance),
cty.StringVal("bar"),
false,
)
})
statePath := testStateFile(t, originalState)
ui := new(cli.MockUi)
c := &OutputCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(testProvider()),
Ui: ui,
},
}
args := []string{
"-state", statePath,
"foo",
}
if code := c.Run(args); code != 0 {
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
}
actual := strings.TrimSpace(ui.OutputWriter.String())
if actual != `"bar"` {
t.Fatalf("bad: %#v", actual)
}
}
func TestOutput_nestedListAndMap(t *testing.T) {
originalState := states.BuildState(func(s *states.SyncState) {
s.SetOutputValue(
addrs.OutputValue{Name: "foo"}.Absolute(addrs.RootModuleInstance),
cty.ListVal([]cty.Value{
cty.MapVal(map[string]cty.Value{
"key": cty.StringVal("value"),
"key2": cty.StringVal("value2"),
}),
cty.MapVal(map[string]cty.Value{
"key": cty.StringVal("value"),
}),
}),
false,
)
})
statePath := testStateFile(t, originalState)
ui := new(cli.MockUi)
c := &OutputCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(testProvider()),
Ui: ui,
},
}
args := []string{
"-state", statePath,
}
if code := c.Run(args); code != 0 {
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
}
actual := strings.TrimSpace(ui.OutputWriter.String())
expected := strings.TrimSpace(`
foo = tolist([
tomap({
"key" = "value"
"key2" = "value2"
}),
tomap({
"key" = "value"
}),
])
`)
if actual != expected {
t.Fatalf("wrong output\ngot: %s\nwant: %s", actual, expected)
}
}
func TestOutput_json(t *testing.T) {
originalState := states.BuildState(func(s *states.SyncState) {
s.SetOutputValue(
addrs.OutputValue{Name: "foo"}.Absolute(addrs.RootModuleInstance),
cty.StringVal("bar"),
false,
)
})
statePath := testStateFile(t, originalState)
ui := new(cli.MockUi)
c := &OutputCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(testProvider()),
Ui: ui,
},
}
args := []string{
"-state", statePath,
"-json",
}
if code := c.Run(args); code != 0 {
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
}
actual := strings.TrimSpace(ui.OutputWriter.String())
expected := "{\n \"foo\": {\n \"sensitive\": false,\n \"type\": \"string\",\n \"value\": \"bar\"\n }\n}"
if actual != expected {
t.Fatalf("wrong output\ngot: %#v\nwant: %#v", actual, expected)
}
}
func TestOutput_raw(t *testing.T) {
originalState := states.BuildState(func(s *states.SyncState) {
s.SetOutputValue(
addrs.OutputValue{Name: "str"}.Absolute(addrs.RootModuleInstance),
cty.StringVal("bar"),
false,
)
s.SetOutputValue(
addrs.OutputValue{Name: "multistr"}.Absolute(addrs.RootModuleInstance),
cty.StringVal("bar\nbaz"),
false,
)
s.SetOutputValue(
addrs.OutputValue{Name: "num"}.Absolute(addrs.RootModuleInstance),
cty.NumberIntVal(2),
false,
)
s.SetOutputValue(
addrs.OutputValue{Name: "bool"}.Absolute(addrs.RootModuleInstance),
cty.True,
false,
)
s.SetOutputValue(
addrs.OutputValue{Name: "obj"}.Absolute(addrs.RootModuleInstance),
cty.EmptyObjectVal,
false,
)
s.SetOutputValue(
addrs.OutputValue{Name: "null"}.Absolute(addrs.RootModuleInstance),
cty.NullVal(cty.String),
false,
)
})
statePath := testStateFile(t, originalState)
tests := map[string]struct {
WantOutput string
WantErr bool
}{
"str": {WantOutput: "bar"},
"multistr": {WantOutput: "bar\nbaz"},
"num": {WantOutput: "2"},
"bool": {WantOutput: "true"},
"obj": {WantErr: true},
"null": {WantErr: true},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
var printed string
ui := cli.NewMockUi()
c := &OutputCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(testProvider()),
Ui: ui,
},
rawPrint: func(s string) {
printed = s
},
}
args := []string{
"-state", statePath,
"-raw",
name,
}
code := c.Run(args)
if code != 0 {
if !test.WantErr {
t.Errorf("unexpected failure\n%s", ui.ErrorWriter.String())
}
return
}
if test.WantErr {
t.Fatalf("succeeded, but want error")
}
if got, want := printed, test.WantOutput; got != want {
t.Errorf("wrong result\ngot: %q\nwant: %q", got, want)
}
})
}
}
func TestOutput_emptyOutputs(t *testing.T) {
originalState := states.NewState()
statePath := testStateFile(t, originalState)
p := testProvider()
ui := new(cli.MockUi)
c := &OutputCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(p),
Ui: ui,
},
}
args := []string{
"-state", statePath,
}
if code := c.Run(args); code != 0 {
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
}
if got, want := ui.ErrorWriter.String(), "Warning: No outputs found"; !strings.Contains(got, want) {
t.Fatalf("bad output: expected to contain %q, got:\n%s", want, got)
}
}
func TestOutput_jsonEmptyOutputs(t *testing.T) {
originalState := states.NewState()
statePath := testStateFile(t, originalState)
p := testProvider()
ui := new(cli.MockUi)
c := &OutputCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(p),
Ui: ui,
},
}
args := []string{
"-state", statePath,
"-json",
}
if code := c.Run(args); code != 0 {
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
}
actual := strings.TrimSpace(ui.OutputWriter.String())
expected := "{}"
if actual != expected {
t.Fatalf("bad:\n%#v\n%#v", expected, actual)
}
}
func TestOutput_badVar(t *testing.T) {
originalState := states.BuildState(func(s *states.SyncState) {
s.SetOutputValue(
addrs.OutputValue{Name: "foo"}.Absolute(addrs.RootModuleInstance),
cty.StringVal("bar"),
false,
)
})
statePath := testStateFile(t, originalState)
ui := new(cli.MockUi)
c := &OutputCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(testProvider()),
Ui: ui,
},
}
args := []string{
"-state", statePath,
"bar",
}
if code := c.Run(args); code != 1 {
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
}
}
func TestOutput_blank(t *testing.T) {
originalState := states.BuildState(func(s *states.SyncState) {
s.SetOutputValue(
addrs.OutputValue{Name: "foo"}.Absolute(addrs.RootModuleInstance),
cty.StringVal("bar"),
false,
)
s.SetOutputValue(
addrs.OutputValue{Name: "name"}.Absolute(addrs.RootModuleInstance),
cty.StringVal("john-doe"),
false,
)
})
statePath := testStateFile(t, originalState)
ui := new(cli.MockUi)
c := &OutputCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(testProvider()),
Ui: ui,
},
}
args := []string{
"-state", statePath,
"",
}
if code := c.Run(args); code != 0 {
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
}
expectedOutput := "foo = \"bar\"\nname = \"john-doe\"\n"
output := ui.OutputWriter.String()
if output != expectedOutput {
t.Fatalf("wrong output\ngot: %#v\nwant: %#v", output, expectedOutput)
}
}
func TestOutput_manyArgs(t *testing.T) {
ui := new(cli.MockUi)
c := &OutputCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(testProvider()),
Ui: ui,
},
}
args := []string{
"bad",
"bad",
}
if code := c.Run(args); code != 1 {
t.Fatalf("bad: \n%s", ui.OutputWriter.String())
}
}
func TestOutput_noArgs(t *testing.T) {
ui := new(cli.MockUi)
c := &OutputCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(testProvider()),
Ui: ui,
},
}
args := []string{}
if code := c.Run(args); code != 0 {
t.Fatalf("bad: \n%s", ui.OutputWriter.String())
}
}
func TestOutput_noState(t *testing.T) {
originalState := states.NewState()
statePath := testStateFile(t, originalState)
ui := new(cli.MockUi)
c := &OutputCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(testProvider()),
Ui: ui,
},
}
args := []string{
"-state", statePath,
"foo",
}
if code := c.Run(args); code != 0 {
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
}
}
func TestOutput_noVars(t *testing.T) {
originalState := states.NewState()
statePath := testStateFile(t, originalState)
ui := new(cli.MockUi)
c := &OutputCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(testProvider()),
Ui: ui,
},
}
args := []string{
"-state", statePath,
"bar",
}
if code := c.Run(args); code != 0 {
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
}
}
func TestOutput_stateDefault(t *testing.T) {
originalState := states.BuildState(func(s *states.SyncState) {
s.SetOutputValue(
addrs.OutputValue{Name: "foo"}.Absolute(addrs.RootModuleInstance),
cty.StringVal("bar"),
false,
)
})
// Write the state file in a temporary directory with the
// default filename.
td := testTempDir(t)
statePath := filepath.Join(td, DefaultStateFilename)
f, err := os.Create(statePath)
if err != nil {
t.Fatalf("err: %s", err)
}
err = writeStateForTesting(originalState, f)
f.Close()
if err != nil {
t.Fatalf("err: %s", err)
}
// Change to that directory
cwd, err := os.Getwd()
if err != nil {
t.Fatalf("err: %s", err)
}
if err := os.Chdir(filepath.Dir(statePath)); err != nil {
t.Fatalf("err: %s", err)
}
defer os.Chdir(cwd)
ui := new(cli.MockUi)
c := &OutputCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(testProvider()),
Ui: ui,
},
}
args := []string{
"foo",
}
if code := c.Run(args); code != 0 {
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
}
actual := strings.TrimSpace(ui.OutputWriter.String())
if actual != `"bar"` {
t.Fatalf("bad: %#v", actual)
}
}