-
Notifications
You must be signed in to change notification settings - Fork 11
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(project_user): Recreate project_user if ignore_missing_user #177
Conversation
}, | ||
}, | ||
// expect user to be added to state | ||
Check: resource.ComposeTestCheckFunc( |
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 the error from the acceptance tests:
=== RUN TestAccProjectMember_missing_user_ignored
resource_project_user_test.go:394: Step 1/4 error: After applying this test step, the refresh plan was not empty.
stdout
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# project_user.not_existingsolpd will be created
+ resource "project_user" "not_existingsolpd" {
+ id = (known after apply)
+ ignore_missing_user = true
+ name = "not_existingsolpd"
+ project_key = "czmmvqeaxp"
+ roles = [
+ "Developer",
+ "Project Admin",
]
}
Plan: 1 to add, 0 to change, 0 to destroy.
--- FAIL: TestAccProjectMember_missing_user_ignored (2.94s)
FAIL
FAIL github.com/jfrog/terraform-provider-project/pkg/project/resource 4.160s
FAIL
I think you'll need:
- Add
ExpectNonEmtpyPlan: true
- Remove
Check: ...
since there'd be no state being saved by the resource.
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.
- Add ExpectNonEmtpyPlan: true
Yes, this looks promising according to: https://github.com/hashicorp/terraform-plugin-testing/blob/4a889266a95c9a38734a7c9f6e079b641a8fae53/helper/resource/testing_new_config.go#L358-L376
I updated the PR with annotations on the first 3 steps where the plan should not be empty.
- Remove Check: ... since there'd be no state being saved by the resource.
TF will still write the project_user to state in this variant of the fix. My initial attempt to not write a state entry failed. TF will report an error if a TF provider does not create a state entry for a resource. So its either "fail" or "create state entry".
The key change in this PR is that on a read
we remove the item from the state if it is missing (causing a create to be detected on plan). Hence the assertions that the state has values as I've seen it on manual 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.
This is the test Steps
that pass for me:
Steps: []resource.TestStep{
// attempt create, will not work
{
Config: config,
ConfigPlanChecks: resource.ConfigPlanChecks{
PostApplyPostRefresh: []plancheck.PlanCheck{
// expect create of project user
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionCreate),
},
},
ExpectNonEmptyPlan: true,
// expect user to be added to state
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "project_key", fmt.Sprintf("%s", params["project_key"])),
resource.TestCheckResourceAttr(resourceName, "name", username),
resource.TestCheckResourceAttr(resourceName, "ignore_missing_user", "true"),
resource.TestCheckResourceAttr(resourceName, "roles.#", "2"),
resource.TestCheckResourceAttr(resourceName, "roles.0", "Developer"),
resource.TestCheckResourceAttr(resourceName, "roles.1", "Project Admin"),
)},
// re-attempt create, will still not work
{
Config: config,
ConfigPlanChecks: resource.ConfigPlanChecks{
PostApplyPostRefresh: []plancheck.PlanCheck{
// again expect create of project user (refresh will mark project user as missing)
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionCreate),
},
},
ExpectNonEmptyPlan: true,
// expect user to be in the state
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "project_key", fmt.Sprintf("%s", params["project_key"])),
resource.TestCheckResourceAttr(resourceName, "name", username),
resource.TestCheckResourceAttr(resourceName, "ignore_missing_user", "true"),
resource.TestCheckResourceAttr(resourceName, "roles.#", "2"),
resource.TestCheckResourceAttr(resourceName, "roles.0", "Developer"),
resource.TestCheckResourceAttr(resourceName, "roles.1", "Project Admin"),
)},
// re-attempt create with user being added, will work
{
Config: configUpdated,
ConfigPlanChecks: resource.ConfigPlanChecks{
PreApply: []plancheck.PlanCheck{
// again expect create of project user (refresh will mark project user as missing)
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionCreate),
},
PostApplyPostRefresh: []plancheck.PlanCheck{
// again expect create of project user (refresh will mark project user as missing)
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionNoop),
},
},
// expect user to be in the state
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "project_key", fmt.Sprintf("%s", params["project_key"])),
resource.TestCheckResourceAttr(resourceName, "name", username),
resource.TestCheckResourceAttr(resourceName, "ignore_missing_user", "true"),
resource.TestCheckResourceAttr(resourceName, "roles.#", "2"),
resource.TestCheckResourceAttr(resourceName, "roles.0", "Developer"),
resource.TestCheckResourceAttr(resourceName, "roles.1", "Project Admin"),
)},
// now user is there, no action should be performed
{
Config: configUpdated,
ConfigPlanChecks: resource.ConfigPlanChecks{
PostApplyPostRefresh: []plancheck.PlanCheck{
// again expect create of project user (refresh will mark project user as missing)
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionNoop),
},
},
// expect user to be in the state
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "project_key", fmt.Sprintf("%s", params["project_key"])),
resource.TestCheckResourceAttr(resourceName, "name", username),
resource.TestCheckResourceAttr(resourceName, "ignore_missing_user", "true"),
resource.TestCheckResourceAttr(resourceName, "roles.#", "2"),
resource.TestCheckResourceAttr(resourceName, "roles.0", "Developer"),
resource.TestCheckResourceAttr(resourceName, "roles.1", "Project Admin"),
)},
},
})
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 also need to add this to TestCase
for step 3 to work:
ExternalProviders: map[string]resource.ExternalProvider{
"artifactory": {
Source: "jfrog/artifactory",
},
},
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.
@alexhung Highly appreciate your help here due to my lack of a test environment. I updated the PR with your proposed changes. The changes make sense and still fit my expectations on how things should work. I'm still fairly new to developing TF providers, a lot of unknowns in the testing framework 😁
8578120
to
509221c
Compare
509221c
to
b15c57d
Compare
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.
LGTM
Fixes #175
I manually tested the change to work as expected using a local provider build. I also extended the integration test to check the expected state and actions. Due to a lack of test-env I cannot check if the tests are really green like this. I might need some assistence there.