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

     1  package terraform
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/go-test/deep"
     7  
     8  	"github.com/hashicorp/terraform-plugin-sdk/internal/configs"
     9  	"github.com/hashicorp/terraform-plugin-sdk/internal/moduledeps"
    10  	"github.com/hashicorp/terraform-plugin-sdk/internal/plugin/discovery"
    11  )
    12  
    13  func TestModuleTreeDependencies(t *testing.T) {
    14  	tests := map[string]struct {
    15  		ConfigDir string // directory name from testdata dir
    16  		State     *State
    17  		Want      *moduledeps.Module
    18  	}{
    19  		"no config or state": {
    20  			"",
    21  			nil,
    22  			&moduledeps.Module{
    23  				Name:      "root",
    24  				Providers: moduledeps.Providers{},
    25  				Children:  nil,
    26  			},
    27  		},
    28  		"empty config no state": {
    29  			"empty",
    30  			nil,
    31  			&moduledeps.Module{
    32  				Name:      "root",
    33  				Providers: moduledeps.Providers{},
    34  				Children:  nil,
    35  			},
    36  		},
    37  		"explicit provider": {
    38  			"module-deps-explicit-provider",
    39  			nil,
    40  			&moduledeps.Module{
    41  				Name: "root",
    42  				Providers: moduledeps.Providers{
    43  					"foo": moduledeps.ProviderDependency{
    44  						Constraints: discovery.ConstraintStr(">=1.0.0").MustParse(),
    45  						Reason:      moduledeps.ProviderDependencyExplicit,
    46  					},
    47  					"foo.bar": moduledeps.ProviderDependency{
    48  						Constraints: discovery.ConstraintStr(">=2.0.0").MustParse(),
    49  						Reason:      moduledeps.ProviderDependencyExplicit,
    50  					},
    51  				},
    52  				Children: nil,
    53  			},
    54  		},
    55  		"explicit provider unconstrained": {
    56  			"module-deps-explicit-provider-unconstrained",
    57  			nil,
    58  			&moduledeps.Module{
    59  				Name: "root",
    60  				Providers: moduledeps.Providers{
    61  					"foo": moduledeps.ProviderDependency{
    62  						Constraints: discovery.AllVersions,
    63  						Reason:      moduledeps.ProviderDependencyExplicit,
    64  					},
    65  				},
    66  				Children: nil,
    67  			},
    68  		},
    69  		"implicit provider": {
    70  			"module-deps-implicit-provider",
    71  			nil,
    72  			&moduledeps.Module{
    73  				Name: "root",
    74  				Providers: moduledeps.Providers{
    75  					"foo": moduledeps.ProviderDependency{
    76  						Constraints: discovery.AllVersions,
    77  						Reason:      moduledeps.ProviderDependencyImplicit,
    78  					},
    79  					"foo.baz": moduledeps.ProviderDependency{
    80  						Constraints: discovery.AllVersions,
    81  						Reason:      moduledeps.ProviderDependencyImplicit,
    82  					},
    83  				},
    84  				Children: nil,
    85  			},
    86  		},
    87  		"explicit provider with resource": {
    88  			"module-deps-explicit-provider-resource",
    89  			nil,
    90  			&moduledeps.Module{
    91  				Name: "root",
    92  				Providers: moduledeps.Providers{
    93  					"foo": moduledeps.ProviderDependency{
    94  						Constraints: discovery.ConstraintStr(">=1.0.0").MustParse(),
    95  						Reason:      moduledeps.ProviderDependencyExplicit,
    96  					},
    97  				},
    98  				Children: nil,
    99  			},
   100  		},
   101  		"inheritance of providers": {
   102  			"module-deps-inherit-provider",
   103  			nil,
   104  			&moduledeps.Module{
   105  				Name: "root",
   106  				Providers: moduledeps.Providers{
   107  					"foo": moduledeps.ProviderDependency{
   108  						Constraints: discovery.AllVersions,
   109  						Reason:      moduledeps.ProviderDependencyExplicit,
   110  					},
   111  					"bar": moduledeps.ProviderDependency{
   112  						Constraints: discovery.AllVersions,
   113  						Reason:      moduledeps.ProviderDependencyExplicit,
   114  					},
   115  				},
   116  				Children: []*moduledeps.Module{
   117  					{
   118  						Name: "child",
   119  						Providers: moduledeps.Providers{
   120  							"foo": moduledeps.ProviderDependency{
   121  								Constraints: discovery.AllVersions,
   122  								Reason:      moduledeps.ProviderDependencyInherited,
   123  							},
   124  							"baz": moduledeps.ProviderDependency{
   125  								Constraints: discovery.AllVersions,
   126  								Reason:      moduledeps.ProviderDependencyImplicit,
   127  							},
   128  						},
   129  						Children: []*moduledeps.Module{
   130  							{
   131  								Name: "grandchild",
   132  								Providers: moduledeps.Providers{
   133  									"bar": moduledeps.ProviderDependency{
   134  										Constraints: discovery.AllVersions,
   135  										Reason:      moduledeps.ProviderDependencyInherited,
   136  									},
   137  									"foo": moduledeps.ProviderDependency{
   138  										Constraints: discovery.AllVersions,
   139  										Reason:      moduledeps.ProviderDependencyExplicit,
   140  									},
   141  								},
   142  							},
   143  						},
   144  					},
   145  				},
   146  			},
   147  		},
   148  		"provider from state": {
   149  			"empty",
   150  			&State{
   151  				Modules: []*ModuleState{
   152  					{
   153  						Path: []string{"root"},
   154  						Resources: map[string]*ResourceState{
   155  							"foo_bar.baz": {
   156  								Type:     "foo_bar",
   157  								Provider: "",
   158  							},
   159  						},
   160  					},
   161  				},
   162  			},
   163  			&moduledeps.Module{
   164  				Name: "root",
   165  				Providers: moduledeps.Providers{
   166  					"foo": moduledeps.ProviderDependency{
   167  						Constraints: discovery.AllVersions,
   168  						Reason:      moduledeps.ProviderDependencyFromState,
   169  					},
   170  				},
   171  				Children: nil,
   172  			},
   173  		},
   174  		"providers in both config and state": {
   175  			"module-deps-explicit-provider",
   176  			&State{
   177  				Modules: []*ModuleState{
   178  					{
   179  						Path: []string{"root"},
   180  						Resources: map[string]*ResourceState{
   181  							"foo_bar.test1": {
   182  								Type:     "foo_bar",
   183  								Provider: "",
   184  							},
   185  							"foo_bar.test2": {
   186  								Type:     "foo_bar",
   187  								Provider: "foo.bar",
   188  							},
   189  							"baz_bar.test": {
   190  								Type:     "baz_bar",
   191  								Provider: "",
   192  							},
   193  						},
   194  					},
   195  					// note that we've skipped root.child intentionally here,
   196  					// to verify that we'll infer it based on the following
   197  					// module rather than crashing.
   198  					{
   199  						Path: []string{"root", "child", "grandchild"},
   200  						Resources: map[string]*ResourceState{
   201  							"banana_skin.test": {
   202  								Type:     "banana_skin",
   203  								Provider: "",
   204  							},
   205  						},
   206  					},
   207  				},
   208  			},
   209  			&moduledeps.Module{
   210  				Name: "root",
   211  				Providers: moduledeps.Providers{
   212  					"foo": moduledeps.ProviderDependency{
   213  						Constraints: discovery.ConstraintStr(">=1.0.0").MustParse(),
   214  						Reason:      moduledeps.ProviderDependencyExplicit,
   215  					},
   216  					"foo.bar": moduledeps.ProviderDependency{
   217  						Constraints: discovery.ConstraintStr(">=2.0.0").MustParse(),
   218  						Reason:      moduledeps.ProviderDependencyExplicit,
   219  					},
   220  					"baz": moduledeps.ProviderDependency{
   221  						Constraints: discovery.AllVersions,
   222  						Reason:      moduledeps.ProviderDependencyFromState,
   223  					},
   224  				},
   225  				Children: []*moduledeps.Module{
   226  					{
   227  						Name:      "child",
   228  						Providers: make(moduledeps.Providers),
   229  						Children: []*moduledeps.Module{
   230  							{
   231  								Name: "grandchild",
   232  								Providers: moduledeps.Providers{
   233  									"banana": moduledeps.ProviderDependency{
   234  										Constraints: discovery.AllVersions,
   235  										Reason:      moduledeps.ProviderDependencyFromState,
   236  									},
   237  								},
   238  							},
   239  						},
   240  					},
   241  				},
   242  			},
   243  		},
   244  	}
   245  
   246  	for name, test := range tests {
   247  		t.Run(name, func(t *testing.T) {
   248  			var root *configs.Config
   249  			if test.ConfigDir != "" {
   250  				root = testModule(t, test.ConfigDir)
   251  			}
   252  
   253  			got := ConfigTreeDependencies(root, MustShimLegacyState(test.State))
   254  			for _, problem := range deep.Equal(got, test.Want) {
   255  				t.Error(problem)
   256  			}
   257  		})
   258  	}
   259  }