-
Notifications
You must be signed in to change notification settings - Fork 905
chore: Refactor integration tests #2986
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?
Conversation
|
👋 Hi! Thank you for this contribution! Just to let you know, our GitHub SDK team does a round of issue and PR reviews twice a week, every Monday and Friday! We have a process in place for prioritizing and responding to your input. Because you are a part of this community please feel free to comment, add to, or pick up any issues/PRs that are labeled with |
64384d9 to
a3a1145
Compare
a3a1145 to
79637e0
Compare
79637e0 to
8f8da76
Compare
deiga
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Half-way through, looking good so far!
| // Can't test due to SDK and test framework limitations | ||
| // t.Run("queries an invalid branch without error", func(t *testing.T) { | ||
| // randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) | ||
|
|
||
| // config := fmt.Sprintf(` | ||
| // resource "github_repository" "test" { | ||
| // name = "tf-acc-test-%[1]s" | ||
| // auto_init = true | ||
| // } | ||
|
|
||
| // data "github_branch" "test" { | ||
| // repository = github_repository.test.name | ||
| // branch = "xxxxxx" | ||
| // } | ||
| // `, randomID) | ||
|
|
||
| // check := resource.ComposeTestCheckFunc( | ||
| // resource.TestCheckResourceAttr( | ||
| // "data.github_branch.test", "ref", "", | ||
| // ), | ||
| // ) | ||
|
|
||
| // resource.Test(t, resource.TestCase{ | ||
| // PreCheck: func() { skipUnauthenticated(t) }, | ||
| // ProviderFactories: providerFactories, | ||
| // Steps: []resource.TestStep{ | ||
| // { | ||
| // Config: config, | ||
| // Check: check, | ||
| // }, | ||
| // }, | ||
| // }) | ||
| // }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: Is there value in keeping this test? The API for refs returns 404 if a ref doesn't exist. I don't understand why this behaviour would be expected from the provider
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The question about the behaviour is why I've left them commented out. I think we'll need a few issues opened once this is merged to make iterative improvements.
| // Can't test due to SDK and test framework limitations | ||
| // t.Run("queries an invalid ref without error", func(t *testing.T) { | ||
| // randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) | ||
| // config := fmt.Sprintf(` | ||
| // resource "github_repository" "test" { | ||
| // name = "tf-acc-test-%[1]s" | ||
| // auto_init = true | ||
| // } | ||
|
|
||
| // data "github_ref" "test" { | ||
| // repository = github_repository.test.id | ||
| // ref = "heads/xxxxxx" | ||
| // } | ||
| // `, randomID) | ||
|
|
||
| // check := resource.ComposeTestCheckFunc( | ||
| // resource.TestCheckNoResourceAttr( | ||
| // "data.github_ref.test", "id", | ||
| // ), | ||
| // ) | ||
|
|
||
| // resource.Test(t, resource.TestCase{ | ||
| // PreCheck: func() { skipUnauthenticated(t) }, | ||
| // ProviderFactories: providerFactories, | ||
| // Steps: []resource.TestStep{ | ||
| // { | ||
| // Config: config, | ||
| // Check: check, | ||
| // }, | ||
| // }, | ||
| // }) | ||
| // }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // Can't test due to SDK and test framework limitations | ||
| // t.Run("try reading a non-existent file without an error", func(t *testing.T) { | ||
| // randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) | ||
| // config := fmt.Sprintf(` | ||
| // resource "github_repository" "test" { | ||
| // name = "tf-acc-test-%s" | ||
| // auto_init = true | ||
|
|
||
| // lifecycle { | ||
| // ignore_changes = all | ||
| // } | ||
| // } | ||
|
|
||
| // data "github_repository_file" "test" { | ||
| // repository = github_repository.test.name | ||
| // file = "test" | ||
| // } | ||
| // `, randomID) | ||
|
|
||
| // resource.Test(t, resource.TestCase{ | ||
| // PreCheck: func() { skipUnauthenticated(t) }, | ||
| // ProviderFactories: providerFactories, | ||
| // Steps: []resource.TestStep{ | ||
| // { | ||
| // Config: config, | ||
| // Check: resource.ComposeTestCheckFunc( | ||
| // resource.TestCheckNoResourceAttr("data.github_repository_file.test", "id"), | ||
| // resource.TestCheckNoResourceAttr("data.github_repository_file.test", "branch"), | ||
| // resource.TestCheckNoResourceAttr("data.github_repository_file.test", "ref"), | ||
| // resource.TestCheckNoResourceAttr("data.github_repository_file.test", "content"), | ||
| // resource.TestCheckNoResourceAttr("data.github_repository_file.test", "sha"), | ||
| // resource.TestCheckNoResourceAttr("data.github_repository_file.test", "commit_sha"), | ||
| // resource.TestCheckNoResourceAttr("data.github_repository_file.test", "commit_message"), | ||
| // resource.TestCheckNoResourceAttr("data.github_repository_file.test", "commit_author"), | ||
| // resource.TestCheckNoResourceAttr("data.github_repository_file.test", "commit_email"), | ||
| // ), | ||
| // }, | ||
| // }, | ||
| // }) | ||
| // }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: Similar to https://github.com/integrations/terraform-provider-github/pull/2986/files#r2601299558, is there value in keeping this as it's not something the API supports?
| // t.Run("fails for invalid endpoint", func(t *testing.T) { | ||
| // config := ` | ||
| // data "github_rest_api" "test" { | ||
| // endpoint = "/xxx" | ||
| // } | ||
| // ` | ||
|
|
||
| // resource.Test(t, resource.TestCase{ | ||
| // PreCheck: func() { skipUnauthenticated(t) }, | ||
| // ProviderFactories: providerFactories, | ||
| // Steps: []resource.TestStep{ | ||
| // { | ||
| // Config: config, | ||
| // ExpectError: regexp.MustCompile("Error: GET https://api.github.com/xx.*: 414"), | ||
| // }, | ||
| // }, | ||
| // }) | ||
| // }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: Why is this commented out?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current REST API implementation swallows 404 errors, and I can't off the top of my head think of a way to repeatedly get a different error response with an anonymous call. This is another behaviour that needs discussing.
| t.Run("with an organization account", func(t *testing.T) { | ||
| testCase(t, organization) | ||
| depends_on = ["github_repository.test", "github_team.test", "github_team_repository.test"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: Do all of these dependents need to be set? I would assume that github_team_repository would already depend on github_team and github_repository implicitly.
If it doesn't should that be fixed?
Also: I don't think resources can be quoted there
| depends_on = ["github_repository.test", "github_team.test", "github_team_repository.test"] | |
| depends_on = [github_team_repository.test] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The depends on needs to be set as it's a data source under test so the resources need to be applied first. Given the behaviour of depends on it's good practice to be explicit here as if the pattern is re-used in a multi step test not having all the resources in there could cause an issue or require additional work to validate if it's the reason for a failure.
Also: I don't think resources can be quoted there
At first glance I'd have agreed with you (if I didn't know the tests were passing), but HCL is very permissive and TF has a lot of legacy baggage.
I'll update these ones, but this type of stylistic cleanup is something that can happen once the PR has landed.
| if len(testAccConf.testExternalUser) == 0 { | ||
| t.Skip("No external user provided") | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: Would we benefit from this moving to acc_test.go as a skipUnlessExternal function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would do, once we've got the tests actually running in CI and the concepts are correct. I'm pretty sure the org app pattern in the tests at the moment is wrong and will need replacing, but all of this would be easier being incremental changes on top of a largely working test suite.
8f8da76 to
d6872d3
Compare
d6872d3 to
b273abd
Compare
b273abd to
337b854
Compare
be3c601 to
94d69ba
Compare
| AllowedValues: allowedValuesString, | ||
| } | ||
|
|
||
| if val, ok := d.GetOk("values_editable_by"); ok { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: Since this is a computed value, aren't there cases where ok would be false, but val has a value? Should we ignore the value in those cases?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is in the resource create, we only want to send the value if it's been explicitly set. The computed part happenes when we set it after it's been created, at which point we can use that value. Without this change the implementation requires the value to be set as otherwise we're sending "" instead of nil.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: Is there a reason to keep this file around? Are we planning to re-use it for projectsV2?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The other files exist, so this should be removed with them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same question as for project tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same question as for project tests
| collaborators := state.RootModule().Resources["github_repository_collaborators.test_repo_collaborators"].Primary | ||
| for name, val := range collaborators.Attributes { | ||
| if strings.HasPrefix(name, "user.") && strings.HasSuffix(name, ".username") && val != testAccConf.testExternalUser { | ||
| return fmt.Errorf("expected user.*.username to be set to %s, was %s", testAccConf.testExternalUser, val) | ||
| } | ||
| if strings.HasPrefix(name, "user.") && strings.HasSuffix(name, ".permission") && val != "push" { | ||
| return fmt.Errorf("expected user.*.permission to be set to push, was %s", val) | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: Could this be replaced with a resource.TestCheckResourceAttr function call?
Or is there a purpose to this which I'm not seeing?
Maybe something like:
resource.TestCheckResourceAttr("github_repository_collaborators.test_repo_collaborators", "user.0.username", testAccConf.testExternalUser)
resource.TestCheckResourceAttr("github_repository_collaborators.test_repo_collaborators", "user.0.permission", "push")There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's been a while since I wrote this, but I'm pretty sure that it solves the unknown ordering issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get that, but there is only 1 collaborator in this config, right? If it's meant to be a helper for the sorting case, maybe it should be extracted for re-use?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah it could be, but given the sheer amount of resources I've put into this PR I'd just like to get it merged and then it can be iterated on. I'd hate to lose something I spent time on that turns out later to be important. Once the code is merged anything removed can be retrieved, I think I've already lost work due to needing to get the tests passing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure! Most of my suggestions are usually "address now, if capacity, otherwise do a follow-up".
I should learn to write that, since usually people can't rind my mind! 😬
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's fine. If this was a smaller piece of work or even if it was all fresh in my mind I'd be making more changes and being less cautious about removing code.
94d69ba to
86c88d6
Compare
86c88d6 to
e2e13b1
Compare
e2e13b1 to
f992480
Compare
Signed-off-by: Steve Hipwell <[email protected]>
f992480 to
810b97c
Compare
|
|
||
| blocked, _, err := conn.Organizations.IsBlocked(context.TODO(), orgName, username) | ||
| blocked, _, err := conn.Organizations.IsBlocked(context.Background(), orgName, username) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: would we get access to t.Context() if we changed the function definition to func testAccCheckOrganizationBlockExists(ctx context.Context, n string)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I cascaded t.Context() everywhere I could (other than for projects where I just got rid of context.TODO()), but some usage comes from typed functions being called directly. We could wrap up these function calls to pass it in, but IMHO this is a problem for another day.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely, let's get this shippable!
Resolves #2983
Resolves #2984
Resolves #2985
Closes #2941
Before the change?
After the change?
Pull request checklist
Does this introduce a breaking change?
Please see our docs on breaking changes to help!