Add exit code regression test for plan, query and refresh

Errors during variable collection should result in a non-zero exit code
pull/38690/head
Daniel Banck 1 week ago committed by Daniel Banck
parent bfa5d9e5e4
commit 4178d19a3b

@ -1325,6 +1325,50 @@ func TestPlan_varFileWithDecls(t *testing.T) {
}
}
// TestPlan_varFileDuplicateAttr is a regression test for a bug where a
// -var-file containing a duplicated attribute would print an error diagnostic
// but still exit 0, silently discarding the file and falling back to other
// variable sources (here, the variable's default value). A malformed var file
// must cause the plan to fail.
func TestPlan_varFileDuplicateAttr(t *testing.T) {
td := t.TempDir()
testCopyDir(t, testFixturePath("plan-duplicate-var-file"), td)
t.Chdir(td)
p := planVarsFixtureProvider()
planned := false
p.PlanResourceChangeFn = func(req providers.PlanResourceChangeRequest) (resp providers.PlanResourceChangeResponse) {
planned = true
resp.PlannedState = req.ProposedNewState
return
}
view, done := testView(t)
c := &PlanCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(p),
View: view,
},
}
args := []string{
"-var-file", "duplicate.tfvars",
}
code := c.Run(args)
output := done(t)
if code == 0 {
t.Fatalf("succeeded; want failure with a non-zero exit code\n\n%s", output.Stdout())
}
if got, want := output.Stderr(), "Attribute redefined"; !strings.Contains(got, want) {
t.Fatalf("missing expected error message\nwant message containing %q\ngot:\n%s", want, got)
}
if planned {
t.Fatal("plan proceeded using the variable's default value; the malformed var file should have aborted the operation")
}
}
func TestPlan_detailedExitcode(t *testing.T) {
td := t.TempDir()
testCopyDir(t, testFixturePath("plan"), td)

@ -248,6 +248,50 @@ this variable.
}
}
// TestQuery_varFileDuplicateAttr is a regression test for a bug where a
// -var-file containing a duplicated attribute would print an error diagnostic
// but still exit 0, silently discarding the file and falling back to other
// variable sources. A malformed var file must cause the query to fail.
func TestQuery_varFileDuplicateAttr(t *testing.T) {
td := t.TempDir()
testCopyDir(t, testFixturePath(path.Join("query", "duplicate-var-file")), td)
t.Chdir(td)
providerSource := newMockProviderSource(t, map[string][]string{
"hashicorp/test": {"1.0.0"},
})
p := queryFixtureProvider()
view, done := testView(t)
meta := Meta{
testingOverrides: metaOverridesForProvider(p),
View: view,
AllowExperimentalFeatures: true,
ProviderSource: providerSource,
}
init := &InitCommand{Meta: meta}
initCode := init.Run(nil)
initOutput := done(t)
if initCode != 0 {
t.Fatalf("init failed: %d\n\n%s", initCode, initOutput.All())
}
view, done = testView(t)
meta.View = view
c := &QueryCommand{Meta: meta}
code := c.Run([]string{"-no-color", "-var-file=duplicate.tfvars"})
output := done(t)
if code == 0 {
t.Fatalf("succeeded; want failure with a non-zero exit code\n\n%s", output.Stdout())
}
if got, want := output.Stderr(), "Attribute redefined"; !strings.Contains(got, want) {
t.Fatalf("missing expected error message\nwant message containing %q\ngot:\n%s", want, got)
}
}
func queryFixtureProvider() *testing_provider.MockProvider {
p := testProvider()
instanceListSchema := &configschema.Block{

@ -460,6 +460,48 @@ func TestRefresh_varFile(t *testing.T) {
}
}
// TestRefresh_varFileDuplicateAttr is a regression test for a bug where a
// -var-file containing a duplicated attribute would print an error diagnostic
// but still exit 0, silently discarding the file and falling back to other
// variable sources (here, the variable's default value). A malformed var file
// must cause the refresh to fail.
func TestRefresh_varFileDuplicateAttr(t *testing.T) {
td := t.TempDir()
testCopyDir(t, testFixturePath("refresh-duplicate-var-file"), td)
t.Chdir(td)
state := testState()
statePath := testStateFile(t, state)
p := testProvider()
p.GetProviderSchemaResponse = refreshVarFixtureSchema()
view, done := testView(t)
c := &RefreshCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(p),
View: view,
},
}
args := []string{
"-var-file", "duplicate.tfvars",
"-state", statePath,
}
code := c.Run(args)
output := done(t)
if code == 0 {
t.Fatalf("succeeded; want failure with a non-zero exit code\n\n%s", output.Stdout())
}
if got, want := output.Stderr(), "Attribute redefined"; !strings.Contains(got, want) {
t.Fatalf("missing expected error message\nwant message containing %q\ngot:\n%s", want, got)
}
if p.ConfigureProviderCalled {
t.Fatal("refresh proceeded using the variable's default value; the malformed var file should have aborted the operation")
}
}
func TestRefresh_varFileDefault(t *testing.T) {
// Create a temporary working directory that is empty
td := t.TempDir()

@ -0,0 +1,7 @@
variable "foo" {
default = "default-value"
}
resource "test_instance" "foo" {
value = var.foo
}

@ -0,0 +1,2 @@
target_ami = "ami-aaa"
target_ami = "ami-bbb"

@ -0,0 +1,9 @@
terraform {
required_providers {
test = {
source = "hashicorp/test"
}
}
}
provider "test" {}

@ -0,0 +1,12 @@
variable "target_ami" {
description = "The AMI to search for"
type = string
}
list "test_instance" "example" {
provider = test
config {
ami = var.target_ami
}
}

@ -0,0 +1,9 @@
variable "foo" {
default = "default-value"
}
provider "test" {
value = var.foo
}
resource "test_instance" "foo" {}
Loading…
Cancel
Save