github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/initwd/testing.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package initwd
     5  
     6  import (
     7  	"context"
     8  	"testing"
     9  
    10  	"github.com/terramate-io/tf/configs"
    11  	"github.com/terramate-io/tf/configs/configload"
    12  	"github.com/terramate-io/tf/registry"
    13  	"github.com/terramate-io/tf/tfdiags"
    14  )
    15  
    16  // LoadConfigForTests is a convenience wrapper around configload.NewLoaderForTests,
    17  // ModuleInstaller.InstallModules and configload.Loader.LoadConfig that allows
    18  // a test configuration to be loaded in a single step.
    19  //
    20  // If module installation fails, t.Fatal (or similar) is called to halt
    21  // execution of the test, under the assumption that installation failures are
    22  // not expected. If installation failures _are_ expected then use
    23  // NewLoaderForTests and work with the loader object directly. If module
    24  // installation succeeds but generates warnings, these warnings are discarded.
    25  //
    26  // If installation succeeds but errors are detected during loading then a
    27  // possibly-incomplete config is returned along with error diagnostics. The
    28  // test run is not aborted in this case, so that the caller can make assertions
    29  // against the returned diagnostics.
    30  //
    31  // As with NewLoaderForTests, a cleanup function is returned which must be
    32  // called before the test completes in order to remove the temporary
    33  // modules directory.
    34  func LoadConfigForTests(t *testing.T, rootDir string, testsDir string) (*configs.Config, *configload.Loader, func(), tfdiags.Diagnostics) {
    35  	t.Helper()
    36  
    37  	var diags tfdiags.Diagnostics
    38  
    39  	loader, cleanup := configload.NewLoaderForTests(t)
    40  	inst := NewModuleInstaller(loader.ModulesDir(), loader, registry.NewClient(nil, nil))
    41  
    42  	_, moreDiags := inst.InstallModules(context.Background(), rootDir, testsDir, true, false, ModuleInstallHooksImpl{})
    43  	diags = diags.Append(moreDiags)
    44  	if diags.HasErrors() {
    45  		cleanup()
    46  		t.Fatal(diags.Err())
    47  		return nil, nil, func() {}, diags
    48  	}
    49  
    50  	// Since module installer has modified the module manifest on disk, we need
    51  	// to refresh the cache of it in the loader.
    52  	if err := loader.RefreshModules(); err != nil {
    53  		t.Fatalf("failed to refresh modules after installation: %s", err)
    54  	}
    55  
    56  	config, hclDiags := loader.LoadConfig(rootDir)
    57  	diags = diags.Append(hclDiags)
    58  	return config, loader, cleanup, diags
    59  }
    60  
    61  // MustLoadConfigForTests is a variant of LoadConfigForTests which calls
    62  // t.Fatal (or similar) if there are any errors during loading, and thus
    63  // does not return diagnostics at all.
    64  //
    65  // This is useful for concisely writing tests that don't expect errors at
    66  // all. For tests that expect errors and need to assert against them, use
    67  // LoadConfigForTests instead.
    68  func MustLoadConfigForTests(t *testing.T, rootDir, testsDir string) (*configs.Config, *configload.Loader, func()) {
    69  	t.Helper()
    70  
    71  	config, loader, cleanup, diags := LoadConfigForTests(t, rootDir, testsDir)
    72  	if diags.HasErrors() {
    73  		cleanup()
    74  		t.Fatal(diags.Err())
    75  	}
    76  	return config, loader, cleanup
    77  }