-
-
Notifications
You must be signed in to change notification settings - Fork 0
Simplify testing for Cloud Posse components #41
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,106 @@ | ||||||
package aws_component_helper | ||||||
|
||||||
import ( | ||||||
"github.com/gruntwork-io/terratest/modules/logger" | ||||||
"github.com/stretchr/testify/require" | ||||||
"os" | ||||||
"path/filepath" | ||||||
"strings" | ||||||
"testing" | ||||||
|
||||||
"github.com/cloudposse/test-helpers/pkg/atmos" | ||||||
"github.com/gruntwork-io/terratest/modules/files" | ||||||
"github.com/stretchr/testify/assert" | ||||||
) | ||||||
|
||||||
func awsComponentTestCleanup(t *testing.T, opts *atmos.Options, destroy bool, tmpDir string, protectDir string) { | ||||||
if destroy { | ||||||
out, err := atmos.DestroyE(t, opts) | ||||||
if err == nil { | ||||||
// if the destroy was successful, remove the temp directory | ||||||
if tmpDir == protectDir { | ||||||
t.Logf("Not removing protected directory %s", protectDir) | ||||||
} else { | ||||||
t.Log("Cleaning out temp folder...") | ||||||
err = os.RemoveAll(tmpDir) | ||||||
if err == nil { | ||||||
t.Logf("Removed temp directory %s", tmpDir) | ||||||
} else { | ||||||
assert.NoError(t, err, "Failed to remove temp directory %s", tmpDir) | ||||||
} | ||||||
} | ||||||
} else { | ||||||
// if the destroy failed, leave the temp directory in place | ||||||
assert.NoError(t, err, "Failed to destroy subject. Leaving source and state in %v\n\nDestroy output:\n%v\n\n", tmpDir, out) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Avoid failing the test during cleanup when destroy operation fails If the destroy operation fails during cleanup, using Apply this diff to log the error instead: - assert.NoError(t, err, "Failed to destroy subject. Leaving source and state in %v\n\nDestroy output:\n%v\n\n", tmpDir, out)
+ t.Errorf("Failed to destroy subject. Leaving source and state in %v\n\nDestroy output:\n%v\n\nError: %v", tmpDir, out, err) 📝 Committable suggestion
Suggested change
|
||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
type ComponentTestResults struct { | ||||||
Output string | ||||||
TestID string | ||||||
} | ||||||
|
||||||
func IsLocalAwsComponentTest(t *testing.T) bool { | ||||||
atmosPlainOpts := &atmos.Options{} | ||||||
existingTestID, err := atmos.RunAtmosCommandE(t, atmosPlainOpts, "test", "get-test-id") | ||||||
|
||||||
return err == nil && len(existingTestID) > 0 | ||||||
} | ||||||
|
||||||
func AwsComponentTestHelper(t *testing.T, opts *atmos.Options, callback func(t *testing.T, opts *atmos.Options, results ComponentTestResults)) { | ||||||
testSrcRoot := os.Getenv("ATMOS_BASE_PATH") | ||||||
testRoot := testSrcRoot | ||||||
if testSrcRoot == "" { | ||||||
assert.FailNow(t, "ATMOS_BASE_PATH must be set, but is empty") | ||||||
} | ||||||
|
||||||
atmosPlainOpts := &atmos.Options{} | ||||||
doApply := false | ||||||
|
||||||
var testID string | ||||||
|
||||||
existingTestID, err := atmos.RunAtmosCommandE(t, atmosPlainOpts, "test", "get-test-id") | ||||||
if err != nil || len(existingTestID) == 0 { | ||||||
doApply = true | ||||||
// Copy test source to a temp directory and create a new test ID | ||||||
t.Log("Copying files to temp folder...") | ||||||
testRoot, err = files.CopyTerraformFolderToTemp(testSrcRoot, t.Name()) | ||||||
require.NoError(t, err) | ||||||
err = copyDirectoryRecursively(filepath.Join(testSrcRoot, "state"), filepath.Join(testRoot, "state")) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ensure The function Please define the |
||||||
require.NoError(t, err) | ||||||
atmosPlainOpts.AtmosBasePath = testRoot | ||||||
testID, err = atmos.RunAtmosCommandE(t, atmosPlainOpts, "test", "make-test-id") | ||||||
require.NoError(t, err) | ||||||
testID = strings.TrimSpace(testID) | ||||||
} else { | ||||||
testID = strings.TrimSpace(existingTestID) | ||||||
} | ||||||
|
||||||
t.Logf("Running test \"%s\" with test ID \"%s\" in directory %s", t.Name(), testID, testRoot) | ||||||
|
||||||
options := atmos.WithDefaultRetryableErrors(t, opts) | ||||||
options.AtmosBasePath = testRoot | ||||||
// Keep the output quiet | ||||||
if !testing.Verbose() { | ||||||
options.Logger = logger.Discard | ||||||
} | ||||||
|
||||||
defer awsComponentTestCleanup(t, options, doApply, testRoot, testSrcRoot) | ||||||
|
||||||
// Apply the deployment | ||||||
out := "" | ||||||
if doApply { | ||||||
out, err = atmos.ApplyE(t, options) | ||||||
require.NoError(t, err, "Failed to deploy component, skipping other tests.") | ||||||
} | ||||||
// Call the callback function for assertions | ||||||
callback(t, options, ComponentTestResults{ | ||||||
Output: out, | ||||||
TestID: testID, | ||||||
}) | ||||||
|
||||||
if !doApply { | ||||||
t.Logf("\n\n\nTests complete in %s\n\n", testRoot) | ||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -14,6 +14,16 @@ import ( | |||||||||||||||||||
) | ||||||||||||||||||||
|
||||||||||||||||||||
func generateCommand(options *Options, args ...string) shell.Command { | ||||||||||||||||||||
// TODO: replace with command line argument | ||||||||||||||||||||
if options.AtmosBasePath != "" { | ||||||||||||||||||||
var err error | ||||||||||||||||||||
options, err = options.Clone() | ||||||||||||||||||||
if err != nil { | ||||||||||||||||||||
fmt.Printf("Error cloning options: %v", err) | ||||||||||||||||||||
return shell.Command{} | ||||||||||||||||||||
} | ||||||||||||||||||||
Comment on lines
+21
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Improve error handling for clone failure Returning an empty
- if err != nil {
- fmt.Printf("Error cloning options: %v", err)
- return shell.Command{}
- }
+ if err != nil {
+ // Either propagate the error:
+ panic(fmt.Sprintf("Failed to clone options: %v", err))
+ // Or use original options as fallback:
+ options.EnvVars["ATMOS_BASE_PATH"] = options.AtmosBasePath
+ }
|
||||||||||||||||||||
options.EnvVars["ATMOS_BASE_PATH"] = options.AtmosBasePath | ||||||||||||||||||||
} | ||||||||||||||||||||
cmd := shell.Command{ | ||||||||||||||||||||
Command: options.AtmosBinary, | ||||||||||||||||||||
Args: args, | ||||||||||||||||||||
|
@@ -43,6 +53,13 @@ func GetCommonOptions(options *Options, args ...string) (*Options, []string) { | |||||||||||||||||||
options.AtmosBinary = DefaultExecutable | ||||||||||||||||||||
} | ||||||||||||||||||||
|
||||||||||||||||||||
// TODO: | ||||||||||||||||||||
// if options.AtmosBasePath != "", then add args "--base-path", options.AtmosBasePath to the args | ||||||||||||||||||||
// Unfortunately, as of Atmos 1.109.0, the flag "--base-path" does not work | ||||||||||||||||||||
// if options.AtmosBasePath != "" { | ||||||||||||||||||||
// args = append([]string{"--base-path", options.AtmosBasePath}, args...) | ||||||||||||||||||||
// } | ||||||||||||||||||||
|
||||||||||||||||||||
Comment on lines
+56
to
+62
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Remove commented code and track the issue properly The commented code block indicates that the
- // TODO:
- // if options.AtmosBasePath != "", then add args "--base-path", options.AtmosBasePath to the args
- // Unfortunately, as of Atmos 1.109.0, the flag "--base-path" does not work
- // if options.AtmosBasePath != "" {
- // args = append([]string{"--base-path", options.AtmosBasePath}, args...)
- // }
+ // NOTE: Atmos base path is currently set via ATMOS_BASE_PATH environment variable in generateCommand()
+ // as the --base-path flag is not supported as of Atmos 1.109.0
+ // Track progress at: <link-to-issue> 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||
if options.Parallelism > 0 && len(args) > 0 && args[0] == "terraform" && collections.ListContains(commandsWithParallelism, args[1]) { | ||||||||||||||||||||
args = append(args, fmt.Sprintf("--parallelism=%d", options.Parallelism)) | ||||||||||||||||||||
} | ||||||||||||||||||||
|
Uh oh!
There was an error while loading. Please reload this page.