don't assert set block length with unknowns

If a planned NestingList block value looks like it may represent a
dynamic block, we don't check the length since it may be unknown. This
check was missing in the NestingSet case, but it applies for the same
reason.

<
This commit is contained in:
James Bardin 2019-07-12 16:33:18 -04:00
parent a20e209397
commit 7a183a0e90
2 changed files with 41 additions and 3 deletions

View File

@ -169,6 +169,16 @@ func assertObjectCompatible(schema *configschema.Block, planned, actual cty.Valu
}) })
errs = append(errs, setErrs...) errs = append(errs, setErrs...)
if maybeUnknownBlocks {
// When unknown blocks are present the final number of blocks
// may be different, either because the unknown set values
// become equal and are collapsed, or the count is unknown due
// a dynamic block. Unfortunately this means we can't do our
// usual checks in this case without generating false
// negatives.
continue
}
// There can be fewer elements in a set after its elements are all // There can be fewer elements in a set after its elements are all
// known (values that turn out to be equal will coalesce) but the // known (values that turn out to be equal will coalesce) but the
// number of elements must never get larger. // number of elements must never get larger.

View File

@ -1068,9 +1068,9 @@ func TestAssertObjectCompatible(t *testing.T) {
}), }),
}), }),
}), }),
[]string{ // there is no error here, because the presence of unknowns
`.block: block set length changed from 2 to 3`, // indicates this may be a dynamic block, and the length is unknown
}, nil,
}, },
{ {
&configschema.Block{ &configschema.Block{
@ -1135,6 +1135,34 @@ func TestAssertObjectCompatible(t *testing.T) {
}), }),
nil, nil,
}, },
{
&configschema.Block{
BlockTypes: map[string]*configschema.NestedBlock{
"block": {
Nesting: configschema.NestingSet,
Block: schemaWithFoo,
},
},
},
cty.ObjectVal(map[string]cty.Value{
"block": cty.SetVal([]cty.Value{
cty.ObjectVal(map[string]cty.Value{
"foo": cty.UnknownVal(cty.String),
}),
}),
}),
cty.ObjectVal(map[string]cty.Value{
"block": cty.SetVal([]cty.Value{
cty.ObjectVal(map[string]cty.Value{
"foo": cty.StringVal("a"),
}),
cty.ObjectVal(map[string]cty.Value{
"foo": cty.StringVal("b"),
}),
}),
}),
nil,
},
{ {
&configschema.Block{ &configschema.Block{
BlockTypes: map[string]*configschema.NestedBlock{ BlockTypes: map[string]*configschema.NestedBlock{