Skip to content

Commit

Permalink
hcldec: A test case for attributes set to cty.DynamicVal with refinem…
Browse files Browse the repository at this point in the history
…ents

This test case is here to anticipate a _possible_ bug that isn't actually
buggy in the current implementation: if an attribute spec is given a
non-dynamic type constraint and then refined based on that type constraint
then the hcldec implementation must perform the type conversion first and
only then attempt to add the refinements.

Another possible variation here would be for the attribute spec to have
a dynamic type constraint (cty.DynamicPseudoType) and then try to refine
its result. That case isn't tested here because that's always an
implementation error in the calling application: RefineValueSpec must be
used only in ways that are valid for the full range of types that the
nested spec could produce, and there are no refinements that are valid
for the full range of cty.DynamicPseudoType. That situation can and will
panic at runtime, alerting the application developer that they've used
hcldec incorrectly. There is no way for end-user input to cause this panic
if the calling application is written correctly.

This doesn't actually change the system behavior. It's a regression test
to catch possible regressions under future maintenance.
  • Loading branch information
apparentlymart committed Aug 30, 2023
1 parent ed6d4bf commit 3617411
Showing 1 changed file with 8 additions and 0 deletions.
8 changes: 8 additions & 0 deletions hcldec/spec_test.go
Expand Up @@ -217,6 +217,7 @@ func TestRefineValueSpec(t *testing.T) {
config := `
foo = "hello"
bar = unk
dyn = dyn
`

f, diags := hclsyntax.ParseConfig([]byte(config), "", hcl.InitialPos)
Expand Down Expand Up @@ -257,11 +258,13 @@ bar = unk
spec := &ObjectSpec{
"foo": attrSpec("foo"),
"bar": attrSpec("bar"),
"dyn": attrSpec("dyn"),
}

got, diags := Decode(f.Body, spec, &hcl.EvalContext{
Variables: map[string]cty.Value{
"unk": cty.UnknownVal(cty.String),
"dyn": cty.DynamicVal,
},
})
if diags.HasErrors() {
Expand All @@ -276,6 +279,11 @@ bar = unk

// The final value of bar is unknown but refined as non-null.
"bar": cty.UnknownVal(cty.String).RefineNotNull(),

// The final value of dyn is unknown but refined as non-null.
// Correct behavior here requires that we convert the DynamicVal
// to an unknown string first and then refine it.
"dyn": cty.UnknownVal(cty.String).RefineNotNull(),
})
if diff := cmp.Diff(want, got, ctydebug.CmpOptions); diff != "" {
t.Errorf("wrong result\n%s", diff)
Expand Down

0 comments on commit 3617411

Please sign in to comment.