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

[PROPOSAL] Implement TypeSet resource.TestCheckFuncs #13556

Merged
merged 2 commits into from
Jun 15, 2020
Merged

Conversation

appilon
Copy link
Contributor

@appilon appilon commented May 29, 2020

This proposed PR would add 2 helper resource.TestCheckFunc that can substitute current checks that use a pre-calculated hash in the key. These functions essentially search all of the instance state for a schema.TypeSet element that matches either the simple value or a nested group of attr/value pairs.

In V2 of the SDK, the underlying test driver uses this library which naively exports TypeSets as a list so this implementation supports both "element ids" of either number or hash.

TypeSet indexes should be substituted with the sentinel value *, this works across deep nesting. TestCheckTypeSetElemNestedAttrs should be used with a granular value map to ensure an element is a full match.

Examples

Deep TypeSet simple element

test.TestCheckTypeSetElemAttr("foo.test", "cors_configuration.0.allow_headers.*", "Authorization"),

TypeSet nested object

test.TestCheckTypeSetElemNestedAttrs("foo.test", "parameter.*", map[string]string{
    "name":  "character_set_results",
    "value": "utf8",
})

TypeSet with downstream TypeList

test.TestCheckTypeSetElemNestedAttrs("foo.test", "origin.*", map[string]string{
    "custom_origin_config.0.http_port":  "80",
})

TypeSet with downstream TypeList with downstream TypeSet

test.TestCheckTypeSetElemNestedAttrs("foo.test", "parameter.*.lifecycle_rule.2.transition.*", map[string]string{
    "storage_class":  "INTELLIGENT_TIERING",
})

@appilon appilon requested a review from a team May 29, 2020 21:31
@ghost ghost added size/L Managed by automation to categorize the size of a PR. service/apigatewayv2 Issues and PRs that pertain to the apigatewayv2 service. service/rds Issues and PRs that pertain to the rds service. tests PRs: expanded test coverage. Issues: expanded coverage, enhancements to test infrastructure. labels May 29, 2020
@bflad bflad mentioned this pull request Jun 1, 2020
18 tasks
@gdavison
Copy link
Contributor

gdavison commented Jun 1, 2020

This looks great, @appilon!

How does it handle collections nested inside a TypeSet? For example:

  • TestAccAWSCodeBuildProject_Source_Auth tests for nested values from a TypeSet inside another TypeSet
  • TestAccAWSMqBroker_allFieldsDefaultVpc tests for a TypeSet inside another TypeSet
  • TestAccAWSCloudFrontDistribution_noOptionalItemsConfig tests for a TypeList inside a TypeSet

I searched for "[a-z_]+\.[0-9]{10}\.[a-z_]+\.[0-9] (the unmatched " is expected)

@ewbankkit
Copy link
Contributor

Definitely looking forward to this as I have to tweak another set of acceptance test values 😄.
Second the need to ideally extend this to nested collections.

@appilon
Copy link
Contributor Author

appilon commented Jun 1, 2020

Thanks @gdavison

TestAccAWSCloudFrontDistribution_noOptionalItemsConfig

This should just work, the "unflattening" part just lifts the path leading up to the Set into a map, so any state past that point should all "just work". I will look for a similar case and verify this, I would try this one but the test mentions deletion takes a while (if you have an example that you know runs relatively quickly please let me know).

TestAccAWSMqBroker_allFieldsDefaultVpc
TestAccAWSCodeBuildProject_Source_Auth

😂 I'm not sure how to handle this yet, was deliberately NOT looking for those cases, but I'll focus on this now.

@appilon
Copy link
Contributor Author

appilon commented Jun 3, 2020

@gdavison @ewbankkit The implementation has changed to support nesting sets.

@gdavison
Copy link
Contributor

gdavison commented Jun 3, 2020

Is there a way to check the case of a TypeSet inside a TypeList where the list has multiple values? For example TestAccAWSS3Bucket_LifecycleBasic() and the tests for "lifecycle_rule.<index>.transition.<item>.<value>"

I'd like to be able to differentiate the list items, and I'm not sure how I'd do that using the depth parameter in TestCheckTypeSetElemNestedAttrs()

resource.TestCheckResourceAttr(resourceName, "lifecycle_rule.0.transition.2000431762.date", ""),
resource.TestCheckResourceAttr(resourceName, "lifecycle_rule.0.transition.2000431762.days", "30"),
resource.TestCheckResourceAttr(resourceName, "lifecycle_rule.0.transition.2000431762.storage_class", "STANDARD_IA"),
resource.TestCheckResourceAttr(resourceName, "lifecycle_rule.0.transition.3601168188.date", ""),
resource.TestCheckResourceAttr(resourceName, "lifecycle_rule.0.transition.3601168188.days", "60"),
resource.TestCheckResourceAttr(resourceName, "lifecycle_rule.0.transition.3601168188.storage_class", "INTELLIGENT_TIERING"),
resource.TestCheckResourceAttr(resourceName, "lifecycle_rule.0.transition.3854926587.date", ""),
resource.TestCheckResourceAttr(resourceName, "lifecycle_rule.0.transition.3854926587.days", "90"),
resource.TestCheckResourceAttr(resourceName, "lifecycle_rule.0.transition.3854926587.storage_class", "ONEZONE_IA"),
resource.TestCheckResourceAttr(resourceName, "lifecycle_rule.0.transition.962205413.date", ""),
resource.TestCheckResourceAttr(resourceName, "lifecycle_rule.0.transition.962205413.days", "120"),
resource.TestCheckResourceAttr(resourceName, "lifecycle_rule.0.transition.962205413.storage_class", "GLACIER"),
resource.TestCheckResourceAttr(resourceName, "lifecycle_rule.0.transition.1571523406.date", ""),
resource.TestCheckResourceAttr(resourceName, "lifecycle_rule.0.transition.1571523406.days", "210"),
resource.TestCheckResourceAttr(resourceName, "lifecycle_rule.0.transition.1571523406.storage_class", "DEEP_ARCHIVE"),

