Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(test-structure): add save test data if dne #1319

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
34 changes: 24 additions & 10 deletions modules/test-structure/save_test_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,14 @@ import (
// SaveTerraformOptions serializes and saves TerraformOptions into the given folder. This allows you to create TerraformOptions during setup
// and to reuse that TerraformOptions later during validation and teardown.
func SaveTerraformOptions(t testing.TestingT, testFolder string, terraformOptions *terraform.Options) {
SaveTestData(t, formatTerraformOptionsPath(testFolder), terraformOptions)
SaveTestData(t, formatTerraformOptionsPath(testFolder), true, terraformOptions)
}

// SaveTerraformOptionsIfNotPresent serializes and saves TerraformOptions into the given folder if the file does not exist or the json is
// empty. This allows you to create TerraformOptions during setup and to reuse that TerraformOptions later during validation and teardown,
// but will prevent overwritting the contents and potentially duplicating resources.
func SaveTerraformOptionsIfNotPresent(t testing.TestingT, testFolder string, terraformOptions *terraform.Options) {
SaveTestData(t, formatTerraformOptionsPath(testFolder), false, terraformOptions)
}

// LoadTerraformOptions loads and unserializes TerraformOptions from the given folder. This allows you to reuse a TerraformOptions that was
Expand All @@ -40,7 +47,7 @@ func formatTerraformOptionsPath(testFolder string) string {
// SavePackerOptions serializes and saves PackerOptions into the given folder. This allows you to create PackerOptions during setup
// and to reuse that PackerOptions later during validation and teardown.
func SavePackerOptions(t testing.TestingT, testFolder string, packerOptions *packer.Options) {
SaveTestData(t, formatPackerOptionsPath(testFolder), packerOptions)
SaveTestData(t, formatPackerOptionsPath(testFolder), true, packerOptions)
}

// LoadPackerOptions loads and unserializes PackerOptions from the given folder. This allows you to reuse a PackerOptions that was
Expand All @@ -59,7 +66,7 @@ func formatPackerOptionsPath(testFolder string) string {
// SaveEc2KeyPair serializes and saves an Ec2KeyPair into the given folder. This allows you to create an Ec2KeyPair during setup
// and to reuse that Ec2KeyPair later during validation and teardown.
func SaveEc2KeyPair(t testing.TestingT, testFolder string, keyPair *aws.Ec2Keypair) {
SaveTestData(t, formatEc2KeyPairPath(testFolder), keyPair)
SaveTestData(t, formatEc2KeyPairPath(testFolder), true, keyPair)
}

// LoadEc2KeyPair loads and unserializes an Ec2KeyPair from the given folder. This allows you to reuse an Ec2KeyPair that was
Expand All @@ -78,7 +85,7 @@ func formatEc2KeyPairPath(testFolder string) string {
// SaveSshKeyPair serializes and saves an SshKeyPair into the given folder. This allows you to create an SshKeyPair during setup
// and to reuse that SshKeyPair later during validation and teardown.
func SaveSshKeyPair(t testing.TestingT, testFolder string, keyPair *ssh.KeyPair) {
SaveTestData(t, formatSshKeyPairPath(testFolder), keyPair)
SaveTestData(t, formatSshKeyPairPath(testFolder), true, keyPair)
}

// LoadSshKeyPair loads and unserializes an SshKeyPair from the given folder. This allows you to reuse an SshKeyPair that was
Expand All @@ -97,7 +104,7 @@ func formatSshKeyPairPath(testFolder string) string {
// SaveKubectlOptions serializes and saves KubectlOptions into the given folder. This allows you to create a KubectlOptions during setup
// and reuse that KubectlOptions later during validation and teardown.
func SaveKubectlOptions(t testing.TestingT, testFolder string, kubectlOptions *k8s.KubectlOptions) {
SaveTestData(t, formatKubectlOptionsPath(testFolder), kubectlOptions)
SaveTestData(t, formatKubectlOptionsPath(testFolder), true, kubectlOptions)
}

// LoadKubectlOptions loads and unserializes a KubectlOptions from the given folder. This allows you to reuse a KubectlOptions that was
Expand All @@ -117,7 +124,7 @@ func formatKubectlOptionsPath(testFolder string) string {
// values during one stage -- each with a unique name -- and to reuse those values during later stages.
func SaveString(t testing.TestingT, testFolder string, name string, val string) {
path := formatNamedTestDataPath(testFolder, name)
SaveTestData(t, path, val)
SaveTestData(t, path, true, val)
}

// LoadString loads and unserializes a uniquely named string value from the given folder. This allows you to reuse one or more string
Expand All @@ -132,7 +139,7 @@ func LoadString(t testing.TestingT, testFolder string, name string) string {
// values during one stage -- each with a unique name -- and to reuse those values during later stages.
func SaveInt(t testing.TestingT, testFolder string, name string, val int) {
path := formatNamedTestDataPath(testFolder, name)
SaveTestData(t, path, val)
SaveTestData(t, path, true, val)
}

// LoadInt loads a uniquely named int value from the given folder. This allows you to reuse one or more int
Expand Down Expand Up @@ -183,12 +190,19 @@ func FormatTestDataPath(testFolder string, filename string) string {
}

// SaveTestData serializes and saves a value used at test time to the given path. This allows you to create some sort of test data
// (e.g., TerraformOptions) during setup and to reuse this data later during validation and teardown.
func SaveTestData(t testing.TestingT, path string, value interface{}) {
// (e.g., TerraformOptions) during setup and to reuse this data later during validation and teardown. If `overwrite` is `true`,
// any contents that exist in the file found at `path` will be overwritten. This has the potential for causing duplicated resources
// and should be used with caution. If `overwrite` is `false`, the save will be skipped and a warning will be logged.
func SaveTestData(t testing.TestingT, path string, overwrite bool, value interface{}) {
logger.Logf(t, "Storing test data in %s so it can be reused later", path)

if IsTestDataPresent(t, path) {
logger.Logf(t, "[WARNING] The named test data at path %s is non-empty. Save operation will overwrite existing value with \"%v\".\n.", path, value)
if overwrite {
logger.Logf(t, "[WARNING] The named test data at path %s is non-empty. Save operation will overwrite existing value with \"%v\".\n.", path, value)
} else {
logger.Logf(t, "[WARNING] The named test data at path %s is non-empty. Skipping save operation to prevent overwriting existing value with \"%v\".\n.", path, value)
return
}
}

bytes, err := json.Marshal(value)
Expand Down
54 changes: 53 additions & 1 deletion modules/test-structure/save_test_data_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ func TestSaveAndLoadTestData(t *testing.T) {
isTestDataPresent = IsTestDataPresent(t, tmpFile.Name())
assert.False(t, isTestDataPresent, "Expected no test data would be present because file exists but no data has been written yet.")

SaveTestData(t, tmpFile.Name(), expectedData)
overwrite := true
SaveTestData(t, tmpFile.Name(), overwrite, expectedData)

isTestDataPresent = IsTestDataPresent(t, tmpFile.Name())
assert.True(t, isTestDataPresent, "Expected test data would be present because file exists and data has been written to file.")
Expand All @@ -45,6 +46,15 @@ func TestSaveAndLoadTestData(t *testing.T) {
LoadTestData(t, tmpFile.Name(), &actualData)
assert.Equal(t, expectedData, actualData)

overwritingData := testData{
Foo: "foo",
Bar: false,
Baz: map[string]interface{}{"123": "456", "789": 1.0, "0": false},
}
SaveTestData(t, tmpFile.Name(), !overwrite, overwritingData)
LoadTestData(t, tmpFile.Name(), &actualData)
assert.Equal(t, expectedData, actualData)

CleanupTestData(t, tmpFile.Name())
assert.False(t, files.FileExists(tmpFile.Name()))
}
Expand Down Expand Up @@ -107,6 +117,48 @@ func TestSaveAndLoadTerraformOptions(t *testing.T) {
assert.Equal(t, expectedData, actualData)
}

func TestSaveTerraformOptionsIfNotPresent(t *testing.T) {
t.Parallel()

tmpFolder := t.TempDir()

expectedData := &terraform.Options{
TerraformDir: "/abc/def/ghi",
Vars: map[string]interface{}{},
}
SaveTerraformOptionsIfNotPresent(t, tmpFolder, expectedData)

overwritingData := &terraform.Options{
TerraformDir: "/123/456/789",
Vars: map[string]interface{}{},
}
SaveTerraformOptionsIfNotPresent(t, tmpFolder, overwritingData)

actualData := LoadTerraformOptions(t, tmpFolder)
assert.Equal(t, expectedData, actualData)
}

func TestSaveTerraformOptionsOverwrite(t *testing.T) {
t.Parallel()

tmpFolder := t.TempDir()

originaData := &terraform.Options{
TerraformDir: "/abc/def/ghi",
Vars: map[string]interface{}{},
}
SaveTerraformOptions(t, tmpFolder, originaData)

overwritingData := &terraform.Options{
TerraformDir: "/123/456/789",
Vars: map[string]interface{}{},
}
SaveTerraformOptions(t, tmpFolder, overwritingData)

actualData := LoadTerraformOptions(t, tmpFolder)
assert.Equal(t, overwritingData, actualData)
}

func TestSaveAndLoadAmiId(t *testing.T) {
t.Parallel()

Expand Down