Skip to content

Commit

Permalink
internal/schemavalidator: Fix bug where unknown values were returning…
Browse files Browse the repository at this point in the history
… error diagnostics too early (#252)

* internal/schemavalidator: Fix bug where unknown values were returning error diagnostics too early

* changelog
  • Loading branch information
austinvalle authored Dec 12, 2024
1 parent 16687f3 commit b500ce7
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 2 deletions.
6 changes: 6 additions & 0 deletions .changes/unreleased/BUG FIXES-20241212-152125.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: BUG FIXES
body: Fixed bug with `ConflictsWith` and `AlsoRequires` validators where unknown values
would raise invalid diagnostics during `terraform validate`.
time: 2024-12-12T15:21:25.964001-05:00
custom:
Issue: "251"
3 changes: 2 additions & 1 deletion internal/schemavalidator/also_requires.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ func (av AlsoRequiresValidator) MarkdownDescription(_ context.Context) string {

func (av AlsoRequiresValidator) Validate(ctx context.Context, req AlsoRequiresValidatorRequest, res *AlsoRequiresValidatorResponse) {
// If attribute configuration is null, there is nothing else to validate
if req.ConfigValue.IsNull() {
// If attribute configuration is unknown, delay the validation until it is known.
if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {
return
}

Expand Down
27 changes: 27 additions & 0 deletions internal/schemavalidator/also_requires_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,33 @@ func TestAlsoRequiresValidatorValidate(t *testing.T) {
path.MatchRoot("foo"),
},
},
"self-is-unknown": {
req: schemavalidator.AlsoRequiresValidatorRequest{
ConfigValue: types.StringUnknown(),
Path: path.Root("bar"),
PathExpression: path.MatchRoot("bar"),
Config: tfsdk.Config{
Schema: schema.Schema{
Attributes: map[string]schema.Attribute{
"foo": schema.Int64Attribute{},
"bar": schema.StringAttribute{},
},
},
Raw: tftypes.NewValue(tftypes.Object{
AttributeTypes: map[string]tftypes.Type{
"foo": tftypes.Number,
"bar": tftypes.String,
},
}, map[string]tftypes.Value{
"foo": tftypes.NewValue(tftypes.Number, nil),
"bar": tftypes.NewValue(tftypes.String, tftypes.UnknownValue),
}),
},
},
in: path.Expressions{
path.MatchRoot("foo"),
},
},
"error_missing-one": {
req: schemavalidator.AlsoRequiresValidatorRequest{
ConfigValue: types.StringValue("bar value"),
Expand Down
1 change: 1 addition & 0 deletions internal/schemavalidator/at_least_one_of.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ func (av AtLeastOneOfValidator) MarkdownDescription(_ context.Context) string {

func (av AtLeastOneOfValidator) Validate(ctx context.Context, req AtLeastOneOfValidatorRequest, res *AtLeastOneOfValidatorResponse) {
// If attribute configuration is not null, validator already succeeded.
// If attribute configuration is unknown, delay the validation until it is known.
if !req.ConfigValue.IsNull() {
return
}
Expand Down
28 changes: 28 additions & 0 deletions internal/schemavalidator/at_least_one_of_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,34 @@ func TestAtLeastOneOfValidatorValidate(t *testing.T) {
},
expected: &schemavalidator.AtLeastOneOfValidatorResponse{},
},
"self-is-unknown": {
req: schemavalidator.AtLeastOneOfValidatorRequest{
ConfigValue: types.StringUnknown(),
Path: path.Root("bar"),
PathExpression: path.MatchRoot("bar"),
Config: tfsdk.Config{
Schema: schema.Schema{
Attributes: map[string]schema.Attribute{
"foo": schema.Int64Attribute{},
"bar": schema.StringAttribute{},
},
},
Raw: tftypes.NewValue(tftypes.Object{
AttributeTypes: map[string]tftypes.Type{
"foo": tftypes.Number,
"bar": tftypes.String,
},
}, map[string]tftypes.Value{
"foo": tftypes.NewValue(tftypes.Number, 42),
"bar": tftypes.NewValue(tftypes.String, tftypes.UnknownValue),
}),
},
},
in: path.Expressions{
path.MatchRoot("foo"),
},
expected: &schemavalidator.AtLeastOneOfValidatorResponse{},
},
"error_none-set": {
req: schemavalidator.AtLeastOneOfValidatorRequest{
ConfigValue: types.StringNull(),
Expand Down
3 changes: 2 additions & 1 deletion internal/schemavalidator/conflicts_with.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ func (av ConflictsWithValidator) MarkdownDescription(_ context.Context) string {

func (av ConflictsWithValidator) Validate(ctx context.Context, req ConflictsWithValidatorRequest, res *ConflictsWithValidatorResponse) {
// If attribute configuration is null, it cannot conflict with others
if req.ConfigValue.IsNull() {
// If attribute configuration is unknown, delay the validation until it is known.
if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {
return
}

Expand Down
27 changes: 27 additions & 0 deletions internal/schemavalidator/conflicts_with_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,33 @@ func TestConflictsWithValidatorValidate(t *testing.T) {
path.MatchRoot("foo"),
},
},
"self-is-unknown": {
req: schemavalidator.ConflictsWithValidatorRequest{
ConfigValue: types.StringUnknown(),
Path: path.Root("bar"),
PathExpression: path.MatchRoot("bar"),
Config: tfsdk.Config{
Schema: schema.Schema{
Attributes: map[string]schema.Attribute{
"foo": schema.Int64Attribute{},
"bar": schema.StringAttribute{},
},
},
Raw: tftypes.NewValue(tftypes.Object{
AttributeTypes: map[string]tftypes.Type{
"foo": tftypes.Number,
"bar": tftypes.String,
},
}, map[string]tftypes.Value{
"foo": tftypes.NewValue(tftypes.Number, 42),
"bar": tftypes.NewValue(tftypes.String, tftypes.UnknownValue),
}),
},
},
in: path.Expressions{
path.MatchRoot("foo"),
},
},
"error_allow-duplicate-input": {
req: schemavalidator.ConflictsWithValidatorRequest{
ConfigValue: types.StringValue("bar value"),
Expand Down
27 changes: 27 additions & 0 deletions internal/schemavalidator/exactly_one_of_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,33 @@ func TestExactlyOneOfValidator(t *testing.T) {
path.MatchRoot("foo"),
},
},
"self-is-unknown": {
req: schemavalidator.ExactlyOneOfValidatorRequest{
ConfigValue: types.StringUnknown(),
Path: path.Root("bar"),
PathExpression: path.MatchRoot("bar"),
Config: tfsdk.Config{
Schema: schema.Schema{
Attributes: map[string]schema.Attribute{
"foo": schema.Int64Attribute{},
"bar": schema.StringAttribute{},
},
},
Raw: tftypes.NewValue(tftypes.Object{
AttributeTypes: map[string]tftypes.Type{
"foo": tftypes.Number,
"bar": tftypes.String,
},
}, map[string]tftypes.Value{
"foo": tftypes.NewValue(tftypes.Number, 42),
"bar": tftypes.NewValue(tftypes.String, tftypes.UnknownValue),
}),
},
},
in: path.Expressions{
path.MatchRoot("foo"),
},
},
"error_too-many": {
req: schemavalidator.ExactlyOneOfValidatorRequest{
ConfigValue: types.StringValue("bar value"),
Expand Down

0 comments on commit b500ce7

Please sign in to comment.