mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-30 10:47:14 -06:00
521bdcc241
GraphNodeModulePath is similar to GraphNodeSubPath, except that it returns an addrs.Module rather than an addrs.ModuleInstance. This is used by the ReferenceTransformer to connect references, when modules may not yet be expanded. Because references only exist within the scope of a module, we can connect everything knowing only the module path. If the reference is to an expanded module instance output, we can still properly order the reference because we'll wait for the entire module to complete evaluation.
223 lines
4.4 KiB
Go
223 lines
4.4 KiB
Go
package terraform
|
|
|
|
import (
|
|
"reflect"
|
|
"sort"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/terraform/addrs"
|
|
"github.com/hashicorp/terraform/dag"
|
|
)
|
|
|
|
func TestReferenceTransformer_simple(t *testing.T) {
|
|
g := Graph{Path: addrs.RootModuleInstance}
|
|
g.Add(&graphNodeRefParentTest{
|
|
NameValue: "A",
|
|
Names: []string{"A"},
|
|
})
|
|
g.Add(&graphNodeRefChildTest{
|
|
NameValue: "B",
|
|
Refs: []string{"A"},
|
|
})
|
|
|
|
tf := &ReferenceTransformer{}
|
|
if err := tf.Transform(&g); err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
|
|
actual := strings.TrimSpace(g.String())
|
|
expected := strings.TrimSpace(testTransformRefBasicStr)
|
|
if actual != expected {
|
|
t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
|
|
}
|
|
}
|
|
|
|
func TestReferenceTransformer_self(t *testing.T) {
|
|
g := Graph{Path: addrs.RootModuleInstance}
|
|
g.Add(&graphNodeRefParentTest{
|
|
NameValue: "A",
|
|
Names: []string{"A"},
|
|
})
|
|
g.Add(&graphNodeRefChildTest{
|
|
NameValue: "B",
|
|
Refs: []string{"A", "B"},
|
|
})
|
|
|
|
tf := &ReferenceTransformer{}
|
|
if err := tf.Transform(&g); err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
|
|
actual := strings.TrimSpace(g.String())
|
|
expected := strings.TrimSpace(testTransformRefBasicStr)
|
|
if actual != expected {
|
|
t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
|
|
}
|
|
}
|
|
|
|
func TestReferenceTransformer_path(t *testing.T) {
|
|
g := Graph{Path: addrs.RootModuleInstance}
|
|
g.Add(&graphNodeRefParentTest{
|
|
NameValue: "A",
|
|
Names: []string{"A"},
|
|
})
|
|
g.Add(&graphNodeRefChildTest{
|
|
NameValue: "B",
|
|
Refs: []string{"A"},
|
|
})
|
|
g.Add(&graphNodeRefParentTest{
|
|
NameValue: "child.A",
|
|
PathValue: []string{"root", "child"},
|
|
Names: []string{"A"},
|
|
})
|
|
g.Add(&graphNodeRefChildTest{
|
|
NameValue: "child.B",
|
|
PathValue: []string{"root", "child"},
|
|
Refs: []string{"A"},
|
|
})
|
|
|
|
tf := &ReferenceTransformer{}
|
|
if err := tf.Transform(&g); err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
|
|
actual := strings.TrimSpace(g.String())
|
|
expected := strings.TrimSpace(testTransformRefPathStr)
|
|
if actual != expected {
|
|
t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
|
|
}
|
|
}
|
|
|
|
func TestReferenceMapReferences(t *testing.T) {
|
|
cases := map[string]struct {
|
|
Nodes []dag.Vertex
|
|
Check dag.Vertex
|
|
Result []string
|
|
}{
|
|
"simple": {
|
|
Nodes: []dag.Vertex{
|
|
&graphNodeRefParentTest{
|
|
NameValue: "A",
|
|
Names: []string{"A"},
|
|
},
|
|
},
|
|
Check: &graphNodeRefChildTest{
|
|
NameValue: "foo",
|
|
Refs: []string{"A"},
|
|
},
|
|
Result: []string{"A"},
|
|
},
|
|
}
|
|
|
|
for tn, tc := range cases {
|
|
t.Run(tn, func(t *testing.T) {
|
|
rm := NewReferenceMap(tc.Nodes)
|
|
result := rm.References(tc.Check)
|
|
|
|
var resultStr []string
|
|
for _, v := range result {
|
|
resultStr = append(resultStr, dag.VertexName(v))
|
|
}
|
|
|
|
sort.Strings(resultStr)
|
|
sort.Strings(tc.Result)
|
|
if !reflect.DeepEqual(resultStr, tc.Result) {
|
|
t.Fatalf("bad: %#v", resultStr)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
type graphNodeRefParentTest struct {
|
|
NameValue string
|
|
PathValue []string
|
|
Names []string
|
|
}
|
|
|
|
var _ GraphNodeReferenceable = (*graphNodeRefParentTest)(nil)
|
|
|
|
func (n *graphNodeRefParentTest) Name() string {
|
|
return n.NameValue
|
|
}
|
|
|
|
func (n *graphNodeRefParentTest) ReferenceableAddrs() []addrs.Referenceable {
|
|
ret := make([]addrs.Referenceable, len(n.Names))
|
|
for i, name := range n.Names {
|
|
ret[i] = addrs.LocalValue{Name: name}
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func (n *graphNodeRefParentTest) Path() addrs.ModuleInstance {
|
|
return normalizeModulePath(n.PathValue)
|
|
}
|
|
|
|
func (n *graphNodeRefParentTest) ModulePath() addrs.Module {
|
|
return normalizeModulePath(n.PathValue).Module()
|
|
}
|
|
|
|
type graphNodeRefChildTest struct {
|
|
NameValue string
|
|
PathValue []string
|
|
Refs []string
|
|
}
|
|
|
|
var _ GraphNodeReferencer = (*graphNodeRefChildTest)(nil)
|
|
|
|
func (n *graphNodeRefChildTest) Name() string {
|
|
return n.NameValue
|
|
}
|
|
|
|
func (n *graphNodeRefChildTest) References() []*addrs.Reference {
|
|
ret := make([]*addrs.Reference, len(n.Refs))
|
|
for i, name := range n.Refs {
|
|
ret[i] = &addrs.Reference{
|
|
Subject: addrs.LocalValue{Name: name},
|
|
}
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func (n *graphNodeRefChildTest) Path() addrs.ModuleInstance {
|
|
return normalizeModulePath(n.PathValue)
|
|
}
|
|
|
|
func (n *graphNodeRefChildTest) ModulePath() addrs.Module {
|
|
return normalizeModulePath(n.PathValue).Module()
|
|
}
|
|
|
|
const testTransformRefBasicStr = `
|
|
A
|
|
B
|
|
A
|
|
`
|
|
|
|
const testTransformRefBackupStr = `
|
|
A
|
|
B
|
|
A
|
|
`
|
|
|
|
const testTransformRefBackupPrimaryStr = `
|
|
A
|
|
B
|
|
C
|
|
C
|
|
`
|
|
|
|
const testTransformRefModulePathStr = `
|
|
A
|
|
B
|
|
A
|
|
`
|
|
|
|
const testTransformRefPathStr = `
|
|
A
|
|
B
|
|
A
|
|
child.A
|
|
child.B
|
|
child.A
|
|
`
|