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