mirror of
https://github.com/opentffoundation/opentf.git
synced 2025-12-25 10:00:44 -05:00
hcl2shim: MockValueComposer handles structural-typed attributes (#2994)
Signed-off-by: Martin Atkins <mart@degeneration.co.uk> Signed-off-by: Christian Mesh <christianmesh1@gmail.com> Co-authored-by: Christian Mesh <christianmesh1@gmail.com> Signed-off-by: Christian Mesh <christianmesh1@gmail.com>
This commit is contained in:
committed by
Christian Mesh
parent
c5fa034cfb
commit
e69e22edb5
@@ -101,7 +101,17 @@ func (mvc MockValueComposer) composeMockValueForAttributes(schema *configschema.
|
||||
// Non-computed attributes can't be generated
|
||||
// so we set them from configuration only.
|
||||
if !attr.Computed {
|
||||
mockAttrs[k] = cty.NullVal(attr.Type)
|
||||
if attr.NestedType != nil && attr.NestedType.Nesting == configschema.NestingGroup {
|
||||
// This should not be possible to hit. Neither tofu or the provider framework will allow
|
||||
// NestingGroup in here. However, this could change at some point and we want to be prepared for it.
|
||||
diags = diags.Append(tfdiags.WholeContainingBody(
|
||||
tfdiags.Error,
|
||||
fmt.Sprintf("Unsupported field `%v` in attribute mocking", k),
|
||||
"Overriding non-computed fields is not allowed, so this field cannot be processed.",
|
||||
))
|
||||
continue
|
||||
}
|
||||
mockAttrs[k] = cty.NullVal(attr.ImpliedType())
|
||||
if _, ok := defaults[k]; ok {
|
||||
diags = diags.Append(tfdiags.WholeContainingBody(
|
||||
tfdiags.Error,
|
||||
@@ -115,7 +125,7 @@ func (mvc MockValueComposer) composeMockValueForAttributes(schema *configschema.
|
||||
// If the attribute is computed and not configured,
|
||||
// we use provided value from defaults.
|
||||
if ov, ok := defaults[k]; ok {
|
||||
converted, err := convert.Convert(ov, attr.Type)
|
||||
converted, err := convert.Convert(ov, attr.ImpliedType())
|
||||
if err != nil {
|
||||
diags = diags.Append(tfdiags.WholeContainingBody(
|
||||
tfdiags.Error,
|
||||
|
||||
@@ -3,8 +3,10 @@ package hcl2shim
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/opentofu/opentofu/internal/configs/configschema"
|
||||
"github.com/zclconf/go-cty-debug/ctydebug"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
|
||||
"github.com/opentofu/opentofu/internal/configs/configschema"
|
||||
)
|
||||
|
||||
// TestComposeMockValueBySchema ensures different configschema.Block values
|
||||
@@ -177,6 +179,127 @@ func TestComposeMockValueBySchema(t *testing.T) {
|
||||
}),
|
||||
}),
|
||||
},
|
||||
"structural-attr-single": {
|
||||
schema: &configschema.Block{
|
||||
Attributes: map[string]*configschema.Attribute{
|
||||
"nested": {
|
||||
NestedType: &configschema.Object{
|
||||
Nesting: configschema.NestingSingle,
|
||||
Attributes: map[string]*configschema.Attribute{
|
||||
"attr": {
|
||||
Type: cty.Number,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
config: cty.ObjectVal(map[string]cty.Value{
|
||||
"nested": cty.NullVal(cty.DynamicPseudoType),
|
||||
}),
|
||||
wantVal: cty.ObjectVal(map[string]cty.Value{
|
||||
"nested": cty.NullVal(cty.Object(map[string]cty.Type{
|
||||
"attr": cty.Number,
|
||||
})),
|
||||
}),
|
||||
},
|
||||
"structural-attr-group": {
|
||||
schema: &configschema.Block{
|
||||
Attributes: map[string]*configschema.Attribute{
|
||||
"nested": {
|
||||
NestedType: &configschema.Object{
|
||||
Nesting: configschema.NestingGroup,
|
||||
Attributes: map[string]*configschema.Attribute{
|
||||
"attr": {
|
||||
Type: cty.Number,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
config: cty.ObjectVal(map[string]cty.Value{
|
||||
"nested": cty.NullVal(cty.DynamicPseudoType),
|
||||
}),
|
||||
wantError: true, // This should not be hit in today's tofu/providers. If that assumption ever changes, we want to handle it gracefully.
|
||||
},
|
||||
"structural-attr-list": {
|
||||
schema: &configschema.Block{
|
||||
Attributes: map[string]*configschema.Attribute{
|
||||
"nested": {
|
||||
NestedType: &configschema.Object{
|
||||
Nesting: configschema.NestingList,
|
||||
Attributes: map[string]*configschema.Attribute{
|
||||
"attr": {
|
||||
Type: cty.Number,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
config: cty.ObjectVal(map[string]cty.Value{
|
||||
"nested": cty.NullVal(cty.DynamicPseudoType),
|
||||
}),
|
||||
wantVal: cty.ObjectVal(map[string]cty.Value{
|
||||
"nested": cty.NullVal(cty.List(cty.Object(map[string]cty.Type{
|
||||
"attr": cty.Number,
|
||||
}))),
|
||||
}),
|
||||
},
|
||||
"structural-attr-map": {
|
||||
schema: &configschema.Block{
|
||||
Attributes: map[string]*configschema.Attribute{
|
||||
"nested": {
|
||||
NestedType: &configschema.Object{
|
||||
Nesting: configschema.NestingMap,
|
||||
Attributes: map[string]*configschema.Attribute{
|
||||
"attr": {
|
||||
Type: cty.Number,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
config: cty.ObjectVal(map[string]cty.Value{
|
||||
"nested": cty.NullVal(cty.DynamicPseudoType),
|
||||
}),
|
||||
wantVal: cty.ObjectVal(map[string]cty.Value{
|
||||
"nested": cty.NullVal(cty.Map(cty.Object(map[string]cty.Type{
|
||||
"attr": cty.Number,
|
||||
}))),
|
||||
}),
|
||||
},
|
||||
"structural-attr-set": {
|
||||
schema: &configschema.Block{
|
||||
Attributes: map[string]*configschema.Attribute{
|
||||
"nested": {
|
||||
NestedType: &configschema.Object{
|
||||
Nesting: configschema.NestingSet,
|
||||
Attributes: map[string]*configschema.Attribute{
|
||||
"attr": {
|
||||
Type: cty.Number,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
config: cty.ObjectVal(map[string]cty.Value{
|
||||
"nested": cty.NullVal(cty.DynamicPseudoType),
|
||||
}),
|
||||
wantVal: cty.ObjectVal(map[string]cty.Value{
|
||||
"nested": cty.NullVal(cty.Set(cty.Object(map[string]cty.Type{
|
||||
"attr": cty.Number,
|
||||
}))),
|
||||
}),
|
||||
},
|
||||
"basic-group-block": {
|
||||
schema: &configschema.Block{
|
||||
BlockTypes: map[string]*configschema.NestedBlock{
|
||||
@@ -558,7 +681,7 @@ func TestComposeMockValueBySchema(t *testing.T) {
|
||||
t.Fatalf("Got unexpected error diags: %v", gotDiags.ErrWithWarnings())
|
||||
|
||||
case !test.wantVal.RawEquals(gotVal):
|
||||
t.Fatalf("Got unexpected value: %v", gotVal.GoString())
|
||||
t.Fatalf("Wrong value\ngot: %swant: %sdiff: %s", ctydebug.ValueString(gotVal), ctydebug.ValueString(test.wantVal), ctydebug.DiffValues(test.wantVal, gotVal))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user