github.com/hashicorp/terraform-plugin-sdk@v1.17.2/terraform/transform_reference_test.go (about)

     1  package terraform
     2  
     3  import (
     4  	"reflect"
     5  	"sort"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/hashicorp/terraform-plugin-sdk/internal/addrs"
    10  	"github.com/hashicorp/terraform-plugin-sdk/internal/dag"
    11  )
    12  
    13  func TestReferenceTransformer_simple(t *testing.T) {
    14  	g := Graph{Path: addrs.RootModuleInstance}
    15  	g.Add(&graphNodeRefParentTest{
    16  		NameValue: "A",
    17  		Names:     []string{"A"},
    18  	})
    19  	g.Add(&graphNodeRefChildTest{
    20  		NameValue: "B",
    21  		Refs:      []string{"A"},
    22  	})
    23  
    24  	tf := &ReferenceTransformer{}
    25  	if err := tf.Transform(&g); err != nil {
    26  		t.Fatalf("err: %s", err)
    27  	}
    28  
    29  	actual := strings.TrimSpace(g.String())
    30  	expected := strings.TrimSpace(testTransformRefBasicStr)
    31  	if actual != expected {
    32  		t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
    33  	}
    34  }
    35  
    36  func TestReferenceTransformer_self(t *testing.T) {
    37  	g := Graph{Path: addrs.RootModuleInstance}
    38  	g.Add(&graphNodeRefParentTest{
    39  		NameValue: "A",
    40  		Names:     []string{"A"},
    41  	})
    42  	g.Add(&graphNodeRefChildTest{
    43  		NameValue: "B",
    44  		Refs:      []string{"A", "B"},
    45  	})
    46  
    47  	tf := &ReferenceTransformer{}
    48  	if err := tf.Transform(&g); err != nil {
    49  		t.Fatalf("err: %s", err)
    50  	}
    51  
    52  	actual := strings.TrimSpace(g.String())
    53  	expected := strings.TrimSpace(testTransformRefBasicStr)
    54  	if actual != expected {
    55  		t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
    56  	}
    57  }
    58  
    59  func TestReferenceTransformer_path(t *testing.T) {
    60  	g := Graph{Path: addrs.RootModuleInstance}
    61  	g.Add(&graphNodeRefParentTest{
    62  		NameValue: "A",
    63  		Names:     []string{"A"},
    64  	})
    65  	g.Add(&graphNodeRefChildTest{
    66  		NameValue: "B",
    67  		Refs:      []string{"A"},
    68  	})
    69  	g.Add(&graphNodeRefParentTest{
    70  		NameValue: "child.A",
    71  		PathValue: []string{"root", "child"},
    72  		Names:     []string{"A"},
    73  	})
    74  	g.Add(&graphNodeRefChildTest{
    75  		NameValue: "child.B",
    76  		PathValue: []string{"root", "child"},
    77  		Refs:      []string{"A"},
    78  	})
    79  
    80  	tf := &ReferenceTransformer{}
    81  	if err := tf.Transform(&g); err != nil {
    82  		t.Fatalf("err: %s", err)
    83  	}
    84  
    85  	actual := strings.TrimSpace(g.String())
    86  	expected := strings.TrimSpace(testTransformRefPathStr)
    87  	if actual != expected {
    88  		t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
    89  	}
    90  }
    91  
    92  func TestReferenceMapReferences(t *testing.T) {
    93  	cases := map[string]struct {
    94  		Nodes  []dag.Vertex
    95  		Check  dag.Vertex
    96  		Result []string
    97  	}{
    98  		"simple": {
    99  			Nodes: []dag.Vertex{
   100  				&graphNodeRefParentTest{
   101  					NameValue: "A",
   102  					Names:     []string{"A"},
   103  				},
   104  			},
   105  			Check: &graphNodeRefChildTest{
   106  				NameValue: "foo",
   107  				Refs:      []string{"A"},
   108  			},
   109  			Result: []string{"A"},
   110  		},
   111  	}
   112  
   113  	for tn, tc := range cases {
   114  		t.Run(tn, func(t *testing.T) {
   115  			rm := NewReferenceMap(tc.Nodes)
   116  			result, _ := rm.References(tc.Check)
   117  
   118  			var resultStr []string
   119  			for _, v := range result {
   120  				resultStr = append(resultStr, dag.VertexName(v))
   121  			}
   122  
   123  			sort.Strings(resultStr)
   124  			sort.Strings(tc.Result)
   125  			if !reflect.DeepEqual(resultStr, tc.Result) {
   126  				t.Fatalf("bad: %#v", resultStr)
   127  			}
   128  		})
   129  	}
   130  }
   131  
   132  func TestReferenceMapReferencedBy(t *testing.T) {
   133  	cases := map[string]struct {
   134  		Nodes  []dag.Vertex
   135  		Check  dag.Vertex
   136  		Result []string
   137  	}{
   138  		"simple": {
   139  			Nodes: []dag.Vertex{
   140  				&graphNodeRefChildTest{
   141  					NameValue: "A",
   142  					Refs:      []string{"A"},
   143  				},
   144  				&graphNodeRefChildTest{
   145  					NameValue: "B",
   146  					Refs:      []string{"A"},
   147  				},
   148  				&graphNodeRefChildTest{
   149  					NameValue: "C",
   150  					Refs:      []string{"B"},
   151  				},
   152  			},
   153  			Check: &graphNodeRefParentTest{
   154  				NameValue: "foo",
   155  				Names:     []string{"A"},
   156  			},
   157  			Result: []string{"A", "B"},
   158  		},
   159  	}
   160  
   161  	for tn, tc := range cases {
   162  		t.Run(tn, func(t *testing.T) {
   163  			rm := NewReferenceMap(tc.Nodes)
   164  			result := rm.Referrers(tc.Check)
   165  
   166  			var resultStr []string
   167  			for _, v := range result {
   168  				resultStr = append(resultStr, dag.VertexName(v))
   169  			}
   170  
   171  			sort.Strings(resultStr)
   172  			sort.Strings(tc.Result)
   173  			if !reflect.DeepEqual(resultStr, tc.Result) {
   174  				t.Fatalf("bad: %#v", resultStr)
   175  			}
   176  		})
   177  	}
   178  }
   179  
   180  type graphNodeRefParentTest struct {
   181  	NameValue string
   182  	PathValue []string
   183  	Names     []string
   184  }
   185  
   186  var _ GraphNodeReferenceable = (*graphNodeRefParentTest)(nil)
   187  
   188  func (n *graphNodeRefParentTest) Name() string {
   189  	return n.NameValue
   190  }
   191  
   192  func (n *graphNodeRefParentTest) ReferenceableAddrs() []addrs.Referenceable {
   193  	ret := make([]addrs.Referenceable, len(n.Names))
   194  	for i, name := range n.Names {
   195  		ret[i] = addrs.LocalValue{Name: name}
   196  	}
   197  	return ret
   198  }
   199  
   200  func (n *graphNodeRefParentTest) Path() addrs.ModuleInstance {
   201  	return normalizeModulePath(n.PathValue)
   202  }
   203  
   204  type graphNodeRefChildTest struct {
   205  	NameValue string
   206  	PathValue []string
   207  	Refs      []string
   208  }
   209  
   210  var _ GraphNodeReferencer = (*graphNodeRefChildTest)(nil)
   211  
   212  func (n *graphNodeRefChildTest) Name() string {
   213  	return n.NameValue
   214  }
   215  
   216  func (n *graphNodeRefChildTest) References() []*addrs.Reference {
   217  	ret := make([]*addrs.Reference, len(n.Refs))
   218  	for i, name := range n.Refs {
   219  		ret[i] = &addrs.Reference{
   220  			Subject: addrs.LocalValue{Name: name},
   221  		}
   222  	}
   223  	return ret
   224  }
   225  
   226  func (n *graphNodeRefChildTest) Path() addrs.ModuleInstance {
   227  	return normalizeModulePath(n.PathValue)
   228  }
   229  
   230  const testTransformRefBasicStr = `
   231  A
   232  B
   233    A
   234  `
   235  
   236  const testTransformRefPathStr = `
   237  A
   238  B
   239    A
   240  child.A
   241  child.B
   242    child.A
   243  `