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

[fix] [testing] make TDD more productive #206

Merged
merged 11 commits into from
Jun 29, 2020

Conversation

ryanking
Copy link
Contributor

@ryanking ryanking commented Jun 24, 2020

This uses a technique inspired by terratest's test-structure tools to make it easier to iterate
on this code.

The idea is that each test will be broken into stages 'options',
'apply', 'validate' and 'cleanup' which can be skipped but also persist
any state (like randomly generated options).

So you can do something like:

make test TEST=./aws-s3-private-bucket SKIP=cleanup

Which will

  1. run 'options' to generate and persist a set of random variables
  2. run 'apply' which will terraform apply to create resources and persist the state file
  3. run 'validate' to make assertions about the resources created
  4. skip 'cleanup'

This time will be dominated by how long it takes to apply the changes (seconds to ~1hr).

Then if you run:

make test TEST=./aws-s3-private-bucket SKIP=cleanup,options,apply

It will only run the validate step, which takes < 10s. You can re run
this, iterating on your tests until you are satisfied.

At some point you might realize you need to update the terraform code.
After you make those edits you can run:

make test TEST=./aws-s3-private-bucket SKIP=cleanup,options

which will

  1. skip options and use the persisted options
  2. run apply, using existing options and state file. This will mean that
    for some resources you can do an update-in-place, potentially much
    faster.
  3. run validate
  4. skip cleanup

When all done, you can run cleanup and then re-run with no skips to make
sure it works end-to-end.

This uses terratest's test-structure tools to make it easier to iterate
on this code.

The idea is that each test will be broken into stages like 'options',
'apply', 'validate' and 'cleanup' which can be skipped but also persist
any state (like randomly generated options).

So you can do something like:

`make test TEST=./aws-s3-private-bucket SKIP_cleanup=1`

Which will

1. run 'options' to generate a set of random variables as input
for this test and perist them
2. run 'apply' which will use `terraform apply` to create resources and perist the state file
3. run 'validate' to make assertions about the resources created
4. skip 'cleanup'

This will take 1-2min.

Then if you run:

`make test TEST=./aws-s3-private-bucket SKIP_cleanup=1 SKIP_options=1 SKIP_apply=1`

It will only run the validate step, which takes < 10s. You can re run
this, iterating on your tests until you are satisfied.

At some point you might realize you need to update the terraform code.
After you make those edits you can run:

`make test TEST=./aws-s3-private-bucket SKIP_cleanup=1 SKIP_options=1`

which will

1. skip options, using the existing options
2. run apply, using existing options and state file. This will mean that
   for some resources you can do an update-in-place, potentially much
   faster.
3. run validate
4. skip cleanup

When all done, you can run cleanup and then re-run with no skips to make
sure it works end-to-end.
@@ -102,7 +102,10 @@ data "aws_iam_policy_document" "bucket_policy" {
statement {
sid = "EnforceTLS"
actions = ["*"]
resources = ["arn:aws:s3:::${var.bucket_name}/*"]
resources = [
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that writing these tests led me to realize we had a bug here!

@@ -138,7 +138,10 @@ func Cleanup(t *testing.T, options *terraform.Options) {

func ListEnvVar(name string) []string {
s := os.Getenv(name)
return strings.Split(s, ",")
splitFn := func(c rune) bool {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

without this change an input of "" will give a slice with {""}

@ryanking ryanking changed the title WIP attempt at making TDD more productive make TDD more productive Jun 25, 2020
@ryanking ryanking changed the title make TDD more productive [testing] make TDD more productive Jun 25, 2020
@ryanking ryanking changed the title [testing] make TDD more productive [fix] [testing] make TDD more productive Jun 25, 2020
@ryanking ryanking requested a review from edulop91 June 25, 2020 19:06
@ryanking ryanking marked this pull request as ready for review June 25, 2020 19:06
@ryanking ryanking requested a review from a team as a code owner June 25, 2020 19:06
Copy link
Contributor

@edulop91 edulop91 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯

@czimergebot czimergebot merged commit 1fe821e into master Jun 29, 2020
@czimergebot czimergebot deleted the ryanking/private-bucket-test-stages branch June 29, 2020 20:56
czimergebot pushed a commit that referenced this pull request Jul 17, 2020
Apply the pattern established with #206.

This refactor is a small step toward making TDD-driven workflows more management for modules.

### Test Plan
* CI

### References
* #206
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants