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

[TF-20366] Return correct error message when workspace is locked by a Team or User #975

Conversation

ctrombley
Copy link
Contributor

Description

This PR aims to close #971 where the tfe client would return an incorrect error message whenever a user attempted to unlock a workspace that was already locked by a team or a different user.

The current implementation of this client defaults to "workspaces already unlocked" whenever a status 409 is received from the workspace unlock endpoint. A matcher function errorPayloadHasMatch currently parses the the error detail and searches for the "locked by Run" substring that indicates the workspace was locked by a run.

This pattern was extended for the two other instances in which a status 409 is returned. The "locked by Team" substring indicates the workspace was locked by a Team, and similarly the "locked by User" substring indicates that the workspace was locked by a different User.

Testing plan

To run the integration test:

go test -run TestWorkspacesUnlock -v ./... -tags=integration

Because I've modified tfe.go, it's always good to verify those tests as well:

go test -run TestClient -v ./... -tags=integration

I wasn't able to find a way to create a secondary user in the integration tests to test the "locked by User" scenario in a automated fashion. Any suggestions on how to accomplish this would be appreciated.

External links

Output from tests

Including output from tests may require access to a TFE instance. Ignore this section if you have no environment to test against.

For TestWorkspacesUnlock:

=== RUN   TestWorkspacesUnlock
=== RUN   TestWorkspacesUnlock/with_valid_options
=== RUN   TestWorkspacesUnlock/when_workspace_is_already_unlocked
=== RUN   TestWorkspacesUnlock/when_a_workspace_is_locked_by_a_run
=== RUN   TestWorkspacesUnlock/when_a_workspace_is_locked_by_a_team
=== RUN   TestWorkspacesUnlock/without_a_valid_workspace_ID
--- PASS: TestWorkspacesUnlock (11.35s)
    --- PASS: TestWorkspacesUnlock/with_valid_options (0.23s)
    --- PASS: TestWorkspacesUnlock/when_workspace_is_already_unlocked (0.17s)
    --- PASS: TestWorkspacesUnlock/when_a_workspace_is_locked_by_a_run (5.82s)
    --- PASS: TestWorkspacesUnlock/when_a_workspace_is_locked_by_a_team (3.43s)
    --- PASS: TestWorkspacesUnlock/without_a_valid_workspace_ID (0.00s)
PASS
ok      github.com/hashicorp/go-tfe     (cached)

For TestClient:

?       github.com/hashicorp/go-tfe/examples/backing_data       [no test files]
?       github.com/hashicorp/go-tfe/examples/configuration_versions     [no test files]
?       github.com/hashicorp/go-tfe/examples/organizations      [no test files]
?       github.com/hashicorp/go-tfe/examples/registry_modules   [no test files]
?       github.com/hashicorp/go-tfe/examples/run_errors [no test files]
?       github.com/hashicorp/go-tfe/examples/state_versions     [no test files]
?       github.com/hashicorp/go-tfe/examples/users      [no test files]
?       github.com/hashicorp/go-tfe/examples/workspaces [no test files]
?       github.com/hashicorp/go-tfe/mocks       [no test files]
=== RUN   TestClientRequest_DoJSON
=== RUN   TestClientRequest_DoJSON/Success_200_responses
2024/09/12 11:07:54 [DEBUG] PUT http://127.0.0.1:62369/ok_request
=== RUN   TestClientRequest_DoJSON/Success_response_with_no_body
2024/09/12 11:07:54 [DEBUG] POST http://127.0.0.1:62369/created_request
=== RUN   TestClientRequest_DoJSON/Not_Modified_response
2024/09/12 11:07:54 [DEBUG] POST http://127.0.0.1:62369/not_modified_request
=== RUN   TestClientRequest_DoJSON/Bad_400_responses
2024/09/12 11:07:54 [DEBUG] POST http://127.0.0.1:62369/bad_request
--- PASS: TestClientRequest_DoJSON (0.00s)
    --- PASS: TestClientRequest_DoJSON/Success_200_responses (0.00s)
    --- PASS: TestClientRequest_DoJSON/Success_response_with_no_body (0.00s)
    --- PASS: TestClientRequest_DoJSON/Not_Modified_response (0.00s)
    --- PASS: TestClientRequest_DoJSON/Bad_400_responses (0.00s)
=== RUN   TestClient_newClient
=== RUN   TestClient_newClient/uses_env_vars_if_values_are_missing
=== RUN   TestClient_newClient/fails_if_token_is_empty
=== RUN   TestClient_newClient/makes_a_new_client_with_good_settings
--- PASS: TestClient_newClient (0.00s)
    --- PASS: TestClient_newClient/uses_env_vars_if_values_are_missing (0.00s)
    --- PASS: TestClient_newClient/fails_if_token_is_empty (0.00s)
    --- PASS: TestClient_newClient/makes_a_new_client_with_good_settings (0.00s)
=== RUN   TestClient_defaultConfig
=== RUN   TestClient_defaultConfig/with_no_environment_variables
=== RUN   TestClient_defaultConfig/with_environment_variables
=== RUN   TestClient_defaultConfig/with_environment_variables/with_TFE_ADDRESS_set
=== RUN   TestClient_defaultConfig/with_environment_variables/with_TFE_HOSTNAME_set
--- PASS: TestClient_defaultConfig (0.00s)
    --- PASS: TestClient_defaultConfig/with_no_environment_variables (0.00s)
    --- PASS: TestClient_defaultConfig/with_environment_variables (0.00s)
        --- PASS: TestClient_defaultConfig/with_environment_variables/with_TFE_ADDRESS_set (0.00s)
        --- PASS: TestClient_defaultConfig/with_environment_variables/with_TFE_HOSTNAME_set (0.00s)
=== RUN   TestClient_headers
--- PASS: TestClient_headers (0.00s)
=== RUN   TestClient_userAgent
--- PASS: TestClient_userAgent (0.00s)
=== RUN   TestClient_requestBodySerialization
=== RUN   TestClient_requestBodySerialization/jsonapi_request
=== RUN   TestClient_requestBodySerialization/jsonapi_slice_of_pointers_request
=== RUN   TestClient_requestBodySerialization/plain_json_request
=== RUN   TestClient_requestBodySerialization/plain_json_slice_of_pointers_request
=== RUN   TestClient_requestBodySerialization/nil_request
=== RUN   TestClient_requestBodySerialization/invalid_struct_request
=== RUN   TestClient_requestBodySerialization/non-pointer_request
=== RUN   TestClient_requestBodySerialization/slice_of_non-pointer_request
=== RUN   TestClient_requestBodySerialization/map_request
=== RUN   TestClient_requestBodySerialization/string_request
--- PASS: TestClient_requestBodySerialization (2.97s)
    --- PASS: TestClient_requestBodySerialization/jsonapi_request (0.39s)
    --- PASS: TestClient_requestBodySerialization/jsonapi_slice_of_pointers_request (0.26s)
    --- PASS: TestClient_requestBodySerialization/plain_json_request (0.32s)
    --- PASS: TestClient_requestBodySerialization/plain_json_slice_of_pointers_request (0.26s)
    --- PASS: TestClient_requestBodySerialization/nil_request (0.25s)
    --- PASS: TestClient_requestBodySerialization/invalid_struct_request (0.31s)
    --- PASS: TestClient_requestBodySerialization/non-pointer_request (0.26s)
    --- PASS: TestClient_requestBodySerialization/slice_of_non-pointer_request (0.30s)
    --- PASS: TestClient_requestBodySerialization/map_request (0.31s)
    --- PASS: TestClient_requestBodySerialization/string_request (0.32s)
=== RUN   TestClient_configureLimiter
--- PASS: TestClient_configureLimiter (0.00s)
=== RUN   TestClient_retryHTTPCheck
--- PASS: TestClient_retryHTTPCheck (0.00s)
=== RUN   TestClient_retryHTTPBackoff
--- PASS: TestClient_retryHTTPBackoff (0.00s)
PASS
ok      github.com/hashicorp/go-tfe     (cached)

@Maed223 Maed223 merged commit c4d3b14 into main Sep 17, 2024
8 checks passed
Copy link

Reminder to the contributor that merged this PR: if your changes have added important functionality or fixed a relevant bug, open a follow-up PR to update CHANGELOG.md with a note on your changes.

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.

Unlocking a workspace that is locked by a Team or User returns the wrong error
4 participants