don't cache unknown function results

The CheckPrior function results validation did not take into account
unknown values, because unknown values were not originally allowed in
the plugin protocol from which this check was adapted.

The test is simple, in that we can just reverse the check which
originally didn't allow this change in value. Provider function return
values types are defined by the protocol, and should be validated at
that call site. The CheckPrior code paths should only be used for the
exact purpose of detecting invalid changes in the return value between
successive phases of execution.
pull/37810/head
James Bardin 6 months ago
parent 2e5b5dee5d
commit 2227441f7d

@ -51,6 +51,16 @@ func (f *FunctionResults) CheckPrior(name string, args []cty.Value, result cty.V
// CheckPriorProvider compares the provider function call against any cached
// results, and returns an error if the result does not match a prior call.
func (f *FunctionResults) CheckPriorProvider(provider addrs.Provider, name string, args []cty.Value, result cty.Value) error {
// Don't cache unknown values. We could technically store types and
// refinements for validation, but we don't currently have a way to
// serialize those in the plan. Unknowns are also handled much more
// gracefully throughout the evaluation system, whereas invalid data is
// harder to trace back to the source since it's usually only visible due to
// unexpected side-effects.
if !result.IsKnown() {
return nil
}
argSum := sha256.New()
if !provider.IsZero() {

@ -72,7 +72,7 @@ func TestFunctionCache(t *testing.T) {
result: cty.False,
},
// result changed from unknown => false
expectErr: true,
expectErr: false,
},
{
first: testCall{
@ -172,6 +172,9 @@ func TestFunctionCache(t *testing.T) {
if err != nil && !test.expectErr {
t.Fatal(err)
}
if err == nil && test.expectErr {
t.Fatal("expected error")
}
// reload the data to ensure we validate identically
newResults := NewFunctionResultsTable(results.GetHashes())

Loading…
Cancel
Save