mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-30 10:47:14 -06:00
8664749b59
Terraform Core expects all variables to be set, but for some ancillary commands it's fine for them to just be set to placeholders because the variable values themselves are not key to the command's functionality as long as the terraform.Context is still self-consistent. For such commands, rather than prompting for interactive input for required variables we'll just stub them out as unknowns to reflect that they are placeholders for values that a user would normally need to provide. This achieves a similar effect to how these commands behaved before, but without the tendency to produce a slightly invalid terraform.Context that would fail in strange ways when asked to run certain operations.
136 lines
3.5 KiB
Go
136 lines
3.5 KiB
Go
package command
|
|
|
|
import (
|
|
"bytes"
|
|
"io/ioutil"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/mitchellh/cli"
|
|
)
|
|
|
|
// ConsoleCommand is tested primarily with tests in the "repl" package.
|
|
// It is not tested here because the Console uses a readline-like library
|
|
// that takes over stdin/stdout. It is difficult to test directly. The
|
|
// core logic is tested in "repl"
|
|
//
|
|
// This file still contains some tests using the stdin-based input.
|
|
|
|
func TestConsole_basic(t *testing.T) {
|
|
tmp, cwd := testCwd(t)
|
|
defer testFixCwd(t, tmp, cwd)
|
|
|
|
p := testProvider()
|
|
ui := new(cli.MockUi)
|
|
c := &ConsoleCommand{
|
|
Meta: Meta{
|
|
testingOverrides: metaOverridesForProvider(p),
|
|
Ui: ui,
|
|
},
|
|
}
|
|
|
|
var output bytes.Buffer
|
|
defer testStdinPipe(t, strings.NewReader("1+5\n"))()
|
|
outCloser := testStdoutCapture(t, &output)
|
|
|
|
args := []string{}
|
|
code := c.Run(args)
|
|
outCloser()
|
|
if code != 0 {
|
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
|
}
|
|
|
|
actual := output.String()
|
|
if actual != "6\n" {
|
|
t.Fatalf("bad: %q", actual)
|
|
}
|
|
}
|
|
|
|
func TestConsole_tfvars(t *testing.T) {
|
|
tmp, cwd := testCwd(t)
|
|
defer testFixCwd(t, tmp, cwd)
|
|
|
|
// Write a terraform.tvars
|
|
varFilePath := filepath.Join(tmp, "terraform.tfvars")
|
|
if err := ioutil.WriteFile(varFilePath, []byte(applyVarFile), 0644); err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
|
|
p := testProvider()
|
|
ui := new(cli.MockUi)
|
|
c := &ConsoleCommand{
|
|
Meta: Meta{
|
|
testingOverrides: metaOverridesForProvider(p),
|
|
Ui: ui,
|
|
},
|
|
}
|
|
|
|
var output bytes.Buffer
|
|
defer testStdinPipe(t, strings.NewReader("var.foo\n"))()
|
|
outCloser := testStdoutCapture(t, &output)
|
|
|
|
args := []string{
|
|
testFixturePath("apply-vars"),
|
|
}
|
|
code := c.Run(args)
|
|
outCloser()
|
|
if code != 0 {
|
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
|
}
|
|
|
|
actual := output.String()
|
|
if actual != "bar\n" {
|
|
t.Fatalf("bad: %q", actual)
|
|
}
|
|
}
|
|
|
|
func TestConsole_unsetRequiredVars(t *testing.T) {
|
|
// This test is verifying that it's possible to run "terraform console"
|
|
// without providing values for all required variables, without
|
|
// "terraform console" producing an interactive prompt for those variables
|
|
// or producing errors. Instead, it should allow evaluation in that
|
|
// partial context but see the unset variables values as being unknown.
|
|
|
|
tmp, cwd := testCwd(t)
|
|
defer testFixCwd(t, tmp, cwd)
|
|
|
|
p := testProvider()
|
|
ui := new(cli.MockUi)
|
|
c := &ConsoleCommand{
|
|
Meta: Meta{
|
|
testingOverrides: metaOverridesForProvider(p),
|
|
Ui: ui,
|
|
},
|
|
}
|
|
|
|
var output bytes.Buffer
|
|
defer testStdinPipe(t, strings.NewReader("var.foo\n"))()
|
|
outCloser := testStdoutCapture(t, &output)
|
|
|
|
args := []string{
|
|
// This test fixture includes variable "foo" {}, which we are
|
|
// intentionally not setting here.
|
|
testFixturePath("apply-vars"),
|
|
}
|
|
code := c.Run(args)
|
|
outCloser()
|
|
|
|
// Because we're running "terraform console" in piped input mode, we're
|
|
// expecting it to return a nonzero exit status here but the message
|
|
// must be the one indicating that it did attempt to evaluate var.foo and
|
|
// got an unknown value in return, rather than an error about var.foo
|
|
// not being set or a failure to prompt for it.
|
|
if code == 0 {
|
|
t.Fatalf("unexpected success\n%s", ui.OutputWriter.String())
|
|
}
|
|
|
|
// The error message should be the one console produces when it encounters
|
|
// an unknown value.
|
|
got := ui.ErrorWriter.String()
|
|
want := `Error: Result depends on values that cannot be determined`
|
|
if !strings.Contains(got, want) {
|
|
t.Fatalf("wrong output\ngot:\n%s\n\nwant string containing %q", got, want)
|
|
}
|
|
}
|