github.com/graywolf-at-work-2/terraform-vendor@v1.4.5/internal/configs/configload/loader_load_test.go (about)

     1  package configload
     2  
     3  import (
     4  	"path/filepath"
     5  	"reflect"
     6  	"sort"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/davecgh/go-spew/spew"
    11  	"github.com/zclconf/go-cty/cty"
    12  
    13  	"github.com/hashicorp/terraform/internal/configs"
    14  )
    15  
    16  func TestLoaderLoadConfig_okay(t *testing.T) {
    17  	fixtureDir := filepath.Clean("testdata/already-installed")
    18  	loader, err := NewLoader(&Config{
    19  		ModulesDir: filepath.Join(fixtureDir, ".terraform/modules"),
    20  	})
    21  	if err != nil {
    22  		t.Fatalf("unexpected error from NewLoader: %s", err)
    23  	}
    24  
    25  	cfg, diags := loader.LoadConfig(fixtureDir)
    26  	assertNoDiagnostics(t, diags)
    27  	if cfg == nil {
    28  		t.Fatalf("config is nil; want non-nil")
    29  	}
    30  
    31  	var gotPaths []string
    32  	cfg.DeepEach(func(c *configs.Config) {
    33  		gotPaths = append(gotPaths, strings.Join(c.Path, "."))
    34  	})
    35  	sort.Strings(gotPaths)
    36  	wantPaths := []string{
    37  		"", // root module
    38  		"child_a",
    39  		"child_a.child_c",
    40  		"child_b",
    41  		"child_b.child_d",
    42  	}
    43  
    44  	if !reflect.DeepEqual(gotPaths, wantPaths) {
    45  		t.Fatalf("wrong module paths\ngot: %swant %s", spew.Sdump(gotPaths), spew.Sdump(wantPaths))
    46  	}
    47  
    48  	t.Run("child_a.child_c output", func(t *testing.T) {
    49  		output := cfg.Children["child_a"].Children["child_c"].Module.Outputs["hello"]
    50  		got, diags := output.Expr.Value(nil)
    51  		assertNoDiagnostics(t, diags)
    52  		assertResultCtyEqual(t, got, cty.StringVal("Hello from child_c"))
    53  	})
    54  	t.Run("child_b.child_d output", func(t *testing.T) {
    55  		output := cfg.Children["child_b"].Children["child_d"].Module.Outputs["hello"]
    56  		got, diags := output.Expr.Value(nil)
    57  		assertNoDiagnostics(t, diags)
    58  		assertResultCtyEqual(t, got, cty.StringVal("Hello from child_d"))
    59  	})
    60  }
    61  
    62  func TestLoaderLoadConfig_addVersion(t *testing.T) {
    63  	// This test is for what happens when there is a version constraint added
    64  	// to a module that previously didn't have one.
    65  	fixtureDir := filepath.Clean("testdata/add-version-constraint")
    66  	loader, err := NewLoader(&Config{
    67  		ModulesDir: filepath.Join(fixtureDir, ".terraform/modules"),
    68  	})
    69  	if err != nil {
    70  		t.Fatalf("unexpected error from NewLoader: %s", err)
    71  	}
    72  
    73  	_, diags := loader.LoadConfig(fixtureDir)
    74  	if !diags.HasErrors() {
    75  		t.Fatalf("success; want error")
    76  	}
    77  	got := diags.Error()
    78  	want := "Module version requirements have changed"
    79  	if !strings.Contains(got, want) {
    80  		t.Fatalf("wrong error\ngot:\n%s\n\nwant: containing %q", got, want)
    81  	}
    82  }
    83  
    84  func TestLoaderLoadConfig_loadDiags(t *testing.T) {
    85  	// building a config which didn't load correctly may cause configs to panic
    86  	fixtureDir := filepath.Clean("testdata/invalid-names")
    87  	loader, err := NewLoader(&Config{
    88  		ModulesDir: filepath.Join(fixtureDir, ".terraform/modules"),
    89  	})
    90  	if err != nil {
    91  		t.Fatalf("unexpected error from NewLoader: %s", err)
    92  	}
    93  
    94  	cfg, diags := loader.LoadConfig(fixtureDir)
    95  	if !diags.HasErrors() {
    96  		t.Fatal("success; want error")
    97  	}
    98  
    99  	if cfg == nil {
   100  		t.Fatal("partial config not returned with diagnostics")
   101  	}
   102  
   103  	if cfg.Module == nil {
   104  		t.Fatal("expected config module")
   105  	}
   106  }
   107  
   108  func TestLoaderLoadConfig_loadDiagsFromSubmodules(t *testing.T) {
   109  	// building a config which didn't load correctly may cause configs to panic
   110  	fixtureDir := filepath.Clean("testdata/invalid-names-in-submodules")
   111  	loader, err := NewLoader(&Config{
   112  		ModulesDir: filepath.Join(fixtureDir, ".terraform/modules"),
   113  	})
   114  	if err != nil {
   115  		t.Fatalf("unexpected error from NewLoader: %s", err)
   116  	}
   117  
   118  	cfg, diags := loader.LoadConfig(fixtureDir)
   119  	if !diags.HasErrors() {
   120  		t.Fatalf("loading succeeded; want an error")
   121  	}
   122  	if got, want := diags.Error(), " Invalid provider local name"; !strings.Contains(got, want) {
   123  		t.Errorf("missing expected error\nwant substring: %s\ngot: %s", want, got)
   124  	}
   125  
   126  	if cfg == nil {
   127  		t.Fatal("partial config not returned with diagnostics")
   128  	}
   129  
   130  	if cfg.Module == nil {
   131  		t.Fatal("expected config module")
   132  	}
   133  }
   134  
   135  func TestLoaderLoadConfig_childProviderGrandchildCount(t *testing.T) {
   136  	// This test is focused on the specific situation where:
   137  	// - A child module contains a nested provider block, which is no longer
   138  	//   recommended but supported for backward-compatibility.
   139  	// - A child of that child does _not_ contain a nested provider block,
   140  	//   and is called with "count" (would also apply to "for_each" and
   141  	//   "depends_on").
   142  	// It isn't valid to use "count" with a module that _itself_ contains
   143  	// a provider configuration, but it _is_ valid for a module with a
   144  	// provider configuration to call another module with count. We previously
   145  	// botched this rule and so this is a regression test to cover the
   146  	// solution to that mistake:
   147  	//     https://github.com/hashicorp/terraform/issues/31081
   148  
   149  	// Since this test is based on success rather than failure and it's
   150  	// covering a relatively large set of code where only a small part
   151  	// contributes to the test, we'll make sure to test both the success and
   152  	// failure cases here so that we'll have a better chance of noticing if a
   153  	// future change makes this succeed only because we've reorganized the code
   154  	// so that the check isn't happening at all anymore.
   155  	//
   156  	// If the "not okay" subtest fails, you should also be skeptical about
   157  	// whether the "okay" subtest is still valid, even if it happens to
   158  	// still be passing.
   159  	t.Run("okay", func(t *testing.T) {
   160  		fixtureDir := filepath.Clean("testdata/child-provider-grandchild-count")
   161  		loader, err := NewLoader(&Config{
   162  			ModulesDir: filepath.Join(fixtureDir, ".terraform/modules"),
   163  		})
   164  		if err != nil {
   165  			t.Fatalf("unexpected error from NewLoader: %s", err)
   166  		}
   167  
   168  		cfg, diags := loader.LoadConfig(fixtureDir)
   169  		assertNoDiagnostics(t, diags)
   170  		if cfg == nil {
   171  			t.Fatalf("config is nil; want non-nil")
   172  		}
   173  
   174  		var gotPaths []string
   175  		cfg.DeepEach(func(c *configs.Config) {
   176  			gotPaths = append(gotPaths, strings.Join(c.Path, "."))
   177  		})
   178  		sort.Strings(gotPaths)
   179  		wantPaths := []string{
   180  			"", // root module
   181  			"child",
   182  			"child.grandchild",
   183  		}
   184  
   185  		if !reflect.DeepEqual(gotPaths, wantPaths) {
   186  			t.Fatalf("wrong module paths\ngot: %swant %s", spew.Sdump(gotPaths), spew.Sdump(wantPaths))
   187  		}
   188  	})
   189  	t.Run("not okay", func(t *testing.T) {
   190  		fixtureDir := filepath.Clean("testdata/child-provider-child-count")
   191  		loader, err := NewLoader(&Config{
   192  			ModulesDir: filepath.Join(fixtureDir, ".terraform/modules"),
   193  		})
   194  		if err != nil {
   195  			t.Fatalf("unexpected error from NewLoader: %s", err)
   196  		}
   197  
   198  		_, diags := loader.LoadConfig(fixtureDir)
   199  		if !diags.HasErrors() {
   200  			t.Fatalf("loading succeeded; want an error")
   201  		}
   202  		if got, want := diags.Error(), "Module is incompatible with count, for_each, and depends_on"; !strings.Contains(got, want) {
   203  			t.Errorf("missing expected error\nwant substring: %s\ngot: %s", want, got)
   204  		}
   205  	})
   206  
   207  }