mirror of
https://github.com/hashicorp/terraform.git
synced 2026-03-21 10:00:09 -04:00
190 lines
4.4 KiB
Go
190 lines
4.4 KiB
Go
// Copyright IBM Corp. 2014, 2026
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package lang
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/terraform/internal/addrs"
|
|
"github.com/zclconf/go-cty/cty"
|
|
|
|
// set the correct global logger for tests
|
|
_ "github.com/hashicorp/terraform/internal/logging"
|
|
)
|
|
|
|
func TestFunctionCache(t *testing.T) {
|
|
testAddr := addrs.NewDefaultProvider("test")
|
|
|
|
type testCall struct {
|
|
provider addrs.Provider
|
|
name string
|
|
args []cty.Value
|
|
result cty.Value
|
|
}
|
|
|
|
tests := []struct {
|
|
first, second testCall
|
|
expectErr bool
|
|
}{
|
|
{
|
|
first: testCall{
|
|
provider: testAddr,
|
|
name: "fun",
|
|
args: []cty.Value{cty.StringVal("ok")},
|
|
result: cty.True,
|
|
},
|
|
second: testCall{
|
|
provider: testAddr,
|
|
name: "fun",
|
|
args: []cty.Value{cty.StringVal("ok")},
|
|
result: cty.True,
|
|
},
|
|
},
|
|
{
|
|
first: testCall{
|
|
provider: testAddr,
|
|
name: "fun",
|
|
args: []cty.Value{cty.StringVal("ok")},
|
|
result: cty.True,
|
|
},
|
|
second: testCall{
|
|
provider: testAddr,
|
|
name: "fun",
|
|
args: []cty.Value{cty.StringVal("ok")},
|
|
result: cty.False,
|
|
},
|
|
// result changed from true => false
|
|
expectErr: true,
|
|
},
|
|
{
|
|
first: testCall{
|
|
provider: testAddr,
|
|
name: "fun",
|
|
args: []cty.Value{cty.StringVal("ok")},
|
|
result: cty.UnknownVal(cty.Bool),
|
|
},
|
|
second: testCall{
|
|
provider: testAddr,
|
|
name: "fun",
|
|
args: []cty.Value{cty.StringVal("ok")},
|
|
result: cty.False,
|
|
},
|
|
// result changed from unknown => false
|
|
expectErr: false,
|
|
},
|
|
{
|
|
first: testCall{
|
|
provider: testAddr,
|
|
name: "fun",
|
|
args: []cty.Value{cty.StringVal("ok")},
|
|
result: cty.True,
|
|
},
|
|
second: testCall{
|
|
provider: addrs.NewDefaultProvider("fake"),
|
|
name: "fun",
|
|
args: []cty.Value{cty.StringVal("ok")},
|
|
result: cty.False,
|
|
},
|
|
// OK because provider changed
|
|
},
|
|
{
|
|
first: testCall{
|
|
provider: testAddr,
|
|
name: "fun",
|
|
args: []cty.Value{cty.StringVal("ok")},
|
|
result: cty.True,
|
|
},
|
|
second: testCall{
|
|
provider: testAddr,
|
|
name: "func",
|
|
args: []cty.Value{cty.StringVal("ok")},
|
|
result: cty.False,
|
|
},
|
|
// OK because function name changed
|
|
},
|
|
{
|
|
first: testCall{
|
|
provider: testAddr,
|
|
name: "fun",
|
|
args: []cty.Value{cty.StringVal("ok")},
|
|
result: cty.True,
|
|
},
|
|
second: testCall{
|
|
provider: testAddr,
|
|
name: "fun",
|
|
args: []cty.Value{cty.StringVal("ok"), cty.StringVal("ok")},
|
|
result: cty.False,
|
|
},
|
|
// OK because args changed
|
|
},
|
|
{
|
|
first: testCall{
|
|
provider: testAddr,
|
|
name: "fun",
|
|
args: []cty.Value{cty.ObjectVal(map[string]cty.Value{
|
|
"attr": cty.NumberIntVal(1),
|
|
})},
|
|
result: cty.True,
|
|
},
|
|
second: testCall{
|
|
provider: testAddr,
|
|
name: "fun",
|
|
args: []cty.Value{cty.ObjectVal(map[string]cty.Value{
|
|
"attr": cty.NumberIntVal(2),
|
|
})},
|
|
result: cty.False,
|
|
},
|
|
// OK because args changed
|
|
},
|
|
{
|
|
first: testCall{
|
|
provider: testAddr,
|
|
name: "fun",
|
|
args: []cty.Value{cty.UnknownVal(cty.Object(map[string]cty.Type{
|
|
"attr": cty.Number,
|
|
}))},
|
|
result: cty.UnknownVal(cty.Bool),
|
|
},
|
|
second: testCall{
|
|
provider: testAddr,
|
|
name: "fun",
|
|
args: []cty.Value{cty.ObjectVal(map[string]cty.Value{
|
|
"attr": cty.NumberIntVal(2),
|
|
})},
|
|
result: cty.False,
|
|
},
|
|
// OK because args changed from unknown to known
|
|
},
|
|
}
|
|
|
|
for i, test := range tests {
|
|
t.Run(fmt.Sprint(i), func(t *testing.T) {
|
|
results := NewFunctionResultsTable(nil)
|
|
err := results.CheckPriorProvider(test.first.provider, test.first.name, test.first.args, test.first.result)
|
|
if err != nil {
|
|
t.Fatal("error on first call!", err)
|
|
}
|
|
|
|
err = results.CheckPriorProvider(test.second.provider, test.second.name, test.second.args, test.second.result)
|
|
|
|
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())
|
|
|
|
originalErr := err != nil
|
|
reloadedErr := newResults.CheckPriorProvider(test.second.provider, test.second.name, test.second.args, test.second.result) != nil
|
|
|
|
if originalErr != reloadedErr {
|
|
t.Fatalf("original check returned err:%t, reloaded check returned err:%t", originalErr, reloadedErr)
|
|
}
|
|
})
|
|
}
|
|
}
|