github.com/terraform-modules-krish/terratest@v0.29.0/modules/test-structure/test_structure.go (about)

     1  // Package test_structure allows to set up tests and their environment.
     2  package test_structure
     3  
     4  import (
     5  	"fmt"
     6  	"os"
     7  	"path/filepath"
     8  	"strings"
     9  
    10  	"github.com/terraform-modules-krish/terratest/modules/files"
    11  	"github.com/terraform-modules-krish/terratest/modules/logger"
    12  	"github.com/terraform-modules-krish/terratest/modules/testing"
    13  )
    14  
    15  // SKIP_STAGE_ENV_VAR_PREFIX is the prefix used for skipping stage environment variables.
    16  const SKIP_STAGE_ENV_VAR_PREFIX = "SKIP_"
    17  
    18  // RunTestStage executes the given test stage (e.g., setup, teardown, validation) if an environment variable of the name
    19  // `SKIP_<stageName>` (e.g., SKIP_teardown) is not set.
    20  func RunTestStage(t testing.TestingT, stageName string, stage func()) {
    21  	envVarName := fmt.Sprintf("%s%s", SKIP_STAGE_ENV_VAR_PREFIX, stageName)
    22  	if os.Getenv(envVarName) == "" {
    23  		logger.Logf(t, "The '%s' environment variable is not set, so executing stage '%s'.", envVarName, stageName)
    24  		stage()
    25  	} else {
    26  		logger.Logf(t, "The '%s' environment variable is set, so skipping stage '%s'.", envVarName, stageName)
    27  	}
    28  }
    29  
    30  // SkipStageEnvVarSet returns true if an environment variable is set instructing Terratest to skip a test stage. This can be an easy way
    31  // to tell if the tests are running in a local dev environment vs a CI server.
    32  func SkipStageEnvVarSet() bool {
    33  	for _, environmentVariable := range os.Environ() {
    34  		if strings.HasPrefix(environmentVariable, SKIP_STAGE_ENV_VAR_PREFIX) {
    35  			return true
    36  		}
    37  	}
    38  
    39  	return false
    40  }
    41  
    42  // CopyTerraformFolderToTemp copies the given root folder to a randomly-named temp folder and return the path to the
    43  // given terraform modules folder within the new temp root folder. This is useful when running multiple tests in
    44  // parallel against the same set of Terraform files to ensure the tests don't overwrite each other's .terraform working
    45  // directory and terraform.tfstate files. To ensure relative paths work, we copy over the entire root folder to a temp
    46  // folder, and then return the path within that temp folder to the given terraform module dir, which is where the actual
    47  // test will be running.
    48  // For example, suppose you had the target terraform folder you want to test in "/examples/terraform-aws-example"
    49  // relative to the repo root. If your tests reside in the "/test" relative to the root, then you will use this as
    50  // follows:
    51  //
    52  //       // Root folder where terraform files should be (relative to the test folder)
    53  //       rootFolder := ".."
    54  //
    55  //       // Relative path to terraform module being tested from the root folder
    56  //       terraformFolderRelativeToRoot := "examples/terraform-aws-example"
    57  //
    58  //       // Copy the terraform folder to a temp folder
    59  //       tempTestFolder := test_structure.CopyTerraformFolderToTemp(t, rootFolder, terraformFolderRelativeToRoot)
    60  //
    61  //       // Make sure to use the temp test folder in the terraform options
    62  //       terraformOptions := &terraform.Options{
    63  //       		TerraformDir: tempTestFolder,
    64  //       }
    65  //
    66  // Note that if any of the SKIP_<stage> environment variables is set, we assume this is a test in the local dev where
    67  // there are no other concurrent tests running and we want to be able to cache test data between test stages, so in that
    68  // case, we do NOT copy anything to a temp folder, and return the path to the original terraform module folder instead.
    69  func CopyTerraformFolderToTemp(t testing.TestingT, rootFolder string, terraformModuleFolder string) string {
    70  	if SkipStageEnvVarSet() {
    71  		logger.Logf(t, "A SKIP_XXX environment variable is set. Using original examples folder rather than a temp folder so we can cache data between stages for faster local testing.")
    72  		return filepath.Join(rootFolder, terraformModuleFolder)
    73  	}
    74  
    75  	tmpRootFolder, err := files.CopyTerraformFolderToTemp(rootFolder, cleanName(t.Name()))
    76  	if err != nil {
    77  		t.Fatal(err)
    78  	}
    79  
    80  	tmpTestFolder := filepath.Join(tmpRootFolder, terraformModuleFolder)
    81  
    82  	// Log temp folder so we can see it
    83  	logger.Logf(t, "Copied terraform folder %s to %s", filepath.Join(rootFolder, terraformModuleFolder), tmpTestFolder)
    84  
    85  	return tmpTestFolder
    86  }
    87  
    88  func cleanName(originalName string) string {
    89  	parts := strings.Split(originalName, "/")
    90  	return parts[len(parts)-1]
    91  }