mirror of
https://github.com/hashicorp/terraform.git
synced 2026-03-21 10:00:09 -04:00
91 lines
5.3 KiB
Go
91 lines
5.3 KiB
Go
// Copyright IBM Corp. 2014, 2026
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package namedvals
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/hashicorp/terraform/internal/addrs"
|
|
"github.com/zclconf/go-cty/cty"
|
|
)
|
|
|
|
func TestValues(t *testing.T) {
|
|
// The behavior of [values] is the same for all named value address types,
|
|
// and so we'll just use local values here as a placeholder and assume
|
|
// that input variables and output values would also work.
|
|
|
|
// The following addresses are taking some liberties with which combinations
|
|
// would actually be possible in practice with a real Terraform
|
|
// configuration -- unknowns and knowns cannot typically mix at the same
|
|
// known-expansion module prefix -- but the abstraction in this package
|
|
// doesn't aim to enforce those rules, and so we can expect it to be a
|
|
// little more flexible here than it really needs to be, as a way to
|
|
// reduce the amount of test setup we need.
|
|
childInst0 := addrs.ModuleInstance{{Name: "child", InstanceKey: addrs.IntKey(0)}}
|
|
childInst1 := addrs.ModuleInstance{{Name: "child", InstanceKey: addrs.IntKey(1)}}
|
|
childInst2 := addrs.ModuleInstance{{Name: "child", InstanceKey: addrs.IntKey(2)}}
|
|
childInstUnk := addrs.RootModuleInstance.UnexpandedChild(addrs.ModuleCall{Name: "child"})
|
|
grandchildInst0_0 := childInst0.Child("grandchild", addrs.IntKey(0))
|
|
grandchildInst1_unk := childInst1.UnexpandedChild(addrs.ModuleCall{Name: "grandchild"})
|
|
grandchildInst2_unk := childInst2.UnexpandedChild(addrs.ModuleCall{Name: "grandchild"})
|
|
grandchildInstUnk_unk := childInstUnk.Child(addrs.ModuleCall{Name: "grandchild"})
|
|
|
|
inRoot := addrs.LocalValue{Name: "in_root"}.Absolute(addrs.RootModuleInstance)
|
|
inChild0 := addrs.LocalValue{Name: "in_child"}.Absolute(childInst0)
|
|
inChildUnk := addrs.ObjectInPartialExpandedModule(childInstUnk, addrs.LocalValue{Name: "in_child"})
|
|
inGrandchild0_0 := addrs.LocalValue{Name: "in_grandchild"}.Absolute(grandchildInst0_0)
|
|
inGrandchild1_unk := addrs.ObjectInPartialExpandedModule(grandchildInst1_unk, addrs.LocalValue{Name: "in_grandchild"})
|
|
inGrandchild2_unk := addrs.ObjectInPartialExpandedModule(grandchildInst2_unk, addrs.LocalValue{Name: "in_grandchild"})
|
|
inGrandchildUnk_unk := addrs.ObjectInPartialExpandedModule(grandchildInstUnk_unk, addrs.LocalValue{Name: "in_grandchild"})
|
|
|
|
vals := newValues[addrs.LocalValue, addrs.AbsLocalValue]()
|
|
vals.SetExactResult(inRoot, cty.StringVal("in root"))
|
|
vals.SetExactResult(inChild0, cty.StringVal("in child 0"))
|
|
vals.SetExactResult(inGrandchild0_0, cty.StringVal("in grandchild 0, 0"))
|
|
vals.SetPlaceholderResult(inChildUnk, cty.StringVal("placeholder for all unknown instances of child"))
|
|
vals.SetPlaceholderResult(inGrandchild1_unk, cty.StringVal("placeholder for all unknown instances of child 1 grandchild"))
|
|
vals.SetPlaceholderResult(inGrandchildUnk_unk, cty.StringVal("placeholder for all unknown instances of child unknown grandchild"))
|
|
|
|
t.Run("exact values", func(t *testing.T) {
|
|
// Exact values require the given address to exactly match something
|
|
// that was registered.
|
|
|
|
if got, want := vals.GetExactResult(inRoot), cty.StringVal("in root"); !want.RawEquals(got) {
|
|
t.Errorf("wrong exact value for %s\ngot: %#v\nwant: %#v", inRoot, got, want)
|
|
}
|
|
if got, want := vals.GetExactResult(inChild0), cty.StringVal("in child 0"); !want.RawEquals(got) {
|
|
t.Errorf("wrong exact value for %s\ngot: %#v\nwant: %#v", inChild0, got, want)
|
|
}
|
|
if got, want := vals.GetExactResult(inGrandchild0_0), cty.StringVal("in grandchild 0, 0"); !want.RawEquals(got) {
|
|
t.Errorf("wrong exact value for %s\ngot: %#v\nwant: %#v", inGrandchild0_0, got, want)
|
|
}
|
|
})
|
|
t.Run("placeholder values", func(t *testing.T) {
|
|
// Placeholder values are selected by longest-prefix pattern matching,
|
|
// and so we can ask both for specific prefixes we registered above
|
|
// and for more specific prefixes that we didn't register but yet
|
|
// still match a less-specific address.
|
|
|
|
if got, want := vals.GetPlaceholderResult(inChildUnk), cty.StringVal("placeholder for all unknown instances of child"); !want.RawEquals(got) {
|
|
// This one exactly matches one of the address patterns we registered.
|
|
t.Errorf("wrong exact value for %s\ngot: %#v\nwant: %#v", inChildUnk, got, want)
|
|
}
|
|
if got, want := vals.GetPlaceholderResult(inGrandchild1_unk), cty.StringVal("placeholder for all unknown instances of child 1 grandchild"); !want.RawEquals(got) {
|
|
// This one exactly matches one of the address patterns we registered.
|
|
t.Errorf("wrong exact value for %s\ngot: %#v\nwant: %#v", inGrandchild1_unk, got, want)
|
|
}
|
|
if got, want := vals.GetPlaceholderResult(inGrandchild2_unk), cty.StringVal("placeholder for all unknown instances of child unknown grandchild"); !want.RawEquals(got) {
|
|
// This one falls back to the placeholder for when the child
|
|
// instance key isn't known, because there isn't a more specific
|
|
// placeholder available.
|
|
t.Errorf("wrong exact value for %s\ngot: %#v\nwant: %#v", inGrandchild2_unk, got, want)
|
|
}
|
|
if got, want := vals.GetPlaceholderResult(inGrandchildUnk_unk), cty.StringVal("placeholder for all unknown instances of child unknown grandchild"); !want.RawEquals(got) {
|
|
// This one falls back to the placeholder for when the child
|
|
// instance key isn't known, because we can't know which of
|
|
// the more specific placeholders to select.
|
|
t.Errorf("wrong exact value for %s\ngot: %#v\nwant: %#v", inGrandchildUnk_unk, got, want)
|
|
}
|
|
})
|
|
}
|