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  }