github.com/opentofu/opentofu@v1.7.1/internal/lang/globalref/analyzer_contributing_resources_test.go (about) 1 // Copyright (c) The OpenTofu Authors 2 // SPDX-License-Identifier: MPL-2.0 3 // Copyright (c) 2023 HashiCorp, Inc. 4 // SPDX-License-Identifier: MPL-2.0 5 6 package globalref 7 8 import ( 9 "sort" 10 "testing" 11 12 "github.com/google/go-cmp/cmp" 13 "github.com/opentofu/opentofu/internal/addrs" 14 ) 15 16 func TestAnalyzerContributingResources(t *testing.T) { 17 azr := testAnalyzer(t, "contributing-resources") 18 19 tests := map[string]struct { 20 StartRefs func() []Reference 21 WantAddrs []string 22 }{ 23 "root output 'network'": { 24 func() []Reference { 25 return azr.ReferencesFromOutputValue( 26 addrs.OutputValue{Name: "network"}.Absolute(addrs.RootModuleInstance), 27 ) 28 }, 29 []string{ 30 `data.test_thing.environment`, 31 `module.network.test_thing.subnet`, 32 `module.network.test_thing.vpc`, 33 }, 34 }, 35 "root output 'c10s_url'": { 36 func() []Reference { 37 return azr.ReferencesFromOutputValue( 38 addrs.OutputValue{Name: "c10s_url"}.Absolute(addrs.RootModuleInstance), 39 ) 40 }, 41 []string{ 42 `data.test_thing.environment`, 43 `module.compute.test_thing.load_balancer`, 44 `module.network.test_thing.subnet`, 45 `module.network.test_thing.vpc`, 46 47 // NOTE: module.compute.test_thing.controller isn't here 48 // because we can see statically that the output value refers 49 // only to the "string" attribute of 50 // module.compute.test_thing.load_balancer , and so we 51 // don't consider references inside the "list" blocks. 52 }, 53 }, 54 "module.compute.test_thing.load_balancer": { 55 func() []Reference { 56 return azr.ReferencesFromResourceInstance( 57 addrs.Resource{ 58 Mode: addrs.ManagedResourceMode, 59 Type: "test_thing", 60 Name: "load_balancer", 61 }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance.Child("compute", addrs.NoKey)), 62 ) 63 }, 64 []string{ 65 `data.test_thing.environment`, 66 `module.compute.test_thing.controller`, 67 `module.network.test_thing.subnet`, 68 `module.network.test_thing.vpc`, 69 }, 70 }, 71 "data.test_thing.environment": { 72 func() []Reference { 73 return azr.ReferencesFromResourceInstance( 74 addrs.Resource{ 75 Mode: addrs.DataResourceMode, 76 Type: "test_thing", 77 Name: "environment", 78 }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), 79 ) 80 }, 81 []string{ 82 // Nothing! This one only refers to an input variable. 83 }, 84 }, 85 } 86 87 for name, test := range tests { 88 t.Run(name, func(t *testing.T) { 89 startRefs := test.StartRefs() 90 addrs := azr.ContributingResources(startRefs...) 91 92 want := test.WantAddrs 93 got := make([]string, len(addrs)) 94 for i, addr := range addrs { 95 got[i] = addr.String() 96 } 97 if diff := cmp.Diff(want, got); diff != "" { 98 t.Errorf("wrong addresses\n%s", diff) 99 } 100 }) 101 } 102 } 103 104 func TestAnalyzerContributingResourceAttrs(t *testing.T) { 105 azr := testAnalyzer(t, "contributing-resources") 106 107 tests := map[string]struct { 108 StartRefs func() []Reference 109 WantAttrs []string 110 }{ 111 "root output 'network'": { 112 func() []Reference { 113 return azr.ReferencesFromOutputValue( 114 addrs.OutputValue{Name: "network"}.Absolute(addrs.RootModuleInstance), 115 ) 116 }, 117 []string{ 118 `data.test_thing.environment.any.base_cidr_block`, 119 `data.test_thing.environment.any.subnet_count`, 120 `module.network.test_thing.subnet`, 121 `module.network.test_thing.vpc.string`, 122 }, 123 }, 124 "root output 'c10s_url'": { 125 func() []Reference { 126 return azr.ReferencesFromOutputValue( 127 addrs.OutputValue{Name: "c10s_url"}.Absolute(addrs.RootModuleInstance), 128 ) 129 }, 130 []string{ 131 `data.test_thing.environment.any.base_cidr_block`, 132 `data.test_thing.environment.any.subnet_count`, 133 `module.compute.test_thing.load_balancer.string`, 134 `module.network.test_thing.subnet`, 135 `module.network.test_thing.vpc.string`, 136 }, 137 }, 138 "module.compute.test_thing.load_balancer": { 139 func() []Reference { 140 return azr.ReferencesFromResourceInstance( 141 addrs.Resource{ 142 Mode: addrs.ManagedResourceMode, 143 Type: "test_thing", 144 Name: "load_balancer", 145 }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance.Child("compute", addrs.NoKey)), 146 ) 147 }, 148 []string{ 149 `data.test_thing.environment.any.base_cidr_block`, 150 `data.test_thing.environment.any.subnet_count`, 151 `module.compute.test_thing.controller`, 152 `module.network.test_thing.subnet`, 153 `module.network.test_thing.vpc.string`, 154 }, 155 }, 156 "data.test_thing.environment": { 157 func() []Reference { 158 return azr.ReferencesFromResourceInstance( 159 addrs.Resource{ 160 Mode: addrs.DataResourceMode, 161 Type: "test_thing", 162 Name: "environment", 163 }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), 164 ) 165 }, 166 []string{ 167 // Nothing! This one only refers to an input variable. 168 }, 169 }, 170 } 171 172 for name, test := range tests { 173 t.Run(name, func(t *testing.T) { 174 startRefs := test.StartRefs() 175 refs := azr.ContributingResourceReferences(startRefs...) 176 177 want := test.WantAttrs 178 got := make([]string, len(refs)) 179 for i, ref := range refs { 180 resAttr, ok := ref.ResourceAttr() 181 if !ok { 182 t.Errorf("%s is not a resource attr reference", resAttr.DebugString()) 183 continue 184 } 185 got[i] = resAttr.DebugString() 186 } 187 188 sort.Strings(got) 189 190 if diff := cmp.Diff(want, got); diff != "" { 191 t.Errorf("wrong addresses\n%s", diff) 192 } 193 }) 194 } 195 }