mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
Fix error message when default value of variable is of wrong type (#2444)
Signed-off-by: yottta <andrei.ciobanu@opentofu.org>
This commit is contained in:
parent
77c19fab1e
commit
ab9a7f4d72
@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/hashicorp/hcl/v2/ext/typeexpr"
|
"github.com/hashicorp/hcl/v2/ext/typeexpr"
|
||||||
"github.com/hashicorp/hcl/v2/gohcl"
|
"github.com/hashicorp/hcl/v2/gohcl"
|
||||||
"github.com/hashicorp/hcl/v2/hclsyntax"
|
"github.com/hashicorp/hcl/v2/hclsyntax"
|
||||||
|
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
"github.com/zclconf/go-cty/cty/convert"
|
"github.com/zclconf/go-cty/cty/convert"
|
||||||
|
|
||||||
@ -157,7 +158,7 @@ func decodeVariableBlock(block *hcl.Block, override bool) (*Variable, hcl.Diagno
|
|||||||
diags = append(diags, &hcl.Diagnostic{
|
diags = append(diags, &hcl.Diagnostic{
|
||||||
Severity: hcl.DiagError,
|
Severity: hcl.DiagError,
|
||||||
Summary: "Invalid default value for variable",
|
Summary: "Invalid default value for variable",
|
||||||
Detail: fmt.Sprintf("This default value is not compatible with the variable's type constraint: %s.", err),
|
Detail: fmt.Sprintf("This default value is not compatible with the variable's type constraint: %s.", tfdiags.FormatError(err)),
|
||||||
Subject: attr.Expr.Range().Ptr(),
|
Subject: attr.Expr.Range().Ptr(),
|
||||||
})
|
})
|
||||||
val = cty.DynamicVal
|
val = cty.DynamicVal
|
||||||
|
@ -92,47 +92,61 @@ func TestParserLoadConfigFileFailure(t *testing.T) {
|
|||||||
|
|
||||||
// This test uses a subset of the same fixture files as
|
// This test uses a subset of the same fixture files as
|
||||||
// TestParserLoadConfigFileFailure, but additionally verifies that each
|
// TestParserLoadConfigFileFailure, but additionally verifies that each
|
||||||
// file produces the expected diagnostic summary.
|
// file produces the expected diagnostic summary and detail.
|
||||||
func TestParserLoadConfigFileFailureMessages(t *testing.T) {
|
func TestParserLoadConfigFileFailureMessages(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
Filename string
|
Filename string
|
||||||
WantSeverity hcl.DiagnosticSeverity
|
WantSeverity hcl.DiagnosticSeverity
|
||||||
WantDiag string
|
WantDiag string
|
||||||
|
WantDetail string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"invalid-files/data-resource-lifecycle.tf",
|
"invalid-files/data-resource-lifecycle.tf",
|
||||||
hcl.DiagError,
|
hcl.DiagError,
|
||||||
"Invalid data resource lifecycle argument",
|
"Invalid data resource lifecycle argument",
|
||||||
|
`The lifecycle argument "ignore_changes" is defined only for managed resources ("resource" blocks), and is not valid for data resources.`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"invalid-files/variable-type-unknown.tf",
|
"invalid-files/variable-type-unknown.tf",
|
||||||
hcl.DiagError,
|
hcl.DiagError,
|
||||||
"Invalid type specification",
|
"Invalid type specification",
|
||||||
|
`The keyword "notatype" is not a valid type specification.`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"invalid-files/unexpected-attr.tf",
|
"invalid-files/unexpected-attr.tf",
|
||||||
hcl.DiagError,
|
hcl.DiagError,
|
||||||
"Unsupported argument",
|
"Unsupported argument",
|
||||||
|
`An argument named "foo" is not expected here.`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"invalid-files/unexpected-block.tf",
|
"invalid-files/unexpected-block.tf",
|
||||||
hcl.DiagError,
|
hcl.DiagError,
|
||||||
"Unsupported block type",
|
"Unsupported block type",
|
||||||
|
`Blocks of type "varyable" are not expected here. Did you mean "variable"?`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"invalid-files/resource-count-and-for_each.tf",
|
"invalid-files/resource-count-and-for_each.tf",
|
||||||
hcl.DiagError,
|
hcl.DiagError,
|
||||||
`Invalid combination of "count" and "for_each"`,
|
`Invalid combination of "count" and "for_each"`,
|
||||||
|
`The "count" and "for_each" meta-arguments are mutually-exclusive, only one should be used to be explicit about the number of resources to be created.`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"invalid-files/data-count-and-for_each.tf",
|
"invalid-files/data-count-and-for_each.tf",
|
||||||
hcl.DiagError,
|
hcl.DiagError,
|
||||||
`Invalid combination of "count" and "for_each"`,
|
`Invalid combination of "count" and "for_each"`,
|
||||||
|
`The "count" and "for_each" meta-arguments are mutually-exclusive, only one should be used to be explicit about the number of resources to be created.`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"invalid-files/resource-lifecycle-badbool.tf",
|
"invalid-files/resource-lifecycle-badbool.tf",
|
||||||
hcl.DiagError,
|
hcl.DiagError,
|
||||||
"Unsuitable value type",
|
"Unsuitable value type",
|
||||||
|
`Unsuitable value: a bool is required`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"invalid-files/variable-complex-bad-default-inner-obj.tf",
|
||||||
|
hcl.DiagError,
|
||||||
|
"Invalid default value for variable",
|
||||||
|
`This default value is not compatible with the variable's type constraint: ["mykey"].field: a bool is required.`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,6 +175,9 @@ func TestParserLoadConfigFileFailureMessages(t *testing.T) {
|
|||||||
if diags[0].Summary != test.WantDiag {
|
if diags[0].Summary != test.WantDiag {
|
||||||
t.Errorf("Wrong diagnostic summary\ngot: %s\nwant: %s", diags[0].Summary, test.WantDiag)
|
t.Errorf("Wrong diagnostic summary\ngot: %s\nwant: %s", diags[0].Summary, test.WantDiag)
|
||||||
}
|
}
|
||||||
|
if diags[0].Detail != test.WantDetail {
|
||||||
|
t.Errorf("Wrong diagnostic detail\ngot: %s\nwant: %s", diags[0].Detail, test.WantDetail)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
internal/configs/testdata/invalid-files/variable-complex-bad-default-inner-obj.tf
vendored
Normal file
15
internal/configs/testdata/invalid-files/variable-complex-bad-default-inner-obj.tf
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// https://github.com/opentofu/opentofu/issues/2394
|
||||||
|
// This validates the returned error message when the default value
|
||||||
|
// inner field type does not match the definition of the variable
|
||||||
|
variable "bad_type_for_inner_field" {
|
||||||
|
type = map(object({
|
||||||
|
field = bool
|
||||||
|
}))
|
||||||
|
|
||||||
|
default = {
|
||||||
|
"mykey" = {
|
||||||
|
field = "not a bool"
|
||||||
|
dont = "mind me"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user