github.com/darmach/terratest@v0.34.8-0.20210517103231-80931f95e3ff/test/terraform_basic_example_regression_test.go (about)

     1  package test
     2  
     3  import (
     4  	"encoding/json"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/stretchr/testify/require"
    10  
    11  	"github.com/gruntwork-io/terratest/modules/random"
    12  	"github.com/gruntwork-io/terratest/modules/terraform"
    13  	test_structure "github.com/gruntwork-io/terratest/modules/test-structure"
    14  )
    15  
    16  // The tests in this folder are not example usage of Terratest. Instead, this is a regression test to ensure the
    17  // formatting rules work with an actual Terraform call when using more complex structures.
    18  
    19  func TestTerraformFormatNestedOneLevelList(t *testing.T) {
    20  	t.Parallel()
    21  
    22  	testList := [][]string{
    23  		[]string{random.UniqueId()},
    24  	}
    25  
    26  	options := GetTerraformOptionsForFormatTests(t)
    27  	options.Vars["example_any"] = testList
    28  
    29  	defer terraform.Destroy(t, options)
    30  	terraform.InitAndApply(t, options)
    31  	outputMap := terraform.OutputForKeys(t, options, []string{"example_any"})
    32  	actualExampleList := outputMap["example_any"]
    33  	AssertEqualJson(t, actualExampleList, testList)
    34  }
    35  
    36  func TestTerraformFormatNestedTwoLevelList(t *testing.T) {
    37  	t.Parallel()
    38  
    39  	testList := [][][]string{
    40  		[][]string{[]string{random.UniqueId()}},
    41  	}
    42  
    43  	options := GetTerraformOptionsForFormatTests(t)
    44  	options.Vars["example_any"] = testList
    45  
    46  	defer terraform.Destroy(t, options)
    47  	terraform.InitAndApply(t, options)
    48  	outputMap := terraform.OutputForKeys(t, options, []string{"example_any"})
    49  	actualExampleList := outputMap["example_any"]
    50  	AssertEqualJson(t, actualExampleList, testList)
    51  }
    52  
    53  func TestTerraformFormatNestedMultipleItems(t *testing.T) {
    54  	t.Parallel()
    55  
    56  	testList := [][]string{
    57  		[]string{random.UniqueId(), random.UniqueId()},
    58  		[]string{random.UniqueId(), random.UniqueId(), random.UniqueId()},
    59  	}
    60  
    61  	options := GetTerraformOptionsForFormatTests(t)
    62  	options.Vars["example_any"] = testList
    63  
    64  	defer terraform.Destroy(t, options)
    65  	terraform.InitAndApply(t, options)
    66  	outputMap := terraform.OutputForKeys(t, options, []string{"example_any"})
    67  	actualExampleList := outputMap["example_any"]
    68  	AssertEqualJson(t, actualExampleList, testList)
    69  }
    70  
    71  func TestTerraformFormatNestedOneLevelMap(t *testing.T) {
    72  	t.Parallel()
    73  
    74  	testMap := map[string]map[string]string{
    75  		"test": map[string]string{
    76  			"foo": random.UniqueId(),
    77  		},
    78  	}
    79  
    80  	options := GetTerraformOptionsForFormatTests(t)
    81  	options.Vars["example_any"] = testMap
    82  
    83  	defer terraform.Destroy(t, options)
    84  	terraform.InitAndApply(t, options)
    85  	outputMap := terraform.OutputForKeys(t, options, []string{"example_any"})
    86  	actualExampleMap := outputMap["example_any"]
    87  	AssertEqualJson(t, actualExampleMap, testMap)
    88  }
    89  
    90  func TestTerraformFormatNestedTwoLevelMap(t *testing.T) {
    91  	t.Parallel()
    92  
    93  	testMap := map[string]map[string]map[string]string{
    94  		"test": map[string]map[string]string{
    95  			"foo": map[string]string{
    96  				"bar": random.UniqueId(),
    97  			},
    98  		},
    99  	}
   100  
   101  	options := GetTerraformOptionsForFormatTests(t)
   102  	options.Vars["example_any"] = testMap
   103  
   104  	defer terraform.Destroy(t, options)
   105  	terraform.InitAndApply(t, options)
   106  	outputMap := terraform.OutputForKeys(t, options, []string{"example_any"})
   107  	actualExampleMap := outputMap["example_any"]
   108  	AssertEqualJson(t, actualExampleMap, testMap)
   109  }
   110  
   111  func TestTerraformFormatNestedMultipleItemsMap(t *testing.T) {
   112  	t.Parallel()
   113  
   114  	testMap := map[string]map[string]string{
   115  		"test": map[string]string{
   116  			"foo": random.UniqueId(),
   117  			"bar": random.UniqueId(),
   118  		},
   119  		"other": map[string]string{
   120  			"baz": random.UniqueId(),
   121  			"boo": random.UniqueId(),
   122  		},
   123  	}
   124  
   125  	options := GetTerraformOptionsForFormatTests(t)
   126  	options.Vars["example_any"] = testMap
   127  
   128  	defer terraform.Destroy(t, options)
   129  	terraform.InitAndApply(t, options)
   130  	outputMap := terraform.OutputForKeys(t, options, []string{"example_any"})
   131  	actualExampleMap := outputMap["example_any"]
   132  	AssertEqualJson(t, actualExampleMap, testMap)
   133  }
   134  
   135  func TestTerraformFormatNestedListMap(t *testing.T) {
   136  	t.Parallel()
   137  
   138  	testMap := map[string][]string{
   139  		"test": []string{random.UniqueId(), random.UniqueId()},
   140  	}
   141  
   142  	options := GetTerraformOptionsForFormatTests(t)
   143  	options.Vars["example_any"] = testMap
   144  
   145  	defer terraform.Destroy(t, options)
   146  	terraform.InitAndApply(t, options)
   147  	outputMap := terraform.OutputForKeys(t, options, []string{"example_any"})
   148  	actualExampleMap := outputMap["example_any"]
   149  	AssertEqualJson(t, actualExampleMap, testMap)
   150  }
   151  
   152  func GetTerraformOptionsForFormatTests(t *testing.T) *terraform.Options {
   153  	exampleFolder := test_structure.CopyTerraformFolderToTemp(t, "../", "examples/terraform-basic-example")
   154  
   155  	// Set up terratest to retry on known failures
   156  	maxTerraformRetries := 3
   157  	sleepBetweenTerraformRetries := 5 * time.Second
   158  	retryableTerraformErrors := map[string]string{
   159  		// `terraform init` frequently fails in CI due to network issues accessing plugins. The reason is unknown, but
   160  		// eventually these succeed after a few retries.
   161  		".*unable to verify signature.*":             "Failed to retrieve plugin due to transient network error.",
   162  		".*unable to verify checksum.*":              "Failed to retrieve plugin due to transient network error.",
   163  		".*no provider exists with the given name.*": "Failed to retrieve plugin due to transient network error.",
   164  		".*registry service is unreachable.*":        "Failed to retrieve plugin due to transient network error.",
   165  		".*connection reset by peer.*":               "Failed to retrieve plugin due to transient network error.",
   166  	}
   167  
   168  	terraformOptions := &terraform.Options{
   169  		TerraformDir:             exampleFolder,
   170  		Vars:                     map[string]interface{}{},
   171  		NoColor:                  true,
   172  		RetryableTerraformErrors: retryableTerraformErrors,
   173  		MaxRetries:               maxTerraformRetries,
   174  		TimeBetweenRetries:       sleepBetweenTerraformRetries,
   175  	}
   176  	return terraformOptions
   177  }
   178  
   179  // The value of the output nested in the outputMap returned by OutputForKeys uses the interface{} type for nested
   180  // structures. This can't be compared to actual types like [][]string{}, so we instead compare the json versions.
   181  func AssertEqualJson(t *testing.T, actual interface{}, expected interface{}) {
   182  	actualJson, err := json.Marshal(actual)
   183  	require.NoError(t, err)
   184  	expectedJson, err := json.Marshal(expected)
   185  	require.NoError(t, err)
   186  	assert.Equal(t, actualJson, expectedJson)
   187  }