package configs import ( "io/ioutil" "testing" "github.com/go-test/deep" "github.com/hashicorp/hcl/v2" "github.com/hashicorp/terraform/internal/addrs" ) func TestLoadModuleCall(t *testing.T) { src, err := ioutil.ReadFile("testdata/invalid-files/module-calls.tf") if err != nil { t.Fatal(err) } parser := testParser(map[string]string{ "module-calls.tf": string(src), }) file, diags := parser.LoadConfigFile("module-calls.tf") assertExactDiagnostics(t, diags, []string{ `module-calls.tf:20,3-11: Invalid combination of "count" and "for_each"; The "count" and "for_each" meta-arguments are mutually-exclusive, only one should be used to be explicit about the number of resources to be created.`, }) gotModules := file.ModuleCalls wantModules := []*ModuleCall{ { Name: "foo", SourceAddr: addrs.ModuleSourceLocal("./foo"), SourceAddrRaw: "./foo", SourceSet: true, SourceAddrRange: hcl.Range{ Filename: "module-calls.tf", Start: hcl.Pos{Line: 3, Column: 12, Byte: 27}, End: hcl.Pos{Line: 3, Column: 19, Byte: 34}, }, DeclRange: hcl.Range{ Filename: "module-calls.tf", Start: hcl.Pos{Line: 2, Column: 1, Byte: 1}, End: hcl.Pos{Line: 2, Column: 13, Byte: 13}, }, }, { Name: "bar", SourceAddr: addrs.ModuleSourceRegistry{ PackageAddr: addrs.ModuleRegistryPackage{ Host: addrs.DefaultModuleRegistryHost, Namespace: "hashicorp", Name: "bar", TargetSystem: "aws", }, }, SourceAddrRaw: "hashicorp/bar/aws", SourceSet: true, SourceAddrRange: hcl.Range{ Filename: "module-calls.tf", Start: hcl.Pos{Line: 8, Column: 12, Byte: 113}, End: hcl.Pos{Line: 8, Column: 31, Byte: 132}, }, DeclRange: hcl.Range{ Filename: "module-calls.tf", Start: hcl.Pos{Line: 7, Column: 1, Byte: 87}, End: hcl.Pos{Line: 7, Column: 13, Byte: 99}, }, }, { Name: "baz", SourceAddr: addrs.ModuleSourceRemote{ PackageAddr: addrs.ModulePackage("git::https://example.com/"), }, SourceAddrRaw: "git::https://example.com/", SourceSet: true, SourceAddrRange: hcl.Range{ Filename: "module-calls.tf", Start: hcl.Pos{Line: 15, Column: 12, Byte: 193}, End: hcl.Pos{Line: 15, Column: 39, Byte: 220}, }, DependsOn: []hcl.Traversal{ { hcl.TraverseRoot{ Name: "module", SrcRange: hcl.Range{ Filename: "module-calls.tf", Start: hcl.Pos{Line: 23, Column: 5, Byte: 295}, End: hcl.Pos{Line: 23, Column: 11, Byte: 301}, }, }, hcl.TraverseAttr{ Name: "bar", SrcRange: hcl.Range{ Filename: "module-calls.tf", Start: hcl.Pos{Line: 23, Column: 11, Byte: 301}, End: hcl.Pos{Line: 23, Column: 15, Byte: 305}, }, }, }, }, Providers: []PassedProviderConfig{ { InChild: &ProviderConfigRef{ Name: "aws", NameRange: hcl.Range{ Filename: "module-calls.tf", Start: hcl.Pos{Line: 27, Column: 5, Byte: 332}, End: hcl.Pos{Line: 27, Column: 8, Byte: 335}, }, }, InParent: &ProviderConfigRef{ Name: "aws", NameRange: hcl.Range{ Filename: "module-calls.tf", Start: hcl.Pos{Line: 27, Column: 11, Byte: 338}, End: hcl.Pos{Line: 27, Column: 14, Byte: 341}, }, Alias: "foo", AliasRange: &hcl.Range{ Filename: "module-calls.tf", Start: hcl.Pos{Line: 27, Column: 14, Byte: 341}, End: hcl.Pos{Line: 27, Column: 18, Byte: 345}, }, }, }, }, DeclRange: hcl.Range{ Filename: "module-calls.tf", Start: hcl.Pos{Line: 14, Column: 1, Byte: 167}, End: hcl.Pos{Line: 14, Column: 13, Byte: 179}, }, }, } // We'll hide all of the bodies/exprs since we're treating them as opaque // here anyway... the point of this test is to ensure we handle everything // else properly. for _, m := range gotModules { m.Config = nil m.Count = nil m.ForEach = nil } for _, problem := range deep.Equal(gotModules, wantModules) { t.Error(problem) } } func TestModuleSourceAddrEntersNewPackage(t *testing.T) { tests := []struct { Addr string Want bool }{ { "./", false, }, { "../bork", false, }, { "/absolute/path", true, }, { "github.com/example/foo", true, }, { "hashicorp/subnets/cidr", // registry module true, }, { "registry.terraform.io/hashicorp/subnets/cidr", // registry module true, }, } for _, test := range tests { t.Run(test.Addr, func(t *testing.T) { addr, err := addrs.ParseModuleSource(test.Addr) if err != nil { t.Fatalf("parsing failed for %q: %s", test.Addr, err) } got := moduleSourceAddrEntersNewPackage(addr) if got != test.Want { t.Errorf("wrong result for %q\ngot: %#v\nwant: %#v", addr, got, test.Want) } }) } }