package configload import ( "fmt" "path/filepath" "reflect" "sort" "strings" "testing" "github.com/davecgh/go-spew/spew" "github.com/zclconf/go-cty/cty" "github.com/hashicorp/terraform/configs" ) func TestLoaderLoadConfig_okay(t *testing.T) { fixtureDir := filepath.Clean("testdata/already-installed") loader, err := NewLoader(&Config{ ModulesDir: filepath.Join(fixtureDir, ".terraform/modules"), }) if err != nil { t.Fatalf("unexpected error from NewLoader: %s", err) } cfg, diags := loader.LoadConfig(fixtureDir) assertNoDiagnostics(t, diags) if cfg == nil { t.Fatalf("config is nil; want non-nil") } var gotPaths []string cfg.DeepEach(func(c *configs.Config) { gotPaths = append(gotPaths, strings.Join(c.Path, ".")) }) sort.Strings(gotPaths) wantPaths := []string{ "", // root module "child_a", "child_a.child_c", "child_b", "child_b.child_d", } if !reflect.DeepEqual(gotPaths, wantPaths) { t.Fatalf("wrong module paths\ngot: %swant %s", spew.Sdump(gotPaths), spew.Sdump(wantPaths)) } t.Run("child_a.child_c output", func(t *testing.T) { output := cfg.Children["child_a"].Children["child_c"].Module.Outputs["hello"] got, diags := output.Expr.Value(nil) assertNoDiagnostics(t, diags) assertResultCtyEqual(t, got, cty.StringVal("Hello from child_c")) }) t.Run("child_b.child_d output", func(t *testing.T) { output := cfg.Children["child_b"].Children["child_d"].Module.Outputs["hello"] got, diags := output.Expr.Value(nil) assertNoDiagnostics(t, diags) assertResultCtyEqual(t, got, cty.StringVal("Hello from child_d")) }) } func TestLoaderLoadConfig_addVersion(t *testing.T) { // This test is for what happens when there is a version constraint added // to a module that previously didn't have one. fixtureDir := filepath.Clean("testdata/add-version-constraint") loader, err := NewLoader(&Config{ ModulesDir: filepath.Join(fixtureDir, ".terraform/modules"), }) if err != nil { t.Fatalf("unexpected error from NewLoader: %s", err) } _, diags := loader.LoadConfig(fixtureDir) if !diags.HasErrors() { t.Fatalf("success; want error") } got := diags.Error() want := "Module version requirements have changed" if !strings.Contains(got, want) { t.Fatalf("wrong error\ngot:\n%s\n\nwant: containing %q", got, want) } } func TestLoaderLoadConfig_moduleExpand(t *testing.T) { // We do not allow providers to be configured in expanding modules // In addition, if a provider is present but an empty block, it is allowed, // but IFF a provider is passed through the module call paths := []string{"provider-configured", "no-provider-passed", "nested-provider", "more-nested-provider"} for _, p := range paths { fixtureDir := filepath.Clean(fmt.Sprintf("testdata/expand-modules/%s", p)) loader, err := NewLoader(&Config{ ModulesDir: filepath.Join(fixtureDir, ".terraform/modules"), }) if err != nil { t.Fatalf("unexpected error from NewLoader at path %s: %s", p, err) } _, diags := loader.LoadConfig(fixtureDir) if !diags.HasErrors() { t.Fatalf("success; want error at path %s", p) } got := diags.Error() want := "Module does not support count" if !strings.Contains(got, want) { t.Fatalf("wrong error at path %s \ngot:\n%s\n\nwant: containing %q", p, got, want) } } } func TestLoaderLoadConfig_moduleExpandValid(t *testing.T) { // This tests for when valid configs are passing a provider through as a proxy, // either with or without an alias present. fixtureDir := filepath.Clean("testdata/expand-modules/valid") loader, err := NewLoader(&Config{ ModulesDir: filepath.Join(fixtureDir, ".terraform/modules"), }) if err != nil { t.Fatalf("unexpected error from NewLoader: %s", err) } _, diags := loader.LoadConfig(fixtureDir) assertNoDiagnostics(t, diags) } func TestLoaderLoadConfig_moduleDependsOnProviders(t *testing.T) { // We do not allow providers to be configured in module using depends_on. fixtureDir := filepath.Clean("testdata/module-depends-on") loader, err := NewLoader(&Config{ ModulesDir: filepath.Join(fixtureDir, ".terraform/modules"), }) if err != nil { t.Fatalf("unexpected error from NewLoader: %s", err) } _, diags := loader.LoadConfig(fixtureDir) if !diags.HasErrors() { t.Fatal("success; want error") } got := diags.Error() want := "Module does not support depends_on" if !strings.Contains(got, want) { t.Fatalf("wrong error\ngot:\n%s\n\nwant: containing %q", got, want) } }