resource.TestCheckResourceAttr(resourceName, "lifecycle_rule.2.transition.460947558.days", "0"),

resource.TestCheckResourceAttr(resourceName, "lifecycle_rule.4.transition.460947558.days", "0"),
resource.TestCheckResourceAttr(resourceName, "lifecycle_rule.4.transition.460947558.storage_class", "GLACIER"),

resource.TestCheckResourceAttr(resourceName, "lifecycle_rule.5.transition.460947558.days", "0"),
resource.TestCheckResourceAttr(resourceName, "lifecycle_rule.5.transition.460947558.storage_class", "GLACIER"),

@appilon
Copy link
Contributor Author

appilon commented Jun 3, 2020

@gdavison Indeed it appears this implementation wouldn't be able to discern between those list items since the depth is the same 😢 . These are great examples though keep them coming, back to the drawing board!

@appilon
Copy link
Contributor Author

appilon commented Jun 9, 2020

@ewbankkit @gdavison oookay hopefully this covers all cases.

Copy link
Contributor

@gdavison gdavison left a comment

Choose a reason for hiding this comment

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

Looks great! One question, because it looks like a test is changing

Comment on lines 135 to 163
resource.TestCheckNoResourceAttr(resourceName, "parameter.2475805061.value"),
resource.TestCheckNoResourceAttr(resourceName, "parameter.1706463059.value"),
resource.TestCheckResourceAttr(resourceName, "parameter.#", "3"),
test.TestCheckTypeSetElemNestedAttrs(resourceName, "parameter.*", map[string]string{
"name": "character_set_results",
"value": "utf8",
}),
test.TestCheckTypeSetElemNestedAttrs(resourceName, "parameter.*", map[string]string{
"name": "character_set_server",
"value": "utf8",
}),
test.TestCheckTypeSetElemNestedAttrs(resourceName, "parameter.*", map[string]string{
"name": "character_set_client",
"value": "utf8",
}),
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems to be changing the test, since there were two items, and no values set for value, and now there are three and they have values.. Is that intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah yes this is a bit quirky. There isn't really anyway to represent a specific set element that doesn't exist... My PR proposes helpers to guarantee a single element meets the desired criteria. So I flipped the test to "3 elements with the following property maps, and that the set only contains 3 entries (and not 5)"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I inferred that this is what was being validated by looking at the test config (goes from 5 parameters to 3)

@appilon
Copy link
Contributor Author

appilon commented Jun 12, 2020

Okay although flaky the last example you mentioned @gdavison has passed 🎉

❯ make testacc TEST=./aws TESTARGS='-run=TestAccAWSS3Bucket_LifecycleBasic'
==> Checking that code complies with gofmt requirements...
TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSS3Bucket_LifecycleBasic -timeout 120m
=== RUN   TestAccAWSS3Bucket_LifecycleBasic
=== PAUSE TestAccAWSS3Bucket_LifecycleBasic
=== CONT  TestAccAWSS3Bucket_LifecycleBasic
--- PASS: TestAccAWSS3Bucket_LifecycleBasic (118.38s)
PASS
ok  	github.com/terraform-providers/terraform-provider-aws/aws	121.065s

@ghost ghost added the service/s3 Issues and PRs that pertain to the s3 service. label Jun 12, 2020
Copy link
Contributor

@bflad bflad left a comment

Choose a reason for hiding this comment

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

This should cover us for now! Two notes below, otherwise looks good to me. 🚀

@@ -0,0 +1,114 @@
package test
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be super awesome if these new testing functions had unit testing so they can be updated without needing to verify with various acceptance tests. 👍 I'm also not the biggest fan of the package being named test since the function names already relay that (I'd suggest tfawsresource), but that's a personal nit since its internal to this module until it is migrated to the SDK.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

no problem I can change the package name

)

const (
sentinelIndex = "*"
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it worth having the functions return an error if this sentinel value is not present or present more than once?

Copy link
Contributor Author

@appilon appilon Jun 15, 2020

Choose a reason for hiding this comment

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

I can return error if the last part in the address isn't *, since it always should

Added check that the last part of a path is in fact the sentinel value
@ghost ghost added size/XXL Managed by automation to categorize the size of a PR. and removed size/L Managed by automation to categorize the size of a PR. labels Jun 15, 2020
@appilon appilon merged commit 844f6b9 into master Jun 15, 2020
@appilon appilon deleted the typeset-check branch June 15, 2020 20:04
@ghost
Copy link

ghost commented Jul 16, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks!

@ghost ghost locked and limited conversation to collaborators Jul 16, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
service/apigatewayv2 Issues and PRs that pertain to the apigatewayv2 service. service/rds Issues and PRs that pertain to the rds service. service/s3 Issues and PRs that pertain to the s3 service. size/XXL Managed by automation to categorize the size of a PR. tests PRs: expanded test coverage. Issues: expanded coverage, enhancements to test infrastructure.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants