cloudformation-cli icon indicating copy to clipboard operation
cloudformation-cli copied to clipboard

Resource type handler_update fails to delete the right model version

Open assafkamil opened this issue 1 year ago • 1 comments

The updated_resource in handler_update resource type test suite is wrongly deleting the created model in its finally section instead of the potentially updated model.

My resource type is maintaining a Version field on the server with optimistic locking to avoid accidental overwrite of the resource. Upon a successful update, the version is auto-incremented and the new version is returned to the client. The client specifies the version in the If-Match header of the HTTP request, and the server allows the mutation only if the version stored is the same.

In the following function:

def updated_resource(resource_client):
    create_request = input_model = resource_client.generate_create_example()
    model = {}
    try:
        _status, response, _error = resource_client.call_and_assert(
            Action.CREATE, OperationStatus.SUCCESS, create_request
        )
        created_model = model = response["resourceModel"]
        test_input_equals_output(resource_client, input_model, created_model)

        update_request = resource_client.generate_update_example(created_model)

        _status, response, _error = resource_client.call_and_assert(
            Action.UPDATE, OperationStatus.SUCCESS, update_request, created_model
        )
        updated_model = response["resourceModel"]
        test_input_equals_output(resource_client, update_request, updated_model)

        # flake8: noqa: B950
        # pylint: disable=C0301
        yield create_request, created_model, update_request, updated_model, update_request
    finally:
        resource_client.call_and_assert(Action.DELETE, OperationStatus.SUCCESS, model)

The following call to update:

       _status, response, _error = resource_client.call_and_assert(
            Action.UPDATE, OperationStatus.SUCCESS, update_request, created_model
        )
        updated_model = response["resourceModel"]

increments the resource version but the delete is made on the original model, which in my case, has the previous version, and thus fails:

     finally:
        resource_client.call_and_assert(Action.DELETE, OperationStatus.SUCCESS, model)

A potential fix, is to update the model upon successful update:

       _status, response, _error = resource_client.call_and_assert(
            Action.UPDATE, OperationStatus.SUCCESS, update_request, created_model
        )
        model = updated_model = response["resourceModel"]

When trying to delete the resource in the finally section now, the right model is provided

assafkamil avatar Aug 15 '24 05:08 assafkamil

I am encountering the same issue. Due to this test, any resource that updates and tracks a remote identifier which is used for retrieving said resource will fail.

Scribbd avatar Aug 21 '24 19:08 Scribbd