terraform/terraform/module_dependencies_test.go

260 lines
6.7 KiB
Go

package terraform
import (
"testing"
"github.com/google/go-cmp/cmp"
"github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/configs"
"github.com/hashicorp/terraform/moduledeps"
"github.com/hashicorp/terraform/plugin/discovery"
)
func TestModuleTreeDependencies(t *testing.T) {
tests := map[string]struct {
ConfigDir string // directory name from testdata dir
State *State
Want *moduledeps.Module
}{
"no config or state": {
"",
nil,
&moduledeps.Module{
Name: "root",
Providers: moduledeps.Providers{},
Children: nil,
},
},
"empty config no state": {
"empty",
nil,
&moduledeps.Module{
Name: "root",
Providers: moduledeps.Providers{},
Children: nil,
},
},
"explicit provider": {
"module-deps-explicit-provider",
nil,
&moduledeps.Module{
Name: "root",
Providers: moduledeps.Providers{
addrs.NewLegacyProvider("foo"): moduledeps.ProviderDependency{
Constraints: discovery.ConstraintStr(">=1.0.0,>=2.0.0").MustParse(),
Reason: moduledeps.ProviderDependencyExplicit,
},
},
Children: nil,
},
},
"required_providers block": {
"module-deps-required-providers",
nil,
&moduledeps.Module{
Name: "root",
Providers: moduledeps.Providers{
addrs.NewLegacyProvider("foo"): moduledeps.ProviderDependency{
Constraints: discovery.ConstraintStr(">=1.0.0").MustParse(),
Reason: moduledeps.ProviderDependencyExplicit,
},
},
Children: nil,
},
},
"explicit provider unconstrained": {
"module-deps-explicit-provider-unconstrained",
nil,
&moduledeps.Module{
Name: "root",
Providers: moduledeps.Providers{
addrs.NewLegacyProvider("foo"): moduledeps.ProviderDependency{
Constraints: discovery.AllVersions,
Reason: moduledeps.ProviderDependencyExplicit,
},
},
Children: nil,
},
},
"implicit provider": {
"module-deps-implicit-provider",
nil,
&moduledeps.Module{
Name: "root",
Providers: moduledeps.Providers{
addrs.NewLegacyProvider("foo"): moduledeps.ProviderDependency{
Constraints: discovery.AllVersions,
Reason: moduledeps.ProviderDependencyImplicit,
},
},
Children: nil,
},
},
"explicit provider with resource": {
"module-deps-explicit-provider-resource",
nil,
&moduledeps.Module{
Name: "root",
Providers: moduledeps.Providers{
addrs.NewLegacyProvider("foo"): moduledeps.ProviderDependency{
Constraints: discovery.ConstraintStr(">=1.0.0").MustParse(),
Reason: moduledeps.ProviderDependencyExplicit,
},
},
Children: nil,
},
},
"inheritance of providers": {
"module-deps-inherit-provider",
nil,
&moduledeps.Module{
Name: "root",
Providers: moduledeps.Providers{
addrs.NewLegacyProvider("foo"): moduledeps.ProviderDependency{
Constraints: discovery.AllVersions,
Reason: moduledeps.ProviderDependencyExplicit,
},
addrs.NewLegacyProvider("bar"): moduledeps.ProviderDependency{
Constraints: discovery.AllVersions,
Reason: moduledeps.ProviderDependencyExplicit,
},
},
Children: []*moduledeps.Module{
{
Name: "child",
Providers: moduledeps.Providers{
addrs.NewLegacyProvider("foo"): moduledeps.ProviderDependency{
Constraints: discovery.AllVersions,
Reason: moduledeps.ProviderDependencyInherited,
},
addrs.NewLegacyProvider("baz"): moduledeps.ProviderDependency{
Constraints: discovery.AllVersions,
Reason: moduledeps.ProviderDependencyImplicit,
},
},
Children: []*moduledeps.Module{
{
Name: "grandchild",
Providers: moduledeps.Providers{
addrs.NewLegacyProvider("bar"): moduledeps.ProviderDependency{
Constraints: discovery.AllVersions,
Reason: moduledeps.ProviderDependencyInherited,
},
addrs.NewLegacyProvider("foo"): moduledeps.ProviderDependency{
Constraints: discovery.AllVersions,
Reason: moduledeps.ProviderDependencyExplicit,
},
},
},
},
},
},
},
},
"provider from state": {
"empty",
&State{
Modules: []*ModuleState{
{
Path: []string{"root"},
Resources: map[string]*ResourceState{
"foo_bar.baz": {
Type: "foo_bar",
Provider: "",
},
},
},
},
},
&moduledeps.Module{
Name: "root",
Providers: moduledeps.Providers{
addrs.NewLegacyProvider("foo"): moduledeps.ProviderDependency{
Constraints: discovery.AllVersions,
Reason: moduledeps.ProviderDependencyFromState,
},
},
Children: nil,
},
},
"providers in both config and state": {
"module-deps-explicit-provider",
&State{
Modules: []*ModuleState{
{
Path: []string{"root"},
Resources: map[string]*ResourceState{
"foo_bar.test1": {
Type: "foo_bar",
Provider: "",
},
"baz_bar.test": {
Type: "baz_bar",
Provider: "",
},
},
},
// note that we've skipped root.child intentionally here,
// to verify that we'll infer it based on the following
// module rather than crashing.
{
Path: []string{"root", "child", "grandchild"},
Resources: map[string]*ResourceState{
"banana_skin.test": {
Type: "banana_skin",
Provider: "",
},
},
},
},
},
&moduledeps.Module{
Name: "root",
Providers: moduledeps.Providers{
addrs.NewLegacyProvider("foo"): moduledeps.ProviderDependency{
Constraints: discovery.ConstraintStr(">=1.0.0,>=2.0.0").MustParse(),
Reason: moduledeps.ProviderDependencyExplicit,
},
addrs.NewLegacyProvider("baz"): moduledeps.ProviderDependency{
Constraints: discovery.AllVersions,
Reason: moduledeps.ProviderDependencyFromState,
},
},
Children: []*moduledeps.Module{
{
Name: "child",
Providers: make(moduledeps.Providers),
Children: []*moduledeps.Module{
{
Name: "grandchild",
Providers: moduledeps.Providers{
addrs.NewLegacyProvider("banana"): moduledeps.ProviderDependency{
Constraints: discovery.AllVersions,
Reason: moduledeps.ProviderDependencyFromState,
},
},
},
},
},
},
},
},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
var root *configs.Config
if test.ConfigDir != "" {
root = testModule(t, test.ConfigDir)
}
got := ConfigTreeDependencies(root, MustShimLegacyState(test.State))
if !cmp.Equal(got, test.Want) {
t.Error(cmp.Diff(got, test.Want))
}
})
}
}