From 8b11e74a5bd30f08ea7f130bb11edf98bf4be9ed Mon Sep 17 00:00:00 2001 From: "localstack[bot]" Date: Thu, 5 Jun 2025 07:28:31 +0000 Subject: [PATCH 01/74] prepare next development iteration From 94db52d9edfa329c4097f09abd7d59d947898b6e Mon Sep 17 00:00:00 2001 From: Silvio Vasiljevic Date: Thu, 5 Jun 2025 15:41:18 +0200 Subject: [PATCH 02/74] Fix Workflow summaries for ARM workflows (#12707) --- .github/workflows/aws-tests.yml | 34 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/.github/workflows/aws-tests.yml b/.github/workflows/aws-tests.yml index 38e77786227d0..49d763255ca36 100644 --- a/.github/workflows/aws-tests.yml +++ b/.github/workflows/aws-tests.yml @@ -447,12 +447,12 @@ jobs: name: Publish Test Results strategy: matrix: - runner: - - ubuntu-latest - - ubuntu-24.04-arm + arch: + - amd64 + - arm64 exclude: # skip the ARM integration tests in case we are not on the master and not on the upgrade-dependencies branch and forceARMTests is not set to true - - runner: ${{ (github.ref != 'refs/heads/master' && github.ref != 'upgrade-dependencies' && inputs.forceARMTests == false) && 'ubuntu-24.04-arm' || ''}} + - arch: ${{ (github.ref != 'refs/heads/master' && github.ref != 'upgrade-dependencies' && inputs.forceARMTests == false) && 'arm64' || ''}} needs: - test-integration - test-bootstrap @@ -465,20 +465,16 @@ jobs: # execute on success or failure, but not if the workflow is cancelled or any of the dependencies has been skipped if: always() && !cancelled() && !contains(needs.*.result, 'skipped') steps: - - name: Determine Runner Architecture - shell: bash - run: echo "PLATFORM=${{ (runner.arch == 'X64' && 'amd64') || (runner.arch == 'ARM64' && 'arm64') || '' }}" >> $GITHUB_ENV - - name: Download Bootstrap Artifacts uses: actions/download-artifact@v4 - if: ${{ env.PLATFORM == 'amd64' }} + if: ${{ matrix.arch == 'amd64' }} with: pattern: test-results-bootstrap - name: Download Integration Artifacts uses: actions/download-artifact@v4 with: - pattern: test-results-integration-${{ env.PLATFORM }}-* + pattern: test-results-integration-${{ matrix.arch }}-* - name: Publish Bootstrap and Integration Test Results uses: EnricoMi/publish-unit-test-result-action@v2 @@ -486,7 +482,7 @@ jobs: with: files: | **/pytest-junit-*.xml - check_name: "Test Results (${{ env.PLATFORM }}${{ inputs.testAWSAccountId != '000000000000' && ', MA/MR' || ''}}) - Integration${{ env.PLATFORM == 'amd64' && ', Bootstrap' || ''}}" + check_name: "Test Results (${{ matrix.arch }}${{ inputs.testAWSAccountId != '000000000000' && ', MA/MR' || ''}}) - Integration${{ matrix.arch == 'amd64' && ', Bootstrap' || ''}}" test_file_prefix: "-/opt/code/localstack/" action_fail_on_inconclusive: true @@ -571,12 +567,12 @@ jobs: name: Publish Acceptance Test Results strategy: matrix: - runner: - - ubuntu-latest - - ubuntu-24.04-arm + arch: + - amd64 + - arm64 exclude: # skip the ARM integration tests in case we are not on the master and not on the upgrade-dependencies branch and forceARMTests is not set to true - - runner: ${{ (github.ref != 'refs/heads/master' && github.ref != 'upgrade-dependencies' && inputs.forceARMTests == false) && 'ubuntu-24.04-arm' || ''}} + - arch: ${{ (github.ref != 'refs/heads/master' && github.ref != 'upgrade-dependencies' && inputs.forceARMTests == false) && 'arm64' || ''}} needs: - test-acceptance runs-on: ubuntu-latest @@ -588,14 +584,10 @@ jobs: # execute on success or failure, but not if the workflow is cancelled or any of the dependencies has been skipped if: always() && !cancelled() && !contains(needs.*.result, 'skipped') steps: - - name: Determine Runner Architecture - shell: bash - run: echo "PLATFORM=${{ (runner.arch == 'X64' && 'amd64') || (runner.arch == 'ARM64' && 'arm64') || '' }}" >> $GITHUB_ENV - - name: Download Acceptance Artifacts uses: actions/download-artifact@v4 with: - pattern: test-results-acceptance-${{ env.PLATFORM }} + pattern: test-results-acceptance-${{ matrix.arch }} - name: Publish Acceptance Test Results uses: EnricoMi/publish-unit-test-result-action@v2 @@ -603,7 +595,7 @@ jobs: with: files: | **/pytest-junit-*.xml - check_name: "Test Results (${{ env.PLATFORM }}${{ inputs.testAWSAccountId != '000000000000' && ', MA/MR' || ''}}) - Acceptance" + check_name: "Test Results (${{ matrix.arch }}${{ inputs.testAWSAccountId != '000000000000' && ', MA/MR' || ''}}) - Acceptance" test_file_prefix: "-/opt/code/localstack/" action_fail_on_inconclusive: true From c0b1c13e50b4555ef1ec457fd0bf46ffe90adf64 Mon Sep 17 00:00:00 2001 From: Quetzalli Date: Thu, 5 Jun 2025 07:41:35 -0700 Subject: [PATCH 03/74] fix: update readme for 4.5 release (#12718) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4292cf113fb99..0bbd286f93e47 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

-:zap: We are thrilled to announce the release of LocalStack 4.4 :zap: +:zap: We are thrilled to announce the release of LocalStack 4.5 :zap:

From 4d02baed1e7f2233b07caa5ff7830ddbb410dd3c Mon Sep 17 00:00:00 2001 From: Misha Tiurin <650819+tiurin@users.noreply.github.com> Date: Thu, 5 Jun 2025 17:05:47 +0200 Subject: [PATCH 04/74] Update launch instructions in README.md for 4.5.0 (#12719) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0bbd286f93e47..00916b05e0891 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ Start LocalStack inside a Docker container by running: / /___/ /_/ / /__/ /_/ / /___/ / /_/ /_/ / /__/ ,< /_____/\____/\___/\__,_/_//____/\__/\__,_/\___/_/|_| -- LocalStack CLI: 4.4.0 +- LocalStack CLI: 4.5.0 - Profile: default - App: https://app.localstack.cloud From aeea74602c33e2b29d0d576eabb35006a8902376 Mon Sep 17 00:00:00 2001 From: Ben Simon Hartung <42031100+bentsku@users.noreply.github.com> Date: Thu, 5 Jun 2025 17:11:41 +0200 Subject: [PATCH 05/74] Events: fix PutEvents triggering Scheduled rules (#12716) --- .../localstack/services/events/provider.py | 4 ++ .../services/events/test_events_schedule.py | 37 +++++++++++++++++++ .../test_events_schedule.validation.json | 9 +++++ 3 files changed, 50 insertions(+) diff --git a/localstack-core/localstack/services/events/provider.py b/localstack-core/localstack/services/events/provider.py index 644129e220511..91e95b5100374 100644 --- a/localstack-core/localstack/services/events/provider.py +++ b/localstack-core/localstack/services/events/provider.py @@ -1896,6 +1896,10 @@ def _process_entry( if configured_rules := list(event_bus.rules.values()): for rule in configured_rules: + if rule.schedule_expression: + # we do not want to execute Scheduled Rules on PutEvents + continue + self._process_rules(rule, region, account_id, event_formatted, trace_header) else: LOG.info( diff --git a/tests/aws/services/events/test_events_schedule.py b/tests/aws/services/events/test_events_schedule.py index 9bdda3cbf8147..aef36fadb04f2 100644 --- a/tests/aws/services/events/test_events_schedule.py +++ b/tests/aws/services/events/test_events_schedule.py @@ -6,6 +6,7 @@ from botocore.exceptions import ClientError from localstack.testing.aws.eventbus_utils import trigger_scheduled_rule +from localstack.testing.aws.util import is_aws_cloud from localstack.testing.pytest import markers from localstack.testing.snapshots.transformer_utility import TransformerUtility from localstack.utils.strings import short_uid @@ -385,3 +386,39 @@ def test_schedule_cron_target_sqs( time_message = time_message.replace(second=0, microsecond=0) assert time_message == target_datetime + + @markers.aws.validated + def tests_scheduled_rule_does_not_trigger_on_put_events( + self, sqs_as_events_target, events_put_rule, aws_client + ): + queue_url, queue_arn = sqs_as_events_target() + + bus_name = "default" + rule_name = f"test-rule-{short_uid()}" + events_put_rule( + Name=rule_name, EventBusName=bus_name, ScheduleExpression="rate(10 minutes)" + ) + + target_id = f"target-{short_uid()}" + aws_client.events.put_targets( + Rule=rule_name, + EventBusName=bus_name, + Targets=[ + { + "Id": target_id, + "Arn": queue_arn, + "Input": json.dumps({"custom-value": "somecustominput"}), + }, + ], + ) + test_event = { + "Source": "core.update-account-command", + "DetailType": "core.update-account-command", + "Detail": json.dumps({"command": ["update-account"]}), + } + aws_client.events.put_events(Entries=[test_event]) + + messages = aws_client.sqs.receive_message( + QueueUrl=queue_url, WaitTimeSeconds=10 if is_aws_cloud() else 3 + ) + assert not messages.get("Messages") diff --git a/tests/aws/services/events/test_events_schedule.validation.json b/tests/aws/services/events/test_events_schedule.validation.json index de1d5cb7e40e8..2dce0326ca018 100644 --- a/tests/aws/services/events/test_events_schedule.validation.json +++ b/tests/aws/services/events/test_events_schedule.validation.json @@ -68,6 +68,15 @@ "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(5,35 14 * * ? *)]": { "last_validated_date": "2025-01-22T13:22:43+00:00" }, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_scheduled_rule_does_not_trigger_on_put_events": { + "last_validated_date": "2025-06-04T19:23:59+00:00", + "durations_in_seconds": { + "setup": 0.56, + "call": 11.78, + "teardown": 1.18, + "total": 13.52 + } + }, "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[ rate(10 minutes)]": { "last_validated_date": "2024-05-14T11:27:18+00:00" }, From 986ed8b84e9f8be0badde27867f24c794c9c8987 Mon Sep 17 00:00:00 2001 From: Anastasia Dusak <61540676+k-a-il@users.noreply.github.com> Date: Thu, 5 Jun 2025 19:17:23 +0200 Subject: [PATCH 06/74] GH Actions: change test selection parameter (#12710) --- .github/workflows/aws-main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/aws-main.yml b/.github/workflows/aws-main.yml index 9e6888c4a3f65..acbda45a8e1d0 100644 --- a/.github/workflows/aws-main.yml +++ b/.github/workflows/aws-main.yml @@ -81,7 +81,7 @@ jobs: # default "disableCaching" to `false` if it's a push or schedule event disableCaching: ${{ inputs.disableCaching == true }} # default "disableTestSelection" to `true` if it's a push or schedule event - disableTestSelection: ${{ inputs.enableTestSelection != true }} + disableTestSelection: ${{ (inputs.enableTestSelection != '' && inputs.enableTestSelection) || github.event_name == 'push' }} PYTEST_LOGLEVEL: ${{ inputs.PYTEST_LOGLEVEL }} forceARMTests: ${{ inputs.forceARMTests == true }} secrets: From 6a52793d078869889c5cf265582425a877ae9185 Mon Sep 17 00:00:00 2001 From: Misha Tiurin <650819+tiurin@users.noreply.github.com> Date: Fri, 6 Jun 2025 09:48:11 +0200 Subject: [PATCH 07/74] Remove unneeded positional argument from cleanup lambda (#12702) --- tests/aws/services/iam/test_iam.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/aws/services/iam/test_iam.py b/tests/aws/services/iam/test_iam.py index e6315e6542606..ef6b6ad5f6ce4 100755 --- a/tests/aws/services/iam/test_iam.py +++ b/tests/aws/services/iam/test_iam.py @@ -491,7 +491,7 @@ def test_simulate_principle_policy( elif arn_type == "group": group_name = f"group-{short_uid()}" group = aws_client.iam.create_group(GroupName=group_name)["Group"] - cleanups.append(lambda _: aws_client.iam.delete_group(GroupName=group_name)) + cleanups.append(lambda: aws_client.iam.delete_group(GroupName=group_name)) aws_client.iam.attach_group_policy(GroupName=group_name, PolicyArn=policy_arn) arn = group["Arn"] From 2f1fe4876c3c51d456092545ee06b972b303608c Mon Sep 17 00:00:00 2001 From: Silvio Vasiljevic Date: Fri, 6 Jun 2025 13:29:13 +0200 Subject: [PATCH 08/74] Move publishing of images and coverage from CircleCI to GHA (#12708) --- .circleci/config.yml | 34 ---------------------------------- .github/workflows/aws-main.yml | 7 ++----- 2 files changed, 2 insertions(+), 39 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 890308fa1cdbc..937d78fb6a86f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -880,14 +880,6 @@ workflows: resource_class: medium requires: - docker-build-amd64 - - push: - filters: - branches: - only: master - requires: - - acceptance-tests-amd64 - - acceptance-tests-arm64 - - unit-tests full-run: # this workflow only runs when only-acceptance-tests is not explicitly set (the default) # or when the pipeline is running on the master branch because of a Github event (webhook) @@ -982,29 +974,3 @@ workflows: name: collect-not-implemented requires: - docker-build-amd64 - - report: - requires: - - itest-cloudwatch-v1-provider - - itest-events-v1-provider - - itest-ddb-v2-provider - - itest-cfn-v2-engine-provider - - acceptance-tests-amd64 - - acceptance-tests-arm64 - - integration-tests-amd64 - - integration-tests-arm64 - - collect-not-implemented - - unit-tests - - push: - filters: - branches: - only: master - requires: - - itest-cloudwatch-v1-provider - - itest-events-v1-provider - - itest-ddb-v2-provider - - itest-cfn-v2-engine-provider - - acceptance-tests-amd64 - - acceptance-tests-arm64 - - integration-tests-amd64 - - integration-tests-arm64 - - unit-tests diff --git a/.github/workflows/aws-main.yml b/.github/workflows/aws-main.yml index acbda45a8e1d0..60561e413a85f 100644 --- a/.github/workflows/aws-main.yml +++ b/.github/workflows/aws-main.yml @@ -140,8 +140,7 @@ jobs: source .venv/bin/activate coverage report || true coverage html || true -# TO-DO: enable job after workflow in CircleCI is disabled -# coveralls || true + coveralls || true - name: Create Coverage Diff (Code Coverage) # pycobertura diff will return with exit code 0-3 -> we currently expect 2 (2: the changes worsened the overall coverage), @@ -189,9 +188,7 @@ jobs: name: "Push images" runs-on: ubuntu-latest # push image on master, target branch not set, and the dependent steps were either successful or skipped - # TO-DO: enable job after workflow in CircleCI is disabled - if: false - # if: github.ref == 'refs/heads/master' && !failure() && !cancelled() && github.repository == 'localstack/localstack' + if: github.ref == 'refs/heads/master' && !failure() && !cancelled() && github.repository == 'localstack/localstack' needs: # all tests need to be successful for the image to be pushed - test From c22632d00835e87944138d25af180180996fad61 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Palma <64580864+MEPalma@users.noreply.github.com> Date: Fri, 6 Jun 2025 13:58:19 +0200 Subject: [PATCH 09/74] CloudFormation v2 Engine: Parity Improvements for Fn::Sub (#12705) --- .../engine/v2/change_set_model.py | 7 + .../engine/v2/change_set_model_describer.py | 94 +++++------ .../engine/v2/change_set_model_preproc.py | 153 +++++++++++------- .../api/test_reference_resolving.py | 1 - .../ported_from_v1/engine/test_references.py | 2 - .../v2/ported_from_v1/test_template_engine.py | 2 - 6 files changed, 140 insertions(+), 119 deletions(-) diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model.py index b3c7009692f72..62f54eb8552eb 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model.py @@ -534,6 +534,13 @@ def _visit_intrinsic_function( self._visited_scopes[scope] = node_intrinsic_function return node_intrinsic_function + def _resolve_intrinsic_function_fn_sub(self, arguments: ChangeSetEntity) -> ChangeType: + # TODO: This routine should instead export the implicit Ref and GetAtt calls within the first + # string template parameter and compute the respective change set types. Currently, + # changes referenced by Fn::Sub templates are only picked up during preprocessing; not + # at modelling. + return arguments.change_type + def _resolve_intrinsic_function_fn_get_att(self, arguments: ChangeSetEntity) -> ChangeType: # TODO: add support for nested intrinsic functions. # TODO: validate arguments structure and type. diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_describer.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_describer.py index e58c71f6a4757..8c5f19b900a16 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_describer.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_describer.py @@ -8,7 +8,6 @@ NodeIntrinsicFunction, NodeProperty, NodeResource, - Nothing, PropertiesKey, is_nothing, ) @@ -41,66 +40,44 @@ def get_changes(self) -> cfn_api.Changes: self.process() return self._changes - def visit_node_intrinsic_function_fn_get_att( - self, node_intrinsic_function: NodeIntrinsicFunction - ) -> PreprocEntityDelta: + def _resolve_attribute(self, arguments: str | list[str], select_before: bool) -> str: + if select_before: + return super()._resolve_attribute(arguments=arguments, select_before=select_before) + + # Replicate AWS's limitations in describing change set's updated values. # Consideration: If we can properly compute the before and after value, why should we - # artificially limit the precision of our output to match AWS's? - - arguments_delta = self.visit(node_intrinsic_function.arguments) - before_argument: Optional[list[str]] = arguments_delta.before - if isinstance(before_argument, str): - before_argument = before_argument.split(".") - after_argument: Optional[list[str]] = arguments_delta.after - if isinstance(after_argument, str): - after_argument = after_argument.split(".") - - before = Nothing - if not is_nothing(before_argument): - before_logical_name_of_resource = before_argument[0] - before_attribute_name = before_argument[1] - before_node_resource = self._get_node_resource_for( - resource_name=before_logical_name_of_resource, node_template=self._node_template - ) - before_node_property: Optional[NodeProperty] = self._get_node_property_for( - property_name=before_attribute_name, node_resource=before_node_resource - ) - if before_node_property is not None: - before_property_delta = self.visit(before_node_property) - before = before_property_delta.before + # artificially limit the precision of our output to match AWS's? + + arguments_list: list[str] + if isinstance(arguments, str): + arguments_list = arguments.split(".") + else: + arguments_list = arguments + logical_name_of_resource = arguments_list[0] + attribute_name = arguments_list[1] + + node_resource = self._get_node_resource_for( + resource_name=logical_name_of_resource, node_template=self._node_template + ) + node_property: Optional[NodeProperty] = self._get_node_property_for( + property_name=attribute_name, node_resource=node_resource + ) + if node_property is not None: + property_delta = self.visit(node_property) + if property_delta.before == property_delta.after: + value = property_delta.after else: - before = self._before_deployed_property_value_of( - resource_logical_id=before_logical_name_of_resource, - property_name=before_attribute_name, + value = CHANGESET_KNOWN_AFTER_APPLY + else: + try: + value = self._after_deployed_property_value_of( + resource_logical_id=logical_name_of_resource, + property_name=attribute_name, ) + except RuntimeError: + value = CHANGESET_KNOWN_AFTER_APPLY - after = Nothing - if not is_nothing(after_argument): - after_logical_name_of_resource = after_argument[0] - after_attribute_name = after_argument[1] - after_node_resource = self._get_node_resource_for( - resource_name=after_logical_name_of_resource, node_template=self._node_template - ) - after_property_delta: PreprocEntityDelta - after_node_property = self._get_node_property_for( - property_name=after_attribute_name, node_resource=after_node_resource - ) - if after_node_property is not None: - after_property_delta = self.visit(after_node_property) - if after_property_delta.before == after_property_delta.after: - after = after_property_delta.after - else: - after = CHANGESET_KNOWN_AFTER_APPLY - else: - try: - after = self._after_deployed_property_value_of( - resource_logical_id=after_logical_name_of_resource, - property_name=after_attribute_name, - ) - except RuntimeError: - after = CHANGESET_KNOWN_AFTER_APPLY - - return PreprocEntityDelta(before=before, after=after) + return value def visit_node_intrinsic_function_fn_join( self, node_intrinsic_function: NodeIntrinsicFunction @@ -209,6 +186,9 @@ def visit_node_resource( self, node_resource: NodeResource ) -> PreprocEntityDelta[PreprocResource, PreprocResource]: delta = super().visit_node_resource(node_resource=node_resource) + after_resource = delta.after + if not is_nothing(after_resource) and after_resource.physical_resource_id is None: + after_resource.physical_resource_id = CHANGESET_KNOWN_AFTER_APPLY self._describe_resource_change( name=node_resource.name, before=delta.before, after=delta.after ) diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py index 0c3a5fa3805ec..4b318f262c479 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py @@ -379,62 +379,56 @@ def visit_node_object(self, node_object: NodeObject) -> PreprocEntityDelta: after[name] = delta_after return PreprocEntityDelta(before=before, after=after) + def _resolve_attribute(self, arguments: str | list[str], select_before: bool) -> str: + # TODO: add arguments validation. + arguments_list: list[str] + if isinstance(arguments, str): + arguments_list = arguments.split(".") + else: + arguments_list = arguments + logical_name_of_resource = arguments_list[0] + attribute_name = arguments_list[1] + + node_resource = self._get_node_resource_for( + resource_name=logical_name_of_resource, node_template=self._node_template + ) + node_property: Optional[NodeProperty] = self._get_node_property_for( + property_name=attribute_name, node_resource=node_resource + ) + if node_property is not None: + # The property is statically defined in the template and its value can be computed. + property_delta = self.visit(node_property) + value = property_delta.before if select_before else property_delta.after + else: + # The property is not statically defined and must therefore be available in + # the properties deployed set. + if select_before: + value = self._before_deployed_property_value_of( + resource_logical_id=logical_name_of_resource, + property_name=attribute_name, + ) + else: + value = self._after_deployed_property_value_of( + resource_logical_id=logical_name_of_resource, + property_name=attribute_name, + ) + return value + def visit_node_intrinsic_function_fn_get_att( self, node_intrinsic_function: NodeIntrinsicFunction ) -> PreprocEntityDelta: # TODO: validate the return value according to the spec. arguments_delta = self.visit(node_intrinsic_function.arguments) - before_argument: Maybe[list[str]] = arguments_delta.before - if isinstance(before_argument, str): - before_argument = before_argument.split(".") - after_argument: Maybe[list[str]] = arguments_delta.after - if isinstance(after_argument, str): - after_argument = after_argument.split(".") + before_arguments: Maybe[str | list[str]] = arguments_delta.before + after_arguments: Maybe[str | list[str]] = arguments_delta.after before = Nothing - if before_argument: - before_logical_name_of_resource = before_argument[0] - before_attribute_name = before_argument[1] - - before_node_resource = self._get_node_resource_for( - resource_name=before_logical_name_of_resource, node_template=self._node_template - ) - before_node_property: Optional[NodeProperty] = self._get_node_property_for( - property_name=before_attribute_name, node_resource=before_node_resource - ) - if before_node_property is not None: - # The property is statically defined in the template and its value can be computed. - before_property_delta = self.visit(before_node_property) - before = before_property_delta.before - else: - # The property is not statically defined and must therefore be available in - # the properties deployed set. - before = self._before_deployed_property_value_of( - resource_logical_id=before_logical_name_of_resource, - property_name=before_attribute_name, - ) + if not is_nothing(before_arguments): + before = self._resolve_attribute(arguments=before_arguments, select_before=True) after = Nothing - if after_argument: - after_logical_name_of_resource = after_argument[0] - after_attribute_name = after_argument[1] - after_node_resource = self._get_node_resource_for( - resource_name=after_logical_name_of_resource, node_template=self._node_template - ) - after_node_property = self._get_node_property_for( - property_name=after_attribute_name, node_resource=after_node_resource - ) - if after_node_property is not None: - # The property is statically defined in the template and its value can be computed. - after_property_delta = self.visit(after_node_property) - after = after_property_delta.after - else: - # The property is not statically defined and must therefore be available in - # the properties deployed set. - after = self._after_deployed_property_value_of( - resource_logical_id=after_logical_name_of_resource, - property_name=after_attribute_name, - ) + if not is_nothing(after_arguments): + after = self._resolve_attribute(arguments=after_arguments, select_before=False) return PreprocEntityDelta(before=before, after=after) @@ -574,7 +568,7 @@ def visit_node_intrinsic_function_fn_sub( arguments_before = arguments_delta.before arguments_after = arguments_delta.after - def _compute_sub(args: str | list[Any], select_before: bool = False) -> str: + def _compute_sub(args: str | list[Any], select_before: bool) -> str: # TODO: add further schema validation. string_template: str sub_parameters: dict @@ -597,12 +591,28 @@ def _compute_sub(args: str | list[Any], select_before: bool = False) -> str: sub_string = string_template template_variable_names = re.findall("\\${([^}]+)}", string_template) for template_variable_name in template_variable_names: + template_variable_value = Nothing + + # Try to resolve the variable name as pseudo parameter. if template_variable_name in _PSEUDO_PARAMETERS: template_variable_value = self._resolve_pseudo_parameter( pseudo_parameter_name=template_variable_name ) + + # Try to resolve the variable name as an entry to the defined parameters. elif template_variable_name in sub_parameters: template_variable_value = sub_parameters[template_variable_name] + + # Try to resolve the variable name as GetAtt. + elif "." in template_variable_name: + try: + template_variable_value = self._resolve_attribute( + arguments=template_variable_name, select_before=select_before + ) + except RuntimeError: + pass + + # Try to resolve the variable name as Ref. else: try: resource_delta = self._resolve_reference(logical_id=template_variable_name) @@ -610,22 +620,45 @@ def _compute_sub(args: str | list[Any], select_before: bool = False) -> str: resource_delta.before if select_before else resource_delta.after ) if isinstance(template_variable_value, PreprocResource): - template_variable_value = template_variable_value.logical_id + template_variable_value = template_variable_value.physical_resource_id except RuntimeError: - raise RuntimeError( - f"Undefined variable name in Fn::Sub string template '{template_variable_name}'" - ) + pass + + if is_nothing(template_variable_value): + raise RuntimeError( + f"Undefined variable name in Fn::Sub string template '{template_variable_name}'" + ) + + if not isinstance(template_variable_value, str): + template_variable_value = str(template_variable_value) + sub_string = sub_string.replace( f"${{{template_variable_name}}}", template_variable_value ) - return sub_string + + # FIXME: the following type reduction is ported from v1; however it appears as though such + # reduction is not performed by the engine, and certainly not at this depth given the + # lack of context. This section should be removed with Fn::Sub always retuning a string + # and the resource providers reviewed. + account_id = self._change_set.account_id + is_another_account_id = sub_string.isdigit() and len(sub_string) == len(account_id) + if sub_string == account_id or is_another_account_id: + result = sub_string + elif sub_string.isdigit(): + result = int(sub_string) + else: + try: + result = float(sub_string) + except ValueError: + result = sub_string + return result before = Nothing if not is_nothing(arguments_before): before = _compute_sub(args=arguments_before, select_before=True) after = Nothing if not is_nothing(arguments_after): - after = _compute_sub(args=arguments_after) + after = _compute_sub(args=arguments_after, select_before=False) return PreprocEntityDelta(before=before, after=after) def visit_node_intrinsic_function_fn_join( @@ -642,7 +675,13 @@ def _compute_join(args: list[Any]) -> str: values: list[Any] = args[1] if not isinstance(values, list): raise RuntimeError(f"Invalid arguments list definition for Fn::Join: '{args}'") - join_result = delimiter.join(map(str, values)) + str_values: list[str] = list() + for value in values: + if value is None: + continue + str_value = str(value) + str_values.append(str_value) + join_result = delimiter.join(str_values) return join_result before = Nothing @@ -728,14 +767,14 @@ def _compute_fn_get_a_zs(region) -> Any: account_id = self._change_set.account_id ec2_client = connect_to(aws_access_key_id=account_id, region_name=region).ec2 try: - describe_availability_zones_result: DescribeAvailabilityZonesResult = ( + get_availability_zones_result: DescribeAvailabilityZonesResult = ( ec2_client.describe_availability_zones() ) except ClientError: raise RuntimeError( "Could not describe zones availability whilst evaluating Fn::GetAZs" ) - availability_zones: AvailabilityZoneList = describe_availability_zones_result[ + availability_zones: AvailabilityZoneList = get_availability_zones_result[ "AvailabilityZones" ] azs = [az["ZoneName"] for az in availability_zones] diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_reference_resolving.py b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_reference_resolving.py index 0884a17eef8d4..b6013fc8dbbcc 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_reference_resolving.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_reference_resolving.py @@ -42,7 +42,6 @@ def test_nested_getatt_ref(deploy_cfn_template, aws_client, attribute_name, snap assert topic_arn in topic_arns -@pytest.mark.skip(reason="CFNV2:Fn::Sub") @markers.aws.validated def test_sub_resolving(deploy_cfn_template, aws_client, snapshot): """ diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_references.py b/tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_references.py index 54fcff1aa16c5..ab44e05cea288 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_references.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_references.py @@ -43,7 +43,6 @@ class TestFnSub: # TODO: add test for list sub without a second argument (i.e. the list) # => Template error: One or more Fn::Sub intrinsic functions don't specify expected arguments. Specify a string as first argument, and an optional second argument to specify a mapping of values to replace in the string - @pytest.mark.skip(reason="CFNV2:Fn::Sub") @markers.aws.validated def test_fn_sub_cases(self, deploy_cfn_template, aws_client, snapshot): ssm_parameter_name = f"test-param-{short_uid()}" @@ -64,7 +63,6 @@ def test_fn_sub_cases(self, deploy_cfn_template, aws_client, snapshot): snapshot.match("outputs", deployment.outputs) - @pytest.mark.skip(reason="CFNV2:Fn::Sub") @markers.aws.validated def test_non_string_parameter_in_sub(self, deploy_cfn_template, aws_client, snapshot): ssm_parameter_name = f"test-param-{short_uid()}" diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py b/tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py index fe0528f437ad6..29678a35be9de 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py @@ -253,7 +253,6 @@ def test_cfn_template_with_short_form_fn_sub(self, deploy_cfn_template): result = stack.outputs["Result"] assert result == "test" - @pytest.mark.skip(reason="CFNV2:Fn::Sub typing or replacement always string") @markers.aws.validated def test_sub_number_type(self, deploy_cfn_template): alarm_name_prefix = "alarm-test-latency-preemptive" @@ -274,7 +273,6 @@ def test_sub_number_type(self, deploy_cfn_template): assert stack.outputs["Threshold"] == threshold assert stack.outputs["Period"] == period - @pytest.mark.skip(reason="CFNV2:Fn::Join") @markers.aws.validated def test_join_no_value_construct(self, deploy_cfn_template, snapshot, aws_client): stack = deploy_cfn_template( From 2128c6a9c5e963d20c8390e1b50d32a20bae0f8f Mon Sep 17 00:00:00 2001 From: Silvio Vasiljevic Date: Fri, 6 Jun 2025 16:17:48 +0200 Subject: [PATCH 10/74] Fix publishing credentials (#12723) --- .github/workflows/aws-main.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/aws-main.yml b/.github/workflows/aws-main.yml index 60561e413a85f..10f367f8bd795 100644 --- a/.github/workflows/aws-main.yml +++ b/.github/workflows/aws-main.yml @@ -219,8 +219,8 @@ jobs: - name: Push ${{ env.PLATFORM_NAME_AMD64 }} Docker Image env: - DOCKER_USERNAME: ${{ secrets.DOCKERHUB_PUSH_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_PUSH_TOKEN }} + DOCKER_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} + DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_PASSWORD }} PLATFORM: ${{ env.PLATFORM_NAME_AMD64 }} run: | # Push to Docker Hub @@ -235,8 +235,8 @@ jobs: - name: Push ${{ env.PLATFORM_NAME_ARM64 }} Docker Image env: - DOCKER_USERNAME: ${{ secrets.DOCKERHUB_PUSH_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_PUSH_TOKEN }} + DOCKER_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} + DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_PASSWORD }} PLATFORM: ${{ env.PLATFORM_NAME_ARM64 }} run: | # Push to Docker Hub @@ -246,8 +246,8 @@ jobs: - name: Push Multi-Arch Manifest env: - DOCKER_USERNAME: ${{ secrets.DOCKERHUB_PUSH_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_PUSH_TOKEN }} + DOCKER_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} + DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_PASSWORD }} run: | # Push to Docker Hub ./bin/docker-helper.sh push-manifests @@ -256,8 +256,8 @@ jobs: - name: Publish dev release env: - DOCKER_USERNAME: ${{ secrets.DOCKERHUB_PUSH_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_PUSH_TOKEN }} + TWINE_USERNAME: ${{ secrets.TWINE_USERNAME }} + TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }} run: | if git describe --exact-match --tags >/dev/null 2>&1; then echo "not publishing a dev release as this is a tagged commit" From 9de2d58113201c722b87158e7352944b6e649836 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Palma <64580864+MEPalma@users.noreply.github.com> Date: Fri, 6 Jun 2025 17:33:22 +0200 Subject: [PATCH 11/74] CloudFormation v2 Engine: Base Support for Fn::And Fn::Or and Condition Bindings (#12706) --- .../engine/v2/change_set_model.py | 18 +++++ .../engine/v2/change_set_model_preproc.py | 67 +++++++++++++++++++ .../engine/v2/change_set_model_visitor.py | 11 +++ .../v2/ported_from_v1/engine/test_mappings.py | 1 - .../ported_from_v1/engine/test_references.py | 1 - .../ported_from_v1/resources/test_events.py | 4 +- .../ported_from_v1/resources/test_kinesis.py | 6 +- .../ported_from_v1/resources/test_lambda.py | 10 ++- .../v2/ported_from_v1/test_template_engine.py | 1 - 9 files changed, 107 insertions(+), 12 deletions(-) diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model.py index 62f54eb8552eb..5a4cae3e042d1 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model.py @@ -415,7 +415,10 @@ def __init__(self, scope: Scope, value: Any): DependsOnKey: Final[str] = "DependsOn" # TODO: expand intrinsic functions set. RefKey: Final[str] = "Ref" +RefConditionKey: Final[str] = "Condition" FnIfKey: Final[str] = "Fn::If" +FnAnd: Final[str] = "Fn::And" +FnOr: Final[str] = "Fn::Or" FnNotKey: Final[str] = "Fn::Not" FnJoinKey: Final[str] = "Fn::Join" FnGetAttKey: Final[str] = "Fn::GetAtt" @@ -429,7 +432,10 @@ def __init__(self, scope: Scope, value: Any): FnBase64: Final[str] = "Fn::Base64" INTRINSIC_FUNCTIONS: Final[set[str]] = { RefKey, + RefConditionKey, FnIfKey, + FnAnd, + FnOr, FnNotKey, FnJoinKey, FnEqualsKey, @@ -593,6 +599,18 @@ def _resolve_intrinsic_function_ref(self, arguments: ChangeSetEntity) -> ChangeT node_resource = self._retrieve_or_visit_resource(resource_name=logical_id) return node_resource.change_type + def _resolve_intrinsic_function_condition(self, arguments: ChangeSetEntity) -> ChangeType: + if arguments.change_type != ChangeType.UNCHANGED: + return arguments.change_type + if not isinstance(arguments, TerminalValue): + return arguments.change_type + + condition_name = arguments.value + node_condition = self._retrieve_condition_if_exists(condition_name=condition_name) + if isinstance(node_condition, NodeCondition): + return node_condition.change_type + raise RuntimeError(f"Undefined condition '{condition_name}'") + def _resolve_intrinsic_function_fn_find_in_map(self, arguments: ChangeSetEntity) -> ChangeType: if arguments.change_type != ChangeType.UNCHANGED: return arguments.change_type diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py index 4b318f262c479..969e695318fa1 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py @@ -472,6 +472,47 @@ def _compute_delta_for_if_statement(args: list[Any]) -> PreprocEntityDelta: after = after_outcome_delta.after return PreprocEntityDelta(before=before, after=after) + def visit_node_intrinsic_function_fn_and( + self, node_intrinsic_function: NodeIntrinsicFunction + ) -> PreprocEntityDelta: + arguments_delta = self.visit(node_intrinsic_function.arguments) + arguments_before = arguments_delta.before + arguments_after = arguments_delta.after + + def _compute_fn_and(args: list[bool]): + result = all(args) + return result + + before = Nothing + if not is_nothing(arguments_before): + before = _compute_fn_and(arguments_before) + + after = Nothing + if not is_nothing(arguments_after): + after = _compute_fn_and(arguments_after) + + return PreprocEntityDelta(before=before, after=after) + + def visit_node_intrinsic_function_fn_or( + self, node_intrinsic_function: NodeIntrinsicFunction + ) -> PreprocEntityDelta: + arguments_delta = self.visit(node_intrinsic_function.arguments) + arguments_before = arguments_delta.before + arguments_after = arguments_delta.after + + def _compute_fn_and(args: list[bool]): + result = any(args) + return result + + before = Nothing + if not is_nothing(arguments_before): + before = _compute_fn_and(arguments_before) + + after = Nothing + if not is_nothing(arguments_after): + after = _compute_fn_and(arguments_after) + return PreprocEntityDelta(before=before, after=after) + def visit_node_intrinsic_function_fn_not( self, node_intrinsic_function: NodeIntrinsicFunction ) -> PreprocEntityDelta: @@ -900,6 +941,32 @@ def visit_node_intrinsic_function_ref( return PreprocEntityDelta(before=before, after=after) + def visit_node_intrinsic_function_condition( + self, node_intrinsic_function: NodeIntrinsicFunction + ) -> PreprocEntityDelta: + arguments_delta = self.visit(node_intrinsic_function.arguments) + before_condition_name = arguments_delta.before + after_condition_name = arguments_delta.after + + def _delta_of_condition(name: str) -> PreprocEntityDelta: + node_condition = self._get_node_condition_if_exists(condition_name=name) + if is_nothing(node_condition): + raise RuntimeError(f"Undefined condition '{name}'") + delta = self.visit(node_condition) + return delta + + before = Nothing + if not is_nothing(before_condition_name): + before_delta = _delta_of_condition(before_condition_name) + before = before_delta.before + + after = Nothing + if not is_nothing(after_condition_name): + after_delta = _delta_of_condition(after_condition_name) + after = after_delta.after + + return PreprocEntityDelta(before=before, after=after) + def visit_node_array(self, node_array: NodeArray) -> PreprocEntityDelta: node_change_type = node_array.change_type before = list() if node_change_type != ChangeType.CREATED else Nothing diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_visitor.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_visitor.py index fb982d8301f8d..732141270fb65 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_visitor.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_visitor.py @@ -144,6 +144,12 @@ def visit_node_intrinsic_function_fn_sub(self, node_intrinsic_function: NodeIntr def visit_node_intrinsic_function_fn_if(self, node_intrinsic_function: NodeIntrinsicFunction): self.visit_children(node_intrinsic_function) + def visit_node_intrinsic_function_fn_and(self, node_intrinsic_function: NodeIntrinsicFunction): + self.visit_children(node_intrinsic_function) + + def visit_node_intrinsic_function_fn_or(self, node_intrinsic_function: NodeIntrinsicFunction): + self.visit_children(node_intrinsic_function) + def visit_node_intrinsic_function_fn_not(self, node_intrinsic_function: NodeIntrinsicFunction): self.visit_children(node_intrinsic_function) @@ -158,6 +164,11 @@ def visit_node_intrinsic_function_fn_find_in_map( def visit_node_intrinsic_function_ref(self, node_intrinsic_function: NodeIntrinsicFunction): self.visit_children(node_intrinsic_function) + def visit_node_intrinsic_function_condition( + self, node_intrinsic_function: NodeIntrinsicFunction + ): + self.visit_children(node_intrinsic_function) + def visit_node_divergence(self, node_divergence: NodeDivergence): self.visit_children(node_divergence) diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_mappings.py b/tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_mappings.py index c327159aa958d..de1b0029fb703 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_mappings.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_mappings.py @@ -249,7 +249,6 @@ def test_mapping_ref_map_key(self, deploy_cfn_template, aws_client, map_key, sho aws_client.sns.get_topic_attributes(TopicArn=topic_arn) - # @pytest.mark.skip(reason="CFNV2:Mappings") @markers.aws.validated def test_aws_refs_in_mappings(self, deploy_cfn_template, account_id): """ diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_references.py b/tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_references.py index ab44e05cea288..d89ae634ae003 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_references.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_references.py @@ -111,7 +111,6 @@ def test_useful_error_when_invalid_ref(deploy_cfn_template, snapshot): snapshot.match("validation_error", exc_info.value.response) -@pytest.mark.skip(reason="CFNV2:Other") @markers.aws.validated def test_resolve_transitive_placeholders_in_strings(deploy_cfn_template, aws_client, snapshot): queue_name = f"q-{short_uid()}" diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_events.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_events.py index d963a283edc1b..75c648f00903c 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_events.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_events.py @@ -18,7 +18,9 @@ ) -@pytest.mark.skip(reason="CFNV2:ReferenceDotSyntax") +@pytest.mark.skip( + reason="CFNV2:Destroy resource name conflict with another test case resource in this suite" +) @markers.aws.validated def test_cfn_event_api_destination_resource(deploy_cfn_template, region_name, aws_client): def _assert(expected_len): diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_kinesis.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_kinesis.py index ba68025561b77..ec4fb4f2f882a 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_kinesis.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_kinesis.py @@ -16,7 +16,7 @@ ) -@pytest.mark.skip(reason="CFNV2:ReferenceDotSyntax") +@pytest.mark.skip(reason="CFNV2:DescribeStacks") @markers.aws.validated @markers.snapshot.skip_snapshot_verify(paths=["$..StreamDescription.StreamModeDetails"]) def test_stream_creation(deploy_cfn_template, snapshot, aws_client): @@ -169,7 +169,9 @@ def test_dynamodb_stream_response_with_cf(deploy_cfn_template, aws_client, snaps snapshot.add_transformer(snapshot.transform.key_value("TableName")) -@pytest.mark.skip(reason="CFNV2:ReferenceDotSyntax") +@pytest.mark.skip( + reason="CFNV2:Other resource provider returns NULL physical resource id for StreamConsumer thus later references to this resource fail to compute" +) @markers.aws.validated def test_kinesis_stream_consumer_creations(deploy_cfn_template, aws_client): consumer_name = f"{short_uid()}" diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py index c196f5988cba9..1ef4b43dca830 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py @@ -25,7 +25,7 @@ ) -@pytest.mark.skip(reason="CFNV2:ReferenceDotSyntax") +@pytest.mark.skip(reason="CFNV2:Transform") @markers.aws.validated def test_lambda_w_dynamodb_event_filter(deploy_cfn_template, aws_client): function_name = f"test-fn-{short_uid()}" @@ -58,7 +58,7 @@ def _assert_single_lambda_call(): retry(_assert_single_lambda_call, retries=30) -@pytest.mark.skip(reason="CFNV2:ReferenceDotSyntax") +@pytest.mark.skip(reason="CFNV2:Transform") @markers.snapshot.skip_snapshot_verify( [ # TODO: Fix flaky ESM state mismatch upon update in LocalStack (expected Enabled, actual Disabled) @@ -130,7 +130,6 @@ def test_update_lambda_function(s3_create_bucket, deploy_cfn_template, aws_clien assert response["Configuration"]["Environment"]["Variables"]["TEST"] == "UPDATED" -# @pytest.mark.skip(reason="CFNV2:Other") @markers.aws.validated def test_update_lambda_function_name(s3_create_bucket, deploy_cfn_template, aws_client): function_name_1 = f"lambda-{short_uid()}" @@ -1293,13 +1292,12 @@ def wait_for_logs(): wait_until(wait_for_logs) -@pytest.mark.skip(reason="CFNV2:Other") @markers.aws.validated def test_python_lambda_code_deployed_via_s3(deploy_cfn_template, aws_client, s3_bucket): bucket_key = "handler.zip" zip_file = create_lambda_archive( load_file( - os.path.join(os.path.dirname(__file__), "../../lambda_/functions/lambda_echo.py") + os.path.join(os.path.dirname(__file__), "../../../../lambda_/functions/lambda_echo.py") ), get_content=True, runtime=Runtime.python3_12, @@ -1343,7 +1341,7 @@ def test_lambda_cfn_dead_letter_config_async_invocation( zip_file = create_lambda_archive( load_file( os.path.join( - os.path.dirname(__file__), "../../lambda_/functions/lambda_handler_error.py" + os.path.dirname(__file__), "../../../../lambda_/functions/lambda_handler_error.py" ) ), get_content=True, diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py b/tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py index 29678a35be9de..966bc541b7050 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py @@ -65,7 +65,6 @@ def test_implicit_type_conversion(self, deploy_cfn_template, snapshot, aws_clien class TestIntrinsicFunctions: - @pytest.mark.skip(reason="CFNV2:Fn::And CFNV2:Fn::Or") @pytest.mark.parametrize( ("intrinsic_fn", "parameter_1", "parameter_2", "expected_bucket_created"), [ From 36f5b6d51febb6da8f15d97df76ac69271afc8ba Mon Sep 17 00:00:00 2001 From: Silvio Vasiljevic Date: Fri, 6 Jun 2025 17:46:13 +0200 Subject: [PATCH 12/74] Re-create venv for dev release publish (#12725) --- .github/workflows/aws-main.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/aws-main.yml b/.github/workflows/aws-main.yml index 10f367f8bd795..08b1e6e72644d 100644 --- a/.github/workflows/aws-main.yml +++ b/.github/workflows/aws-main.yml @@ -262,8 +262,7 @@ jobs: if git describe --exact-match --tags >/dev/null 2>&1; then echo "not publishing a dev release as this is a tagged commit" else - source .venv/bin/activate - make publish || echo "dev release failed (maybe it is already published)" + make install-basic publish || echo "dev release failed (maybe it is already published)" fi push-to-tinybird: From ed6c94a1b6d2042aa39fa6a29d4a1a9f9a3a5020 Mon Sep 17 00:00:00 2001 From: Ben Simon Hartung <42031100+bentsku@users.noreply.github.com> Date: Fri, 6 Jun 2025 22:53:53 +0200 Subject: [PATCH 13/74] fix dependencies installation for dev release publish (#12726) Co-authored-by: Mathieu Cloutier <79954947+cloutierMat@users.noreply.github.com> --- .github/workflows/aws-main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/aws-main.yml b/.github/workflows/aws-main.yml index 08b1e6e72644d..4a20111727b0f 100644 --- a/.github/workflows/aws-main.yml +++ b/.github/workflows/aws-main.yml @@ -262,7 +262,7 @@ jobs: if git describe --exact-match --tags >/dev/null 2>&1; then echo "not publishing a dev release as this is a tagged commit" else - make install-basic publish || echo "dev release failed (maybe it is already published)" + make install-runtime publish || echo "dev release failed (maybe it is already published)" fi push-to-tinybird: From 6487dbf5a219915ea953f3f67673f22d76c68bb7 Mon Sep 17 00:00:00 2001 From: Mathieu Cloutier <79954947+cloutierMat@users.noreply.github.com> Date: Fri, 6 Jun 2025 16:28:17 -0600 Subject: [PATCH 14/74] Apigw add tests fot vtl bracket assignment (#12727) Co-authored-by: Benjamin Simon --- .../test_apigateway_integrations.py | 77 +++++++++++++++++++ ...test_apigateway_integrations.snapshot.json | 13 ++++ ...st_apigateway_integrations.validation.json | 3 + 3 files changed, 93 insertions(+) diff --git a/tests/aws/services/apigateway/test_apigateway_integrations.py b/tests/aws/services/apigateway/test_apigateway_integrations.py index d3e3198a2d86a..92c12a023494b 100644 --- a/tests/aws/services/apigateway/test_apigateway_integrations.py +++ b/tests/aws/services/apigateway/test_apigateway_integrations.py @@ -806,6 +806,83 @@ def invoke_api(url) -> requests.Response: ) +@markers.aws.validated +def test_integration_mock_with_vtl_map_assignation(create_rest_apigw, aws_client, snapshot): + api_id, _, root_id = create_rest_apigw( + name=f"test-api-{short_uid()}", + description="this is my api", + ) + + aws_client.apigateway.put_method( + restApiId=api_id, + resourceId=root_id, + httpMethod="GET", + authorizationType="NONE", + ) + + aws_client.apigateway.put_method_response( + restApiId=api_id, resourceId=root_id, httpMethod="GET", statusCode="200" + ) + + request_template = textwrap.dedent(""" + #set($paramName = "foo") + #set($context.requestOverride.querystring[$paramName] = "bar") + #set($paramPutName = "putfoo") + $context.requestOverride.querystring.put($paramPutName, "putBar") + #set($context["requestOverride"].querystring["nestedfoo"] = "nestedFoo") + { + "statusCode": 200 + } + """) + + aws_client.apigateway.put_integration( + restApiId=api_id, + resourceId=root_id, + httpMethod="GET", + integrationHttpMethod="POST", + type="MOCK", + requestParameters={}, + requestTemplates={"application/json": request_template}, + ) + response_template = textwrap.dedent(""" + #set($value = $context.requestOverride.querystring["foo"]) + #set($value2 = $context.requestOverride.querystring["putfoo"]) + #set($value3 = $context.requestOverride.querystring["nestedfoo"]) + { + "value": "$value", + "value2": "$value2", + "value3": "$value3" + } + """) + + aws_client.apigateway.put_integration_response( + restApiId=api_id, + resourceId=root_id, + httpMethod="GET", + statusCode="200", + selectionPattern="2\\d{2}", + responseTemplates={"application/json": response_template}, + ) + stage_name = "dev" + aws_client.apigateway.create_deployment(restApiId=api_id, stageName=stage_name) + + invocation_url = api_invoke_url(api_id=api_id, stage=stage_name) + + def invoke_api(url) -> requests.Response: + _response = requests.get(url, verify=False) + assert _response.status_code == 200 + return _response + + response_data = retry(invoke_api, sleep=2, retries=10, url=invocation_url) + snapshot.match( + "response", + { + "body": response_data.json(), + "status_code": response_data.status_code, + }, + ) + + @pytest.fixture def default_vpc(aws_client): vpcs = aws_client.ec2.describe_vpcs() diff --git a/tests/aws/services/apigateway/test_apigateway_integrations.snapshot.json b/tests/aws/services/apigateway/test_apigateway_integrations.snapshot.json index d0e0d59455823..3b4a1be1aebdf 100644 --- a/tests/aws/services/apigateway/test_apigateway_integrations.snapshot.json +++ b/tests/aws/services/apigateway/test_apigateway_integrations.snapshot.json @@ -1100,5 +1100,18 @@ "status_code": 444 } } + }, + "tests/aws/services/apigateway/test_apigateway_integrations.py::test_integration_mock_with_vtl_map_assignation": { + "recorded-date": "29-05-2025, 15:49:45", + "recorded-content": { + "response": { + "body": { + "value": "bar", + "value2": "putBar", + "value3": "nestedFoo" + }, + "status_code": 200 + } + } } } diff --git a/tests/aws/services/apigateway/test_apigateway_integrations.validation.json b/tests/aws/services/apigateway/test_apigateway_integrations.validation.json index 883298cf6153e..93c003bd54660 100644 --- a/tests/aws/services/apigateway/test_apigateway_integrations.validation.json +++ b/tests/aws/services/apigateway/test_apigateway_integrations.validation.json @@ -26,6 +26,9 @@ "tests/aws/services/apigateway/test_apigateway_integrations.py::test_integration_mock_with_response_override_in_request_template[True]": { "last_validated_date": "2025-05-16T10:22:21+00:00" }, + "tests/aws/services/apigateway/test_apigateway_integrations.py::test_integration_mock_with_vtl_map_assignation": { + "last_validated_date": "2025-05-29T15:49:45+00:00" + }, "tests/aws/services/apigateway/test_apigateway_integrations.py::test_put_integration_response_with_response_template": { "last_validated_date": "2024-05-30T16:15:58+00:00" }, From 3adead260476eecc39419a49c48a283fd3613449 Mon Sep 17 00:00:00 2001 From: Anastasia Dusak <61540676+k-a-il@users.noreply.github.com> Date: Mon, 9 Jun 2025 08:39:52 +0200 Subject: [PATCH 15/74] CircleCI to GH Actions:updated docs references to GH Actions (#12666) Co-authored-by: Silvio Vasiljevic --- DOCKER.md | 2 +- README.md | 2 +- .../multi-account-region-testing/README.md | 29 ++++++------------ .../randomize-aws-credentials.png | Bin 30971 -> 0 bytes 4 files changed, 11 insertions(+), 22 deletions(-) delete mode 100644 docs/testing/multi-account-region-testing/randomize-aws-credentials.png diff --git a/DOCKER.md b/DOCKER.md index a66c8d9baa367..9d102b1a0e942 100644 --- a/DOCKER.md +++ b/DOCKER.md @@ -3,7 +3,7 @@

- CircleCI + GitHub Actions Coverage Status PyPI Version Docker Pulls diff --git a/README.md b/README.md index 00916b05e0891..a2e28869759a7 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@

- CircleCI + GitHub Actions Coverage Status PyPI Version Docker Pulls diff --git a/docs/testing/multi-account-region-testing/README.md b/docs/testing/multi-account-region-testing/README.md index dd153cbe3b30a..323643cbc8a97 100644 --- a/docs/testing/multi-account-region-testing/README.md +++ b/docs/testing/multi-account-region-testing/README.md @@ -4,11 +4,11 @@ LocalStack has multi-account and multi-region support. This document contains so ## Overview -For cross-account inter-service access, specify a role with which permissions the source service makes a request to the target service to access another service's resource. +For cross-account inter-service access, specify a role with which permissions the source service makes a request to the target service to access another service's resource. This role should be in the source account. When writing an AWS validated test case, you need to properly configure IAM roles. -For example: +For example: The test case [`test_apigateway_with_step_function_integration`](https://github.com/localstack/localstack/blob/628b96b44a4fc63d880a4c1238a4f15f5803a3f2/tests/aws/services/apigateway/test_apigateway_basic.py#L999) specifies a [role](https://github.com/localstack/localstack/blob/628b96b44a4fc63d880a4c1238a4f15f5803a3f2/tests/aws/services/apigateway/test_apigateway_basic.py#L1029-L1034) which has permissions to access the target step function account. ```python role_arn = create_iam_role_with_policy( @@ -28,30 +28,20 @@ connect_to.with_assumed_role( region_name=region_name, ).lambda_ ``` - -When there is no role specified, you should use the source arn conceptually if cross-account is allowed. -This can be seen in a case where `account_id` was added [added](https://github.com/localstack/localstack/blob/ae31f63bb6d8254edc0c85a66e3c36cd0c7dc7b0/localstack/utils/aws/message_forwarding.py#L42) to [send events to the target](https://github.com/localstack/localstack/blob/ae31f63bb6d8254edc0c85a66e3c36cd0c7dc7b0/localstack/utils/aws/message_forwarding.py#L31) service like SQS, SNS, Lambda, etc. -Always refer to the official AWS documentation and investigate how the the services communicate with each other. +When there is no role specified, you should use the source arn conceptually if cross-account is allowed. +This can be seen in a case where `account_id` was [added](https://github.com/localstack/localstack/blob/ae31f63bb6d8254edc0c85a66e3c36cd0c7dc7b0/localstack/utils/aws/message_forwarding.py#L42) to [send events to the target](https://github.com/localstack/localstack/blob/ae31f63bb6d8254edc0c85a66e3c36cd0c7dc7b0/localstack/utils/aws/message_forwarding.py#L31) service like SQS, SNS, Lambda, etc. + +Always refer to the official AWS documentation and investigate how the the services communicate with each other. For example, here are the [AWS Firehose docs](https://docs.aws.amazon.com/firehose/latest/dev/controlling-access.html#cross-account-delivery-s3) explaining Firehose and S3 integration. ## Test changes in CI with random credentials -We regularly run the test suite in CircleCI to check the multi-account and multi-region feature compatibility. -There is a [scheduled CircleCI workflow](https://github.com/localstack/localstack/blob/master/.circleci/config.yml) which executes the tests with randomized account ID and region at 01:00 UTC daily. - -If you have permissions, this workflow can be manually triggered on CircleCI as follows: -1. Go to the [LocalStack project on CircleCI](https://app.circleci.com/pipelines/github/localstack/localstack). -1. Select a branch for which you want to trigger the workflow from the filters section. - - For PRs coming from forks, you can select the branch by using the PR number like this: `pull/` -1. Click on the **Trigger Pipeline** button on the right and use the following values: - 1. Set **Parameter type** to `boolean` - 1. Set **Name** to `randomize-aws-credentials` - 1. Set **Value** to `true` -1. Click the **Trigger Pipeline** button to commence the workflow. +We regularly run the test suite on GitHub Actions to verify compatibility with multi-account and multi-region features. -![CircleCI Trigger Pipeline](./randomize-aws-credentials.png) +A [scheduled GitHub Actions workflow](https://github.com/localstack/localstack/actions/workflows/aws-tests-mamr.yml) runs on working days at 01:00 UTC, executing the tests with randomized account IDs and regions. +If you have the necessary permissions, you can also manually trigger the [workflow](https://github.com/localstack/localstack/actions/workflows/aws-tests-mamr.yml) directly from GitHub. ## Test changes locally with random credentials @@ -61,6 +51,5 @@ To test changes locally for multi-account and multi-region compatibility, set th - `TEST_AWS_ACCESS_KEY_ID` (Any value except `000000000000`) - `TEST_AWS_REGION` (Any value except `us-east-1`) -You may also opt to create a commit (for example: [`da3f8d5`](https://github.com/localstack/localstack/pull/9751/commits/da3f8d5f2328adb7c5c025722994fea4433c08ba)) to test the pipeline for non-default credentials against your changes. Note that within all tests you must use `account_id`, `secondary_account_id`, `region_name`, `secondary_region_name` fixtures. Importing and using `localstack.constants.TEST_` values is not advised. diff --git a/docs/testing/multi-account-region-testing/randomize-aws-credentials.png b/docs/testing/multi-account-region-testing/randomize-aws-credentials.png deleted file mode 100644 index 9f57fc84b945a7a08101ca41af124da28b020fb0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30971 zcmdqJc{r7A_%^yUC`6PgL!wARNJW`qNui?5WQc^4AtG}!tWZ+Pkc5yilpz(OBBW5p z2AM*Xc_`C9@Avn8-?9JOf9`$kj`uwhYgx~5-`90c*Kj=flPqDHN7BOnnE^O0{JM(k~EYsN;K z@2#c1*s?a|gnDJjAzhVxdXCkry|0BSI-F+^*(=@@OWV+7q@$aXlG471r(iZVDTRBF z^xX&St8)&^j|#jz@Mqnb0yg1+NricZ_oZiT&t7W(_S9qaYxLseM`fGSr&nyc&0 z+d4wJ`c0z3=`tLygF> zxp8azSlp1EY;0D&)z{NFKRi5iy(<0ay)h@|Tb`rplPT)qK|(|B7mSUKn~!pg_q=6t z`}LXO(xpo@8tvv@!^0PUzTYunw8Lrd-o0aEW3S#tZFTwcRemT-V5+yseb}J=%a?~| z>hC`DUoJ2Fdv$DT=#$K%h0KU#NNy+7PkdqZrPwjQ zpdc#!rN?NQo!CT5P zc;;GEZ0_jjcy{SG4-5bPZH`NAxVkRuC(n6J4YEy4Or%_ox>-e&M7v z<{0mOQ&XcQqdALcq5aUh8Mn+>1JlK+TBh6`AYuB!2eH{6hmC^RcN`b_t^rO6@?2MnY^qJZo zpHiFs^UdnqIVJ%C0m`c~@7W|BQJq|qJ*!r)KGI5m;rq*L$!eihZ{MzN$u=aHDc^1A zM1rEX0r#35@gI7^A|gUkQmjP|ErIv%^Y6bjLR-0p#S#mv%B$qUw_A@xuq;!KKTygr zEs@MJ%wt)_bNaqYXQJ2r$16H3|I^miY#bb`ckSAxmuJq;!oo7xlFcP)_H0X^*0*OaD=mD+ zSM%(<5b>)e`*lkT#{=IP0eb9ELRz;-&Mgr^Lys^m-c+Cm7T?o;XHdB zk_>W9*0QivV;Mevl4dwDImyP$8-84QksY6q|MaO^wm~i{8{3tEj}NpyX-(}f)w(Nw z(9&{?%n_2XJKJM?+H_QKHJtqG{%R8g|Z`GOE-GYj8s+yGj(<7+;r)!?jCGfJu)I?^Nuw( zJ|5SJjd$<)SFc0YOP_C-+9o2xxg$(K(Q6gzN8!0Pme$r*Y_`W4i$_x*J=!WPyjsPI z?eU1aWH_pu^}CybxB+Vl3k&lveA_Q>TD-2bw3K_d?K*5jW;Hc6%B$(&Hu7teMS1qS ziH`jK9hHy}fs)^ia?P#mrx3sA+>FV*&MmU7edlNFKBY6G1{S#XYkn>FC4KMpM1Q^X z*$;ezvt*w!{=6$;iUOe%`{8F_?d`eVNM)&uKec`4f0tD47p`q+hz<#J$L&!-TfEM* zNA>jS(@`k~$B(baKUPpaXB)034J@x>DGY5TweS7Y@Vr* zJ>$DTfXk4&KZRaojRCG+DEp#rat#wGCgte$BV8VM*SX7uOVZ#PJLpn;1NfF~Ni}F>Jbv&|bpV~HT==?V|v{FFefzWOHfq{Xo3JQFbEiv^4 zC~dfDD@0#DJF20v=3Hw|Wzo4d=Y=^JUA9&1GkuO-<@~thTyMLmmoDwSb?cTC+Fy6* zK3r$|ix)2*v8`RPVg{J-&Nr=o)_Bjr;F>@#1T&7b{E40D5MgwZj=-%1cY-`S|$q z9a_YiyeMRWhprbuQ&Fc44GwM*5jiw<@CI!RozcqJ)bvHW%g^S;T}O=tl+jj~9h(D< z<+rJMx%{Zmm-BD5j@O_5)uP2C))ci>Bd9_nf?Kz5xc3&LUcZ-2+&b)*(u{_8@7CV9 zaU+GB!l&%VH#9Uv3HbBv1=H%Mw;Y@-U6g-z_w=0TS<2Y$`_IklWu9ts05I3{OTWXy zxpu9fXlrZNeZHMl*W7%9r|Q*}mBAIq6BQVeoZr=;NKtUhvdtUUuzwgyUU0A|O7i7( z>?~xHc=7DnS~V^i8JVDG6SsFz)@_oZ>ajbVJNFQKgu)ogd`EWkKX*m%nRRF&p`oE` zu&R>s@+@rZXnOs1(ZNn?s939+n3$~meqS8;Q2F|`n&-Ou=ZodO^F4nj2Wa8p8{b9? zq}=J+AZl-Ke=V%Xd-hKC?jgrGLY_ zx}EGJP3`Xt1MnS`j0xw}a{k@9r+f6>yTjB&hq4O86g|gOc)WJW?%C5lFc7+Fw{6m) z>paar+YDY@a_n|Gb9~;ye^GdW$Cy3Ky``PzY&1R~jg8$2qYtNgi`> z$dc6yN>5Mk{N4;Mv31`*t_v3~y!-eu^xi$*4I4K$Jw5wTNX_*Q>6g9vii(OZBkj_w zR;~K+v*BKf@2=sQquSby4>i{37(b=2tgKWu1Go3kkxf2t!o&8Gl1^U9%W9Qot+Nhw*4jS zb(u?dZr#4Et|oK`3;yc-?C9&RE(_Wor|*3C_BmCfAX(bjtn%>iNdE0!+?A}hW?`a! zSNoGQ;jFv&>6H!l_U$URG&sTe0i}A^Y~ZGhB=x7iBGzu&wCRjkU{PUVka>OEj^}q2Jt6BO=zBmHTXZ;P)?cY@4L0s0#WX?o)8e%-e9Tx!)ySV?Qcap8xio zEHH3IlbmS6shzEGmRnp8@hIaOpjyD`?vKJ3H&-BNmh5^E-IDx=JseWoKu%M0;y5 zI>&Y1(NX$L9eWe&I-DD-OZUJ7f6k)l;^nuxiuHccb_{lWe9F)KwEq-g+> zdUNVBLRF}W`kz*to0~s#?PtWFe9!UIP2w9sa}FOnW>72n8Hdl!&HV$fYkzunJ+7ij z-`S+I4e_frG-^)!2lT7mzH?`l(1z+-P8?6ilQXI>p2Y6nw@(9YlE9qQw6ty@xm_}9 z)ufO3k4czRX$705LcZws^ zilVDuy$bMWzA0U86s#lI)nHQOuzJm!HL0noKYHGV6C8}UZ@FEY4?&?4OA3Kq z2?=})Q=g7|g3rAyD;o!5qH1V_`#B!1ee-4&5Jok~*g+}*Ec7gVG!&+8Ai(yQmv`R~ zP-bCfW(FN)vT*m$Kw}TN@a=i>*^h~h&COLGm6yd8%&~9>+Y27v7o=8 zaFcDASB>uIJTqbpBABlI+BV|)buICDx)x^O+w0)hYufK#U2eWcW`RW*~BSs6hIgQ3N9$c8+3pD z))hQ^&l{x<6e@^Yl=GoLzX@jIx|x_L8Gn&iR3UN4$@Dv!mh_C?_l_Pts^0s;cu4!` z(b5>`I7Y$Ag3NmC?!P`)E-lWpadWT5aSsj-zN)OG>+bGOdBD)x$f~?bP*4z6j!8jL z(aO$lt*@`ItYas8K|w*v-#hxdF5IrQG0L~3Blv+3U(n^o*47X+NsalL-vw5$>EGYm zcl_P*O)QVCGBO+f{Q1*}a$Ha#4epSS)+hA(7=_>(Ik!PpujyaG;Bjgwnj#`1cFm~_ zKR-T*(sQ050f3^Agmt;4bQNJHMPW1^kGf zvW|D}x=-mxH*S}T0?TrZytsp0EK5jT2Hkq?i9airmv|wxs9m`5STr#z>Ix2yB06&B z?$TT>7G?hFw~V^$L=!4ijHM39%j?Gm#+4}nWg8h8Wi0;vz09+61}v z4}5&;MO9-XD|qlLkp1A7RG{(w{w4dpsWEr=z8&D%hFm+^_2g+ zjP;;q7xatlMzOvZ2_Yf$U`^v+oGJ*AiSVlyPRNTZ@LtSw8&u=EFOQQ%B3D#raDVM+Zhc%H9cJw*d85l z?Yec;JoB=!sfeLpzfOO9?%ob2w)etUT9@BEbL3{lK(tS+Vj9+A%n(;20qWI8ZzmqS zWJQg^zY5xPt#+-l`A=~iIo19DmI^te3y2dFLJr9Fwfb)Bk*md*CvBg-c=5Wklc!?o zUv?ppM|W~T_}aYh0v|i0dS(fVgB9ux(3I!DsZ6(xff*U1g?3FVz_FXtJ$|CAXBg&f zK5^ni>QN{0?c3Kt>_a15MNt5HWag25g*zY|x4d~s>By|{^M$>2y$XIAW~WX`J9f(2 z&*kQrm2SX0patC7+l{q=k3l1eWWDI>DmKBV_x-~I<-8}C1R=u|UifChLqGPbJbIs@ zq2W4iDGFBHo%Hf3vZk%8BM#mcIhv0R`>eF|$VpZnp0K@+orhlwMC|LRm>u_r>N)b; z?#Rl~&ZL7^8_RvYtu8~WuxoqF4>T4Wo15!c;M95o;>p;=L|{nueD<`2xH!ryGfIm6 zrvneOvzeTnoId9mpX{85P0UWP)B40Mvq;g+mr? z&)v^W4YwWVIrO`;NWK2-hlI*5|7B*%;Uh<`T)lcVyebqyU=t0tcjE+VM zYuzPELG$M}SI7;7fdk1&?b#E(_v!M@Ckg{~^`V8kA_^uZzlYmG6MO~~Uk?(o$KkVR z!9bR5d3pKR^mKGc*A7!tQ$p@}{2l=*k1x)4X}w;~nrMFnQ5Zb_ZvAC(rv9Y`E`6+N z?T?kup2^7_IItB$F#5|{CZ^lzlz_pjw&mPyHS(nX{rgn`9_CWZ zF&`DNiuO%bx=-I%xV*v7&kv&ML8t-F|EBDdB|s+$gzI?qIgb579cR#;V54({<^%u(XNU}fFiYI zogZj(&-@nmvRMEBT*M~lRx_e|~ge*Jbr?!>fzAYBHQY_Iz zu$)vu|GLqrL1-Br>jYJ>p@Q*prTLNF(R(aPU3%&1*Ktz-KR!P`#e4AJK_Dx7or!|1 z=U&rd__X5l9f9>RyKo4WV9cuX_?nHAlU_qZ1NY3jIrYf9h6aw#$;rv_ZysIvWd7pf z;=%7_2cU%RD2$0gXC~C!y5`2%>}(CXdA&laEqPaMZ6&mh)T4nAVc$Pc7QkLr!I2WJ zwdt=zSGgjP@(Kzr2Z7U#1_@}&DduHf`9($QkU$CCPL`0BWrqM)6Dw_PdG6fKg$K+3 zhV$?-p}-Afi$h{c)>*?CdgT5610|m)S5umrnjm&;!kz5y?Y)ZTL+hlo#D|jG>(H8W zZL^}+50ubm_NeX06D@IDGW4@K`S|$>eC_M+XZSrcGZVY}?2S5}U;!gQw4gI61=xeu zeea?&PQBO*{YU!pgbmp^5Ye44T?)B+btV1!&BSxK)_QNhyBPTWskYZ)1da%^U1MmUXv z-vYPF(8toLDYpnd`3)fPM0|zFHV%xPb>X>@aM>|dw*78{l;g*bck|(sUqhM3ecb78 zfu7T~#!&WntQ4K^zo~;%>M9~nHa0d2Iq7IhOH0Qp`R@NWJsb*^`894U90B#yr&DD0 zVPl+p^Y*QvkkATjSG-;Y8x^9Y&`}PEYeFc&!))(P4sKI4K=R@?XOw*J1GstVdUEjE|k}(^O-kG zO7`sj4cd!dt_cTO$=cdMMMXu8<&fLZ zC)Ox0j9slW$pe!=4aFTAzlx2`wk*BO6MbqL#;(N|zJ)b5>JSkU>!gbJ8#bQ$WpXZU z7XH@(5w7*9bT4ZRe7H}5Do7REPJ^5P006I5(wT z#?2cyUIl~nSzeqS?0CA}AkSPvENlC*1RD7*gi)YM5s?R=yc_z3>M<86q#;01VHb9p zzr2}FCn`=$D{UU=z!~Fp45<8WBkgR&6<9nTeJEMy)rSv{->p&B$2L>PIgup?L#L{` zn#k6ik~5~y-F9Fltxg(~e+Esdr9~amne)`3E*9@raq)Fn?(DvHs{)v~B)3RNFypTv zfO*&i0XUGV+FAzSRbZOE;6cITy*1&jrcZ2+WDe{^2eI&-=70@F#Bl6x>&B#mDeEb< zwY9YC*WZ#0m!B_1d?2(Hj?VC>@L*u(ST&`nL*TCr`O* zMPBsbDl7_CR@Q*kOq`ZgK@4+HW5!W1no3Jyj_r5Jx~fMxLtZwcG>Al5ISrubU($Pq!Il(^kzZ-J9EDmnj9 zarjc4o3Blkg=Yo|7%iHf`Z5w)rQoI6Kc}8Nd6I&~bB#uWCvw=eGy(F+HJTk1>As<% z9eo?wARb=tbCnks7G`79wX+j#$+LI>?=>i)z`EuH_$`e#h|}2?Q*Zw^jN`3jOn*B# zmKG-`r`z-|eZlRLk~dJ@iNUR^J%mHX3x{w6snn_d7>g74_By_+stVk!UC%g%h*Au0-@ zwU0-^GruwM!Gq%ud?pxtm;Me=r+&GVyYzhcE9IX(ik@z8%`w3O!Cp>z(*$O zp#sjc&{+F=d$)$QWS$H~tIbSGQlUY&&}<*Yp1h4$R!im{{@+;uteNCRh?#;A1v{U) zJY+pt1Tt}}zCZ2zrP1#aeFygM=d_Qh@0WG@t`MEOVS2Rd0Xp>|YTjmxe(TKCm!sI8 zx(T!l6zb1FXZEo)8m{*d$(T>r$H7Ji57PaepTC`#m&a;ae0~#drd6q2-SWzofiCoA z@-kfN-~^P*lji1$H*ryy(cD8tm6a`M5~jrw=s3Z#&nKsGnVyuC?3$<`;@z)rFZQu< zd@p(W^y#2sqtmw5-rPRW-w;|ksE@kWR{hMMD}$}G>3-Bj z@1!t#8=90{U=~s(^vu=uM|bxX?BVe83B5;!*2<8t(1Zyr>sErVxlTyzQhFeoE^-A% zgPRoKR3Ey*$DpO9mAqyIEn#eC#=v-Z5h$bi<_};!NGnkp+c_y&2DxGjr|u?TrS$?3 zz%;u$Hix!e1*KVbfnLNWW zU!&tGp&H7<4?pF`2JgHy+F`eZtUEOwaMlGyZr8H1vj;&jYV*tKca?X8-_{SSgDzn3 zvLjqao*FDU=3vz;=v&EvgwD>+uh4VH7XDt;&GWV&7{;Z1S63${qvV5D2$SM&KHebl z{F#wEuW;0iWigzwxVX4y9;1n(k8ePewd(*yBPKyjeRJ~$NUUPU>K3z5A;t!qwh|Nl zbpYK;OKa<`U+>J@fM!2`)rL33$H%7(n}E*JQ>qsE6}{M(mX@GzaJs&H`BJCILBD%B zRSsJ&7(Oj-TX1Y<<_`Qy!hIMA_* z=UX@e6SX|*q-v)G9@6*n+K=~Hq2q_uFE6K5V(rAn#?m^?L(9vR+}z!@e9gOH^5df0 zeJPe8J}u;vElNt|@8r6BL_fw%lx~;M&eqEegbqPF?WA@2!l&kD0;TPJz3Z&Su1)xW z?O36|rC5olDelu!rGmdhC^jhgs9S1g{%hF>hI7HNKHwJUC7sTke-2-0?xRPBKie3f z)ey`Djp{7~5R2i(AZY^^-_Pn#wM7U(ZF=G1WMgAvS$|i808PpdoKlQU%n0O>42z0# zS+f*4UP6%RpopRCHbS6=an_h^xXWHFCnqO0dEaR}I~ppA6)0+R`i3r*vX?LO?V5x@ zN|RvWW$0yYK%F4Ct+KwJ3F@Y^o7pY25h~Pq<%W9>%WVFqY@fN092h`2pH2SDZ_lY+a&Si**#sDDo3I zuuSq!eI{}#qGj(se2{cags-1EH2M~-j|3v%C1<>2y#ZR-J=Xo&A(Zodg8W8Y2*_o3 z_R>*^DNIqfjcYIWJ@BhFcPIP9Gtu$!VZiEEmmw8W0ssZqN@rp@2?d{Z8F(&>b|WPt zQ?;vNK`87vz#*KD4R6ic@M-Gx@UudZ+Za1&CKIWnV5w2 zIAx>KwwHOA*xBAdR%Hu{KkApN_P>O4-(Siv&GoKt>b-OS{&i5PXruEn)9$C?sG!ii zLFb8zk2mRCp*{3J&GJ{`Pr!An%D~lF_@Uw9OwgesLEMRn*{m0ZYSbIPt6T*w5Mlt+ zMi_>&M^7O4^9Gjz-r;d%Ay)3TeIHO#QZg2z0HR1@YoL7_{iIF<4dPmIGLDqAlsH)s z2l2|4E8LLV00RKBuL4DF!fxI%lWhqZr@gbY2lsqza&jewXxrFJB%uNeM9{eRw~?u7 zFG6qRoCg~o%c9&9r2{a49^2n%qISF7r4eq3OF?;B^#t`^y|!^XA-*sX0`l^9!2p)> z_+vIVKhJbBCi4>!rZ;UOrF(AV>BpP5ZUut&t`JQyRy*RAQ(axHdhb?rG{>cp_A8K9 zs=j?I(^lsDlyq=qp;Oo9t%o9B!Q#|?bc~-EbqMAWcJTSw3j+g>KVNsuXc&@Y0@TKC zX~P@J`ZD|W)c~!r2?*@s8Mr*rcLX0S2=fdDz6!?(R?)MeCbBKpl#7mzE>_{P4DgIj zwt>X?jwh=@2UO3W&yhWqi+&Om6l4h{&vWbt9WK+F1I-`Qq!Lo}*BVS6^lUx>rWfzzy zZ{EDI1gKMu%!rBM0@_>yNZrI9S|=#!bPig2esOUK9CB#*LAWYC*?Hw+6U^_v#LKw| zf%gZ%);f*jBbgsqme}56JUbbqY2;4!Q1`?hc z_E%aa0y~0p&}3XjzbhgSAt)pBg15L!IZ&+WcF-}BsUC=g8drNM_El~>`- z(12HSj0#j^IW_kO8`)z!K*YJ~RQ{J904x{?5A0JK(UK;^cg@xke~v!&UtW^)nUf+S zB`S4vrX76%!LVp~goG2E0TXzOg2KXmj`u27d1+7f8MHiiA1131elz=ySUQrUv+FF} z0j+qOSo|6mzO`}MB*%jI6*nLNbgAUJcy)CM7U*(Dg?4NR1R#wO*xug0kLT z<`>5`&f^!vV#z~wH11h_;zV+C@-qZ*3s%#6?}LOvj|_5CY!&Rjhol#mTsReXk=uGS z1h_LWFi?tk0UNC&7SH;AR&2;Q4M9}{`YtYQ5IU$8XtSLAuRDWneRa296KiFr+_~xf zlKbuL$E)F|jWz7+LZp`o;Fxyp8r$`7Ni7!QzqHR!Jm5*J{LhPNzc-ihD1m$z&Xoe* z{oi+EdCX)<5;j6Qot~@VzaK_qR>Bwg?@NdO54~*UA!KW2`;4mRmnTJF36ku3dqq&V z?Tl`$vcD1%#)8a-M!LGXMET|VKz_O=rHZ2gbS~h=4Hne-)T3|f-oFph7I_VaBJJo3 zcX`0MKy8tY-ypydq(H)r@gK}TLE@4^huI*o>@kEWONK!%&ttPvAxE!Kk>iQ$us0~L zpjNm*!@yq}x8CCN75J+Ki^V@s_P>D&NH8O!Zg=)pc%TPUeS8#pdV32HbVLTd>f^`t zC=$2Q{q%BjbER$HbK5^NgRpA_tC;)1C2=5<)CQ-1uy=BxNUQ`IVRJM>l1}zqEFr>G zcU3S}M-AeZssG)uoo6|+?7jnEBr5rafqw}io7K7SeGm388V8XWQ3wk>M$KjI8YwWh z@1)-~_VX*3oznIC)JqIm9C2N)T^=GJPz9Mw%_JSgJb?ERWY?flg9@*a71N)i%FzIH zW!LdUIE0xu1X@}*npZRX0tDf?zT3wkfI`1ta~_L7{zQ7h6Ns__(C=V#io8Mj3q|36 z{puA3+RtEDg)$10XklnjP!hHtx195qb?ep<6^)gRQ_^fLBx0Or<%bU}#KInbjQ5cC zM}oSj!mklDAe|N)ejG9p368=ZQU?wWUw5jb(0(Ie78Bx1B#DTdNJjxURTa724S<8h zd;l&gDl$V-{#snF{kR1r@`l<++dSHHVnux4Q?y(+Z-bQ8Ixob4REyi8aj zFs;LTNFeON0|5{^Fg=pIM6#TTL|xR=G^6uv8+blvo?P?q-#@$08ElAhtfUaZ9CGux1pGTLG(wG!2#?Gtf;6MOprYFoE^Cil7oSvO6>Y)FJAOwA*!+@ zEq&#BgcJvq&FB!4$uanz!G~TFjy9!LhA*_9o5aDhy#-?zCA%5%xC~UADbxp=D+F>? z#^6A(Tze#|k=_=A5VW1b&d-19Ctqf2>b4asP}7@55ONWMJRu|mY|4%xP$Nn(s-GGz zhDa7x32aY>zleOT3P5*Pfh>C`Awe6O*>$5 zHv_Q_fo%zcO))YtZJg22Ox8ih|0%Tqwk9=u@Atuox)nRB9s_J=9SsD60Y>ZA1Hntc27Z6$>c| z(FJINTcKj;;@S`43{vKw6cweR--lhlF1&sFcA{3r?6TOP+wox$cqjuaf{181Y6i+8 z*iwodsmXPQrJM~^DsakH%G>Y2lYn;`&H8oQgoFZZWa4z*0SxM(5vj`qR&0yYKD1-U z4pnh^d1F1+7-0=fW7(QFZyJI1hS1yG=4TvD5d5gMk%3Od$Hule-DXjULXn)mRp?)L zsK7fQEgE7Ux8Y7=kb^-UX$4}=GSpM4C_m{aHVpMxQ84e4ZXG12imgg?KEWC2A5mEH zY-}9t>^Fg!-ABKlvitb)<95`Dree^YL6B{(yD(ohDR#)(tByd-6GC4%d1}kd#^KM0 zJ1#<*8tK?A$hmp*F=S)e?&_zdr!z)oXW^)D={Oiqq!_;KM{T(_s4qAVZCwzC(~=r$VI`mgjIXX@9MUs(kzM|A=4=1mgl7JP$MI&;(W zSb8KS41JeRrQ7fy^yjL!36<`Adi^uCJB~o%r`98>IJYqQQQCXvJS70j6gRyQTxkLB zz+pstK&BGWLa+=-=z>DzDR|Y4UotH!lt5t`VW&fGBb^?rObx&*h>xOP-HqQ`RaeId z)~Wg)iWl;xlmIYjLWoa2cdNvu3`#)#?H%cOTJ_|P>!F+QP#DOrB$^PuNy3f+DK)6J zbYT84?AHUkAf!z-GKy`Kj805sp;XE1LnPmVP}f>qV8K=#3C2%d(M^-iWz7B4O_!|wuL3naFK(vfC==FqY-=YCKy3em=i0$c*Vd7`FMtnF!WF=ws^xXy{TNlaORo(JaS zi2M8-dW8DQ2)p6L>4PNZLuqXGn(mNPRu+JC3E&XVdJ?L&sEes4qBvk^SD-2(%D=CC z*N+zK#qjtm^LUP<;(>B-&6M9yv_T%!I(^BnuJF-D$9~Ii&CkoVt|k zvz*7fz<`2d)6+$eqzhM^Arae}8Vw%KQvYS5c8fE|kjnLzvtxF&%g{R~>-*H#o!(!% ze*PsWw4h`*Z%TG&u6Y>`F1k;4U;vGbM0t97F_yioGbM}#{OHt+OLU?M8~z}Ns4BQZ zMYeZ^PI1D%X^6ZSm1)Z1s_Wp>d}wxj2W(#dh4E0$>U)`pIfxlPjxa5`Kyn&Y4X_Kr z@Yp6~Wo4=JUsKeXfUpF2?$jzwgmLZA_E@6t$aR?2P#q`~^jG5d;#{k-JcQ$dQJn}I z^+s zz!evMgMCeCpwO&-{659mI&?cE}vQ6a4tGWcu+3H!vr)8HK+F`;vtE2)!eQ=mfj~=dm9LAuw)5 zU4is_P(_8}HTwtV-C9!WkP0EW0sy0I*Y&5Bl$6?^yYD29C=Q=vxHVTzTYDXvV_GKW z8iHPwmU3*miqR0auZUlwG*kfq!ezgXd;v*JK?Y9w3IUmLLPX>aVP|6)FNAI-Jw5{mc`=h!xrcw6mi< zAvnTndlMFpEJ%No7n+H%g@uLgdB{w9&{}oRV`89hWJDWBYvbs66s#>BAd=}f>ese& z=gwuBl|GTmeup}32a=2Az#d>0L8O~ZN?p_PkGa$wq!wQKZQ|bKZ5UG-JpJev#6|uIq#2$!hEC+mTahLKKmNlD@L$3Ro55C#KaVqQUR*oB8)}`T&+fCYD5sN zf@%-os*bgv_CL%;Ltt@iok0PV11ksubMTzB_`S{88txz9Ld?`miZD|Fie!Ap8Yko# zApFBgM))b5e1d&EOAHdH4SP8!|tLsadgn;4jK6 zWM!%2Fb^qtotvyje0P+jl-f4L$3lpM^cq68EMPv7UJ-T`Ix4}zmJIWpXUWp{{QP{u z+|Z*3BrAc*XM=;QSFKVxdGhI-6nRn6!|Z1x3OsVZhS~1G2BN$Iq^6^QVPLqCWol~b zM_*qMel=q$L_MOC1Msn6sV3}qXM{IF#!9g%tsES}Fsuh>heEk4c?v#g2&A!O)MY6t zDHZ5H&LHlHQu2VJk>3k{P4KG*M!84^4LUZ^i50Xb5~~0krGZ#bD5!T#%E}cdCa?6& z8b%}Oia-Pn007sDIHlwlPwFt~jQ#H{z|V%@1T+&h%y?n7L*l#=7q!W{9jA(jZnIn_}LgJi5tRNRI_kO6bal?8x3Q z&?RB|e0aroaW7aM#||)PzE$wTI9u3;c`P zOTu&rj_B#J({179<^A{bo>PYVaO+Ye;=g`f=*JYvJebcr~q@Oq4J#sVatSvr>CQnsnA zLI|N8MSCL+$qQBi`4(iUAshl&Q1Ee+z6Es4s=Xc~?FZ3ISnrmVmDSeOh0)A88lVGH zr~H3^yX<*Ve~Er<_R`T$zM-6*s`a)VsR6+z2f6pM9lXTH?XIFyC(065XR^wjeYF`K zTjP}-^AopQ=+1EHypjpf*`c|{W`~y6y}Rj0JCXF&mTWjvs%~o6y{NE$eS`e=?X?Z1 z4fk%}J{bk{PPYZ0=`as46qX|DiVfRQ;`D%W6XLR=w#e;RZIPjlr;jj=Mx(uhqPjW& z?L&=9Em^$&C(i(x(-w;lLPF?39F!;UV=;)l5yWk%tD=HtHvIAY-f-GsbWhl{@8Ao+ zJzYS9?&3DwdbDg894l6e>tLf`(Xw~2qU^xWpPG;*;6+-9bB3$g0XN)5O{xcbR;Rvk zDBAxr^NGMm1Wei3jLW==C}du`;{uiH@Hs#x=03?6BHud6j+dsLQ-syTR!ilSjxolNvbh!)(H6X9eT)y1PYm} z2@4B*Z2E9uWMmx$1??b2hH(rl31QkFvrtBuQ-=n{-+9)?CJELO%b8h5q{T^_`KUO{ zr?fbAGIT#m(JFfS9w+~KUNQoKR`trE$b4VoRCVZLX`ymgu1V2}VY)Bl!YK!~!%)CK zt4Mqgv5M1hfeCcLwW3h4SI>A!>|jcqrKY;qs6JKf6AKH(R6J>Ps6dnef((Ek4{K^x zVH_zcG4Y0y?>{>)=P3*`lZZE*xr4ZT#FhqwJ^bbUm9I9BSk!eX6gVv+n=kjVh3@yx z7yEtbOH6Q+-5cvj#gL=-_Ey%^tija)qi))Jl7oZeAocTnGa>{p=X%0f9C>8zemMU% zpKPmG;y|QG8cOlVSV%V{qrtDGyG;u1t^kq?ZripB-7M|#WoxfqYn&5HiM2ol)oozv zR}0e%kI`zpJSsXmxMK0Qlf$>s%MzuV{?|!fJbd__`|d}Vx_l;?DO=>_Hz8XJw(&AO z_#uRzA22|1wyG!{bQI2T^-ozNBUi9)PI}IDhtg4iuVA+t%*N6u{RvEND;H;1FTG%R zo%nKaVsZGpKF19-;|U7g!^7c7p(PyfV2M=vCz_Iy@&hBnWN;j1+1b@KkcO(f64tic zv!$|XkSxf_ZyrV}g`pJ&g@mm5Pd+8L3;rpww-Eihz(cFATJpibbB2=*x$9um%?-3c z7N}#}iPbaP`*>5yq{->^RoEg9#u&}{xBH{FP_vk6Rkr0!WGhD7ZV&Ut## z#VEJ6xj_%q4YFz#3>)&02b5b&`1;RxQ}!_(!^X2ic$=iljdBf$4vZl|Vm+4s{mDxn zK@srVv;$1U6DpNcN4Yq8$i?m2pf+=FW-@~fK7-jq#)nNboXL0Rk4?m~f$0s-eelQ; z1_WEzL7{&6?^iZ)d+_{>j1LC>(2L}-tlYH>{_H^&R>wdLQG$zd06TQpS38wWa}qNX z&vq~pzkBb-_80fAM*_s3#soSyruO~*4Q&?<3&flsD;c6ga;~u9TE+@>b#*~Zg2I$j z0UvD2w^A$mbIBaatPm?7Uj(2*m7S~*^a|9MEAX-@SS)TU+wSf&OyK>UsB5CD8%4s; zfN|R}i}d~S06*R1-{zLfJ$K)p*3Em08F~B98BtI{jzB%{uigHDo#NVEwR$={0Nl*r z%gURODYIj4-@3Ib!0e@`F7$#dYSjSLn?!621yx%Nx z5%Jg5){cOqS`Uc$c>>N?*ozl0{t54iI=5Jc`DW-?LRh>L-@QjOrwy|8k#Q7OP%wj( z*;lzn;0`ug=Jf0>-s@?wPH6Y;-TSAm!uBQR;Op0~h4D}VbHBf5GQoGAn}*H&?Rf5< zO}U9wiBXv!-0(Nm)mbs?@$?R`f{j-zw_u6L_{=#=$7wq#vVD`E;lB~q`*5t&$ z@Bkqp)U_CdHpek9g8Fb6T$H~&sbMmarg@TjL8k1Ghx+;R;xJrWnCI!flvkmh1iwAK zV{&3WuD_6&vd8bpdp95Ac*zhW5uTs|rR0j>XDKge$)&e2=)p@S7s$Fgt}q@{jI1J! z_D4wa;}-G@nk(aM$=^c!>mcaj&wlQBByDLlH!0bTAl+<38DmHN^UO*Ek>dG2m6zL8 zc3hVo51pv|`0==@yQ$n=TGr;oW$J9+#Qx=-;f(7Wa2V=XyttBu`fd*(W0M%c(%6yL z1ysH1v4!o={iECdS{UoiO{`<<-c>rEaPOXJ>3bFzaW;KLh2?91Ec)G-3^_SA|IcA$ z?GO2XI6g}|ajZwO5*Ch-ThJFp@gId)OT7$#2XO2%-j@ZGWkFY3v1?#c>y^{5ZwSfu*Kk;9>5&L ziChVEN=BVCs=L{~#aCLY0A!Qcg(HW)46sW;im1_3+v_F}%0jRRCz!og&qH-h7G(q= zPRYgn8HDQTIn|^=MkO3u+_4772OmcE;Jck!jQuGRTb@6lt)-~wvL8L#(mOIjwwgmY z1MCrL(B-1H(VAFd<8Qev?81j6GZ=e=2hFz$!P4cYSYoau-sB$C*Bm?x3Ec?4&oIq4 z{;0^tM8ALb@Z7iH**l0v2evr4+dYLn4#{8@{Z%?7Av{q;S}ffTI2N8bd9vy8sRPi( zaD7)`n(<-=nJbC9d6R;&1pd$+cQ)}Lrln1~D*XKyhK~DJ!N?%t5bV2$Sg5E)+L`8q z$B1>AhzIJxx}gVBo%`s&v=XI`%iNO=cmb$Dg^Y|rD4O06)fj~e8pI)F1}$ZI*fwpt z2J{>AYZF46sug~Vq!mC#)J~8ae_n8=$b>v*1P>+PUPn(9Z}^>h!@o^}rbOhN|X<+su|EC@6)OE+kYXnwO(vRI|RM&kxZ|Eg5i3k80^hTDy z8vs#IEo95CUB`1PqD-$(BT+6SF8)5*7th^k%sjb0^a*fKgn;s93VG5O9$%9Ls)5lj zb)Y{NeX(HfkTnna^QezZVAa+BSNw2YGnX?!2=5Z*o`4bLy-s&hQ`Qz3>XQSF{dO!@%#0N z4s%i4fdA+y?Jy(R)hjUFv5jii7rrAXo;7T%hBZ)RcFMe)(?D2JYZN(U$u zG$rDO2JlA4ppL5QvLox0=Efz(y>6~Xc`4bvmG>l7Z?Bb=6()dKFwI+l?!x;)E{5ej zdQa(}>GY~2s}H#L(TWE>7?_zkpuKO}dp;Heh9{Qr*s|~xQ5on{MGYX1s{?kfQfAArU6jKi4|$prVB z{-#ixqxg<6A?$)%NLOiM9lQPR)W>q!frnMyB6c*SKZF+5!Lmh#gs{0cQhG3PfVFxH z*iI7*l&Z@fI^P1>VjSW(VFe&vlKlJKSSb@2PtSH-nuw{O;jtYrXTN(-fJPnxI(S=K zdxWH1gxW6bl#?@3`Zu`MxZI}{(Jga!^(fqsclcNvNOdwukI-$wR^Vid!V?kbwvdyc z(V!^2gMZoL&%`OtO0F%23TU+023vbbgNR7I!}2|YNYw^DK5+~f6?|*rZR8z>Ce1-{ zg)hX$242jDX)PBI4=%6)p|;Ik5Ome4HV8+ZDD!eRF0_lvIrYK-a~Q&K?r+7#*}rJw zMf&6(h|W7~a2tStW<0fmVeQ(RWKxiNet?&9d8D8QPtj3Fp)*LYIq)Cfz&y_#a-mL~ zxCMd{6&2-hkF54zbH){ZWea~l`g7ti+;b3f(xM!;u}LLgknvTR0vk4OmIUl@MSi{m zPne0^AIeWH0Idt&Ap)$=86YDP-O%gayI1R(ZJfW?Nt z8$A$8`?Iga`%ijW+7ZMgQlZ@3N=V4Lizws~@)#{Vx<%LD>AStYm~0G7vXBtTF+xwq z9O;Ja7BSdXGM29>p?k@q2IDJr?pBTKq?rlCuUW^v1wHBX-g_-iPz1EVEvRoekCEl@ z_U&7T#fVM2-`L4!oq@4>8{%fE=Xgq|EqV~pN{aboaWeA-SXb6xfzxovyQI}G%~JPp zJ=+%}uV0yu`0CK-Q|J{BfZ+VaMimrl3;d2}C$;*+zNTj2j0hRg$=|~0v-WJpLkMnL1VDg|C6}YC(mt z)&Tf7aBv6%8$E#l&Q|d4F#?+G930nZhb=9Wa2XE$9tCk|F8B5BC^{Dd03AB7V`e5! z2G=M$^BdVpy{5Ck;_ApVD};(CC4_`ja}2UO4~>qSh;uTqu-rX(l|FM?sJMJ2ximGE zijvR&eT0*XOACv)A5suU)Vbu2rF0dl4H)DK6+ACPOh^cijqoA;-KmQojyT0YMLL8#gB z6I{R0{S@-31YitiwksXy=_v{@5@Rt0Mr=j2JGk6GG9M+XIyi`t*|e%ERb1z!jEuGD z;S^Aj?y)BH1UdXH3F`(7>Ov_K5n_J~3_Ox}d;-nrkF)&$4CU=WKsgX}3l#)&9pNk0bYOaIhE54nK0=?*FXhU<|(bsr(9Oe@l)OCrjT=ezzYtS=3osWAccwXNnqnNB&&+zbY z7l@3Z1MBl81_};9CPq-^Dw@lQ-zzEDbNO%^r)7S~8DRO)Q4l*&!NGr?FeTe#9OWF; ziABzDK@QV5P;*;`t5xhv_TP0o*ExQI)5}_OK3-j~L;r5uG70D7H*=#4KCkX5-}Vrd zDZbU?ShUHf91c7!g92e&@9Nb{zTu0jM=^_Z#^Ir`&@;E84Uj@tW8!|g>*+@&rdP!w zm=YsdsQ^qZV+)58z6pIcJ~8Vqxe#P_rkESvStYK|pLa(tZYS=dQ^n%mME|ABK9ddm zXy-HO}L)WI}<^SyPY?B9XxW22 z6S$|2^8-E_#Auj$Va5WQwkOvl0o_#ZZ z1XNskelMg|R_ugM2THL^R7^}L+Bddi2Cglh(L+N$&F=Tt!zdluK=_bMi&)aN9ycNh1#!RWDNe7*eTWB8E|hY_`QBY3 zL->$226Y}WkNe}{3Qrp!9Tx~4X!!JL@_Cm<+7Q2%*n#=E@)llxQsVUWL)w78=YZ#jKwI<?Qaf7VIR?vSb z{-%Gyp_MUVFll)hN|5j8dRN?ttJ3c&afU@oSSa%#9!;%R@`AD&OotSM8kl3G2K+SFj(<4RMiDgFzS@VBqgVzd#?mL7#jnJztB(A zb23ZS%F3$!m>v{kaS4e+_)otjH#eISD?wO6y6V?U^(}C-H&|M>IhBcY**;?I5t#WKNbZN@7WBoVw zpP;R4-i>cd{luDs6KUCp+PY)y@9V}~`sY*&o!MoYyu)1i>9ln;asPQ2#76>mv<`{ zf-L)BU76u9#W>Ft1_bGq$xU;;LtZ7Wi3sj(#N8$fknjKQO?>`HPj-_2ii|WTT`Yu3 zOs*+TjQ)W^J0Xa+eaLq;LtVu{y%$}j(`blrhkmt~vIwJRY)7fBl)MrI4#^_zT zgLDy}!KJ!wIPx1iIs%XiD0=zwrOC;3Bm8F6+eni~z|4byZI?nreYxkmY^V_^_@sbU zfJ_8a09iZ;vkq%l>{~|l57=^xLnL&JWrQ_#bOZr3Yy=YdF!)1{wR zB-rOImn+vU^n8`E#CDOqye_r6;usNtO5Qgx5Egd8O@l0kY>FrWg+4|58l2ff0Ec{E z&5zuzQv&LNzWejltKwWfs-VbG$o_Zq?-3Id_2@kX{e|cbnHVrF#UU~$;|OIvMDPSe z%tqS5#yxIC)iuZm=;_JoPzbNxn*EUPw?XxKiU5k(M24O|akP1?E`|MIA#a-8`X$@C zfO?3_u&Z$|C_c$?RPA=&#fvG`%umYz`hNHkysI*O)6|5THZ4S z1Qub!_*cj$8asFDb=o@SooiF6|M};cB5RI?1GsJj%!S;(ola(_0p4sd3=M#bCqOmi z+9c-oU(YJ?KRLiVBDGjd3_C18lZ+UDnl%y#&7GagDeG~m)A<$rlQ6h~8hAMj50&vq z=lp~N;R+op3c;4nuLhM$KJO9_KAxdCJmX>aiC;13Bs=^3N>oL$9u2vy^B7E`Iv+(v zMMO6@BDS*tki4TuL~PhBpv}`+p*5jC-J#lORgb*7TB}^FO56S0o>}q1lI``n^IPsH z4*wLXkoXM@`}p_dB;U#g!YaUio_NFL%`h|=iY22zjVcTH4hlW6)U$Hs0$gL&xnpdw z_t)*x(3N}cof64RpH~O%06IJ<|n@CRKe6gz{ViuFe4Ms1x4>%d9zn6)69< z0QgshQ`g0Ej{ql*(rVMJV2}@0EdiT8n-+bsST~n({<{3q&e6mb0xXt|i7RC?snd9B zo=EHy0d-YOKhw&ST?J)q9VnoqUgm$M!2!rVaqNS-Z=Jmfux*Yr5Q%} z96ci-rcvN%+J2Lj*Mvi3O0@(yf%SOHalh*JmC3!ZkmHck(-31%dH(>CCfq;GvwjwV zPa`G8Vpp#9gdRLOlOy6<$_w2q_MyBHLIBdgt?5<_Rm`$cacPG zK)~OGUhkyv9F&b}Q~J&o?v~G$)mMAihGqMCnu5a57g4U5N|m$dA){Z2AsE240o`bw84Hr{luCjd=_kZH=&($i_!3Su3)eteB$DSx;ks^YfRd}7lBG4{M zE_%RUL+q40-L?Tl*6j|qWUJdu1w>i2niN^e6U4$8J&p1}z2IZ0L(<~at@D64Yz*#1 z87NKoptVU8FyrdK42CP8oJ}4Sh+AL7#P}?TvKVz;j~PuLni>OhlbL;f@Q>RQLHH@y zGlyE_uI-?4M}~?n>5xMqo6GBdbEWz8%VorszL2*?Q3-5Inu*0GP36Y8;bOkhP&9Ni zKWLE=I5FR$FEi$7=i9J!jA5W&To`kvU`@gx%g}jwSz0wzf`gxvdU}ALktpPgtD4H9 z(LJJ!5by-ak;ZgZAoNhSB*~XlTtufZ&t5FRRi zh6h8%FQhaUjSWHWu1r0m16eKFJZj!Lhe=4U(3P$b;(=lufW{`KfXF)*;Ws{xcy-dz zw^I0-%bJFxMx-%M~T^hfDy%saQ)bEp&K1X4dWpur>t zimTbs=MRJEHV6bfHwDDXv}i{JgX{QrE1m-NW@o@EeIbOK!tFr%_zY5H6g-8N0dKJGOCK}{Ev3yMAt=rg z38-&hodN_pDBc&aP+;K35hQ~(jzI3E1PmCTXQ3X2}%?Ra<4-T>CQfC2PzYT%UO613G%+2B6>p=3I*)+94+V{MWtq zz3vxww@2|uwJRx0=Jw~ex1 z7LU(K`yZ)vj4||k=1b8chEP1EnYV45ic@ymwr%9c5gjnch!up|J(}CdYmA5Hyfvk%j`v%DxvUK&%Yy%3$2}e0bzxi&@B5E#0JJ-l{wSDs=$pB*kHjlvrRq|)qP>< z$9zSMeKRl;Jexq|*tOs0JY?hGGDg7%sh?EF3LOJ%Z9L1VBtsj9VMs`bF?JuC+(qgD z9^Vu=8}Rs8fTP%)PdznN#a)SS5K>!e9W&TcvSs_HKBbYalo>2ALN08Pw?NFIb0i#6 zBnlj~Lp8Sw#^D&Gg^3e6O;48#`#?4JQn9R8y2IZ+@5t=)e?qgc!!z0&zX7)99e=Tn ze*|EDgwnPEI;m@=s;lX7l}O|3W^?{YK07PRD$qZc_rgJZ0QQ~@maBz%!{hHR(}3W_ z%Vi^rzgFk>9ciZgiR&^s)@=FWhvf{D1b+!JF-xTH{M(crxBLmd_B55r;i~=p{|{aA z|L*1fC!786zCh7pOhOoJCWN3C1%Iu2BmFvJS-$_crhgA0{OF7RAHVYt69RwtqyO*) zq^j9*3Cl$H#0dhV2?cVBMaJjZO8oOT4B0KP&TfgQPM(sV*ZtNz1=^AE_uNDL;`rCU z>3e$SL=|gRPfWbj-hkc}fZ@xW@j6Q`pEDT}5>P*tkuf03SI%Aj`$GF&vx`2Td{I<2 zMZvEsv7+(C2gK&p1PiQJ%gJ=kU_rbi-=xl9)tE*&;N z_ArxaMB&G0cgvHHnVLs~#Eh zOpW&%m7X1XpOagv>9;Fl!bUeM?q5;~<@MjZ=ak@$*T*k8RRv5Okl3hYKUCjp$_mfY z{^IB3V*ZUl>1s$~+7<(MB;gS8Uf*zxzzpTyQT(gpR_Q4I5EBBLQ=!{`4rs#1gbp(x_le0R@2Jr+=7?CW>N`$g+Q|U0COM7*L{O;y7t?Og@gFP74TM7Pd zttyQ7(%FM1SQeAzvl`>f_ReT(_5JBC&+KwV?R&%A8x?y^GA5@6e0h8=T$hwelsO{1pmQbWCKKnujhaIZ-U_p${n zRooAF=1{60sjlB16IK9R`4E%`Cp$gr2X>Ge9;Kp|@KO!+yR*SL+N#r*Qv(+gK6(q2Q-z`iK?zNxXJ(_`)ibFpV_r&p)tlo^WR&)>9mEO`8C+U3=^3!7fBdsHjU+%4a$ zQ&Zc~Z~H`p?X;qiU3)XWNxio7wf%UUhPxgZjYPrFOr2uqlr; ziOm$t?R7Mqk+=Q?XF?EI8$T9C_jCtHPp?%x^hxQ8-`+LjT+B1s zSrgLY+>I)&iIFFRrWac)p5Nz=N5@!kX126joEjV%)``l_jERU_*<1B+IbLSt`0s0< zoONes4!Hg@Tk3;Bh1YXw@#LxLx8+SHo^e-XYca~zH)GnPK7ZS-W6!`pBUE>qy(X;k z7)?g&=eWoc-a;BH0$u`xc2DN;;hLa`jDa+foybh4y@I|$5B|YD$z{y*6x#PBCLA+u z|KutW2Sk&)+akmRHoYHf+?ewHh8|vhyd`}$@$CqP4 zaH0bC%cllWD!8F0L5$i{0vkkZ6>7mEa!aSxEgP)vgr$+l^Ab1D&2PKKSq3xm zo)7%t*x9}O!2FTs%&eYS%;&(lZ>M)&OB&++RZ5^SHfoZ}!IdpxW$A0Q%$q)1yO#@o zs2&r+NNIw>(FaDaJ+jrj4@%8yz9yKzKIHbxw6%r_)|vN^K8*g^tu4aOZhX{r6j^Vp z_t+jE0`?o`S=VqjA%H<6h4k1U=xRWl|C!Fa@zD4 zBl$R+Qq!8mNBZ`Q=FIUdhe6Ok+R!De4FiaSLF8+uwIU-G+D+lFIoon@EK=6FL0wVzHGdj=ZQtvOez!Mq6J36RgCj*% zz3(q;`A_TfW?Uki#OoVe$3x4Ok4N9DIFctYt}^An3q_2zsvOOJBx!4-;J3@^g%JPI5EZjcbuh}$D zP~`nt@$rWB+_}RK;`TUR9gyoE3k?nvjqzpmEzlpmU3T?hoN2zW^PmS?_)YJFOU*vX=zrUXz`s+jLKOC9t-?DtZY+h#Nuzez&~Lyv#I^# znLk>tH{al2@-9b+n{(RK@2QlDnnY|QQu zR4&_k=@)^C$Jau(MEo@HDSKY+fxG_{@0%mz$Bp>HpO=K#zG`Y{ zUniavVj0&y|3g#9nF~%HvJpm3I1a4h$^`#RH+zQC7xiDnp8wVr|G&JzxM+jPqv4FX T{PuX7F{7crOD$oe@#%j9&T@c$ From 05db0f1e01d865225a4deecbc9342d3a64d84136 Mon Sep 17 00:00:00 2001 From: Simon Walker Date: Mon, 9 Jun 2025 21:14:02 +0100 Subject: [PATCH 16/74] CFn v2: implement support for CDK bootstrap (#12731) --- .../engine/v2/change_set_model_executor.py | 57 +++++++++++++++- .../engine/v2/change_set_model_preproc.py | 5 ++ .../services/cloudformation/v2/entities.py | 24 +++++++ .../services/cloudformation/v2/provider.py | 66 +++++++++++++------ .../v2/ported_from_v1/resources/test_cdk.py | 4 +- 5 files changed, 133 insertions(+), 23 deletions(-) diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py index 8388e678d207c..d80b7e5ecf067 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py @@ -4,8 +4,13 @@ from dataclasses import dataclass from typing import Final, Optional -from localstack.aws.api.cloudformation import ChangeAction, StackStatus +from localstack.aws.api.cloudformation import ( + ChangeAction, + ResourceStatus, + StackStatus, +) from localstack.constants import INTERNAL_AWS_SECRET_ACCESS_KEY +from localstack.services.cloudformation.engine.parameters import resolve_ssm_parameter from localstack.services.cloudformation.engine.v2.change_set_model import ( NodeDependsOn, NodeOutput, @@ -59,7 +64,25 @@ def execute(self) -> ChangeSetModelExecutorResult: ) def visit_node_parameter(self, node_parameter: NodeParameter) -> PreprocEntityDelta: - delta = super().visit_node_parameter(node_parameter=node_parameter) + delta = super().visit_node_parameter(node_parameter) + + # handle dynamic references, e.g. references to SSM parameters + # TODO: support more parameter types + parameter_type: str = node_parameter.type_.value + if parameter_type.startswith("AWS::SSM"): + if parameter_type in [ + "AWS::SSM::Parameter::Value", + "AWS::SSM::Parameter::Value", + "AWS::SSM::Parameter::Value", + ]: + delta.after = resolve_ssm_parameter( + account_id=self._change_set.account_id, + region_name=self._change_set.region_name, + stack_parameter_value=delta.after, + ) + else: + raise Exception(f"Unsupported stack parameter type: {parameter_type}") + self.resolved_parameters[node_parameter.name] = delta.after return delta @@ -253,6 +276,17 @@ def _execute_resource_action( stack.set_stack_status(StackStatus.CREATE_FAILED, reason=reason) elif stack_status == StackStatus.UPDATE_IN_PROGRESS: stack.set_stack_status(StackStatus.UPDATE_FAILED, reason=reason) + # update resource status + stack.set_resource_status( + logical_resource_id=logical_resource_id, + # TODO, + physical_resource_id="", + resource_type=resource_type, + status=ResourceStatus.CREATE_FAILED + if action == ChangeAction.Add + else ResourceStatus.UPDATE_FAILED, + resource_status_reason=reason, + ) return else: event = ProgressEvent(OperationStatus.SUCCESS, resource_model={}) @@ -290,6 +324,15 @@ def _execute_resource_action( physical_resource_id = self._before_resource_physical_id(logical_resource_id) self.resources[logical_resource_id]["PhysicalResourceId"] = physical_resource_id + self._change_set.stack.set_resource_status( + logical_resource_id=logical_resource_id, + physical_resource_id=physical_resource_id, + resource_type=resource_type, + status=ResourceStatus.CREATE_COMPLETE + if action == ChangeAction.Add + else ResourceStatus.UPDATE_COMPLETE, + ) + case OperationStatus.FAILED: reason = event.message LOG.warning( @@ -305,6 +348,16 @@ def _execute_resource_action( stack.set_stack_status(StackStatus.UPDATE_FAILED, reason=reason) else: raise NotImplementedError(f"Unhandled stack status: '{stack.status}'") + stack.set_resource_status( + logical_resource_id=logical_resource_id, + # TODO + physical_resource_id="", + resource_type=resource_type, + status=ResourceStatus.CREATE_FAILED + if action == ChangeAction.Add + else ResourceStatus.UPDATE_FAILED, + resource_status_reason=reason, + ) case any: raise NotImplementedError(f"Event status '{any}' not handled") diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py index 969e695318fa1..5fc274f0e5107 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py @@ -715,6 +715,11 @@ def _compute_join(args: list[Any]) -> str: delimiter: str = str(args[0]) values: list[Any] = args[1] if not isinstance(values, list): + # shortcut if values is the empty string, for example: + # {"Fn::Join": ["", {"Ref": }]} + # CDK bootstrap does this + if values == "": + return "" raise RuntimeError(f"Invalid arguments list definition for Fn::Join: '{args}'") str_values: list[str] = list() for value in values: diff --git a/localstack-core/localstack/services/cloudformation/v2/entities.py b/localstack-core/localstack/services/cloudformation/v2/entities.py index da7a5e311afda..481cbdbd9896c 100644 --- a/localstack-core/localstack/services/cloudformation/v2/entities.py +++ b/localstack-core/localstack/services/cloudformation/v2/entities.py @@ -8,8 +8,10 @@ ExecutionStatus, Output, Parameter, + ResourceStatus, StackDriftInformation, StackDriftStatus, + StackResource, StackStatus, StackStatusReason, ) @@ -46,6 +48,7 @@ class Stack: resolved_parameters: dict[str, str] resolved_resources: dict[str, ResolvedResource] resolved_outputs: dict[str, str] + resource_states: dict[str, StackResource] def __init__( self, @@ -84,12 +87,33 @@ def __init__( self.resolved_parameters = {} self.resolved_resources = {} self.resolved_outputs = {} + self.resource_states = {} def set_stack_status(self, status: StackStatus, reason: StackStatusReason | None = None): self.status = status if reason: self.status_reason = reason + def set_resource_status( + self, + *, + logical_resource_id: str, + physical_resource_id: str | None, + resource_type: str, + status: ResourceStatus, + resource_status_reason: str | None = None, + ): + self.resource_states[logical_resource_id] = StackResource( + StackName=self.stack_name, + StackId=self.stack_id, + LogicalResourceId=logical_resource_id, + PhysicalResourceId=physical_resource_id, + ResourceType=resource_type, + Timestamp=datetime.now(tz=timezone.utc), + ResourceStatus=status, + ResourceStatusReason=resource_status_reason, + ) + def describe_details(self) -> ApiStack: result = { "ChangeSetId": self.change_set_id, diff --git a/localstack-core/localstack/services/cloudformation/v2/provider.py b/localstack-core/localstack/services/cloudformation/v2/provider.py index 7393533d2a977..07f09a0cd2ae5 100644 --- a/localstack-core/localstack/services/cloudformation/v2/provider.py +++ b/localstack-core/localstack/services/cloudformation/v2/provider.py @@ -1,3 +1,4 @@ +import copy import logging from typing import Any @@ -14,14 +15,17 @@ DeletionMode, DescribeChangeSetOutput, DescribeStackEventsOutput, + DescribeStackResourcesOutput, DescribeStacksOutput, DisableRollback, ExecuteChangeSetOutput, ExecutionStatus, IncludePropertyValues, InvalidChangeSetStatusException, + LogicalResourceId, NextToken, Parameter, + PhysicalResourceId, RetainExceptOnCreate, RetainResources, RoleARN, @@ -62,6 +66,25 @@ def is_changeset_arn(change_set_name_or_id: str) -> bool: return ARN_CHANGESET_REGEX.match(change_set_name_or_id) is not None +def find_stack_v2(state: CloudFormationStore, stack_name: str | None) -> Stack: + if stack_name: + if is_stack_arn(stack_name): + return state.stacks_v2[stack_name] + else: + stack_candidates = [] + for stack in state.stacks_v2.values(): + if stack.stack_name == stack_name and stack.status != StackStatus.DELETE_COMPLETE: + stack_candidates.append(stack) + if len(stack_candidates) == 0: + raise ValidationError(f"No stack with name {stack_name} found") + elif len(stack_candidates) > 1: + raise RuntimeError("Programing error, duplicate stacks found") + else: + return stack_candidates[0] + else: + raise NotImplementedError + + def find_change_set_v2( state: CloudFormationStore, change_set_name: str, stack_name: str | None = None ) -> ChangeSet | None: @@ -364,28 +387,31 @@ def describe_stacks( **kwargs, ) -> DescribeStacksOutput: state = get_cloudformation_store(context.account_id, context.region) - if stack_name: - if is_stack_arn(stack_name): - stack = state.stacks_v2[stack_name] - else: - stack_candidates = [] - for stack in state.stacks_v2.values(): - if ( - stack.stack_name == stack_name - and stack.status != StackStatus.DELETE_COMPLETE - ): - stack_candidates.append(stack) - if len(stack_candidates) == 0: - raise ValidationError(f"No stack with name {stack_name} found") - elif len(stack_candidates) > 1: - raise RuntimeError("Programing error, duplicate stacks found") - else: - stack = stack_candidates[0] - else: - raise NotImplementedError - + stack = find_stack_v2(state, stack_name) return DescribeStacksOutput(Stacks=[stack.describe_details()]) + @handler("DescribeStackResources") + def describe_stack_resources( + self, + context: RequestContext, + stack_name: StackName = None, + logical_resource_id: LogicalResourceId = None, + physical_resource_id: PhysicalResourceId = None, + **kwargs, + ) -> DescribeStackResourcesOutput: + if physical_resource_id and stack_name: + raise ValidationError("Cannot specify both StackName and PhysicalResourceId") + state = get_cloudformation_store(context.account_id, context.region) + stack = find_stack_v2(state, stack_name) + # TODO: filter stack by PhysicalResourceId! + statuses = [] + for resource_id, resource_status in stack.resource_states.items(): + if resource_id == logical_resource_id or logical_resource_id is None: + status = copy.deepcopy(resource_status) + status.setdefault("DriftInformation", {"StackResourceDriftStatus": "NOT_CHECKED"}) + statuses.append(status) + return DescribeStackResourcesOutput(StackResources=statuses) + @handler("DescribeStackEvents") def describe_stack_events( self, diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_cdk.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_cdk.py index 3310beaca3f7d..89e176d0f1cde 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_cdk.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_cdk.py @@ -16,7 +16,9 @@ class TestCdkInit: - @pytest.mark.skip(reason="CFNV2:Fn::Join on empty string args") + @pytest.mark.skip( + reason="CFNV2:Destroy each test passes individually but because we don't delete resources, running all parameterized options fails" + ) @pytest.mark.parametrize("bootstrap_version", ["10", "11", "12"]) @markers.aws.validated def test_cdk_bootstrap(self, deploy_cfn_template, bootstrap_version, aws_client): From 2b1a97a57d53a2b139dc4a2b524cac4141f36ac7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Jun 2025 09:45:23 +0200 Subject: [PATCH 17/74] Bump python from 3.11.12-slim-bookworm to 3.11.13-slim-bookworm in the docker-base-images group (#12733) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Dockerfile | 2 +- Dockerfile.s3 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index a773eb6a0f5fa..ecabcde459554 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # # base: Stage which installs necessary runtime dependencies (OS packages, etc.) # -FROM python:3.11.12-slim-bookworm@sha256:dbf1de478a55d6763afaa39c2f3d7b54b25230614980276de5cacdde79529d0c AS base +FROM python:3.11.13-slim-bookworm@sha256:7a3ed1226224bcc1fe5443262363d42f48cf832a540c1836ba8ccbeaadf8637c AS base ARG TARGETARCH # Install runtime OS package dependencies diff --git a/Dockerfile.s3 b/Dockerfile.s3 index e09bf1231006e..3f377c27dc4bd 100644 --- a/Dockerfile.s3 +++ b/Dockerfile.s3 @@ -1,5 +1,5 @@ # base: Stage which installs necessary runtime dependencies (OS packages, filesystem...) -FROM python:3.11.12-slim-bookworm@sha256:dbf1de478a55d6763afaa39c2f3d7b54b25230614980276de5cacdde79529d0c AS base +FROM python:3.11.13-slim-bookworm@sha256:7a3ed1226224bcc1fe5443262363d42f48cf832a540c1836ba8ccbeaadf8637c AS base ARG TARGETARCH # set workdir From cb0ad39b769983eefcb53fc20a750fb7d31134fd Mon Sep 17 00:00:00 2001 From: LocalStack Bot <88328844+localstack-bot@users.noreply.github.com> Date: Tue, 10 Jun 2025 11:28:03 +0200 Subject: [PATCH 18/74] Upgrade pinned Python dependencies (#12734) Co-authored-by: LocalStack Bot --- .pre-commit-config.yaml | 4 +-- requirements-base-runtime.txt | 6 ++-- requirements-basic.txt | 4 +-- requirements-dev.txt | 16 +++++------ requirements-runtime.txt | 8 +++--- requirements-test.txt | 12 ++++---- requirements-typehint.txt | 52 +++++++++++++++++------------------ 7 files changed, 51 insertions(+), 51 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9f2fa6a1b4d65..52bdb9e2f0fee 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,7 +3,7 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.11.12 + rev: v0.11.13 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] @@ -29,7 +29,7 @@ repos: - id: check-pinned-deps-for-needed-upgrade - repo: https://github.com/python-openapi/openapi-spec-validator - rev: 0.7.1 + rev: 0.8.0b1 hooks: - id: openapi-spec-validator files: .*openapi.*\.(json|yaml|yml) diff --git a/requirements-base-runtime.txt b/requirements-base-runtime.txt index 3e22c15bbaf7e..90e0c1dc25196 100644 --- a/requirements-base-runtime.txt +++ b/requirements-base-runtime.txt @@ -34,7 +34,7 @@ click==8.2.1 # via localstack-core (pyproject.toml) constantly==23.10.4 # via localstack-twisted -cryptography==45.0.3 +cryptography==45.0.4 # via # localstack-core (pyproject.toml) # pyopenssl @@ -110,7 +110,7 @@ openapi-schema-validator==0.6.3 # via # openapi-core # openapi-spec-validator -openapi-spec-validator==0.7.1 +openapi-spec-validator==0.7.2 # via openapi-core packaging==25.0 # via build @@ -151,7 +151,7 @@ referencing==0.36.2 # jsonschema # jsonschema-path # jsonschema-specifications -requests==2.32.3 +requests==2.32.4 # via # docker # jsonschema-path diff --git a/requirements-basic.txt b/requirements-basic.txt index bc61d5c61c492..0a080017af899 100644 --- a/requirements-basic.txt +++ b/requirements-basic.txt @@ -16,7 +16,7 @@ charset-normalizer==3.4.2 # via requests click==8.2.1 # via localstack-core (pyproject.toml) -cryptography==45.0.3 +cryptography==45.0.4 # via localstack-core (pyproject.toml) dill==0.3.6 # via localstack-core (pyproject.toml) @@ -46,7 +46,7 @@ python-dotenv==1.1.0 # via localstack-core (pyproject.toml) pyyaml==6.0.2 # via localstack-core (pyproject.toml) -requests==2.32.3 +requests==2.32.4 # via localstack-core (pyproject.toml) rich==14.0.0 # via localstack-core (pyproject.toml) diff --git a/requirements-dev.txt b/requirements-dev.txt index d11867663619c..daac3b6f0d9cc 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -29,11 +29,11 @@ aws-cdk-asset-awscli-v1==2.2.237 # via aws-cdk-lib aws-cdk-asset-node-proxy-agent-v6==2.1.0 # via aws-cdk-lib -aws-cdk-cloud-assembly-schema==44.1.0 +aws-cdk-cloud-assembly-schema==44.2.0 # via aws-cdk-lib -aws-cdk-lib==2.200.0 +aws-cdk-lib==2.200.1 # via localstack-core -aws-sam-translator==1.97.0 +aws-sam-translator==1.98.0 # via # cfn-lint # localstack-core @@ -102,14 +102,14 @@ coveralls==4.0.1 # via localstack-core (pyproject.toml) crontab==1.0.4 # via localstack-core -cryptography==45.0.3 +cryptography==45.0.4 # via # joserfc # localstack-core # localstack-core (pyproject.toml) # moto-ext # pyopenssl -cython==3.1.1 +cython==3.1.2 # via localstack-core (pyproject.toml) decorator==5.2.1 # via jsonpath-rw @@ -272,7 +272,7 @@ openapi-schema-validator==0.6.3 # via # openapi-core # openapi-spec-validator -openapi-spec-validator==0.7.1 +openapi-spec-validator==0.7.2 # via # localstack-core (pyproject.toml) # moto-ext @@ -400,7 +400,7 @@ referencing==0.36.2 # jsonschema-specifications regex==2024.11.6 # via cfn-lint -requests==2.32.3 +requests==2.32.4 # via # coveralls # docker @@ -433,7 +433,7 @@ rsa==4.7.2 # via awscli rstr==3.2.2 # via localstack-core (pyproject.toml) -ruff==0.11.12 +ruff==0.11.13 # via localstack-core (pyproject.toml) s3transfer==0.13.0 # via diff --git a/requirements-runtime.txt b/requirements-runtime.txt index 3cb49e20584c8..efc1125228d11 100644 --- a/requirements-runtime.txt +++ b/requirements-runtime.txt @@ -21,7 +21,7 @@ attrs==25.3.0 # jsonschema # localstack-twisted # referencing -aws-sam-translator==1.97.0 +aws-sam-translator==1.98.0 # via # cfn-lint # localstack-core (pyproject.toml) @@ -76,7 +76,7 @@ constantly==23.10.4 # via localstack-twisted crontab==1.0.4 # via localstack-core (pyproject.toml) -cryptography==45.0.3 +cryptography==45.0.4 # via # joserfc # localstack-core @@ -202,7 +202,7 @@ openapi-schema-validator==0.6.3 # via # openapi-core # openapi-spec-validator -openapi-spec-validator==0.7.1 +openapi-spec-validator==0.7.2 # via # moto-ext # openapi-core @@ -283,7 +283,7 @@ referencing==0.36.2 # jsonschema-specifications regex==2024.11.6 # via cfn-lint -requests==2.32.3 +requests==2.32.4 # via # docker # jsonschema-path diff --git a/requirements-test.txt b/requirements-test.txt index 6645beab0043e..1f5d2575473cb 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -29,11 +29,11 @@ aws-cdk-asset-awscli-v1==2.2.237 # via aws-cdk-lib aws-cdk-asset-node-proxy-agent-v6==2.1.0 # via aws-cdk-lib -aws-cdk-cloud-assembly-schema==44.1.0 +aws-cdk-cloud-assembly-schema==44.2.0 # via aws-cdk-lib -aws-cdk-lib==2.200.0 +aws-cdk-lib==2.200.1 # via localstack-core (pyproject.toml) -aws-sam-translator==1.97.0 +aws-sam-translator==1.98.0 # via # cfn-lint # localstack-core @@ -96,7 +96,7 @@ coverage==7.8.2 # via localstack-core (pyproject.toml) crontab==1.0.4 # via localstack-core -cryptography==45.0.3 +cryptography==45.0.4 # via # joserfc # localstack-core @@ -248,7 +248,7 @@ openapi-schema-validator==0.6.3 # via # openapi-core # openapi-spec-validator -openapi-spec-validator==0.7.1 +openapi-spec-validator==0.7.2 # via # moto-ext # openapi-core @@ -361,7 +361,7 @@ referencing==0.36.2 # jsonschema-specifications regex==2024.11.6 # via cfn-lint -requests==2.32.3 +requests==2.32.4 # via # docker # jsonschema-path diff --git a/requirements-typehint.txt b/requirements-typehint.txt index 20a8d295cecee..bd3045df2004d 100644 --- a/requirements-typehint.txt +++ b/requirements-typehint.txt @@ -29,11 +29,11 @@ aws-cdk-asset-awscli-v1==2.2.237 # via aws-cdk-lib aws-cdk-asset-node-proxy-agent-v6==2.1.0 # via aws-cdk-lib -aws-cdk-cloud-assembly-schema==44.1.0 +aws-cdk-cloud-assembly-schema==44.2.0 # via aws-cdk-lib -aws-cdk-lib==2.200.0 +aws-cdk-lib==2.200.1 # via localstack-core -aws-sam-translator==1.97.0 +aws-sam-translator==1.98.0 # via # cfn-lint # localstack-core @@ -49,7 +49,7 @@ boto3==1.38.27 # kclpy-ext # localstack-core # moto-ext -boto3-stubs==1.38.28 +boto3-stubs==1.38.33 # via localstack-core (pyproject.toml) botocore==1.38.27 # via @@ -59,7 +59,7 @@ botocore==1.38.27 # localstack-core # moto-ext # s3transfer -botocore-stubs==1.38.28 +botocore-stubs==1.38.30 # via boto3-stubs build==1.2.2.post1 # via @@ -106,14 +106,14 @@ coveralls==4.0.1 # via localstack-core crontab==1.0.4 # via localstack-core -cryptography==45.0.3 +cryptography==45.0.4 # via # joserfc # localstack-core # localstack-core (pyproject.toml) # moto-ext # pyopenssl -cython==3.1.1 +cython==3.1.2 # via localstack-core decorator==5.2.1 # via jsonpath-rw @@ -266,11 +266,11 @@ mypy-boto3-acm==1.38.4 # via boto3-stubs mypy-boto3-acm-pca==1.38.0 # via boto3-stubs -mypy-boto3-amplify==1.38.26 +mypy-boto3-amplify==1.38.30 # via boto3-stubs -mypy-boto3-apigateway==1.38.0 +mypy-boto3-apigateway==1.38.29 # via boto3-stubs -mypy-boto3-apigatewayv2==1.38.0 +mypy-boto3-apigatewayv2==1.38.29 # via boto3-stubs mypy-boto3-appconfig==1.38.7 # via boto3-stubs @@ -278,7 +278,7 @@ mypy-boto3-appconfigdata==1.38.0 # via boto3-stubs mypy-boto3-application-autoscaling==1.38.21 # via boto3-stubs -mypy-boto3-appsync==1.38.2 +mypy-boto3-appsync==1.38.33 # via boto3-stubs mypy-boto3-athena==1.38.28 # via boto3-stubs @@ -288,11 +288,11 @@ mypy-boto3-backup==1.38.28 # via boto3-stubs mypy-boto3-batch==1.38.0 # via boto3-stubs -mypy-boto3-ce==1.38.24 +mypy-boto3-ce==1.38.33 # via boto3-stubs mypy-boto3-cloudcontrol==1.38.0 # via boto3-stubs -mypy-boto3-cloudformation==1.38.0 +mypy-boto3-cloudformation==1.38.31 # via boto3-stubs mypy-boto3-cloudfront==1.38.12 # via boto3-stubs @@ -324,13 +324,13 @@ mypy-boto3-dynamodb==1.38.4 # via boto3-stubs mypy-boto3-dynamodbstreams==1.38.0 # via boto3-stubs -mypy-boto3-ec2==1.38.25 +mypy-boto3-ec2==1.38.33 # via boto3-stubs mypy-boto3-ecr==1.38.6 # via boto3-stubs mypy-boto3-ecs==1.38.28 # via boto3-stubs -mypy-boto3-efs==1.38.0 +mypy-boto3-efs==1.38.33 # via boto3-stubs mypy-boto3-eks==1.38.28 # via boto3-stubs @@ -342,7 +342,7 @@ mypy-boto3-elbv2==1.38.0 # via boto3-stubs mypy-boto3-emr==1.38.18 # via boto3-stubs -mypy-boto3-emr-serverless==1.38.27 +mypy-boto3-emr-serverless==1.38.29 # via boto3-stubs mypy-boto3-es==1.38.0 # via boto3-stubs @@ -376,7 +376,7 @@ mypy-boto3-kinesisanalytics==1.38.0 # via boto3-stubs mypy-boto3-kinesisanalyticsv2==1.38.0 # via boto3-stubs -mypy-boto3-kms==1.38.0 +mypy-boto3-kms==1.38.32 # via boto3-stubs mypy-boto3-lakeformation==1.38.0 # via boto3-stubs @@ -386,7 +386,7 @@ mypy-boto3-logs==1.38.16 # via boto3-stubs mypy-boto3-managedblockchain==1.38.0 # via boto3-stubs -mypy-boto3-mediaconvert==1.38.16 +mypy-boto3-mediaconvert==1.38.30 # via boto3-stubs mypy-boto3-mediastore==1.38.0 # via boto3-stubs @@ -410,7 +410,7 @@ mypy-boto3-qldb==1.38.0 # via boto3-stubs mypy-boto3-qldb-session==1.38.0 # via boto3-stubs -mypy-boto3-rds==1.38.20 +mypy-boto3-rds==1.38.32 # via boto3-stubs mypy-boto3-rds-data==1.38.0 # via boto3-stubs @@ -422,7 +422,7 @@ mypy-boto3-resource-groups==1.38.0 # via boto3-stubs mypy-boto3-resourcegroupstaggingapi==1.38.0 # via boto3-stubs -mypy-boto3-route53==1.38.0 +mypy-boto3-route53==1.38.32 # via boto3-stubs mypy-boto3-route53resolver==1.38.0 # via boto3-stubs @@ -430,7 +430,7 @@ mypy-boto3-s3==1.38.26 # via boto3-stubs mypy-boto3-s3control==1.38.14 # via boto3-stubs -mypy-boto3-sagemaker==1.38.27 +mypy-boto3-sagemaker==1.38.30 # via boto3-stubs mypy-boto3-sagemaker-runtime==1.38.0 # via boto3-stubs @@ -460,11 +460,11 @@ mypy-boto3-timestream-query==1.38.10 # via boto3-stubs mypy-boto3-timestream-write==1.38.10 # via boto3-stubs -mypy-boto3-transcribe==1.38.0 +mypy-boto3-transcribe==1.38.30 # via boto3-stubs mypy-boto3-verifiedpermissions==1.38.7 # via boto3-stubs -mypy-boto3-wafv2==1.38.0 +mypy-boto3-wafv2==1.38.31 # via boto3-stubs mypy-boto3-xray==1.38.0 # via boto3-stubs @@ -482,7 +482,7 @@ openapi-schema-validator==0.6.3 # via # openapi-core # openapi-spec-validator -openapi-spec-validator==0.7.1 +openapi-spec-validator==0.7.2 # via # localstack-core # moto-ext @@ -610,7 +610,7 @@ referencing==0.36.2 # jsonschema-specifications regex==2024.11.6 # via cfn-lint -requests==2.32.3 +requests==2.32.4 # via # coveralls # docker @@ -643,7 +643,7 @@ rsa==4.7.2 # via awscli rstr==3.2.2 # via localstack-core -ruff==0.11.12 +ruff==0.11.13 # via localstack-core s3transfer==0.13.0 # via From 3a5f08b7c18fa9c39e72d07b2300437d898b068e Mon Sep 17 00:00:00 2001 From: Bert Blommers Date: Tue, 10 Jun 2025 09:57:15 +0000 Subject: [PATCH 19/74] Transcribe: Enable MyPy (#12588) --- .../localstack/services/transcribe/models.py | 2 +- .../services/transcribe/packages.py | 6 ++-- .../localstack/services/transcribe/plugins.py | 3 +- .../services/transcribe/provider.py | 30 +++++++++---------- .../localstack/testing/aws/asf_utils.py | 6 ++++ localstack-core/mypy.ini | 2 +- 6 files changed, 28 insertions(+), 21 deletions(-) diff --git a/localstack-core/localstack/services/transcribe/models.py b/localstack-core/localstack/services/transcribe/models.py index 772eadcb16ab3..4f9935a310501 100644 --- a/localstack-core/localstack/services/transcribe/models.py +++ b/localstack-core/localstack/services/transcribe/models.py @@ -3,7 +3,7 @@ class TranscribeStore(BaseStore): - transcription_jobs: dict[TranscriptionJobName, TranscriptionJob] = LocalAttribute(default=dict) + transcription_jobs: dict[TranscriptionJobName, TranscriptionJob] = LocalAttribute(default=dict) # type: ignore[assignment] transcribe_stores = AccountRegionBundle("transcribe", TranscribeStore) diff --git a/localstack-core/localstack/services/transcribe/packages.py b/localstack-core/localstack/services/transcribe/packages.py index b4bad8f009b50..14faf968c2159 100644 --- a/localstack-core/localstack/services/transcribe/packages.py +++ b/localstack-core/localstack/services/transcribe/packages.py @@ -1,16 +1,16 @@ from typing import List -from localstack.packages import Package, PackageInstaller +from localstack.packages import Package from localstack.packages.core import PythonPackageInstaller _VOSK_DEFAULT_VERSION = "0.3.43" -class VoskPackage(Package): +class VoskPackage(Package[PythonPackageInstaller]): def __init__(self, default_version: str = _VOSK_DEFAULT_VERSION): super().__init__(name="Vosk", default_version=default_version) - def _get_installer(self, version: str) -> PackageInstaller: + def _get_installer(self, version: str) -> PythonPackageInstaller: return VoskPackageInstaller(version) def get_versions(self) -> List[str]: diff --git a/localstack-core/localstack/services/transcribe/plugins.py b/localstack-core/localstack/services/transcribe/plugins.py index 342209536f23c..78cc12751894d 100644 --- a/localstack-core/localstack/services/transcribe/plugins.py +++ b/localstack-core/localstack/services/transcribe/plugins.py @@ -1,8 +1,9 @@ from localstack.packages import Package, package +from localstack.packages.core import PythonPackageInstaller @package(name="vosk") -def vosk_package() -> Package: +def vosk_package() -> Package[PythonPackageInstaller]: from localstack.services.transcribe.packages import vosk_package return vosk_package diff --git a/localstack-core/localstack/services/transcribe/provider.py b/localstack-core/localstack/services/transcribe/provider.py index c5818a5e92934..b0d1f62d458ed 100644 --- a/localstack-core/localstack/services/transcribe/provider.py +++ b/localstack-core/localstack/services/transcribe/provider.py @@ -5,7 +5,7 @@ import wave from functools import cache from pathlib import Path -from typing import Tuple +from typing import Any, Tuple from zipfile import ZipFile from localstack import config @@ -102,16 +102,16 @@ class TranscribeProvider(TranscribeApi): def get_transcription_job( - self, context: RequestContext, transcription_job_name: TranscriptionJobName, **kwargs + self, context: RequestContext, transcription_job_name: TranscriptionJobName, **kwargs: Any ) -> GetTranscriptionJobResponse: store = transcribe_stores[context.account_id][context.region] if job := store.transcription_jobs.get(transcription_job_name): # fetch output key and output bucket output_bucket, output_key = get_bucket_and_key_from_presign_url( - job["Transcript"]["TranscriptFileUri"] + job["Transcript"]["TranscriptFileUri"] # type: ignore[index,arg-type] ) - job["Transcript"]["TranscriptFileUri"] = connect_to().s3.generate_presigned_url( + job["Transcript"]["TranscriptFileUri"] = connect_to().s3.generate_presigned_url( # type: ignore[index] "get_object", Params={"Bucket": output_bucket, "Key": output_key}, ExpiresIn=60 * 15, @@ -128,13 +128,13 @@ def _setup_vosk() -> None: # Install and configure vosk vosk_package.install() - from vosk import SetLogLevel # noqa + from vosk import SetLogLevel # type: ignore[import-not-found] # noqa # Suppress Vosk logging SetLogLevel(-1) @handler("StartTranscriptionJob", expand=False) - def start_transcription_job( + def start_transcription_job( # type: ignore[override] self, context: RequestContext, request: StartTranscriptionJobRequest, @@ -157,7 +157,7 @@ def start_transcription_job( ) s3_path = request["Media"]["MediaFileUri"] - output_bucket = request.get("OutputBucketName", get_bucket_and_key_from_s3_uri(s3_path)[0]) + output_bucket = request.get("OutputBucketName", get_bucket_and_key_from_s3_uri(s3_path)[0]) # type: ignore[arg-type] output_key = request.get("OutputKey") if not output_key: @@ -196,7 +196,7 @@ def list_transcription_jobs( job_name_contains: TranscriptionJobName | None = None, next_token: NextToken | None = None, max_results: MaxResults | None = None, - **kwargs, + **kwargs: Any, ) -> ListTranscriptionJobsResponse: store = transcribe_stores[context.account_id][context.region] summaries = [] @@ -216,7 +216,7 @@ def list_transcription_jobs( return ListTranscriptionJobsResponse(TranscriptionJobSummaries=summaries) def delete_transcription_job( - self, context: RequestContext, transcription_job_name: TranscriptionJobName, **kwargs + self, context: RequestContext, transcription_job_name: TranscriptionJobName, **kwargs: Any ) -> None: store = transcribe_stores[context.account_id][context.region] @@ -277,7 +277,7 @@ def download_model(name: str) -> str: # Threads # - def _run_transcription_job(self, args: Tuple[TranscribeStore, str]): + def _run_transcription_job(self, args: Tuple[TranscribeStore, str]) -> None: store, job_name = args job = store.transcription_jobs[job_name] @@ -292,7 +292,7 @@ def _run_transcription_job(self, args: Tuple[TranscribeStore, str]): # Get file from S3 file_path = new_tmp_file() s3_client = connect_to().s3 - s3_path = job["Media"]["MediaFileUri"] + s3_path: str = job["Media"]["MediaFileUri"] # type: ignore[index,assignment] bucket, _, key = s3_path.removeprefix("s3://").partition("/") s3_client.download_file(Bucket=bucket, Key=key, Filename=file_path) @@ -303,7 +303,7 @@ def _run_transcription_job(self, args: Tuple[TranscribeStore, str]): LOG.debug("Determining media format") # TODO set correct failure_reason if ffprobe execution fails ffprobe_output = json.loads( - run( + run( # type: ignore[arg-type] f"{ffprobe_bin} -show_streams -show_format -print_format json -hide_banner -v error {file_path}" ) ) @@ -346,8 +346,8 @@ def _run_transcription_job(self, args: Tuple[TranscribeStore, str]): raise RuntimeError() # Prepare transcriber - language_code = job["LanguageCode"] - model_name = LANGUAGE_MODELS[language_code] + language_code: str = job["LanguageCode"] # type: ignore[assignment] + model_name = LANGUAGE_MODELS[language_code] # type: ignore[index] self._setup_vosk() model_path = self.download_model(model_name) from vosk import KaldiRecognizer, Model # noqa @@ -397,7 +397,7 @@ def _run_transcription_job(self, args: Tuple[TranscribeStore, str]): } # Save to S3 - output_s3_path = job["Transcript"]["TranscriptFileUri"] + output_s3_path: str = job["Transcript"]["TranscriptFileUri"] # type: ignore[index,assignment] output_bucket, output_key = get_bucket_and_key_from_presign_url(output_s3_path) s3_client.put_object(Bucket=output_bucket, Key=output_key, Body=json.dumps(output)) diff --git a/localstack-core/localstack/testing/aws/asf_utils.py b/localstack-core/localstack/testing/aws/asf_utils.py index 83699e1d4e772..33035496ebf2f 100644 --- a/localstack-core/localstack/testing/aws/asf_utils.py +++ b/localstack-core/localstack/testing/aws/asf_utils.py @@ -148,6 +148,12 @@ def check_provider_signature(sub_class: type, base_class: type, method_name: str # arg: ArgType | None = None # These should be considered equal, so until the API is fixed, we remove any Optionals # This also gives us the flexibility to correct the API without fixing all implementations at the same time + + if kwarg not in base_spec.annotations: + # Typically happens when the implementation uses '**kwargs: Any' + # This parameter is not part of the base spec, so we can't compare types + continue + sub_type = _remove_optional(sub_spec.annotations[kwarg]) base_type = _remove_optional(base_spec.annotations[kwarg]) assert sub_type == base_type, ( diff --git a/localstack-core/mypy.ini b/localstack-core/mypy.ini index b2844cc18c3a2..5fdadc333f36c 100644 --- a/localstack-core/mypy.ini +++ b/localstack-core/mypy.ini @@ -1,7 +1,7 @@ [mypy] explicit_package_bases = true mypy_path=localstack-core -files=localstack/aws/api/core.py,localstack/packages,localstack/services/kinesis/packages.py +files=localstack/aws/api/core.py,localstack/packages,localstack/services/transcribe,localstack/services/kinesis/packages.py ignore_missing_imports = False follow_imports = silent ignore_errors = False From 688225c853454f753ec5135e40e2431e7e2003d5 Mon Sep 17 00:00:00 2001 From: LocalStack Bot <88328844+localstack-bot@users.noreply.github.com> Date: Tue, 10 Jun 2025 14:17:26 +0200 Subject: [PATCH 20/74] Update ASF APIs (#12730) Co-authored-by: LocalStack Bot Co-authored-by: Mathieu Cloutier Co-authored-by: Silvio Vasiljevic Co-authored-by: Alexander Rashed --- .../localstack/aws/api/apigateway/__init__.py | 9 +++ .../aws/api/cloudformation/__init__.py | 1 + .../localstack/aws/api/kms/__init__.py | 63 ++++++++++++++++++- .../localstack/aws/api/route53/__init__.py | 3 + .../localstack/aws/api/transcribe/__init__.py | 5 ++ .../services/apigateway/legacy/provider.py | 3 + .../localstack/services/kms/provider.py | 23 +++++-- pyproject.toml | 4 +- requirements-base-runtime.txt | 4 +- requirements-dev.txt | 6 +- requirements-runtime.txt | 6 +- requirements-test.txt | 6 +- requirements-typehint.txt | 6 +- 13 files changed, 116 insertions(+), 23 deletions(-) diff --git a/localstack-core/localstack/aws/api/apigateway/__init__.py b/localstack-core/localstack/aws/api/apigateway/__init__.py index b23bd9969aa31..0010dd6b5b24a 100644 --- a/localstack-core/localstack/aws/api/apigateway/__init__.py +++ b/localstack-core/localstack/aws/api/apigateway/__init__.py @@ -159,6 +159,12 @@ class ResourceOwner(StrEnum): OTHER_ACCOUNTS = "OTHER_ACCOUNTS" +class RoutingMode(StrEnum): + BASE_PATH_MAPPING_ONLY = "BASE_PATH_MAPPING_ONLY" + ROUTING_RULE_ONLY = "ROUTING_RULE_ONLY" + ROUTING_RULE_THEN_BASE_PATH_MAPPING = "ROUTING_RULE_THEN_BASE_PATH_MAPPING" + + class SecurityPolicy(StrEnum): TLS_1_0 = "TLS_1_0" TLS_1_2 = "TLS_1_2" @@ -473,6 +479,7 @@ class CreateDomainNameRequest(ServiceRequest): mutualTlsAuthentication: Optional[MutualTlsAuthenticationInput] ownershipVerificationCertificateArn: Optional[String] policy: Optional[String] + routingMode: Optional[RoutingMode] class CreateModelRequest(ServiceRequest): @@ -751,6 +758,7 @@ class DomainName(TypedDict, total=False): ownershipVerificationCertificateArn: Optional[String] managementPolicy: Optional[String] policy: Optional[String] + routingMode: Optional[RoutingMode] class DomainNameAccessAssociation(TypedDict, total=False): @@ -1766,6 +1774,7 @@ def create_domain_name( mutual_tls_authentication: MutualTlsAuthenticationInput | None = None, ownership_verification_certificate_arn: String | None = None, policy: String | None = None, + routing_mode: RoutingMode | None = None, **kwargs, ) -> DomainName: raise NotImplementedError diff --git a/localstack-core/localstack/aws/api/cloudformation/__init__.py b/localstack-core/localstack/aws/api/cloudformation/__init__.py index c0621eca7d581..8f2dc3dfe350e 100644 --- a/localstack-core/localstack/aws/api/cloudformation/__init__.py +++ b/localstack-core/localstack/aws/api/cloudformation/__init__.py @@ -717,6 +717,7 @@ class WarningType(StrEnum): MUTUALLY_EXCLUSIVE_PROPERTIES = "MUTUALLY_EXCLUSIVE_PROPERTIES" UNSUPPORTED_PROPERTIES = "UNSUPPORTED_PROPERTIES" MUTUALLY_EXCLUSIVE_TYPES = "MUTUALLY_EXCLUSIVE_TYPES" + EXCLUDED_PROPERTIES = "EXCLUDED_PROPERTIES" class AlreadyExistsException(ServiceException): diff --git a/localstack-core/localstack/aws/api/kms/__init__.py b/localstack-core/localstack/aws/api/kms/__init__.py index 9acaf5e5a100b..55f03cfa36c2d 100644 --- a/localstack-core/localstack/aws/api/kms/__init__.py +++ b/localstack-core/localstack/aws/api/kms/__init__.py @@ -7,6 +7,8 @@ AWSAccountIdType = str AliasNameType = str ArnType = str +BackingKeyIdResponseType = str +BackingKeyIdType = str BooleanType = bool CloudHsmClusterIdType = str CustomKeyStoreIdType = str @@ -19,6 +21,7 @@ GrantNameType = str GrantTokenType = str KeyIdType = str +KeyMaterialDescriptionType = str KeyStorePasswordType = str LimitType = int MarkerType = str @@ -150,6 +153,21 @@ class GrantOperation(StrEnum): DeriveSharedSecret = "DeriveSharedSecret" +class ImportState(StrEnum): + IMPORTED = "IMPORTED" + PENDING_IMPORT = "PENDING_IMPORT" + + +class ImportType(StrEnum): + NEW_KEY_MATERIAL = "NEW_KEY_MATERIAL" + EXISTING_KEY_MATERIAL = "EXISTING_KEY_MATERIAL" + + +class IncludeKeyMaterial(StrEnum): + ALL_KEY_MATERIAL = "ALL_KEY_MATERIAL" + ROTATIONS_ONLY = "ROTATIONS_ONLY" + + class KeyAgreementAlgorithmSpec(StrEnum): ECDH = "ECDH" @@ -163,6 +181,12 @@ class KeyManagerType(StrEnum): CUSTOMER = "CUSTOMER" +class KeyMaterialState(StrEnum): + NON_CURRENT = "NON_CURRENT" + CURRENT = "CURRENT" + PENDING_ROTATION = "PENDING_ROTATION" + + class KeySpec(StrEnum): RSA_2048 = "RSA_2048" RSA_3072 = "RSA_3072" @@ -702,6 +726,7 @@ class KeyMetadata(TypedDict, total=False): PendingDeletionWindowInDays: Optional[PendingWindowInDaysType] MacAlgorithms: Optional[MacAlgorithmSpecList] XksKeyConfiguration: Optional[XksKeyConfigurationType] + CurrentKeyMaterialId: Optional[BackingKeyIdType] class CreateKeyResponse(TypedDict, total=False): @@ -754,6 +779,7 @@ class DecryptResponse(TypedDict, total=False): Plaintext: Optional[PlaintextType] EncryptionAlgorithm: Optional[EncryptionAlgorithmSpec] CiphertextForRecipient: Optional[CiphertextType] + KeyMaterialId: Optional[BackingKeyIdType] class DeleteAliasRequest(ServiceRequest): @@ -770,6 +796,12 @@ class DeleteCustomKeyStoreResponse(TypedDict, total=False): class DeleteImportedKeyMaterialRequest(ServiceRequest): KeyId: KeyIdType + KeyMaterialId: Optional[BackingKeyIdType] + + +class DeleteImportedKeyMaterialResponse(TypedDict, total=False): + KeyId: Optional[KeyIdType] + KeyMaterialId: Optional[BackingKeyIdResponseType] PublicKeyType = bytes @@ -870,6 +902,7 @@ class GenerateDataKeyPairResponse(TypedDict, total=False): KeyId: Optional[KeyIdType] KeyPairSpec: Optional[DataKeyPairSpec] CiphertextForRecipient: Optional[CiphertextType] + KeyMaterialId: Optional[BackingKeyIdType] class GenerateDataKeyPairWithoutPlaintextRequest(ServiceRequest): @@ -885,6 +918,7 @@ class GenerateDataKeyPairWithoutPlaintextResponse(TypedDict, total=False): PublicKey: Optional[PublicKeyType] KeyId: Optional[KeyIdType] KeyPairSpec: Optional[DataKeyPairSpec] + KeyMaterialId: Optional[BackingKeyIdType] class GenerateDataKeyRequest(ServiceRequest): @@ -902,6 +936,7 @@ class GenerateDataKeyResponse(TypedDict, total=False): Plaintext: Optional[PlaintextType] KeyId: Optional[KeyIdType] CiphertextForRecipient: Optional[CiphertextType] + KeyMaterialId: Optional[BackingKeyIdType] class GenerateDataKeyWithoutPlaintextRequest(ServiceRequest): @@ -916,6 +951,7 @@ class GenerateDataKeyWithoutPlaintextRequest(ServiceRequest): class GenerateDataKeyWithoutPlaintextResponse(TypedDict, total=False): CiphertextBlob: Optional[CiphertextType] KeyId: Optional[KeyIdType] + KeyMaterialId: Optional[BackingKeyIdType] class GenerateMacRequest(ServiceRequest): @@ -1015,10 +1051,14 @@ class ImportKeyMaterialRequest(ServiceRequest): EncryptedKeyMaterial: CiphertextType ValidTo: Optional[DateType] ExpirationModel: Optional[ExpirationModelType] + ImportType: Optional[ImportType] + KeyMaterialDescription: Optional[KeyMaterialDescriptionType] + KeyMaterialId: Optional[BackingKeyIdType] class ImportKeyMaterialResponse(TypedDict, total=False): - pass + KeyId: Optional[KeyIdType] + KeyMaterialId: Optional[BackingKeyIdType] class KeyListEntry(TypedDict, total=False): @@ -1072,12 +1112,19 @@ class ListKeyPoliciesResponse(TypedDict, total=False): class ListKeyRotationsRequest(ServiceRequest): KeyId: KeyIdType + IncludeKeyMaterial: Optional[IncludeKeyMaterial] Limit: Optional[LimitType] Marker: Optional[MarkerType] class RotationsListEntry(TypedDict, total=False): KeyId: Optional[KeyIdType] + KeyMaterialId: Optional[BackingKeyIdType] + KeyMaterialDescription: Optional[KeyMaterialDescriptionType] + ImportState: Optional[ImportState] + KeyMaterialState: Optional[KeyMaterialState] + ExpirationModel: Optional[ExpirationModelType] + ValidTo: Optional[DateType] RotationDate: Optional[DateType] RotationType: Optional[RotationType] @@ -1145,6 +1192,8 @@ class ReEncryptResponse(TypedDict, total=False): KeyId: Optional[KeyIdType] SourceEncryptionAlgorithm: Optional[EncryptionAlgorithmSpec] DestinationEncryptionAlgorithm: Optional[EncryptionAlgorithmSpec] + SourceKeyMaterialId: Optional[BackingKeyIdType] + DestinationKeyMaterialId: Optional[BackingKeyIdType] class ReplicateKeyRequest(ServiceRequest): @@ -1387,8 +1436,12 @@ def delete_custom_key_store( @handler("DeleteImportedKeyMaterial") def delete_imported_key_material( - self, context: RequestContext, key_id: KeyIdType, **kwargs - ) -> None: + self, + context: RequestContext, + key_id: KeyIdType, + key_material_id: BackingKeyIdType | None = None, + **kwargs, + ) -> DeleteImportedKeyMaterialResponse: raise NotImplementedError @handler("DeriveSharedSecret") @@ -1595,6 +1648,9 @@ def import_key_material( encrypted_key_material: CiphertextType, valid_to: DateType | None = None, expiration_model: ExpirationModelType | None = None, + import_type: ImportType | None = None, + key_material_description: KeyMaterialDescriptionType | None = None, + key_material_id: BackingKeyIdType | None = None, **kwargs, ) -> ImportKeyMaterialResponse: raise NotImplementedError @@ -1639,6 +1695,7 @@ def list_key_rotations( self, context: RequestContext, key_id: KeyIdType, + include_key_material: IncludeKeyMaterial | None = None, limit: LimitType | None = None, marker: MarkerType | None = None, **kwargs, diff --git a/localstack-core/localstack/aws/api/route53/__init__.py b/localstack-core/localstack/aws/api/route53/__init__.py index a2c3b810aa20b..c026d75133729 100644 --- a/localstack-core/localstack/aws/api/route53/__init__.py +++ b/localstack-core/localstack/aws/api/route53/__init__.py @@ -164,6 +164,7 @@ class CloudWatchRegion(StrEnum): us_isof_south_1 = "us-isof-south-1" us_isof_east_1 = "us-isof-east-1" ap_southeast_7 = "ap-southeast-7" + ap_east_2 = "ap-east-2" class ComparisonOperator(StrEnum): @@ -279,6 +280,7 @@ class ResourceRecordSetRegion(StrEnum): ap_southeast_7 = "ap-southeast-7" us_gov_east_1 = "us-gov-east-1" us_gov_west_1 = "us-gov-west-1" + ap_east_2 = "ap-east-2" class ReusableDelegationSetLimitType(StrEnum): @@ -340,6 +342,7 @@ class VPCRegion(StrEnum): us_isof_south_1 = "us-isof-south-1" us_isof_east_1 = "us-isof-east-1" ap_southeast_7 = "ap-southeast-7" + ap_east_2 = "ap-east-2" class CidrBlockInUseException(ServiceException): diff --git a/localstack-core/localstack/aws/api/transcribe/__init__.py b/localstack-core/localstack/aws/api/transcribe/__init__.py index 6e1d666bcd326..ac5b8cf19b94e 100644 --- a/localstack-core/localstack/aws/api/transcribe/__init__.py +++ b/localstack-core/localstack/aws/api/transcribe/__init__.py @@ -210,6 +210,11 @@ class MedicalScribeLanguageCode(StrEnum): class MedicalScribeNoteTemplate(StrEnum): HISTORY_AND_PHYSICAL = "HISTORY_AND_PHYSICAL" GIRPP = "GIRPP" + BIRP = "BIRP" + SIRP = "SIRP" + DAP = "DAP" + BEHAVIORAL_SOAP = "BEHAVIORAL_SOAP" + PHYSICAL_SOAP = "PHYSICAL_SOAP" class MedicalScribeParticipantRole(StrEnum): diff --git a/localstack-core/localstack/services/apigateway/legacy/provider.py b/localstack-core/localstack/services/apigateway/legacy/provider.py index 084108eaf2e0c..91c0a4df2105e 100644 --- a/localstack-core/localstack/services/apigateway/legacy/provider.py +++ b/localstack-core/localstack/services/apigateway/legacy/provider.py @@ -76,6 +76,7 @@ ResourceOwner, RestApi, RestApis, + RoutingMode, SecurityPolicy, Stage, Stages, @@ -421,6 +422,7 @@ def create_domain_name( mutual_tls_authentication: MutualTlsAuthenticationInput = None, ownership_verification_certificate_arn: String = None, policy: String = None, + routing_mode: RoutingMode = None, **kwargs, ) -> DomainName: if not domain_name: @@ -451,6 +453,7 @@ def create_domain_name( regionalCertificateArn=regional_certificate_arn, securityPolicy=SecurityPolicy.TLS_1_2, endpointConfiguration=endpoint_configuration, + routingMode=routing_mode, ) store.domain_names[domain_name] = domain return domain diff --git a/localstack-core/localstack/services/kms/provider.py b/localstack-core/localstack/services/kms/provider.py index 9f29780fa2103..02d8eb20f3261 100644 --- a/localstack-core/localstack/services/kms/provider.py +++ b/localstack-core/localstack/services/kms/provider.py @@ -13,6 +13,7 @@ from localstack.aws.api.kms import ( AlgorithmSpec, AlreadyExistsException, + BackingKeyIdType, CancelKeyDeletionRequest, CancelKeyDeletionResponse, CiphertextType, @@ -25,6 +26,7 @@ DateType, DecryptResponse, DeleteAliasRequest, + DeleteImportedKeyMaterialResponse, DeriveSharedSecretResponse, DescribeKeyRequest, DescribeKeyResponse, @@ -57,12 +59,14 @@ GrantTokenList, GrantTokenType, ImportKeyMaterialResponse, + ImportType, IncorrectKeyException, InvalidCiphertextException, InvalidGrantIdException, InvalidKeyUsageException, KeyAgreementAlgorithmSpec, KeyIdType, + KeyMaterialDescriptionType, KeySpec, KeyState, KeyUsageType, @@ -1104,8 +1108,11 @@ def import_key_material( key_id: KeyIdType, import_token: CiphertextType, encrypted_key_material: CiphertextType, - valid_to: DateType = None, - expiration_model: ExpirationModelType = None, + valid_to: DateType | None = None, + expiration_model: ExpirationModelType | None = None, + import_type: ImportType | None = None, + key_material_description: KeyMaterialDescriptionType | None = None, + key_material_id: BackingKeyIdType | None = None, **kwargs, ) -> ImportKeyMaterialResponse: store = self._get_store(context.account_id, context.region) @@ -1159,8 +1166,13 @@ def import_key_material( return ImportKeyMaterialResponse() def delete_imported_key_material( - self, context: RequestContext, key_id: KeyIdType, **kwargs - ) -> None: + self, + context: RequestContext, + key_id: KeyIdType, + key_material_id: BackingKeyIdType | None = None, + **kwargs, + ) -> DeleteImportedKeyMaterialResponse: + # TODO add support for key_material_id key = self._get_kms_key( context.account_id, context.region, @@ -1173,6 +1185,9 @@ def delete_imported_key_material( key.metadata["KeyState"] = KeyState.PendingImport key.metadata.pop("ExpirationModel", None) + # TODO populate DeleteImportedKeyMaterialResponse + return DeleteImportedKeyMaterialResponse() + @handler("CreateAlias", expand=False) def create_alias(self, context: RequestContext, request: CreateAliasRequest) -> None: store = self._get_store(context.account_id, context.region) diff --git a/pyproject.toml b/pyproject.toml index 4884a6739b48d..ef7f9e3a6f62d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,9 +53,9 @@ Issues = "https://github.com/localstack/localstack/issues" # minimal required to actually run localstack on the host for services natively implemented in python base-runtime = [ # pinned / updated by ASF update action - "boto3==1.38.27", + "boto3==1.38.32", # pinned / updated by ASF update action - "botocore==1.38.27", + "botocore==1.38.32", "awscrt>=0.13.14,!=0.27.1", "cbor2>=5.5.0", "dnspython>=1.16.0", diff --git a/requirements-base-runtime.txt b/requirements-base-runtime.txt index 90e0c1dc25196..31b5a7130db12 100644 --- a/requirements-base-runtime.txt +++ b/requirements-base-runtime.txt @@ -11,9 +11,9 @@ attrs==25.3.0 # referencing awscrt==0.27.2 # via localstack-core (pyproject.toml) -boto3==1.38.27 +boto3==1.38.32 # via localstack-core (pyproject.toml) -botocore==1.38.27 +botocore==1.38.32 # via # boto3 # localstack-core (pyproject.toml) diff --git a/requirements-dev.txt b/requirements-dev.txt index daac3b6f0d9cc..36b4d72c0b87e 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -39,17 +39,17 @@ aws-sam-translator==1.98.0 # localstack-core aws-xray-sdk==2.14.0 # via moto-ext -awscli==1.40.26 +awscli==1.40.31 # via localstack-core awscrt==0.27.2 # via localstack-core -boto3==1.38.27 +boto3==1.38.32 # via # aws-sam-translator # kclpy-ext # localstack-core # moto-ext -botocore==1.38.27 +botocore==1.38.32 # via # aws-xray-sdk # awscli diff --git a/requirements-runtime.txt b/requirements-runtime.txt index efc1125228d11..7b079c4aa2ab4 100644 --- a/requirements-runtime.txt +++ b/requirements-runtime.txt @@ -27,17 +27,17 @@ aws-sam-translator==1.98.0 # localstack-core (pyproject.toml) aws-xray-sdk==2.14.0 # via moto-ext -awscli==1.40.26 +awscli==1.40.31 # via localstack-core (pyproject.toml) awscrt==0.27.2 # via localstack-core -boto3==1.38.27 +boto3==1.38.32 # via # aws-sam-translator # kclpy-ext # localstack-core # moto-ext -botocore==1.38.27 +botocore==1.38.32 # via # aws-xray-sdk # awscli diff --git a/requirements-test.txt b/requirements-test.txt index 1f5d2575473cb..ecd564ffa5770 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -39,17 +39,17 @@ aws-sam-translator==1.98.0 # localstack-core aws-xray-sdk==2.14.0 # via moto-ext -awscli==1.40.26 +awscli==1.40.31 # via localstack-core awscrt==0.27.2 # via localstack-core -boto3==1.38.27 +boto3==1.38.32 # via # aws-sam-translator # kclpy-ext # localstack-core # moto-ext -botocore==1.38.27 +botocore==1.38.32 # via # aws-xray-sdk # awscli diff --git a/requirements-typehint.txt b/requirements-typehint.txt index bd3045df2004d..9728353958250 100644 --- a/requirements-typehint.txt +++ b/requirements-typehint.txt @@ -39,11 +39,11 @@ aws-sam-translator==1.98.0 # localstack-core aws-xray-sdk==2.14.0 # via moto-ext -awscli==1.40.26 +awscli==1.40.31 # via localstack-core awscrt==0.27.2 # via localstack-core -boto3==1.38.27 +boto3==1.38.32 # via # aws-sam-translator # kclpy-ext @@ -51,7 +51,7 @@ boto3==1.38.27 # moto-ext boto3-stubs==1.38.33 # via localstack-core (pyproject.toml) -botocore==1.38.27 +botocore==1.38.32 # via # aws-xray-sdk # awscli From f6075f6d6382421f944f37b02662f859977daacd Mon Sep 17 00:00:00 2001 From: Silvio Vasiljevic Date: Tue, 10 Jun 2025 15:18:14 +0200 Subject: [PATCH 21/74] Remove CircleCI config (#12737) --- .circleci/config.yml | 976 ------------------------------------------- CODEOWNERS | 1 - 2 files changed, 977 deletions(-) delete mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 937d78fb6a86f..0000000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,976 +0,0 @@ -version: 2.1 - -parameters: - ubuntu-amd64-machine-image: - type: string - default: "ubuntu-2204:2023.02.1" - ubuntu-arm64-machine-image: - type: string - default: "ubuntu-2204:2023.02.1" - PYTEST_LOGLEVEL: - type: string - default: "WARNING" - skip_test_selection: - type: boolean - default: false - randomize-aws-credentials: - type: boolean - default: false - only-acceptance-tests: - type: boolean - default: false - -executors: - ubuntu-machine-amd64: - machine: - image: << pipeline.parameters.ubuntu-amd64-machine-image >> - -commands: - prepare-acceptance-tests: - steps: - - run: - name: Check if only Acceptance Tests are running - command: | - only_acceptance_tests="<< pipeline.parameters.only-acceptance-tests >>" - trigger_source="<< pipeline.trigger_source >>" - git_branch="<< pipeline.git.branch >>" - echo "only-acceptance-tests: $only_acceptance_tests" - # GitHub event: webhook, Scheduled run: scheduled_pipeline, Manual run: api - echo "trigger_source: $trigger_source" - echo "git branch: $git_branch" - - # Function to set environment variables - set_env_vars() { - echo "export ONLY_ACCEPTANCE_TESTS=$1" >> $BASH_ENV - echo "export DEFAULT_TAG='$2'" >> $BASH_ENV - echo "$3" - } - - if [[ "$only_acceptance_tests" == "true" ]]; then - set_env_vars "true" "latest" "Only acceptance tests run, the default tag is 'latest'" - elif [[ "$git_branch" == "master" ]] && [[ "$trigger_source" == "webhook" ]]; then - set_env_vars "true" "latest" "Regular push run to master means only acceptance test run, the default tag is 'latest'" - else - set_env_vars "false" "latest" "All tests run, the default tag is 'latest'" - fi - - source $BASH_ENV - - prepare-testselection: - steps: - - unless: - condition: << pipeline.parameters.skip_test_selection >> - steps: - - run: - name: Setup test selection environment variable - command: | - if [[ -n "$CI_PULL_REQUEST" ]] ; then - echo "export TESTSELECTION_PYTEST_ARGS='--path-filter=target/testselection/test-selection.txt '" >> $BASH_ENV - fi - - prepare-pytest-tinybird: - steps: - - run: - name: Setup Environment Variables - command: | - if [[ $CIRCLE_BRANCH == "master" ]] ; then - echo "export TINYBIRD_PYTEST_ARGS='--report-to-tinybird '" >> $BASH_ENV - fi - if << pipeline.parameters.randomize-aws-credentials >> ; then - echo "export TINYBIRD_DATASOURCE=community_tests_circleci_ma_mr" >> $BASH_ENV - elif [[ $ONLY_ACCEPTANCE_TESTS == "true" ]] ; then - echo "export TINYBIRD_DATASOURCE=community_tests_circleci_acceptance" >> $BASH_ENV - else - echo "export TINYBIRD_DATASOURCE=community_tests_circleci" >> $BASH_ENV - fi - echo "export TINYBIRD_TOKEN=${TINYBIRD_CI_TOKEN}" >> $BASH_ENV - echo "export CI_COMMIT_BRANCH=${CIRCLE_BRANCH}" >> $BASH_ENV - echo "export CI_COMMIT_SHA=${CIRCLE_SHA1}" >> $BASH_ENV - echo "export CI_JOB_URL=${CIRCLE_BUILD_URL}" >> $BASH_ENV - # workflow ID as the job name to associate the tests with workflows in TB - echo "export CI_JOB_NAME=${CIRCLE_WORKFLOW_ID}" >> $BASH_ENV - echo "export CI_JOB_ID=${CIRCLE_JOB}" >> $BASH_ENV - source $BASH_ENV - - prepare-account-region-randomization: - steps: - - when: - condition: << pipeline.parameters.randomize-aws-credentials >> - steps: - - run: - name: Generate Random AWS Account ID - command: | - # Generate a random 12-digit number for TEST_AWS_ACCOUNT_ID - export TEST_AWS_ACCOUNT_ID=$(LC_ALL=C tr -dc '0-9' < /dev/urandom | fold -w 12 | head -n 1) - export TEST_AWS_ACCESS_KEY_ID=$TEST_AWS_ACCOUNT_ID - # Set TEST_AWS_REGION_NAME to a random AWS region other than us-east-1 - export AWS_REGIONS=("us-east-2" "us-west-1" "us-west-2" "ap-southeast-2" "ap-northeast-1" "eu-central-1" "eu-west-1") - export TEST_AWS_REGION_NAME=${AWS_REGIONS[$RANDOM % ${#AWS_REGIONS[@]}]} - echo "export TEST_AWS_REGION_NAME=${TEST_AWS_REGION_NAME}" >> $BASH_ENV - echo "export TEST_AWS_ACCESS_KEY_ID=${TEST_AWS_ACCESS_KEY_ID}" >> $BASH_ENV - echo "export TEST_AWS_ACCOUNT_ID=${TEST_AWS_ACCOUNT_ID}" >> $BASH_ENV - source $BASH_ENV - - -jobs: - ################ - ## Build Jobs ## - ################ - docker-build: - parameters: - platform: - description: "Platform to build for" - default: "amd64" - type: string - machine_image: - description: "CircleCI machine type to run at" - default: << pipeline.parameters.ubuntu-amd64-machine-image >> - type: string - resource_class: - description: "CircleCI machine type to run at" - default: "medium" - type: string - machine: - image: << parameters.machine_image >> - resource_class: << parameters.resource_class >> - working_directory: /tmp/workspace/repo - environment: - IMAGE_NAME: "localstack/localstack" - PLATFORM: "<< parameters.platform >>" - steps: - - prepare-acceptance-tests - - attach_workspace: - at: /tmp/workspace - - run: - name: Install global python dependencies - command: | - pip install --upgrade setuptools setuptools_scm - - run: - name: Build community docker image - command: ./bin/docker-helper.sh build - - run: - name: Save docker image - working_directory: target - command: ../bin/docker-helper.sh save - - persist_to_workspace: - root: - /tmp/workspace - paths: - - repo/target/ - - install: - executor: ubuntu-machine-amd64 - working_directory: /tmp/workspace/repo - steps: - - checkout - - restore_cache: - key: python-requirements-{{ checksum "requirements-typehint.txt" }} - - run: - name: Setup environment - command: | - make install-dev-types - make install - mkdir -p target/reports - mkdir -p target/coverage - - save_cache: - key: python-requirements-{{ checksum "requirements-typehint.txt" }} - paths: - - "~/.cache/pip" - - persist_to_workspace: - root: - /tmp/workspace - paths: - - repo - - - ########################## - ## Acceptance Test Jobs ## - ########################## - preflight: - executor: ubuntu-machine-amd64 - working_directory: /tmp/workspace/repo - steps: - - attach_workspace: - at: /tmp/workspace - - run: - name: Linting - command: make lint - - run: - name: Checking AWS compatibility markers - command: make check-aws-markers - - # can't completely skip it since we need the dependency from other tasks => conditional in run step - test-selection: - executor: ubuntu-machine-amd64 - working_directory: /tmp/workspace/repo - steps: - - attach_workspace: - at: /tmp/workspace - - unless: - condition: << pipeline.parameters.skip_test_selection >> - steps: - - run: - # script expects an environment variable $GITHUB_API_TOKEN to be set to fetch PR details - name: Generate test selection filters from changed files - command: | - if [[ -z "$CI_PULL_REQUEST" ]] ; then - echo "Skipping test selection" - circleci-agent step halt - else - source .venv/bin/activate - PYTHONPATH=localstack-core python -m localstack.testing.testselection.scripts.generate_test_selection /tmp/workspace/repo target/testselection/test-selection.txt --pr-url $CI_PULL_REQUEST - cat target/testselection/test-selection.txt - fi - - - persist_to_workspace: - root: - /tmp/workspace - paths: - - repo/target/testselection/ - - unit-tests: - executor: ubuntu-machine-amd64 - working_directory: /tmp/workspace/repo - steps: - - attach_workspace: - at: /tmp/workspace - - prepare-pytest-tinybird - - prepare-account-region-randomization - - run: - name: Unit tests - environment: - TEST_PATH: "tests/unit" - COVERAGE_ARGS: "-p" - command: | - COVERAGE_FILE="target/coverage/.coverage.unit.${CIRCLE_NODE_INDEX}" \ - PYTEST_ARGS="${TINYBIRD_PYTEST_ARGS}--junitxml=target/reports/unit-tests.xml -o junit_suite_name=unit-tests" \ - make test-coverage - - store_test_results: - path: target/reports/ - - persist_to_workspace: - root: - /tmp/workspace - paths: - - repo/target/coverage/ - - acceptance-tests: - parameters: - platform: - description: "Platform to run on" - default: "amd64" - type: string - resource_class: - description: "CircleCI machine type to run at" - default: "medium" - type: string - machine_image: - description: "CircleCI machine type to run at" - default: << pipeline.parameters.ubuntu-amd64-machine-image >> - type: string - machine: - image: << parameters.machine_image >> - resource_class: << parameters.resource_class >> - working_directory: /tmp/workspace/repo - environment: - PYTEST_LOGLEVEL: << pipeline.parameters.PYTEST_LOGLEVEL >> - IMAGE_NAME: "localstack/localstack" - PLATFORM: "<< parameters.platform >>" - steps: - - prepare-acceptance-tests - - attach_workspace: - at: /tmp/workspace - - run: - name: Load docker image - working_directory: target - command: ../bin/docker-helper.sh load - - prepare-pytest-tinybird - - prepare-account-region-randomization - - run: - name: Acceptance tests - environment: - TEST_PATH: "tests/aws/" - COVERAGE_ARGS: "-p" - COVERAGE_FILE: "target/coverage/.coverage.acceptance.<< parameters.platform >>" - PYTEST_ARGS: "${TINYBIRD_PYTEST_ARGS}--reruns 3 -m acceptance_test --junitxml=target/reports/acceptance-test-report-<< parameters.platform >>-${CIRCLE_NODE_INDEX}.xml -o junit_suite_name='acceptance_test'" - LOCALSTACK_INTERNAL_TEST_COLLECT_METRIC: 1 - DEBUG: 1 - command: | - make docker-run-tests - - store_test_results: - path: target/reports/ - - persist_to_workspace: - root: - /tmp/workspace - paths: - - repo/target/reports/ - - repo/target/metric_reports/ - - repo/target/coverage/ - - - ########################### - ## Integration Test Jobs ## - ########################### - integration-tests: - parameters: - platform: - description: "Platform to build for" - default: "amd64" - type: string - resource_class: - description: "CircleCI machine type to run at" - default: "medium" - type: string - machine_image: - description: "CircleCI machine type to run at" - default: << pipeline.parameters.ubuntu-amd64-machine-image >> - type: string - machine: - image: << parameters.machine_image >> - resource_class: << parameters.resource_class >> - working_directory: /tmp/workspace/repo - parallelism: 4 - environment: - PYTEST_LOGLEVEL: << pipeline.parameters.PYTEST_LOGLEVEL >> - IMAGE_NAME: "localstack/localstack" - PLATFORM: "<< parameters.platform >>" - steps: - - prepare-acceptance-tests - - attach_workspace: - at: /tmp/workspace - - run: - name: Load docker image - working_directory: target - command: ../bin/docker-helper.sh load - # Prebuild and cache Lambda multiruntime test functions, supporting both architectures: amd64 and arm64 - # Currently, all runners prebuild the Lambda functions, not just the one(s) executing Lambda multiruntime tests. - - run: - name: Compute Lambda build hashes - # Any change in the Lambda function source code (i.e., **/src/**) or build process (i.e., **/Makefile) invalidates the cache - command: | - find tests/aws/services/lambda_/functions/common -type f \( -path '**/src/**' -o -path '**/Makefile' \) | xargs sha256sum > /tmp/common-functions-checksums - - restore_cache: - key: common-functions-<< parameters.platform >>-{{ checksum "/tmp/common-functions-checksums" }} - - run: - name: Pre-build Lambda common test packages - command: ./scripts/build_common_test_functions.sh `pwd`/tests/aws/services/lambda_/functions/common - - save_cache: - key: common-functions-<< parameters.platform >>-{{ checksum "/tmp/common-functions-checksums" }} - paths: - - "tests/aws/services/lambda_/functions/common" - - prepare-testselection - - prepare-pytest-tinybird - - prepare-account-region-randomization - - run: - name: Run integration tests - # circleci split returns newline separated list, so `tr` is necessary to prevent problems in the Makefile - # if we're doing performing a test selection, we need to filter the list of files before splitting by timings - command: | - if [ -z $TESTSELECTION_PYTEST_ARGS ] ; then - TEST_FILES=$(circleci tests glob "tests/aws/**/test_*.py" "tests/integration/**/test_*.py" | circleci tests split --verbose --split-by=timings | tr '\n' ' ') - else - TEST_FILES=$(circleci tests glob "tests/aws/**/test_*.py" "tests/integration/**/test_*.py" | PYTHONPATH=localstack-core python -m localstack.testing.testselection.scripts.filter_by_test_selection target/testselection/test-selection.txt | circleci tests split --verbose --split-by=timings | tr '\n' ' ') - fi - echo $TEST_FILES - if [[ -z "$TEST_FILES" ]] ; then - echo "Skipping test execution because no tests were selected" - circleci-agent step halt - else - PYTEST_ARGS="${TINYBIRD_PYTEST_ARGS}${TESTSELECTION_PYTEST_ARGS}-o junit_family=legacy --junitxml=target/reports/test-report-<< parameters.platform >>-${CIRCLE_NODE_INDEX}.xml" \ - COVERAGE_FILE="target/coverage/.coverage.<< parameters.platform >>.${CIRCLE_NODE_INDEX}" \ - TEST_PATH=$TEST_FILES \ - DEBUG=1 \ - make docker-run-tests - fi - - store_test_results: - path: target/reports/ - - store_artifacts: - path: target/reports/ - - persist_to_workspace: - root: - /tmp/workspace - paths: - - repo/target/reports/ - - repo/target/coverage/ - - repo/target/metric_reports - - bootstrap-tests: - executor: ubuntu-machine-amd64 - working_directory: /tmp/workspace/repo - environment: - PYTEST_LOGLEVEL: << pipeline.parameters.PYTEST_LOGLEVEL >> - IMAGE_NAME: "localstack/localstack" - PLATFORM: "amd64" - steps: - - prepare-acceptance-tests - - attach_workspace: - at: /tmp/workspace - - run: - name: Load docker image - working_directory: target - command: ../bin/docker-helper.sh load - - prepare-pytest-tinybird - - prepare-account-region-randomization - - run: - name: Run bootstrap tests - environment: - TEST_PATH: "tests/bootstrap" - COVERAGE_ARGS: "-p" - command: | - PYTEST_ARGS="${TINYBIRD_PYTEST_ARGS}--junitxml=target/reports/bootstrap-tests.xml -o junit_suite_name=bootstrap-tests" make test-coverage - - store_test_results: - path: target/reports/ - - run: - name: Store coverage results - command: mv .coverage.* target/coverage/ - - persist_to_workspace: - root: - /tmp/workspace - paths: - - repo/target/coverage/ - - - ###################### - ## Custom Test Jobs ## - ###################### - itest-cloudwatch-v1-provider: - executor: ubuntu-machine-amd64 - working_directory: /tmp/workspace/repo - environment: - PYTEST_LOGLEVEL: << pipeline.parameters.PYTEST_LOGLEVEL >> - steps: - - prepare-acceptance-tests - - attach_workspace: - at: /tmp/workspace - - prepare-testselection - - prepare-pytest-tinybird - - prepare-account-region-randomization - - run: - name: Test CloudWatch v1 provider - environment: - PROVIDER_OVERRIDE_CLOUDWATCH: "v1" - TEST_PATH: "tests/aws/services/cloudwatch/" - COVERAGE_ARGS: "-p" - command: | - COVERAGE_FILE="target/coverage/.coverage.cloudwatchV1.${CIRCLE_NODE_INDEX}" \ - PYTEST_ARGS="${TINYBIRD_PYTEST_ARGS}${TESTSELECTION_PYTEST_ARGS}--reruns 3 --junitxml=target/reports/cloudwatch_v1.xml -o junit_suite_name='cloudwatch_v1'" \ - make test-coverage - - persist_to_workspace: - root: - /tmp/workspace - paths: - - repo/target/coverage/ - - store_test_results: - path: target/reports/ - - # TODO: remove legacy v1 provider in future 4.x release - itest-events-v1-provider: - executor: ubuntu-machine-amd64 - working_directory: /tmp/workspace/repo - environment: - PYTEST_LOGLEVEL: << pipeline.parameters.PYTEST_LOGLEVEL >> - steps: - - prepare-acceptance-tests - - attach_workspace: - at: /tmp/workspace - - prepare-testselection - - prepare-pytest-tinybird - - prepare-account-region-randomization - - run: - name: Test EventBridge v1 provider - environment: - PROVIDER_OVERRIDE_EVENTS: "v1" - TEST_PATH: "tests/aws/services/events/" - COVERAGE_ARGS: "-p" - command: | - COVERAGE_FILE="target/coverage/.coverage.eventsV1.${CIRCLE_NODE_INDEX}" \ - PYTEST_ARGS="${TINYBIRD_PYTEST_ARGS}${TESTSELECTION_PYTEST_ARGS}--reruns 3 --junitxml=target/reports/events_v1.xml -o junit_suite_name='events_v1'" \ - make test-coverage - - persist_to_workspace: - root: - /tmp/workspace - paths: - - repo/target/coverage/ - - store_test_results: - path: target/reports/ - - itest-ddb-v2-provider: - executor: ubuntu-machine-amd64 - working_directory: /tmp/workspace/repo - environment: - PYTEST_LOGLEVEL: << pipeline.parameters.PYTEST_LOGLEVEL >> - steps: - - prepare-acceptance-tests - - attach_workspace: - at: /tmp/workspace - - prepare-testselection - - prepare-pytest-tinybird - - prepare-account-region-randomization - - run: - name: Test DynamoDB(Streams) v2 provider - environment: - PROVIDER_OVERRIDE_DYNAMODB: "v2" - TEST_PATH: "tests/aws/services/dynamodb/ tests/aws/services/dynamodbstreams/ tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py" - COVERAGE_ARGS: "-p" - command: | - COVERAGE_FILE="target/coverage/.coverage.dynamodb_v2.${CIRCLE_NODE_INDEX}" \ - PYTEST_ARGS="${TINYBIRD_PYTEST_ARGS}${TESTSELECTION_PYTEST_ARGS}--reruns 3 --junitxml=target/reports/dynamodb_v2.xml -o junit_suite_name='dynamodb_v2'" \ - make test-coverage - - persist_to_workspace: - root: - /tmp/workspace - paths: - - repo/target/coverage/ - - store_test_results: - path: target/reports/ - - itest-cfn-v2-engine-provider: - executor: ubuntu-machine-amd64 - working_directory: /tmp/workspace/repo - environment: - PYTEST_LOGLEVEL: << pipeline.parameters.PYTEST_LOGLEVEL >> - steps: - - prepare-acceptance-tests - - attach_workspace: - at: /tmp/workspace - - prepare-testselection - - prepare-pytest-tinybird - - prepare-account-region-randomization - - run: - name: Test CloudFormation Engine v2 - environment: - PROVIDER_OVERRIDE_CLOUDFORMATION: "engine-v2" - TEST_PATH: "tests/aws/services/cloudformation/v2" - COVERAGE_ARGS: "-p" - # TODO: use docker-run-tests - command: | - COVERAGE_FILE="target/coverage/.coverage.cloudformation_v2.${CIRCLE_NODE_INDEX}" \ - PYTEST_ARGS="${TINYBIRD_PYTEST_ARGS}${TESTSELECTION_PYTEST_ARGS}--reruns 3 --junitxml=target/reports/cloudformation_v2.xml -o junit_suite_name='cloudformation_v2'" \ - make test-coverage - - persist_to_workspace: - root: - /tmp/workspace - paths: - - repo/target/coverage/ - - store_test_results: - path: target/reports/ - - ######################### - ## Parity Metrics Jobs ## - ######################### - capture-not-implemented: - executor: ubuntu-machine-amd64 - working_directory: /tmp/workspace/repo - environment: - IMAGE_NAME: "localstack/localstack" - PLATFORM: "amd64" - steps: - - prepare-acceptance-tests - - attach_workspace: - at: /tmp/workspace - - run: - name: Load docker image - working_directory: target - command: ../bin/docker-helper.sh load - - run: - name: Run localstack - command: | - source .venv/bin/activate - DEBUG=1 DISABLE_EVENTS="1" IMAGE_NAME="localstack/localstack:latest" localstack start -d - localstack wait -t 120 || (python -m localstack.cli.main logs && false) - - run: - name: Run capture-not-implemented - command: | - source .venv/bin/activate - cd scripts - python -m capture_notimplemented_responses - - run: - name: Print the logs - command: | - source .venv/bin/activate - localstack logs - - run: - name: Stop localstack - command: | - source .venv/bin/activate - localstack stop - - persist_to_workspace: - root: - /tmp/workspace - paths: - - repo/scripts/implementation_coverage_aggregated.csv - - repo/scripts/implementation_coverage_full.csv - - - ############################ - ## Result Publishing Jobs ## - ############################ - report: - executor: ubuntu-machine-amd64 - working_directory: /tmp/workspace/repo - steps: - - prepare-acceptance-tests - - attach_workspace: - at: /tmp/workspace - - run: - name: Collect isolated acceptance coverage - command: | - source .venv/bin/activate - mkdir target/coverage/acceptance - cp target/coverage/.coverage.acceptance.* target/coverage/acceptance - cd target/coverage/acceptance - coverage combine - mv .coverage ../../../.coverage.acceptance - - store_artifacts: - path: .coverage.acceptance - - run: - name: Collect coverage - command: | - source .venv/bin/activate - cd target/coverage - ls -la - coverage combine - mv .coverage ../../ - - run: - name: Report coverage statistics - command: | - if [ -z "${CI_PULL_REQUEST}" ]; then - source .venv/bin/activate - coverage report || true - coverage html || true - coveralls || true - else - echo "Skipping coverage reporting for pull request." - fi - - run: - name: Store acceptance parity metrics - command: | - mkdir acceptance_parity_metrics - mv target/metric_reports/metric-report*acceptance* acceptance_parity_metrics/ - - run: - name: Upload test metrics and implemented coverage data to tinybird - command: | - if [ -z "$CIRCLE_PR_REPONAME" ] ; then - # check if a fork-only env var is set (https://circleci.com/docs/variables/) - source .venv/bin/activate - mkdir parity_metrics && mv target/metric_reports/metric-report-raw-data-*amd64*.csv parity_metrics - METRIC_REPORT_DIR_PATH=parity_metrics \ - IMPLEMENTATION_COVERAGE_FILE=scripts/implementation_coverage_full.csv \ - SOURCE_TYPE=community \ - python -m scripts.tinybird.upload_raw_test_metrics_and_coverage - else - echo "Skipping parity reporting to tinybird (no credentials, running on fork)..." - fi - - - run: - name: Create Coverage Diff (Code Coverage) - # pycobertura diff will return with exit code 0-3 -> we currently expect 2 (2: the changes worsened the overall coverage), - # but we still want cirecleci to continue with the tasks, so we return 0. - # From the docs: - # Upon exit, the diff command may return various exit codes: - # 0: all changes are covered, no new uncovered statements have been introduced - # 1: some exception occurred (likely due to inappropriate usage or a bug in pycobertura) - # 2: the changes worsened the overall coverage - # 3: the changes introduced uncovered statements but the overall coverage is still better than before - command: | - source .venv/bin/activate - pip install pycobertura - coverage xml --data-file=.coverage -o all.coverage.report.xml --include="localstack-core/localstack/services/*/**" --omit="*/**/__init__.py" - coverage xml --data-file=.coverage.acceptance -o acceptance.coverage.report.xml --include="localstack-core/localstack/services/*/**" --omit="*/**/__init__.py" - pycobertura show --format html acceptance.coverage.report.xml -o coverage-acceptance.html - bash -c "pycobertura diff --format html all.coverage.report.xml acceptance.coverage.report.xml -o coverage-diff.html; if [[ \$? -eq 1 ]] ; then exit 1 ; else exit 0 ; fi" - - run: - name: Create Metric Coverage Diff (API Coverage) - environment: - COVERAGE_DIR_ALL: "parity_metrics" - COVERAGE_DIR_ACCEPTANCE: "acceptance_parity_metrics" - OUTPUT_DIR: "api-coverage" - command: | - source .venv/bin/activate - mkdir api-coverage - python -m scripts.metrics_coverage.diff_metrics_coverage - - store_artifacts: - path: api-coverage/ - - store_artifacts: - path: coverage-acceptance.html - - store_artifacts: - path: coverage-diff.html - - store_artifacts: - path: parity_metrics/ - - store_artifacts: - path: acceptance_parity_metrics/ - - store_artifacts: - path: scripts/implementation_coverage_aggregated.csv - destination: community/implementation_coverage_aggregated.csv - - store_artifacts: - path: scripts/implementation_coverage_full.csv - destination: community/implementation_coverage_full.csv - - store_artifacts: - path: .coverage - - push: - executor: ubuntu-machine-amd64 - working_directory: /tmp/workspace/repo - environment: - IMAGE_NAME: "localstack/localstack" - steps: - - prepare-acceptance-tests - - attach_workspace: - at: /tmp/workspace - - run: - name: Install global python dependencies - command: | - pip install --upgrade setuptools setuptools_scm - - run: - name: Load docker image - amd64 - working_directory: target - environment: - PLATFORM: amd64 - command: ../bin/docker-helper.sh load - - run: - name: Log in to ECR registry - command: aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws - - run: - name: Push docker image - amd64 - environment: - PLATFORM: amd64 - command: | - # Push to Docker Hub - ./bin/docker-helper.sh push - # Push to Amazon Public ECR - TARGET_IMAGE_NAME="public.ecr.aws/localstack/localstack" ./bin/docker-helper.sh push - # Load and push per architecture (load overwrites the previous ones) - - run: - name: Load docker image - arm64 - working_directory: target - environment: - PLATFORM: arm64 - command: ../bin/docker-helper.sh load - - run: - name: Push docker image - arm64 - environment: - PLATFORM: arm64 - command: | - # Push to Docker Hub - ./bin/docker-helper.sh push - # Push to Amazon Public ECR - TARGET_IMAGE_NAME="public.ecr.aws/localstack/localstack" ./bin/docker-helper.sh push - - run: - name: Create multi-platform manifests - command: | - # Push to Docker Hub - ./bin/docker-helper.sh push-manifests - # Push to Amazon Public ECR - IMAGE_NAME="public.ecr.aws/localstack/localstack" ./bin/docker-helper.sh push-manifests - - run: - name: Publish a dev release - command: | - if git describe --exact-match --tags >/dev/null 2>&1; then - echo "not publishing a dev release as this is a tagged commit" - else - source .venv/bin/activate - make publish || echo "dev release failed (maybe it is already published)" - fi - - push-to-tinybird: - executor: ubuntu-machine-amd64 - working_directory: /tmp/workspace/repo - steps: - - prepare-acceptance-tests - - run: - name: Wait for the workflow to complete - command: | - # Record the time this step started - START_TIME=$(date +%s) - - # Determine if reporting the workflow even is necessary and what the workflow variant is - if [[ << pipeline.parameters.randomize-aws-credentials >> == "true" ]] && [[ $ONLY_ACCEPTANCE_TESTS == "true" ]] ; then - echo "Don't report only-acceptance-test workflows with randomized aws credentials" - circleci-agent step halt - elif [[ << pipeline.parameters.randomize-aws-credentials >> == "true" ]] ; then - TINYBIRD_WORKFLOW=tests_circleci_ma_mr - elif [[ $ONLY_ACCEPTANCE_TESTS == "true" ]] ; then - TINYBIRD_WORKFLOW=tests_circleci_acceptance - else - TINYBIRD_WORKFLOW=tests_circleci - fi - - - # wait for the workflow to be done - while [[ $(curl --location --request GET "https://circleci.com/api/v2/workflow/$CIRCLE_WORKFLOW_ID/job"| jq -r '.items[]|select(.name != "push-to-tinybird" and .name != "push" and .name != "report")|.status' | grep -c "running") -gt 0 ]]; do - sleep 10 - done - - # check if a step failed / determine the outcome - FAILED_COUNT=$(curl --location --request GET "https://circleci.com/api/v2/workflow/$CIRCLE_WORKFLOW_ID/job" | jq -r '.items[]|.status' | grep -c "failed") || true - echo "failed count: $FAILED_COUNT" - if [[ $FAILED_COUNT -eq 0 ]]; then - OUTCOME="success" - else - OUTCOME="failure" - fi - echo "outcome: $OUTCOME" - - # Record the time this step is done - END_TIME=$(date +%s) - - # Build the payload - echo '{"workflow": "'$TINYBIRD_WORKFLOW'", "attempt": 1, "run_id": "'$CIRCLE_WORKFLOW_ID'", "start": '$START_TIME', "end": '$END_TIME', "commit": "'$CIRCLE_SHA1'", "branch": "'$CIRCLE_BRANCH'", "repository": "'$CIRCLE_PROJECT_USERNAME'/'$CIRCLE_PROJECT_REPONAME'", "outcome": "'$OUTCOME'", "workflow_url": "'$CIRCLE_BUILD_URL'"}' > stats.json - echo 'Sending: '$(cat stats.json) - - # Send the data to Tinybird - curl -X POST "https://api.tinybird.co/v0/events?name=ci_workflows" -H "Authorization: Bearer $TINYBIRD_CI_TOKEN" -d @stats.json - - # Fail this step depending on the success to trigger a rerun of this step together with others in case of a "rerun failed" - [[ $OUTCOME = "success" ]] && exit 0 || exit 1 - - -#################### -## Workflow setup ## -#################### -workflows: - acceptance-only-run: - # this workflow only runs when only-acceptance-tests is explicitly set - # or when the pipeline is running on the master branch but is neither scheduled nor a manual run - # (basically the opposite of the full-run workflow) - when: - or: - - << pipeline.parameters.only-acceptance-tests >> - - and: - - equal: [ master, << pipeline.git.branch>> ] - - equal: [ webhook, << pipeline.trigger_source >> ] - jobs: - - push-to-tinybird: - filters: - branches: - only: master - - install - - preflight: - requires: - - install - - unit-tests: - requires: - - preflight - - docker-build: - name: docker-build-amd64 - platform: amd64 - machine_image: << pipeline.parameters.ubuntu-amd64-machine-image >> - resource_class: medium - requires: - - preflight - - docker-build: - name: docker-build-arm64 - platform: arm64 - # The latest version of ubuntu is not yet supported for ARM: - # https://circleci.com/docs/2.0/arm-resources/ - machine_image: << pipeline.parameters.ubuntu-arm64-machine-image >> - resource_class: arm.medium - requires: - - preflight - - acceptance-tests: - name: acceptance-tests-arm64 - platform: arm64 - resource_class: arm.medium - machine_image: << pipeline.parameters.ubuntu-arm64-machine-image >> - requires: - - docker-build-arm64 - - acceptance-tests: - name: acceptance-tests-amd64 - platform: amd64 - machine_image: << pipeline.parameters.ubuntu-amd64-machine-image >> - resource_class: medium - requires: - - docker-build-amd64 - full-run: - # this workflow only runs when only-acceptance-tests is not explicitly set (the default) - # or when the pipeline is running on the master branch because of a Github event (webhook) - # (basically the opposite of the acceptance-only-run workflow) - unless: - or: - - << pipeline.parameters.only-acceptance-tests >> - - and: - - equal: [ master, << pipeline.git.branch>> ] - - equal: [ webhook, << pipeline.trigger_source >> ] - jobs: - - push-to-tinybird: - filters: - branches: - only: master - - install - - preflight: - requires: - - install - - test-selection: - requires: - - install - - itest-cloudwatch-v1-provider: - requires: - - preflight - - test-selection - - itest-events-v1-provider: - requires: - - preflight - - test-selection - - itest-ddb-v2-provider: - requires: - - preflight - - test-selection - - itest-cfn-v2-engine-provider: - requires: - - preflight - - test-selection - - unit-tests: - requires: - - preflight - - docker-build: - name: docker-build-amd64 - platform: amd64 - machine_image: << pipeline.parameters.ubuntu-amd64-machine-image >> - resource_class: medium - requires: - - preflight - - docker-build: - name: docker-build-arm64 - platform: arm64 - # The latest version of ubuntu is not yet supported for ARM: - # https://circleci.com/docs/2.0/arm-resources/ - machine_image: << pipeline.parameters.ubuntu-arm64-machine-image >> - resource_class: arm.medium - requires: - - preflight - - acceptance-tests: - name: acceptance-tests-arm64 - platform: arm64 - resource_class: arm.medium - machine_image: << pipeline.parameters.ubuntu-arm64-machine-image >> - requires: - - docker-build-arm64 - - acceptance-tests: - name: acceptance-tests-amd64 - platform: amd64 - machine_image: << pipeline.parameters.ubuntu-amd64-machine-image >> - resource_class: medium - requires: - - docker-build-amd64 - - integration-tests: - name: integration-tests-arm64 - platform: arm64 - resource_class: arm.medium - machine_image: << pipeline.parameters.ubuntu-arm64-machine-image >> - requires: - - docker-build-arm64 - - test-selection - - integration-tests: - name: integration-tests-amd64 - platform: amd64 - resource_class: medium - machine_image: << pipeline.parameters.ubuntu-amd64-machine-image >> - requires: - - docker-build-amd64 - - test-selection - - bootstrap-tests: - requires: - - docker-build-amd64 - - capture-not-implemented: - name: collect-not-implemented - requires: - - docker-build-amd64 diff --git a/CODEOWNERS b/CODEOWNERS index e165d6d3cc5d3..21eb166c492c2 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -17,7 +17,6 @@ /Dockerfile @alexrashed # Git, Pipelines, GitHub config -/.circleci @alexrashed @dfangl @dominikschubert @silv-io @k-a-il /.github @alexrashed @dfangl @dominikschubert @silv-io @k-a-il /.test_durations @alexrashed /.git-blame-ignore-revs @alexrashed @thrau From 5b623bfd0c74ae1dc3ae2443a8894f7e6faf08cf Mon Sep 17 00:00:00 2001 From: Vittorio Polverino Date: Wed, 11 Jun 2025 09:42:12 +0200 Subject: [PATCH 22/74] refactor: metrics instrumentation framework typing and structure (#12717) --- .../services/apigateway/analytics.py | 4 +- .../execute_api/handlers/analytics.py | 6 +- .../cloudformation/{usage.py => analytics.py} | 4 +- .../cloudformation/resource_provider.py | 6 +- .../localstack/services/events/analytics.py | 6 +- .../localstack/services/lambda_/analytics.py | 8 +- .../localstack/services/sns/analytics.py | 6 +- .../stepfunctions/{usage.py => analytics.py} | 4 +- .../usage_metrics_static_analyser.py | 4 +- .../localstack/utils/analytics/metrics.py | 373 ------------------ .../utils/analytics/metrics/__init__.py | 6 + .../localstack/utils/analytics/metrics/api.py | 42 ++ .../utils/analytics/metrics/counter.py | 209 ++++++++++ .../utils/analytics/metrics/publisher.py | 36 ++ .../utils/analytics/metrics/registry.py | 97 +++++ tests/unit/utils/analytics/test_metrics.py | 21 +- 16 files changed, 428 insertions(+), 404 deletions(-) rename localstack-core/localstack/services/cloudformation/{usage.py => analytics.py} (58%) rename localstack-core/localstack/services/stepfunctions/{usage.py => analytics.py} (70%) delete mode 100644 localstack-core/localstack/utils/analytics/metrics.py create mode 100644 localstack-core/localstack/utils/analytics/metrics/__init__.py create mode 100644 localstack-core/localstack/utils/analytics/metrics/api.py create mode 100644 localstack-core/localstack/utils/analytics/metrics/counter.py create mode 100644 localstack-core/localstack/utils/analytics/metrics/publisher.py create mode 100644 localstack-core/localstack/utils/analytics/metrics/registry.py diff --git a/localstack-core/localstack/services/apigateway/analytics.py b/localstack-core/localstack/services/apigateway/analytics.py index 13bd7109358ce..d01d93a943f65 100644 --- a/localstack-core/localstack/services/apigateway/analytics.py +++ b/localstack-core/localstack/services/apigateway/analytics.py @@ -1,5 +1,5 @@ -from localstack.utils.analytics.metrics import Counter +from localstack.utils.analytics.metrics import LabeledCounter -invocation_counter = Counter( +invocation_counter = LabeledCounter( namespace="apigateway", name="rest_api_execute", labels=["invocation_type"] ) diff --git a/localstack-core/localstack/services/apigateway/next_gen/execute_api/handlers/analytics.py b/localstack-core/localstack/services/apigateway/next_gen/execute_api/handlers/analytics.py index 7c6525eb0e7e1..46fe8d06a9e9e 100644 --- a/localstack-core/localstack/services/apigateway/next_gen/execute_api/handlers/analytics.py +++ b/localstack-core/localstack/services/apigateway/next_gen/execute_api/handlers/analytics.py @@ -1,7 +1,7 @@ import logging from localstack.http import Response -from localstack.utils.analytics.metrics import LabeledCounterMetric +from localstack.utils.analytics.metrics import LabeledCounter from ..api import RestApiGatewayHandler, RestApiGatewayHandlerChain from ..context import RestApiInvocationContext @@ -10,9 +10,9 @@ class IntegrationUsageCounter(RestApiGatewayHandler): - counter: LabeledCounterMetric + counter: LabeledCounter - def __init__(self, counter: LabeledCounterMetric): + def __init__(self, counter: LabeledCounter): self.counter = counter def __call__( diff --git a/localstack-core/localstack/services/cloudformation/usage.py b/localstack-core/localstack/services/cloudformation/analytics.py similarity index 58% rename from localstack-core/localstack/services/cloudformation/usage.py rename to localstack-core/localstack/services/cloudformation/analytics.py index 66d99b2e4cab0..f5530e262f92e 100644 --- a/localstack-core/localstack/services/cloudformation/usage.py +++ b/localstack-core/localstack/services/cloudformation/analytics.py @@ -1,7 +1,7 @@ -from localstack.utils.analytics.metrics import Counter +from localstack.utils.analytics.metrics import LabeledCounter COUNTER_NAMESPACE = "cloudformation" -resources = Counter( +resources = LabeledCounter( namespace=COUNTER_NAMESPACE, name="resources", labels=["resource_type", "missing"] ) diff --git a/localstack-core/localstack/services/cloudformation/resource_provider.py b/localstack-core/localstack/services/cloudformation/resource_provider.py index 7e48ed8ca5703..31ac0938712bb 100644 --- a/localstack-core/localstack/services/cloudformation/resource_provider.py +++ b/localstack-core/localstack/services/cloudformation/resource_provider.py @@ -19,7 +19,7 @@ from localstack import config from localstack.aws.connect import InternalClientFactory, ServiceLevelClientFactory -from localstack.services.cloudformation import usage +from localstack.services.cloudformation import analytics from localstack.services.cloudformation.deployment_utils import ( check_not_found_exception, convert_data_types, @@ -581,7 +581,7 @@ def try_load_resource_provider(resource_type: str) -> ResourceProvider | None: # 2. try to load community resource provider try: plugin = plugin_manager.load(resource_type) - usage.resources.labels(resource_type=resource_type, missing=False).increment() + analytics.resources.labels(resource_type=resource_type, missing=False).increment() return plugin.factory() except ValueError: # could not find a plugin for that name @@ -600,7 +600,7 @@ def try_load_resource_provider(resource_type: str) -> ResourceProvider | None: f'No resource provider found for "{resource_type}"', ) - usage.resources.labels(resource_type=resource_type, missing=True).increment() + analytics.resources.labels(resource_type=resource_type, missing=True).increment() if config.CFN_IGNORE_UNSUPPORTED_RESOURCE_TYPES: # TODO: figure out a better way to handle non-implemented here? diff --git a/localstack-core/localstack/services/events/analytics.py b/localstack-core/localstack/services/events/analytics.py index f47924d04fdb4..8ebe75d8dd5fd 100644 --- a/localstack-core/localstack/services/events/analytics.py +++ b/localstack-core/localstack/services/events/analytics.py @@ -1,6 +1,6 @@ from enum import StrEnum -from localstack.utils.analytics.metrics import Counter +from localstack.utils.analytics.metrics import LabeledCounter class InvocationStatus(StrEnum): @@ -11,4 +11,6 @@ class InvocationStatus(StrEnum): # number of EventBridge rule invocations per target (e.g., aws:lambda) # - status label can be `success` or `error`, see InvocationStatus # - service label is the target service name -rule_invocation = Counter(namespace="events", name="rule_invocations", labels=["status", "service"]) +rule_invocation = LabeledCounter( + namespace="events", name="rule_invocations", labels=["status", "service"] +) diff --git a/localstack-core/localstack/services/lambda_/analytics.py b/localstack-core/localstack/services/lambda_/analytics.py index 4545f23a7139e..ff4a1ae6f516c 100644 --- a/localstack-core/localstack/services/lambda_/analytics.py +++ b/localstack-core/localstack/services/lambda_/analytics.py @@ -1,12 +1,12 @@ from enum import StrEnum -from localstack.utils.analytics.metrics import Counter +from localstack.utils.analytics.metrics import LabeledCounter NAMESPACE = "lambda" -hotreload_counter = Counter(namespace=NAMESPACE, name="hotreload", labels=["operation"]) +hotreload_counter = LabeledCounter(namespace=NAMESPACE, name="hotreload", labels=["operation"]) -function_counter = Counter( +function_counter = LabeledCounter( namespace=NAMESPACE, name="function", labels=[ @@ -38,7 +38,7 @@ class FunctionStatus(StrEnum): invocation_error = "invocation_error" -esm_counter = Counter(namespace=NAMESPACE, name="esm", labels=["source", "status"]) +esm_counter = LabeledCounter(namespace=NAMESPACE, name="esm", labels=["source", "status"]) class EsmExecutionStatus(StrEnum): diff --git a/localstack-core/localstack/services/sns/analytics.py b/localstack-core/localstack/services/sns/analytics.py index c74ed6ad2b141..426c5403bae6b 100644 --- a/localstack-core/localstack/services/sns/analytics.py +++ b/localstack-core/localstack/services/sns/analytics.py @@ -2,8 +2,10 @@ Usage analytics for SNS internal endpoints """ -from localstack.utils.analytics.metrics import Counter +from localstack.utils.analytics.metrics import LabeledCounter # number of times SNS internal endpoint per resource types # (e.g. PlatformMessage invoked 10x times, SMSMessage invoked 3x times, SubscriptionToken...) -internal_api_calls = Counter(namespace="sns", name="internal_api_call", labels=["resource_type"]) +internal_api_calls = LabeledCounter( + namespace="sns", name="internal_api_call", labels=["resource_type"] +) diff --git a/localstack-core/localstack/services/stepfunctions/usage.py b/localstack-core/localstack/services/stepfunctions/analytics.py similarity index 70% rename from localstack-core/localstack/services/stepfunctions/usage.py rename to localstack-core/localstack/services/stepfunctions/analytics.py index 63c5c90411b40..c96b2c140af13 100644 --- a/localstack-core/localstack/services/stepfunctions/usage.py +++ b/localstack-core/localstack/services/stepfunctions/analytics.py @@ -2,10 +2,10 @@ Usage reporting for StepFunctions service """ -from localstack.utils.analytics.metrics import Counter +from localstack.utils.analytics.metrics import LabeledCounter # Initialize a counter to record the usage of language features for each state machine. -language_features_counter = Counter( +language_features_counter = LabeledCounter( namespace="stepfunctions", name="language_features_used", labels=["query_language", "uses_variables"], diff --git a/localstack-core/localstack/services/stepfunctions/asl/static_analyser/usage_metrics_static_analyser.py b/localstack-core/localstack/services/stepfunctions/asl/static_analyser/usage_metrics_static_analyser.py index b19fd0d4bf420..65d5029e137c7 100644 --- a/localstack-core/localstack/services/stepfunctions/asl/static_analyser/usage_metrics_static_analyser.py +++ b/localstack-core/localstack/services/stepfunctions/asl/static_analyser/usage_metrics_static_analyser.py @@ -3,7 +3,7 @@ import logging from typing import Final -import localstack.services.stepfunctions.usage as UsageMetrics +from localstack.services.stepfunctions import analytics from localstack.services.stepfunctions.asl.antlr.runtime.ASLParser import ASLParser from localstack.services.stepfunctions.asl.component.common.query_language import ( QueryLanguageMode, @@ -40,7 +40,7 @@ def process(definition: str) -> UsageMetricsStaticAnalyser: uses_variables = analyser.uses_variables # Count. - UsageMetrics.language_features_counter.labels( + analytics.language_features_counter.labels( query_language=language_used, uses_variables=uses_variables ).increment() except Exception as e: diff --git a/localstack-core/localstack/utils/analytics/metrics.py b/localstack-core/localstack/utils/analytics/metrics.py deleted file mode 100644 index 87a52e593547e..0000000000000 --- a/localstack-core/localstack/utils/analytics/metrics.py +++ /dev/null @@ -1,373 +0,0 @@ -from __future__ import annotations - -import datetime -import logging -import threading -from abc import ABC, abstractmethod -from collections import defaultdict -from dataclasses import dataclass -from typing import Any, Optional, Union, overload - -from localstack import config -from localstack.runtime import hooks -from localstack.utils.analytics import get_session_id -from localstack.utils.analytics.events import Event, EventMetadata -from localstack.utils.analytics.publisher import AnalyticsClientPublisher - -LOG = logging.getLogger(__name__) - - -@dataclass(frozen=True) -class MetricRegistryKey: - namespace: str - name: str - - -@dataclass(frozen=True) -class CounterPayload: - """An immutable snapshot of a counter metric at the time of collection.""" - - namespace: str - name: str - value: int - type: str - labels: Optional[dict[str, Union[str, float]]] = None - - def as_dict(self) -> dict[str, Any]: - result = { - "namespace": self.namespace, - "name": self.name, - "value": self.value, - "type": self.type, - } - - if self.labels: - # Convert labels to the expected format (label_1, label_1_value, etc.) - for i, (label_name, label_value) in enumerate(self.labels.items(), 1): - result[f"label_{i}"] = label_name - result[f"label_{i}_value"] = label_value - - return result - - -@dataclass -class MetricPayload: - """ - Stores all metric payloads collected during the execution of the LocalStack emulator. - Currently, supports only counter-type metrics, but designed to accommodate other types in the future. - """ - - _payload: list[CounterPayload] # support for other metric types may be added in the future. - - @property - def payload(self) -> list[CounterPayload]: - return self._payload - - def __init__(self, payload: list[CounterPayload]): - self._payload = payload - - def as_dict(self) -> dict[str, list[dict[str, Any]]]: - return {"metrics": [payload.as_dict() for payload in self._payload]} - - -class MetricRegistry: - """ - A Singleton class responsible for managing all registered metrics. - Provides methods for retrieving and collecting metrics. - """ - - _instance: "MetricRegistry" = None - _mutex: threading.Lock = threading.Lock() - - def __new__(cls): - # avoid locking if the instance already exist - if cls._instance is None: - with cls._mutex: - # Prevents race conditions when multiple threads enter the first check simultaneously - if cls._instance is None: - cls._instance = super().__new__(cls) - return cls._instance - - def __init__(self): - if not hasattr(self, "_registry"): - self._registry = dict() - - @property - def registry(self) -> dict[MetricRegistryKey, "Metric"]: - return self._registry - - def register(self, metric: Metric) -> None: - """ - Registers a new metric. - - :param metric: The metric instance to register. - :type metric: Metric - :raises TypeError: If the provided metric is not an instance of `Metric`. - :raises ValueError: If a metric with the same name already exists. - """ - if not isinstance(metric, Metric): - raise TypeError("Only subclasses of `Metric` can be registered.") - - if not metric.namespace: - raise ValueError("Metric 'namespace' must be defined and non-empty.") - - registry_unique_key = MetricRegistryKey(namespace=metric.namespace, name=metric.name) - if registry_unique_key in self._registry: - raise ValueError( - f"A metric named '{metric.name}' already exists in the '{metric.namespace}' namespace" - ) - - self._registry[registry_unique_key] = metric - - def collect(self) -> MetricPayload: - """ - Collects all registered metrics. - """ - payload = [ - metric - for metric_instance in self._registry.values() - for metric in metric_instance.collect() - ] - - return MetricPayload(payload=payload) - - -class Metric(ABC): - """ - Base class for all metrics (e.g., Counter, Gauge). - - Each subclass must implement the `collect()` method. - """ - - _namespace: str - _name: str - - def __init__(self, namespace: str, name: str): - if not namespace or namespace.strip() == "": - raise ValueError("Namespace must be non-empty string.") - self._namespace = namespace - - if not name or name.strip() == "": - raise ValueError("Metric name must be non-empty string.") - self._name = name - - @property - def namespace(self) -> str: - return self._namespace - - @property - def name(self) -> str: - return self._name - - @abstractmethod - def collect( - self, - ) -> list[CounterPayload]: # support for other metric types may be added in the future. - """ - Collects and returns metric data. Subclasses must implement this to return collected metric data. - """ - pass - - -class BaseCounter: - """ - A thread-safe counter for any kind of tracking. - This class should not be instantiated directly, use the Counter class instead. - """ - - _mutex: threading.Lock - _count: int - - def __init__(self): - super(BaseCounter, self).__init__() - self._mutex = threading.Lock() - self._count = 0 - - @property - def count(self) -> int: - return self._count - - def increment(self, value: int = 1) -> None: - """Increments the counter unless events are disabled.""" - if config.DISABLE_EVENTS: - return - - if value <= 0: - raise ValueError("Increment value must be positive.") - - with self._mutex: - self._count += value - - def reset(self) -> None: - """Resets the counter to zero unless events are disabled.""" - if config.DISABLE_EVENTS: - return - - with self._mutex: - self._count = 0 - - -class CounterMetric(Metric, BaseCounter): - """ - A thread-safe counter for tracking occurrences of an event without labels. - This class should not be instantiated directly, use the Counter class instead. - """ - - _type: str - - def __init__(self, namespace: str, name: str): - Metric.__init__(self, namespace=namespace, name=name) - BaseCounter.__init__(self) - - self._type = "counter" - MetricRegistry().register(self) - - def collect(self) -> list[CounterPayload]: - """Collects the metric unless events are disabled.""" - if config.DISABLE_EVENTS: - return list() - - if self._count == 0: - # Return an empty list if the count is 0, as there are no metrics to send to the analytics backend. - return list() - - return [ - CounterPayload( - namespace=self._namespace, name=self.name, value=self._count, type=self._type - ) - ] - - -class LabeledCounterMetric(Metric): - """ - A labeled counter that tracks occurrences of an event across different label combinations. - This class should not be instantiated directly, use the Counter class instead. - """ - - _type: str - _unit: str - _labels: list[str] - _label_values: tuple[Optional[Union[str, float]], ...] - _counters_by_label_values: defaultdict[tuple[Optional[Union[str, float]], ...], BaseCounter] - - def __init__(self, namespace: str, name: str, labels: list[str]): - super(LabeledCounterMetric, self).__init__(namespace=namespace, name=name) - - if not labels: - raise ValueError("At least one label is required; the labels list cannot be empty.") - - if any(not label for label in labels): - raise ValueError("Labels must be non-empty strings.") - - if len(labels) > 6: - raise ValueError("Too many labels: counters allow a maximum of 6.") - - self._type = "counter" - self._labels = labels - self._counters_by_label_values = defaultdict(BaseCounter) - MetricRegistry().register(self) - - def labels(self, **kwargs: Union[str, float, None]) -> BaseCounter: - """ - Create a scoped counter instance with specific label values. - - This method assigns values to the predefined labels of a labeled counter and returns - a BaseCounter object that allows tracking metrics for that specific - combination of label values. - - :raises ValueError: - - If the set of keys provided labels does not match the expected set of labels. - """ - if set(self._labels) != set(kwargs.keys()): - raise ValueError(f"Expected labels {self._labels}, got {list(kwargs.keys())}") - - _label_values = tuple(kwargs[label] for label in self._labels) - - return self._counters_by_label_values[_label_values] - - def collect(self) -> list[CounterPayload]: - if config.DISABLE_EVENTS: - return list() - - payload = [] - num_labels = len(self._labels) - - for label_values, counter in self._counters_by_label_values.items(): - if counter.count == 0: - continue # Skip items with a count of 0, as they should not be sent to the analytics backend. - - if len(label_values) != num_labels: - raise ValueError( - f"Label count mismatch: expected {num_labels} labels {self._labels}, " - f"but got {len(label_values)} values {label_values}." - ) - - # Create labels dictionary - labels_dict = { - label_name: label_value - for label_name, label_value in zip(self._labels, label_values) - } - - payload.append( - CounterPayload( - namespace=self._namespace, - name=self.name, - value=counter.count, - type=self._type, - labels=labels_dict, - ) - ) - - return payload - - -class Counter: - """ - A factory class for creating counter instances. - - This class provides a flexible way to create either a simple counter - (`CounterMetric`) or a labeled counter (`LabeledCounterMetric`) based on - whether labels are provided. - """ - - @overload - def __new__(cls, namespace: str, name: str) -> CounterMetric: - return CounterMetric(namespace=namespace, name=name) - - @overload - def __new__(cls, namespace: str, name: str, labels: list[str]) -> LabeledCounterMetric: - return LabeledCounterMetric(namespace=namespace, name=name, labels=labels) - - def __new__( - cls, namespace: str, name: str, labels: Optional[list[str]] = None - ) -> Union[CounterMetric, LabeledCounterMetric]: - if labels is not None: - return LabeledCounterMetric(namespace=namespace, name=name, labels=labels) - return CounterMetric(namespace=namespace, name=name) - - -@hooks.on_infra_shutdown() -def publish_metrics() -> None: - """ - Collects all the registered metrics and immediately sends them to the analytics service. - Skips execution if event tracking is disabled (`config.DISABLE_EVENTS`). - - This function is automatically triggered on infrastructure shutdown. - """ - if config.DISABLE_EVENTS: - return - - collected_metrics = MetricRegistry().collect() - if not collected_metrics.payload: # Skip publishing if no metrics remain after filtering - return - - metadata = EventMetadata( - session_id=get_session_id(), - client_time=str(datetime.datetime.now()), - ) - - if collected_metrics: - publisher = AnalyticsClientPublisher() - publisher.publish( - [Event(name="ls_metrics", metadata=metadata, payload=collected_metrics.as_dict())] - ) diff --git a/localstack-core/localstack/utils/analytics/metrics/__init__.py b/localstack-core/localstack/utils/analytics/metrics/__init__.py new file mode 100644 index 0000000000000..2d935429e982b --- /dev/null +++ b/localstack-core/localstack/utils/analytics/metrics/__init__.py @@ -0,0 +1,6 @@ +"""LocalStack metrics instrumentation framework""" + +from .counter import Counter, LabeledCounter +from .registry import MetricRegistry, MetricRegistryKey + +__all__ = ["Counter", "LabeledCounter", "MetricRegistry", "MetricRegistryKey"] diff --git a/localstack-core/localstack/utils/analytics/metrics/api.py b/localstack-core/localstack/utils/analytics/metrics/api.py new file mode 100644 index 0000000000000..56125a9ddc472 --- /dev/null +++ b/localstack-core/localstack/utils/analytics/metrics/api.py @@ -0,0 +1,42 @@ +from __future__ import annotations + +from abc import ABC, abstractmethod +from typing import Any, Protocol + + +class Payload(Protocol): + def as_dict(self) -> dict[str, Any]: ... + + +class Metric(ABC): + """ + Base class for all metrics (e.g., Counter, Gauge). + Each subclass must implement the `collect()` method. + """ + + _namespace: str + _name: str + + def __init__(self, namespace: str, name: str): + if not namespace or namespace.strip() == "": + raise ValueError("Namespace must be non-empty string.") + self._namespace = namespace + + if not name or name.strip() == "": + raise ValueError("Metric name must be non-empty string.") + self._name = name + + @property + def namespace(self) -> str: + return self._namespace + + @property + def name(self) -> str: + return self._name + + @abstractmethod + def collect(self) -> list[Payload]: + """ + Collects and returns metric data. Subclasses must implement this to return collected metric data. + """ + pass diff --git a/localstack-core/localstack/utils/analytics/metrics/counter.py b/localstack-core/localstack/utils/analytics/metrics/counter.py new file mode 100644 index 0000000000000..31b8a6a9de008 --- /dev/null +++ b/localstack-core/localstack/utils/analytics/metrics/counter.py @@ -0,0 +1,209 @@ +import threading +from collections import defaultdict +from dataclasses import dataclass +from typing import Any, Optional, Union + +from localstack import config + +from .api import Metric +from .registry import MetricRegistry + + +@dataclass(frozen=True) +class CounterPayload: + """A data object storing the value of a Counter metric.""" + + namespace: str + name: str + value: int + type: str + + def as_dict(self) -> dict[str, Any]: + return { + "namespace": self.namespace, + "name": self.name, + "value": self.value, + "type": self.type, + } + + +@dataclass(frozen=True) +class LabeledCounterPayload: + """A data object storing the value of a LabeledCounter metric.""" + + namespace: str + name: str + value: int + type: str + labels: dict[str, Union[str, float]] + + def as_dict(self) -> dict[str, Any]: + payload_dict = { + "namespace": self.namespace, + "name": self.name, + "value": self.value, + "type": self.type, + } + + for i, (label_name, label_value) in enumerate(self.labels.items(), 1): + payload_dict[f"label_{i}"] = label_name + payload_dict[f"label_{i}_value"] = label_value + + return payload_dict + + +class ThreadSafeCounter: + """ + A thread-safe counter for any kind of tracking. + This class should not be instantiated directly, use Counter or LabeledCounter instead. + """ + + _mutex: threading.Lock + _count: int + + def __init__(self): + super(ThreadSafeCounter, self).__init__() + self._mutex = threading.Lock() + self._count = 0 + + @property + def count(self) -> int: + return self._count + + def increment(self, value: int = 1) -> None: + """Increments the counter unless events are disabled.""" + if config.DISABLE_EVENTS: + return + + if value <= 0: + raise ValueError("Increment value must be positive.") + + with self._mutex: + self._count += value + + def reset(self) -> None: + """Resets the counter to zero unless events are disabled.""" + if config.DISABLE_EVENTS: + return + + with self._mutex: + self._count = 0 + + +class Counter(Metric, ThreadSafeCounter): + """ + A thread-safe, unlabeled counter for tracking the total number of occurrences of a specific event. + This class is intended for metrics that do not require differentiation across dimensions. + For use cases where metrics need to be grouped or segmented by labels, use `LabeledCounter` instead. + """ + + _type: str + + def __init__(self, namespace: str, name: str): + Metric.__init__(self, namespace=namespace, name=name) + ThreadSafeCounter.__init__(self) + + self._type = "counter" + + MetricRegistry().register(self) + + def collect(self) -> list[CounterPayload]: + """Collects the metric unless events are disabled.""" + if config.DISABLE_EVENTS: + return list() + + if self._count == 0: + # Return an empty list if the count is 0, as there are no metrics to send to the analytics backend. + return list() + + return [ + CounterPayload( + namespace=self._namespace, name=self.name, value=self._count, type=self._type + ) + ] + + +class LabeledCounter(Metric): + """ + A thread-safe counter for tracking occurrences of an event across multiple combinations of label values. + It enables fine-grained metric collection and analysis, with each unique label set stored and counted independently. + Use this class when you need dimensional insights into event occurrences. + For simpler, unlabeled use cases, see the `Counter` class. + """ + + _type: str + _labels: list[str] + _label_values: tuple[Optional[Union[str, float]], ...] + _counters_by_label_values: defaultdict[ + tuple[Optional[Union[str, float]], ...], ThreadSafeCounter + ] + + def __init__(self, namespace: str, name: str, labels: list[str]): + super(LabeledCounter, self).__init__(namespace=namespace, name=name) + + if not labels: + raise ValueError("At least one label is required; the labels list cannot be empty.") + + if any(not label for label in labels): + raise ValueError("Labels must be non-empty strings.") + + if len(labels) > 6: + raise ValueError("Too many labels: counters allow a maximum of 6.") + + self._type = "counter" + self._labels = labels + self._counters_by_label_values = defaultdict(ThreadSafeCounter) + MetricRegistry().register(self) + + def labels(self, **kwargs: Union[str, float, None]) -> ThreadSafeCounter: + """ + Create a scoped counter instance with specific label values. + + This method assigns values to the predefined labels of a labeled counter and returns + a ThreadSafeCounter object that allows tracking metrics for that specific + combination of label values. + + :raises ValueError: + - If the set of keys provided labels does not match the expected set of labels. + """ + if set(self._labels) != set(kwargs.keys()): + raise ValueError(f"Expected labels {self._labels}, got {list(kwargs.keys())}") + + _label_values = tuple(kwargs[label] for label in self._labels) + + return self._counters_by_label_values[_label_values] + + def collect(self) -> list[LabeledCounterPayload]: + if config.DISABLE_EVENTS: + return list() + + payload = [] + num_labels = len(self._labels) + + for label_values, counter in self._counters_by_label_values.items(): + if counter.count == 0: + continue # Skip items with a count of 0, as they should not be sent to the analytics backend. + + if len(label_values) != num_labels: + raise ValueError( + f"Label count mismatch: expected {num_labels} labels {self._labels}, " + f"but got {len(label_values)} values {label_values}." + ) + + # Create labels dictionary + labels_dict = { + label_name: label_value + for label_name, label_value in zip(self._labels, label_values) + } + + payload.append( + LabeledCounterPayload( + namespace=self._namespace, + name=self.name, + value=counter.count, + type=self._type, + labels=labels_dict, + ) + ) + + return payload diff --git a/localstack-core/localstack/utils/analytics/metrics/publisher.py b/localstack-core/localstack/utils/analytics/metrics/publisher.py new file mode 100644 index 0000000000000..52639fbc80e93 --- /dev/null +++ b/localstack-core/localstack/utils/analytics/metrics/publisher.py @@ -0,0 +1,36 @@ +from datetime import datetime + +from localstack import config +from localstack.runtime import hooks +from localstack.utils.analytics import get_session_id +from localstack.utils.analytics.events import Event, EventMetadata +from localstack.utils.analytics.publisher import AnalyticsClientPublisher + +from .registry import MetricRegistry + + +@hooks.on_infra_shutdown() +def publish_metrics() -> None: + """ + Collects all the registered metrics and immediately sends them to the analytics service. + Skips execution if event tracking is disabled (`config.DISABLE_EVENTS`). + + This function is automatically triggered on infrastructure shutdown. + """ + if config.DISABLE_EVENTS: + return + + collected_metrics = MetricRegistry().collect() + if not collected_metrics.payload: # Skip publishing if no metrics remain after filtering + return + + metadata = EventMetadata( + session_id=get_session_id(), + client_time=str(datetime.now()), + ) + + if collected_metrics: + publisher = AnalyticsClientPublisher() + publisher.publish( + [Event(name="ls_metrics", metadata=metadata, payload=collected_metrics.as_dict())] + ) diff --git a/localstack-core/localstack/utils/analytics/metrics/registry.py b/localstack-core/localstack/utils/analytics/metrics/registry.py new file mode 100644 index 0000000000000..50f23c345ad67 --- /dev/null +++ b/localstack-core/localstack/utils/analytics/metrics/registry.py @@ -0,0 +1,97 @@ +from __future__ import annotations + +import logging +import threading +from dataclasses import dataclass +from typing import Any + +from .api import Metric, Payload + +LOG = logging.getLogger(__name__) + + +@dataclass +class MetricPayload: + """ + A data object storing the value of all metrics collected during the execution of the application. + """ + + _payload: list[Payload] + + @property + def payload(self) -> list[Payload]: + return self._payload + + def __init__(self, payload: list[Payload]): + self._payload = payload + + def as_dict(self) -> dict[str, list[dict[str, Any]]]: + return {"metrics": [payload.as_dict() for payload in self._payload]} + + +@dataclass(frozen=True) +class MetricRegistryKey: + """A unique identifier for a metric, composed of namespace and name.""" + + namespace: str + name: str + + +class MetricRegistry: + """ + A Singleton class responsible for managing all registered metrics. + Provides methods for retrieving and collecting metrics. + """ + + _instance: "MetricRegistry" = None + _mutex: threading.Lock = threading.Lock() + + def __new__(cls): + # avoid locking if the instance already exist + if cls._instance is None: + with cls._mutex: + # Prevents race conditions when multiple threads enter the first check simultaneously + if cls._instance is None: + cls._instance = super().__new__(cls) + return cls._instance + + def __init__(self): + if not hasattr(self, "_registry"): + self._registry = dict() + + @property + def registry(self) -> dict[MetricRegistryKey, Metric]: + return self._registry + + def register(self, metric: Metric) -> None: + """ + Registers a metric instance. + + Raises a TypeError if the object is not a Metric, + or a ValueError if a metric with the same namespace and name is already registered + """ + if not isinstance(metric, Metric): + raise TypeError("Only subclasses of `Metric` can be registered.") + + if not metric.namespace: + raise ValueError("Metric 'namespace' must be defined and non-empty.") + + registry_unique_key = MetricRegistryKey(namespace=metric.namespace, name=metric.name) + if registry_unique_key in self._registry: + raise ValueError( + f"A metric named '{metric.name}' already exists in the '{metric.namespace}' namespace" + ) + + self._registry[registry_unique_key] = metric + + def collect(self) -> MetricPayload: + """ + Collects all registered metrics. + """ + payload = [ + metric + for metric_instance in self._registry.values() + for metric in metric_instance.collect() + ] + + return MetricPayload(payload=payload) diff --git a/tests/unit/utils/analytics/test_metrics.py b/tests/unit/utils/analytics/test_metrics.py index cc15499768381..8bdec6df31ca9 100644 --- a/tests/unit/utils/analytics/test_metrics.py +++ b/tests/unit/utils/analytics/test_metrics.py @@ -4,6 +4,7 @@ from localstack.utils.analytics.metrics import ( Counter, + LabeledCounter, MetricRegistry, MetricRegistryKey, ) @@ -34,7 +35,7 @@ def test_counter_reset(): def test_labeled_counter_increment(): - labeled_counter = Counter( + labeled_counter = LabeledCounter( namespace="test_namespace", name="test_multilabel_counter", labels=["status"] ) labeled_counter.labels(status="success").increment(value=2) @@ -53,7 +54,7 @@ def test_labeled_counter_increment(): def test_labeled_counter_reset(): - labeled_counter = Counter( + labeled_counter = LabeledCounter( namespace="test_namespace", name="test_multilabel_counter", labels=["status"] ) labeled_counter.labels(status="success").increment(value=5) @@ -83,7 +84,7 @@ def test_counter_when_events_disabled(disable_analytics): def test_labeled_counter_when_events_disabled_(disable_analytics): - labeled_counter = Counter( + labeled_counter = LabeledCounter( namespace="test_namespace", name="test_multilabel_counter", labels=["status"] ) labeled_counter.labels(status="status").increment(value=5) @@ -138,7 +139,7 @@ def increment(): def test_max_labels_limit(): with pytest.raises(ValueError, match="Too many labels: counters allow a maximum of 6."): - Counter( + LabeledCounter( namespace="test_namespace", name="test_counter", labels=["l1", "l2", "l3", "l4", "l5", "l6", "l7"], @@ -165,24 +166,26 @@ def test_counter_raises_if_label_values_off(): with pytest.raises( ValueError, match="At least one label is required; the labels list cannot be empty." ): - Counter(namespace="test_namespace", name="test_counter", labels=[]).labels(l1="a") + LabeledCounter(namespace="test_namespace", name="test_counter", labels=[]).labels(l1="a") with pytest.raises(ValueError): - Counter(namespace="test_namespace", name="test_counter", labels=["l1", "l2"]).labels( + LabeledCounter(namespace="test_namespace", name="test_counter", labels=["l1", "l2"]).labels( l1="a", non_existing="asdf" ) with pytest.raises(ValueError): - Counter(namespace="test_namespace", name="test_counter", labels=["l1", "l2"]).labels(l1="a") + LabeledCounter(namespace="test_namespace", name="test_counter", labels=["l1", "l2"]).labels( + l1="a" + ) with pytest.raises(ValueError): - Counter(namespace="test_namespace", name="test_counter", labels=["l1", "l2"]).labels( + LabeledCounter(namespace="test_namespace", name="test_counter", labels=["l1", "l2"]).labels( l1="a", l2="b", l3="c" ) def test_label_kwargs_order_independent(): - labeled_counter = Counter( + labeled_counter = LabeledCounter( namespace="test_namespace", name="test_multilabel_counter", labels=["status", "type"] ) labeled_counter.labels(status="success", type="counter").increment(value=2) From 75c84f6d19f5427b9597eb9ae8a164e156f9c416 Mon Sep 17 00:00:00 2001 From: Simon Walker Date: Wed, 11 Jun 2025 12:43:10 +0100 Subject: [PATCH 23/74] CFn v2: Implement stack deletion (#12576) --- .../engine/v2/change_set_model_executor.py | 43 +++++++------ .../services/cloudformation/v2/entities.py | 3 + .../services/cloudformation/v2/provider.py | 52 +++++++++++++--- .../resource_providers/aws_kinesis_stream.py | 2 +- .../v2/ported_from_v1/api/test_changesets.py | 5 +- .../api/test_changesets.snapshot.json | 15 +++++ .../api/test_changesets.validation.json | 8 ++- .../v2/ported_from_v1/api/test_stacks.py | 6 +- .../v2/ported_from_v1/api/test_templates.py | 2 +- .../resources/test_cloudwatch.py | 22 +++---- .../ported_from_v1/resources/test_dynamodb.py | 18 +++--- .../v2/ported_from_v1/resources/test_ec2.py | 62 +++++++++---------- .../ported_from_v1/resources/test_events.py | 14 ++--- .../ported_from_v1/resources/test_kinesis.py | 11 ++-- .../v2/ported_from_v1/resources/test_kms.py | 19 +++--- .../ported_from_v1/resources/test_lambda.py | 21 +++---- .../v2/ported_from_v1/resources/test_logs.py | 7 +-- .../v2/ported_from_v1/resources/test_s3.py | 15 +++-- .../resources/test_secretsmanager.py | 12 ++-- .../v2/ported_from_v1/resources/test_sns.py | 11 ++-- .../v2/ported_from_v1/resources/test_sqs.py | 12 ++-- .../v2/ported_from_v1/resources/test_ssm.py | 10 +-- .../resources/test_stepfunctions.py | 11 ++-- 23 files changed, 214 insertions(+), 167 deletions(-) diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py index d80b7e5ecf067..96c936a3cf037 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py @@ -115,7 +115,7 @@ def visit_node_depends_on(self, node_depends_on: NodeDependsOn) -> PreprocEntity node_resource = self._get_node_resource_for( resource_name=depends_on_resource_logical_id, node_template=self._node_template ) - self.visit_node_resource(node_resource) + self.visit(node_resource) return array_identifiers_delta @@ -257,6 +257,7 @@ def _execute_resource_action( resource_provider = resource_provider_executor.try_load_resource_provider(resource_type) extra_resource_properties = {} + event = ProgressEvent(OperationStatus.SUCCESS, resource_model={}) if resource_provider is not None: # TODO: stack events try: @@ -271,11 +272,15 @@ def _execute_resource_action( exc_info=LOG.isEnabledFor(logging.DEBUG), ) stack = self._change_set.stack - stack_status = stack.status - if stack_status == StackStatus.CREATE_IN_PROGRESS: - stack.set_stack_status(StackStatus.CREATE_FAILED, reason=reason) - elif stack_status == StackStatus.UPDATE_IN_PROGRESS: - stack.set_stack_status(StackStatus.UPDATE_FAILED, reason=reason) + match stack.status: + case StackStatus.CREATE_IN_PROGRESS: + stack.set_stack_status(StackStatus.CREATE_FAILED, reason=reason) + case StackStatus.UPDATE_IN_PROGRESS: + stack.set_stack_status(StackStatus.UPDATE_FAILED, reason=reason) + case StackStatus.DELETE_IN_PROGRESS: + stack.set_stack_status(StackStatus.DELETE_FAILED, reason=reason) + case _: + raise NotImplementedError(f"Unexpected stack status: {stack.status}") # update resource status stack.set_resource_status( logical_resource_id=logical_resource_id, @@ -288,8 +293,6 @@ def _execute_resource_action( resource_status_reason=reason, ) return - else: - event = ProgressEvent(OperationStatus.SUCCESS, resource_model={}) self.resources.setdefault(logical_resource_id, {"Properties": {}}) match event.status: @@ -341,13 +344,15 @@ def _execute_resource_action( ) # TODO: duplication stack = self._change_set.stack - stack_status = stack.status - if stack_status == StackStatus.CREATE_IN_PROGRESS: - stack.set_stack_status(StackStatus.CREATE_FAILED, reason=reason) - elif stack_status == StackStatus.UPDATE_IN_PROGRESS: - stack.set_stack_status(StackStatus.UPDATE_FAILED, reason=reason) - else: - raise NotImplementedError(f"Unhandled stack status: '{stack.status}'") + match stack.status: + case StackStatus.CREATE_IN_PROGRESS: + stack.set_stack_status(StackStatus.CREATE_FAILED, reason=reason) + case StackStatus.UPDATE_IN_PROGRESS: + stack.set_stack_status(StackStatus.UPDATE_FAILED, reason=reason) + case StackStatus.DELETE_IN_PROGRESS: + stack.set_stack_status(StackStatus.DELETE_FAILED, reason=reason) + case _: + raise NotImplementedError(f"Unhandled stack status: '{stack.status}'") stack.set_resource_status( logical_resource_id=logical_resource_id, # TODO @@ -358,8 +363,8 @@ def _execute_resource_action( else ResourceStatus.UPDATE_FAILED, resource_status_reason=reason, ) - case any: - raise NotImplementedError(f"Event status '{any}' not handled") + case other: + raise NotImplementedError(f"Event status '{other}' not handled") def create_resource_provider_payload( self, @@ -387,7 +392,9 @@ def create_resource_provider_payload( previous_resource_properties = before_properties_value or {} case ChangeAction.Remove: resource_properties = before_properties_value or {} - previous_resource_properties = None + # previous_resource_properties = None + # HACK: our providers use a mix of `desired_state` and `previous_state` so ensure the payload is present for both + previous_resource_properties = resource_properties case _: raise NotImplementedError(f"Action '{action}' not handled") diff --git a/localstack-core/localstack/services/cloudformation/v2/entities.py b/localstack-core/localstack/services/cloudformation/v2/entities.py index 481cbdbd9896c..fc3fa536221fa 100644 --- a/localstack-core/localstack/services/cloudformation/v2/entities.py +++ b/localstack-core/localstack/services/cloudformation/v2/entities.py @@ -43,6 +43,7 @@ class Stack: status_reason: StackStatusReason | None stack_id: str creation_time: datetime + deletion_time: datetime | None # state after deploy resolved_parameters: dict[str, str] @@ -67,6 +68,7 @@ def __init__( self.status_reason = None self.change_set_ids = change_set_ids or [] self.creation_time = datetime.now(tz=timezone.utc) + self.deletion_time = None self.stack_name = request_payload["StackName"] self.change_set_name = request_payload.get("ChangeSetName") @@ -118,6 +120,7 @@ def describe_details(self) -> ApiStack: result = { "ChangeSetId": self.change_set_id, "CreationTime": self.creation_time, + "DeletionTime": self.deletion_time, "StackId": self.stack_id, "StackName": self.stack_name, "StackStatus": self.status, diff --git a/localstack-core/localstack/services/cloudformation/v2/provider.py b/localstack-core/localstack/services/cloudformation/v2/provider.py index 07f09a0cd2ae5..373c6bf02336e 100644 --- a/localstack-core/localstack/services/cloudformation/v2/provider.py +++ b/localstack-core/localstack/services/cloudformation/v2/provider.py @@ -1,5 +1,6 @@ import copy import logging +from datetime import datetime, timezone from typing import Any from localstack.aws.api import RequestContext, handler @@ -101,7 +102,7 @@ def find_change_set_v2( # TODO: check for active stacks if ( stack_candidate.stack_name == stack_name - and stack.status != StackStatus.DELETE_COMPLETE + and stack_candidate.status != StackStatus.DELETE_COMPLETE ): stack = stack_candidate break @@ -175,10 +176,10 @@ def create_change_set( # on a CREATE an empty Stack should be generated if we didn't find an active one if not active_stack_candidates and change_set_type == ChangeSetType.CREATE: stack = Stack( - context.account_id, - context.region, - request, - structured_template, + account_id=context.account_id, + region_name=context.region, + request_payload=request, + template=structured_template, template_body=template_body, ) state.stacks_v2[stack.stack_id] = stack @@ -240,7 +241,7 @@ def create_change_set( after_template = structured_template # create change set for the stack and apply changes - change_set = ChangeSet(stack, request) + change_set = ChangeSet(stack, request, template=after_template) # only set parameters for the changeset, then switch to stack on execute_change_set change_set.populate_update_graph( @@ -309,6 +310,9 @@ def _run(*args): change_set.stack.resolved_resources = result.resources change_set.stack.resolved_parameters = result.parameters change_set.stack.resolved_outputs = result.outputs + # if the deployment succeeded, update the stack's template representation to that + # which was just deployed + change_set.stack.template = change_set.template except Exception as e: LOG.error( "Execute change set failed: %s", e, exc_info=LOG.isEnabledFor(logging.WARNING) @@ -458,5 +462,37 @@ def delete_stack( # aws will silently ignore invalid stack names - we should do the same return - # TODO: actually delete - stack.set_stack_status(StackStatus.DELETE_COMPLETE) + # shortcut for stacks which have no deployed resources i.e. where a change set was + # created, but never executed + if stack.status == StackStatus.REVIEW_IN_PROGRESS and not stack.resolved_resources: + stack.set_stack_status(StackStatus.DELETE_COMPLETE) + stack.deletion_time = datetime.now(tz=timezone.utc) + return + + # create a dummy change set + change_set = ChangeSet(stack, {"ChangeSetName": f"delete-stack_{stack.stack_name}"}) # noqa + change_set.populate_update_graph( + before_template=stack.template, + after_template=None, + before_parameters=stack.resolved_parameters, + after_parameters=None, + ) + + change_set_executor = ChangeSetModelExecutor(change_set) + + def _run(*args): + try: + stack.set_stack_status(StackStatus.DELETE_IN_PROGRESS) + change_set_executor.execute() + stack.set_stack_status(StackStatus.DELETE_COMPLETE) + stack.deletion_time = datetime.now(tz=timezone.utc) + except Exception as e: + LOG.warning( + "Failed to delete stack '%s': %s", + stack.stack_name, + e, + exc_info=LOG.isEnabledFor(logging.DEBUG), + ) + stack.set_stack_status(StackStatus.DELETE_FAILED) + + start_worker_thread(_run) diff --git a/localstack-core/localstack/services/kinesis/resource_providers/aws_kinesis_stream.py b/localstack-core/localstack/services/kinesis/resource_providers/aws_kinesis_stream.py index 27d18c1ff3fe3..28d231d666484 100644 --- a/localstack-core/localstack/services/kinesis/resource_providers/aws_kinesis_stream.py +++ b/localstack-core/localstack/services/kinesis/resource_providers/aws_kinesis_stream.py @@ -149,7 +149,7 @@ def delete( client.describe_stream(StreamARN=model["Arn"]) return ProgressEvent( status=OperationStatus.IN_PROGRESS, - resource_model={}, + resource_model=model, ) except client.exceptions.ResourceNotFoundException: return ProgressEvent( diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py index c244d6faf832d..0d513d4b2a89e 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py @@ -112,7 +112,6 @@ def test_simple_update_two_resources( res.destroy() - @pytest.mark.skip(reason="CFNV2:Destroy") @markers.aws.validated # TODO: the error response is incorrect, however the test is otherwise validated and raises # an error because the SSM parameter has been deleted (removed from the stack). @@ -576,7 +575,7 @@ def test_delete_change_set_exception(snapshot, aws_client): snapshot.match("e2", e2.value.response) -@pytest.mark.skip("CFNV2:Destroy") +@pytest.mark.skip("CFNV2:Other") @markers.aws.validated def test_create_delete_create(aws_client, cleanups, deploy_cfn_template): """test the re-use of a changeset name with a re-used stack name""" @@ -858,7 +857,7 @@ def _check_changeset_success(): snapshot.match("error_execute_failed", e.value) -@pytest.mark.skip(reason="CFNV2:Destroy") +@pytest.mark.skip(reason="CFNV2:Other delete change set not implemented yet") @markers.aws.validated def test_deleted_changeset(snapshot, cleanups, aws_client): """simple case verifying that proper exception is thrown when trying to get a deleted changeset""" diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.snapshot.json b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.snapshot.json index 3ccc591fb8bc4..930b1ff1e8b93 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.snapshot.json +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.snapshot.json @@ -498,5 +498,20 @@ } } } + }, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::TestUpdates::test_deleting_resource": { + "recorded-date": "02-06-2025, 10:29:41", + "recorded-content": { + "get-parameter-error": { + "Error": { + "Code": "ParameterNotFound", + "Message": "" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 400 + } + } + } } } diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.validation.json b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.validation.json index 9f9ab423100bd..fe83ba323389a 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.validation.json +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.validation.json @@ -42,7 +42,13 @@ "last_validated_date": "2025-04-01T16:40:03+00:00" }, "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::TestUpdates::test_deleting_resource": { - "last_validated_date": "2025-04-15T15:07:18+00:00" + "last_validated_date": "2025-06-02T10:29:46+00:00", + "durations_in_seconds": { + "setup": 1.06, + "call": 20.61, + "teardown": 4.46, + "total": 26.13 + } }, "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::TestUpdates::test_simple_update_two_resources": { "last_validated_date": "2025-04-02T10:05:26+00:00" diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py index 4fafe63d85c00..1403570249c2e 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py @@ -26,7 +26,7 @@ class TestStacksApi: - @pytest.mark.skip(reason="CFNV2:Destroy") + @pytest.mark.skip(reason="CFNV2:Other") @markers.snapshot.skip_snapshot_verify( paths=["$..ChangeSetId", "$..EnableTerminationProtection"] ) @@ -445,7 +445,7 @@ def _assert_stack_process_finished(): ] assert len(updated_resources) == length_expected - @pytest.mark.skip(reason="CFNV2:Destroy") + @pytest.mark.skip(reason="CFNV2:Other") @markers.aws.only_localstack def test_create_stack_with_custom_id( self, aws_client, cleanups, account_id, region_name, set_resource_custom_id @@ -870,7 +870,7 @@ def test_describe_stack_events_errors(aws_client, snapshot): TEMPLATE_ORDER_CASES = list(permutations(["A", "B", "C"])) -@pytest.mark.skip(reason="CFNV2:Destroy") +@pytest.mark.skip(reason="CFNV2:Other stack events") @markers.aws.validated @markers.snapshot.skip_snapshot_verify( paths=[ diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_templates.py b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_templates.py index 75c76510b9c26..7ea4c1cdf922f 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_templates.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_templates.py @@ -39,7 +39,7 @@ def test_get_template_summary(deploy_cfn_template, snapshot, aws_client): snapshot.match("template-summary", res) -@pytest.mark.skip(reason="CFNV2:Other, CFNV2:Destroy") +@pytest.mark.skip(reason="CFNV2:Other") @markers.aws.validated @pytest.mark.parametrize("url_style", ["s3_url", "http_path", "http_host", "http_invalid"]) def test_create_stack_from_s3_template_url( diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_cloudwatch.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_cloudwatch.py index 1f64b3c1a97e5..d1acf12c8a064 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_cloudwatch.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_cloudwatch.py @@ -92,14 +92,13 @@ def alarm_action_name_transformer(key: str, val: str): response = aws_client.cloudwatch.describe_alarms(AlarmNames=[metric_alarm_name]) snapshot.match("metric_alarm", response["MetricAlarms"]) - # CFNV2:Destroy does not destroy resources. - # stack.destroy() - # response = aws_client.cloudwatch.describe_alarms( - # AlarmNames=[composite_alarm_name], AlarmTypes=["CompositeAlarm"] - # ) - # assert not response["CompositeAlarms"] - # response = aws_client.cloudwatch.describe_alarms(AlarmNames=[metric_alarm_name]) - # assert not response["MetricAlarms"] + stack.destroy() + response = aws_client.cloudwatch.describe_alarms( + AlarmNames=[composite_alarm_name], AlarmTypes=["CompositeAlarm"] + ) + assert not response["CompositeAlarms"] + response = aws_client.cloudwatch.describe_alarms(AlarmNames=[metric_alarm_name]) + assert not response["MetricAlarms"] @markers.aws.validated @@ -114,7 +113,6 @@ def test_alarm_ext_statistic(aws_client, deploy_cfn_template, snapshot): response = aws_client.cloudwatch.describe_alarms(AlarmNames=[alarm_name]) snapshot.match("simple_alarm", response["MetricAlarms"]) - # CFNV2:Destroy does not destroy resources. - # stack.destroy() - # response = aws_client.cloudwatch.describe_alarms(AlarmNames=[alarm_name]) - # assert not response["MetricAlarms"] + stack.destroy() + response = aws_client.cloudwatch.describe_alarms(AlarmNames=[alarm_name]) + assert not response["MetricAlarms"] diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_dynamodb.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_dynamodb.py index 0f9248f73f2f7..ed2e5fb25196d 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_dynamodb.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_dynamodb.py @@ -37,10 +37,9 @@ def test_deploy_stack_with_dynamodb_table(deploy_cfn_template, aws_client, regio rs = aws_client.dynamodb.list_tables() assert ddb_table_name in rs["TableNames"] - # CFNV2:Destroy does not destroy resources. - # stack.destroy() - # rs = aws_client.dynamodb.list_tables() - # assert ddb_table_name not in rs["TableNames"] + stack.destroy() + rs = aws_client.dynamodb.list_tables() + assert ddb_table_name not in rs["TableNames"] @markers.aws.validated @@ -141,14 +140,13 @@ def test_global_table(deploy_cfn_template, snapshot, aws_client): response = aws_client.dynamodb.describe_table(TableName=stack.outputs["TableName"]) snapshot.match("table_description", response) - # CFNV2:Destroy does not destroy resources. - # stack.destroy() + stack.destroy() - # with pytest.raises(Exception) as ex: - # aws_client.dynamodb.describe_table(TableName=stack.outputs["TableName"]) + with pytest.raises(Exception) as ex: + aws_client.dynamodb.describe_table(TableName=stack.outputs["TableName"]) - # error_code = ex.value.response["Error"]["Code"] - # assert "ResourceNotFoundException" == error_code + error_code = ex.value.response["Error"]["Code"] + assert "ResourceNotFoundException" == error_code @pytest.mark.skip(reason="CFNV2:Other") diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ec2.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ec2.py index df1d786717ae0..e4e3690642f06 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ec2.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ec2.py @@ -37,10 +37,9 @@ def test_simple_route_table_creation_without_vpc(deploy_cfn_template, aws_client snapshot.add_transformer(snapshot.transform.key_value("VpcId", "vpc-id")) snapshot.add_transformer(snapshot.transform.key_value("RouteTableId", "vpc-id")) - # CFNV2:Destroy does not destroy resources. - # stack.destroy() - # with pytest.raises(ec2.exceptions.ClientError): - # ec2.describe_route_tables(RouteTableIds=[route_table_id]) + stack.destroy() + with pytest.raises(ec2.exceptions.ClientError): + ec2.describe_route_tables(RouteTableIds=[route_table_id]) @markers.aws.validated @@ -64,10 +63,9 @@ def test_simple_route_table_creation(deploy_cfn_template, aws_client, snapshot): snapshot.add_transformer(snapshot.transform.key_value("VpcId", "vpc-id")) snapshot.add_transformer(snapshot.transform.key_value("RouteTableId", "vpc-id")) - # CFNV2:Destroy does not destroy resources. - # stack.destroy() - # with pytest.raises(ec2.exceptions.ClientError): - # ec2.describe_route_tables(RouteTableIds=[route_table_id]) + stack.destroy() + with pytest.raises(ec2.exceptions.ClientError): + ec2.describe_route_tables(RouteTableIds=[route_table_id]) @pytest.mark.skip(reason="CFNV2:Other") @@ -198,27 +196,26 @@ def test_transit_gateway_attachment(deploy_cfn_template, aws_client, snapshot): snapshot.match("attachment", attachment_description["TransitGatewayAttachments"][0]) snapshot.match("gateway", gateway_description["TransitGateways"][0]) - # CFNV2:Destroy does not destroy resources. - # stack.destroy() - - # descriptions = aws_client.ec2.describe_transit_gateways( - # TransitGatewayIds=[stack.outputs["TransitGateway"]] - # ) - # if is_aws_cloud(): - # # aws changes the state to deleted - # descriptions = descriptions["TransitGateways"][0] - # assert descriptions["State"] == "deleted" - # else: - # # moto directly deletes the transit gateway - # transit_gateways_ids = [ - # tgateway["TransitGatewayId"] for tgateway in descriptions["TransitGateways"] - # ] - # assert stack.outputs["TransitGateway"] not in transit_gateways_ids - - # attachment_description = aws_client.ec2.describe_transit_gateway_attachments( - # TransitGatewayAttachmentIds=[stack.outputs["Attachment"]] - # )["TransitGatewayAttachments"] - # assert attachment_description[0]["State"] == "deleted" + stack.destroy() + + descriptions = aws_client.ec2.describe_transit_gateways( + TransitGatewayIds=[stack.outputs["TransitGateway"]] + ) + if is_aws_cloud(): + # aws changes the state to deleted + descriptions = descriptions["TransitGateways"][0] + assert descriptions["State"] == "deleted" + else: + # moto directly deletes the transit gateway + transit_gateways_ids = [ + tgateway["TransitGatewayId"] for tgateway in descriptions["TransitGateways"] + ] + assert stack.outputs["TransitGateway"] not in transit_gateways_ids + + attachment_description = aws_client.ec2.describe_transit_gateway_attachments( + TransitGatewayAttachmentIds=[stack.outputs["Attachment"]] + )["TransitGatewayAttachments"] + assert attachment_description[0]["State"] == "deleted" @markers.aws.validated @@ -247,11 +244,10 @@ def test_vpc_with_route_table(deploy_cfn_template, aws_client, snapshot): snapshot.add_transformer(snapshot.transform.key_value("RouteTableId")) snapshot.add_transformer(snapshot.transform.key_value("VpcId")) - # CFNV2:Destroy does not destroy resources. - # stack.destroy() + stack.destroy() - # with pytest.raises(aws_client.ec2.exceptions.ClientError): - # aws_client.ec2.describe_route_tables(RouteTableIds=[route_id]) + with pytest.raises(aws_client.ec2.exceptions.ClientError): + aws_client.ec2.describe_route_tables(RouteTableIds=[route_id]) @pytest.mark.skip(reason="update doesn't change value for instancetype") diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_events.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_events.py index 75c648f00903c..77a2bdeb9dcc1 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_events.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_events.py @@ -36,7 +36,7 @@ def _assert(expected_len): ] assert len(api_destinations) == expected_len - deploy_cfn_template( + stack = deploy_cfn_template( template_path=os.path.join( os.path.dirname(__file__), "../../../../../templates/events_apidestination.yml" ), @@ -46,9 +46,8 @@ def _assert(expected_len): ) _assert(1) - # CFNV2:Destroy does not destroy resources. - # stack.destroy() - # _assert(0) + stack.destroy() + _assert(0) @pytest.mark.skip(reason="CFNV2:Other") @@ -198,16 +197,15 @@ def _assert(expected_len): connections = [con for con in rs["Connections"] if con["Name"] == "my-test-conn"] assert len(connections) == expected_len - deploy_cfn_template( + stack = deploy_cfn_template( template_path=os.path.join( os.path.dirname(__file__), "../../../../../templates/template31.yaml" ) ) _assert(1) - # CFNV2:Destroy does not destroy resources. - # stack.destroy() - # _assert(0) + stack.destroy() + _assert(0) @markers.aws.validated diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_kinesis.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_kinesis.py index ec4fb4f2f882a..63a9417ab8873 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_kinesis.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_kinesis.py @@ -101,14 +101,13 @@ def test_cfn_handle_kinesis_firehose_resources(deploy_cfn_template, aws_client): rs = aws_client.kinesis.describe_stream(StreamName=kinesis_stream_name) assert rs["StreamDescription"]["StreamName"] == kinesis_stream_name - # CFNV2:Destroy does not destroy resources. # clean up - # stack.destroy() + stack.destroy() - # rs = aws_client.kinesis.list_streams() - # assert kinesis_stream_name not in rs["StreamNames"] - # rs = aws_client.firehose.list_delivery_streams() - # assert firehose_stream_name not in rs["DeliveryStreamNames"] + rs = aws_client.kinesis.list_streams() + assert kinesis_stream_name not in rs["StreamNames"] + rs = aws_client.firehose.list_delivery_streams() + assert firehose_stream_name not in rs["DeliveryStreamNames"] # TODO: use a different template and move this test to a more generic API level test suite diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_kms.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_kms.py index 90f5a38515801..6625e3086df75 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_kms.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_kms.py @@ -6,6 +6,7 @@ from localstack.testing.aws.util import is_aws_cloud from localstack.testing.pytest import markers from localstack.utils.strings import short_uid +from localstack.utils.sync import retry pytestmark = pytest.mark.skipif( condition=not is_v2_engine() and not is_aws_cloud(), @@ -51,9 +52,8 @@ def _get_matching_aliases(): assert len(_get_matching_aliases()) == 1 - # CFNV2:Destroy does not destroy resources. - # stack.destroy() - # assert not _get_matching_aliases() + stack.destroy() + assert not _get_matching_aliases() @markers.aws.validated @@ -66,13 +66,12 @@ def test_deploy_stack_with_kms(deploy_cfn_template, aws_client): assert "KeyId" in stack.outputs - # key_id = stack.outputs["KeyId"] + key_id = stack.outputs["KeyId"] - # CFNV2:Destroy does not destroy resources. - # stack.destroy() + stack.destroy() - # def assert_key_deleted(): - # resp = aws_client.kms.describe_key(KeyId=key_id)["KeyMetadata"] - # assert resp["KeyState"] == "PendingDeletion" + def assert_key_deleted(): + resp = aws_client.kms.describe_key(KeyId=key_id)["KeyMetadata"] + assert resp["KeyState"] == "PendingDeletion" - # retry(assert_key_deleted, retries=5, sleep=5) + retry(assert_key_deleted, retries=5, sleep=5) diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py index 1ef4b43dca830..1d82ca41294dd 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py @@ -855,10 +855,9 @@ def wait_logs(): assert wait_until(wait_logs) - # CFNV2:Destroy does not destroy resources. - # deployment.destroy() - # with pytest.raises(aws_client.lambda_.exceptions.ResourceNotFoundException): - # aws_client.lambda_.get_event_source_mapping(UUID=esm_id) + deployment.destroy() + with pytest.raises(aws_client.lambda_.exceptions.ResourceNotFoundException): + aws_client.lambda_.get_event_source_mapping(UUID=esm_id) @pytest.mark.skip(reason="CFNV2:Other") # TODO: consider moving into the dedicated DynamoDB => Lambda tests because it tests the filtering functionality rather than CloudFormation (just using CF to deploy resources) @@ -1032,10 +1031,9 @@ def wait_logs(): assert wait_until(wait_logs) - # CFNV2:Destroy does not destroy resources. - # deployment.destroy() - # with pytest.raises(aws_client.lambda_.exceptions.ResourceNotFoundException): - # aws_client.lambda_.get_event_source_mapping(UUID=esm_id) + deployment.destroy() + with pytest.raises(aws_client.lambda_.exceptions.ResourceNotFoundException): + aws_client.lambda_.get_event_source_mapping(UUID=esm_id) @pytest.mark.skip(reason="CFNV2:Other") @markers.snapshot.skip_snapshot_verify( @@ -1161,11 +1159,10 @@ def wait_logs(): assert wait_until(wait_logs) - # CFNV2:Destroy does not destroy resources. - # deployment.destroy() + deployment.destroy() - # with pytest.raises(aws_client.lambda_.exceptions.ResourceNotFoundException): - # aws_client.lambda_.get_event_source_mapping(UUID=esm_id) + with pytest.raises(aws_client.lambda_.exceptions.ResourceNotFoundException): + aws_client.lambda_.get_event_source_mapping(UUID=esm_id) class TestCfnLambdaDestinations: diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_logs.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_logs.py index bde0f45355191..75afa2549b354 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_logs.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_logs.py @@ -55,7 +55,6 @@ def test_cfn_handle_log_group_resource(deploy_cfn_template, aws_client, snapshot snapshot.match("describe_log_groups", response) snapshot.add_transformer(snapshot.transform.key_value("logGroupName")) - # CFNV2:Destroy does not destroy resources. - # stack.destroy() - # response = aws_client.logs.describe_log_groups(logGroupNamePrefix=log_group_prefix) - # assert len(response["logGroups"]) == 0 + stack.destroy() + response = aws_client.logs.describe_log_groups(logGroupNamePrefix=log_group_prefix) + assert len(response["logGroups"]) == 0 diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_s3.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_s3.py index 76c5660e7b375..79ea1ba69ebd7 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_s3.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_s3.py @@ -145,13 +145,12 @@ def test_cfn_handle_s3_notification_configuration( rs = aws_client.s3.get_bucket_notification_configuration(Bucket=stack.outputs["BucketName"]) snapshot.match("get_bucket_notification_configuration", rs) - # CFNV2:Destroy does not destroy resources. - # stack.destroy() + stack.destroy() - # with pytest.raises(ClientError) as ctx: - # aws_client.s3.get_bucket_notification_configuration(Bucket=stack.outputs["BucketName"]) - # snapshot.match("get_bucket_notification_configuration_error", ctx.value.response) + with pytest.raises(ClientError) as ctx: + aws_client.s3.get_bucket_notification_configuration(Bucket=stack.outputs["BucketName"]) + snapshot.match("get_bucket_notification_configuration_error", ctx.value.response) - # snapshot.add_transformer(snapshot.transform.key_value("Id")) - # snapshot.add_transformer(snapshot.transform.key_value("QueueArn")) - # snapshot.add_transformer(snapshot.transform.key_value("BucketName")) + snapshot.add_transformer(snapshot.transform.key_value("Id")) + snapshot.add_transformer(snapshot.transform.key_value("QueueArn")) + snapshot.add_transformer(snapshot.transform.key_value("BucketName")) diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_secretsmanager.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_secretsmanager.py index fbed82fbf69e9..5388d26b94a29 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_secretsmanager.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_secretsmanager.py @@ -2,6 +2,7 @@ import os import aws_cdk as cdk +import botocore.exceptions import pytest from localstack.services.cloudformation.v2.utils import is_v2_engine @@ -42,7 +43,7 @@ def test_cfn_secretsmanager_gen_secret(deploy_cfn_template, aws_client, snapshot @markers.snapshot.skip_snapshot_verify(paths=["$..Tags", "$..VersionIdsToStages"]) def test_cfn_handle_secretsmanager_secret(deploy_cfn_template, aws_client, snapshot): secret_name = f"secret-{short_uid()}" - deploy_cfn_template( + stack = deploy_cfn_template( template_path=os.path.join( os.path.dirname(__file__), "../../../../../templates/secretsmanager_secret.yml" ), @@ -54,13 +55,12 @@ def test_cfn_handle_secretsmanager_secret(deploy_cfn_template, aws_client, snaps snapshot.add_transformer(snapshot.transform.regex(rf"{secret_name}-\w+", "")) snapshot.add_transformer(snapshot.transform.key_value("Name")) - # CFNV2:Destroy does not destroy resources. - # stack.destroy() + stack.destroy() - # with pytest.raises(botocore.exceptions.ClientError) as ex: - # aws_client.secretsmanager.describe_secret(SecretId=secret_name) + with pytest.raises(botocore.exceptions.ClientError) as ex: + aws_client.secretsmanager.describe_secret(SecretId=secret_name) - # snapshot.match("exception", ex.value.response) + snapshot.match("exception", ex.value.response) @markers.aws.validated diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sns.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sns.py index 5719f42f24081..0f60128cddb73 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sns.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sns.py @@ -102,13 +102,12 @@ def test_deploy_stack_with_sns_topic(deploy_cfn_template, aws_client): topics = [tp for tp in rs["Topics"] if tp["TopicArn"] == topic_arn] assert len(topics) == 1 - # CFNV2:Destroy does not destroy resources. - # stack.destroy() + stack.destroy() - # # assert topic resource removed - # rs = aws_client.sns.list_topics() - # topics = [tp for tp in rs["Topics"] if tp["TopicArn"] == topic_arn] - # assert not topics + # assert topic resource removed + rs = aws_client.sns.list_topics() + topics = [tp for tp in rs["Topics"] if tp["TopicArn"] == topic_arn] + assert not topics @markers.aws.validated diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sqs.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sqs.py index 0f76b40282c52..2599e2bb1f520 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sqs.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sqs.py @@ -1,6 +1,7 @@ import os import pytest +from botocore.exceptions import ClientError from localstack.services.cloudformation.v2.utils import is_v2_engine from localstack.testing.aws.util import is_aws_cloud @@ -68,13 +69,12 @@ def test_cfn_handle_sqs_resource(deploy_cfn_template, aws_client, snapshot): snapshot.match("queue", rs) snapshot.add_transformer(snapshot.transform.regex(queue_name, "")) - # CFNV2:Destroy does not destroy resources. - # # clean up - # stack.destroy() + # clean up + stack.destroy() - # with pytest.raises(ClientError) as ctx: - # aws_client.sqs.get_queue_url(QueueName=f"{queue_name}.fifo") - # snapshot.match("error", ctx.value.response) + with pytest.raises(ClientError) as ctx: + aws_client.sqs.get_queue_url(QueueName=f"{queue_name}.fifo") + snapshot.match("error", ctx.value.response) @markers.aws.validated diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ssm.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ssm.py index 58882a1cefab1..49effcdd8647e 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ssm.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ssm.py @@ -1,5 +1,6 @@ import os.path +import botocore.exceptions import pytest from localstack_snapshot.snapshots.transformer import SortingTransformer @@ -32,12 +33,11 @@ def test_parameter_defaults(deploy_cfn_template, aws_client, snapshot): snapshot.add_transformer(snapshot.transform.key_value("Name")) snapshot.add_transformer(snapshot.transform.key_value("Value")) - # CFNV2:Destroy does not destroy resources. - # stack.destroy() + stack.destroy() - # with pytest.raises(botocore.exceptions.ClientError) as ctx: - # aws_client.ssm.get_parameter(Name=parameter_name) - # snapshot.match("ssm_parameter_not_found", ctx.value.response) + with pytest.raises(botocore.exceptions.ClientError) as ctx: + aws_client.ssm.get_parameter(Name=parameter_name) + snapshot.match("ssm_parameter_not_found", ctx.value.response) @markers.aws.validated diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_stepfunctions.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_stepfunctions.py index 7dc070ee68eb3..034b8fce1bd9c 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_stepfunctions.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_stepfunctions.py @@ -269,7 +269,7 @@ def test_retry_and_catch(deploy_cfn_template, aws_client): def test_cfn_statemachine_with_dependencies(deploy_cfn_template, aws_client): sm_name = f"sm_{short_uid()}" activity_name = f"act_{short_uid()}" - deploy_cfn_template( + stack = deploy_cfn_template( template_path=os.path.join( os.path.dirname(__file__), "../../../../../templates/statemachine_machine_with_activity.yml", @@ -286,13 +286,12 @@ def test_cfn_statemachine_with_dependencies(deploy_cfn_template, aws_client): activities = [act for act in rs["activities"] if activity_name in act["name"]] assert len(activities) == 1 - # CFNV2:Destroy does not destroy resources. - # stack.destroy() + stack.destroy() - # rs = aws_client.stepfunctions.list_state_machines() - # statemachines = [sm for sm in rs["stateMachines"] if sm_name in sm["name"]] + rs = aws_client.stepfunctions.list_state_machines() + statemachines = [sm for sm in rs["stateMachines"] if sm_name in sm["name"]] - # assert not statemachines + assert not statemachines @markers.aws.validated From 3a2f014f1ee56524611c48ad39e678c91231be2a Mon Sep 17 00:00:00 2001 From: Arthur Akhadov <48313237+ArthurAkh@users.noreply.github.com> Date: Wed, 11 Jun 2025 18:53:38 +0200 Subject: [PATCH 24/74] APIGW: add IntegrationResponse test and fix UpdateIntegrationResponse (#12743) Co-authored-by: Ben Simon Hartung <42031100+bentsku@users.noreply.github.com> --- .../services/apigateway/legacy/provider.py | 10 +++ .../apigateway/test_apigateway_api.py | 80 +++++++++++++++++ .../test_apigateway_api.snapshot.json | 85 +++++++++++++++++++ .../test_apigateway_api.validation.json | 9 ++ 4 files changed, 184 insertions(+) diff --git a/localstack-core/localstack/services/apigateway/legacy/provider.py b/localstack-core/localstack/services/apigateway/legacy/provider.py index 91c0a4df2105e..aede11a1580d8 100644 --- a/localstack-core/localstack/services/apigateway/legacy/provider.py +++ b/localstack-core/localstack/services/apigateway/legacy/provider.py @@ -631,6 +631,16 @@ def update_integration_response( elif "/contentHandling" in path and op == "replace": integration_response.content_handling = patch_operation.get("value") + elif "/selectionPattern" in path and op == "replace": + integration_response.selection_pattern = patch_operation.get("value") + + response: IntegrationResponse = integration_response.to_json() + # in case it's empty, we still want to pass it on as "" + # TODO: add a test case for this + response["selectionPattern"] = integration_response.selection_pattern + + return response + def update_resource( self, context: RequestContext, diff --git a/tests/aws/services/apigateway/test_apigateway_api.py b/tests/aws/services/apigateway/test_apigateway_api.py index 2ae1dc9571811..71f6aaa1886f8 100644 --- a/tests/aws/services/apigateway/test_apigateway_api.py +++ b/tests/aws/services/apigateway/test_apigateway_api.py @@ -2634,3 +2634,83 @@ def test_put_integration_request_parameter_bool_type( }, ) snapshot.match("put-integration-request-param-bool-value", e.value.response) + + @markers.aws.validated + def test_lifecycle_integration_response(self, aws_client, apigw_create_rest_api, snapshot): + snapshot.add_transformer(snapshot.transform.key_value("cacheNamespace")) + apigw_client = aws_client.apigateway + response = apigw_create_rest_api(name=f"test-api-{short_uid()}") + api_id = response["id"] + root_resource_id = response["rootResourceId"] + + apigw_client.put_method( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + authorizationType="NONE", + ) + apigw_client.put_integration( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + type="MOCK", + requestTemplates={"application/json": '{"statusCode": 200}'}, + ) + + put_response = apigw_client.put_integration_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + responseTemplates={"application/json": '"created"'}, + selectionPattern="", + ) + snapshot.match("put-integration-response", put_response) + + get_response = apigw_client.get_integration_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + ) + snapshot.match("get-integration-response", get_response) + + update_response = apigw_client.update_integration_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + patchOperations=[ + { + "op": "replace", + "path": "/selectionPattern", + "value": "updated-pattern", + } + ], + ) + snapshot.match("update-integration-response", update_response) + + overwrite_response = apigw_client.put_integration_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + responseTemplates={"application/json": "overwrite"}, + selectionPattern="overwrite-pattern", + ) + snapshot.match("overwrite-integration-response", overwrite_response) + + get_method = apigw_client.get_method( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + ) + snapshot.match("get-method", get_method) + + delete_response = apigw_client.delete_integration_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + ) + snapshot.match("delete-integration-response", delete_response) diff --git a/tests/aws/services/apigateway/test_apigateway_api.snapshot.json b/tests/aws/services/apigateway/test_apigateway_api.snapshot.json index 33492c4deaf85..665d8ee288c33 100644 --- a/tests/aws/services/apigateway/test_apigateway_api.snapshot.json +++ b/tests/aws/services/apigateway/test_apigateway_api.snapshot.json @@ -3629,5 +3629,90 @@ } } } + }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_lifecycle_integration_response": { + "recorded-date": "11-06-2025, 09:12:54", + "recorded-content": { + "put-integration-response": { + "responseTemplates": { + "application/json": "\"created\"" + }, + "selectionPattern": "", + "statusCode": "200", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 201 + } + }, + "get-integration-response": { + "responseTemplates": { + "application/json": "\"created\"" + }, + "selectionPattern": "", + "statusCode": "200", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "update-integration-response": { + "responseTemplates": { + "application/json": "\"created\"" + }, + "selectionPattern": "updated-pattern", + "statusCode": "200", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "overwrite-integration-response": { + "responseTemplates": { + "application/json": "overwrite" + }, + "selectionPattern": "overwrite-pattern", + "statusCode": "200", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 201 + } + }, + "get-method": { + "apiKeyRequired": false, + "authorizationType": "NONE", + "httpMethod": "GET", + "methodIntegration": { + "cacheKeyParameters": [], + "cacheNamespace": "", + "integrationResponses": { + "200": { + "responseTemplates": { + "application/json": "overwrite" + }, + "selectionPattern": "overwrite-pattern", + "statusCode": "200" + } + }, + "passthroughBehavior": "WHEN_NO_MATCH", + "requestTemplates": { + "application/json": { + "statusCode": 200 + } + }, + "timeoutInMillis": 29000, + "type": "MOCK" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "delete-integration-response": { + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 204 + } + } + } } } diff --git a/tests/aws/services/apigateway/test_apigateway_api.validation.json b/tests/aws/services/apigateway/test_apigateway_api.validation.json index d34cd8cb44f3d..df3c6379daf87 100644 --- a/tests/aws/services/apigateway/test_apigateway_api.validation.json +++ b/tests/aws/services/apigateway/test_apigateway_api.validation.json @@ -131,6 +131,15 @@ "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayGatewayResponse::test_update_gateway_response": { "last_validated_date": "2024-04-15T20:47:11+00:00" }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_lifecycle_integration_response": { + "last_validated_date": "2025-06-11T09:12:54+00:00", + "durations_in_seconds": { + "setup": 1.49, + "call": 2.35, + "teardown": 0.37, + "total": 4.21 + } + }, "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_put_integration_request_parameter_bool_type": { "last_validated_date": "2024-12-12T10:46:41+00:00" }, From 99c68256d34ace8c25e59a916b120e658b0f8a47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristopher=20Pinz=C3=B3n?= <18080804+pinzon@users.noreply.github.com> Date: Wed, 11 Jun 2025 16:40:32 -0500 Subject: [PATCH 25/74] add small fixes/improvements to Firehose.CreateDeliveryStream (#12656) --- .../localstack/services/firehose/provider.py | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/localstack-core/localstack/services/firehose/provider.py b/localstack-core/localstack/services/firehose/provider.py index c678d0647c076..18142ae80d88b 100644 --- a/localstack-core/localstack/services/firehose/provider.py +++ b/localstack-core/localstack/services/firehose/provider.py @@ -63,6 +63,7 @@ RedshiftDestinationConfiguration, RedshiftDestinationDescription, RedshiftDestinationUpdate, + ResourceInUseException, ResourceNotFoundException, S3DestinationConfiguration, S3DestinationDescription, @@ -282,6 +283,18 @@ def create_delivery_stream( ) -> CreateDeliveryStreamOutput: # TODO add support for database_source_configuration and direct_put_source_configuration store = self.get_store(context.account_id, context.region) + delivery_stream_type = delivery_stream_type or DeliveryStreamType.DirectPut + + delivery_stream_arn = firehose_stream_arn( + stream_name=delivery_stream_name, + account_id=context.account_id, + region_name=context.region, + ) + + if delivery_stream_name in store.delivery_streams.keys(): + raise ResourceInUseException( + f"Firehose {delivery_stream_name} under accountId {context.account_id} already exists" + ) destinations: DestinationDescriptionList = [] if elasticsearch_destination_configuration: @@ -344,11 +357,7 @@ def create_delivery_stream( stream = DeliveryStreamDescription( DeliveryStreamName=delivery_stream_name, - DeliveryStreamARN=firehose_stream_arn( - stream_name=delivery_stream_name, - account_id=context.account_id, - region_name=context.region, - ), + DeliveryStreamARN=delivery_stream_arn, DeliveryStreamStatus=DeliveryStreamStatus.ACTIVE, DeliveryStreamType=delivery_stream_type, HasMoreDestinations=False, @@ -358,8 +367,6 @@ def create_delivery_stream( Source=convert_source_config_to_desc(kinesis_stream_source_configuration), ) delivery_stream_arn = stream["DeliveryStreamARN"] - store.TAGS.tag_resource(delivery_stream_arn, tags) - store.delivery_streams[delivery_stream_name] = stream if delivery_stream_type == DeliveryStreamType.KinesisStreamAsSource: if not kinesis_stream_source_configuration: @@ -396,6 +403,10 @@ def _startup(): stream["DeliveryStreamStatus"] = DeliveryStreamStatus.CREATING_FAILED run_for_max_seconds(25, _startup) + + store.TAGS.tag_resource(delivery_stream_arn, tags) + store.delivery_streams[delivery_stream_name] = stream + return CreateDeliveryStreamOutput(DeliveryStreamARN=stream["DeliveryStreamARN"]) def delete_delivery_stream( From 3bbf94424fd55845e0cb22cf37046ea94fc003f4 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Palma <64580864+MEPalma@users.noreply.github.com> Date: Thu, 12 Jun 2025 08:59:50 +0200 Subject: [PATCH 26/74] CloudFormation v2 Engine: Base Support for Serverless Global Transforms (#12742) --- .../engine/v2/change_set_model.py | 101 +++++++++++- .../engine/v2/change_set_model_preproc.py | 2 +- .../engine/v2/change_set_model_transform.py | 155 ++++++++++++++++++ .../engine/v2/change_set_model_visitor.py | 8 + .../services/cloudformation/v2/entities.py | 25 +-- .../services/cloudformation/v2/provider.py | 61 ++++++- .../v2/ported_from_v1/api/test_changesets.py | 1 + .../resources/test_apigateway.py | 3 +- .../ported_from_v1/resources/test_lambda.py | 2 - .../v2/ported_from_v1/resources/test_sam.py | 3 - .../v2/ported_from_v1/test_template_engine.py | 1 + 11 files changed, 326 insertions(+), 36 deletions(-) create mode 100644 localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_transform.py diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model.py index 5a4cae3e042d1..d366c0906cad8 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model.py @@ -3,7 +3,7 @@ import abc import enum from itertools import zip_longest -from typing import Any, Final, Generator, Optional, Union, cast +from typing import Any, Final, Generator, Optional, TypedDict, Union, cast from typing_extensions import TypeVar @@ -78,6 +78,11 @@ def change_type_of(before: Maybe[Any], after: Maybe[Any], children: list[Maybe[C return change_type +class NormalisedGlobalTransformDefinition(TypedDict): + Name: Any + Parameters: Maybe[Any] + + class Scope(str): _ROOT_SCOPE: Final[str] = str() _SEPARATOR: Final[str] = "/" @@ -143,6 +148,7 @@ class ChangeSetTerminal(ChangeSetEntity, abc.ABC): ... class NodeTemplate(ChangeSetNode): + transform: Final[NodeTransform] mappings: Final[NodeMappings] parameters: Final[NodeParameters] conditions: Final[NodeConditions] @@ -152,14 +158,16 @@ class NodeTemplate(ChangeSetNode): def __init__( self, scope: Scope, + transform: NodeTransform, mappings: NodeMappings, parameters: NodeParameters, conditions: NodeConditions, resources: NodeResources, outputs: NodeOutputs, ): - change_type = parent_change_type_of([resources, outputs]) + change_type = parent_change_type_of([transform, resources, outputs]) super().__init__(scope=scope, change_type=change_type) + self.transform = transform self.mappings = mappings self.parameters = parameters self.conditions = conditions @@ -277,6 +285,29 @@ def __init__(self, scope: Scope, conditions: list[NodeCondition]): self.conditions = conditions +class NodeGlobalTransform(ChangeSetNode): + name: Final[TerminalValue] + parameters: Final[Maybe[ChangeSetEntity]] + + def __init__(self, scope: Scope, name: TerminalValue, parameters: Maybe[ChangeSetEntity]): + if not is_nothing(parameters): + change_type = parent_change_type_of([name, parameters]) + else: + change_type = name.change_type + super().__init__(scope=scope, change_type=change_type) + self.name = name + self.parameters = parameters + + +class NodeTransform(ChangeSetNode): + global_transforms: Final[list[NodeGlobalTransform]] + + def __init__(self, scope: Scope, global_transforms: list[NodeGlobalTransform]): + change_type = parent_change_type_of(global_transforms) + super().__init__(scope=scope, change_type=change_type) + self.global_transforms = global_transforms + + class NodeResources(ChangeSetNode): resources: Final[list[NodeResource]] @@ -401,6 +432,8 @@ def __init__(self, scope: Scope, value: Any): super().__init__(scope=scope, change_type=ChangeType.UNCHANGED, value=value) +NameKey: Final[str] = "Name" +TransformKey: Final[str] = "Transform" TypeKey: Final[str] = "Type" ConditionKey: Final[str] = "Condition" ConditionsKey: Final[str] = "Conditions" @@ -1098,10 +1131,72 @@ def _visit_outputs( outputs.append(output) return NodeOutputs(scope=scope, outputs=outputs) + def _visit_global_transform( + self, + scope: Scope, + before_global_transform: Maybe[NormalisedGlobalTransformDefinition], + after_global_transform: Maybe[NormalisedGlobalTransformDefinition], + ) -> NodeGlobalTransform: + name_scope, (before_name, after_name) = self._safe_access_in( + scope, NameKey, before_global_transform, after_global_transform + ) + name = self._visit_terminal_value( + scope=name_scope, before_value=before_name, after_value=after_name + ) + + parameters_scope, (before_parameters, after_parameters) = self._safe_access_in( + scope, ParametersKey, before_global_transform, after_global_transform + ) + parameters = self._visit_value( + scope=parameters_scope, before_value=before_parameters, after_value=after_parameters + ) + + return NodeGlobalTransform(scope=scope, name=name, parameters=parameters) + + @staticmethod + def _normalise_transformer_value(value: Maybe[str | list[Any]]) -> Maybe[list[Any]]: + # To simplify downstream logics, reduce the type options to array of transformations. + # TODO: add validation logic + # TODO: should we sort to avoid detecting user-side ordering changes as template changes? + if isinstance(value, NothingType): + return value + elif isinstance(value, str): + value = [NormalisedGlobalTransformDefinition(Name=value, Parameters=Nothing)] + elif not isinstance(value, list): + raise RuntimeError(f"Invalid type for Transformer: '{value}'") + return value + + def _visit_transform( + self, scope: Scope, before_transform: Maybe[Any], after_transform: Maybe[Any] + ) -> NodeTransform: + before_transform_normalised = self._normalise_transformer_value(before_transform) + after_transform_normalised = self._normalise_transformer_value(after_transform) + global_transforms = list() + for index, (before_global_transform, after_global_transform) in enumerate( + zip_longest(before_transform_normalised, after_transform_normalised, fillvalue=Nothing) + ): + global_transform_scope = scope.open_index(index=index) + global_transform: NodeGlobalTransform = self._visit_global_transform( + scope=global_transform_scope, + before_global_transform=before_global_transform, + after_global_transform=after_global_transform, + ) + global_transforms.append(global_transform) + return NodeTransform(scope=scope, global_transforms=global_transforms) + def _model(self, before_template: Maybe[dict], after_template: Maybe[dict]) -> NodeTemplate: root_scope = Scope() # TODO: visit other child types + transform_scope, (before_transform, after_transform) = self._safe_access_in( + root_scope, TransformKey, before_template, after_template + ) + transform = self._visit_transform( + scope=transform_scope, + before_transform=before_transform, + after_transform=after_transform, + ) + mappings_scope, (before_mappings, after_mappings) = self._safe_access_in( root_scope, MappingsKey, before_template, after_template ) @@ -1143,9 +1238,9 @@ def _model(self, before_template: Maybe[dict], after_template: Maybe[dict]) -> N scope=outputs_scope, before_outputs=before_outputs, after_outputs=after_outputs ) - # TODO: compute the change_type of the template properly. return NodeTemplate( scope=root_scope, + transform=transform, mappings=mappings, parameters=parameters, conditions=conditions, diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py index 5fc274f0e5107..66a862ba0cc0c 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py @@ -170,7 +170,7 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor): def __init__(self, change_set: ChangeSet): self._change_set = change_set - self._node_template = change_set.update_graph + self._node_template = change_set.update_model self._before_resolved_resources = change_set.stack.resolved_resources self._processed = dict() diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_transform.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_transform.py new file mode 100644 index 0000000000000..84d0ea6feac9b --- /dev/null +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_transform.py @@ -0,0 +1,155 @@ +import copy +import os +from typing import Final, Optional + +import boto3 +from samtranslator.translator.transform import transform as transform_sam + +from localstack.services.cloudformation.engine.policy_loader import create_policy_loader +from localstack.services.cloudformation.engine.transformers import FailedTransformationException +from localstack.services.cloudformation.engine.v2.change_set_model import ( + ChangeType, + Maybe, + NodeGlobalTransform, + NodeTransform, + Nothing, + is_nothing, +) +from localstack.services.cloudformation.engine.v2.change_set_model_preproc import ( + ChangeSetModelPreproc, + PreprocEntityDelta, +) +from localstack.services.cloudformation.v2.entities import ChangeSet + +SERVERLESS_TRANSFORM = "AWS::Serverless-2016-10-31" + + +# TODO: evaluate the use of subtypes to represent and validate types of transforms +class GlobalTransform: + name: str + parameters: Maybe[dict] + + def __init__(self, name: str, parameters: Maybe[dict]): + self.name = name + self.parameters = parameters + + +class ChangeSetModelTransform(ChangeSetModelPreproc): + _before_parameters: Final[dict] + _after_parameters: Final[dict] + _before_template: Final[Maybe[dict]] + _after_template: Final[Maybe[dict]] + + def __init__( + self, + change_set: ChangeSet, + before_parameters: dict, + after_parameters: dict, + before_template: Optional[dict], + after_template: Optional[dict], + ): + super().__init__(change_set=change_set) + self._before_parameters = before_parameters + self._after_parameters = after_parameters + self._before_template = before_template or Nothing + self._after_template = after_template or Nothing + + # Ported from v1: + @staticmethod + def _apply_serverless_transformation( + region_name: str, template: dict, parameters: dict + ) -> dict: + """only returns string when parsing SAM template, otherwise None""" + # TODO: we might also want to override the access key ID to account ID + region_before = os.environ.get("AWS_DEFAULT_REGION") + if boto3.session.Session().region_name is None: + os.environ["AWS_DEFAULT_REGION"] = region_name + loader = create_policy_loader() + # The following transformation function can carry out in-place changes ensure this cannot occur. + template = copy.deepcopy(template) + parameters = copy.deepcopy(parameters) + try: + transformed = transform_sam(template, parameters, loader) + return transformed + except Exception as e: + raise FailedTransformationException(transformation=SERVERLESS_TRANSFORM, message=str(e)) + finally: + # Note: we need to fix boto3 region, otherwise AWS SAM transformer fails + os.environ.pop("AWS_DEFAULT_REGION", None) + if region_before is not None: + os.environ["AWS_DEFAULT_REGION"] = region_before + + def _apply_global_transform( + self, global_transform: GlobalTransform, template: dict, parameters: dict + ) -> dict: + if global_transform.name == SERVERLESS_TRANSFORM: + return self._apply_serverless_transformation( + region_name=self._change_set.region_name, + template=template, + parameters=parameters, + ) + # TODO: expand support + raise RuntimeError(f"Unsupported global transform '{global_transform.name}'") + + def transform(self) -> tuple[dict, dict]: + transform_delta: PreprocEntityDelta[list[GlobalTransform], list[GlobalTransform]] = ( + self.visit_node_transform(self._node_template.transform) + ) + transform_before: Maybe[list[GlobalTransform]] = transform_delta.before + transform_after: Maybe[list[GlobalTransform]] = transform_delta.after + + transformed_before_template = self._before_template + if not is_nothing(transform_before) and not is_nothing(self._before_template): + transformed_before_template = self._before_template + for before_global_transform in transform_before: + transformed_before_template = self._apply_global_transform( + global_transform=before_global_transform, + parameters=self._before_parameters, + template=transformed_before_template, + ) + + transformed_after_template = self._after_template + if not is_nothing(transform_before) and not is_nothing(self._after_template): + transformed_after_template = self._after_template + for after_global_transform in transform_after: + transformed_after_template = self._apply_global_transform( + global_transform=after_global_transform, + parameters=self._after_parameters, + template=transformed_after_template, + ) + + return transformed_before_template, transformed_after_template + + def visit_node_global_transform( + self, node_global_transform: NodeGlobalTransform + ) -> PreprocEntityDelta[GlobalTransform, GlobalTransform]: + change_type = node_global_transform.change_type + + name_delta = self.visit(node_global_transform.name) + parameters_delta = self.visit(node_global_transform.parameters) + + before = Nothing + if change_type != ChangeType.CREATED: + before = GlobalTransform(name=name_delta.before, parameters=parameters_delta.before) + after = Nothing + if change_type != ChangeType.REMOVED: + after = GlobalTransform(name=name_delta.after, parameters=parameters_delta.after) + return PreprocEntityDelta(before=before, after=after) + + def visit_node_transform( + self, node_transform: NodeTransform + ) -> PreprocEntityDelta[list[GlobalTransform], list[GlobalTransform]]: + change_type = node_transform.change_type + before = list() if change_type != ChangeType.CREATED else Nothing + after = list() if change_type != ChangeType.REMOVED else Nothing + for change_set_entity in node_transform.global_transforms: + delta: PreprocEntityDelta[GlobalTransform, GlobalTransform] = self.visit( + change_set_entity=change_set_entity + ) + delta_before = delta.before + delta_after = delta.after + if not is_nothing(before) and not is_nothing(delta_before): + before.append(delta_before) + if not is_nothing(after) and not is_nothing(delta_after): + after.append(delta_after) + return PreprocEntityDelta(before=before, after=after) diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_visitor.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_visitor.py index 732141270fb65..6333e9f8dbae2 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_visitor.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_visitor.py @@ -7,6 +7,7 @@ NodeConditions, NodeDependsOn, NodeDivergence, + NodeGlobalTransform, NodeIntrinsicFunction, NodeMapping, NodeMappings, @@ -20,6 +21,7 @@ NodeResource, NodeResources, NodeTemplate, + NodeTransform, TerminalValueCreated, TerminalValueModified, TerminalValueRemoved, @@ -55,6 +57,12 @@ def visit_node_template(self, node_template: NodeTemplate): self.visit(node_template.resources) self.visit(node_template.outputs) + def visit_node_transform(self, node_transform: NodeTransform): + self.visit_children(node_transform) + + def visit_node_global_transform(self, node_global_transform: NodeGlobalTransform): + self.visit_children(node_global_transform) + def visit_node_outputs(self, node_outputs: NodeOutputs): self.visit_children(node_outputs) diff --git a/localstack-core/localstack/services/cloudformation/v2/entities.py b/localstack-core/localstack/services/cloudformation/v2/entities.py index fc3fa536221fa..111a29a6dfa37 100644 --- a/localstack-core/localstack/services/cloudformation/v2/entities.py +++ b/localstack-core/localstack/services/cloudformation/v2/entities.py @@ -1,5 +1,5 @@ from datetime import datetime, timezone -from typing import TypedDict +from typing import Optional, TypedDict from localstack.aws.api.cloudformation import ( ChangeSetStatus, @@ -23,7 +23,6 @@ StackTemplate, ) from localstack.services.cloudformation.engine.v2.change_set_model import ( - ChangeSetModel, NodeTemplate, ) from localstack.utils.aws import arns @@ -154,7 +153,7 @@ class ChangeSet: change_set_name: str change_set_id: str change_set_type: ChangeSetType - update_graph: NodeTemplate | None + update_model: Optional[NodeTemplate] status: ChangeSetStatus execution_status: ExecutionStatus creation_time: datetime @@ -169,7 +168,7 @@ def __init__( self.template = template self.status = ChangeSetStatus.CREATE_IN_PROGRESS self.execution_status = ExecutionStatus.AVAILABLE - self.update_graph = None + self.update_model = None self.creation_time = datetime.now(tz=timezone.utc) self.change_set_name = request_payload["ChangeSetName"] @@ -181,6 +180,9 @@ def __init__( region_name=self.stack.region_name, ) + def set_update_model(self, update_model: NodeTemplate) -> None: + self.update_model = update_model + def set_change_set_status(self, status: ChangeSetStatus): self.status = status @@ -194,18 +196,3 @@ def account_id(self) -> str: @property def region_name(self) -> str: return self.stack.region_name - - def populate_update_graph( - self, - before_template: dict | None = None, - after_template: dict | None = None, - before_parameters: dict | None = None, - after_parameters: dict | None = None, - ) -> None: - change_set_model = ChangeSetModel( - before_template=before_template, - after_template=after_template, - before_parameters=before_parameters, - after_parameters=after_parameters, - ) - self.update_graph = change_set_model.get_update_model() diff --git a/localstack-core/localstack/services/cloudformation/v2/provider.py b/localstack-core/localstack/services/cloudformation/v2/provider.py index 373c6bf02336e..4b3d06877fe94 100644 --- a/localstack-core/localstack/services/cloudformation/v2/provider.py +++ b/localstack-core/localstack/services/cloudformation/v2/provider.py @@ -1,7 +1,7 @@ import copy import logging from datetime import datetime, timezone -from typing import Any +from typing import Any, Optional from localstack.aws.api import RequestContext, handler from localstack.aws.api.cloudformation import ( @@ -37,12 +37,19 @@ ) from localstack.services.cloudformation import api_utils from localstack.services.cloudformation.engine import template_preparer +from localstack.services.cloudformation.engine.v2.change_set_model import ( + ChangeSetModel, + NodeTemplate, +) from localstack.services.cloudformation.engine.v2.change_set_model_describer import ( ChangeSetModelDescriber, ) from localstack.services.cloudformation.engine.v2.change_set_model_executor import ( ChangeSetModelExecutor, ) +from localstack.services.cloudformation.engine.v2.change_set_model_transform import ( + ChangeSetModelTransform, +) from localstack.services.cloudformation.engine.validations import ValidationError from localstack.services.cloudformation.provider import ( ARN_CHANGESET_REGEX, @@ -122,6 +129,47 @@ def find_change_set_v2( class CloudformationProviderV2(CloudformationProvider): + @staticmethod + def _setup_change_set_model( + change_set: ChangeSet, + before_template: Optional[dict], + after_template: Optional[dict], + before_parameters: Optional[dict], + after_parameters: Optional[dict], + ): + # Create and preprocess the update graph for this template update. + change_set_model = ChangeSetModel( + before_template=before_template, + after_template=after_template, + before_parameters=before_parameters, + after_parameters=after_parameters, + ) + raw_update_model: NodeTemplate = change_set_model.get_update_model() + change_set.set_update_model(raw_update_model) + + # Apply global transforms. + # TODO: skip this process iff both versions of the template don't specify transform blocks. + change_set_model_transform = ChangeSetModelTransform( + change_set=change_set, + before_parameters=before_parameters, + after_parameters=after_parameters, + before_template=before_template, + after_template=after_template, + ) + transformed_before_template, transformed_after_template = ( + change_set_model_transform.transform() + ) + + # Remodel the update graph after the applying the global transforms. + change_set_model = ChangeSetModel( + before_template=transformed_before_template, + after_template=transformed_after_template, + before_parameters=before_parameters, + after_parameters=after_parameters, + ) + update_model = change_set_model.get_update_model() + change_set.set_update_model(update_model) + @handler("CreateChangeSet", expand=False) def create_change_set( self, context: RequestContext, request: CreateChangeSetInput @@ -242,14 +290,14 @@ def create_change_set( # create change set for the stack and apply changes change_set = ChangeSet(stack, request, template=after_template) - - # only set parameters for the changeset, then switch to stack on execute_change_set - change_set.populate_update_graph( + self._setup_change_set_model( + change_set=change_set, before_template=before_template, after_template=after_template, before_parameters=before_parameters, after_parameters=after_parameters, ) + change_set.set_change_set_status(ChangeSetStatus.CREATE_COMPLETE) stack.change_set_id = change_set.change_set_id stack.change_set_id = change_set.change_set_id @@ -285,7 +333,7 @@ def execute_change_set( # stack_name, # len(change_set.template_resources), # ) - if not change_set.update_graph: + if not change_set.update_model: raise RuntimeError("Programming error: no update graph found for change set") change_set.set_execution_status(ExecutionStatus.EXECUTE_IN_PROGRESS) @@ -471,7 +519,8 @@ def delete_stack( # create a dummy change set change_set = ChangeSet(stack, {"ChangeSetName": f"delete-stack_{stack.stack_name}"}) # noqa - change_set.populate_update_graph( + self._setup_change_set_model( + change_set=change_set, before_template=stack.template, after_template=None, before_parameters=stack.resolved_parameters, diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py index 0d513d4b2a89e..fe8f4838cb993 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py @@ -906,6 +906,7 @@ def _check_changeset_available(): snapshot.match("postdelete_changeset_notfound", e.value) +@pytest.mark.skip(reason="CFNV2:Macros") @markers.aws.validated def test_autoexpand_capability_requirement(cleanups, aws_client): stack_name = f"test-stack-{short_uid()}" diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py index 43540351b0504..563e7a76587ac 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py @@ -115,7 +115,6 @@ def test_cfn_apigateway_aws_integration(deploy_cfn_template, aws_client): assert mappings[0] == "(none)" -@pytest.mark.skip(reason="CFNV2:AWS::Serverless") @markers.aws.validated def test_cfn_apigateway_swagger_import(deploy_cfn_template, echo_http_server_post, aws_client): api_name = f"rest-api-{short_uid()}" @@ -558,7 +557,7 @@ def test_api_gateway_with_policy_as_dict(deploy_cfn_template, snapshot, aws_clie @pytest.mark.skip( - reason="CFNV2:AWS::Serverless no resource provider found for AWS::Serverless::Api" + reason="CFNV2:Other lambda function fails on creation due to invalid function name" ) @markers.aws.validated @markers.snapshot.skip_snapshot_verify( diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py index 1d82ca41294dd..46b01456d42e2 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py @@ -25,7 +25,6 @@ ) -@pytest.mark.skip(reason="CFNV2:Transform") @markers.aws.validated def test_lambda_w_dynamodb_event_filter(deploy_cfn_template, aws_client): function_name = f"test-fn-{short_uid()}" @@ -58,7 +57,6 @@ def _assert_single_lambda_call(): retry(_assert_single_lambda_call, retries=30) -@pytest.mark.skip(reason="CFNV2:Transform") @markers.snapshot.skip_snapshot_verify( [ # TODO: Fix flaky ESM state mismatch upon update in LocalStack (expected Enabled, actual Disabled) diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sam.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sam.py index 81b9032128cb9..457334ad1c756 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sam.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sam.py @@ -33,7 +33,6 @@ def test_sam_policies(deploy_cfn_template, snapshot, aws_client): snapshot.match("list_attached_role_policies", roles) -@pytest.mark.skip(reason="CFNV2:ServerlessResources") @markers.aws.validated def test_sam_template(deploy_cfn_template, aws_client): # deploy template @@ -51,7 +50,6 @@ def test_sam_template(deploy_cfn_template, aws_client): assert result == {"hello": "world"} -@pytest.mark.skip(reason="CFNV2:ServerlessResources") @markers.aws.validated def test_sam_sqs_event(deploy_cfn_template, aws_client): result_key = f"event-{short_uid()}" @@ -78,7 +76,6 @@ def get_object(): assert body == message_body -@pytest.mark.skip(reason="CFNV2:ServerlessResources") @markers.aws.validated @markers.snapshot.skip_snapshot_verify(paths=["$..Tags", "$..tags", "$..Configuration.CodeSha256"]) def test_cfn_handle_serverless_api_resource(deploy_cfn_template, aws_client, snapshot): diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py b/tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py index 966bc541b7050..99b519236ea18 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py @@ -121,6 +121,7 @@ def test_base64_sub_and_getatt_functions(self, deploy_cfn_template): converted_string = base64.b64encode(bytes(original_string, "utf-8")).decode("utf-8") assert converted_string == deployed.outputs["Encoded"] + @pytest.mark.skip(reason="CFNV2:LanguageExtensions") @markers.aws.validated def test_split_length_and_join_functions(self, deploy_cfn_template): template_path = os.path.join( From 02ad74e65eafc9a846adcc27397e95640cab06ae Mon Sep 17 00:00:00 2001 From: Silvio Vasiljevic Date: Fri, 13 Jun 2025 14:25:53 +0200 Subject: [PATCH 27/74] Do not login to DockerHub if there is no pull secret (#12747) --- .github/workflows/aws-tests.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/aws-tests.yml b/.github/workflows/aws-tests.yml index 49d763255ca36..7fcd14086b9e5 100644 --- a/.github/workflows/aws-tests.yml +++ b/.github/workflows/aws-tests.yml @@ -133,6 +133,7 @@ env: CI_JOB_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/attempts/${{ github.run_attempt }} # report to tinybird if executed on master TINYBIRD_PYTEST_ARGS: "${{ github.ref == 'refs/heads/master' && '--report-to-tinybird ' || '' }}" + DOCKER_PULL_SECRET_AVAILABLE: ${{ secrets.DOCKERHUB_PULL_USERNAME != '' && secrets.DOCKERHUB_PULL_TOKEN != '' && 'true' || 'false' }} @@ -322,7 +323,7 @@ jobs: - name: Login to Docker Hub # login to DockerHub to avoid rate limiting issues on custom runners - if: github.repository_owner == 'localstack' + if: github.repository_owner == 'localstack' && env.DOCKER_PULL_SECRET_AVAILABLE == 'true' uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_PULL_USERNAME }} @@ -514,7 +515,7 @@ jobs: - name: Login to Docker Hub # login to DockerHub to avoid rate limiting issues on custom runners - if: github.repository_owner == 'localstack' + if: github.repository_owner == 'localstack' && env.DOCKER_PULL_SECRET_AVAILABLE == 'true' uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_PULL_USERNAME }} @@ -845,7 +846,7 @@ jobs: steps: - name: Login to Docker Hub # login to DockerHub to avoid rate limiting issues on custom runners - if: github.repository_owner == 'localstack' + if: github.repository_owner == 'localstack' && env.DOCKER_PULL_SECRET_AVAILABLE == 'true' uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_PULL_USERNAME }} From 715d1186190ee66881534bcb41dbe29776912adc Mon Sep 17 00:00:00 2001 From: Simon Walker Date: Fri, 13 Jun 2025 14:53:41 +0100 Subject: [PATCH 28/74] Docker registry customisation (#12590) --- localstack-core/localstack/config.py | 1 + .../utils/container_utils/container_client.py | 11 +++++++++++ .../utils/container_utils/docker_cmd_client.py | 4 ++++ .../utils/container_utils/docker_sdk_client.py | 5 +++++ 4 files changed, 21 insertions(+) diff --git a/localstack-core/localstack/config.py b/localstack-core/localstack/config.py index 5c2af11762fb4..c7986b22daa3f 100644 --- a/localstack-core/localstack/config.py +++ b/localstack-core/localstack/config.py @@ -1007,6 +1007,7 @@ def populate_edge_configuration( # b) json dict mapping the to an image, e.g. {"python3.9": "custom-repo/lambda-py:thon3.9"} LAMBDA_RUNTIME_IMAGE_MAPPING = os.environ.get("LAMBDA_RUNTIME_IMAGE_MAPPING", "").strip() + # PUBLIC: 0 (default) # Whether to disable usage of deprecated runtimes LAMBDA_RUNTIME_VALIDATION = int(os.environ.get("LAMBDA_RUNTIME_VALIDATION") or 0) diff --git a/localstack-core/localstack/utils/container_utils/container_client.py b/localstack-core/localstack/utils/container_utils/container_client.py index e05fdd6da5a55..fb880ba50f71c 100644 --- a/localstack-core/localstack/utils/container_utils/container_client.py +++ b/localstack-core/localstack/utils/container_utils/container_client.py @@ -589,9 +589,20 @@ class DockerRunFlags: dns: Optional[List[str]] +class RegistryResolverStrategy(Protocol): + def resolve(self, image_name: str) -> str: ... + + +class HardCodedResolver: + def resolve(self, image_name: str) -> str: # noqa + return image_name + + # TODO: remove Docker/Podman compatibility switches (in particular strip_wellknown_repo_prefixes=...) # from the container client base interface and introduce derived Podman client implementations instead! class ContainerClient(metaclass=ABCMeta): + registry_resolver_strategy: RegistryResolverStrategy = HardCodedResolver() + @abstractmethod def get_system_info(self) -> dict: """Returns the docker system-wide information as dictionary (``docker info``).""" diff --git a/localstack-core/localstack/utils/container_utils/docker_cmd_client.py b/localstack-core/localstack/utils/container_utils/docker_cmd_client.py index 7cdd7b59f8092..ac50a195bf38b 100644 --- a/localstack-core/localstack/utils/container_utils/docker_cmd_client.py +++ b/localstack-core/localstack/utils/container_utils/docker_cmd_client.py @@ -356,6 +356,7 @@ def copy_from_container( def pull_image(self, docker_image: str, platform: Optional[DockerPlatform] = None) -> None: cmd = self._docker_cmd() + docker_image = self.registry_resolver_strategy.resolve(docker_image) cmd += ["pull", docker_image] if platform: cmd += ["--platform", platform] @@ -518,6 +519,7 @@ def inspect_image( pull: bool = True, strip_wellknown_repo_prefixes: bool = True, ) -> Dict[str, Union[dict, list, str]]: + image_name = self.registry_resolver_strategy.resolve(image_name) try: result = self._inspect_object(image_name) if strip_wellknown_repo_prefixes: @@ -656,6 +658,7 @@ def has_docker(self) -> bool: return False def create_container(self, image_name: str, **kwargs) -> str: + image_name = self.registry_resolver_strategy.resolve(image_name) cmd, env_file = self._build_run_create_cmd("create", image_name, **kwargs) LOG.debug("Create container with cmd: %s", cmd) try: @@ -674,6 +677,7 @@ def create_container(self, image_name: str, **kwargs) -> str: Util.rm_env_vars_file(env_file) def run_container(self, image_name: str, stdin=None, **kwargs) -> Tuple[bytes, bytes]: + image_name = self.registry_resolver_strategy.resolve(image_name) cmd, env_file = self._build_run_create_cmd("run", image_name, **kwargs) LOG.debug("Run container with cmd: %s", cmd) try: diff --git a/localstack-core/localstack/utils/container_utils/docker_sdk_client.py b/localstack-core/localstack/utils/container_utils/docker_sdk_client.py index de69fd101c56e..a2b8f8a5f6746 100644 --- a/localstack-core/localstack/utils/container_utils/docker_sdk_client.py +++ b/localstack-core/localstack/utils/container_utils/docker_sdk_client.py @@ -337,6 +337,8 @@ def copy_from_container( def pull_image(self, docker_image: str, platform: Optional[DockerPlatform] = None) -> None: LOG.debug("Pulling Docker image: %s", docker_image) # some path in the docker image string indicates a custom repository + + docker_image = self.registry_resolver_strategy.resolve(docker_image) try: self.client().images.pull(docker_image, platform=platform) except ImageNotFound: @@ -465,6 +467,7 @@ def inspect_image( pull: bool = True, strip_wellknown_repo_prefixes: bool = True, ) -> Dict[str, Union[dict, list, str]]: + image_name = self.registry_resolver_strategy.resolve(image_name) try: result = self.client().images.get(image_name).attrs if strip_wellknown_repo_prefixes: @@ -778,6 +781,8 @@ def create_container( if volumes: mounts = Util.convert_mount_list_to_dict(volumes) + image_name = self.registry_resolver_strategy.resolve(image_name) + def create_container(): return self.client().containers.create( image=image_name, From bdc489f1c61fe1f536d94e86c6fa1df548fd8f2c Mon Sep 17 00:00:00 2001 From: LocalStack Bot <88328844+localstack-bot@users.noreply.github.com> Date: Mon, 16 Jun 2025 08:57:09 +0200 Subject: [PATCH 29/74] Update ASF APIs (#12759) Co-authored-by: LocalStack Bot --- localstack-core/localstack/aws/api/ec2/__init__.py | 11 +++++++++++ localstack-core/localstack/aws/api/kms/__init__.py | 5 +++++ pyproject.toml | 4 ++-- requirements-base-runtime.txt | 4 ++-- requirements-dev.txt | 6 +++--- requirements-runtime.txt | 6 +++--- requirements-test.txt | 6 +++--- requirements-typehint.txt | 6 +++--- 8 files changed, 32 insertions(+), 16 deletions(-) diff --git a/localstack-core/localstack/aws/api/ec2/__init__.py b/localstack-core/localstack/aws/api/ec2/__init__.py index 2c54e41e41615..6940b26e626b5 100644 --- a/localstack-core/localstack/aws/api/ec2/__init__.py +++ b/localstack-core/localstack/aws/api/ec2/__init__.py @@ -3452,6 +3452,8 @@ class SubnetState(StrEnum): pending = "pending" available = "available" unavailable = "unavailable" + failed = "failed" + failed_insufficient_capacity = "failed-insufficient-capacity" class SummaryStatus(StrEnum): @@ -4609,6 +4611,7 @@ class Address(TypedDict, total=False): CustomerOwnedIp: Optional[String] CustomerOwnedIpv4Pool: Optional[String] CarrierIp: Optional[String] + SubnetId: Optional[String] ServiceManaged: Optional[ServiceManaged] InstanceId: Optional[String] PublicIp: Optional[String] @@ -5235,6 +5238,7 @@ class AssociatedRole(TypedDict, total=False): AssociatedRolesList = List[AssociatedRole] +AssociatedSubnetList = List[SubnetId] class AssociatedTargetNetwork(TypedDict, total=False): @@ -6827,6 +6831,7 @@ class Subnet(TypedDict, total=False): Ipv6Native: Optional[Boolean] PrivateDnsNameOptionsOnLaunch: Optional[PrivateDnsNameOptionsOnLaunch] BlockPublicAccessStates: Optional[BlockPublicAccessStates] + Type: Optional[String] SubnetId: Optional[String] State: Optional[SubnetState] VpcId: Optional[String] @@ -8773,6 +8778,7 @@ class NetworkInterface(TypedDict, total=False): Ipv6Native: Optional[Boolean] Ipv6Address: Optional[String] Operator: Optional[OperatorResponse] + AssociatedSubnets: Optional[AssociatedSubnetList] class CreateNetworkInterfaceResult(TypedDict, total=False): @@ -18893,11 +18899,15 @@ class NetworkInterfaceAttachmentChanges(TypedDict, total=False): DeleteOnTermination: Optional[Boolean] +SubnetIdList = List[SubnetId] + + class ModifyNetworkInterfaceAttributeRequest(ServiceRequest): EnaSrdSpecification: Optional[EnaSrdSpecification] EnablePrimaryIpv6: Optional[Boolean] ConnectionTrackingSpecification: Optional[ConnectionTrackingSpecificationRequest] AssociatePublicIpAddress: Optional[Boolean] + AssociatedSubnetIds: Optional[SubnetIdList] DryRun: Optional[Boolean] NetworkInterfaceId: NetworkInterfaceId Description: Optional[AttributeValue] @@ -27590,6 +27600,7 @@ def modify_network_interface_attribute( enable_primary_ipv6: Boolean | None = None, connection_tracking_specification: ConnectionTrackingSpecificationRequest | None = None, associate_public_ip_address: Boolean | None = None, + associated_subnet_ids: SubnetIdList | None = None, dry_run: Boolean | None = None, description: AttributeValue | None = None, source_dest_check: AttributeBooleanValue | None = None, diff --git a/localstack-core/localstack/aws/api/kms/__init__.py b/localstack-core/localstack/aws/api/kms/__init__.py index 55f03cfa36c2d..b5e0fec886732 100644 --- a/localstack-core/localstack/aws/api/kms/__init__.py +++ b/localstack-core/localstack/aws/api/kms/__init__.py @@ -201,6 +201,9 @@ class KeySpec(StrEnum): HMAC_384 = "HMAC_384" HMAC_512 = "HMAC_512" SM2 = "SM2" + ML_DSA_44 = "ML_DSA_44" + ML_DSA_65 = "ML_DSA_65" + ML_DSA_87 = "ML_DSA_87" class KeyState(StrEnum): @@ -231,6 +234,7 @@ class MacAlgorithmSpec(StrEnum): class MessageType(StrEnum): RAW = "RAW" DIGEST = "DIGEST" + EXTERNAL_MU = "EXTERNAL_MU" class MultiRegionKeyType(StrEnum): @@ -261,6 +265,7 @@ class SigningAlgorithmSpec(StrEnum): ECDSA_SHA_384 = "ECDSA_SHA_384" ECDSA_SHA_512 = "ECDSA_SHA_512" SM2DSA = "SM2DSA" + ML_DSA_SHAKE_256 = "ML_DSA_SHAKE_256" class WrappingKeySpec(StrEnum): diff --git a/pyproject.toml b/pyproject.toml index ef7f9e3a6f62d..40556c7264e5e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,9 +53,9 @@ Issues = "https://github.com/localstack/localstack/issues" # minimal required to actually run localstack on the host for services natively implemented in python base-runtime = [ # pinned / updated by ASF update action - "boto3==1.38.32", + "boto3==1.38.36", # pinned / updated by ASF update action - "botocore==1.38.32", + "botocore==1.38.36", "awscrt>=0.13.14,!=0.27.1", "cbor2>=5.5.0", "dnspython>=1.16.0", diff --git a/requirements-base-runtime.txt b/requirements-base-runtime.txt index 31b5a7130db12..e2c0b40f48b4d 100644 --- a/requirements-base-runtime.txt +++ b/requirements-base-runtime.txt @@ -11,9 +11,9 @@ attrs==25.3.0 # referencing awscrt==0.27.2 # via localstack-core (pyproject.toml) -boto3==1.38.32 +boto3==1.38.36 # via localstack-core (pyproject.toml) -botocore==1.38.32 +botocore==1.38.36 # via # boto3 # localstack-core (pyproject.toml) diff --git a/requirements-dev.txt b/requirements-dev.txt index 36b4d72c0b87e..bdf749572c41a 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -39,17 +39,17 @@ aws-sam-translator==1.98.0 # localstack-core aws-xray-sdk==2.14.0 # via moto-ext -awscli==1.40.31 +awscli==1.40.35 # via localstack-core awscrt==0.27.2 # via localstack-core -boto3==1.38.32 +boto3==1.38.36 # via # aws-sam-translator # kclpy-ext # localstack-core # moto-ext -botocore==1.38.32 +botocore==1.38.36 # via # aws-xray-sdk # awscli diff --git a/requirements-runtime.txt b/requirements-runtime.txt index 7b079c4aa2ab4..6120934b9e685 100644 --- a/requirements-runtime.txt +++ b/requirements-runtime.txt @@ -27,17 +27,17 @@ aws-sam-translator==1.98.0 # localstack-core (pyproject.toml) aws-xray-sdk==2.14.0 # via moto-ext -awscli==1.40.31 +awscli==1.40.35 # via localstack-core (pyproject.toml) awscrt==0.27.2 # via localstack-core -boto3==1.38.32 +boto3==1.38.36 # via # aws-sam-translator # kclpy-ext # localstack-core # moto-ext -botocore==1.38.32 +botocore==1.38.36 # via # aws-xray-sdk # awscli diff --git a/requirements-test.txt b/requirements-test.txt index ecd564ffa5770..792d549f302ba 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -39,17 +39,17 @@ aws-sam-translator==1.98.0 # localstack-core aws-xray-sdk==2.14.0 # via moto-ext -awscli==1.40.31 +awscli==1.40.35 # via localstack-core awscrt==0.27.2 # via localstack-core -boto3==1.38.32 +boto3==1.38.36 # via # aws-sam-translator # kclpy-ext # localstack-core # moto-ext -botocore==1.38.32 +botocore==1.38.36 # via # aws-xray-sdk # awscli diff --git a/requirements-typehint.txt b/requirements-typehint.txt index 9728353958250..ab97dbdfa7de0 100644 --- a/requirements-typehint.txt +++ b/requirements-typehint.txt @@ -39,11 +39,11 @@ aws-sam-translator==1.98.0 # localstack-core aws-xray-sdk==2.14.0 # via moto-ext -awscli==1.40.31 +awscli==1.40.35 # via localstack-core awscrt==0.27.2 # via localstack-core -boto3==1.38.32 +boto3==1.38.36 # via # aws-sam-translator # kclpy-ext @@ -51,7 +51,7 @@ boto3==1.38.32 # moto-ext boto3-stubs==1.38.33 # via localstack-core (pyproject.toml) -botocore==1.38.32 +botocore==1.38.36 # via # aws-xray-sdk # awscli From df9ebe90552af29bb04c229b69a6a214cfed9f23 Mon Sep 17 00:00:00 2001 From: Ben Simon Hartung <42031100+bentsku@users.noreply.github.com> Date: Mon, 16 Jun 2025 11:25:29 +0200 Subject: [PATCH 30/74] S3: fix Checksum handling in UploadPartCopy (#12753) --- .../localstack/services/s3/provider.py | 33 +++-- .../services/s3/storage/ephemeral.py | 8 +- tests/aws/services/s3/test_s3.py | 79 ++++++++++- tests/aws/services/s3/test_s3.snapshot.json | 128 ++++++++++++++++++ tests/aws/services/s3/test_s3.validation.json | 9 ++ .../aws/services/s3/test_s3_api.snapshot.json | 4 +- .../services/s3/test_s3_api.validation.json | 16 ++- 7 files changed, 257 insertions(+), 20 deletions(-) diff --git a/localstack-core/localstack/services/s3/provider.py b/localstack-core/localstack/services/s3/provider.py index 6bab36e9457ba..cfb266d095744 100644 --- a/localstack-core/localstack/services/s3/provider.py +++ b/localstack-core/localstack/services/s3/provider.py @@ -2397,11 +2397,19 @@ def upload_part_copy( request: UploadPartCopyRequest, ) -> UploadPartCopyOutput: # TODO: handle following parameters: - # copy_source_if_match: CopySourceIfMatch = None, - # copy_source_if_modified_since: CopySourceIfModifiedSince = None, - # copy_source_if_none_match: CopySourceIfNoneMatch = None, - # copy_source_if_unmodified_since: CopySourceIfUnmodifiedSince = None, - # request_payer: RequestPayer = None, + # CopySourceIfMatch: Optional[CopySourceIfMatch] + # CopySourceIfModifiedSince: Optional[CopySourceIfModifiedSince] + # CopySourceIfNoneMatch: Optional[CopySourceIfNoneMatch] + # CopySourceIfUnmodifiedSince: Optional[CopySourceIfUnmodifiedSince] + # SSECustomerAlgorithm: Optional[SSECustomerAlgorithm] + # SSECustomerKey: Optional[SSECustomerKey] + # SSECustomerKeyMD5: Optional[SSECustomerKeyMD5] + # CopySourceSSECustomerAlgorithm: Optional[CopySourceSSECustomerAlgorithm] + # CopySourceSSECustomerKey: Optional[CopySourceSSECustomerKey] + # CopySourceSSECustomerKeyMD5: Optional[CopySourceSSECustomerKeyMD5] + # RequestPayer: Optional[RequestPayer] + # ExpectedBucketOwner: Optional[AccountId] + # ExpectedSourceBucketOwner: Optional[AccountId] dest_bucket = request["Bucket"] dest_key = request["Key"] store = self.get_store(context.account_id, context.region) @@ -2449,24 +2457,22 @@ def upload_part_copy( ) source_range = request.get("CopySourceRange") - # TODO implement copy source IF (done in ASF provider) + # TODO implement copy source IF range_data: Optional[ObjectRange] = None if source_range: range_data = parse_copy_source_range_header(source_range, src_s3_object.size) s3_part = S3Part(part_number=part_number) + if s3_multipart.checksum_algorithm: + s3_part.checksum_algorithm = s3_multipart.checksum_algorithm stored_multipart = self._storage_backend.get_multipart(dest_bucket, s3_multipart) stored_multipart.copy_from_object(s3_part, src_bucket, src_s3_object, range_data) s3_multipart.parts[part_number] = s3_part - # TODO: return those fields (checksum not handled currently in moto for parts) - # ChecksumCRC32: Optional[ChecksumCRC32] - # ChecksumCRC32C: Optional[ChecksumCRC32C] - # ChecksumSHA1: Optional[ChecksumSHA1] - # ChecksumSHA256: Optional[ChecksumSHA256] + # TODO: return those fields # RequestCharged: Optional[RequestCharged] result = CopyPartResult( @@ -2481,6 +2487,9 @@ def upload_part_copy( if src_s3_bucket.versioning_status and src_s3_object.version_id: response["CopySourceVersionId"] = src_s3_object.version_id + if s3_part.checksum_algorithm: + result[f"Checksum{s3_part.checksum_algorithm.upper()}"] = s3_part.checksum_value + add_encryption_to_response(response, s3_object=s3_multipart.object) return response @@ -2750,7 +2759,7 @@ def list_parts( PartNumber=part_number, Size=part.size, ) - if s3_multipart.checksum_algorithm: + if s3_multipart.checksum_algorithm and part.checksum_algorithm: part_item[f"Checksum{part.checksum_algorithm.upper()}"] = part.checksum_value parts.append(part_item) diff --git a/localstack-core/localstack/services/s3/storage/ephemeral.py b/localstack-core/localstack/services/s3/storage/ephemeral.py index 6031610aeea62..64fc3440d7996 100644 --- a/localstack-core/localstack/services/s3/storage/ephemeral.py +++ b/localstack-core/localstack/services/s3/storage/ephemeral.py @@ -340,10 +340,12 @@ def copy_from_object( ): if not range_data: stored_part.write(src_stored_object) - return + else: + object_slice = LimitedStream(src_stored_object, range_data=range_data) + stored_part.write(object_slice) - object_slice = LimitedStream(src_stored_object, range_data=range_data) - stored_part.write(object_slice) + if s3_part.checksum_algorithm: + s3_part.checksum_value = stored_part.checksum class BucketTemporaryFileSystem(TypedDict): diff --git a/tests/aws/services/s3/test_s3.py b/tests/aws/services/s3/test_s3.py index f9e40f87b12c5..53254f997f1e7 100644 --- a/tests/aws/services/s3/test_s3.py +++ b/tests/aws/services/s3/test_s3.py @@ -483,7 +483,6 @@ def test_metadata_header_character_decoding(self, s3_bucket, snapshot, aws_clien assert metadata_saved["Metadata"] == {"test_meta_1": "foo", "__meta_2": "bar"} @markers.aws.validated - @markers.snapshot.skip_snapshot_verify(paths=["$..ChecksumType"]) def test_upload_file_multipart(self, s3_bucket, tmpdir, snapshot, aws_client): snapshot.add_transformer(snapshot.transform.s3_api()) key = "my-key" @@ -13023,6 +13022,84 @@ def test_multipart_size_validation(self, aws_client, s3_bucket, snapshot): ) snapshot.match("get-object-attrs", object_attrs) + @markers.aws.validated + def test_multipart_upload_part_copy_checksum(self, s3_bucket, snapshot, aws_client): + snapshot.add_transformer( + [ + snapshot.transform.key_value("Bucket", reference_replacement=False), + snapshot.transform.key_value("Location"), + snapshot.transform.key_value("UploadId"), + snapshot.transform.key_value("DisplayName", reference_replacement=False), + snapshot.transform.key_value("ID", reference_replacement=False), + ] + ) + + part_key = "test-part-checksum" + put_object = aws_client.s3.put_object( + Bucket=s3_bucket, + Key=part_key, + Body="this is a part", + ) + snapshot.match("put-object", put_object) + + key_name = "test-multipart-checksum" + response = aws_client.s3.create_multipart_upload( + Bucket=s3_bucket, Key=key_name, ChecksumAlgorithm="SHA256" + ) + snapshot.match("create-mpu-checksum-sha256", response) + upload_id = response["UploadId"] + + copy_source_key = f"{s3_bucket}/{part_key}" + upload_part_copy = aws_client.s3.upload_part_copy( + Bucket=s3_bucket, + UploadId=upload_id, + Key=key_name, + PartNumber=1, + CopySource=copy_source_key, + ) + snapshot.match("upload-part-copy", upload_part_copy) + + list_parts = aws_client.s3.list_parts( + Bucket=s3_bucket, + UploadId=upload_id, + Key=key_name, + ) + snapshot.match("list-parts", list_parts) + + # complete with no checksum type specified, just all default values + response = aws_client.s3.complete_multipart_upload( + Bucket=s3_bucket, + Key=key_name, + MultipartUpload={ + "Parts": [ + { + "ETag": upload_part_copy["CopyPartResult"]["ETag"], + "PartNumber": 1, + "ChecksumSHA256": upload_part_copy["CopyPartResult"]["ChecksumSHA256"], + } + ] + }, + UploadId=upload_id, + ) + snapshot.match("complete-multipart-checksum", response) + + get_object_with_checksum = aws_client.s3.get_object( + Bucket=s3_bucket, Key=key_name, ChecksumMode="ENABLED" + ) + snapshot.match("get-object-with-checksum", get_object_with_checksum) + + head_object_with_checksum = aws_client.s3.head_object( + Bucket=s3_bucket, Key=key_name, ChecksumMode="ENABLED" + ) + snapshot.match("head-object-with-checksum", head_object_with_checksum) + + object_attrs = aws_client.s3.get_object_attributes( + Bucket=s3_bucket, + Key=key_name, + ObjectAttributes=["Checksum", "ETag"], + ) + snapshot.match("get-object-attrs", object_attrs) + def _s3_client_pre_signed_client(conf: Config, endpoint_url: str = None): if is_aws_cloud(): diff --git a/tests/aws/services/s3/test_s3.snapshot.json b/tests/aws/services/s3/test_s3.snapshot.json index ec8b2e57b7391..b46f9ac443760 100644 --- a/tests/aws/services/s3/test_s3.snapshot.json +++ b/tests/aws/services/s3/test_s3.snapshot.json @@ -17411,5 +17411,133 @@ } } } + }, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_copy_checksum": { + "recorded-date": "13-06-2025, 12:45:49", + "recorded-content": { + "put-object": { + "ChecksumCRC32": "nG7pIA==", + "ChecksumType": "FULL_OBJECT", + "ETag": "\"11df95d595559285eb2b042124e74f09\"", + "ServerSideEncryption": "AES256", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "create-mpu-checksum-sha256": { + "Bucket": "bucket", + "ChecksumAlgorithm": "SHA256", + "ChecksumType": "COMPOSITE", + "Key": "test-multipart-checksum", + "ServerSideEncryption": "AES256", + "UploadId": "", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "upload-part-copy": { + "CopyPartResult": { + "ChecksumSHA256": "+j3Oc5P9QdoIdPJ4lFSyNlAAX0G7Am+wZsxu4FYN+wo=", + "ETag": "\"11df95d595559285eb2b042124e74f09\"", + "LastModified": "datetime" + }, + "ServerSideEncryption": "AES256", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "list-parts": { + "Bucket": "bucket", + "ChecksumAlgorithm": "SHA256", + "ChecksumType": "COMPOSITE", + "Initiator": { + "DisplayName": "display-name", + "ID": "i-d" + }, + "IsTruncated": false, + "Key": "test-multipart-checksum", + "MaxParts": 1000, + "NextPartNumberMarker": 1, + "Owner": { + "DisplayName": "display-name", + "ID": "i-d" + }, + "PartNumberMarker": 0, + "Parts": [ + { + "ChecksumSHA256": "+j3Oc5P9QdoIdPJ4lFSyNlAAX0G7Am+wZsxu4FYN+wo=", + "ETag": "\"11df95d595559285eb2b042124e74f09\"", + "LastModified": "datetime", + "PartNumber": 1, + "Size": 14 + } + ], + "StorageClass": "STANDARD", + "UploadId": "", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "complete-multipart-checksum": { + "Bucket": "bucket", + "ChecksumSHA256": "/4+xERoRlzE2Ryan+GX/sqNSrf6Qe30L2IM7APXadSE=-1", + "ChecksumType": "COMPOSITE", + "ETag": "\"395d97c07920de036bfa21e7568a2e9f-1\"", + "Key": "test-multipart-checksum", + "Location": "", + "ServerSideEncryption": "AES256", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "get-object-with-checksum": { + "AcceptRanges": "bytes", + "Body": "this is a part", + "ChecksumSHA256": "/4+xERoRlzE2Ryan+GX/sqNSrf6Qe30L2IM7APXadSE=-1", + "ChecksumType": "COMPOSITE", + "ContentLength": 14, + "ContentType": "binary/octet-stream", + "ETag": "\"395d97c07920de036bfa21e7568a2e9f-1\"", + "LastModified": "datetime", + "Metadata": {}, + "ServerSideEncryption": "AES256", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "head-object-with-checksum": { + "AcceptRanges": "bytes", + "ChecksumSHA256": "/4+xERoRlzE2Ryan+GX/sqNSrf6Qe30L2IM7APXadSE=-1", + "ChecksumType": "COMPOSITE", + "ContentLength": 14, + "ContentType": "binary/octet-stream", + "ETag": "\"395d97c07920de036bfa21e7568a2e9f-1\"", + "LastModified": "datetime", + "Metadata": {}, + "ServerSideEncryption": "AES256", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "get-object-attrs": { + "Checksum": { + "ChecksumSHA256": "/4+xERoRlzE2Ryan+GX/sqNSrf6Qe30L2IM7APXadSE=", + "ChecksumType": "COMPOSITE" + }, + "ETag": "395d97c07920de036bfa21e7568a2e9f-1", + "LastModified": "datetime", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } } } diff --git a/tests/aws/services/s3/test_s3.validation.json b/tests/aws/services/s3/test_s3.validation.json index dcc4ca26324c6..80b50d625e8ea 100644 --- a/tests/aws/services/s3/test_s3.validation.json +++ b/tests/aws/services/s3/test_s3.validation.json @@ -671,6 +671,15 @@ "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_checksum_exception[SHA256]": { "last_validated_date": "2025-03-17T18:21:07+00:00" }, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_copy_checksum": { + "last_validated_date": "2025-06-13T12:45:50+00:00", + "durations_in_seconds": { + "setup": 0.92, + "call": 1.39, + "teardown": 1.01, + "total": 3.32 + } + }, "tests/aws/services/s3/test_s3.py::TestS3ObjectLockLegalHold::test_delete_locked_object": { "last_validated_date": "2025-01-21T18:17:15+00:00" }, diff --git a/tests/aws/services/s3/test_s3_api.snapshot.json b/tests/aws/services/s3/test_s3_api.snapshot.json index 488e94f968f79..d980b973f7119 100644 --- a/tests/aws/services/s3/test_s3_api.snapshot.json +++ b/tests/aws/services/s3/test_s3_api.snapshot.json @@ -3237,7 +3237,7 @@ } }, "tests/aws/services/s3/test_s3_api.py::TestS3Multipart::test_upload_part_copy_range": { - "recorded-date": "21-01-2025, 18:10:14", + "recorded-date": "13-06-2025, 12:42:54", "recorded-content": { "put-src-object": { "ChecksumCRC32": "poTHxg==", @@ -3517,7 +3517,7 @@ } }, "tests/aws/services/s3/test_s3_api.py::TestS3Multipart::test_upload_part_copy_no_copy_source_range": { - "recorded-date": "21-01-2025, 18:10:16", + "recorded-date": "13-06-2025, 12:42:57", "recorded-content": { "put-src-object": { "ChecksumCRC32": "poTHxg==", diff --git a/tests/aws/services/s3/test_s3_api.validation.json b/tests/aws/services/s3/test_s3_api.validation.json index 54c592fb6a1ea..d106b843931f2 100644 --- a/tests/aws/services/s3/test_s3_api.validation.json +++ b/tests/aws/services/s3/test_s3_api.validation.json @@ -69,10 +69,22 @@ "last_validated_date": "2025-01-21T18:10:31+00:00" }, "tests/aws/services/s3/test_s3_api.py::TestS3Multipart::test_upload_part_copy_no_copy_source_range": { - "last_validated_date": "2025-01-21T18:10:16+00:00" + "last_validated_date": "2025-06-13T12:42:58+00:00", + "durations_in_seconds": { + "setup": 0.55, + "call": 0.66, + "teardown": 1.07, + "total": 2.28 + } }, "tests/aws/services/s3/test_s3_api.py::TestS3Multipart::test_upload_part_copy_range": { - "last_validated_date": "2025-01-21T18:10:14+00:00" + "last_validated_date": "2025-06-13T12:42:55+00:00", + "durations_in_seconds": { + "setup": 1.02, + "call": 5.28, + "teardown": 1.54, + "total": 7.84 + } }, "tests/aws/services/s3/test_s3_api.py::TestS3ObjectCRUD::test_delete_object": { "last_validated_date": "2025-01-21T18:09:31+00:00" From ca540515bf552076c31c0fc345874b36af0b8805 Mon Sep 17 00:00:00 2001 From: Alexander Rashed <2796604+alexrashed@users.noreply.github.com> Date: Mon, 16 Jun 2025 15:32:29 +0200 Subject: [PATCH 31/74] Migrate from depenadbot reviewers to codeowners (#12762) --- .github/dependabot.yml | 6 ------ CODEOWNERS | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e2d4b7fd95167..3fd7b9f6a75e2 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,9 +4,6 @@ updates: directory: "/" schedule: interval: "weekly" - reviewers: - - "silv-io" - - "alexrashed" ignore: - dependency-name: "python" update-types: ["version-update:semver-major", "version-update:semver-minor"] @@ -23,9 +20,6 @@ updates: directory: "/" schedule: interval: "weekly" - reviewers: - - "silv-io" - - "alexrashed" labels: - "area: dependencies" - "semver: patch" diff --git a/CODEOWNERS b/CODEOWNERS index 21eb166c492c2..d234e770c5024 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -14,7 +14,7 @@ # Docker /bin/docker-entrypoint.sh @thrau @alexrashed /.dockerignore @alexrashed -/Dockerfile @alexrashed +/Dockerfile* @alexrashed @silv-io # Git, Pipelines, GitHub config /.github @alexrashed @dfangl @dominikschubert @silv-io @k-a-il From 1f6e382f30f2569ee1f490074afaf6f187b4c842 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Jun 2025 08:54:10 +0200 Subject: [PATCH 32/74] Bump python from `7a3ed12` to `9e1912a` in the docker-base-images group (#12765) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Dockerfile | 2 +- Dockerfile.s3 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index ecabcde459554..6c27ed582e78d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # # base: Stage which installs necessary runtime dependencies (OS packages, etc.) # -FROM python:3.11.13-slim-bookworm@sha256:7a3ed1226224bcc1fe5443262363d42f48cf832a540c1836ba8ccbeaadf8637c AS base +FROM python:3.11.13-slim-bookworm@sha256:9e1912aab0a30bbd9488eb79063f68f42a68ab0946cbe98fecf197fe5b085506 AS base ARG TARGETARCH # Install runtime OS package dependencies diff --git a/Dockerfile.s3 b/Dockerfile.s3 index 3f377c27dc4bd..25c6aae9a348e 100644 --- a/Dockerfile.s3 +++ b/Dockerfile.s3 @@ -1,5 +1,5 @@ # base: Stage which installs necessary runtime dependencies (OS packages, filesystem...) -FROM python:3.11.13-slim-bookworm@sha256:7a3ed1226224bcc1fe5443262363d42f48cf832a540c1836ba8ccbeaadf8637c AS base +FROM python:3.11.13-slim-bookworm@sha256:9e1912aab0a30bbd9488eb79063f68f42a68ab0946cbe98fecf197fe5b085506 AS base ARG TARGETARCH # set workdir From 21c4d5ded1128499d9f25d4d0a9da67c7a09a872 Mon Sep 17 00:00:00 2001 From: Anastasia Dusak <61540676+k-a-il@users.noreply.github.com> Date: Tue, 17 Jun 2025 10:02:18 +0200 Subject: [PATCH 33/74] Update test durations automatically based on latest durations from master (#12748) --- .github/workflows/aws-tests.yml | 8 ++- .github/workflows/update-test-durations.yml | 75 +++++++++++++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/update-test-durations.yml diff --git a/.github/workflows/aws-tests.yml b/.github/workflows/aws-tests.yml index 7fcd14086b9e5..e44f6a59bc80c 100644 --- a/.github/workflows/aws-tests.yml +++ b/.github/workflows/aws-tests.yml @@ -374,12 +374,18 @@ jobs: DOCKER_SDK_DEFAULT_TIMEOUT_SECONDS: 300 run: make docker-run-tests + # Test durations are fetched and merged automatically by a separate workflow. + # Files must have unique names to prevent overwrites when multiple artifacts are downloaded + - name: Rename test durations file + run: | + mv .test_durations .test_durations-${{ env.PLATFORM }}-${{ matrix.group }} + - name: Archive Test Durations uses: actions/upload-artifact@v4 if: success() || failure() with: name: pytest-split-durations-${{ env.PLATFORM }}-${{ matrix.group }} - path: .test_durations + path: .test_durations-${{ env.PLATFORM }}-${{ matrix.group }} include-hidden-files: true retention-days: 5 diff --git a/.github/workflows/update-test-durations.yml b/.github/workflows/update-test-durations.yml new file mode 100644 index 0000000000000..12c33df527337 --- /dev/null +++ b/.github/workflows/update-test-durations.yml @@ -0,0 +1,75 @@ +name: Update test durations + +on: + schedule: + - cron: 0 4 * 1-12 MON + workflow_dispatch: + inputs: + publishMethod: + description: 'Select how to publish the workflow result' + type: choice + options: + - UPLOAD_ARTIFACT + - CREATE_PR + default: UPLOAD_ARTIFACT + +env: + # Take test durations only for this platform + PLATFORM: "amd64" + +jobs: + report: + name: "Download, merge and create PR with test durations" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + path: localstack + + - name: Latest run-id from community repository + run: | + latest_workflow_id=$(curl -s https://api.github.com/repos/localstack/localstack/actions/workflows \ + | jq '.workflows[] | select(.path==".github/workflows/aws-main.yml").id') + latest_run_id=$(curl -s \ + "https://api.github.com/repos/localstack/localstack/actions/workflows/${latest_workflow_id}/runs?branch=master&status=success&per_page=30" \ + | jq '[.workflow_runs[] | select(.event == "schedule")][0].id') + echo "Latest run: https://github.com/localstack/localstack/actions/runs/${latest_run_id}" + echo "AWS_MAIN_LATEST_SCHEDULED_RUN_ID=${latest_run_id}" >> $GITHUB_ENV + + - name: Load test durations + uses: actions/download-artifact@v4 + with: + pattern: pytest-split-durations-${{ env.PLATFORM }}-* + path: artifacts-test-durations + merge-multiple: true + run-id: ${{ env.AWS_MAIN_LATEST_SCHEDULED_RUN_ID }} + github-token: ${{ secrets.GITHUB_TOKEN }} # PAT with access to artifacts from GH Actions + + - name: Merge test durations files + shell: bash + run: | + jq -s 'add | to_entries | sort_by(.key) | from_entries' artifacts-test-durations/.test_durations-${{ env.PLATFORM }}* > localstack/.test_durations || echo "::warning::Test durations were not merged" + + - name: Upload artifact with merged test durations + uses: actions/upload-artifact@v4 + if: ${{ success() && inputs.publishMethod == 'UPLOAD_ARTIFACT' }} + with: + name: merged-test-durations + path: localstack/.test_durations + include-hidden-files: true + if-no-files-found: error + + - name: Create PR + uses: peter-evans/create-pull-request@v7 + if: ${{ success() && inputs.publishMethod != 'UPLOAD_ARTIFACT' }} + with: + title: "[Testing] Update test durations" + body: "This PR includes an updated `.test_durations` file, generated based on latest test durations from master" + branch: "test-durations-auto-updates" + author: "LocalStack Bot " + committer: "LocalStack Bot " + commit-message: "CI: update .test_durations to latest version" + path: localstack + add-paths: .test_durations + labels: "semver: patch, area: testing, area: ci" + token: ${{ secrets.PRO_ACCESS_TOKEN }} From d724a6904e6b28bf04fd5d919a12dac399f38e40 Mon Sep 17 00:00:00 2001 From: Viren Nadkarni Date: Tue, 17 Jun 2025 16:04:03 +0530 Subject: [PATCH 34/74] SQS: Register query API routes in provider lifecycle hook (#12685) --- localstack-core/localstack/services/providers.py | 4 ---- localstack-core/localstack/services/sqs/provider.py | 2 ++ 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/localstack-core/localstack/services/providers.py b/localstack-core/localstack/services/providers.py index 810c7fd097b16..2a09121d430f1 100644 --- a/localstack-core/localstack/services/providers.py +++ b/localstack-core/localstack/services/providers.py @@ -320,12 +320,8 @@ def sns(): @aws_provider() def sqs(): - from localstack.services import edge - from localstack.services.sqs import query_api from localstack.services.sqs.provider import SqsProvider - query_api.register(edge.ROUTER) - provider = SqsProvider() return Service.for_provider(provider) diff --git a/localstack-core/localstack/services/sqs/provider.py b/localstack-core/localstack/services/sqs/provider.py index 10988383bd745..6afd18f0d8fe5 100644 --- a/localstack-core/localstack/services/sqs/provider.py +++ b/localstack-core/localstack/services/sqs/provider.py @@ -77,6 +77,7 @@ from localstack.services.edge import ROUTER from localstack.services.plugins import ServiceLifecycleHook from localstack.services.sqs import constants as sqs_constants +from localstack.services.sqs import query_api from localstack.services.sqs.constants import ( HEADER_LOCALSTACK_SQS_OVERRIDE_MESSAGE_COUNT, HEADER_LOCALSTACK_SQS_OVERRIDE_WAIT_TIME_SECONDS, @@ -828,6 +829,7 @@ def get_store(account_id: str, region: str) -> SqsStore: return sqs_stores[account_id][region] def on_before_start(self): + query_api.register(ROUTER) self._router_rules = ROUTER.add(SqsDeveloperEndpoints()) self._queue_update_worker.start() self._start_cloudwatch_metrics_reporting() From 1d3ef0c2b0e580367acfcfe2638a2f4d96421c08 Mon Sep 17 00:00:00 2001 From: Vittorio Polverino Date: Tue, 17 Jun 2025 13:24:02 +0200 Subject: [PATCH 35/74] feat: metrics schema version (#12732) --- .../localstack/utils/analytics/metrics/api.py | 18 ++++- .../utils/analytics/metrics/counter.py | 22 ++++-- tests/unit/utils/analytics/test_metrics.py | 71 +++++++++++++++++++ 3 files changed, 104 insertions(+), 7 deletions(-) diff --git a/localstack-core/localstack/utils/analytics/metrics/api.py b/localstack-core/localstack/utils/analytics/metrics/api.py index 56125a9ddc472..f8d79483d666b 100644 --- a/localstack-core/localstack/utils/analytics/metrics/api.py +++ b/localstack-core/localstack/utils/analytics/metrics/api.py @@ -16,8 +16,9 @@ class Metric(ABC): _namespace: str _name: str + _schema_version: int - def __init__(self, namespace: str, name: str): + def __init__(self, namespace: str, name: str, schema_version: int = 1): if not namespace or namespace.strip() == "": raise ValueError("Namespace must be non-empty string.") self._namespace = namespace @@ -26,6 +27,17 @@ def __init__(self, namespace: str, name: str): raise ValueError("Metric name must be non-empty string.") self._name = name + if schema_version is None: + raise ValueError("An explicit schema_version is required for Counter metrics") + + if not isinstance(schema_version, int): + raise TypeError("Schema version must be an integer.") + + if schema_version <= 0: + raise ValueError("Schema version must be greater than zero.") + + self._schema_version = schema_version + @property def namespace(self) -> str: return self._namespace @@ -34,6 +46,10 @@ def namespace(self) -> str: def name(self) -> str: return self._name + @property + def schema_version(self) -> int: + return self._schema_version + @abstractmethod def collect(self) -> list[Payload]: """ diff --git a/localstack-core/localstack/utils/analytics/metrics/counter.py b/localstack-core/localstack/utils/analytics/metrics/counter.py index 31b8a6a9de008..42dfa5a673e9c 100644 --- a/localstack-core/localstack/utils/analytics/metrics/counter.py +++ b/localstack-core/localstack/utils/analytics/metrics/counter.py @@ -17,6 +17,7 @@ class CounterPayload: name: str value: int type: str + schema_version: int def as_dict(self) -> dict[str, Any]: return { @@ -24,6 +25,7 @@ def as_dict(self) -> dict[str, Any]: "name": self.name, "value": self.value, "type": self.type, + "schema_version": self.schema_version, } @@ -35,6 +37,7 @@ class LabeledCounterPayload: name: str value: int type: str + schema_version: int labels: dict[str, Union[str, float]] def as_dict(self) -> dict[str, Any]: @@ -43,6 +46,7 @@ def as_dict(self) -> dict[str, Any]: "name": self.name, "value": self.value, "type": self.type, + "schema_version": self.schema_version, } for i, (label_name, label_value) in enumerate(self.labels.items(), 1): @@ -99,12 +103,11 @@ class Counter(Metric, ThreadSafeCounter): _type: str - def __init__(self, namespace: str, name: str): - Metric.__init__(self, namespace=namespace, name=name) + def __init__(self, namespace: str, name: str, schema_version: int = 1): + Metric.__init__(self, namespace=namespace, name=name, schema_version=schema_version) ThreadSafeCounter.__init__(self) self._type = "counter" - MetricRegistry().register(self) def collect(self) -> list[CounterPayload]: @@ -118,7 +121,11 @@ def collect(self) -> list[CounterPayload]: return [ CounterPayload( - namespace=self._namespace, name=self.name, value=self._count, type=self._type + namespace=self._namespace, + name=self.name, + value=self._count, + type=self._type, + schema_version=self._schema_version, ) ] @@ -138,8 +145,10 @@ class LabeledCounter(Metric): tuple[Optional[Union[str, float]], ...], ThreadSafeCounter ] - def __init__(self, namespace: str, name: str, labels: list[str]): - super(LabeledCounter, self).__init__(namespace=namespace, name=name) + def __init__(self, namespace: str, name: str, labels: list[str], schema_version: int = 1): + super(LabeledCounter, self).__init__( + namespace=namespace, name=name, schema_version=schema_version + ) if not labels: raise ValueError("At least one label is required; the labels list cannot be empty.") @@ -202,6 +211,7 @@ def collect(self) -> list[LabeledCounterPayload]: name=self.name, value=counter.count, type=self._type, + schema_version=self._schema_version, labels=labels_dict, ) ) diff --git a/tests/unit/utils/analytics/test_metrics.py b/tests/unit/utils/analytics/test_metrics.py index 8bdec6df31ca9..1695aeea340d7 100644 --- a/tests/unit/utils/analytics/test_metrics.py +++ b/tests/unit/utils/analytics/test_metrics.py @@ -201,3 +201,74 @@ def test_label_kwargs_order_independent(): metric.value == 3 and metric.labels and metric.labels.get("status") == "error" for metric in collected_metrics ), "Unexpected counter value for label error" + + +def test_default_schema_version_for_counter(): + counter = Counter(namespace="test_namespace", name="test_name") + counter.increment() + collected_metrics = counter.collect() + assert collected_metrics[0].schema_version == 1, ( + "Default schema_version for Counter should be 1" + ) + + +def test_custom_schema_version_for_counter(): + counter = Counter(namespace="test_namespace", name="test_name", schema_version=3) + counter.increment() + collected_metrics = counter.collect() + assert collected_metrics[0].schema_version == 3 + + +def test_default_schema_version_for_labeled_counter(): + labeled_counter = LabeledCounter(namespace="test_namespace", name="test_name", labels=["type"]) + labeled_counter.labels(type="success").increment() + collected_metrics = labeled_counter.collect() + assert collected_metrics[0].schema_version == 1, ( + "Default schema_version for LabeledCounter should be 1" + ) + + +def test_custom_schema_version_for_labeled_counter(): + labeled_counter = LabeledCounter( + namespace="test_namespace", + name="test_name", + labels=["type"], + schema_version=5, + ) + labeled_counter.labels(type="success").increment() + collected_metrics = labeled_counter.collect() + assert collected_metrics[0].schema_version == 5 + + +def test_labeled_counter_schema_version_none_raises_value_error(): + with pytest.raises( + ValueError, match="An explicit schema_version is required for Counter metrics" + ): + LabeledCounter( + namespace="test_namespace", + name="test_name", + labels=["type"], + schema_version=None, + ) + + +@pytest.mark.parametrize("invalid_version", ["1", "invalid"]) +def test_labeled_counter_schema_version_non_int_raises_type_error(invalid_version): + with pytest.raises(TypeError, match="Schema version must be an integer."): + LabeledCounter( + namespace="test_namespace", + name="test_name", + labels=["type"], + schema_version=invalid_version, + ) + + +@pytest.mark.parametrize("invalid_version", [0, -5]) +def test_labeled_counter_schema_version_non_positive_raises_value_error(invalid_version): + with pytest.raises(ValueError, match="Schema version must be greater than zero."): + LabeledCounter( + namespace="test_namespace", + name="test_name", + labels=["type"], + schema_version=invalid_version, + ) From 87d4176e265f5239b4e57ccb0083e96a51efe2ba Mon Sep 17 00:00:00 2001 From: cristiangiann <37883351+cristiangiann@users.noreply.github.com> Date: Tue, 17 Jun 2025 13:28:54 +0200 Subject: [PATCH 36/74] S3: Implement Put, Get, Delete, List S3 MetricsConfiguration API (#12741) --- .../localstack/services/s3/exceptions.py | 5 + .../localstack/services/s3/models.py | 4 + .../localstack/services/s3/provider.py | 142 ++++++++++++++ tests/aws/services/s3/test_s3_api.py | 161 ++++++++++++++++ .../aws/services/s3/test_s3_api.snapshot.json | 173 ++++++++++++++++++ .../services/s3/test_s3_api.validation.json | 28 ++- 6 files changed, 511 insertions(+), 2 deletions(-) diff --git a/localstack-core/localstack/services/s3/exceptions.py b/localstack-core/localstack/services/s3/exceptions.py index 4e00d8dce33a2..382631de91a50 100644 --- a/localstack-core/localstack/services/s3/exceptions.py +++ b/localstack-core/localstack/services/s3/exceptions.py @@ -46,3 +46,8 @@ def __init__(self, message=None): class InvalidBucketOwnerAWSAccountID(CommonServiceException): def __init__(self, message=None) -> None: super().__init__("InvalidBucketOwnerAWSAccountID", status_code=400, message=message) + + +class TooManyConfigurations(CommonServiceException): + def __init__(self, message=None) -> None: + super().__init__("TooManyConfigurations", status_code=400, message=message) diff --git a/localstack-core/localstack/services/s3/models.py b/localstack-core/localstack/services/s3/models.py index 6d96b55b83521..2a036076e5f99 100644 --- a/localstack-core/localstack/services/s3/models.py +++ b/localstack-core/localstack/services/s3/models.py @@ -37,6 +37,8 @@ LoggingEnabled, Metadata, MethodNotAllowed, + MetricsConfiguration, + MetricsId, MultipartUploadId, NoSuchKey, NoSuchVersion, @@ -115,6 +117,7 @@ class S3Bucket: intelligent_tiering_configurations: dict[IntelligentTieringId, IntelligentTieringConfiguration] analytics_configurations: dict[AnalyticsId, AnalyticsConfiguration] inventory_configurations: dict[InventoryId, InventoryConfiguration] + metric_configurations: dict[MetricsId, MetricsConfiguration] object_lock_default_retention: Optional[DefaultRetention] replication: ReplicationConfiguration owner: Owner @@ -154,6 +157,7 @@ def __init__( self.intelligent_tiering_configurations = {} self.analytics_configurations = {} self.inventory_configurations = {} + self.metric_configurations = {} self.object_lock_default_retention = {} self.replication = None self.acl = acl diff --git a/localstack-core/localstack/services/s3/provider.py b/localstack-core/localstack/services/s3/provider.py index cfb266d095744..f5d16597c975f 100644 --- a/localstack-core/localstack/services/s3/provider.py +++ b/localstack-core/localstack/services/s3/provider.py @@ -80,6 +80,7 @@ GetBucketLifecycleConfigurationOutput, GetBucketLocationOutput, GetBucketLoggingOutput, + GetBucketMetricsConfigurationOutput, GetBucketOwnershipControlsOutput, GetBucketPolicyOutput, GetBucketPolicyStatusOutput, @@ -126,6 +127,7 @@ ListBucketAnalyticsConfigurationsOutput, ListBucketIntelligentTieringConfigurationsOutput, ListBucketInventoryConfigurationsOutput, + ListBucketMetricsConfigurationsOutput, ListBucketsOutput, ListMultipartUploadsOutput, ListObjectsOutput, @@ -138,6 +140,8 @@ MaxParts, MaxUploads, MethodNotAllowed, + MetricsConfiguration, + MetricsId, MissingSecurityHeader, MpuObjectSize, MultipartUpload, @@ -240,6 +244,7 @@ MalformedXML, NoSuchConfiguration, NoSuchObjectLockConfiguration, + TooManyConfigurations, UnexpectedContent, ) from localstack.services.s3.models import ( @@ -4433,6 +4438,143 @@ def post_object( return response + def put_bucket_metrics_configuration( + self, + context: RequestContext, + bucket: BucketName, + id: MetricsId, + metrics_configuration: MetricsConfiguration, + expected_bucket_owner: AccountId = None, + **kwargs, + ) -> None: + """ + Update or add a new metrics configuration. If the provided `id` already exists, its associated configuration + will be overwritten. The total number of metric configurations is limited to 1000. If this limit is exceeded, + an error is raised unless the `is` already exists. + + :param context: The request context. + :param bucket: The name of the bucket associated with the metrics configuration. + :param id: Identifies the metrics configuration being added or updated. + :param metrics_configuration: A new or updated configuration associated with the given metrics identifier. + :param expected_bucket_owner: The expected account ID of the bucket owner. + :return: None + :raises TooManyConfigurations: If the total number of metrics configurations exceeds 1000 AND the provided + `metrics_id` does not already exist. + """ + store, s3_bucket = self._get_cross_account_bucket( + context, bucket, expected_bucket_owner=expected_bucket_owner + ) + + if ( + len(s3_bucket.metric_configurations) >= 1000 + and id not in s3_bucket.metric_configurations + ): + raise TooManyConfigurations("Too many metrics configurations") + s3_bucket.metric_configurations[id] = metrics_configuration + + def get_bucket_metrics_configuration( + self, + context: RequestContext, + bucket: BucketName, + id: MetricsId, + expected_bucket_owner: AccountId = None, + **kwargs, + ) -> GetBucketMetricsConfigurationOutput: + """ + Retrieve the metrics configuration associated with a given metrics identifier. + + :param context: The request context. + :param bucket: The name of the bucket associated with the metrics configuration. + :param id: The unique identifier of the metrics configuration to retrieve. + :param expected_bucket_owner: The expected account ID of the bucket owner. + :return: The metrics configuration associated with the given metrics identifier. + :raises NoSuchConfiguration: If the provided metrics configuration does not exist. + """ + store, s3_bucket = self._get_cross_account_bucket( + context, bucket, expected_bucket_owner=expected_bucket_owner + ) + + metric_config = s3_bucket.metric_configurations.get(id) + if not metric_config: + raise NoSuchConfiguration("The specified configuration does not exist.") + return GetBucketMetricsConfigurationOutput(MetricsConfiguration=metric_config) + + def list_bucket_metrics_configurations( + self, + context: RequestContext, + bucket: BucketName, + continuation_token: Token = None, + expected_bucket_owner: AccountId = None, + **kwargs, + ) -> ListBucketMetricsConfigurationsOutput: + """ + Lists the metric configurations available, allowing for pagination using a continuation token to retrieve more + results. + + :param context: The request context. + :param bucket: The name of the bucket associated with the metrics configuration. + :param continuation_token: An optional continuation token to retrieve the next set of results in case there are + more results than the default limit. Provided as a base64-encoded string value. + :param expected_bucket_owner: The expected account ID of the bucket owner. + :return: A list of metric configurations and an optional continuation token for fetching subsequent data, if + applicable. + """ + store, s3_bucket = self._get_cross_account_bucket( + context, bucket, expected_bucket_owner=expected_bucket_owner + ) + + metrics_configurations: list[MetricsConfiguration] = [] + next_continuation_token = None + + decoded_continuation_token = ( + to_str(base64.urlsafe_b64decode(continuation_token.encode())) + if continuation_token + else None + ) + + for metric in sorted(s3_bucket.metric_configurations.values(), key=lambda r: r["Id"]): + if continuation_token and metric["Id"] < decoded_continuation_token: + continue + + if len(metrics_configurations) >= 100: + next_continuation_token = to_str(base64.urlsafe_b64encode(metric["Id"].encode())) + break + + metrics_configurations.append(metric) + + return ListBucketMetricsConfigurationsOutput( + IsTruncated=next_continuation_token is not None, + ContinuationToken=continuation_token, + NextContinuationToken=next_continuation_token, + MetricsConfigurationList=metrics_configurations, + ) + + def delete_bucket_metrics_configuration( + self, + context: RequestContext, + bucket: BucketName, + id: MetricsId, + expected_bucket_owner: AccountId = None, + **kwargs, + ) -> None: + """ + Removes a specific metrics configuration identified by its metrics ID. + + :param context: The request context. + :param bucket: The name of the bucket associated with the metrics configuration. + :param id: The unique identifier of the metrics configuration to delete. + :param expected_bucket_owner: The expected account ID of the bucket owner. + :return: None + :raises NoSuchConfiguration: If the provided metrics configuration does not exist. + """ + store, s3_bucket = self._get_cross_account_bucket( + context, bucket, expected_bucket_owner=expected_bucket_owner + ) + + deleted_config = s3_bucket.metric_configurations.pop(id, None) + if not deleted_config: + raise NoSuchConfiguration("The specified configuration does not exist.") + def generate_version_id(bucket_versioning_status: str) -> str | None: if not bucket_versioning_status: diff --git a/tests/aws/services/s3/test_s3_api.py b/tests/aws/services/s3/test_s3_api.py index 197bb5053af3e..8841a94c0e222 100644 --- a/tests/aws/services/s3/test_s3_api.py +++ b/tests/aws/services/s3/test_s3_api.py @@ -2180,3 +2180,164 @@ def test_multipart_if_match_etag(self, s3_bucket, aws_client, snapshot): IfMatch=multipart_etag, ) snapshot.match("complete-multipart-if-match-overwrite-multipart", complete_multipart_1) + + +class TestS3MetricsConfiguration: + @markers.aws.validated + @markers.snapshot.skip_snapshot_verify( + paths=[ + # PutBucketMetricsConfiguration should return 204, but we return 200 + "$.put_bucket_metrics_configuration.ResponseMetadata.HTTPStatusCode", + ] + ) + def test_put_bucket_metrics_configuration(self, s3_bucket, aws_client, snapshot): + snapshot.add_transformer([snapshot.transform.key_value("Id")]) + + metric_id = short_uid() + metrics_config = {"Id": metric_id, "Filter": {"Prefix": "logs/"}} + + put_result = aws_client.s3.put_bucket_metrics_configuration( + Bucket=s3_bucket, Id=metric_id, MetricsConfiguration=metrics_config + ) + snapshot.match("put_bucket_metrics_configuration", put_result) + + get_result = aws_client.s3.get_bucket_metrics_configuration(Bucket=s3_bucket, Id=metric_id) + snapshot.match("get_bucket_metrics_configuration", get_result) + + @markers.aws.validated + @markers.snapshot.skip_snapshot_verify( + paths=[ + # PutBucketMetricsConfiguration should return 204, but we return 200 + "$.overwrite_bucket_metrics_configuration.ResponseMetadata.HTTPStatusCode", + ] + ) + def test_overwrite_bucket_metrics_configuration(self, s3_bucket, aws_client, snapshot): + snapshot.add_transformer([snapshot.transform.key_value("Id")]) + + metric_id = short_uid() + metrics_config = {"Id": metric_id, "Filter": {"Prefix": "logs/"}} + + aws_client.s3.put_bucket_metrics_configuration( + Bucket=s3_bucket, Id=metric_id, MetricsConfiguration=metrics_config + ) + + metrics_config["Filter"]["Prefix"] = "logs/new-prefix" + + overwrite_result = aws_client.s3.put_bucket_metrics_configuration( + Bucket=s3_bucket, Id=metric_id, MetricsConfiguration=metrics_config + ) + snapshot.match("overwrite_bucket_metrics_configuration", overwrite_result) + + get_result = aws_client.s3.get_bucket_metrics_configuration(Bucket=s3_bucket, Id=metric_id) + snapshot.match("get_bucket_metrics_configuration", get_result) + + @markers.aws.validated + def test_list_bucket_metrics_configurations(self, s3_bucket, aws_client, snapshot): + snapshot.add_transformer(snapshot.transform.key_value("Id")) + + metric_id_1 = f"1-{short_uid()}" + metric_id_2 = f"2-{short_uid()}" + + metrics_configs = { + metric_id_1: {"Id": metric_id_1, "Filter": {"Prefix": "logs/prefix"}}, + metric_id_2: {"Id": metric_id_2, "Filter": {"Prefix": "logs/prefix"}}, + } + + for metrics_config in metrics_configs.values(): + aws_client.s3.put_bucket_metrics_configuration( + Bucket=s3_bucket, Id=metrics_config["Id"], MetricsConfiguration=metrics_config + ) + + result_configs = aws_client.s3.list_bucket_metrics_configurations(Bucket=s3_bucket) + snapshot.match("list_bucket_metrics_configurations", result_configs) + + @markers.aws.validated + def test_list_bucket_metrics_configurations_paginated(self, s3_bucket, aws_client, snapshot): + snapshot.add_transformer( + [ + snapshot.transform.key_value("Id"), + snapshot.transform.key_value("NextContinuationToken"), + snapshot.transform.key_value("ContinuationToken"), + ] + ) + + metrics_configs = {} + for i in range(102): + metric_id = f"{100 + i}-{short_uid()}" + metrics_configs[metric_id] = {"Id": metric_id, "Filter": {"Prefix": "logs/prefix"}} + + for metrics_config in metrics_configs.values(): + aws_client.s3.put_bucket_metrics_configuration( + Bucket=s3_bucket, Id=metrics_config["Id"], MetricsConfiguration=metrics_config + ) + + result_configs_page_1 = aws_client.s3.list_bucket_metrics_configurations(Bucket=s3_bucket) + assert len(result_configs_page_1["MetricsConfigurationList"]) == 100 + assert result_configs_page_1["NextContinuationToken"] + + result_configs_page_2 = aws_client.s3.list_bucket_metrics_configurations( + Bucket=s3_bucket, ContinuationToken=result_configs_page_1["NextContinuationToken"] + ) + snapshot.match("list_bucket_metrics_configurations_page_2", result_configs_page_2) + + @markers.aws.validated + def test_get_bucket_metrics_configuration(self, s3_bucket, aws_client, snapshot): + snapshot.add_transformer(snapshot.transform.key_value("Id")) + + metric_id = short_uid() + metrics_config = {"Id": metric_id, "Filter": {"Prefix": "logs/"}} + + aws_client.s3.put_bucket_metrics_configuration( + Bucket=s3_bucket, Id=metric_id, MetricsConfiguration=metrics_config + ) + + result = aws_client.s3.get_bucket_metrics_configuration(Bucket=s3_bucket, Id=metric_id) + snapshot.match("get_bucket_metrics_configuration", result) + + @markers.aws.validated + def test_get_bucket_metrics_configuration_not_exist(self, s3_bucket, aws_client, snapshot): + snapshot.add_transformer(snapshot.transform.key_value("Id")) + + with pytest.raises(ClientError) as get_err: + aws_client.s3.get_bucket_metrics_configuration(Bucket=s3_bucket, Id="does-not-exist") + snapshot.match("get_bucket_metrics_configuration", get_err.value.response) + + @markers.aws.validated + def test_delete_metrics_configuration(self, s3_bucket, aws_client, snapshot): + snapshot.add_transformer(snapshot.transform.key_value("Id")) + + metric_id = short_uid() + metrics_config = {"Id": metric_id, "Filter": {"Prefix": "logs/"}} + + aws_client.s3.put_bucket_metrics_configuration( + Bucket=s3_bucket, Id=metric_id, MetricsConfiguration=metrics_config + ) + + delete_result = aws_client.s3.delete_bucket_metrics_configuration( + Bucket=s3_bucket, Id=metric_id + ) + snapshot.match("delete_bucket_metrics_configuration", delete_result) + + with pytest.raises(ClientError) as get_err: + aws_client.s3.get_bucket_metrics_configuration(Bucket=s3_bucket, Id=metric_id) + snapshot.match("get_bucket_metrics_configuration", get_err.value.response) + + @markers.aws.validated + def test_delete_metrics_configuration_twice(self, s3_bucket, aws_client, snapshot): + snapshot.add_transformer(snapshot.transform.key_value("Id")) + + metric_id = short_uid() + metrics_config = {"Id": metric_id, "Filter": {"Prefix": "logs/"}} + + aws_client.s3.put_bucket_metrics_configuration( + Bucket=s3_bucket, Id=metric_id, MetricsConfiguration=metrics_config + ) + + delete_result_1 = aws_client.s3.delete_bucket_metrics_configuration( + Bucket=s3_bucket, Id=metric_id + ) + snapshot.match("delete_bucket_metrics_configuration_1", delete_result_1) + + with pytest.raises(ClientError) as delete_err: + aws_client.s3.delete_bucket_metrics_configuration(Bucket=s3_bucket, Id=metric_id) + snapshot.match("delete_bucket_metrics_configuration_2", delete_err.value.response) diff --git a/tests/aws/services/s3/test_s3_api.snapshot.json b/tests/aws/services/s3/test_s3_api.snapshot.json index d980b973f7119..9c1ecc9115109 100644 --- a/tests/aws/services/s3/test_s3_api.snapshot.json +++ b/tests/aws/services/s3/test_s3_api.snapshot.json @@ -4428,5 +4428,178 @@ } } } + }, + "tests/aws/services/s3/test_s3_api.py::TestS3MetricsConfiguration::test_put_bucket_metrics_configuration": { + "recorded-date": "13-06-2025, 08:33:02", + "recorded-content": { + "put_bucket_metrics_configuration": { + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 204 + } + }, + "get_bucket_metrics_configuration": { + "MetricsConfiguration": { + "Filter": { + "Prefix": "logs/" + }, + "Id": "" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } + }, + "tests/aws/services/s3/test_s3_api.py::TestS3MetricsConfiguration::test_overwrite_bucket_metrics_configuration": { + "recorded-date": "13-06-2025, 08:33:03", + "recorded-content": { + "overwrite_bucket_metrics_configuration": { + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 204 + } + }, + "get_bucket_metrics_configuration": { + "MetricsConfiguration": { + "Filter": { + "Prefix": "logs/new-prefix" + }, + "Id": "" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } + }, + "tests/aws/services/s3/test_s3_api.py::TestS3MetricsConfiguration::test_list_bucket_metrics_configurations": { + "recorded-date": "13-06-2025, 08:33:04", + "recorded-content": { + "list_bucket_metrics_configurations": { + "IsTruncated": false, + "MetricsConfigurationList": [ + { + "Filter": { + "Prefix": "logs/prefix" + }, + "Id": "" + }, + { + "Filter": { + "Prefix": "logs/prefix" + }, + "Id": "" + } + ], + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } + }, + "tests/aws/services/s3/test_s3_api.py::TestS3MetricsConfiguration::test_get_bucket_metrics_configuration": { + "recorded-date": "13-06-2025, 08:33:17", + "recorded-content": { + "get_bucket_metrics_configuration": { + "MetricsConfiguration": { + "Filter": { + "Prefix": "logs/" + }, + "Id": "" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } + }, + "tests/aws/services/s3/test_s3_api.py::TestS3MetricsConfiguration::test_get_bucket_metrics_configuration_not_exist": { + "recorded-date": "13-06-2025, 08:33:18", + "recorded-content": { + "get_bucket_metrics_configuration": { + "Error": { + "Code": "NoSuchConfiguration", + "Message": "The specified configuration does not exist." + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 404 + } + } + } + }, + "tests/aws/services/s3/test_s3_api.py::TestS3MetricsConfiguration::test_delete_metrics_configuration": { + "recorded-date": "13-06-2025, 08:33:19", + "recorded-content": { + "delete_bucket_metrics_configuration": { + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 204 + } + }, + "get_bucket_metrics_configuration": { + "Error": { + "Code": "NoSuchConfiguration", + "Message": "The specified configuration does not exist." + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 404 + } + } + } + }, + "tests/aws/services/s3/test_s3_api.py::TestS3MetricsConfiguration::test_list_bucket_metrics_configurations_paginated": { + "recorded-date": "13-06-2025, 08:33:16", + "recorded-content": { + "list_bucket_metrics_configurations_page_2": { + "ContinuationToken": "", + "IsTruncated": false, + "MetricsConfigurationList": [ + { + "Filter": { + "Prefix": "logs/prefix" + }, + "Id": "" + }, + { + "Filter": { + "Prefix": "logs/prefix" + }, + "Id": "" + } + ], + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } + }, + "tests/aws/services/s3/test_s3_api.py::TestS3MetricsConfiguration::test_delete_metrics_configuration_twice": { + "recorded-date": "13-06-2025, 08:33:20", + "recorded-content": { + "delete_bucket_metrics_configuration_1": { + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 204 + } + }, + "delete_bucket_metrics_configuration_2": { + "Error": { + "Code": "NoSuchConfiguration", + "Message": "The specified configuration does not exist." + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 404 + } + } + } } } diff --git a/tests/aws/services/s3/test_s3_api.validation.json b/tests/aws/services/s3/test_s3_api.validation.json index d106b843931f2..2868dd1906731 100644 --- a/tests/aws/services/s3/test_s3_api.validation.json +++ b/tests/aws/services/s3/test_s3_api.validation.json @@ -30,7 +30,7 @@ "last_validated_date": "2025-01-21T18:11:06+00:00" }, "tests/aws/services/s3/test_s3_api.py::TestS3BucketObjectTagging::test_bucket_tagging_exc": { - "last_validated_date": "2025-01-21T18:11:07+00:00" + "last_validated_date": "2025-06-12T23:32:16+00:00" }, "tests/aws/services/s3/test_s3_api.py::TestS3BucketObjectTagging::test_object_tagging_crud": { "last_validated_date": "2025-01-21T18:11:10+00:00" @@ -68,6 +68,30 @@ "tests/aws/services/s3/test_s3_api.py::TestS3BucketVersioning::test_object_version_id_format": { "last_validated_date": "2025-01-21T18:10:31+00:00" }, + "tests/aws/services/s3/test_s3_api.py::TestS3MetricsConfiguration::test_delete_metrics_configuration": { + "last_validated_date": "2025-06-13T08:33:19+00:00" + }, + "tests/aws/services/s3/test_s3_api.py::TestS3MetricsConfiguration::test_delete_metrics_configuration_twice": { + "last_validated_date": "2025-06-13T08:33:20+00:00" + }, + "tests/aws/services/s3/test_s3_api.py::TestS3MetricsConfiguration::test_get_bucket_metrics_configuration": { + "last_validated_date": "2025-06-13T08:33:17+00:00" + }, + "tests/aws/services/s3/test_s3_api.py::TestS3MetricsConfiguration::test_get_bucket_metrics_configuration_not_exist": { + "last_validated_date": "2025-06-13T08:33:18+00:00" + }, + "tests/aws/services/s3/test_s3_api.py::TestS3MetricsConfiguration::test_list_bucket_metrics_configurations": { + "last_validated_date": "2025-06-13T08:33:04+00:00" + }, + "tests/aws/services/s3/test_s3_api.py::TestS3MetricsConfiguration::test_list_bucket_metrics_configurations_paginated": { + "last_validated_date": "2025-06-13T08:33:16+00:00" + }, + "tests/aws/services/s3/test_s3_api.py::TestS3MetricsConfiguration::test_overwrite_bucket_metrics_configuration": { + "last_validated_date": "2025-06-13T08:33:03+00:00" + }, + "tests/aws/services/s3/test_s3_api.py::TestS3MetricsConfiguration::test_put_bucket_metrics_configuration": { + "last_validated_date": "2025-06-13T08:33:02+00:00" + }, "tests/aws/services/s3/test_s3_api.py::TestS3Multipart::test_upload_part_copy_no_copy_source_range": { "last_validated_date": "2025-06-13T12:42:58+00:00", "durations_in_seconds": { @@ -153,7 +177,7 @@ "last_validated_date": "2025-03-17T20:15:50+00:00" }, "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_put_object_if_match_and_if_none_match_validation": { - "last_validated_date": "2025-03-17T20:16:06+00:00" + "last_validated_date": "2025-06-12T23:32:49+00:00" }, "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_put_object_if_match_validation": { "last_validated_date": "2025-03-17T20:15:52+00:00" From 7f025753165c70ffba04dcc421f8907ae2a19657 Mon Sep 17 00:00:00 2001 From: Joel Scheuner Date: Tue, 17 Jun 2025 13:47:28 +0200 Subject: [PATCH 37/74] Fix failing Ruby tests due to internal RUBYLIB variable changed by AWS (#12767) --- .../services/lambda_/test_lambda_common.py | 1 + .../lambda_/test_lambda_common.snapshot.json | 118 ++++++------ .../test_lambda_common.validation.json | 168 +++++++++++++++--- 3 files changed, 207 insertions(+), 80 deletions(-) diff --git a/tests/aws/services/lambda_/test_lambda_common.py b/tests/aws/services/lambda_/test_lambda_common.py index 52850ea655e89..632f899b2040b 100644 --- a/tests/aws/services/lambda_/test_lambda_common.py +++ b/tests/aws/services/lambda_/test_lambda_common.py @@ -133,6 +133,7 @@ def _invoke_with_payload(payload): "$..environment.LD_LIBRARY_PATH", # Only rust runtime (additional /var/lang/bin) "$..environment.PATH", # Only rust runtime (additional /var/lang/bin) "$..environment.LC_CTYPE", # Only python3.11 (part of a broken image rollout, likely rolled back) + "$..environment.RUBYLIB", # Changed around 2025-06-17 # Newer Nodejs images explicitly disable a temporary performance workaround for Nodejs 20 on certain hosts: # https://nodejs.org/api/cli.html#uv_use_io_uringvalue # https://techfindings.net/archives/6469 diff --git a/tests/aws/services/lambda_/test_lambda_common.snapshot.json b/tests/aws/services/lambda_/test_lambda_common.snapshot.json index 262931448bb8c..fa2db765c511b 100644 --- a/tests/aws/services/lambda_/test_lambda_common.snapshot.json +++ b/tests/aws/services/lambda_/test_lambda_common.snapshot.json @@ -64,7 +64,7 @@ "recorded-content": {} }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[python3.8]": { - "recorded-date": "31-03-2025, 12:18:00", + "recorded-date": "17-06-2025, 09:51:26", "recorded-content": { "create_function_result": { "Architectures": [ @@ -205,7 +205,7 @@ } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[java11]": { - "recorded-date": "31-03-2025, 12:18:12", + "recorded-date": "17-06-2025, 09:51:40", "recorded-content": { "create_function_result": { "Architectures": [ @@ -344,7 +344,7 @@ } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[provided.al2]": { - "recorded-date": "31-03-2025, 12:21:46", + "recorded-date": "17-06-2025, 09:52:11", "recorded-content": { "create_function_result": { "Architectures": [ @@ -477,7 +477,7 @@ } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[java8.al2]": { - "recorded-date": "31-03-2025, 12:18:15", + "recorded-date": "17-06-2025, 09:51:44", "recorded-content": { "create_function_result": { "Architectures": [ @@ -549,13 +549,13 @@ "AWS_LAMBDA_INITIALIZATION_TYPE": "on-demand", "AWS_LAMBDA_LOG_GROUP_NAME": "/aws/lambda/", "AWS_LAMBDA_LOG_STREAM_NAME": "", - "AWS_LAMBDA_RUNTIME_API": "127.0.0.1:9001", + "AWS_LAMBDA_RUNTIME_API": "169.254.100.1:9001", "AWS_REGION": "", "AWS_SECRET_ACCESS_KEY": "", "AWS_SECRET_KEY": "", "AWS_SESSION_TOKEN": "", "AWS_XRAY_CONTEXT_MISSING": "LOG_ERROR", - "AWS_XRAY_DAEMON_ADDRESS": "169.254.79.129:2000", + "AWS_XRAY_DAEMON_ADDRESS": "169.254.100.1:2000", "LAMBDA_RUNTIME_DIR": "/var/runtime", "LAMBDA_TASK_ROOT": "/var/task", "LANG": "en_US.UTF-8", @@ -563,7 +563,7 @@ "PATH": "/var/lang/bin:/usr/local/bin:/usr/bin/:/bin:/opt/bin", "TEST_KEY": "TEST_VAL", "TZ": ":UTC", - "_AWS_XRAY_DAEMON_ADDRESS": "169.254.79.129", + "_AWS_XRAY_DAEMON_ADDRESS": "169.254.100.1", "_AWS_XRAY_DAEMON_PORT": "2000", "_HANDLER": "echo.Handler", "_X_AMZN_TRACE_ID": "" @@ -592,13 +592,13 @@ "AWS_LAMBDA_INITIALIZATION_TYPE": "on-demand", "AWS_LAMBDA_LOG_GROUP_NAME": "/aws/lambda/", "AWS_LAMBDA_LOG_STREAM_NAME": "", - "AWS_LAMBDA_RUNTIME_API": "127.0.0.1:9001", + "AWS_LAMBDA_RUNTIME_API": "169.254.100.1:9001", "AWS_REGION": "", "AWS_SECRET_ACCESS_KEY": "", "AWS_SECRET_KEY": "", "AWS_SESSION_TOKEN": "", "AWS_XRAY_CONTEXT_MISSING": "LOG_ERROR", - "AWS_XRAY_DAEMON_ADDRESS": "169.254.79.129:2000", + "AWS_XRAY_DAEMON_ADDRESS": "169.254.100.1:2000", "LAMBDA_RUNTIME_DIR": "/var/runtime", "LAMBDA_TASK_ROOT": "/var/task", "LANG": "en_US.UTF-8", @@ -606,7 +606,7 @@ "PATH": "/var/lang/bin:/usr/local/bin:/usr/bin/:/bin:/opt/bin", "TEST_KEY": "TEST_VAL", "TZ": ":UTC", - "_AWS_XRAY_DAEMON_ADDRESS": "169.254.79.129", + "_AWS_XRAY_DAEMON_ADDRESS": "169.254.100.1", "_AWS_XRAY_DAEMON_PORT": "2000", "_HANDLER": "echo.Handler", "_X_AMZN_TRACE_ID": "" @@ -616,7 +616,7 @@ } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[ruby3.2]": { - "recorded-date": "31-03-2025, 12:18:19", + "recorded-date": "17-06-2025, 09:51:47", "recorded-content": { "create_function_result": { "Architectures": [ @@ -687,12 +687,12 @@ "AWS_LAMBDA_INITIALIZATION_TYPE": "on-demand", "AWS_LAMBDA_LOG_GROUP_NAME": "/aws/lambda/", "AWS_LAMBDA_LOG_STREAM_NAME": "", - "AWS_LAMBDA_RUNTIME_API": "127.0.0.1:9001", + "AWS_LAMBDA_RUNTIME_API": "169.254.100.1:9001", "AWS_REGION": "", "AWS_SECRET_ACCESS_KEY": "", "AWS_SESSION_TOKEN": "", "AWS_XRAY_CONTEXT_MISSING": "LOG_ERROR", - "AWS_XRAY_DAEMON_ADDRESS": "169.254.79.129:2000", + "AWS_XRAY_DAEMON_ADDRESS": "169.254.100.1:2000", "GEM_HOME": "/var/runtime", "GEM_PATH": "/var/task/vendor/bundle/ruby/3.2.0:/opt/ruby/gems/3.2.0:/var/runtime:/var/runtime/ruby/3.2.0", "LAMBDA_RUNTIME_DIR": "/var/runtime", @@ -701,11 +701,11 @@ "LD_LIBRARY_PATH": "/var/lang/lib:/var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib:/opt/lib", "PATH": "/var/lang/bin:/var/lang/bin:/usr/local/bin:/usr/bin/:/bin:/opt/bin", "PWD": "/var/task", - "RUBYLIB": "/var/task:/var/runtime/lib:/opt/ruby/lib", + "RUBYLIB": "/var/runtime/gems/aws_lambda_ric-3.0.0/lib:/var/task:/var/runtime/lib:/opt/ruby/lib", "SHLVL": "0", "TEST_KEY": "TEST_VAL", "TZ": ":UTC", - "_AWS_XRAY_DAEMON_ADDRESS": "169.254.79.129", + "_AWS_XRAY_DAEMON_ADDRESS": "169.254.100.1", "_AWS_XRAY_DAEMON_PORT": "2000", "_HANDLER": "function.handler", "_X_AMZN_TRACE_ID": "" @@ -733,12 +733,12 @@ "AWS_LAMBDA_INITIALIZATION_TYPE": "on-demand", "AWS_LAMBDA_LOG_GROUP_NAME": "/aws/lambda/", "AWS_LAMBDA_LOG_STREAM_NAME": "", - "AWS_LAMBDA_RUNTIME_API": "127.0.0.1:9001", + "AWS_LAMBDA_RUNTIME_API": "169.254.100.1:9001", "AWS_REGION": "", "AWS_SECRET_ACCESS_KEY": "", "AWS_SESSION_TOKEN": "", "AWS_XRAY_CONTEXT_MISSING": "LOG_ERROR", - "AWS_XRAY_DAEMON_ADDRESS": "169.254.79.129:2000", + "AWS_XRAY_DAEMON_ADDRESS": "169.254.100.1:2000", "GEM_HOME": "/var/runtime", "GEM_PATH": "/var/task/vendor/bundle/ruby/3.2.0:/opt/ruby/gems/3.2.0:/var/runtime:/var/runtime/ruby/3.2.0", "LAMBDA_RUNTIME_DIR": "/var/runtime", @@ -747,11 +747,11 @@ "LD_LIBRARY_PATH": "/var/lang/lib:/var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib:/opt/lib", "PATH": "/var/lang/bin:/var/lang/bin:/usr/local/bin:/usr/bin/:/bin:/opt/bin", "PWD": "/var/task", - "RUBYLIB": "/var/task:/var/runtime/lib:/opt/ruby/lib", + "RUBYLIB": "/var/runtime/gems/aws_lambda_ric-3.0.0/lib:/var/task:/var/runtime/lib:/opt/ruby/lib", "SHLVL": "0", "TEST_KEY": "TEST_VAL", "TZ": ":UTC", - "_AWS_XRAY_DAEMON_ADDRESS": "169.254.79.129", + "_AWS_XRAY_DAEMON_ADDRESS": "169.254.100.1", "_AWS_XRAY_DAEMON_PORT": "2000", "_HANDLER": "function.handler", "_X_AMZN_TRACE_ID": "" @@ -761,7 +761,7 @@ } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[python3.11]": { - "recorded-date": "31-03-2025, 12:17:51", + "recorded-date": "17-06-2025, 09:51:17", "recorded-content": { "create_function_result": { "Architectures": [ @@ -832,12 +832,12 @@ "AWS_LAMBDA_INITIALIZATION_TYPE": "on-demand", "AWS_LAMBDA_LOG_GROUP_NAME": "/aws/lambda/", "AWS_LAMBDA_LOG_STREAM_NAME": "", - "AWS_LAMBDA_RUNTIME_API": "127.0.0.1:9001", + "AWS_LAMBDA_RUNTIME_API": "169.254.100.1:9001", "AWS_REGION": "", "AWS_SECRET_ACCESS_KEY": "", "AWS_SESSION_TOKEN": "", "AWS_XRAY_CONTEXT_MISSING": "LOG_ERROR", - "AWS_XRAY_DAEMON_ADDRESS": "169.254.79.129:2000", + "AWS_XRAY_DAEMON_ADDRESS": "169.254.100.1:2000", "LAMBDA_RUNTIME_DIR": "/var/runtime", "LAMBDA_TASK_ROOT": "/var/task", "LANG": "en_US.UTF-8", @@ -848,7 +848,7 @@ "SHLVL": "0", "TEST_KEY": "TEST_VAL", "TZ": ":UTC", - "_AWS_XRAY_DAEMON_ADDRESS": "169.254.79.129", + "_AWS_XRAY_DAEMON_ADDRESS": "169.254.100.1", "_AWS_XRAY_DAEMON_PORT": "2000", "_HANDLER": "handler.handler", "_X_AMZN_TRACE_ID": "" @@ -876,12 +876,12 @@ "AWS_LAMBDA_INITIALIZATION_TYPE": "on-demand", "AWS_LAMBDA_LOG_GROUP_NAME": "/aws/lambda/", "AWS_LAMBDA_LOG_STREAM_NAME": "", - "AWS_LAMBDA_RUNTIME_API": "127.0.0.1:9001", + "AWS_LAMBDA_RUNTIME_API": "169.254.100.1:9001", "AWS_REGION": "", "AWS_SECRET_ACCESS_KEY": "", "AWS_SESSION_TOKEN": "", "AWS_XRAY_CONTEXT_MISSING": "LOG_ERROR", - "AWS_XRAY_DAEMON_ADDRESS": "169.254.79.129:2000", + "AWS_XRAY_DAEMON_ADDRESS": "169.254.100.1:2000", "LAMBDA_RUNTIME_DIR": "/var/runtime", "LAMBDA_TASK_ROOT": "/var/task", "LANG": "en_US.UTF-8", @@ -892,7 +892,7 @@ "SHLVL": "0", "TEST_KEY": "TEST_VAL", "TZ": ":UTC", - "_AWS_XRAY_DAEMON_ADDRESS": "169.254.79.129", + "_AWS_XRAY_DAEMON_ADDRESS": "169.254.100.1", "_AWS_XRAY_DAEMON_PORT": "2000", "_HANDLER": "handler.handler", "_X_AMZN_TRACE_ID": "" @@ -902,7 +902,7 @@ } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[java17]": { - "recorded-date": "31-03-2025, 12:18:08", + "recorded-date": "17-06-2025, 09:51:36", "recorded-content": { "create_function_result": { "Architectures": [ @@ -1037,7 +1037,7 @@ } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[nodejs18.x]": { - "recorded-date": "31-03-2025, 12:17:39", + "recorded-date": "17-06-2025, 09:51:05", "recorded-content": { "create_function_result": { "Architectures": [ @@ -1107,12 +1107,12 @@ "AWS_LAMBDA_INITIALIZATION_TYPE": "on-demand", "AWS_LAMBDA_LOG_GROUP_NAME": "/aws/lambda/", "AWS_LAMBDA_LOG_STREAM_NAME": "", - "AWS_LAMBDA_RUNTIME_API": "127.0.0.1:9001", + "AWS_LAMBDA_RUNTIME_API": "169.254.100.1:9001", "AWS_REGION": "", "AWS_SECRET_ACCESS_KEY": "", "AWS_SESSION_TOKEN": "", "AWS_XRAY_CONTEXT_MISSING": "LOG_ERROR", - "AWS_XRAY_DAEMON_ADDRESS": "169.254.79.129:2000", + "AWS_XRAY_DAEMON_ADDRESS": "169.254.100.1:2000", "LAMBDA_RUNTIME_DIR": "/var/runtime", "LAMBDA_TASK_ROOT": "/var/task", "LANG": "en_US.UTF-8", @@ -1124,7 +1124,7 @@ "SHLVL": "0", "TEST_KEY": "TEST_VAL", "TZ": ":UTC", - "_AWS_XRAY_DAEMON_ADDRESS": "169.254.79.129", + "_AWS_XRAY_DAEMON_ADDRESS": "169.254.100.1", "_AWS_XRAY_DAEMON_PORT": "2000", "_HANDLER": "index.handler", "_X_AMZN_TRACE_ID": "" @@ -1151,12 +1151,12 @@ "AWS_LAMBDA_INITIALIZATION_TYPE": "on-demand", "AWS_LAMBDA_LOG_GROUP_NAME": "/aws/lambda/", "AWS_LAMBDA_LOG_STREAM_NAME": "", - "AWS_LAMBDA_RUNTIME_API": "127.0.0.1:9001", + "AWS_LAMBDA_RUNTIME_API": "169.254.100.1:9001", "AWS_REGION": "", "AWS_SECRET_ACCESS_KEY": "", "AWS_SESSION_TOKEN": "", "AWS_XRAY_CONTEXT_MISSING": "LOG_ERROR", - "AWS_XRAY_DAEMON_ADDRESS": "169.254.79.129:2000", + "AWS_XRAY_DAEMON_ADDRESS": "169.254.100.1:2000", "LAMBDA_RUNTIME_DIR": "/var/runtime", "LAMBDA_TASK_ROOT": "/var/task", "LANG": "en_US.UTF-8", @@ -1168,7 +1168,7 @@ "SHLVL": "0", "TEST_KEY": "TEST_VAL", "TZ": ":UTC", - "_AWS_XRAY_DAEMON_ADDRESS": "169.254.79.129", + "_AWS_XRAY_DAEMON_ADDRESS": "169.254.100.1", "_AWS_XRAY_DAEMON_PORT": "2000", "_HANDLER": "index.handler", "_X_AMZN_TRACE_ID": "" @@ -1178,7 +1178,7 @@ } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[java21]": { - "recorded-date": "31-03-2025, 12:18:04", + "recorded-date": "17-06-2025, 09:51:33", "recorded-content": { "create_function_result": { "Architectures": [ @@ -1313,7 +1313,7 @@ } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[provided.al2023]": { - "recorded-date": "31-03-2025, 12:21:36", + "recorded-date": "17-06-2025, 09:52:07", "recorded-content": { "create_function_result": { "Architectures": [ @@ -1446,7 +1446,7 @@ } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[python3.9]": { - "recorded-date": "31-03-2025, 12:17:57", + "recorded-date": "17-06-2025, 09:51:23", "recorded-content": { "create_function_result": { "Architectures": [ @@ -1517,12 +1517,12 @@ "AWS_LAMBDA_INITIALIZATION_TYPE": "on-demand", "AWS_LAMBDA_LOG_GROUP_NAME": "/aws/lambda/", "AWS_LAMBDA_LOG_STREAM_NAME": "", - "AWS_LAMBDA_RUNTIME_API": "127.0.0.1:9001", + "AWS_LAMBDA_RUNTIME_API": "169.254.100.1:9001", "AWS_REGION": "", "AWS_SECRET_ACCESS_KEY": "", "AWS_SESSION_TOKEN": "", "AWS_XRAY_CONTEXT_MISSING": "LOG_ERROR", - "AWS_XRAY_DAEMON_ADDRESS": "169.254.79.129:2000", + "AWS_XRAY_DAEMON_ADDRESS": "169.254.100.1:2000", "LAMBDA_RUNTIME_DIR": "/var/runtime", "LAMBDA_TASK_ROOT": "/var/task", "LANG": "en_US.UTF-8", @@ -1533,7 +1533,7 @@ "SHLVL": "0", "TEST_KEY": "TEST_VAL", "TZ": ":UTC", - "_AWS_XRAY_DAEMON_ADDRESS": "169.254.79.129", + "_AWS_XRAY_DAEMON_ADDRESS": "169.254.100.1", "_AWS_XRAY_DAEMON_PORT": "2000", "_HANDLER": "handler.handler", "_X_AMZN_TRACE_ID": "" @@ -1561,12 +1561,12 @@ "AWS_LAMBDA_INITIALIZATION_TYPE": "on-demand", "AWS_LAMBDA_LOG_GROUP_NAME": "/aws/lambda/", "AWS_LAMBDA_LOG_STREAM_NAME": "", - "AWS_LAMBDA_RUNTIME_API": "127.0.0.1:9001", + "AWS_LAMBDA_RUNTIME_API": "169.254.100.1:9001", "AWS_REGION": "", "AWS_SECRET_ACCESS_KEY": "", "AWS_SESSION_TOKEN": "", "AWS_XRAY_CONTEXT_MISSING": "LOG_ERROR", - "AWS_XRAY_DAEMON_ADDRESS": "169.254.79.129:2000", + "AWS_XRAY_DAEMON_ADDRESS": "169.254.100.1:2000", "LAMBDA_RUNTIME_DIR": "/var/runtime", "LAMBDA_TASK_ROOT": "/var/task", "LANG": "en_US.UTF-8", @@ -1577,7 +1577,7 @@ "SHLVL": "0", "TEST_KEY": "TEST_VAL", "TZ": ":UTC", - "_AWS_XRAY_DAEMON_ADDRESS": "169.254.79.129", + "_AWS_XRAY_DAEMON_ADDRESS": "169.254.100.1", "_AWS_XRAY_DAEMON_PORT": "2000", "_HANDLER": "handler.handler", "_X_AMZN_TRACE_ID": "" @@ -1587,7 +1587,7 @@ } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[python3.10]": { - "recorded-date": "31-03-2025, 12:17:54", + "recorded-date": "17-06-2025, 09:51:20", "recorded-content": { "create_function_result": { "Architectures": [ @@ -1658,12 +1658,12 @@ "AWS_LAMBDA_INITIALIZATION_TYPE": "on-demand", "AWS_LAMBDA_LOG_GROUP_NAME": "/aws/lambda/", "AWS_LAMBDA_LOG_STREAM_NAME": "", - "AWS_LAMBDA_RUNTIME_API": "127.0.0.1:9001", + "AWS_LAMBDA_RUNTIME_API": "169.254.100.1:9001", "AWS_REGION": "", "AWS_SECRET_ACCESS_KEY": "", "AWS_SESSION_TOKEN": "", "AWS_XRAY_CONTEXT_MISSING": "LOG_ERROR", - "AWS_XRAY_DAEMON_ADDRESS": "169.254.79.129:2000", + "AWS_XRAY_DAEMON_ADDRESS": "169.254.100.1:2000", "LAMBDA_RUNTIME_DIR": "/var/runtime", "LAMBDA_TASK_ROOT": "/var/task", "LANG": "en_US.UTF-8", @@ -1674,7 +1674,7 @@ "SHLVL": "0", "TEST_KEY": "TEST_VAL", "TZ": ":UTC", - "_AWS_XRAY_DAEMON_ADDRESS": "169.254.79.129", + "_AWS_XRAY_DAEMON_ADDRESS": "169.254.100.1", "_AWS_XRAY_DAEMON_PORT": "2000", "_HANDLER": "handler.handler", "_X_AMZN_TRACE_ID": "" @@ -1702,12 +1702,12 @@ "AWS_LAMBDA_INITIALIZATION_TYPE": "on-demand", "AWS_LAMBDA_LOG_GROUP_NAME": "/aws/lambda/", "AWS_LAMBDA_LOG_STREAM_NAME": "", - "AWS_LAMBDA_RUNTIME_API": "127.0.0.1:9001", + "AWS_LAMBDA_RUNTIME_API": "169.254.100.1:9001", "AWS_REGION": "", "AWS_SECRET_ACCESS_KEY": "", "AWS_SESSION_TOKEN": "", "AWS_XRAY_CONTEXT_MISSING": "LOG_ERROR", - "AWS_XRAY_DAEMON_ADDRESS": "169.254.79.129:2000", + "AWS_XRAY_DAEMON_ADDRESS": "169.254.100.1:2000", "LAMBDA_RUNTIME_DIR": "/var/runtime", "LAMBDA_TASK_ROOT": "/var/task", "LANG": "en_US.UTF-8", @@ -1718,7 +1718,7 @@ "SHLVL": "0", "TEST_KEY": "TEST_VAL", "TZ": ":UTC", - "_AWS_XRAY_DAEMON_ADDRESS": "169.254.79.129", + "_AWS_XRAY_DAEMON_ADDRESS": "169.254.100.1", "_AWS_XRAY_DAEMON_PORT": "2000", "_HANDLER": "handler.handler", "_X_AMZN_TRACE_ID": "" @@ -1728,7 +1728,7 @@ } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[python3.12]": { - "recorded-date": "31-03-2025, 12:17:48", + "recorded-date": "17-06-2025, 09:51:14", "recorded-content": { "create_function_result": { "Architectures": [ @@ -1871,7 +1871,7 @@ } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[nodejs20.x]": { - "recorded-date": "31-03-2025, 12:17:36", + "recorded-date": "17-06-2025, 09:51:01", "recorded-content": { "create_function_result": { "Architectures": [ @@ -2010,7 +2010,7 @@ } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[dotnet6]": { - "recorded-date": "31-03-2025, 12:18:32", + "recorded-date": "17-06-2025, 09:51:57", "recorded-content": { "create_function_result": { "Architectures": [ @@ -2155,7 +2155,7 @@ } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[nodejs16.x]": { - "recorded-date": "31-03-2025, 12:17:42", + "recorded-date": "17-06-2025, 09:51:08", "recorded-content": { "create_function_result": { "Architectures": [ @@ -4072,7 +4072,7 @@ "recorded-content": {} }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[dotnet8]": { - "recorded-date": "31-03-2025, 12:18:36", + "recorded-date": "17-06-2025, 09:52:01", "recorded-content": { "create_function_result": { "Architectures": [ @@ -4362,7 +4362,7 @@ "recorded-content": {} }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[ruby3.3]": { - "recorded-date": "31-03-2025, 12:18:22", + "recorded-date": "17-06-2025, 09:51:50", "recorded-content": { "create_function_result": { "Architectures": [ @@ -4630,7 +4630,7 @@ "recorded-content": {} }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[python3.13]": { - "recorded-date": "31-03-2025, 12:17:45", + "recorded-date": "17-06-2025, 09:51:11", "recorded-content": { "create_function_result": { "Architectures": [ @@ -4897,7 +4897,7 @@ "recorded-content": {} }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[nodejs22.x]": { - "recorded-date": "31-03-2025, 12:17:33", + "recorded-date": "17-06-2025, 09:50:58", "recorded-content": { "create_function_result": { "Architectures": [ @@ -5159,7 +5159,7 @@ "recorded-content": {} }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[ruby3.4]": { - "recorded-date": "31-03-2025, 12:18:27", + "recorded-date": "17-06-2025, 09:51:54", "recorded-content": { "create_function_result": { "Architectures": [ diff --git a/tests/aws/services/lambda_/test_lambda_common.validation.json b/tests/aws/services/lambda_/test_lambda_common.validation.json index 9ea9db3a25ba3..f17afd9193b9c 100644 --- a/tests/aws/services/lambda_/test_lambda_common.validation.json +++ b/tests/aws/services/lambda_/test_lambda_common.validation.json @@ -120,67 +120,193 @@ "last_validated_date": "2025-03-31T12:16:24+00:00" }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[dotnet6]": { - "last_validated_date": "2025-03-31T12:18:32+00:00" + "last_validated_date": "2025-06-17T09:54:42+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 2.97, + "teardown": 0.37, + "total": 3.34 + } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[dotnet8]": { - "last_validated_date": "2025-03-31T12:18:35+00:00" + "last_validated_date": "2025-06-17T09:54:45+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 3.14, + "teardown": 0.35, + "total": 3.49 + } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[java11]": { - "last_validated_date": "2025-03-31T12:18:11+00:00" + "last_validated_date": "2025-06-17T09:54:24+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 3.48, + "teardown": 0.38, + "total": 3.86 + } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[java17]": { - "last_validated_date": "2025-03-31T12:18:07+00:00" + "last_validated_date": "2025-06-17T09:54:20+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 3.21, + "teardown": 0.4, + "total": 3.61 + } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[java21]": { - "last_validated_date": "2025-03-31T12:18:04+00:00" + "last_validated_date": "2025-06-17T09:54:17+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 3.45, + "teardown": 0.36, + "total": 3.81 + } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[java8.al2]": { - "last_validated_date": "2025-03-31T12:18:15+00:00" + "last_validated_date": "2025-06-17T09:54:28+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 3.87, + "teardown": 0.37, + "total": 4.24 + } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[nodejs16.x]": { - "last_validated_date": "2025-03-31T12:17:42+00:00" + "last_validated_date": "2025-06-17T09:53:53+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 2.92, + "teardown": 0.34, + "total": 3.26 + } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[nodejs18.x]": { - "last_validated_date": "2025-03-31T12:17:39+00:00" + "last_validated_date": "2025-06-17T09:53:50+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 2.9, + "teardown": 0.34, + "total": 3.24 + } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[nodejs20.x]": { - "last_validated_date": "2025-03-31T12:17:36+00:00" + "last_validated_date": "2025-06-17T09:53:47+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 2.91, + "teardown": 0.37, + "total": 3.28 + } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[nodejs22.x]": { - "last_validated_date": "2025-03-31T12:17:33+00:00" + "last_validated_date": "2025-06-17T09:53:44+00:00", + "durations_in_seconds": { + "setup": 11.98, + "call": 3.16, + "teardown": 0.35, + "total": 15.49 + } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[provided.al2023]": { - "last_validated_date": "2025-03-31T12:21:35+00:00" + "last_validated_date": "2025-06-17T09:54:51+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 5.57, + "teardown": 0.4, + "total": 5.97 + } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[provided.al2]": { - "last_validated_date": "2025-03-31T12:21:46+00:00" + "last_validated_date": "2025-06-17T09:54:58+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 5.13, + "teardown": 1.61, + "total": 6.74 + } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[python3.10]": { - "last_validated_date": "2025-03-31T12:17:54+00:00" + "last_validated_date": "2025-06-17T09:54:06+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 2.9, + "teardown": 0.35, + "total": 3.25 + } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[python3.11]": { - "last_validated_date": "2025-03-31T12:17:51+00:00" + "last_validated_date": "2025-06-17T09:54:03+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 2.67, + "teardown": 0.42, + "total": 3.09 + } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[python3.12]": { - "last_validated_date": "2025-03-31T12:17:48+00:00" + "last_validated_date": "2025-06-17T09:54:00+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 2.83, + "teardown": 0.38, + "total": 3.21 + } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[python3.13]": { - "last_validated_date": "2025-03-31T12:17:45+00:00" + "last_validated_date": "2025-06-17T09:53:57+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 2.83, + "teardown": 0.35, + "total": 3.18 + } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[python3.8]": { - "last_validated_date": "2025-03-31T12:18:00+00:00" + "last_validated_date": "2025-06-17T09:54:13+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 2.97, + "teardown": 0.34, + "total": 3.31 + } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[python3.9]": { - "last_validated_date": "2025-03-31T12:17:56+00:00" + "last_validated_date": "2025-06-17T09:54:09+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 2.82, + "teardown": 0.36, + "total": 3.18 + } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[ruby3.2]": { - "last_validated_date": "2025-03-31T12:18:18+00:00" + "last_validated_date": "2025-06-17T09:54:31+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 2.85, + "teardown": 0.36, + "total": 3.21 + } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[ruby3.3]": { - "last_validated_date": "2025-03-31T12:18:21+00:00" + "last_validated_date": "2025-06-17T09:54:35+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 3.02, + "teardown": 0.36, + "total": 3.38 + } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[ruby3.4]": { - "last_validated_date": "2025-03-31T12:18:26+00:00" + "last_validated_date": "2025-06-17T09:54:38+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 2.97, + "teardown": 0.35, + "total": 3.32 + } }, "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[dotnet6]": { "last_validated_date": "2025-03-31T12:26:32+00:00" From ea6c7a2a7e4913850151873dd9bc7f111028b66a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristopher=20Pinz=C3=B3n?= <18080804+pinzon@users.noreply.github.com> Date: Tue, 17 Jun 2025 09:09:08 -0500 Subject: [PATCH 38/74] fix issue with CloudWatch after state reset (#12755) --- localstack-core/localstack/services/cloudwatch/provider_v2.py | 1 + 1 file changed, 1 insertion(+) diff --git a/localstack-core/localstack/services/cloudwatch/provider_v2.py b/localstack-core/localstack/services/cloudwatch/provider_v2.py index 88b700e8d562f..31f737fec9e23 100644 --- a/localstack-core/localstack/services/cloudwatch/provider_v2.py +++ b/localstack-core/localstack/services/cloudwatch/provider_v2.py @@ -175,6 +175,7 @@ def on_before_state_reset(self): self.cloudwatch_database.clear_tables() def on_after_state_reset(self): + self.cloudwatch_database = CloudwatchDatabase() self.start_alarm_scheduler() def on_before_state_load(self): From ea0a194102807b59c44e74dc355ef1dd07981ed8 Mon Sep 17 00:00:00 2001 From: LocalStack Bot <88328844+localstack-bot@users.noreply.github.com> Date: Tue, 17 Jun 2025 17:17:49 +0200 Subject: [PATCH 39/74] Upgrade pinned Python dependencies (#12766) Co-authored-by: LocalStack Bot --- requirements-base-runtime.txt | 4 ++-- requirements-basic.txt | 4 ++-- requirements-dev.txt | 20 ++++++++--------- requirements-runtime.txt | 12 +++++----- requirements-test.txt | 18 +++++++-------- requirements-typehint.txt | 42 +++++++++++++++++------------------ 6 files changed, 50 insertions(+), 50 deletions(-) diff --git a/requirements-base-runtime.txt b/requirements-base-runtime.txt index e2c0b40f48b4d..385d78ed99a03 100644 --- a/requirements-base-runtime.txt +++ b/requirements-base-runtime.txt @@ -20,11 +20,11 @@ botocore==1.38.36 # s3transfer build==1.2.2.post1 # via localstack-core (pyproject.toml) -cachetools==6.0.0 +cachetools==6.1.0 # via localstack-core (pyproject.toml) cbor2==5.6.5 # via localstack-core (pyproject.toml) -certifi==2025.4.26 +certifi==2025.6.15 # via requests cffi==1.17.1 # via cryptography diff --git a/requirements-basic.txt b/requirements-basic.txt index 0a080017af899..f086ba98a6999 100644 --- a/requirements-basic.txt +++ b/requirements-basic.txt @@ -6,9 +6,9 @@ # build==1.2.2.post1 # via localstack-core (pyproject.toml) -cachetools==6.0.0 +cachetools==6.1.0 # via localstack-core (pyproject.toml) -certifi==2025.4.26 +certifi==2025.6.15 # via requests cffi==1.17.1 # via cryptography diff --git a/requirements-dev.txt b/requirements-dev.txt index bdf749572c41a..3b9cc3c1a0034 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -29,9 +29,9 @@ aws-cdk-asset-awscli-v1==2.2.237 # via aws-cdk-lib aws-cdk-asset-node-proxy-agent-v6==2.1.0 # via aws-cdk-lib -aws-cdk-cloud-assembly-schema==44.2.0 +aws-cdk-cloud-assembly-schema==44.5.0 # via aws-cdk-lib -aws-cdk-lib==2.200.1 +aws-cdk-lib==2.201.0 # via localstack-core aws-sam-translator==1.98.0 # via @@ -61,7 +61,7 @@ build==1.2.2.post1 # via # localstack-core # localstack-core (pyproject.toml) -cachetools==6.0.0 +cachetools==6.1.0 # via # airspeed-ext # localstack-core @@ -70,7 +70,7 @@ cattrs==24.1.3 # via jsii cbor2==5.6.5 # via localstack-core -certifi==2025.4.26 +certifi==2025.6.15 # via # httpcore # httpx @@ -80,7 +80,7 @@ cffi==1.17.1 # via cryptography cfgv==3.4.0 # via pre-commit -cfn-lint==1.35.4 +cfn-lint==1.36.0 # via moto-ext charset-normalizer==3.4.2 # via requests @@ -94,7 +94,7 @@ constantly==23.10.4 # via localstack-twisted constructs==10.4.2 # via aws-cdk-lib -coverage==7.8.2 +coverage==7.9.1 # via # coveralls # localstack-core @@ -232,7 +232,7 @@ jsonschema-specifications==2025.4.1 # via # jsonschema # openapi-schema-validator -kclpy-ext==3.0.3 +kclpy-ext==3.0.5 # via localstack-core lazy-object-proxy==1.11.0 # via openapi-spec-validator @@ -256,7 +256,7 @@ mpmath==1.3.0 # via sympy multipart==1.2.1 # via moto-ext -mypy==1.16.0 +mypy==1.16.1 # via localstack-core (pyproject.toml) mypy-extensions==1.1.0 # via mypy @@ -337,7 +337,7 @@ pyasn1==0.6.1 # via rsa pycparser==2.22 # via cffi -pydantic==2.11.5 +pydantic==2.11.7 # via aws-sam-translator pydantic-core==2.33.2 # via pydantic @@ -345,7 +345,7 @@ pygments==2.19.1 # via # pytest # rich -pymongo==4.13.0 +pymongo==4.13.2 # via localstack-core pyopenssl==25.1.0 # via diff --git a/requirements-runtime.txt b/requirements-runtime.txt index 6120934b9e685..52934e5c2933c 100644 --- a/requirements-runtime.txt +++ b/requirements-runtime.txt @@ -49,20 +49,20 @@ build==1.2.2.post1 # via # localstack-core # localstack-core (pyproject.toml) -cachetools==6.0.0 +cachetools==6.1.0 # via # airspeed-ext # localstack-core # localstack-core (pyproject.toml) cbor2==5.6.5 # via localstack-core -certifi==2025.4.26 +certifi==2025.6.15 # via # opensearch-py # requests cffi==1.17.1 # via cryptography -cfn-lint==1.35.4 +cfn-lint==1.36.0 # via moto-ext charset-normalizer==3.4.2 # via requests @@ -172,7 +172,7 @@ jsonschema-specifications==2025.4.1 # via # jsonschema # openapi-schema-validator -kclpy-ext==3.0.3 +kclpy-ext==3.0.5 # via localstack-core (pyproject.toml) lazy-object-proxy==1.11.0 # via openapi-spec-validator @@ -239,13 +239,13 @@ pyasn1==0.6.1 # via rsa pycparser==2.22 # via cffi -pydantic==2.11.5 +pydantic==2.11.7 # via aws-sam-translator pydantic-core==2.33.2 # via pydantic pygments==2.19.1 # via rich -pymongo==4.13.0 +pymongo==4.13.2 # via localstack-core (pyproject.toml) pyopenssl==25.1.0 # via diff --git a/requirements-test.txt b/requirements-test.txt index 792d549f302ba..8d938fc6d63a6 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -29,9 +29,9 @@ aws-cdk-asset-awscli-v1==2.2.237 # via aws-cdk-lib aws-cdk-asset-node-proxy-agent-v6==2.1.0 # via aws-cdk-lib -aws-cdk-cloud-assembly-schema==44.2.0 +aws-cdk-cloud-assembly-schema==44.5.0 # via aws-cdk-lib -aws-cdk-lib==2.200.1 +aws-cdk-lib==2.201.0 # via localstack-core (pyproject.toml) aws-sam-translator==1.98.0 # via @@ -61,7 +61,7 @@ build==1.2.2.post1 # via # localstack-core # localstack-core (pyproject.toml) -cachetools==6.0.0 +cachetools==6.1.0 # via # airspeed-ext # localstack-core @@ -70,7 +70,7 @@ cattrs==24.1.3 # via jsii cbor2==5.6.5 # via localstack-core -certifi==2025.4.26 +certifi==2025.6.15 # via # httpcore # httpx @@ -78,7 +78,7 @@ certifi==2025.4.26 # requests cffi==1.17.1 # via cryptography -cfn-lint==1.35.4 +cfn-lint==1.36.0 # via moto-ext charset-normalizer==3.4.2 # via requests @@ -92,7 +92,7 @@ constantly==23.10.4 # via localstack-twisted constructs==10.4.2 # via aws-cdk-lib -coverage==7.8.2 +coverage==7.9.1 # via localstack-core (pyproject.toml) crontab==1.0.4 # via localstack-core @@ -216,7 +216,7 @@ jsonschema-specifications==2025.4.1 # via # jsonschema # openapi-schema-validator -kclpy-ext==3.0.3 +kclpy-ext==3.0.5 # via localstack-core lazy-object-proxy==1.11.0 # via openapi-spec-validator @@ -301,7 +301,7 @@ pyasn1==0.6.1 # via rsa pycparser==2.22 # via cffi -pydantic==2.11.5 +pydantic==2.11.7 # via aws-sam-translator pydantic-core==2.33.2 # via pydantic @@ -309,7 +309,7 @@ pygments==2.19.1 # via # pytest # rich -pymongo==4.13.0 +pymongo==4.13.2 # via localstack-core pyopenssl==25.1.0 # via diff --git a/requirements-typehint.txt b/requirements-typehint.txt index ab97dbdfa7de0..d2248fecdd13d 100644 --- a/requirements-typehint.txt +++ b/requirements-typehint.txt @@ -29,9 +29,9 @@ aws-cdk-asset-awscli-v1==2.2.237 # via aws-cdk-lib aws-cdk-asset-node-proxy-agent-v6==2.1.0 # via aws-cdk-lib -aws-cdk-cloud-assembly-schema==44.2.0 +aws-cdk-cloud-assembly-schema==44.5.0 # via aws-cdk-lib -aws-cdk-lib==2.200.1 +aws-cdk-lib==2.201.0 # via localstack-core aws-sam-translator==1.98.0 # via @@ -49,7 +49,7 @@ boto3==1.38.36 # kclpy-ext # localstack-core # moto-ext -boto3-stubs==1.38.33 +boto3-stubs==1.38.37 # via localstack-core (pyproject.toml) botocore==1.38.36 # via @@ -65,7 +65,7 @@ build==1.2.2.post1 # via # localstack-core # localstack-core (pyproject.toml) -cachetools==6.0.0 +cachetools==6.1.0 # via # airspeed-ext # localstack-core @@ -74,7 +74,7 @@ cattrs==24.1.3 # via jsii cbor2==5.6.5 # via localstack-core -certifi==2025.4.26 +certifi==2025.6.15 # via # httpcore # httpx @@ -84,7 +84,7 @@ cffi==1.17.1 # via cryptography cfgv==3.4.0 # via pre-commit -cfn-lint==1.35.4 +cfn-lint==1.36.0 # via moto-ext charset-normalizer==3.4.2 # via requests @@ -98,7 +98,7 @@ constantly==23.10.4 # via localstack-twisted constructs==10.4.2 # via aws-cdk-lib -coverage==7.8.2 +coverage==7.9.1 # via # coveralls # localstack-core @@ -236,7 +236,7 @@ jsonschema-specifications==2025.4.1 # via # jsonschema # openapi-schema-validator -kclpy-ext==3.0.3 +kclpy-ext==3.0.5 # via localstack-core lazy-object-proxy==1.11.0 # via openapi-spec-validator @@ -260,7 +260,7 @@ mpmath==1.3.0 # via sympy multipart==1.2.1 # via moto-ext -mypy==1.16.0 +mypy==1.16.1 # via localstack-core mypy-boto3-acm==1.38.4 # via boto3-stubs @@ -268,9 +268,9 @@ mypy-boto3-acm-pca==1.38.0 # via boto3-stubs mypy-boto3-amplify==1.38.30 # via boto3-stubs -mypy-boto3-apigateway==1.38.29 +mypy-boto3-apigateway==1.38.36 # via boto3-stubs -mypy-boto3-apigatewayv2==1.38.29 +mypy-boto3-apigatewayv2==1.38.36 # via boto3-stubs mypy-boto3-appconfig==1.38.7 # via boto3-stubs @@ -326,13 +326,13 @@ mypy-boto3-dynamodbstreams==1.38.0 # via boto3-stubs mypy-boto3-ec2==1.38.33 # via boto3-stubs -mypy-boto3-ecr==1.38.6 +mypy-boto3-ecr==1.38.37 # via boto3-stubs -mypy-boto3-ecs==1.38.28 +mypy-boto3-ecs==1.38.36 # via boto3-stubs mypy-boto3-efs==1.38.33 # via boto3-stubs -mypy-boto3-eks==1.38.28 +mypy-boto3-eks==1.38.35 # via boto3-stubs mypy-boto3-elasticache==1.38.0 # via boto3-stubs @@ -342,7 +342,7 @@ mypy-boto3-elbv2==1.38.0 # via boto3-stubs mypy-boto3-emr==1.38.18 # via boto3-stubs -mypy-boto3-emr-serverless==1.38.29 +mypy-boto3-emr-serverless==1.38.36 # via boto3-stubs mypy-boto3-es==1.38.0 # via boto3-stubs @@ -376,7 +376,7 @@ mypy-boto3-kinesisanalytics==1.38.0 # via boto3-stubs mypy-boto3-kinesisanalyticsv2==1.38.0 # via boto3-stubs -mypy-boto3-kms==1.38.32 +mypy-boto3-kms==1.38.36 # via boto3-stubs mypy-boto3-lakeformation==1.38.0 # via boto3-stubs @@ -410,7 +410,7 @@ mypy-boto3-qldb==1.38.0 # via boto3-stubs mypy-boto3-qldb-session==1.38.0 # via boto3-stubs -mypy-boto3-rds==1.38.32 +mypy-boto3-rds==1.38.35 # via boto3-stubs mypy-boto3-rds-data==1.38.0 # via boto3-stubs @@ -430,7 +430,7 @@ mypy-boto3-s3==1.38.26 # via boto3-stubs mypy-boto3-s3control==1.38.14 # via boto3-stubs -mypy-boto3-sagemaker==1.38.30 +mypy-boto3-sagemaker==1.38.37 # via boto3-stubs mypy-boto3-sagemaker-runtime==1.38.0 # via boto3-stubs @@ -464,7 +464,7 @@ mypy-boto3-transcribe==1.38.30 # via boto3-stubs mypy-boto3-verifiedpermissions==1.38.7 # via boto3-stubs -mypy-boto3-wafv2==1.38.31 +mypy-boto3-wafv2==1.38.35 # via boto3-stubs mypy-boto3-xray==1.38.0 # via boto3-stubs @@ -547,7 +547,7 @@ pyasn1==0.6.1 # via rsa pycparser==2.22 # via cffi -pydantic==2.11.5 +pydantic==2.11.7 # via aws-sam-translator pydantic-core==2.33.2 # via pydantic @@ -555,7 +555,7 @@ pygments==2.19.1 # via # pytest # rich -pymongo==4.13.0 +pymongo==4.13.2 # via localstack-core pyopenssl==25.1.0 # via From 99cd6daac4eaa7cc8643204bcbae4a31ff7e0496 Mon Sep 17 00:00:00 2001 From: Ben Simon Hartung <42031100+bentsku@users.noreply.github.com> Date: Wed, 18 Jun 2025 15:02:07 +0200 Subject: [PATCH 40/74] S3: implement ObjectParts in GetObjectAttributes (#12764) --- .../localstack/services/s3/models.py | 23 +- .../localstack/services/s3/provider.py | 75 +++- tests/aws/services/s3/test_s3.py | 25 +- tests/aws/services/s3/test_s3.snapshot.json | 346 +++++++++++++++--- tests/aws/services/s3/test_s3.validation.json | 277 ++++++++++++-- .../services/s3/test_s3_list_operations.py | 80 ++++ .../s3/test_s3_list_operations.snapshot.json | 145 ++++++++ .../test_s3_list_operations.validation.json | 9 + 8 files changed, 871 insertions(+), 109 deletions(-) diff --git a/localstack-core/localstack/services/s3/models.py b/localstack-core/localstack/services/s3/models.py index 2a036076e5f99..6246d394dad33 100644 --- a/localstack-core/localstack/services/s3/models.py +++ b/localstack-core/localstack/services/s3/models.py @@ -52,6 +52,7 @@ ObjectStorageClass, ObjectVersionId, Owner, + Part, PartNumber, Payer, Policy, @@ -91,6 +92,10 @@ _gmt_zone_info = ZoneInfo("GMT") +class InternalObjectPart(Part): + _position: int + + # note: not really a need to use a dataclass here, as it has a lot of fields, but only a few are set at creation class S3Bucket: name: BucketName @@ -275,7 +280,7 @@ class S3Object: website_redirect_location: Optional[WebsiteRedirectLocation] acl: Optional[AccessControlPolicy] is_current: bool - parts: Optional[dict[int, tuple[int, int]]] + parts: Optional[dict[int, InternalObjectPart]] restore: Optional[Restore] internal_last_modified: int @@ -498,14 +503,16 @@ def complete_multipart( object_etag = hashlib.md5(usedforsecurity=False) has_checksum = self.checksum_algorithm is not None checksum_hash = None + checksum_key = None if has_checksum: + checksum_key = f"Checksum{self.checksum_algorithm.upper()}" if self.checksum_type == ChecksumType.COMPOSITE: checksum_hash = get_s3_checksum(self.checksum_algorithm) else: checksum_hash = CombinedCrcHash(self.checksum_algorithm) pos = 0 - parts_map = {} + parts_map: dict[int, InternalObjectPart] = {} for index, part in enumerate(parts): part_number = part["PartNumber"] part_etag = part["ETag"].strip('"') @@ -526,7 +533,6 @@ def complete_multipart( ) if has_checksum: - checksum_key = f"Checksum{self.checksum_algorithm.upper()}" if not (part_checksum := part.get(checksum_key)): if self.checksum_type == ChecksumType.COMPOSITE: # weird case, they still try to validate a different checksum type than the multipart @@ -575,7 +581,16 @@ def complete_multipart( object_etag.update(bytes.fromhex(s3_part.etag)) # keep track of the parts size, as it can be queried afterward on the object as a Range - parts_map[part_number] = (pos, s3_part.size) + internal_part = InternalObjectPart( + _position=pos, + Size=s3_part.size, + ETag=s3_part.etag, + PartNumber=s3_part.part_number, + ) + if has_checksum and self.checksum_type == ChecksumType.COMPOSITE: + internal_part[checksum_key] = s3_part.checksum_value + + parts_map[part_number] = internal_part pos += s3_part.size if mpu_size and mpu_size != pos: diff --git a/localstack-core/localstack/services/s3/provider.py b/localstack-core/localstack/services/s3/provider.py index f5d16597c975f..bfd335ad7bf0e 100644 --- a/localstack-core/localstack/services/s3/provider.py +++ b/localstack-core/localstack/services/s3/provider.py @@ -167,6 +167,7 @@ ObjectLockRetention, ObjectLockToken, ObjectOwnership, + ObjectPart, ObjectVersion, ObjectVersionId, ObjectVersionStorageClass, @@ -317,6 +318,7 @@ from localstack.services.s3.website_hosting import register_website_hosting_routes from localstack.state import AssetDirectory, StateVisitor from localstack.utils.aws.arns import s3_bucket_name +from localstack.utils.collections import select_from_typed_dict from localstack.utils.strings import short_uid, to_bytes, to_str LOG = logging.getLogger(__name__) @@ -2032,6 +2034,7 @@ def get_object_attributes( object_attrs = request.get("ObjectAttributes", []) response = GetObjectAttributesOutput() + object_checksum_type = getattr(s3_object, "checksum_type", ChecksumType.FULL_OBJECT) if "ETag" in object_attrs: response["ETag"] = s3_object.etag if "StorageClass" in object_attrs: @@ -2045,7 +2048,7 @@ def get_object_attributes( checksum_value = s3_object.checksum_value response["Checksum"] = { f"Checksum{checksum_algorithm.upper()}": checksum_value, - "ChecksumType": getattr(s3_object, "checksum_type", ChecksumType.FULL_OBJECT), + "ChecksumType": object_checksum_type, } response["LastModified"] = s3_object.last_modified @@ -2054,9 +2057,55 @@ def get_object_attributes( response["VersionId"] = s3_object.version_id if "ObjectParts" in object_attrs and s3_object.parts: - # TODO: implements ObjectParts, this is basically a simplified `ListParts` call on the object, we might - # need to store more data about the Parts once we implement checksums for them - response["ObjectParts"] = GetObjectAttributesParts(TotalPartsCount=len(s3_object.parts)) + if object_checksum_type == ChecksumType.FULL_OBJECT: + response["ObjectParts"] = GetObjectAttributesParts( + TotalPartsCount=len(s3_object.parts) + ) + else: + # this is basically a simplified `ListParts` call on the object, only returned when the checksum type is + # COMPOSITE + count = 0 + is_truncated = False + part_number_marker = request.get("PartNumberMarker") or 0 + max_parts = request.get("MaxParts") or 1000 + + parts = [] + all_parts = sorted(s3_object.parts.items()) + last_part_number, last_part = all_parts[-1] + + # TODO: remove this backward compatibility hack needed for state created with <= 4.5 + # the parts would only be a tuple and would not store the proper state for 4.5 and earlier, so we need + # to return early + if isinstance(last_part, tuple): + response["ObjectParts"] = GetObjectAttributesParts( + TotalPartsCount=len(s3_object.parts) + ) + return response + + for part_number, part in all_parts: + if part_number <= part_number_marker: + continue + part_item = select_from_typed_dict(ObjectPart, part) + + parts.append(part_item) + count += 1 + + if count >= max_parts and part["PartNumber"] != last_part_number: + is_truncated = True + break + + object_parts = GetObjectAttributesParts( + TotalPartsCount=len(s3_object.parts), + IsTruncated=is_truncated, + MaxParts=max_parts, + PartNumberMarker=part_number_marker, + NextPartNumberMarker=0, + ) + if parts: + object_parts["Parts"] = parts + object_parts["NextPartNumberMarker"] = parts[-1]["PartNumber"] + + response["ObjectParts"] = object_parts return response @@ -2729,8 +2778,6 @@ def list_parts( sse_customer_key_md5: SSECustomerKeyMD5 = None, **kwargs, ) -> ListPartsOutput: - # TODO: implement MaxParts - # TODO: implements PartNumberMarker store, s3_bucket = self._get_cross_account_bucket(context, bucket) if ( @@ -2743,10 +2790,6 @@ def list_parts( UploadId=upload_id, ) - # AbortDate: Optional[AbortDate] TODO: lifecycle - # AbortRuleId: Optional[AbortRuleId] TODO: lifecycle - # RequestCharged: Optional[RequestCharged] - count = 0 is_truncated = False part_number_marker = part_number_marker or 0 @@ -2797,6 +2840,10 @@ def list_parts( response["ChecksumAlgorithm"] = s3_multipart.object.checksum_algorithm response["ChecksumType"] = getattr(s3_multipart, "checksum_type", None) + # AbortDate: Optional[AbortDate] TODO: lifecycle + # AbortRuleId: Optional[AbortRuleId] TODO: lifecycle + # RequestCharged: Optional[RequestCharged] + return response def list_multipart_uploads( @@ -4680,7 +4727,13 @@ def get_part_range(s3_object: S3Object, part_number: PartNumber) -> ObjectRange: ActualPartCount=len(s3_object.parts), ) - begin, part_length = part_data + # TODO: remove for next major version 5.0, compatibility for <= 4.5 + if isinstance(part_data, tuple): + begin, part_length = part_data + else: + begin = part_data["_position"] + part_length = part_data["Size"] + end = begin + part_length - 1 return ObjectRange( begin=begin, diff --git a/tests/aws/services/s3/test_s3.py b/tests/aws/services/s3/test_s3.py index 53254f997f1e7..0a16f083aaf8b 100644 --- a/tests/aws/services/s3/test_s3.py +++ b/tests/aws/services/s3/test_s3.py @@ -12298,7 +12298,7 @@ def test_complete_multipart_parts_checksum_composite( object_attrs = aws_client.s3.get_object_attributes( Bucket=s3_bucket, Key=key_name, - ObjectAttributes=["Checksum", "ETag"], + ObjectAttributes=["Checksum", "ETag", "ObjectParts"], ) snapshot.match("get-object-attrs", object_attrs) @@ -12311,7 +12311,7 @@ def test_complete_multipart_parts_checksum_composite( object_attrs = aws_client.s3.get_object_attributes( Bucket=s3_bucket, Key=dest_key, - ObjectAttributes=["Checksum", "ETag"], + ObjectAttributes=["Checksum", "ETag", "ObjectParts"], ) snapshot.match("get-copy-object-attrs", object_attrs) @@ -12595,7 +12595,7 @@ def test_complete_multipart_parts_checksum_full_object( object_attrs = aws_client.s3.get_object_attributes( Bucket=s3_bucket, Key=key_name, - ObjectAttributes=["Checksum", "ETag"], + ObjectAttributes=["Checksum", "ETag", "ObjectParts"], ) snapshot.match("get-object-attrs", object_attrs) @@ -12608,7 +12608,7 @@ def test_complete_multipart_parts_checksum_full_object( object_attrs = aws_client.s3.get_object_attributes( Bucket=s3_bucket, Key=dest_key, - ObjectAttributes=["Checksum", "ETag"], + ObjectAttributes=["Checksum", "ETag", "ObjectParts"], ) snapshot.match("get-copy-object-attrs", object_attrs) @@ -12877,7 +12877,7 @@ def test_complete_multipart_parts_checksum_default(self, s3_bucket, snapshot, aw object_attrs = aws_client.s3.get_object_attributes( Bucket=s3_bucket, Key=key_name, - ObjectAttributes=["Checksum", "ETag"], + ObjectAttributes=["Checksum", "ETag", "ObjectParts"], ) snapshot.match("get-object-attrs", object_attrs) @@ -12890,7 +12890,7 @@ def test_complete_multipart_parts_checksum_default(self, s3_bucket, snapshot, aw object_attrs = aws_client.s3.get_object_attributes( Bucket=s3_bucket, Key=dest_key, - ObjectAttributes=["Checksum", "ETag"], + ObjectAttributes=["Checksum", "ETag", "ObjectParts"], ) snapshot.match("get-copy-object-attrs", object_attrs) @@ -12959,7 +12959,7 @@ def test_complete_multipart_parts_checksum_full_object_default( object_attrs = aws_client.s3.get_object_attributes( Bucket=s3_bucket, Key=key_name, - ObjectAttributes=["Checksum", "ETag"], + ObjectAttributes=["Checksum", "ETag", "ObjectParts"], ) snapshot.match("get-object-attrs", object_attrs) @@ -13023,7 +13023,10 @@ def test_multipart_size_validation(self, aws_client, s3_bucket, snapshot): snapshot.match("get-object-attrs", object_attrs) @markers.aws.validated - def test_multipart_upload_part_copy_checksum(self, s3_bucket, snapshot, aws_client): + @pytest.mark.parametrize("checksum_type", ("COMPOSITE", "FULL_OBJECT")) + def test_multipart_upload_part_copy_checksum( + self, s3_bucket, snapshot, aws_client, checksum_type + ): snapshot.add_transformer( [ snapshot.transform.key_value("Bucket", reference_replacement=False), @@ -13044,7 +13047,7 @@ def test_multipart_upload_part_copy_checksum(self, s3_bucket, snapshot, aws_clie key_name = "test-multipart-checksum" response = aws_client.s3.create_multipart_upload( - Bucket=s3_bucket, Key=key_name, ChecksumAlgorithm="SHA256" + Bucket=s3_bucket, Key=key_name, ChecksumAlgorithm="CRC32C", ChecksumType=checksum_type ) snapshot.match("create-mpu-checksum-sha256", response) upload_id = response["UploadId"] @@ -13075,7 +13078,7 @@ def test_multipart_upload_part_copy_checksum(self, s3_bucket, snapshot, aws_clie { "ETag": upload_part_copy["CopyPartResult"]["ETag"], "PartNumber": 1, - "ChecksumSHA256": upload_part_copy["CopyPartResult"]["ChecksumSHA256"], + "ChecksumCRC32C": upload_part_copy["CopyPartResult"]["ChecksumCRC32C"], } ] }, @@ -13096,7 +13099,7 @@ def test_multipart_upload_part_copy_checksum(self, s3_bucket, snapshot, aws_clie object_attrs = aws_client.s3.get_object_attributes( Bucket=s3_bucket, Key=key_name, - ObjectAttributes=["Checksum", "ETag"], + ObjectAttributes=["Checksum", "ETag", "ObjectParts"], ) snapshot.match("get-object-attrs", object_attrs) diff --git a/tests/aws/services/s3/test_s3.snapshot.json b/tests/aws/services/s3/test_s3.snapshot.json index b46f9ac443760..5bdf50c8c4091 100644 --- a/tests/aws/services/s3/test_s3.snapshot.json +++ b/tests/aws/services/s3/test_s3.snapshot.json @@ -5238,7 +5238,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_parts_checksum_exceptions_composite": { - "recorded-date": "17-03-2025, 18:21:29", + "recorded-date": "15-06-2025, 17:11:24", "recorded-content": { "create-mpu-wrong-checksum-algo": { "Error": { @@ -14676,7 +14676,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_composite[CRC32]": { - "recorded-date": "17-03-2025, 22:35:34", + "recorded-date": "15-06-2025, 17:09:04", "recorded-content": { "create-mpu-checksum": { "Bucket": "bucket", @@ -14769,7 +14769,7 @@ "Code": "InvalidPart", "ETag": "c4c753e69bb853187f5854c46cf801c6", "Message": "One or more of the specified parts could not be found. The part may not have been uploaded, or the specified entity tag may not match the part's entity tag.", - "PartNumber": "1", + "PartNumber": "2", "UploadId": "" }, "ResponseMetadata": { @@ -14838,6 +14838,30 @@ }, "ETag": "4d45984fc3feb2ac9b22683c49674b56-3", "LastModified": "datetime", + "ObjectParts": { + "IsTruncated": false, + "MaxParts": 1000, + "NextPartNumberMarker": 3, + "PartNumberMarker": 0, + "Parts": [ + { + "ChecksumCRC32": "NRU+Sw==", + "PartNumber": 1, + "Size": 5242881 + }, + { + "ChecksumCRC32": "NRU+Sw==", + "PartNumber": 2, + "Size": 5242881 + }, + { + "ChecksumCRC32": "TBHN8A==", + "PartNumber": 3, + "Size": 10 + } + ], + "TotalPartsCount": 3 + }, "ResponseMetadata": { "HTTPHeaders": {}, "HTTPStatusCode": 200 @@ -14870,7 +14894,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_composite[CRC32C]": { - "recorded-date": "17-03-2025, 22:35:48", + "recorded-date": "15-06-2025, 17:09:18", "recorded-content": { "create-mpu-checksum": { "Bucket": "bucket", @@ -14963,7 +14987,7 @@ "Code": "InvalidPart", "ETag": "c4c753e69bb853187f5854c46cf801c6", "Message": "One or more of the specified parts could not be found. The part may not have been uploaded, or the specified entity tag may not match the part's entity tag.", - "PartNumber": "2", + "PartNumber": "1", "UploadId": "" }, "ResponseMetadata": { @@ -15032,6 +15056,30 @@ }, "ETag": "4d45984fc3feb2ac9b22683c49674b56-3", "LastModified": "datetime", + "ObjectParts": { + "IsTruncated": false, + "MaxParts": 1000, + "NextPartNumberMarker": 3, + "PartNumberMarker": 0, + "Parts": [ + { + "ChecksumCRC32C": "2/Ckiw==", + "PartNumber": 1, + "Size": 5242881 + }, + { + "ChecksumCRC32C": "2/Ckiw==", + "PartNumber": 2, + "Size": 5242881 + }, + { + "ChecksumCRC32C": "5yZkMA==", + "PartNumber": 3, + "Size": 10 + } + ], + "TotalPartsCount": 3 + }, "ResponseMetadata": { "HTTPHeaders": {}, "HTTPStatusCode": 200 @@ -15064,7 +15112,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_composite[SHA1]": { - "recorded-date": "17-03-2025, 22:36:04", + "recorded-date": "15-06-2025, 17:09:33", "recorded-content": { "create-mpu-checksum": { "Bucket": "bucket", @@ -15226,6 +15274,30 @@ }, "ETag": "4d45984fc3feb2ac9b22683c49674b56-3", "LastModified": "datetime", + "ObjectParts": { + "IsTruncated": false, + "MaxParts": 1000, + "NextPartNumberMarker": 3, + "PartNumberMarker": 0, + "Parts": [ + { + "ChecksumSHA1": "bH71WIZUKQtUwR2wKSSkFjCRBPM=", + "PartNumber": 1, + "Size": 5242881 + }, + { + "ChecksumSHA1": "bH71WIZUKQtUwR2wKSSkFjCRBPM=", + "PartNumber": 2, + "Size": 5242881 + }, + { + "ChecksumSHA1": "NJX/adNGcdHhWzOmPBN5/e3Toyo=", + "PartNumber": 3, + "Size": 10 + } + ], + "TotalPartsCount": 3 + }, "ResponseMetadata": { "HTTPHeaders": {}, "HTTPStatusCode": 200 @@ -15258,7 +15330,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_composite[SHA256]": { - "recorded-date": "17-03-2025, 22:36:19", + "recorded-date": "15-06-2025, 17:09:48", "recorded-content": { "create-mpu-checksum": { "Bucket": "bucket", @@ -15420,6 +15492,30 @@ }, "ETag": "4d45984fc3feb2ac9b22683c49674b56-3", "LastModified": "datetime", + "ObjectParts": { + "IsTruncated": false, + "MaxParts": 1000, + "NextPartNumberMarker": 3, + "PartNumberMarker": 0, + "Parts": [ + { + "ChecksumSHA256": "DjU70AB1bON8k0n0fVHv2PJQVWcA/jWsITp6ti20Tbs=", + "PartNumber": 1, + "Size": 5242881 + }, + { + "ChecksumSHA256": "DjU70AB1bON8k0n0fVHv2PJQVWcA/jWsITp6ti20Tbs=", + "PartNumber": 2, + "Size": 5242881 + }, + { + "ChecksumSHA256": "vyy1imj2hNlaO3jvj2Ycmk5bCegsyPnMiMzpBSjK6yc=", + "PartNumber": 3, + "Size": 10 + } + ], + "TotalPartsCount": 3 + }, "ResponseMetadata": { "HTTPHeaders": {}, "HTTPStatusCode": 200 @@ -15452,7 +15548,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[COMPOSITE-CRC32]": { - "recorded-date": "17-03-2025, 18:20:12", + "recorded-date": "15-06-2025, 17:09:49", "recorded-content": { "create-mpu-checksum": { "Bucket": "bucket", @@ -15469,7 +15565,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[COMPOSITE-CRC32C]": { - "recorded-date": "17-03-2025, 18:20:13", + "recorded-date": "15-06-2025, 17:09:50", "recorded-content": { "create-mpu-checksum": { "Bucket": "bucket", @@ -15486,7 +15582,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[COMPOSITE-SHA1]": { - "recorded-date": "17-03-2025, 18:20:15", + "recorded-date": "15-06-2025, 17:09:52", "recorded-content": { "create-mpu-checksum": { "Bucket": "bucket", @@ -15503,7 +15599,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[COMPOSITE-SHA256]": { - "recorded-date": "17-03-2025, 18:20:16", + "recorded-date": "15-06-2025, 17:09:53", "recorded-content": { "create-mpu-checksum": { "Bucket": "bucket", @@ -15520,7 +15616,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[COMPOSITE-CRC64NVME]": { - "recorded-date": "17-03-2025, 18:20:17", + "recorded-date": "15-06-2025, 17:09:54", "recorded-content": { "create-mpu-checksum-exc": { "Error": { @@ -15535,7 +15631,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[FULL_OBJECT-CRC32]": { - "recorded-date": "17-03-2025, 18:20:19", + "recorded-date": "15-06-2025, 17:09:56", "recorded-content": { "create-mpu-checksum": { "Bucket": "bucket", @@ -15552,7 +15648,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[FULL_OBJECT-CRC32C]": { - "recorded-date": "17-03-2025, 18:20:20", + "recorded-date": "15-06-2025, 17:09:57", "recorded-content": { "create-mpu-checksum": { "Bucket": "bucket", @@ -15569,7 +15665,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[FULL_OBJECT-SHA1]": { - "recorded-date": "17-03-2025, 18:20:21", + "recorded-date": "15-06-2025, 17:09:58", "recorded-content": { "create-mpu-checksum-exc": { "Error": { @@ -15584,7 +15680,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[FULL_OBJECT-SHA256]": { - "recorded-date": "17-03-2025, 18:20:23", + "recorded-date": "15-06-2025, 17:10:00", "recorded-content": { "create-mpu-checksum-exc": { "Error": { @@ -15599,7 +15695,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[FULL_OBJECT-CRC64NVME]": { - "recorded-date": "17-03-2025, 18:20:24", + "recorded-date": "15-06-2025, 17:10:01", "recorded-content": { "create-mpu-checksum": { "Bucket": "bucket", @@ -15616,7 +15712,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_default_for_checksum[CRC32]": { - "recorded-date": "17-03-2025, 18:20:25", + "recorded-date": "15-06-2025, 17:10:03", "recorded-content": { "create-mpu-default-checksum-type": { "Bucket": "bucket", @@ -15633,7 +15729,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_default_for_checksum[CRC32C]": { - "recorded-date": "17-03-2025, 18:20:27", + "recorded-date": "15-06-2025, 17:10:04", "recorded-content": { "create-mpu-default-checksum-type": { "Bucket": "bucket", @@ -15650,7 +15746,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_default_for_checksum[SHA1]": { - "recorded-date": "17-03-2025, 18:20:28", + "recorded-date": "15-06-2025, 17:10:05", "recorded-content": { "create-mpu-default-checksum-type": { "Bucket": "bucket", @@ -15667,7 +15763,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_default_for_checksum[SHA256]": { - "recorded-date": "17-03-2025, 18:20:30", + "recorded-date": "15-06-2025, 17:10:07", "recorded-content": { "create-mpu-default-checksum-type": { "Bucket": "bucket", @@ -15684,7 +15780,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_default_for_checksum[CRC64NVME]": { - "recorded-date": "17-03-2025, 18:20:31", + "recorded-date": "15-06-2025, 17:10:08", "recorded-content": { "create-mpu-default-checksum-type": { "Bucket": "bucket", @@ -15701,7 +15797,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_full_object[CRC32]": { - "recorded-date": "17-03-2025, 22:59:16", + "recorded-date": "15-06-2025, 17:11:37", "recorded-content": { "create-mpu-checksum": { "Bucket": "bucket", @@ -15853,6 +15949,9 @@ }, "ETag": "4d45984fc3feb2ac9b22683c49674b56-3", "LastModified": "datetime", + "ObjectParts": { + "TotalPartsCount": 3 + }, "ResponseMetadata": { "HTTPHeaders": {}, "HTTPStatusCode": 200 @@ -15885,7 +15984,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_full_object[CRC32C]": { - "recorded-date": "17-03-2025, 22:59:31", + "recorded-date": "15-06-2025, 17:11:53", "recorded-content": { "create-mpu-checksum": { "Bucket": "bucket", @@ -15978,7 +16077,7 @@ "Code": "InvalidPart", "ETag": "c4c753e69bb853187f5854c46cf801c6", "Message": "One or more of the specified parts could not be found. The part may not have been uploaded, or the specified entity tag may not match the part's entity tag.", - "PartNumber": "1", + "PartNumber": "2", "UploadId": "" }, "ResponseMetadata": { @@ -16037,6 +16136,9 @@ }, "ETag": "4d45984fc3feb2ac9b22683c49674b56-3", "LastModified": "datetime", + "ObjectParts": { + "TotalPartsCount": 3 + }, "ResponseMetadata": { "HTTPHeaders": {}, "HTTPStatusCode": 200 @@ -16069,7 +16171,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_full_object[CRC64NVME]": { - "recorded-date": "17-03-2025, 22:59:46", + "recorded-date": "15-06-2025, 17:12:07", "recorded-content": { "create-mpu-checksum": { "Bucket": "bucket", @@ -16221,6 +16323,9 @@ }, "ETag": "4d45984fc3feb2ac9b22683c49674b56-3", "LastModified": "datetime", + "ObjectParts": { + "TotalPartsCount": 3 + }, "ResponseMetadata": { "HTTPHeaders": {}, "HTTPStatusCode": 200 @@ -16253,7 +16358,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_parts_checksum_exceptions_full_object": { - "recorded-date": "17-03-2025, 19:08:00", + "recorded-date": "15-06-2025, 17:12:51", "recorded-content": { "create-mpu-no-checksum-algo-with-type": { "Error": { @@ -16415,7 +16520,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_default": { - "recorded-date": "17-03-2025, 22:36:46", + "recorded-date": "15-06-2025, 17:12:56", "recorded-content": { "create-mpu-no-checksum": { "Bucket": "bucket", @@ -16592,6 +16697,9 @@ }, "ETag": "e2c3da976e66ec9e7dc128fbc782fc91-1", "LastModified": "datetime", + "ObjectParts": { + "TotalPartsCount": 1 + }, "ResponseMetadata": { "HTTPHeaders": {}, "HTTPStatusCode": 200 @@ -16624,7 +16732,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_size_validation": { - "recorded-date": "17-03-2025, 19:05:35", + "recorded-date": "15-06-2025, 17:13:01", "recorded-content": { "create-mpu": { "Bucket": "bucket", @@ -16683,7 +16791,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_checksum_exception[CRC32]": { - "recorded-date": "17-03-2025, 18:20:42", + "recorded-date": "15-06-2025, 17:10:17", "recorded-content": { "put-wrong-checksum-no-b64": { "Error": { @@ -16708,7 +16816,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_checksum_exception[CRC32C]": { - "recorded-date": "17-03-2025, 18:20:50", + "recorded-date": "15-06-2025, 17:10:27", "recorded-content": { "put-wrong-checksum-no-b64": { "Error": { @@ -16733,7 +16841,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_checksum_exception[SHA1]": { - "recorded-date": "17-03-2025, 18:21:00", + "recorded-date": "15-06-2025, 17:10:44", "recorded-content": { "put-wrong-checksum-no-b64": { "Error": { @@ -16758,7 +16866,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_checksum_exception[SHA256]": { - "recorded-date": "17-03-2025, 18:21:07", + "recorded-date": "15-06-2025, 17:10:59", "recorded-content": { "put-wrong-checksum-no-b64": { "Error": { @@ -16783,7 +16891,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_checksum_exception[CRC64NVME]": { - "recorded-date": "17-03-2025, 18:21:23", + "recorded-date": "15-06-2025, 17:11:10", "recorded-content": { "put-wrong-checksum-no-b64": { "Error": { @@ -16901,7 +17009,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_full_object_default": { - "recorded-date": "17-03-2025, 18:22:27", + "recorded-date": "15-06-2025, 17:12:58", "recorded-content": { "create-mpu-checksum-crc64": { "Bucket": "bucket", @@ -16975,6 +17083,9 @@ }, "ETag": "e2c3da976e66ec9e7dc128fbc782fc91-1", "LastModified": "datetime", + "ObjectParts": { + "TotalPartsCount": 1 + }, "ResponseMetadata": { "HTTPHeaders": {}, "HTTPStatusCode": 200 @@ -17412,8 +17523,8 @@ } } }, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_copy_checksum": { - "recorded-date": "13-06-2025, 12:45:49", + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_copy_checksum[COMPOSITE]": { + "recorded-date": "16-06-2025, 10:53:39", "recorded-content": { "put-object": { "ChecksumCRC32": "nG7pIA==", @@ -17427,7 +17538,7 @@ }, "create-mpu-checksum-sha256": { "Bucket": "bucket", - "ChecksumAlgorithm": "SHA256", + "ChecksumAlgorithm": "CRC32C", "ChecksumType": "COMPOSITE", "Key": "test-multipart-checksum", "ServerSideEncryption": "AES256", @@ -17439,7 +17550,7 @@ }, "upload-part-copy": { "CopyPartResult": { - "ChecksumSHA256": "+j3Oc5P9QdoIdPJ4lFSyNlAAX0G7Am+wZsxu4FYN+wo=", + "ChecksumCRC32C": "iqJrOQ==", "ETag": "\"11df95d595559285eb2b042124e74f09\"", "LastModified": "datetime" }, @@ -17451,7 +17562,7 @@ }, "list-parts": { "Bucket": "bucket", - "ChecksumAlgorithm": "SHA256", + "ChecksumAlgorithm": "CRC32C", "ChecksumType": "COMPOSITE", "Initiator": { "DisplayName": "display-name", @@ -17468,7 +17579,7 @@ "PartNumberMarker": 0, "Parts": [ { - "ChecksumSHA256": "+j3Oc5P9QdoIdPJ4lFSyNlAAX0G7Am+wZsxu4FYN+wo=", + "ChecksumCRC32C": "iqJrOQ==", "ETag": "\"11df95d595559285eb2b042124e74f09\"", "LastModified": "datetime", "PartNumber": 1, @@ -17484,7 +17595,7 @@ }, "complete-multipart-checksum": { "Bucket": "bucket", - "ChecksumSHA256": "/4+xERoRlzE2Ryan+GX/sqNSrf6Qe30L2IM7APXadSE=-1", + "ChecksumCRC32C": "F9bAnw==-1", "ChecksumType": "COMPOSITE", "ETag": "\"395d97c07920de036bfa21e7568a2e9f-1\"", "Key": "test-multipart-checksum", @@ -17498,7 +17609,7 @@ "get-object-with-checksum": { "AcceptRanges": "bytes", "Body": "this is a part", - "ChecksumSHA256": "/4+xERoRlzE2Ryan+GX/sqNSrf6Qe30L2IM7APXadSE=-1", + "ChecksumCRC32C": "F9bAnw==-1", "ChecksumType": "COMPOSITE", "ContentLength": 14, "ContentType": "binary/octet-stream", @@ -17513,7 +17624,7 @@ }, "head-object-with-checksum": { "AcceptRanges": "bytes", - "ChecksumSHA256": "/4+xERoRlzE2Ryan+GX/sqNSrf6Qe30L2IM7APXadSE=-1", + "ChecksumCRC32C": "F9bAnw==-1", "ChecksumType": "COMPOSITE", "ContentLength": 14, "ContentType": "binary/octet-stream", @@ -17528,11 +17639,156 @@ }, "get-object-attrs": { "Checksum": { - "ChecksumSHA256": "/4+xERoRlzE2Ryan+GX/sqNSrf6Qe30L2IM7APXadSE=", + "ChecksumCRC32C": "F9bAnw==", "ChecksumType": "COMPOSITE" }, "ETag": "395d97c07920de036bfa21e7568a2e9f-1", "LastModified": "datetime", + "ObjectParts": { + "IsTruncated": false, + "MaxParts": 1000, + "NextPartNumberMarker": 1, + "PartNumberMarker": 0, + "Parts": [ + { + "ChecksumCRC32C": "iqJrOQ==", + "PartNumber": 1, + "Size": 14 + } + ], + "TotalPartsCount": 1 + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } + }, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_copy_checksum[FULL_OBJECT]": { + "recorded-date": "16-06-2025, 10:53:42", + "recorded-content": { + "put-object": { + "ChecksumCRC32": "nG7pIA==", + "ChecksumType": "FULL_OBJECT", + "ETag": "\"11df95d595559285eb2b042124e74f09\"", + "ServerSideEncryption": "AES256", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "create-mpu-checksum-sha256": { + "Bucket": "bucket", + "ChecksumAlgorithm": "CRC32C", + "ChecksumType": "FULL_OBJECT", + "Key": "test-multipart-checksum", + "ServerSideEncryption": "AES256", + "UploadId": "", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "upload-part-copy": { + "CopyPartResult": { + "ChecksumCRC32C": "iqJrOQ==", + "ETag": "\"11df95d595559285eb2b042124e74f09\"", + "LastModified": "datetime" + }, + "ServerSideEncryption": "AES256", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "list-parts": { + "Bucket": "bucket", + "ChecksumAlgorithm": "CRC32C", + "ChecksumType": "FULL_OBJECT", + "Initiator": { + "DisplayName": "display-name", + "ID": "i-d" + }, + "IsTruncated": false, + "Key": "test-multipart-checksum", + "MaxParts": 1000, + "NextPartNumberMarker": 1, + "Owner": { + "DisplayName": "display-name", + "ID": "i-d" + }, + "PartNumberMarker": 0, + "Parts": [ + { + "ChecksumCRC32C": "iqJrOQ==", + "ETag": "\"11df95d595559285eb2b042124e74f09\"", + "LastModified": "datetime", + "PartNumber": 1, + "Size": 14 + } + ], + "StorageClass": "STANDARD", + "UploadId": "", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "complete-multipart-checksum": { + "Bucket": "bucket", + "ChecksumCRC32C": "iqJrOQ==", + "ChecksumType": "FULL_OBJECT", + "ETag": "\"395d97c07920de036bfa21e7568a2e9f-1\"", + "Key": "test-multipart-checksum", + "Location": "", + "ServerSideEncryption": "AES256", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "get-object-with-checksum": { + "AcceptRanges": "bytes", + "Body": "this is a part", + "ChecksumCRC32C": "iqJrOQ==", + "ChecksumType": "FULL_OBJECT", + "ContentLength": 14, + "ContentType": "binary/octet-stream", + "ETag": "\"395d97c07920de036bfa21e7568a2e9f-1\"", + "LastModified": "datetime", + "Metadata": {}, + "ServerSideEncryption": "AES256", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "head-object-with-checksum": { + "AcceptRanges": "bytes", + "ChecksumCRC32C": "iqJrOQ==", + "ChecksumType": "FULL_OBJECT", + "ContentLength": 14, + "ContentType": "binary/octet-stream", + "ETag": "\"395d97c07920de036bfa21e7568a2e9f-1\"", + "LastModified": "datetime", + "Metadata": {}, + "ServerSideEncryption": "AES256", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "get-object-attrs": { + "Checksum": { + "ChecksumCRC32C": "iqJrOQ==", + "ChecksumType": "FULL_OBJECT" + }, + "ETag": "395d97c07920de036bfa21e7568a2e9f-1", + "LastModified": "datetime", + "ObjectParts": { + "TotalPartsCount": 1 + }, "ResponseMetadata": { "HTTPHeaders": {}, "HTTPStatusCode": 200 diff --git a/tests/aws/services/s3/test_s3.validation.json b/tests/aws/services/s3/test_s3.validation.json index 80b50d625e8ea..ecfb962312509 100644 --- a/tests/aws/services/s3/test_s3.validation.json +++ b/tests/aws/services/s3/test_s3.validation.json @@ -576,108 +576,309 @@ "last_validated_date": "2023-08-14T20:35:53+00:00" }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_composite[CRC32C]": { - "last_validated_date": "2025-03-17T22:35:48+00:00" + "last_validated_date": "2025-06-15T17:09:19+00:00", + "durations_in_seconds": { + "setup": 0.64, + "call": 13.05, + "teardown": 1.03, + "total": 14.72 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_composite[CRC32]": { - "last_validated_date": "2025-03-17T22:35:34+00:00" + "last_validated_date": "2025-06-15T17:09:05+00:00", + "durations_in_seconds": { + "setup": 0.94, + "call": 13.68, + "teardown": 1.01, + "total": 15.63 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_composite[SHA1]": { - "last_validated_date": "2025-03-17T22:36:04+00:00" + "last_validated_date": "2025-06-15T17:09:34+00:00", + "durations_in_seconds": { + "setup": 0.5, + "call": 13.37, + "teardown": 0.96, + "total": 14.83 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_composite[SHA256]": { - "last_validated_date": "2025-03-17T22:36:19+00:00" + "last_validated_date": "2025-06-15T17:09:49+00:00", + "durations_in_seconds": { + "setup": 0.69, + "call": 12.73, + "teardown": 1.01, + "total": 14.43 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_default": { - "last_validated_date": "2025-03-17T22:36:46+00:00" + "last_validated_date": "2025-06-15T17:12:57+00:00", + "durations_in_seconds": { + "setup": 0.59, + "call": 2.92, + "teardown": 0.99, + "total": 4.5 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_full_object[CRC32C]": { - "last_validated_date": "2025-03-17T22:59:31+00:00" + "last_validated_date": "2025-06-15T17:11:54+00:00", + "durations_in_seconds": { + "setup": 0.49, + "call": 14.13, + "teardown": 0.96, + "total": 15.58 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_full_object[CRC32]": { - "last_validated_date": "2025-03-17T22:59:16+00:00" + "last_validated_date": "2025-06-15T17:11:38+00:00", + "durations_in_seconds": { + "setup": 0.5, + "call": 11.77, + "teardown": 1.01, + "total": 13.28 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_full_object[CRC64NVME]": { - "last_validated_date": "2025-03-17T22:59:46+00:00" + "last_validated_date": "2025-06-15T17:12:08+00:00", + "durations_in_seconds": { + "setup": 0.49, + "call": 12.83, + "teardown": 0.99, + "total": 14.31 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_full_object_default": { - "last_validated_date": "2025-03-17T18:22:27+00:00" + "last_validated_date": "2025-06-15T17:12:59+00:00", + "durations_in_seconds": { + "setup": 0.5, + "call": 0.92, + "teardown": 1.0, + "total": 2.42 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[COMPOSITE-CRC32C]": { - "last_validated_date": "2025-03-17T18:20:13+00:00" + "last_validated_date": "2025-06-15T17:09:51+00:00", + "durations_in_seconds": { + "setup": 0.5, + "call": 0.12, + "teardown": 0.61, + "total": 1.23 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[COMPOSITE-CRC32]": { - "last_validated_date": "2025-03-17T18:20:12+00:00" + "last_validated_date": "2025-06-15T17:09:50+00:00", + "durations_in_seconds": { + "setup": 0.48, + "call": 0.12, + "teardown": 0.56, + "total": 1.16 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[COMPOSITE-CRC64NVME]": { - "last_validated_date": "2025-03-17T18:20:17+00:00" + "last_validated_date": "2025-06-15T17:09:55+00:00", + "durations_in_seconds": { + "setup": 0.56, + "call": 0.11, + "teardown": 0.77, + "total": 1.44 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[COMPOSITE-SHA1]": { - "last_validated_date": "2025-03-17T18:20:15+00:00" + "last_validated_date": "2025-06-15T17:09:52+00:00", + "durations_in_seconds": { + "setup": 0.57, + "call": 0.14, + "teardown": 0.58, + "total": 1.29 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[COMPOSITE-SHA256]": { - "last_validated_date": "2025-03-17T18:20:16+00:00" + "last_validated_date": "2025-06-15T17:09:54+00:00", + "durations_in_seconds": { + "setup": 0.48, + "call": 0.14, + "teardown": 0.57, + "total": 1.19 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[FULL_OBJECT-CRC32C]": { - "last_validated_date": "2025-03-17T18:20:20+00:00" + "last_validated_date": "2025-06-15T17:09:58+00:00", + "durations_in_seconds": { + "setup": 0.64, + "call": 0.13, + "teardown": 0.64, + "total": 1.41 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[FULL_OBJECT-CRC32]": { - "last_validated_date": "2025-03-17T18:20:19+00:00" + "last_validated_date": "2025-06-15T17:09:56+00:00", + "durations_in_seconds": { + "setup": 0.51, + "call": 0.13, + "teardown": 0.64, + "total": 1.28 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[FULL_OBJECT-CRC64NVME]": { - "last_validated_date": "2025-03-17T18:20:24+00:00" + "last_validated_date": "2025-06-15T17:10:02+00:00", + "durations_in_seconds": { + "setup": 0.51, + "call": 0.15, + "teardown": 0.64, + "total": 1.3 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[FULL_OBJECT-SHA1]": { - "last_validated_date": "2025-03-17T18:20:21+00:00" + "last_validated_date": "2025-06-15T17:09:59+00:00", + "durations_in_seconds": { + "setup": 0.51, + "call": 0.11, + "teardown": 0.91, + "total": 1.53 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[FULL_OBJECT-SHA256]": { - "last_validated_date": "2025-03-17T18:20:23+00:00" + "last_validated_date": "2025-06-15T17:10:01+00:00", + "durations_in_seconds": { + "setup": 0.51, + "call": 0.12, + "teardown": 0.83, + "total": 1.46 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_default_for_checksum[CRC32C]": { - "last_validated_date": "2025-03-17T18:20:27+00:00" + "last_validated_date": "2025-06-15T17:10:05+00:00", + "durations_in_seconds": { + "setup": 0.57, + "call": 0.13, + "teardown": 0.63, + "total": 1.33 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_default_for_checksum[CRC32]": { - "last_validated_date": "2025-03-17T18:20:25+00:00" + "last_validated_date": "2025-06-15T17:10:03+00:00", + "durations_in_seconds": { + "setup": 0.49, + "call": 0.12, + "teardown": 0.6, + "total": 1.21 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_default_for_checksum[CRC64NVME]": { - "last_validated_date": "2025-03-17T18:20:31+00:00" + "last_validated_date": "2025-06-15T17:10:08+00:00", + "durations_in_seconds": { + "setup": 0.47, + "call": 0.11, + "teardown": 0.57, + "total": 1.15 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_default_for_checksum[SHA1]": { - "last_validated_date": "2025-03-17T18:20:28+00:00" + "last_validated_date": "2025-06-15T17:10:06+00:00", + "durations_in_seconds": { + "setup": 0.59, + "call": 0.14, + "teardown": 0.6, + "total": 1.33 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_default_for_checksum[SHA256]": { - "last_validated_date": "2025-03-17T18:20:29+00:00" + "last_validated_date": "2025-06-15T17:10:07+00:00", + "durations_in_seconds": { + "setup": 0.5, + "call": 0.11, + "teardown": 0.57, + "total": 1.18 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_parts_checksum_exceptions_composite": { - "last_validated_date": "2025-03-17T18:21:29+00:00" + "last_validated_date": "2025-06-15T17:11:25+00:00", + "durations_in_seconds": { + "setup": 0.52, + "call": 12.45, + "teardown": 0.89, + "total": 13.86 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_parts_checksum_exceptions_full_object": { - "last_validated_date": "2025-03-17T19:08:00+00:00" + "last_validated_date": "2025-06-15T17:12:52+00:00", + "durations_in_seconds": { + "setup": 0.49, + "call": 42.48, + "teardown": 1.16, + "total": 44.13 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_size_validation": { - "last_validated_date": "2025-03-17T19:05:35+00:00" + "last_validated_date": "2025-06-15T17:13:02+00:00", + "durations_in_seconds": { + "setup": 0.53, + "call": 1.14, + "teardown": 1.03, + "total": 2.7 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_checksum_exception[CRC32C]": { - "last_validated_date": "2025-03-17T18:20:50+00:00" + "last_validated_date": "2025-06-15T17:10:28+00:00", + "durations_in_seconds": { + "setup": 0.47, + "call": 9.47, + "teardown": 0.9, + "total": 10.84 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_checksum_exception[CRC32]": { - "last_validated_date": "2025-03-17T18:20:42+00:00" + "last_validated_date": "2025-06-15T17:10:18+00:00", + "durations_in_seconds": { + "setup": 0.46, + "call": 8.02, + "teardown": 0.84, + "total": 9.32 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_checksum_exception[CRC64NVME]": { - "last_validated_date": "2025-03-17T18:21:23+00:00" + "last_validated_date": "2025-06-15T17:11:11+00:00", + "durations_in_seconds": { + "setup": 0.52, + "call": 9.39, + "teardown": 0.81, + "total": 10.72 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_checksum_exception[SHA1]": { - "last_validated_date": "2025-03-17T18:21:00+00:00" + "last_validated_date": "2025-06-15T17:10:44+00:00", + "durations_in_seconds": { + "setup": 0.52, + "call": 14.71, + "teardown": 0.86, + "total": 16.09 + } }, "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_checksum_exception[SHA256]": { - "last_validated_date": "2025-03-17T18:21:07+00:00" + "last_validated_date": "2025-06-15T17:11:00+00:00", + "durations_in_seconds": { + "setup": 0.62, + "call": 14.22, + "teardown": 0.81, + "total": 15.65 + } }, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_copy_checksum": { - "last_validated_date": "2025-06-13T12:45:50+00:00", + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_copy_checksum[COMPOSITE]": { + "last_validated_date": "2025-06-16T10:53:40+00:00", "durations_in_seconds": { - "setup": 0.92, - "call": 1.39, - "teardown": 1.01, - "total": 3.32 + "setup": 0.97, + "call": 1.5, + "teardown": 1.06, + "total": 3.53 + } + }, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_copy_checksum[FULL_OBJECT]": { + "last_validated_date": "2025-06-16T10:53:43+00:00", + "durations_in_seconds": { + "setup": 0.52, + "call": 1.4, + "teardown": 0.94, + "total": 2.86 } }, "tests/aws/services/s3/test_s3.py::TestS3ObjectLockLegalHold::test_delete_locked_object": { diff --git a/tests/aws/services/s3/test_s3_list_operations.py b/tests/aws/services/s3/test_s3_list_operations.py index 492043e8631ac..f081782c0ecb3 100644 --- a/tests/aws/services/s3/test_s3_list_operations.py +++ b/tests/aws/services/s3/test_s3_list_operations.py @@ -1075,3 +1075,83 @@ def test_s3_list_parts_timestamp_precision( timestamp: str = resp_dict["ListPartsResult"]["Part"]["LastModified"] # the timestamp should be looking like the following: 2023-11-15T12:02:40.000Z assert_timestamp_is_iso8061_s3_format(timestamp) + + @markers.aws.validated + def test_list_parts_via_object_attrs_pagination(self, s3_bucket, snapshot, aws_client): + snapshot.add_transformer( + [ + snapshot.transform.key_value("Bucket", reference_replacement=False), + snapshot.transform.key_value("Location"), + snapshot.transform.key_value("UploadId"), + snapshot.transform.key_value("DisplayName", reference_replacement=False), + snapshot.transform.key_value("ID", reference_replacement=False), + ] + ) + object_key = "test-object-attrs-pagination" + response = aws_client.s3.create_multipart_upload( + Bucket=s3_bucket, Key=object_key, ChecksumAlgorithm="SHA256" + ) + upload_id = response["UploadId"] + + # data must be at least 5MiB + part_data = b"a" * (5_242_880 + 1) + multipart_upload_parts = [] + + for i in range(1, 3): + upload_part = aws_client.s3.upload_part( + Bucket=s3_bucket, + Key=object_key, + Body=part_data, + PartNumber=i, + UploadId=upload_id, + ChecksumAlgorithm="SHA256", + ) + multipart_upload_parts.append( + { + "ETag": upload_part["ETag"], + "PartNumber": i, + "ChecksumSHA256": upload_part["ChecksumSHA256"], + } + ) + + response = aws_client.s3.list_parts(Bucket=s3_bucket, UploadId=upload_id, Key=object_key) + snapshot.match("list-parts", response) + + complete_multipart = aws_client.s3.complete_multipart_upload( + Bucket=s3_bucket, + UploadId=upload_id, + Key=object_key, + MultipartUpload={"Parts": multipart_upload_parts}, + ) + snapshot.match("complete-mpu", complete_multipart) + + object_attrs = aws_client.s3.get_object_attributes( + Bucket=s3_bucket, + Key=object_key, + ObjectAttributes=["ObjectParts"], + ) + snapshot.match("get-object-attrs-all", object_attrs) + + object_attrs_1 = aws_client.s3.get_object_attributes( + Bucket=s3_bucket, Key=object_key, ObjectAttributes=["ObjectParts"], MaxParts=1 + ) + snapshot.match("get-object-attrs-1", object_attrs) + next_part_number_marker = object_attrs_1["ObjectParts"]["NextPartNumberMarker"] + + object_attrs_next = aws_client.s3.get_object_attributes( + Bucket=s3_bucket, + Key=object_key, + ObjectAttributes=["ObjectParts"], + MaxParts=1, + PartNumberMarker=next_part_number_marker, + ) + snapshot.match("get-object-attrs-next", object_attrs_next) + + object_attrs_wrong = aws_client.s3.get_object_attributes( + Bucket=s3_bucket, + Key=object_key, + ObjectAttributes=["ObjectParts"], + MaxParts=1, + PartNumberMarker=10, + ) + snapshot.match("get-object-attrs-wrong-part", object_attrs_wrong) diff --git a/tests/aws/services/s3/test_s3_list_operations.snapshot.json b/tests/aws/services/s3/test_s3_list_operations.snapshot.json index 60a0a7f756f9a..ab827dee03cff 100644 --- a/tests/aws/services/s3/test_s3_list_operations.snapshot.json +++ b/tests/aws/services/s3/test_s3_list_operations.snapshot.json @@ -3223,5 +3223,150 @@ } } } + }, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListParts::test_list_parts_via_object_attrs_pagination": { + "recorded-date": "16-06-2025, 13:47:27", + "recorded-content": { + "list-parts": { + "Bucket": "bucket", + "ChecksumAlgorithm": "SHA256", + "ChecksumType": "COMPOSITE", + "Initiator": { + "DisplayName": "display-name", + "ID": "i-d" + }, + "IsTruncated": false, + "Key": "test-object-attrs-pagination", + "MaxParts": 1000, + "NextPartNumberMarker": 2, + "Owner": { + "DisplayName": "display-name", + "ID": "i-d" + }, + "PartNumberMarker": 0, + "Parts": [ + { + "ChecksumSHA256": "DjU70AB1bON8k0n0fVHv2PJQVWcA/jWsITp6ti20Tbs=", + "ETag": "\"c4c753e69bb853187f5854c46cf801c6\"", + "LastModified": "datetime", + "PartNumber": 1, + "Size": 5242881 + }, + { + "ChecksumSHA256": "DjU70AB1bON8k0n0fVHv2PJQVWcA/jWsITp6ti20Tbs=", + "ETag": "\"c4c753e69bb853187f5854c46cf801c6\"", + "LastModified": "datetime", + "PartNumber": 2, + "Size": 5242881 + } + ], + "StorageClass": "STANDARD", + "UploadId": "", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "complete-mpu": { + "Bucket": "bucket", + "ChecksumSHA256": "2Wjxbc3N6c1y3Eqve6x8X+xPy4qXhB1vAMgge0qeZJM=-2", + "ChecksumType": "COMPOSITE", + "ETag": "\"14cb3f95b2dfe6bd47fb59d47949e00e-2\"", + "Key": "test-object-attrs-pagination", + "Location": "", + "ServerSideEncryption": "AES256", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "get-object-attrs-all": { + "LastModified": "datetime", + "ObjectParts": { + "IsTruncated": false, + "MaxParts": 1000, + "NextPartNumberMarker": 2, + "PartNumberMarker": 0, + "Parts": [ + { + "ChecksumSHA256": "DjU70AB1bON8k0n0fVHv2PJQVWcA/jWsITp6ti20Tbs=", + "PartNumber": 1, + "Size": 5242881 + }, + { + "ChecksumSHA256": "DjU70AB1bON8k0n0fVHv2PJQVWcA/jWsITp6ti20Tbs=", + "PartNumber": 2, + "Size": 5242881 + } + ], + "TotalPartsCount": 2 + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "get-object-attrs-1": { + "LastModified": "datetime", + "ObjectParts": { + "IsTruncated": false, + "MaxParts": 1000, + "NextPartNumberMarker": 2, + "PartNumberMarker": 0, + "Parts": [ + { + "ChecksumSHA256": "DjU70AB1bON8k0n0fVHv2PJQVWcA/jWsITp6ti20Tbs=", + "PartNumber": 1, + "Size": 5242881 + }, + { + "ChecksumSHA256": "DjU70AB1bON8k0n0fVHv2PJQVWcA/jWsITp6ti20Tbs=", + "PartNumber": 2, + "Size": 5242881 + } + ], + "TotalPartsCount": 2 + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "get-object-attrs-next": { + "LastModified": "datetime", + "ObjectParts": { + "IsTruncated": false, + "MaxParts": 1, + "NextPartNumberMarker": 2, + "PartNumberMarker": 1, + "Parts": [ + { + "ChecksumSHA256": "DjU70AB1bON8k0n0fVHv2PJQVWcA/jWsITp6ti20Tbs=", + "PartNumber": 2, + "Size": 5242881 + } + ], + "TotalPartsCount": 2 + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "get-object-attrs-wrong-part": { + "LastModified": "datetime", + "ObjectParts": { + "IsTruncated": false, + "MaxParts": 1, + "NextPartNumberMarker": 0, + "PartNumberMarker": 10, + "TotalPartsCount": 2 + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } } } diff --git a/tests/aws/services/s3/test_s3_list_operations.validation.json b/tests/aws/services/s3/test_s3_list_operations.validation.json index b7ef285ae6971..127660f3efd56 100644 --- a/tests/aws/services/s3/test_s3_list_operations.validation.json +++ b/tests/aws/services/s3/test_s3_list_operations.validation.json @@ -86,6 +86,15 @@ "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListParts::test_list_parts_pagination": { "last_validated_date": "2025-01-21T18:15:18+00:00" }, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListParts::test_list_parts_via_object_attrs_pagination": { + "last_validated_date": "2025-06-16T13:47:28+00:00", + "durations_in_seconds": { + "setup": 0.97, + "call": 10.45, + "teardown": 0.97, + "total": 12.39 + } + }, "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListParts::test_s3_list_parts_timestamp_precision": { "last_validated_date": "2025-01-21T18:15:22+00:00" } From 67b3da66272ec39516394205ed61fc9b8c5c4e54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carole=20Lavillonni=C3=A8re?= Date: Wed, 18 Jun 2025 16:41:04 +0200 Subject: [PATCH 41/74] Step Functions: Enable Mock Service Integrations Through StartSyncExecution (#12712) --- .../stepfunctions/backend/execution.py | 1 + .../services/stepfunctions/provider.py | 67 +++++---- .../testing/pytest/stepfunctions/utils.py | 50 +++++++ .../v2/mocking/test_base_scenarios.py | 68 ++++++++++ .../mocking/test_base_scenarios.snapshot.json | 127 ++++++++++++++++++ .../test_base_scenarios.validation.json | 3 + 6 files changed, 290 insertions(+), 26 deletions(-) diff --git a/localstack-core/localstack/services/stepfunctions/backend/execution.py b/localstack-core/localstack/services/stepfunctions/backend/execution.py index 76090c7981944..552497557193f 100644 --- a/localstack-core/localstack/services/stepfunctions/backend/execution.py +++ b/localstack-core/localstack/services/stepfunctions/backend/execution.py @@ -392,6 +392,7 @@ def _get_start_execution_worker(self) -> SyncExecutionWorker: exec_comm=self._get_start_execution_worker_comm(), cloud_watch_logging_session=self._cloud_watch_logging_session, activity_store=self._activity_store, + mock_test_case=self.mock_test_case, ) def _get_start_execution_worker_comm(self) -> BaseExecutionWorkerCommunication: diff --git a/localstack-core/localstack/services/stepfunctions/provider.py b/localstack-core/localstack/services/stepfunctions/provider.py index c43fd396c9a8f..2202014eb0b90 100644 --- a/localstack-core/localstack/services/stepfunctions/provider.py +++ b/localstack-core/localstack/services/stepfunctions/provider.py @@ -443,7 +443,7 @@ def create_state_machine( logging_configuration=state_machine_logging_configuration ) - # CreateStateMachine is an idempotent API. Subsequent requests won’t create a duplicate resource if it was + # CreateStateMachine is an idempotent API. Subsequent requests won't create a duplicate resource if it was # already created. idem_state_machine: Optional[StateMachineRevision] = self._idempotent_revision( context=context, @@ -656,7 +656,7 @@ def create_state_machine_alias( stateMachineAliasArn=state_machine_alias_arn, creationDate=alias.create_date ) else: - # CreateStateMachineAlias is an idempotent API. Idempotent requests won’t create duplicate resources. + # CreateStateMachineAlias is an idempotent API. Idempotent requests won't create duplicate resources. raise ConflictException( "Failed to create alias because an alias with the same name and a " "different routing configuration already exists." @@ -772,6 +772,33 @@ def send_task_failure( raise TaskDoesNotExist() raise InvalidToken("Invalid token") + @staticmethod + def _get_state_machine_arn(state_machine_arn: str) -> str: + """Extract the state machine ARN by removing the test case suffix.""" + return state_machine_arn.split("#")[0] + + @staticmethod + def _get_mock_test_case( + state_machine_arn: str, state_machine_name: str + ) -> Optional[MockTestCase]: + """Extract and load a mock test case from a state machine ARN if present.""" + parts = state_machine_arn.split("#") + if len(parts) != 2: + return None + + mock_test_case_name = parts[1] + mock_test_case = load_mock_test_case_for( + state_machine_name=state_machine_name, test_case_name=mock_test_case_name + ) + if mock_test_case is None: + raise InvalidName( + f"Invalid mock test case name '{mock_test_case_name}' " + f"for state machine '{state_machine_name}'." + "Either the test case is not defined or the mock configuration file " + "could not be loaded. See logs for details." + ) + return mock_test_case + def start_execution( self, context: RequestContext, @@ -783,21 +810,16 @@ def start_execution( ) -> StartExecutionOutput: self._validate_state_machine_arn(state_machine_arn) - state_machine_arn_parts = state_machine_arn.split("#") - state_machine_arn = state_machine_arn_parts[0] - mock_test_case_name = ( - state_machine_arn_parts[1] if len(state_machine_arn_parts) == 2 else None - ) - + base_arn = self._get_state_machine_arn(state_machine_arn) store = self.get_store(context=context) - alias: Optional[Alias] = store.aliases.get(state_machine_arn) + alias: Optional[Alias] = store.aliases.get(base_arn) alias_sample_state_machine_version_arn = alias.sample() if alias is not None else None unsafe_state_machine: Optional[StateMachineInstance] = store.state_machines.get( - alias_sample_state_machine_version_arn or state_machine_arn + alias_sample_state_machine_version_arn or base_arn ) if not unsafe_state_machine: - self._raise_state_machine_does_not_exist(state_machine_arn) + self._raise_state_machine_does_not_exist(base_arn) # Update event change parameters about the state machine and should not affect those about this execution. state_machine_clone = copy.deepcopy(unsafe_state_machine) @@ -842,19 +864,7 @@ def start_execution( configuration=state_machine_clone.cloud_watch_logging_configuration, ) - mock_test_case: Optional[MockTestCase] = None - if mock_test_case_name is not None: - state_machine_name = state_machine_clone.name - mock_test_case = load_mock_test_case_for( - state_machine_name=state_machine_name, test_case_name=mock_test_case_name - ) - if mock_test_case is None: - raise InvalidName( - f"Invalid mock test case name '{mock_test_case_name}' " - f"for state machine '{state_machine_name}'." - "Either the test case is not defined or the mock configuration file " - "could not be loaded. See logs for details." - ) + mock_test_case = self._get_mock_test_case(state_machine_arn, state_machine_clone.name) execution = Execution( name=exec_name, @@ -889,11 +899,13 @@ def start_sync_execution( **kwargs, ) -> StartSyncExecutionOutput: self._validate_state_machine_arn(state_machine_arn) + + base_arn = self._get_state_machine_arn(state_machine_arn) unsafe_state_machine: Optional[StateMachineInstance] = self.get_store( context - ).state_machines.get(state_machine_arn) + ).state_machines.get(base_arn) if not unsafe_state_machine: - self._raise_state_machine_does_not_exist(state_machine_arn) + self._raise_state_machine_does_not_exist(base_arn) if unsafe_state_machine.sm_type == StateMachineType.STANDARD: self._raise_state_machine_type_not_supported() @@ -928,6 +940,8 @@ def start_sync_execution( configuration=state_machine_clone.cloud_watch_logging_configuration, ) + mock_test_case = self._get_mock_test_case(state_machine_arn, state_machine_clone.name) + execution = SyncExecution( name=exec_name, sm_type=state_machine_clone.sm_type, @@ -941,6 +955,7 @@ def start_sync_execution( input_data=input_data, trace_header=trace_header, activity_store=self.get_store(context).activities, + mock_test_case=mock_test_case, ) self.get_store(context).executions[exec_arn] = execution diff --git a/localstack-core/localstack/testing/pytest/stepfunctions/utils.py b/localstack-core/localstack/testing/pytest/stepfunctions/utils.py index 3b2925e5a9353..401b6173d66f4 100644 --- a/localstack-core/localstack/testing/pytest/stepfunctions/utils.py +++ b/localstack-core/localstack/testing/pytest/stepfunctions/utils.py @@ -404,6 +404,7 @@ def create_state_machine_with_iam_role( definition: Definition, logging_configuration: Optional[LoggingConfiguration] = None, state_machine_name: Optional[str] = None, + state_machine_type: StateMachineType = StateMachineType.STANDARD, ): snf_role_arn = create_state_machine_iam_role(target_aws_client=target_aws_client) snapshot.add_transformer(RegexTransformer(snf_role_arn, "snf_role_arn")) @@ -422,6 +423,7 @@ def create_state_machine_with_iam_role( "name": sm_name, "definition": definition, "roleArn": snf_role_arn, + "type": state_machine_type, } if logging_configuration is not None: create_arguments["loggingConfiguration"] = logging_configuration @@ -507,6 +509,27 @@ def launch_and_record_mocked_execution( return execution_arn +def launch_and_record_mocked_sync_execution( + target_aws_client, + sfn_snapshot, + state_machine_arn, + execution_input, + test_name, +) -> LongArn: + stepfunctions_client = target_aws_client.stepfunctions + + exec_resp = stepfunctions_client.start_sync_execution( + stateMachineArn=f"{state_machine_arn}#{test_name}", + input=execution_input, + ) + + sfn_snapshot.add_transformer(sfn_snapshot.transform.sfn_sm_sync_exec_arn(exec_resp, 0)) + + sfn_snapshot.match("start_execution_sync_response", exec_resp) + + return exec_resp["executionArn"] + + def launch_and_record_logs( target_aws_client, state_machine_arn, @@ -579,6 +602,7 @@ def create_and_record_mocked_execution( execution_input, state_machine_name, test_name, + state_machine_type: StateMachineType = StateMachineType.STANDARD, ) -> LongArn: state_machine_arn = create_state_machine_with_iam_role( target_aws_client, @@ -587,6 +611,7 @@ def create_and_record_mocked_execution( sfn_snapshot, definition, state_machine_name=state_machine_name, + state_machine_type=state_machine_type, ) execution_arn = launch_and_record_mocked_execution( target_aws_client, sfn_snapshot, state_machine_arn, execution_input, test_name @@ -594,6 +619,31 @@ def create_and_record_mocked_execution( return execution_arn +def create_and_record_mocked_sync_execution( + target_aws_client, + create_state_machine_iam_role, + create_state_machine, + sfn_snapshot, + definition, + execution_input, + state_machine_name, + test_name, +) -> LongArn: + state_machine_arn = create_state_machine_with_iam_role( + target_aws_client, + create_state_machine_iam_role, + create_state_machine, + sfn_snapshot, + definition, + state_machine_name=state_machine_name, + state_machine_type=StateMachineType.EXPRESS, + ) + execution_arn = launch_and_record_mocked_sync_execution( + target_aws_client, sfn_snapshot, state_machine_arn, execution_input, test_name + ) + return execution_arn + + def create_and_run_mock( target_aws_client, monkeypatch, diff --git a/tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py b/tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py index 7c30e0d513801..a267d59cf91dc 100644 --- a/tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py +++ b/tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py @@ -12,7 +12,9 @@ SfnNoneRecursiveParallelTransformer, await_execution_terminated, create_and_record_execution, + create_and_record_express_sync_execution, create_and_record_mocked_execution, + create_and_record_mocked_sync_execution, ) from localstack.utils.strings import short_uid from tests.aws.services.stepfunctions.mocked_service_integrations.mocked_service_integrations import ( @@ -233,6 +235,72 @@ def test_lambda_service_invoke( test_name, ) + @markers.aws.validated + @markers.snapshot.skip_snapshot_verify( + paths=[ + "$..billingDetails", + ] + ) + def test_lambda_service_invoke_sync_execution( + self, + aws_client, + aws_client_no_sync_prefix, + create_state_machine_iam_role, + create_state_machine, + create_lambda_function, + sfn_snapshot, + monkeypatch, + mock_config_file, + ): + template = ServicesTemplates.load_sfn_template(ServicesTemplates.LAMBDA_INVOKE) + definition = json.dumps(template) + + function_name = f"lambda_{short_uid()}" + sfn_snapshot.add_transformer(RegexTransformer(function_name, "lambda_function_name")) + exec_input = json.dumps({"FunctionName": function_name, "Payload": {"body": "string body"}}) + + if is_aws_cloud(): + create_lambda_function( + func_name=function_name, + handler_file=ServicesTemplates.LAMBDA_ID_FUNCTION, + runtime=Runtime.python3_12, + ) + create_and_record_express_sync_execution( + aws_client, + create_state_machine_iam_role, + create_state_machine, + sfn_snapshot, + definition, + exec_input, + ) + else: + state_machine_name = f"mocked_state_machine_{short_uid()}" + test_name = "TestCaseName" + lambda_200_string_body = MockedServiceIntegrationsLoader.load( + MockedServiceIntegrationsLoader.MOCKED_RESPONSE_LAMBDA_200_STRING_BODY + ) + mock_config = { + "StateMachines": { + state_machine_name: { + "TestCases": {test_name: {"Start": "lambda_200_string_body"}} + } + }, + "MockedResponses": {"lambda_200_string_body": lambda_200_string_body}, + } + mock_config_file_path = mock_config_file(mock_config) + monkeypatch.setattr(config, "SFN_MOCK_CONFIG", mock_config_file_path) + + create_and_record_mocked_sync_execution( + target_aws_client=aws_client_no_sync_prefix, + create_state_machine_iam_role=create_state_machine_iam_role, + create_state_machine=create_state_machine, + sfn_snapshot=sfn_snapshot, + definition=definition, + execution_input=exec_input, + state_machine_name=state_machine_name, + test_name=test_name, + ) + @markers.aws.validated def test_sqs_send_message( self, diff --git a/tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.snapshot.json b/tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.snapshot.json index 825c405214dcb..739ec3945461f 100644 --- a/tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.snapshot.json +++ b/tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.snapshot.json @@ -2475,5 +2475,132 @@ } } } + }, + "tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py::TestBaseScenarios::test_lambda_service_invoke_sync_execution": { + "recorded-date": "03-06-2025, 18:47:04", + "recorded-content": { + "creation_response": { + "creationDate": "datetime", + "stateMachineArn": "arn::states::111111111111:stateMachine:", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "start_execution_sync_response": { + "billingDetails": { + "billedDurationInMilliseconds": 300, + "billedMemoryUsedInMB": 64 + }, + "executionArn": "arn::states::111111111111:express:::", + "input": { + "FunctionName": "lambda_function_name", + "Payload": { + "body": "string body" + } + }, + "inputDetails": { + "included": true + }, + "name": "", + "output": { + "ExecutedVersion": "$LATEST", + "Payload": { + "body": "string body" + }, + "SdkHttpMetadata": { + "AllHttpHeaders": { + "X-Amz-Executed-Version": [ + "$LATEST" + ], + "x-amzn-Remapped-Content-Length": [ + "0" + ], + "Connection": [ + "keep-alive" + ], + "x-amzn-RequestId": "x-amzn-RequestId", + "Content-Length": [ + "23" + ], + "Date": "date", + "X-Amzn-Trace-Id": "X-Amzn-Trace-Id", + "Content-Type": [ + "application/json" + ] + }, + "HttpHeaders": { + "Connection": "keep-alive", + "Content-Length": "23", + "Content-Type": "application/json", + "Date": "date", + "X-Amz-Executed-Version": "$LATEST", + "x-amzn-Remapped-Content-Length": "0", + "x-amzn-RequestId": "x-amzn-RequestId", + "X-Amzn-Trace-Id": "X-Amzn-Trace-Id" + }, + "HttpStatusCode": 200 + }, + "SdkResponseMetadata": { + "RequestId": "RequestId" + }, + "StatusCode": 200, + "final": { + "ExecutedVersion": "$LATEST", + "Payload": { + "body": "string body" + }, + "SdkHttpMetadata": { + "AllHttpHeaders": { + "X-Amz-Executed-Version": [ + "$LATEST" + ], + "x-amzn-Remapped-Content-Length": [ + "0" + ], + "Connection": [ + "keep-alive" + ], + "x-amzn-RequestId": "x-amzn-RequestId", + "Content-Length": [ + "23" + ], + "Date": "date", + "X-Amzn-Trace-Id": "X-Amzn-Trace-Id", + "Content-Type": [ + "application/json" + ] + }, + "HttpHeaders": { + "Connection": "keep-alive", + "Content-Length": "23", + "Content-Type": "application/json", + "Date": "date", + "X-Amz-Executed-Version": "$LATEST", + "x-amzn-Remapped-Content-Length": "0", + "x-amzn-RequestId": "x-amzn-RequestId", + "X-Amzn-Trace-Id": "X-Amzn-Trace-Id" + }, + "HttpStatusCode": 200 + }, + "SdkResponseMetadata": { + "RequestId": "RequestId" + }, + "StatusCode": 200 + } + }, + "outputDetails": { + "included": true + }, + "startDate": "datetime", + "stateMachineArn": "arn::states::111111111111:stateMachine:", + "status": "SUCCEEDED", + "stopDate": "datetime", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } } } diff --git a/tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.validation.json b/tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.validation.json index 11b63a4402426..5836f11a2ed34 100644 --- a/tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.validation.json +++ b/tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.validation.json @@ -11,6 +11,9 @@ "tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py::TestBaseScenarios::test_lambda_service_invoke": { "last_validated_date": "2025-04-14T18:51:50+00:00" }, + "tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py::TestBaseScenarios::test_lambda_service_invoke_sync_execution": { + "last_validated_date": "2025-06-03T18:47:04+00:00" + }, "tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py::TestBaseScenarios::test_map_state_lambda": { "last_validated_date": "2025-04-24T11:11:05+00:00" }, From c9e027948fb8b20a74980209d6b8932be2875fd2 Mon Sep 17 00:00:00 2001 From: Ben Simon Hartung <42031100+bentsku@users.noreply.github.com> Date: Thu, 19 Jun 2025 11:23:40 +0200 Subject: [PATCH 42/74] APIGW: fix VTL $input.path and $input.json (#12774) --- .../next_gen/execute_api/template_mapping.py | 27 ++++++++-- .../apigateway/test_apigateway_common.py | 19 +++++++ .../test_apigateway_common.snapshot.json | 7 ++- .../test_apigateway_common.validation.json | 8 ++- .../apigateway/test_template_mapping.py | 52 ++++++++++++++++++- 5 files changed, 105 insertions(+), 8 deletions(-) diff --git a/localstack-core/localstack/services/apigateway/next_gen/execute_api/template_mapping.py b/localstack-core/localstack/services/apigateway/next_gen/execute_api/template_mapping.py index 01beb0114f598..fd729f853d187 100644 --- a/localstack-core/localstack/services/apigateway/next_gen/execute_api/template_mapping.py +++ b/localstack-core/localstack/services/apigateway/next_gen/execute_api/template_mapping.py @@ -23,6 +23,7 @@ import airspeed from airspeed.operators import dict_to_string +from jsonpath_rw import parse from localstack import config from localstack.services.apigateway.next_gen.execute_api.variables import ( @@ -31,7 +32,7 @@ ContextVarsResponseOverride, ) from localstack.utils.aws.templating import APIGW_SOURCE, VelocityUtil, VtlTemplate -from localstack.utils.json import extract_jsonpath, json_safe +from localstack.utils.json import json_safe LOG = logging.getLogger(__name__) @@ -69,6 +70,15 @@ def cast_to_vtl_json_object(value: Any) -> Any: return value +def extract_jsonpath(value: dict | list, path: str): + jsonpath_expr = parse(path) + result = [match.value for match in jsonpath_expr.find(value)] + if not result: + return None + result = result[0] if len(result) == 1 else result + return result + + class VTLMap(dict): """Overrides __str__ of python dict (and all child dict) to return a Java like string representation""" @@ -211,8 +221,15 @@ def __init__(self, body, params): def _extract_json_path(self, path): if not self.value: - return {} - value = self.value if isinstance(self.value, dict) else json.loads(self.value) + return None + if isinstance(self.value, dict): + value = self.value + else: + try: + value = json.loads(self.value) + except json.JSONDecodeError: + return None + return extract_jsonpath(value, path) def path(self, path): @@ -221,7 +238,9 @@ def path(self, path): def json(self, path): path = path or "$" matching = self._extract_json_path(path) - if isinstance(matching, (list, dict)): + if matching is None: + matching = "" + elif isinstance(matching, (list, dict)): matching = json_safe(matching) return json.dumps(matching) diff --git a/tests/aws/services/apigateway/test_apigateway_common.py b/tests/aws/services/apigateway/test_apigateway_common.py index c585df9dcb05d..50d032e0d2245 100644 --- a/tests/aws/services/apigateway/test_apigateway_common.py +++ b/tests/aws/services/apigateway/test_apigateway_common.py @@ -837,6 +837,14 @@ def _create_route(path: str, response_templates): _create_route("nested", '#set($result = $input.path("$.json"))$result.nested') _create_route("list", '#set($result = $input.path("$.json"))$result[0]') _create_route("to-string", '#set($result = $input.path("$.json"))$result.toString()') + _create_route( + "invalid-path", + '#set($result = $input.path("$.nonExisting")){"body": $result, "nested": $result.nested, "isNull": #if( $result == $null )"true"#else"false"#end, "isEmptyString": #if( $result == "" )"true"#else"false"#end}', + ) + _create_route( + "nested-list", + '#set($result = $input.path("$.json.listValue")){"body": $result, "nested": $result.nested, "isNull": #if( $result == $null )"true"#else"false"#end, "isEmptyString": #if( $result == "" )"true"#else"false"#end}', + ) stage_name = "dev" aws_client.apigateway.create_deployment(restApiId=api_id, stageName=stage_name) @@ -846,6 +854,8 @@ def _create_route(path: str, response_templates): nested_url = url + "nested" list_url = url + "list" to_string = url + "to-string" + invalid_path = url + "invalid-path" + nested_list = url + "nested-list" response = requests.post(path_url, json={"foo": "bar"}) snapshot.match("dict-response", response.text) @@ -879,6 +889,15 @@ def _create_route(path: str, response_templates): response = requests.post(to_string, json={"list": [{"foo": "bar"}]}) snapshot.match("list-to-string", response.text) + response = requests.post(invalid_path) + snapshot.match("empty-body", response.text) + + response = requests.post(nested_list, json={"listValue": []}) + snapshot.match("nested-empty-list", response.text) + + response = requests.post(nested_list, json={"listValue": None}) + snapshot.match("nested-null-list", response.text) + @markers.aws.validated def test_input_body_formatting( self, aws_client, create_lambda_function, create_rest_apigw, snapshot diff --git a/tests/aws/services/apigateway/test_apigateway_common.snapshot.json b/tests/aws/services/apigateway/test_apigateway_common.snapshot.json index 9a12de591ead8..fd306b34e47b9 100644 --- a/tests/aws/services/apigateway/test_apigateway_common.snapshot.json +++ b/tests/aws/services/apigateway/test_apigateway_common.snapshot.json @@ -1378,7 +1378,7 @@ } }, "tests/aws/services/apigateway/test_apigateway_common.py::TestApiGatewayCommon::test_input_path_template_formatting": { - "recorded-date": "12-03-2025, 21:18:25", + "recorded-date": "18-06-2025, 17:28:59", "recorded-content": { "dict-response": "{foo=bar}", "json-list": "[{\"foo\":\"bar\"}]", @@ -1389,7 +1389,10 @@ "dict-with-nested-list": "{foo=[{\"nested\":\"bar\"}]}", "bigger-dict": "{bigger=dict, to=test, with=separators}", "to-string": "{foo=bar}", - "list-to-string": "{list=[{\"foo\":\"bar\"}]}" + "list-to-string": "{list=[{\"foo\":\"bar\"}]}", + "empty-body": "{\"body\": , \"nested\": , \"isNull\": \"true\", \"isEmptyString\": \"true\"}", + "nested-empty-list": "{\"body\": [], \"nested\": , \"isNull\": \"false\", \"isEmptyString\": \"false\"}", + "nested-null-list": "{\"body\": , \"nested\": , \"isNull\": \"true\", \"isEmptyString\": \"true\"}" } }, "tests/aws/services/apigateway/test_apigateway_common.py::TestApiGatewayCommon::test_input_body_formatting": { diff --git a/tests/aws/services/apigateway/test_apigateway_common.validation.json b/tests/aws/services/apigateway/test_apigateway_common.validation.json index 44135ffb7c4fd..9cbc496d24987 100644 --- a/tests/aws/services/apigateway/test_apigateway_common.validation.json +++ b/tests/aws/services/apigateway/test_apigateway_common.validation.json @@ -12,7 +12,13 @@ "last_validated_date": "2025-03-19T17:03:40+00:00" }, "tests/aws/services/apigateway/test_apigateway_common.py::TestApiGatewayCommon::test_input_path_template_formatting": { - "last_validated_date": "2025-03-12T21:18:25+00:00" + "last_validated_date": "2025-06-18T17:29:00+00:00", + "durations_in_seconds": { + "setup": 0.48, + "call": 42.72, + "teardown": 0.86, + "total": 44.06 + } }, "tests/aws/services/apigateway/test_apigateway_common.py::TestApiGatewayCommon::test_integration_request_parameters_mapping": { "last_validated_date": "2024-02-05T19:37:03+00:00" diff --git a/tests/unit/services/apigateway/test_template_mapping.py b/tests/unit/services/apigateway/test_template_mapping.py index 9b58d85225736..4c6c6a4a175ab 100644 --- a/tests/unit/services/apigateway/test_template_mapping.py +++ b/tests/unit/services/apigateway/test_template_mapping.py @@ -94,12 +94,42 @@ def test_apply_template(self): def test_apply_template_no_json_payload(self): variables = MappingTemplateVariables(input=MappingTemplateInput(body='"#foobar123"')) + template = "$input.json('$.message')" + rendered_request = ApiGatewayVtlTemplate().render_vtl( + template=template, variables=variables + ) + + assert rendered_request == '""' + + def test_apply_template_no_json_payload_non_quoted(self): + variables = MappingTemplateVariables(input=MappingTemplateInput(body="not json")) + + template = "$input.json('$.message')" + rendered_request = ApiGatewayVtlTemplate().render_vtl( + template=template, variables=variables + ) + + assert rendered_request == '""' + + def test_apply_template_no_json_payload_nested(self): + variables = MappingTemplateVariables(input=MappingTemplateInput(body='"#foobar123"')) + + template = "$input.json('$.message').testAccess" + rendered_request = ApiGatewayVtlTemplate().render_vtl( + template=template, variables=variables + ) + + assert rendered_request == "" + + def test_apply_template_no_json_payload_escaped(self): + variables = MappingTemplateVariables(input=MappingTemplateInput(body='"#foobar123"')) + template = "$util.escapeJavaScript($input.json('$.message'))" rendered_request = ApiGatewayVtlTemplate().render_vtl( template=template, variables=variables ) - assert "[]" == rendered_request + assert rendered_request == '\\"\\"' @pytest.mark.parametrize("format", [APPLICATION_JSON, APPLICATION_XML]) def test_render_custom_template(self, format): @@ -265,6 +295,26 @@ def test_input_url_encode_empty_body(self): assert rendered_request == "%7B%7D" + def test_input_path_empty_body(self): + variables = MappingTemplateVariables(input=MappingTemplateInput(body="")) + + template = '$input.path("$.myVar")' + rendered_request = ApiGatewayVtlTemplate().render_vtl( + template=template, variables=variables + ) + + assert rendered_request == "" + + def test_input_path_not_json_body(self): + variables = MappingTemplateVariables(input=MappingTemplateInput(body="not json")) + + template = '$input.path("$.myVar")' + rendered_request = ApiGatewayVtlTemplate().render_vtl( + template=template, variables=variables + ) + + assert rendered_request == "" + TEMPLATE_JSON = """ From 3b2f334577d965927861c747c7773d7ce240040a Mon Sep 17 00:00:00 2001 From: Marco Edoardo Palma <64580864+MEPalma@users.noreply.github.com> Date: Thu, 19 Jun 2025 17:50:35 +0200 Subject: [PATCH 43/74] CloudFormation v2 Engine: Base Support for Global Macros (#12761) --- .../engine/v2/change_set_model.py | 26 +- .../engine/v2/change_set_model_preproc.py | 16 + .../engine/v2/change_set_model_transform.py | 122 ++++- .../v2/ported_from_v1/api/test_changesets.py | 1 - .../v2/ported_from_v1/api/test_stacks.py | 2 +- .../v2/ported_from_v1/api/test_templates.py | 2 +- .../ported_from_v1/engine/test_conditions.py | 3 - .../v2/ported_from_v1/engine/test_mappings.py | 1 - .../resources/test_apigateway.py | 1 - .../ported_from_v1/resources/test_dynamodb.py | 2 - .../v2/ported_from_v1/resources/test_ec2.py | 2 +- .../ported_from_v1/resources/test_events.py | 2 +- .../ported_from_v1/resources/test_firehose.py | 1 - .../ported_from_v1/resources/test_kinesis.py | 1 - .../ported_from_v1/resources/test_lambda.py | 14 +- .../v2/ported_from_v1/resources/test_s3.py | 1 - .../v2/ported_from_v1/resources/test_sam.py | 1 - .../v2/ported_from_v1/resources/test_sns.py | 1 - .../v2/ported_from_v1/resources/test_ssm.py | 1 - .../resources/test_stepfunctions.py | 4 - .../v2/ported_from_v1/test_template_engine.py | 11 +- .../v2/test_change_set_global_macros.py | 101 ++++ ...est_change_set_global_macros.snapshot.json | 435 ++++++++++++++++++ ...t_change_set_global_macros.validation.json | 11 + .../cloudformation/v2/test_change_set_ref.py | 1 - 25 files changed, 713 insertions(+), 50 deletions(-) create mode 100644 tests/aws/services/cloudformation/v2/test_change_set_global_macros.py create mode 100644 tests/aws/services/cloudformation/v2/test_change_set_global_macros.snapshot.json create mode 100644 tests/aws/services/cloudformation/v2/test_change_set_global_macros.validation.json diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model.py index d366c0906cad8..c898c3d4bf4de 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model.py @@ -802,6 +802,7 @@ def _visit_property( node_property = self._visited_scopes.get(scope) if isinstance(node_property, NodeProperty): return node_property + # TODO: Review the use of Fn::Transform as resource properties. value = self._visit_value( scope=scope, before_value=before_property, after_value=after_property ) @@ -1156,14 +1157,30 @@ def _visit_global_transform( @staticmethod def _normalise_transformer_value(value: Maybe[str | list[Any]]) -> Maybe[list[Any]]: # To simplify downstream logics, reduce the type options to array of transformations. - # TODO: add validation logic + # TODO: add further validation logic # TODO: should we sort to avoid detecting user-side ordering changes as template changes? if isinstance(value, NothingType): return value elif isinstance(value, str): value = [NormalisedGlobalTransformDefinition(Name=value, Parameters=Nothing)] - elif not isinstance(value, list): - raise RuntimeError(f"Invalid type for Transformer: '{value}'") + elif isinstance(value, list): + tmp_value = list() + for item in value: + if isinstance(item, str): + tmp_value.append( + NormalisedGlobalTransformDefinition(Name=item, Parameters=Nothing) + ) + else: + tmp_value.append(item) + value = tmp_value + elif isinstance(value, dict): + if "Name" not in value: + raise RuntimeError(f"Missing 'Name' field in Transform definition '{value}'") + name = value["Name"] + parameters = value.get("Parameters", Nothing) + value = [NormalisedGlobalTransformDefinition(Name=name, Parameters=parameters)] + else: + raise RuntimeError(f"Invalid Transform definition: '{value}'") return value def _visit_transform( @@ -1325,7 +1342,8 @@ def _is_intrinsic_function_name(function_name: str) -> bool: def _safe_access_in(scope: Scope, key: str, *objects: Maybe[dict]) -> tuple[Scope, Maybe[Any]]: results = list() for obj in objects: - # TODO: raise errors if not dict + if not isinstance(obj, (dict, NothingType)): + raise RuntimeError(f"Invalid definition type at '{obj}'") if not isinstance(obj, NothingType): results.append(obj.get(key, Nothing)) else: diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py index 66a862ba0cc0c..5ec1b58e8bcf3 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py @@ -27,6 +27,7 @@ NodeOutput, NodeOutputs, NodeParameter, + NodeParameters, NodeProperties, NodeProperty, NodeResource, @@ -882,6 +883,21 @@ def visit_node_mapping(self, node_mapping: NodeMapping) -> PreprocEntityDelta: bindings_delta = self.visit(node_mapping.bindings) return bindings_delta + def visit_node_parameters( + self, node_parameters: NodeParameters + ) -> PreprocEntityDelta[dict[str, Any], dict[str, Any]]: + before_parameters = dict() + after_parameters = dict() + for parameter in node_parameters.parameters: + parameter_delta = self.visit(parameter) + parameter_before = parameter_delta.before + if not is_nothing(parameter_before): + before_parameters[parameter.name] = parameter_before + parameter_after = parameter_delta.after + if not is_nothing(parameter_after): + after_parameters[parameter.name] = parameter_after + return PreprocEntityDelta(before=before_parameters, after=after_parameters) + def visit_node_parameter(self, node_parameter: NodeParameter) -> PreprocEntityDelta: dynamic_value = node_parameter.dynamic_value dynamic_delta = self.visit(dynamic_value) diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_transform.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_transform.py index 84d0ea6feac9b..4ba3e43c5c700 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_transform.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_transform.py @@ -1,16 +1,21 @@ import copy +import logging import os -from typing import Final, Optional +from typing import Any, Final, Optional, TypedDict import boto3 from samtranslator.translator.transform import transform as transform_sam from localstack.services.cloudformation.engine.policy_loader import create_policy_loader -from localstack.services.cloudformation.engine.transformers import FailedTransformationException +from localstack.services.cloudformation.engine.transformers import ( + FailedTransformationException, + execute_macro, +) from localstack.services.cloudformation.engine.v2.change_set_model import ( ChangeType, Maybe, NodeGlobalTransform, + NodeParameter, NodeTransform, Nothing, is_nothing, @@ -19,9 +24,14 @@ ChangeSetModelPreproc, PreprocEntityDelta, ) +from localstack.services.cloudformation.stores import get_cloudformation_store from localstack.services.cloudformation.v2.entities import ChangeSet +LOG = logging.getLogger(__name__) + SERVERLESS_TRANSFORM = "AWS::Serverless-2016-10-31" +EXTENSIONS_TRANSFORM = "AWS::LanguageExtensions" +SECRETSMANAGER_TRANSFORM = "AWS::SecretsManager-2020-07-23" # TODO: evaluate the use of subtypes to represent and validate types of transforms @@ -34,6 +44,13 @@ def __init__(self, name: str, parameters: Maybe[dict]): self.parameters = parameters +class TransformPreprocParameter(TypedDict): + # TODO: expand + ParameterKey: str + ParameterValue: Any + ParameterType: Optional[str] + + class ChangeSetModelTransform(ChangeSetModelPreproc): _before_parameters: Final[dict] _after_parameters: Final[dict] @@ -54,9 +71,48 @@ def __init__( self._before_template = before_template or Nothing self._after_template = after_template or Nothing + def visit_node_parameter( + self, node_parameter: NodeParameter + ) -> PreprocEntityDelta[ + dict[str, TransformPreprocParameter], dict[str, TransformPreprocParameter] + ]: + # Enable compatability with v1 util. + # TODO: port v1's SSM parameter resolution + + parameter_value_delta = super().visit_node_parameter(node_parameter=node_parameter) + parameter_value_before = parameter_value_delta.before + parameter_value_after = parameter_value_delta.after + + parameter_type_delta = self.visit(node_parameter.type_) + parameter_type_before = parameter_type_delta.before + parameter_type_after = parameter_type_delta.after + + parameter_key = node_parameter.name + + before = Nothing + if not is_nothing(parameter_value_before): + before = TransformPreprocParameter( + ParameterKey=parameter_key, + ParameterValue=parameter_value_before, + ParameterType=parameter_type_before + if not is_nothing(parameter_type_before) + else None, + ) + after = Nothing + if not is_nothing(parameter_value_after): + after = TransformPreprocParameter( + ParameterKey=parameter_key, + ParameterValue=parameter_value_after, + ParameterType=parameter_type_after + if not is_nothing(parameter_type_after) + else None, + ) + + return PreprocEntityDelta(before=before, after=after) + # Ported from v1: @staticmethod - def _apply_serverless_transformation( + def _apply_global_serverless_transformation( region_name: str, template: dict, parameters: dict ) -> dict: """only returns string when parsing SAM template, otherwise None""" @@ -79,19 +135,65 @@ def _apply_serverless_transformation( if region_before is not None: os.environ["AWS_DEFAULT_REGION"] = region_before + @staticmethod + def _apply_global_macro_transformation( + account_id: str, + region_name, + global_transform: GlobalTransform, + template: dict, + parameters: dict, + ) -> Optional[dict]: + macro_name = global_transform.name + macros_store = get_cloudformation_store( + account_id=account_id, region_name=region_name + ).macros + macro = macros_store.get(macro_name) + if macro is None: + raise RuntimeError(f"No definitions for global transform '{macro_name}'") + transformation_parameters = global_transform.parameters or dict() + transformed_template = execute_macro( + account_id, + region_name, + parsed_template=template, + macro=macro, + stack_parameters=parameters, + transformation_parameters=transformation_parameters, + ) + # The type annotation on the v1 util appears to be incorrect. + return transformed_template # noqa + def _apply_global_transform( self, global_transform: GlobalTransform, template: dict, parameters: dict ) -> dict: - if global_transform.name == SERVERLESS_TRANSFORM: - return self._apply_serverless_transformation( + transform_name = global_transform.name + if transform_name == EXTENSIONS_TRANSFORM: + # Applied lazily in downstream tasks (see ChangeSetModelPreproc). + transformed_template = template + elif transform_name == SERVERLESS_TRANSFORM: + transformed_template = self._apply_global_serverless_transformation( region_name=self._change_set.region_name, template=template, parameters=parameters, ) - # TODO: expand support - raise RuntimeError(f"Unsupported global transform '{global_transform.name}'") + elif transform_name == SECRETSMANAGER_TRANSFORM: + # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/transform-aws-secretsmanager.html + LOG.warning("%s is not yet supported. Ignoring.", SECRETSMANAGER_TRANSFORM) + transformed_template = template + else: + transformed_template = self._apply_global_macro_transformation( + account_id=self._change_set.account_id, + region_name=self._change_set.region_name, + global_transform=global_transform, + template=template, + parameters=parameters, + ) + return transformed_template def transform(self) -> tuple[dict, dict]: + parameters_delta = self.visit_node_parameters(self._node_template.parameters) + parameters_before = parameters_delta.before + parameters_after = parameters_delta.after + transform_delta: PreprocEntityDelta[list[GlobalTransform], list[GlobalTransform]] = ( self.visit_node_transform(self._node_template.transform) ) @@ -104,17 +206,17 @@ def transform(self) -> tuple[dict, dict]: for before_global_transform in transform_before: transformed_before_template = self._apply_global_transform( global_transform=before_global_transform, - parameters=self._before_parameters, + parameters=parameters_before, template=transformed_before_template, ) transformed_after_template = self._after_template - if not is_nothing(transform_before) and not is_nothing(self._after_template): + if not is_nothing(transform_after) and not is_nothing(self._after_template): transformed_after_template = self._after_template for after_global_transform in transform_after: transformed_after_template = self._apply_global_transform( global_transform=after_global_transform, - parameters=self._after_parameters, + parameters=parameters_after, template=transformed_after_template, ) diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py index fe8f4838cb993..0d513d4b2a89e 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py @@ -906,7 +906,6 @@ def _check_changeset_available(): snapshot.match("postdelete_changeset_notfound", e.value) -@pytest.mark.skip(reason="CFNV2:Macros") @markers.aws.validated def test_autoexpand_capability_requirement(cleanups, aws_client): stack_name = f"test-stack-{short_uid()}" diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py index 1403570249c2e..ce401e102cd21 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py @@ -283,7 +283,7 @@ def test_update_stack_with_same_template_withoutchange( snapshot.match("no_change_exception", ctx.value.response) - @pytest.mark.skip(reason="CFNV2:Other") + @pytest.mark.skip(reason="CFNV2:Validation") @markers.aws.validated def test_update_stack_with_same_template_withoutchange_transformation( self, deploy_cfn_template, aws_client diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_templates.py b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_templates.py index 7ea4c1cdf922f..8a0724f49fa38 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_templates.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_templates.py @@ -17,7 +17,7 @@ ) -@pytest.mark.skip(reason="CFNV2:Other") +@pytest.mark.skip(reason="CFNV2:Provider") @markers.aws.validated @markers.snapshot.skip_snapshot_verify( paths=["$..ResourceIdentifierSummaries..ResourceIdentifiers", "$..Parameters"] diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_conditions.py b/tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_conditions.py index 736cd8d2c0fa0..21d8af81371bc 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_conditions.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_conditions.py @@ -17,7 +17,6 @@ class TestCloudFormationConditions: - @pytest.mark.skip(reason="CFNV2:DescribeStackResources") @markers.aws.validated def test_simple_condition_evaluation_deploys_resource( self, aws_client, deploy_cfn_template, cleanups @@ -44,7 +43,6 @@ def test_simple_condition_evaluation_deploys_resource( if topic_name in t["TopicArn"] ] - @pytest.mark.skip(reason="CFNV2:DescribeStackResources") @markers.aws.validated def test_simple_condition_evaluation_doesnt_deploy_resource( self, aws_client, deploy_cfn_template, cleanups @@ -407,7 +405,6 @@ def test_sub_in_conditions(self, deploy_cfn_template, aws_client): aws_client.sns.get_topic_attributes(TopicArn=topic_arn_with_suffix) assert topic_arn_with_suffix.split(":")[-1] == f"{topic_prefix}-{region}-{suffix}" - @pytest.mark.skip(reason="CFNV2:ConditionInCondition") @markers.aws.validated @pytest.mark.parametrize("env,region", [("dev", "us-west-2"), ("production", "us-east-1")]) def test_conditional_in_conditional(self, env, region, deploy_cfn_template, aws_client): diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_mappings.py b/tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_mappings.py index de1b0029fb703..a088355fd966a 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_mappings.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_mappings.py @@ -19,7 +19,6 @@ @markers.snapshot.skip_snapshot_verify class TestCloudFormationMappings: - @pytest.mark.skip(reason="CFNV2:DescribeStackResources") @markers.aws.validated def test_simple_mapping_working(self, aws_client, deploy_cfn_template): """ diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py index 563e7a76587ac..e283ca0fcefe2 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py @@ -226,7 +226,6 @@ def test_cfn_with_apigateway_resources(deploy_cfn_template, aws_client, snapshot # assert not apis -@pytest.mark.skip(reason="CFNV2:Other NotFoundException Invalid Method identifier specified") @markers.aws.validated @markers.snapshot.skip_snapshot_verify( paths=[ diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_dynamodb.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_dynamodb.py index ed2e5fb25196d..4a0b900772ef6 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_dynamodb.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_dynamodb.py @@ -149,7 +149,6 @@ def test_global_table(deploy_cfn_template, snapshot, aws_client): assert "ResourceNotFoundException" == error_code -@pytest.mark.skip(reason="CFNV2:Other") @markers.aws.validated def test_ttl_cdk(aws_client, snapshot, infrastructure_setup): infra = infrastructure_setup(namespace="DDBTableTTL") @@ -195,7 +194,6 @@ def test_table_with_ttl_and_sse(deploy_cfn_template, snapshot, aws_client): snapshot.match("table_description", response) -@pytest.mark.skip(reason="CFNV2:Other") @markers.aws.validated # We return the fields bellow, while AWS doesn't return them @markers.snapshot.skip_snapshot_verify( diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ec2.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ec2.py index e4e3690642f06..a31bf40d39240 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ec2.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ec2.py @@ -128,7 +128,7 @@ def test_cfn_with_multiple_route_table_associations(deploy_cfn_template, aws_cli snapshot.add_transformer(snapshot.transform.key_value("VpcId")) -@pytest.mark.skip(reason="CFNV2:Other") +@pytest.mark.skip(reason="CFNV2:Describe") @markers.aws.validated @markers.snapshot.skip_snapshot_verify(paths=["$..DriftInformation", "$..Metadata"]) def test_internet_gateway_ref_and_attr(deploy_cfn_template, snapshot, aws_client): diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_events.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_events.py index 77a2bdeb9dcc1..59f63ff949f12 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_events.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_events.py @@ -50,7 +50,7 @@ def _assert(expected_len): _assert(0) -@pytest.mark.skip(reason="CFNV2:Other") +@pytest.mark.skip(reason="CFNV2:Describe") @markers.aws.validated def test_eventbus_policies(deploy_cfn_template, aws_client): event_bus_name = f"event-bus-{short_uid()}" diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_firehose.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_firehose.py index 11d8dd5e61fb9..bf3d5a79f2931 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_firehose.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_firehose.py @@ -14,7 +14,6 @@ ) -@pytest.mark.skip(reason="CFNV2:Other") @markers.aws.validated @markers.snapshot.skip_snapshot_verify(paths=["$..Destinations"]) def test_firehose_stack_with_kinesis_as_source(deploy_cfn_template, snapshot, aws_client): diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_kinesis.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_kinesis.py index 63a9417ab8873..6cf7220a835c3 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_kinesis.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_kinesis.py @@ -16,7 +16,6 @@ ) -@pytest.mark.skip(reason="CFNV2:DescribeStacks") @markers.aws.validated @markers.snapshot.skip_snapshot_verify(paths=["$..StreamDescription.StreamModeDetails"]) def test_stream_creation(deploy_cfn_template, snapshot, aws_client): diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py index 46b01456d42e2..67f11739b6e46 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py @@ -157,7 +157,7 @@ def test_update_lambda_function_name(s3_create_bucket, deploy_cfn_template, aws_ aws_client.lambda_.get_function(FunctionName=function_name_2) -@pytest.mark.skip(reason="CFNV2:Other") +@pytest.mark.skip(reason="CFNV2:Describe") @markers.snapshot.skip_snapshot_verify( paths=[ "$..Metadata", @@ -275,7 +275,6 @@ def test_lambda_alias(deploy_cfn_template, snapshot, aws_client): snapshot.match("provisioned_concurrency_config", provisioned_concurrency_config) -@pytest.mark.skip(reason="CFNV2:Other") @markers.aws.validated def test_lambda_logging_config(deploy_cfn_template, snapshot, aws_client): function_name = f"function{short_uid()}" @@ -308,7 +307,6 @@ def test_lambda_logging_config(deploy_cfn_template, snapshot, aws_client): snapshot.match("logging_config", logging_config) -@pytest.mark.skip(reason="CFNV2:Other") @pytest.mark.skipif( not in_default_partition(), reason="Test not applicable in non-default partitions" ) @@ -356,7 +354,6 @@ def test_event_invoke_config(deploy_cfn_template, snapshot, aws_client): snapshot.match("event_invoke_config", event_invoke_config) -@pytest.mark.skip(reason="CFNV2:Other") @markers.snapshot.skip_snapshot_verify( paths=[ # Lambda ZIP flaky in CI @@ -401,7 +398,6 @@ def test_lambda_version(deploy_cfn_template, snapshot, aws_client): snapshot.match("get_function_version", get_function_version) -@pytest.mark.skip(reason="CFNV2:Other") @markers.snapshot.skip_snapshot_verify( paths=[ # Lambda ZIP flaky in CI @@ -630,7 +626,6 @@ def test_multiple_lambda_permissions_for_singlefn(deploy_cfn_template, snapshot, snapshot.match("policy", policy) -@pytest.mark.skip(reason="CFNV2:Other") @markers.aws.validated @markers.snapshot.skip_snapshot_verify( paths=[ @@ -666,7 +661,6 @@ def test_lambda_function_tags(deploy_cfn_template, aws_client, snapshot): class TestCfnLambdaIntegrations: - @pytest.mark.skip(reason="CFNV2:Other") @markers.snapshot.skip_snapshot_verify( paths=[ "$..Attributes.EffectiveDeliveryPolicy", # broken in sns right now. needs to be wrapped within an http key @@ -857,7 +851,6 @@ def wait_logs(): with pytest.raises(aws_client.lambda_.exceptions.ResourceNotFoundException): aws_client.lambda_.get_event_source_mapping(UUID=esm_id) - @pytest.mark.skip(reason="CFNV2:Other") # TODO: consider moving into the dedicated DynamoDB => Lambda tests because it tests the filtering functionality rather than CloudFormation (just using CF to deploy resources) # tests.aws.services.lambda_.test_lambda_integration_dynamodbstreams.TestDynamoDBEventSourceMapping.test_dynamodb_event_filter @markers.aws.validated @@ -895,7 +888,7 @@ def _send_events(): sleep = 10 if os.getenv("TEST_TARGET") == "AWS_CLOUD" else 1 assert wait_until(_send_events, wait=sleep, max_retries=50) - @pytest.mark.skip(reason="CFNV2:Other") + @pytest.mark.skip(reason="CFNV2:Describe") @markers.snapshot.skip_snapshot_verify( paths=[ # Lambda @@ -1033,7 +1026,7 @@ def wait_logs(): with pytest.raises(aws_client.lambda_.exceptions.ResourceNotFoundException): aws_client.lambda_.get_event_source_mapping(UUID=esm_id) - @pytest.mark.skip(reason="CFNV2:Other") + @pytest.mark.skip(reason="CFNV2:Describe") @markers.snapshot.skip_snapshot_verify( paths=[ "$..Role.Description", @@ -1319,7 +1312,6 @@ def test_python_lambda_code_deployed_via_s3(deploy_cfn_template, aws_client, s3_ assert invocation_result["StatusCode"] == 200 -@pytest.mark.skip(reason="CFNV2:Other") @markers.aws.validated def test_lambda_cfn_dead_letter_config_async_invocation( deploy_cfn_template, aws_client, s3_create_bucket, snapshot diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_s3.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_s3.py index 79ea1ba69ebd7..da1be1a4a16d2 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_s3.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_s3.py @@ -130,7 +130,6 @@ def test_object_lock_configuration(deploy_cfn_template, snapshot, aws_client): snapshot.match("object-lock-info-only-enabled", cors_info) -@pytest.mark.skip(reason="CFNV2:Other") @markers.aws.validated def test_cfn_handle_s3_notification_configuration( aws_client, diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sam.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sam.py index 457334ad1c756..6c039975b679e 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sam.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sam.py @@ -16,7 +16,6 @@ ) -@pytest.mark.skip(reason="CFNV2:Other") @markers.aws.validated def test_sam_policies(deploy_cfn_template, snapshot, aws_client): snapshot.add_transformer(snapshot.transform.cloudformation_api()) diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sns.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sns.py index 0f60128cddb73..865248c9b80dd 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sns.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sns.py @@ -141,7 +141,6 @@ def test_update_subscription(snapshot, deploy_cfn_template, aws_client, sqs_queu snapshot.add_transformer(snapshot.transform.cloudformation_api()) -@pytest.mark.skip(reason="CFNV2:Other") @markers.aws.validated def test_sns_topic_with_attributes(infrastructure_setup, aws_client, snapshot): infra = infrastructure_setup(namespace="SnsTests") diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ssm.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ssm.py index 49effcdd8647e..1d9922d481668 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ssm.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ssm.py @@ -144,7 +144,6 @@ def test_deploy_patch_baseline(deploy_cfn_template, aws_client, snapshot): snapshot.match("patch_baseline", describe_resource) -@pytest.mark.skip(reason="CFNV2:Other") @markers.aws.validated def test_maintenance_window(deploy_cfn_template, aws_client, snapshot): stack = deploy_cfn_template( diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_stepfunctions.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_stepfunctions.py index 034b8fce1bd9c..8bb3c96039211 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_stepfunctions.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_stepfunctions.py @@ -81,7 +81,6 @@ def _is_executed(): assert output["Value"] == 3 -@pytest.mark.skip(reason="CFNV2:Other botocore invalid resource identifier specified") @markers.aws.needs_fixing def test_apigateway_invoke(deploy_cfn_template, aws_client): deploy_result = deploy_cfn_template( @@ -108,7 +107,6 @@ def _sfn_finished_running(): assert "hello from stepfunctions" in execution_result["output"] -@pytest.mark.skip(reason="CFNV2:Other botocore invalid resource identifier specified") @markers.aws.validated def test_apigateway_invoke_with_path(deploy_cfn_template, aws_client): deploy_result = deploy_cfn_template( @@ -136,7 +134,6 @@ def _sfn_finished_running(): assert "hello_with_path from stepfunctions" in execution_result["output"] -@pytest.mark.skip(reason="CFNV2:Other botocore invalid resource identifier specified") @markers.aws.only_localstack def test_apigateway_invoke_localhost(deploy_cfn_template, aws_client): """tests the same as above but with the "generic" localhost version of invoking the apigateway""" @@ -182,7 +179,6 @@ def _sfn_finished_running(): assert "hello from stepfunctions" in execution_result["output"] -@pytest.mark.skip(reason="CFNV2:Other botocore invalid resource identifier specified") @markers.aws.only_localstack def test_apigateway_invoke_localhost_with_path(deploy_cfn_template, aws_client): """tests the same as above but with the "generic" localhost version of invoking the apigateway""" diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py b/tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py index 99b519236ea18..7ab6b8ec37c18 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py @@ -611,7 +611,6 @@ def test_import_values_across_stacks(self, deploy_cfn_template, aws_client): # assert cfn_client.list_imports(ExportName=export_name)["Imports"] -@pytest.mark.skip(reason="CFNV2:Macros unsupported") class TestMacros: @markers.aws.validated def test_macro_deployment( @@ -645,6 +644,7 @@ def test_macro_deployment( snapshot.match("stack_outputs", stack_with_macro.outputs) snapshot.match("stack_resource_descriptions", description) + @pytest.mark.skip(reason="CFNV2:Provider create_stack not ported") @markers.aws.validated @markers.snapshot.skip_snapshot_verify( paths=[ @@ -705,6 +705,9 @@ def test_global_scope( snapshot.add_transformer(snapshot.transform.regex(new_value, "new-value")) snapshot.match("processed_template", processed_template) + @pytest.mark.skip( + reason="CFNV2:Fn::Transform as resource property with missing Name and Parameters fields." + ) @markers.aws.validated @pytest.mark.parametrize( "template_to_transform", @@ -841,6 +844,7 @@ def test_scope_order_and_parameters( ) snapshot.match("processed_template", processed_template) + @pytest.mark.skip(reason="CFNV2:Validation") @markers.aws.validated @markers.snapshot.skip_snapshot_verify( paths=[ @@ -910,6 +914,7 @@ def test_capabilities_requirements( snapshot.add_transformer(snapshot.transform.key_value("RoleName", "role-name")) snapshot.match("processed_template", processed_template) + @pytest.mark.skip(reason="CFNV2:Provider create_stack not ported") @markers.aws.validated @markers.snapshot.skip_snapshot_verify( paths=[ @@ -1045,12 +1050,13 @@ def test_error_pass_macro_as_reference(self, snapshot, aws_client): ) snapshot.match("error", ex.value.response) + @pytest.mark.skip(reason="CFNV2:Provider create_stack not ported") @markers.aws.validated def test_functions_and_references_during_transformation( self, deploy_cfn_template, create_lambda_function, snapshot, cleanups, aws_client ): """ - This tests shows the state of instrinsic functions during the execution of the macro + This tests shows the state of intrinsic functions during the execution of the macro """ macro_function_path = os.path.join( os.path.dirname(__file__), "../../../../templates/macros/print_references.py" @@ -1095,6 +1101,7 @@ def test_functions_and_references_during_transformation( processed_template["TemplateBody"]["Resources"]["Parameter"]["Properties"]["Value"], ) + @pytest.mark.skip(reason="CFNV2:Validation") @pytest.mark.parametrize( "macro_function", [ diff --git a/tests/aws/services/cloudformation/v2/test_change_set_global_macros.py b/tests/aws/services/cloudformation/v2/test_change_set_global_macros.py new file mode 100644 index 0000000000000..c557cc1ad6334 --- /dev/null +++ b/tests/aws/services/cloudformation/v2/test_change_set_global_macros.py @@ -0,0 +1,101 @@ +import os + +import pytest +from localstack_snapshot.snapshots.transformer import JsonpathTransformer + +from localstack.aws.api.lambda_ import Runtime +from localstack.services.cloudformation.v2.utils import is_v2_engine +from localstack.testing.aws.util import is_aws_cloud +from localstack.testing.pytest import markers +from localstack.utils.strings import short_uid + + +@pytest.mark.skipif( + condition=not is_v2_engine() and not is_aws_cloud(), reason="Requires the V2 engine" +) +@markers.snapshot.skip_snapshot_verify( + paths=[ + "per-resource-events..*", + "delete-describe..*", + # + # Before/After Context + "$..Capabilities", + "$..NotificationARNs", + "$..IncludeNestedStacks", + "$..Scope", + "$..Details", + "$..Parameters", + "$..Replacement", + "$..PolicyAction", + ] +) +class TestChangeSetGlobalMacros: + @markers.aws.validated + @pytest.mark.skip( + reason="CFNV2:Other deletion of CFN macro is received before the template update event" + ) + def test_base_global_macro( + self, + aws_client, + cleanups, + snapshot, + deploy_cfn_template, + create_lambda_function, + capture_update_process, + ): + snapshot.add_transformer( + JsonpathTransformer( + jsonpath="$..Outputs..OutputValue", + replacement="output-value", + replace_reference=True, + ) + ) + macro_function_path = os.path.join( + os.path.dirname(__file__), "../../../templates/macros/format_template.py" + ) + macro_name = "SubstitutionMacro" + func_name = f"test_lambda_{short_uid()}" + create_lambda_function( + func_name=func_name, + handler_file=macro_function_path, + runtime=Runtime.python3_12, + client=aws_client.lambda_, + timeout=1, + ) + deploy_cfn_template( + template_path=os.path.join( + os.path.dirname(__file__), "../../../templates/macro_resource.yml" + ), + parameters={"FunctionName": func_name, "MacroName": macro_name}, + ) + + template_1 = { + "Transform": "SubstitutionMacro", + "Parameters": {"Substitution": {"Type": "String", "Default": "SubstitutionDefault"}}, + "Resources": { + "Parameter": { + "Type": "AWS::SSM::Parameter", + "Properties": {"Value": "{Substitution}", "Type": "String"}, + } + }, + "Outputs": {"ParameterName": {"Value": {"Ref": "Parameter"}}}, + } + template_2 = { + "Transform": "SubstitutionMacro", + "Parameters": {"Substitution": {"Type": "String", "Default": "SubstitutionDefault"}}, + "Resources": { + "Parameter": { + "Type": "AWS::SSM::Parameter", + "Properties": {"Value": "{Substitution}", "Type": "String"}, + }, + "Parameter2": { + "Type": "AWS::SSM::Parameter", + "Properties": {"Value": "{Substitution}", "Type": "String"}, + }, + }, + "Outputs": { + "ParameterName": {"Value": {"Ref": "Parameter"}}, + "Parameter2Name": {"Value": {"Ref": "Parameter2"}}, + }, + } + capture_update_process(snapshot, template_1, template_2) diff --git a/tests/aws/services/cloudformation/v2/test_change_set_global_macros.snapshot.json b/tests/aws/services/cloudformation/v2/test_change_set_global_macros.snapshot.json new file mode 100644 index 0000000000000..a89dd887a9621 --- /dev/null +++ b/tests/aws/services/cloudformation/v2/test_change_set_global_macros.snapshot.json @@ -0,0 +1,435 @@ +{ + "tests/aws/services/cloudformation/v2/test_change_set_global_macros.py::TestChangeSetGlobalMacros::test_base_global_macro": { + "recorded-date": "16-06-2025, 09:52:28", + "recorded-content": { + "create-change-set-1": { + "Id": "arn::cloudformation::111111111111:changeSet/", + "StackId": "arn::cloudformation::111111111111:stack//", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-change-set-1-prop-values": { + "Capabilities": [], + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "ChangeSetName": "", + "Changes": [ + { + "ResourceChange": { + "Action": "Add", + "AfterContext": { + "Properties": { + "Value": "SubstitutionDefault", + "Type": "String" + } + }, + "Details": [], + "LogicalResourceId": "Parameter", + "ResourceType": "AWS::SSM::Parameter", + "Scope": [] + }, + "Type": "Resource" + } + ], + "CreationTime": "datetime", + "ExecutionStatus": "AVAILABLE", + "IncludeNestedStacks": false, + "NotificationARNs": [], + "Parameters": [ + { + "ParameterKey": "Substitution", + "ParameterValue": "SubstitutionDefault" + } + ], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Status": "CREATE_COMPLETE", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-change-set-1": { + "Capabilities": [], + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "ChangeSetName": "", + "Changes": [ + { + "ResourceChange": { + "Action": "Add", + "Details": [], + "LogicalResourceId": "Parameter", + "ResourceType": "AWS::SSM::Parameter", + "Scope": [] + }, + "Type": "Resource" + } + ], + "CreationTime": "datetime", + "ExecutionStatus": "AVAILABLE", + "IncludeNestedStacks": false, + "NotificationARNs": [], + "Parameters": [ + { + "ParameterKey": "Substitution", + "ParameterValue": "SubstitutionDefault" + } + ], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Status": "CREATE_COMPLETE", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "execute-change-set-1": { + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "post-create-1-describe": { + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "CreationTime": "datetime", + "DisableRollback": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + }, + "EnableTerminationProtection": false, + "LastUpdatedTime": "datetime", + "NotificationARNs": [], + "Outputs": [ + { + "OutputKey": "ParameterName", + "OutputValue": "" + } + ], + "Parameters": [ + { + "ParameterKey": "Substitution", + "ParameterValue": "SubstitutionDefault" + } + ], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "StackStatus": "CREATE_COMPLETE", + "Tags": [] + }, + "create-change-set-2": { + "Id": "arn::cloudformation::111111111111:changeSet/", + "StackId": "arn::cloudformation::111111111111:stack//", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-change-set-2-prop-values": { + "Capabilities": [], + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "ChangeSetName": "", + "Changes": [ + { + "ResourceChange": { + "Action": "Add", + "AfterContext": { + "Properties": { + "Value": "SubstitutionDefault", + "Type": "String" + } + }, + "Details": [], + "LogicalResourceId": "Parameter2", + "ResourceType": "AWS::SSM::Parameter", + "Scope": [] + }, + "Type": "Resource" + } + ], + "CreationTime": "datetime", + "ExecutionStatus": "AVAILABLE", + "IncludeNestedStacks": false, + "NotificationARNs": [], + "Parameters": [ + { + "ParameterKey": "Substitution", + "ParameterValue": "SubstitutionDefault" + } + ], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Status": "CREATE_COMPLETE", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-change-set-2": { + "Capabilities": [], + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "ChangeSetName": "", + "Changes": [ + { + "ResourceChange": { + "Action": "Add", + "Details": [], + "LogicalResourceId": "Parameter2", + "ResourceType": "AWS::SSM::Parameter", + "Scope": [] + }, + "Type": "Resource" + } + ], + "CreationTime": "datetime", + "ExecutionStatus": "AVAILABLE", + "IncludeNestedStacks": false, + "NotificationARNs": [], + "Parameters": [ + { + "ParameterKey": "Substitution", + "ParameterValue": "SubstitutionDefault" + } + ], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Status": "CREATE_COMPLETE", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "execute-change-set-2": { + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "post-create-2-describe": { + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "CreationTime": "datetime", + "DisableRollback": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + }, + "EnableTerminationProtection": false, + "LastUpdatedTime": "datetime", + "NotificationARNs": [], + "Outputs": [ + { + "OutputKey": "ParameterName", + "OutputValue": "" + }, + { + "OutputKey": "Parameter2Name", + "OutputValue": "" + } + ], + "Parameters": [ + { + "ParameterKey": "Substitution", + "ParameterValue": "SubstitutionDefault" + } + ], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "StackStatus": "UPDATE_COMPLETE", + "Tags": [] + }, + "per-resource-events": { + "Parameter": [ + { + "EventId": "Parameter-CREATE_COMPLETE-date", + "LogicalResourceId": "Parameter", + "PhysicalResourceId": "", + "ResourceProperties": { + "Type": "String", + "Value": "SubstitutionDefault" + }, + "ResourceStatus": "CREATE_COMPLETE", + "ResourceType": "AWS::SSM::Parameter", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Parameter-CREATE_IN_PROGRESS-date", + "LogicalResourceId": "Parameter", + "PhysicalResourceId": "", + "ResourceProperties": { + "Type": "String", + "Value": "SubstitutionDefault" + }, + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatusReason": "Resource creation Initiated", + "ResourceType": "AWS::SSM::Parameter", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Parameter-CREATE_IN_PROGRESS-date", + "LogicalResourceId": "Parameter", + "PhysicalResourceId": "", + "ResourceProperties": { + "Type": "String", + "Value": "SubstitutionDefault" + }, + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceType": "AWS::SSM::Parameter", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + } + ], + "Parameter2": [ + { + "EventId": "Parameter2-CREATE_COMPLETE-date", + "LogicalResourceId": "Parameter2", + "PhysicalResourceId": "", + "ResourceProperties": { + "Type": "String", + "Value": "SubstitutionDefault" + }, + "ResourceStatus": "CREATE_COMPLETE", + "ResourceType": "AWS::SSM::Parameter", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Parameter2-CREATE_IN_PROGRESS-date", + "LogicalResourceId": "Parameter2", + "PhysicalResourceId": "", + "ResourceProperties": { + "Type": "String", + "Value": "SubstitutionDefault" + }, + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatusReason": "Resource creation Initiated", + "ResourceType": "AWS::SSM::Parameter", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "Parameter2-CREATE_IN_PROGRESS-date", + "LogicalResourceId": "Parameter2", + "PhysicalResourceId": "", + "ResourceProperties": { + "Type": "String", + "Value": "SubstitutionDefault" + }, + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceType": "AWS::SSM::Parameter", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + } + ], + "": [ + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "UPDATE_COMPLETE", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "UPDATE_IN_PROGRESS", + "ResourceStatusReason": "User Initiated", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "CREATE_COMPLETE", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceStatusReason": "User Initiated", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + }, + { + "EventId": "", + "LogicalResourceId": "", + "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", + "ResourceStatus": "REVIEW_IN_PROGRESS", + "ResourceStatusReason": "User Initiated", + "ResourceType": "AWS::CloudFormation::Stack", + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Timestamp": "timestamp" + } + ] + }, + "delete-describe": { + "CreationTime": "datetime", + "DeletionTime": "datetime", + "DisableRollback": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + }, + "LastUpdatedTime": "datetime", + "NotificationARNs": [], + "Outputs": [ + { + "OutputKey": "ParameterName", + "OutputValue": "" + }, + { + "OutputKey": "Parameter2Name", + "OutputValue": "" + } + ], + "Parameters": [ + { + "ParameterKey": "Substitution", + "ParameterValue": "SubstitutionDefault" + } + ], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "StackStatus": "DELETE_COMPLETE", + "Tags": [] + } + } + } +} diff --git a/tests/aws/services/cloudformation/v2/test_change_set_global_macros.validation.json b/tests/aws/services/cloudformation/v2/test_change_set_global_macros.validation.json new file mode 100644 index 0000000000000..4580e6cbeb1cb --- /dev/null +++ b/tests/aws/services/cloudformation/v2/test_change_set_global_macros.validation.json @@ -0,0 +1,11 @@ +{ + "tests/aws/services/cloudformation/v2/test_change_set_global_macros.py::TestChangeSetGlobalMacros::test_base_global_macro": { + "last_validated_date": "2025-06-16T09:52:29+00:00", + "durations_in_seconds": { + "setup": 12.19, + "call": 37.41, + "teardown": 5.9, + "total": 55.5 + } + } +} diff --git a/tests/aws/services/cloudformation/v2/test_change_set_ref.py b/tests/aws/services/cloudformation/v2/test_change_set_ref.py index b743070ebbfad..3785e861094f2 100644 --- a/tests/aws/services/cloudformation/v2/test_change_set_ref.py +++ b/tests/aws/services/cloudformation/v2/test_change_set_ref.py @@ -243,7 +243,6 @@ def test_direct_attribute_value_change_with_dependent_addition( } capture_update_process(snapshot, template_1, template_2) - # @pytest.mark.skip(reason="") @markers.snapshot.skip_snapshot_verify( paths=[ # Reason: preproc is not able to resolve references to deployed resources' physical id From 18a4b6c908b3fff920fce0bf5b850c5a8d64bd6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristopher=20Pinz=C3=B3n?= <18080804+pinzon@users.noreply.github.com> Date: Thu, 19 Jun 2025 16:29:59 -0500 Subject: [PATCH 44/74] add resource events to CFn v2 (#12721) Co-authored-by: Simon Walker --- .../engine/v2/change_set_model_executor.py | 170 +- .../services/cloudformation/v2/entities.py | 46 +- .../services/cloudformation/v2/provider.py | 9 +- .../testing/pytest/cloudformation/fixtures.py | 77 +- .../cloudformation/v2/test_change_sets.py | 1 - .../v2/test_change_sets.snapshot.json | 1662 ++++------------- .../v2/test_change_sets.validation.json | 80 +- 7 files changed, 639 insertions(+), 1406 deletions(-) diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py index 96c936a3cf037..ff0485df2cf46 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py @@ -36,6 +36,8 @@ LOG = logging.getLogger(__name__) +EventOperationFromAction = {"Add": "CREATE", "Modify": "UPDATE", "Remove": "DELETE"} + @dataclass class ChangeSetModelExecutorResult: @@ -86,6 +88,50 @@ def visit_node_parameter(self, node_parameter: NodeParameter) -> PreprocEntityDe self.resolved_parameters[node_parameter.name] = delta.after return delta + def _get_physical_id(self, logical_resource_id, strict: bool = True) -> str | None: + physical_resource_id = None + try: + physical_resource_id = self._after_resource_physical_id(logical_resource_id) + except RuntimeError: + # The physical id is missing or is set to None, which is invalid. + pass + if physical_resource_id is None: + # The physical resource id is None after an update that didn't rewrite the resource, the previous + # resource id is therefore the current physical id of this resource. + + try: + physical_resource_id = self._before_resource_physical_id(logical_resource_id) + except RuntimeError as e: + if strict: + raise e + return physical_resource_id + + def _process_event( + self, + action: ChangeAction, + logical_resource_id, + event_status: OperationStatus, + special_action: str = None, + reason: str = None, + resource_type=None, + ): + status_from_action = special_action or EventOperationFromAction[action.value] + if event_status == OperationStatus.SUCCESS: + status = f"{status_from_action}_COMPLETE" + else: + status = f"{status_from_action}_{event_status.name}" + + self._change_set.stack.set_resource_status( + logical_resource_id=logical_resource_id, + physical_resource_id=self._get_physical_id(logical_resource_id, False), + resource_type=resource_type, + status=ResourceStatus(status), + resource_status_reason=reason, + ) + + if event_status == OperationStatus.FAILED: + self._change_set.stack.set_stack_status(StackStatus(status)) + def _after_deployed_property_value_of( self, resource_logical_id: str, property_name: str ) -> str: @@ -173,20 +219,29 @@ def _execute_resource_change( # XXX hacky, stick the previous resources' properties into the payload before_properties = self._merge_before_properties(name, before) - self._execute_resource_action( + self._process_event(ChangeAction.Modify, name, OperationStatus.IN_PROGRESS) + event = self._execute_resource_action( action=ChangeAction.Modify, logical_resource_id=name, resource_type=before.resource_type, before_properties=before_properties, after_properties=after.properties, ) + self._process_event( + ChangeAction.Modify, + name, + event.status, + reason=event.message, + resource_type=before.resource_type, + ) # Case: type migration. # TODO: Add test to assert that on type change the resources are replaced. else: # XXX hacky, stick the previous resources' properties into the payload before_properties = self._merge_before_properties(name, before) # Register a Removed for the previous type. - self._execute_resource_action( + + event = self._execute_resource_action( action=ChangeAction.Remove, logical_resource_id=name, resource_type=before.resource_type, @@ -194,35 +249,74 @@ def _execute_resource_change( after_properties=None, ) # Register a Create for the next type. - self._execute_resource_action( + self._process_event( + ChangeAction.Modify, + name, + event.status, + reason=event.message, + resource_type=before.resource_type, + ) + event = self._execute_resource_action( action=ChangeAction.Add, logical_resource_id=name, resource_type=after.resource_type, before_properties=None, after_properties=after.properties, ) + self._process_event( + ChangeAction.Modify, + name, + event.status, + reason=event.message, + resource_type=before.resource_type, + ) elif not is_nothing(before): # Case: removal # XXX hacky, stick the previous resources' properties into the payload # XXX hacky, stick the previous resources' properties into the payload before_properties = self._merge_before_properties(name, before) - - self._execute_resource_action( + self._process_event( + ChangeAction.Remove, + name, + OperationStatus.IN_PROGRESS, + resource_type=before.resource_type, + ) + event = self._execute_resource_action( action=ChangeAction.Remove, logical_resource_id=name, resource_type=before.resource_type, before_properties=before_properties, after_properties=None, ) + self._process_event( + ChangeAction.Remove, + name, + event.status, + reason=event.message, + resource_type=before.resource_type, + ) elif not is_nothing(after): # Case: addition - self._execute_resource_action( + self._process_event( + ChangeAction.Add, + name, + OperationStatus.IN_PROGRESS, + resource_type=after.resource_type, + ) + event = self._execute_resource_action( action=ChangeAction.Add, logical_resource_id=name, resource_type=after.resource_type, before_properties=None, after_properties=after.properties, ) + self._process_event( + ChangeAction.Add, + name, + event.status, + reason=event.message, + resource_type=after.resource_type, + ) def _merge_before_properties( self, name: str, preproc_resource: PreprocResource @@ -242,7 +336,7 @@ def _execute_resource_action( resource_type: str, before_properties: Optional[PreprocProperties], after_properties: Optional[PreprocProperties], - ) -> None: + ) -> ProgressEvent: LOG.debug("Executing resource action: %s for resource '%s'", action, logical_resource_id) resource_provider_executor = ResourceProviderExecutor( stack_name=self._change_set.stack.stack_name, stack_id=self._change_set.stack.stack_id @@ -272,16 +366,6 @@ def _execute_resource_action( exc_info=LOG.isEnabledFor(logging.DEBUG), ) stack = self._change_set.stack - match stack.status: - case StackStatus.CREATE_IN_PROGRESS: - stack.set_stack_status(StackStatus.CREATE_FAILED, reason=reason) - case StackStatus.UPDATE_IN_PROGRESS: - stack.set_stack_status(StackStatus.UPDATE_FAILED, reason=reason) - case StackStatus.DELETE_IN_PROGRESS: - stack.set_stack_status(StackStatus.DELETE_FAILED, reason=reason) - case _: - raise NotImplementedError(f"Unexpected stack status: {stack.status}") - # update resource status stack.set_resource_status( logical_resource_id=logical_resource_id, # TODO, @@ -292,7 +376,11 @@ def _execute_resource_action( else ResourceStatus.UPDATE_FAILED, resource_status_reason=reason, ) - return + event = ProgressEvent( + OperationStatus.FAILED, + resource_model={}, + message=f"Resource provider operation failed: {reason}", + ) self.resources.setdefault(logical_resource_id, {"Properties": {}}) match event.status: @@ -313,28 +401,8 @@ def _execute_resource_action( self.resources[logical_resource_id]["LogicalResourceId"] = logical_resource_id self.resources[logical_resource_id]["Type"] = resource_type - # TODO: review why the physical id is returned as None during updates - # TODO: abstract this in member function of resource classes instead - physical_resource_id = None - try: - physical_resource_id = self._after_resource_physical_id(logical_resource_id) - except RuntimeError: - # The physical id is missing or is set to None, which is invalid. - pass - if physical_resource_id is None: - # The physical resource id is None after an update that didn't rewrite the resource, the previous - # resource id is therefore the current physical id of this resource. - physical_resource_id = self._before_resource_physical_id(logical_resource_id) - self.resources[logical_resource_id]["PhysicalResourceId"] = physical_resource_id - - self._change_set.stack.set_resource_status( - logical_resource_id=logical_resource_id, - physical_resource_id=physical_resource_id, - resource_type=resource_type, - status=ResourceStatus.CREATE_COMPLETE - if action == ChangeAction.Add - else ResourceStatus.UPDATE_COMPLETE, - ) + physical_resource_id = self._get_physical_id(logical_resource_id) + self.resources[logical_resource_id]["PhysicalResourceId"] = physical_resource_id case OperationStatus.FAILED: reason = event.message @@ -342,29 +410,9 @@ def _execute_resource_action( "Resource provider operation failed: '%s'", reason, ) - # TODO: duplication - stack = self._change_set.stack - match stack.status: - case StackStatus.CREATE_IN_PROGRESS: - stack.set_stack_status(StackStatus.CREATE_FAILED, reason=reason) - case StackStatus.UPDATE_IN_PROGRESS: - stack.set_stack_status(StackStatus.UPDATE_FAILED, reason=reason) - case StackStatus.DELETE_IN_PROGRESS: - stack.set_stack_status(StackStatus.DELETE_FAILED, reason=reason) - case _: - raise NotImplementedError(f"Unhandled stack status: '{stack.status}'") - stack.set_resource_status( - logical_resource_id=logical_resource_id, - # TODO - physical_resource_id="", - resource_type=resource_type, - status=ResourceStatus.CREATE_FAILED - if action == ChangeAction.Add - else ResourceStatus.UPDATE_FAILED, - resource_status_reason=reason, - ) case other: raise NotImplementedError(f"Event status '{other}' not handled") + return event def create_resource_provider_payload( self, diff --git a/localstack-core/localstack/services/cloudformation/v2/entities.py b/localstack-core/localstack/services/cloudformation/v2/entities.py index 111a29a6dfa37..b0d12706c89a2 100644 --- a/localstack-core/localstack/services/cloudformation/v2/entities.py +++ b/localstack-core/localstack/services/cloudformation/v2/entities.py @@ -11,6 +11,7 @@ ResourceStatus, StackDriftInformation, StackDriftStatus, + StackEvent, StackResource, StackStatus, StackStatusReason, @@ -26,7 +27,7 @@ NodeTemplate, ) from localstack.utils.aws import arns -from localstack.utils.strings import short_uid +from localstack.utils.strings import long_uid, short_uid class ResolvedResource(TypedDict): @@ -43,6 +44,7 @@ class Stack: stack_id: str creation_time: datetime deletion_time: datetime | None + events = list[StackEvent] # state after deploy resolved_parameters: dict[str, str] @@ -89,12 +91,15 @@ def __init__( self.resolved_resources = {} self.resolved_outputs = {} self.resource_states = {} + self.events = [] def set_stack_status(self, status: StackStatus, reason: StackStatusReason | None = None): self.status = status if reason: self.status_reason = reason + self._store_event(self.stack_name, self.stack_id, status.value, status_reason=reason) + def set_resource_status( self, *, @@ -104,7 +109,7 @@ def set_resource_status( status: ResourceStatus, resource_status_reason: str | None = None, ): - self.resource_states[logical_resource_id] = StackResource( + resource_description = StackResource( StackName=self.stack_name, StackId=self.stack_id, LogicalResourceId=logical_resource_id, @@ -115,6 +120,43 @@ def set_resource_status( ResourceStatusReason=resource_status_reason, ) + if not resource_status_reason: + resource_description.pop("ResourceStatusReason") + + self.resource_states[logical_resource_id] = resource_description + self._store_event(logical_resource_id, physical_resource_id, status, resource_status_reason) + + def _store_event( + self, + resource_id: str = None, + physical_res_id: str = None, + status: str = "", + status_reason: str = "", + ): + resource_id = resource_id + physical_res_id = physical_res_id + resource_type = ( + self.template.get("Resources", {}) + .get(resource_id, {}) + .get("Type", "AWS::CloudFormation::Stack") + ) + + event: StackEvent = { + "EventId": long_uid(), + "Timestamp": datetime.now(tz=timezone.utc), + "StackId": self.stack_id, + "StackName": self.stack_name, + "LogicalResourceId": resource_id, + "PhysicalResourceId": physical_res_id, + "ResourceStatus": status, + "ResourceType": resource_type, + } + + if status_reason: + event["ResourceStatusReason"] = status_reason + + self.events.insert(0, event) + def describe_details(self) -> ApiStack: result = { "ChangeSetId": self.change_set_id, diff --git a/localstack-core/localstack/services/cloudformation/v2/provider.py b/localstack-core/localstack/services/cloudformation/v2/provider.py index 4b3d06877fe94..8dfa504e0fdad 100644 --- a/localstack-core/localstack/services/cloudformation/v2/provider.py +++ b/localstack-core/localstack/services/cloudformation/v2/provider.py @@ -236,7 +236,10 @@ def create_change_set( raise ValidationError(f"Stack '{stack_name}' does not exist.") stack = active_stack_candidates[0] - stack.set_stack_status(StackStatus.REVIEW_IN_PROGRESS) + if stack.status in [StackStatus.CREATE_COMPLETE, StackStatus.UPDATE_COMPLETE]: + stack.set_stack_status(StackStatus.UPDATE_IN_PROGRESS) + else: + stack.set_stack_status(StackStatus.REVIEW_IN_PROGRESS) # TODO: test if rollback status is allowed as well if ( @@ -472,7 +475,9 @@ def describe_stack_events( next_token: NextToken = None, **kwargs, ) -> DescribeStackEventsOutput: - return DescribeStackEventsOutput(StackEvents=[]) + state = get_cloudformation_store(context.account_id, context.region) + stack = find_stack_v2(state, stack_name) + return DescribeStackEventsOutput(StackEvents=stack.events) @handler("DeleteStack") def delete_stack( diff --git a/localstack-core/localstack/testing/pytest/cloudformation/fixtures.py b/localstack-core/localstack/testing/pytest/cloudformation/fixtures.py index 99ce1673259a5..745a547f078c3 100644 --- a/localstack-core/localstack/testing/pytest/cloudformation/fixtures.py +++ b/localstack-core/localstack/testing/pytest/cloudformation/fixtures.py @@ -1,6 +1,6 @@ import json from collections import defaultdict -from typing import Callable +from typing import Callable, Optional, TypedDict import pytest @@ -9,22 +9,83 @@ from localstack.utils.functions import call_safe from localstack.utils.strings import short_uid -PerResourceStackEvents = dict[str, list[StackEvent]] + +class NormalizedEvent(TypedDict): + PhysicalResourceId: Optional[str] + LogicalResourceId: str + ResourceType: str + ResourceStatus: str + Timestamp: str + + +PerResourceStackEvents = dict[str, list[NormalizedEvent]] + + +def normalize_event(event: StackEvent) -> NormalizedEvent: + return NormalizedEvent( + PhysicalResourceId=event.get("PhysicalResourceId"), + LogicalResourceId=event.get("LogicalResourceId"), + ResourceType=event.get("ResourceType"), + ResourceStatus=event.get("ResourceStatus"), + Timestamp=event.get("Timestamp"), + ) @pytest.fixture def capture_per_resource_events( aws_client: ServiceLevelClientFactory, ) -> Callable[[str], PerResourceStackEvents]: - def capture(stack_name: str) -> PerResourceStackEvents: + def capture(stack_name: str) -> dict: events = aws_client.cloudformation.describe_stack_events(StackName=stack_name)[ "StackEvents" ] per_resource_events = defaultdict(list) for event in events: + # TODO: not supported events + if event.get("ResourceStatus") in { + "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", + "DELETE_IN_PROGRESS", + "DELETE_COMPLETE", + }: + continue + if logical_resource_id := event.get("LogicalResourceId"): - per_resource_events[logical_resource_id].append(event) - return per_resource_events + resource_name = ( + logical_resource_id + if logical_resource_id != event.get("StackName") + else "Stack" + ) + normalized_event = normalize_event(event) + per_resource_events[resource_name].append(normalized_event) + + for resource_id in per_resource_events: + per_resource_events[resource_id].sort(key=lambda event: event["Timestamp"]) + + filtered_per_resource_events = {} + for resource_id in per_resource_events: + events = [] + last: tuple[str, str, str] | None = None + + for event in per_resource_events[resource_id]: + unique_key = ( + event["LogicalResourceId"], + event["ResourceStatus"], + event["ResourceType"], + ) + if last is None: + events.append(event) + last = unique_key + continue + + if unique_key == last: + continue + + events.append(event) + last = unique_key + + filtered_per_resource_events[resource_id] = events + + return filtered_per_resource_events return capture @@ -165,9 +226,6 @@ def inner( ] snapshot.match("post-create-2-describe", describe) - events = capture_per_resource_events(stack_name) - snapshot.match("per-resource-events", events) - # delete stack aws_client_no_retry.cloudformation.delete_stack(StackName=stack_id) aws_client_no_retry.cloudformation.get_waiter("stack_delete_complete").wait( @@ -178,4 +236,7 @@ def inner( ] snapshot.match("delete-describe", describe) + events = capture_per_resource_events(stack_id) + snapshot.match("per-resource-events", events) + yield inner diff --git a/tests/aws/services/cloudformation/v2/test_change_sets.py b/tests/aws/services/cloudformation/v2/test_change_sets.py index 2bc1ebff01866..20ef3e331d59e 100644 --- a/tests/aws/services/cloudformation/v2/test_change_sets.py +++ b/tests/aws/services/cloudformation/v2/test_change_sets.py @@ -21,7 +21,6 @@ ) @markers.snapshot.skip_snapshot_verify( paths=[ - "per-resource-events..*", "delete-describe..*", # # Before/After Context diff --git a/tests/aws/services/cloudformation/v2/test_change_sets.snapshot.json b/tests/aws/services/cloudformation/v2/test_change_sets.snapshot.json index d799e38efd682..66b1117810662 100644 --- a/tests/aws/services/cloudformation/v2/test_change_sets.snapshot.json +++ b/tests/aws/services/cloudformation/v2/test_change_sets.snapshot.json @@ -95,7 +95,7 @@ } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_direct_update": { - "recorded-date": "24-04-2025, 17:00:59", + "recorded-date": "18-06-2025, 19:04:55", "recorded-content": { "create-change-set-1": { "Id": "arn::cloudformation::111111111111:changeSet/", @@ -322,195 +322,94 @@ "StackStatus": "UPDATE_COMPLETE", "Tags": [] }, + "delete-describe": { + "CreationTime": "datetime", + "DeletionTime": "datetime", + "DisableRollback": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + }, + "LastUpdatedTime": "datetime", + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "StackStatus": "DELETE_COMPLETE", + "Tags": [] + }, "per-resource-events": { "Foo": [ { - "EventId": "Foo-8fa001c0-096c-4f9e-9aed-0c31f45ded09", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceStatus": "DELETE_COMPLETE", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-57ec24a9-92bd-4f31-8d36-972323072283", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceStatus": "DELETE_IN_PROGRESS", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-UPDATE_COMPLETE-date", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-2", - "ResourceProperties": { - "TopicName": "topic-2" - }, - "ResourceStatus": "UPDATE_COMPLETE", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-UPDATE_IN_PROGRESS-date", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-2", - "ResourceProperties": { - "TopicName": "topic-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-UPDATE_IN_PROGRESS-date", "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceProperties": { - "TopicName": "topic-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "Requested update requires the creation of a new physical resource; hence creating one.", + "PhysicalResourceId": "", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Foo-CREATE_COMPLETE-date", "LogicalResourceId": "Foo", "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceProperties": { - "TopicName": "topic-1" - }, "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Foo-CREATE_IN_PROGRESS-date", "LogicalResourceId": "Foo", "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceProperties": { - "TopicName": "topic-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Foo-CREATE_IN_PROGRESS-date", "LogicalResourceId": "Foo", - "PhysicalResourceId": "", - "ResourceProperties": { - "TopicName": "topic-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", + "PhysicalResourceId": "arn::sns::111111111111:topic-2", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } ], - "": [ - { - "EventId": "", - "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE", - "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, + "Stack": [ { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", + "ResourceStatus": "REVIEW_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "REVIEW_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } ] - }, - "delete-describe": { - "CreationTime": "datetime", - "DeletionTime": "datetime", - "DisableRollback": false, - "DriftInformation": { - "StackDriftStatus": "NOT_CHECKED" - }, - "LastUpdatedTime": "datetime", - "NotificationARNs": [], - "RollbackConfiguration": {}, - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "StackStatus": "DELETE_COMPLETE", - "Tags": [] } } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_dynamic_update": { - "recorded-date": "24-04-2025, 17:02:59", + "recorded-date": "18-06-2025, 19:06:59", "recorded-content": { "create-change-set-1": { "Id": "arn::cloudformation::111111111111:changeSet/", @@ -728,7 +627,7 @@ } ], "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-b4xwNWwXL1pX", + "PhysicalResourceId": "CFN-Parameter-OkuGHMW4ltfZ", "Replacement": "False", "ResourceType": "AWS::SSM::Parameter", "Scope": [ @@ -797,7 +696,7 @@ } ], "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-b4xwNWwXL1pX", + "PhysicalResourceId": "CFN-Parameter-OkuGHMW4ltfZ", "Replacement": "False", "ResourceType": "AWS::SSM::Parameter", "Scope": [ @@ -842,268 +741,124 @@ "StackStatus": "UPDATE_COMPLETE", "Tags": [] }, + "delete-describe": { + "CreationTime": "datetime", + "DeletionTime": "datetime", + "DisableRollback": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + }, + "LastUpdatedTime": "datetime", + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "StackStatus": "DELETE_COMPLETE", + "Tags": [] + }, "per-resource-events": { "Foo": [ { - "EventId": "Foo-33c3e9d2-d059-45a8-a51e-33eaf1f08abc", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceStatus": "DELETE_COMPLETE", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-5160f677-0c84-41ba-ab19-45a474a4b7bf", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceStatus": "DELETE_IN_PROGRESS", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-UPDATE_COMPLETE-date", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-2", - "ResourceProperties": { - "TopicName": "topic-2" - }, - "ResourceStatus": "UPDATE_COMPLETE", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-UPDATE_IN_PROGRESS-date", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-2", - "ResourceProperties": { - "TopicName": "topic-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-UPDATE_IN_PROGRESS-date", "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceProperties": { - "TopicName": "topic-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "Requested update requires the creation of a new physical resource; hence creating one.", + "PhysicalResourceId": "", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Foo-CREATE_COMPLETE-date", "LogicalResourceId": "Foo", "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceProperties": { - "TopicName": "topic-1" - }, "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Foo-CREATE_IN_PROGRESS-date", "LogicalResourceId": "Foo", "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceProperties": { - "TopicName": "topic-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Foo-CREATE_IN_PROGRESS-date", "LogicalResourceId": "Foo", - "PhysicalResourceId": "", - "ResourceProperties": { - "TopicName": "topic-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", + "PhysicalResourceId": "arn::sns::111111111111:topic-2", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } ], "Parameter": [ { - "EventId": "Parameter-UPDATE_COMPLETE-date", - "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-b4xwNWwXL1pX", - "ResourceProperties": { - "Type": "String", - "Value": "topic-2" - }, - "ResourceStatus": "UPDATE_COMPLETE", - "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Parameter-UPDATE_IN_PROGRESS-date", "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-b4xwNWwXL1pX", - "ResourceProperties": { - "Type": "String", - "Value": "topic-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", + "PhysicalResourceId": "", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Parameter-CREATE_COMPLETE-date", "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-b4xwNWwXL1pX", - "ResourceProperties": { - "Type": "String", - "Value": "topic-1" - }, + "PhysicalResourceId": "CFN-Parameter-OkuGHMW4ltfZ", "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Parameter-CREATE_IN_PROGRESS-date", "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-b4xwNWwXL1pX", - "ResourceProperties": { - "Type": "String", - "Value": "topic-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", + "PhysicalResourceId": "CFN-Parameter-OkuGHMW4ltfZ", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Parameter-CREATE_IN_PROGRESS-date", "LogicalResourceId": "Parameter", - "PhysicalResourceId": "", - "ResourceProperties": { - "Type": "String", - "Value": "topic-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", + "PhysicalResourceId": "CFN-Parameter-OkuGHMW4ltfZ", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } ], - "": [ - { - "EventId": "", - "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE", - "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, + "Stack": [ { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", + "ResourceStatus": "REVIEW_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "REVIEW_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } ] - }, - "delete-describe": { - "CreationTime": "datetime", - "DeletionTime": "datetime", - "DisableRollback": false, - "DriftInformation": { - "StackDriftStatus": "NOT_CHECKED" - }, - "LastUpdatedTime": "datetime", - "NotificationARNs": [], - "RollbackConfiguration": {}, - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "StackStatus": "DELETE_COMPLETE", - "Tags": [] } } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_parameter_changes": { - "recorded-date": "24-04-2025, 17:38:55", + "recorded-date": "18-06-2025, 19:09:04", "recorded-content": { "create-change-set-1": { "Id": "arn::cloudformation::111111111111:changeSet/", @@ -1325,8 +1080,9 @@ }, "Details": [ { - "ChangeSource": "DirectModification", - "Evaluation": "Dynamic", + "CausingEntity": "Foo.TopicName", + "ChangeSource": "ResourceAttribute", + "Evaluation": "Static", "Target": { "AfterValue": "{{changeSet:KNOWN_AFTER_APPLY}}", "Attribute": "Properties", @@ -1338,9 +1094,8 @@ } }, { - "CausingEntity": "Foo.TopicName", - "ChangeSource": "ResourceAttribute", - "Evaluation": "Static", + "ChangeSource": "DirectModification", + "Evaluation": "Dynamic", "Target": { "AfterValue": "{{changeSet:KNOWN_AFTER_APPLY}}", "Attribute": "Properties", @@ -1353,7 +1108,7 @@ } ], "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-59wvoXl3mFfy", + "PhysicalResourceId": "CFN-Parameter-lZ25tyPMdFIo", "Replacement": "False", "ResourceType": "AWS::SSM::Parameter", "Scope": [ @@ -1438,7 +1193,7 @@ } ], "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-59wvoXl3mFfy", + "PhysicalResourceId": "CFN-Parameter-lZ25tyPMdFIo", "Replacement": "False", "ResourceType": "AWS::SSM::Parameter", "Scope": [ @@ -1495,274 +1250,130 @@ "StackStatus": "UPDATE_COMPLETE", "Tags": [] }, + "delete-describe": { + "CreationTime": "datetime", + "DeletionTime": "datetime", + "DisableRollback": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + }, + "LastUpdatedTime": "datetime", + "NotificationARNs": [], + "Parameters": [ + { + "ParameterKey": "TopicName", + "ParameterValue": "topic-2" + } + ], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "StackStatus": "DELETE_COMPLETE", + "Tags": [] + }, "per-resource-events": { "Foo": [ { - "EventId": "Foo-da242d34-1619-4128-b9a1-24ae25f05899", "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceStatus": "DELETE_COMPLETE", + "PhysicalResourceId": "", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Foo-8aa7df32-a61d-4794-9f57-c33004142e46", "LogicalResourceId": "Foo", "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceStatus": "DELETE_IN_PROGRESS", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Foo-UPDATE_COMPLETE-date", "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-2", - "ResourceProperties": { - "TopicName": "topic-2" - }, - "ResourceStatus": "UPDATE_COMPLETE", + "PhysicalResourceId": "arn::sns::111111111111:topic-1", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Foo-UPDATE_IN_PROGRESS-date", "LogicalResourceId": "Foo", "PhysicalResourceId": "arn::sns::111111111111:topic-2", - "ResourceProperties": { - "TopicName": "topic-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" - }, + } + ], + "Parameter": [ { - "EventId": "Foo-UPDATE_IN_PROGRESS-date", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceProperties": { - "TopicName": "topic-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "Requested update requires the creation of a new physical resource; hence creating one.", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", + "LogicalResourceId": "Parameter", + "PhysicalResourceId": "", + "ResourceStatus": "CREATE_IN_PROGRESS", + "ResourceType": "AWS::SSM::Parameter", "Timestamp": "timestamp" }, { - "EventId": "Foo-CREATE_COMPLETE-date", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceProperties": { - "TopicName": "topic-1" - }, + "LogicalResourceId": "Parameter", + "PhysicalResourceId": "CFN-Parameter-lZ25tyPMdFIo", "ResourceStatus": "CREATE_COMPLETE", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", + "ResourceType": "AWS::SSM::Parameter", "Timestamp": "timestamp" }, { - "EventId": "Foo-CREATE_IN_PROGRESS-date", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-1", - "ResourceProperties": { - "TopicName": "topic-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-CREATE_IN_PROGRESS-date", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "", - "ResourceProperties": { - "TopicName": "topic-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - } - ], - "Parameter": [ - { - "EventId": "Parameter-UPDATE_COMPLETE-date", - "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-59wvoXl3mFfy", - "ResourceProperties": { - "Type": "String", - "Value": "topic-2" - }, - "ResourceStatus": "UPDATE_COMPLETE", - "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Parameter-UPDATE_IN_PROGRESS-date", "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-59wvoXl3mFfy", - "ResourceProperties": { - "Type": "String", - "Value": "topic-2" - }, + "PhysicalResourceId": "CFN-Parameter-lZ25tyPMdFIo", "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Parameter-CREATE_COMPLETE-date", "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-59wvoXl3mFfy", - "ResourceProperties": { - "Type": "String", - "Value": "topic-1" - }, - "ResourceStatus": "CREATE_COMPLETE", - "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Parameter-CREATE_IN_PROGRESS-date", - "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-59wvoXl3mFfy", - "ResourceProperties": { - "Type": "String", - "Value": "topic-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", - "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Parameter-CREATE_IN_PROGRESS-date", - "LogicalResourceId": "Parameter", - "PhysicalResourceId": "", - "ResourceProperties": { - "Type": "String", - "Value": "topic-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", + "PhysicalResourceId": "CFN-Parameter-lZ25tyPMdFIo", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } ], - "": [ + "Stack": [ { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE", - "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "", - "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", + "ResourceStatus": "REVIEW_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "REVIEW_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } ] - }, - "delete-describe": { - "CreationTime": "datetime", - "DeletionTime": "datetime", - "DisableRollback": false, - "DriftInformation": { - "StackDriftStatus": "NOT_CHECKED" - }, - "LastUpdatedTime": "datetime", - "NotificationARNs": [], - "Parameters": [ - { - "ParameterKey": "TopicName", - "ParameterValue": "topic-2" - } - ], - "RollbackConfiguration": {}, - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "StackStatus": "DELETE_COMPLETE", - "Tags": [] } } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_mappings_with_static_fields": { - "recorded-date": "24-04-2025, 17:40:57", + "recorded-date": "18-06-2025, 19:11:09", "recorded-content": { "create-change-set-1": { "Id": "arn::cloudformation::111111111111:changeSet/", @@ -1952,9 +1563,8 @@ }, "Details": [ { - "CausingEntity": "Foo.TopicName", - "ChangeSource": "ResourceAttribute", - "Evaluation": "Static", + "ChangeSource": "DirectModification", + "Evaluation": "Dynamic", "Target": { "AfterValue": "{{changeSet:KNOWN_AFTER_APPLY}}", "Attribute": "Properties", @@ -1966,8 +1576,9 @@ } }, { - "ChangeSource": "DirectModification", - "Evaluation": "Dynamic", + "CausingEntity": "Foo.TopicName", + "ChangeSource": "ResourceAttribute", + "Evaluation": "Static", "Target": { "AfterValue": "{{changeSet:KNOWN_AFTER_APPLY}}", "Attribute": "Properties", @@ -1980,7 +1591,7 @@ } ], "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-U4lqVSH21TIK", + "PhysicalResourceId": "CFN-Parameter-QY7XaFoB4kQc", "Replacement": "False", "ResourceType": "AWS::SSM::Parameter", "Scope": [ @@ -2049,7 +1660,7 @@ } ], "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-U4lqVSH21TIK", + "PhysicalResourceId": "CFN-Parameter-QY7XaFoB4kQc", "Replacement": "False", "ResourceType": "AWS::SSM::Parameter", "Scope": [ @@ -2094,268 +1705,124 @@ "StackStatus": "UPDATE_COMPLETE", "Tags": [] }, + "delete-describe": { + "CreationTime": "datetime", + "DeletionTime": "datetime", + "DisableRollback": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + }, + "LastUpdatedTime": "datetime", + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "StackStatus": "DELETE_COMPLETE", + "Tags": [] + }, "per-resource-events": { "Foo": [ { - "EventId": "Foo-19d3838e-f734-4c47-bbc3-ed5ce898ae7f", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", - "ResourceStatus": "DELETE_COMPLETE", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-1d67606c-91cd-478e-aa7f-bb5f79834fe4", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", - "ResourceStatus": "DELETE_IN_PROGRESS", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-UPDATE_COMPLETE-date", "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-name-2", - "ResourceProperties": { - "TopicName": "topic-name-2" - }, - "ResourceStatus": "UPDATE_COMPLETE", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-UPDATE_IN_PROGRESS-date", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-name-2", - "ResourceProperties": { - "TopicName": "topic-name-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-UPDATE_IN_PROGRESS-date", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", - "ResourceProperties": { - "TopicName": "topic-name-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "Requested update requires the creation of a new physical resource; hence creating one.", + "PhysicalResourceId": "", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Foo-CREATE_COMPLETE-date", "LogicalResourceId": "Foo", "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", - "ResourceProperties": { - "TopicName": "topic-name-1" - }, "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Foo-CREATE_IN_PROGRESS-date", "LogicalResourceId": "Foo", "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", - "ResourceProperties": { - "TopicName": "topic-name-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Foo-CREATE_IN_PROGRESS-date", "LogicalResourceId": "Foo", - "PhysicalResourceId": "", - "ResourceProperties": { - "TopicName": "topic-name-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-2", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } ], "Parameter": [ { - "EventId": "Parameter-UPDATE_COMPLETE-date", - "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-U4lqVSH21TIK", - "ResourceProperties": { - "Type": "String", - "Value": "topic-name-2" - }, - "ResourceStatus": "UPDATE_COMPLETE", - "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Parameter-UPDATE_IN_PROGRESS-date", "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-U4lqVSH21TIK", - "ResourceProperties": { - "Type": "String", - "Value": "topic-name-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", + "PhysicalResourceId": "", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Parameter-CREATE_COMPLETE-date", "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-U4lqVSH21TIK", - "ResourceProperties": { - "Type": "String", - "Value": "topic-name-1" - }, + "PhysicalResourceId": "CFN-Parameter-QY7XaFoB4kQc", "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Parameter-CREATE_IN_PROGRESS-date", "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-U4lqVSH21TIK", - "ResourceProperties": { - "Type": "String", - "Value": "topic-name-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", + "PhysicalResourceId": "CFN-Parameter-QY7XaFoB4kQc", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Parameter-CREATE_IN_PROGRESS-date", "LogicalResourceId": "Parameter", - "PhysicalResourceId": "", - "ResourceProperties": { - "Type": "String", - "Value": "topic-name-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", + "PhysicalResourceId": "CFN-Parameter-QY7XaFoB4kQc", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } ], - "": [ - { - "EventId": "", - "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE", - "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, + "Stack": [ { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", + "ResourceStatus": "REVIEW_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "REVIEW_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } ] - }, - "delete-describe": { - "CreationTime": "datetime", - "DeletionTime": "datetime", - "DisableRollback": false, - "DriftInformation": { - "StackDriftStatus": "NOT_CHECKED" - }, - "LastUpdatedTime": "datetime", - "NotificationARNs": [], - "RollbackConfiguration": {}, - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "StackStatus": "DELETE_COMPLETE", - "Tags": [] } } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_mappings_with_parameter_lookup": { - "recorded-date": "24-04-2025, 17:42:57", + "recorded-date": "18-06-2025, 19:13:17", "recorded-content": { "create-change-set-1": { "Id": "arn::cloudformation::111111111111:changeSet/", @@ -2522,8 +1989,9 @@ }, "Details": [ { - "ChangeSource": "DirectModification", - "Evaluation": "Dynamic", + "CausingEntity": "TopicName", + "ChangeSource": "ParameterReference", + "Evaluation": "Static", "Target": { "AfterValue": "topic-name-2", "Attribute": "Properties", @@ -2535,9 +2003,8 @@ } }, { - "CausingEntity": "TopicName", - "ChangeSource": "ParameterReference", - "Evaluation": "Static", + "ChangeSource": "DirectModification", + "Evaluation": "Dynamic", "Target": { "AfterValue": "topic-name-2", "Attribute": "Properties", @@ -2577,8 +2044,9 @@ }, "Details": [ { - "ChangeSource": "DirectModification", - "Evaluation": "Dynamic", + "CausingEntity": "Foo.TopicName", + "ChangeSource": "ResourceAttribute", + "Evaluation": "Static", "Target": { "AfterValue": "{{changeSet:KNOWN_AFTER_APPLY}}", "Attribute": "Properties", @@ -2590,9 +2058,8 @@ } }, { - "CausingEntity": "Foo.TopicName", - "ChangeSource": "ResourceAttribute", - "Evaluation": "Static", + "ChangeSource": "DirectModification", + "Evaluation": "Dynamic", "Target": { "AfterValue": "{{changeSet:KNOWN_AFTER_APPLY}}", "Attribute": "Properties", @@ -2605,7 +2072,7 @@ } ], "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-ir98heGTa0zR", + "PhysicalResourceId": "CFN-Parameter-tGkdmdoGLN1m", "Replacement": "False", "ResourceType": "AWS::SSM::Parameter", "Scope": [ @@ -2690,7 +2157,7 @@ } ], "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-ir98heGTa0zR", + "PhysicalResourceId": "CFN-Parameter-tGkdmdoGLN1m", "Replacement": "False", "ResourceType": "AWS::SSM::Parameter", "Scope": [ @@ -2747,274 +2214,130 @@ "StackStatus": "UPDATE_COMPLETE", "Tags": [] }, + "delete-describe": { + "CreationTime": "datetime", + "DeletionTime": "datetime", + "DisableRollback": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + }, + "LastUpdatedTime": "datetime", + "NotificationARNs": [], + "Parameters": [ + { + "ParameterKey": "TopicName", + "ParameterValue": "key2" + } + ], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "StackStatus": "DELETE_COMPLETE", + "Tags": [] + }, "per-resource-events": { "Foo": [ { - "EventId": "Foo-4f6c54a4-1549-4bd7-97c4-dd0ecca23860", "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", - "ResourceStatus": "DELETE_COMPLETE", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-53ede9ba-f993-45dd-9b68-e31f406d95c2", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", - "ResourceStatus": "DELETE_IN_PROGRESS", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-UPDATE_COMPLETE-date", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-name-2", - "ResourceProperties": { - "TopicName": "topic-name-2" - }, - "ResourceStatus": "UPDATE_COMPLETE", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-UPDATE_IN_PROGRESS-date", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-name-2", - "ResourceProperties": { - "TopicName": "topic-name-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", - "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Foo-UPDATE_IN_PROGRESS-date", - "LogicalResourceId": "Foo", - "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", - "ResourceProperties": { - "TopicName": "topic-name-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "Requested update requires the creation of a new physical resource; hence creating one.", + "PhysicalResourceId": "", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Foo-CREATE_COMPLETE-date", "LogicalResourceId": "Foo", "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", - "ResourceProperties": { - "TopicName": "topic-name-1" - }, "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Foo-CREATE_IN_PROGRESS-date", "LogicalResourceId": "Foo", "PhysicalResourceId": "arn::sns::111111111111:topic-name-1", - "ResourceProperties": { - "TopicName": "topic-name-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Foo-CREATE_IN_PROGRESS-date", "LogicalResourceId": "Foo", - "PhysicalResourceId": "", - "ResourceProperties": { - "TopicName": "topic-name-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", + "PhysicalResourceId": "arn::sns::111111111111:topic-name-2", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::SNS::Topic", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } ], "Parameter": [ { - "EventId": "Parameter-UPDATE_COMPLETE-date", "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-ir98heGTa0zR", - "ResourceProperties": { - "Type": "String", - "Value": "topic-name-2" - }, - "ResourceStatus": "UPDATE_COMPLETE", - "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Parameter-UPDATE_IN_PROGRESS-date", - "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-ir98heGTa0zR", - "ResourceProperties": { - "Type": "String", - "Value": "topic-name-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", + "PhysicalResourceId": "", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Parameter-CREATE_COMPLETE-date", "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-ir98heGTa0zR", - "ResourceProperties": { - "Type": "String", - "Value": "topic-name-1" - }, + "PhysicalResourceId": "CFN-Parameter-tGkdmdoGLN1m", "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Parameter-CREATE_IN_PROGRESS-date", "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-ir98heGTa0zR", - "ResourceProperties": { - "Type": "String", - "Value": "topic-name-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", + "PhysicalResourceId": "CFN-Parameter-tGkdmdoGLN1m", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Parameter-CREATE_IN_PROGRESS-date", "LogicalResourceId": "Parameter", - "PhysicalResourceId": "", - "ResourceProperties": { - "Type": "String", - "Value": "topic-name-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", + "PhysicalResourceId": "CFN-Parameter-tGkdmdoGLN1m", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } ], - "": [ + "Stack": [ { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE", - "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "", - "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", + "ResourceStatus": "REVIEW_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "REVIEW_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } ] - }, - "delete-describe": { - "CreationTime": "datetime", - "DeletionTime": "datetime", - "DisableRollback": false, - "DriftInformation": { - "StackDriftStatus": "NOT_CHECKED" - }, - "LastUpdatedTime": "datetime", - "NotificationARNs": [], - "Parameters": [ - { - "ParameterKey": "TopicName", - "ParameterValue": "key2" - } - ], - "RollbackConfiguration": {}, - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "StackStatus": "DELETE_COMPLETE", - "Tags": [] } } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_conditions": { - "recorded-date": "24-04-2025, 17:54:44", + "recorded-date": "18-06-2025, 19:13:55", "recorded-content": { "create-change-set-1": { "Id": "arn::cloudformation::111111111111:changeSet/", @@ -3237,179 +2560,102 @@ "StackStatus": "UPDATE_COMPLETE", "Tags": [] }, + "delete-describe": { + "CreationTime": "datetime", + "DeletionTime": "datetime", + "DisableRollback": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + }, + "LastUpdatedTime": "datetime", + "NotificationARNs": [], + "Parameters": [ + { + "ParameterKey": "EnvironmentType", + "ParameterValue": "prod" + } + ], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "StackStatus": "DELETE_COMPLETE", + "Tags": [] + }, "per-resource-events": { "Bucket": [ { - "EventId": "Bucket-CREATE_COMPLETE-date", - "LogicalResourceId": "Bucket", - "PhysicalResourceId": "-bucket-lrfokvsfgf0f", - "ResourceProperties": {}, - "ResourceStatus": "CREATE_COMPLETE", - "ResourceType": "AWS::S3::Bucket", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Bucket-CREATE_IN_PROGRESS-date", "LogicalResourceId": "Bucket", - "PhysicalResourceId": "-bucket-lrfokvsfgf0f", - "ResourceProperties": {}, + "PhysicalResourceId": "", "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", "ResourceType": "AWS::S3::Bucket", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Bucket-CREATE_IN_PROGRESS-date", "LogicalResourceId": "Bucket", - "PhysicalResourceId": "", - "ResourceProperties": {}, - "ResourceStatus": "CREATE_IN_PROGRESS", + "PhysicalResourceId": "-bucket-rvkyycxytnfz", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::S3::Bucket", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } ], "Parameter": [ { - "EventId": "Parameter-CREATE_COMPLETE-date", "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-XN7hqAZ0p5We", - "ResourceProperties": { - "Type": "String", - "Value": "test" - }, - "ResourceStatus": "CREATE_COMPLETE", - "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Parameter-CREATE_IN_PROGRESS-date", - "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-XN7hqAZ0p5We", - "ResourceProperties": { - "Type": "String", - "Value": "test" - }, + "PhysicalResourceId": "", "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Parameter-CREATE_IN_PROGRESS-date", "LogicalResourceId": "Parameter", - "PhysicalResourceId": "", - "ResourceProperties": { - "Type": "String", - "Value": "test" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", + "PhysicalResourceId": "CFN-Parameter-ytEGT7JWBrkx", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } ], - "": [ - { - "EventId": "", - "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE", - "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, + "Stack": [ { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", + "ResourceStatus": "REVIEW_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "REVIEW_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } ] - }, - "delete-describe": { - "CreationTime": "datetime", - "DeletionTime": "datetime", - "DisableRollback": false, - "DriftInformation": { - "StackDriftStatus": "NOT_CHECKED" - }, - "LastUpdatedTime": "datetime", - "NotificationARNs": [], - "Parameters": [ - { - "ParameterKey": "EnvironmentType", - "ParameterValue": "prod" - } - ], - "RollbackConfiguration": {}, - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "StackStatus": "DELETE_COMPLETE", - "Tags": [] } } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_base_dynamic_parameter_scenarios[change_dynamic]": { - "recorded-date": "24-04-2025, 17:55:06", + "recorded-date": "18-06-2025, 19:14:21", "recorded-content": { "create-change-set-1": { "Id": "arn::cloudformation::111111111111:changeSet/", @@ -3581,7 +2827,7 @@ } ], "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-UlYVEyGMt3Hh", + "PhysicalResourceId": "CFN-Parameter-BNuHBis1ysn1", "Replacement": "False", "ResourceType": "AWS::SSM::Parameter", "Scope": [ @@ -3640,7 +2886,7 @@ } ], "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-UlYVEyGMt3Hh", + "PhysicalResourceId": "CFN-Parameter-BNuHBis1ysn1", "Replacement": "False", "ResourceType": "AWS::SSM::Parameter", "Scope": [ @@ -3697,179 +2943,108 @@ "StackStatus": "UPDATE_COMPLETE", "Tags": [] }, + "delete-describe": { + "CreationTime": "datetime", + "DeletionTime": "datetime", + "DisableRollback": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + }, + "LastUpdatedTime": "datetime", + "NotificationARNs": [], + "Parameters": [ + { + "ParameterKey": "ParameterValue", + "ParameterValue": "value-2" + } + ], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "StackStatus": "DELETE_COMPLETE", + "Tags": [] + }, "per-resource-events": { "Parameter": [ { - "EventId": "Parameter-UPDATE_COMPLETE-date", - "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-UlYVEyGMt3Hh", - "ResourceProperties": { - "Type": "String", - "Value": "value-2" - }, - "ResourceStatus": "UPDATE_COMPLETE", - "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Parameter-UPDATE_IN_PROGRESS-date", "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-UlYVEyGMt3Hh", - "ResourceProperties": { - "Type": "String", - "Value": "value-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", + "PhysicalResourceId": "", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Parameter-CREATE_COMPLETE-date", "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-UlYVEyGMt3Hh", - "ResourceProperties": { - "Type": "String", - "Value": "value-1" - }, + "PhysicalResourceId": "CFN-Parameter-BNuHBis1ysn1", "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Parameter-CREATE_IN_PROGRESS-date", "LogicalResourceId": "Parameter", - "PhysicalResourceId": "CFN-Parameter-UlYVEyGMt3Hh", - "ResourceProperties": { - "Type": "String", - "Value": "value-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", + "PhysicalResourceId": "CFN-Parameter-BNuHBis1ysn1", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Parameter-CREATE_IN_PROGRESS-date", "LogicalResourceId": "Parameter", - "PhysicalResourceId": "", - "ResourceProperties": { - "Type": "String", - "Value": "value-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", + "PhysicalResourceId": "CFN-Parameter-BNuHBis1ysn1", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } ], - "": [ - { - "EventId": "", - "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE", - "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, + "Stack": [ { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", + "ResourceStatus": "REVIEW_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "REVIEW_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } ] - }, - "delete-describe": { - "CreationTime": "datetime", - "DeletionTime": "datetime", - "DisableRollback": false, - "DriftInformation": { - "StackDriftStatus": "NOT_CHECKED" - }, - "LastUpdatedTime": "datetime", - "NotificationARNs": [], - "Parameters": [ - { - "ParameterKey": "ParameterValue", - "ParameterValue": "value-2" - } - ], - "RollbackConfiguration": {}, - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "StackStatus": "DELETE_COMPLETE", - "Tags": [] } } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_base_dynamic_parameter_scenarios[change_unrelated_property]": { - "recorded-date": "24-04-2025, 17:55:06", + "recorded-date": "18-06-2025, 19:14:21", "recorded-content": {} }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_base_dynamic_parameter_scenarios[change_unrelated_property_not_create_only]": { - "recorded-date": "24-04-2025, 17:55:06", + "recorded-date": "18-06-2025, 19:14:21", "recorded-content": {} }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_base_dynamic_parameter_scenarios[change_parameter_for_condition_create_resource]": { - "recorded-date": "24-04-2025, 17:55:28", + "recorded-date": "18-06-2025, 19:14:47", "recorded-content": { "create-change-set-1": { "Id": "arn::cloudformation::111111111111:changeSet/", @@ -4095,195 +3270,109 @@ "StackStatus": "UPDATE_COMPLETE", "Tags": [] }, + "delete-describe": { + "CreationTime": "datetime", + "DeletionTime": "datetime", + "DisableRollback": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + }, + "LastUpdatedTime": "datetime", + "NotificationARNs": [], + "Parameters": [ + { + "ParameterKey": "ParameterValue", + "ParameterValue": "value-2" + } + ], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "StackStatus": "DELETE_COMPLETE", + "Tags": [] + }, "per-resource-events": { "SSMParameter1": [ { - "EventId": "SSMParameter1-CREATE_COMPLETE-date", - "LogicalResourceId": "SSMParameter1", - "PhysicalResourceId": "CFN-SSMParameter1-qGQrGgGvuC42", - "ResourceProperties": { - "Type": "String", - "Value": "first" - }, - "ResourceStatus": "CREATE_COMPLETE", - "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "SSMParameter1-CREATE_IN_PROGRESS-date", "LogicalResourceId": "SSMParameter1", - "PhysicalResourceId": "CFN-SSMParameter1-qGQrGgGvuC42", - "ResourceProperties": { - "Type": "String", - "Value": "first" - }, + "PhysicalResourceId": "", "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "SSMParameter1-CREATE_IN_PROGRESS-date", "LogicalResourceId": "SSMParameter1", - "PhysicalResourceId": "", - "ResourceProperties": { - "Type": "String", - "Value": "first" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", + "PhysicalResourceId": "CFN-SSMParameter1-YEPpTp1eTqmV", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } ], "SSMParameter2": [ { - "EventId": "SSMParameter2-CREATE_COMPLETE-date", - "LogicalResourceId": "SSMParameter2", - "PhysicalResourceId": "CFN-SSMParameter2-9KvTVovmiPsN", - "ResourceProperties": { - "Type": "String", - "Value": "first" - }, - "ResourceStatus": "CREATE_COMPLETE", - "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "SSMParameter2-CREATE_IN_PROGRESS-date", "LogicalResourceId": "SSMParameter2", - "PhysicalResourceId": "CFN-SSMParameter2-9KvTVovmiPsN", - "ResourceProperties": { - "Type": "String", - "Value": "first" - }, + "PhysicalResourceId": "", "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "SSMParameter2-CREATE_IN_PROGRESS-date", "LogicalResourceId": "SSMParameter2", - "PhysicalResourceId": "", - "ResourceProperties": { - "Type": "String", - "Value": "first" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", + "PhysicalResourceId": "CFN-SSMParameter2-Cy9JferYSQvx", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } ], - "": [ - { - "EventId": "", - "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE", - "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, + "Stack": [ { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", + "ResourceStatus": "REVIEW_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "REVIEW_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } ] - }, - "delete-describe": { - "CreationTime": "datetime", - "DeletionTime": "datetime", - "DisableRollback": false, - "DriftInformation": { - "StackDriftStatus": "NOT_CHECKED" - }, - "LastUpdatedTime": "datetime", - "NotificationARNs": [], - "Parameters": [ - { - "ParameterKey": "ParameterValue", - "ParameterValue": "value-2" - } - ], - "RollbackConfiguration": {}, - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "StackStatus": "DELETE_COMPLETE", - "Tags": [] } } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_execute_with_ref": { - "recorded-date": "24-04-2025, 17:55:57", + "recorded-date": "18-06-2025, 19:15:20", "recorded-content": { "before-value": "", "after-value": "" } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_base_mapping_scenarios[update_string_referencing_resource]": { - "recorded-date": "24-04-2025, 17:56:19", + "recorded-date": "18-06-2025, 19:15:45", "recorded-content": { "create-change-set-1": { "Id": "arn::cloudformation::111111111111:changeSet/", @@ -4423,7 +3512,7 @@ } ], "LogicalResourceId": "MySSMParameter", - "PhysicalResourceId": "CFN-MySSMParameter-sK4jajBbVCXk", + "PhysicalResourceId": "CFN-MySSMParameter-yMAYpjhjWvEz", "Replacement": "False", "ResourceType": "AWS::SSM::Parameter", "Scope": [ @@ -4466,7 +3555,7 @@ } ], "LogicalResourceId": "MySSMParameter", - "PhysicalResourceId": "CFN-MySSMParameter-sK4jajBbVCXk", + "PhysicalResourceId": "CFN-MySSMParameter-yMAYpjhjWvEz", "Replacement": "False", "ResourceType": "AWS::SSM::Parameter", "Scope": [ @@ -4511,160 +3600,89 @@ "StackStatus": "UPDATE_COMPLETE", "Tags": [] }, + "delete-describe": { + "CreationTime": "datetime", + "DeletionTime": "datetime", + "DisableRollback": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + }, + "LastUpdatedTime": "datetime", + "NotificationARNs": [], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "StackStatus": "DELETE_COMPLETE", + "Tags": [] + }, "per-resource-events": { "MySSMParameter": [ { - "EventId": "MySSMParameter-UPDATE_COMPLETE-date", "LogicalResourceId": "MySSMParameter", - "PhysicalResourceId": "CFN-MySSMParameter-sK4jajBbVCXk", - "ResourceProperties": { - "Type": "String", - "Value": "value-2" - }, - "ResourceStatus": "UPDATE_COMPLETE", - "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "MySSMParameter-UPDATE_IN_PROGRESS-date", - "LogicalResourceId": "MySSMParameter", - "PhysicalResourceId": "CFN-MySSMParameter-sK4jajBbVCXk", - "ResourceProperties": { - "Type": "String", - "Value": "value-2" - }, - "ResourceStatus": "UPDATE_IN_PROGRESS", + "PhysicalResourceId": "", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "MySSMParameter-CREATE_COMPLETE-date", "LogicalResourceId": "MySSMParameter", - "PhysicalResourceId": "CFN-MySSMParameter-sK4jajBbVCXk", - "ResourceProperties": { - "Type": "String", - "Value": "value-1" - }, + "PhysicalResourceId": "CFN-MySSMParameter-yMAYpjhjWvEz", "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "MySSMParameter-CREATE_IN_PROGRESS-date", "LogicalResourceId": "MySSMParameter", - "PhysicalResourceId": "CFN-MySSMParameter-sK4jajBbVCXk", - "ResourceProperties": { - "Type": "String", - "Value": "value-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", + "PhysicalResourceId": "CFN-MySSMParameter-yMAYpjhjWvEz", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "MySSMParameter-CREATE_IN_PROGRESS-date", "LogicalResourceId": "MySSMParameter", - "PhysicalResourceId": "", - "ResourceProperties": { - "Type": "String", - "Value": "value-1" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", + "PhysicalResourceId": "CFN-MySSMParameter-yMAYpjhjWvEz", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } ], - "": [ - { - "EventId": "", - "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE", - "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, + "Stack": [ { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", + "ResourceStatus": "REVIEW_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "REVIEW_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } ] - }, - "delete-describe": { - "CreationTime": "datetime", - "DeletionTime": "datetime", - "DisableRollback": false, - "DriftInformation": { - "StackDriftStatus": "NOT_CHECKED" - }, - "LastUpdatedTime": "datetime", - "NotificationARNs": [], - "RollbackConfiguration": {}, - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "StackStatus": "DELETE_COMPLETE", - "Tags": [] } } } diff --git a/tests/aws/services/cloudformation/v2/test_change_sets.validation.json b/tests/aws/services/cloudformation/v2/test_change_sets.validation.json index c54186e955aea..f31398e53fe2f 100644 --- a/tests/aws/services/cloudformation/v2/test_change_sets.validation.json +++ b/tests/aws/services/cloudformation/v2/test_change_sets.validation.json @@ -1,33 +1,93 @@ { "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_base_dynamic_parameter_scenarios[change_dynamic]": { - "last_validated_date": "2025-04-24T17:55:06+00:00" + "last_validated_date": "2025-06-18T19:14:21+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 25.11, + "teardown": 0.14, + "total": 25.25 + } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_base_dynamic_parameter_scenarios[change_parameter_for_condition_create_resource]": { - "last_validated_date": "2025-04-24T17:55:28+00:00" + "last_validated_date": "2025-06-18T19:14:47+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 26.23, + "teardown": 0.14, + "total": 26.37 + } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_base_mapping_scenarios[update_string_referencing_resource]": { - "last_validated_date": "2025-04-24T17:56:19+00:00" + "last_validated_date": "2025-06-18T19:15:45+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 25.01, + "teardown": 0.15, + "total": 25.16 + } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_conditions": { - "last_validated_date": "2025-04-24T17:54:44+00:00" + "last_validated_date": "2025-06-18T19:13:55+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 37.82, + "teardown": 0.16, + "total": 37.98 + } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_direct_update": { - "last_validated_date": "2025-04-24T17:00:59+00:00" + "last_validated_date": "2025-06-18T19:04:55+00:00", + "durations_in_seconds": { + "setup": 0.26, + "call": 116.94, + "teardown": 0.15, + "total": 117.35 + } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_dynamic_update": { - "last_validated_date": "2025-04-24T17:02:59+00:00" + "last_validated_date": "2025-06-18T19:06:59+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 124.05, + "teardown": 0.16, + "total": 124.21 + } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_execute_with_ref": { - "last_validated_date": "2025-04-24T17:55:52+00:00" + "last_validated_date": "2025-06-18T19:15:20+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 26.07, + "teardown": 6.64, + "total": 32.71 + } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_mappings_with_parameter_lookup": { - "last_validated_date": "2025-04-24T17:42:57+00:00" + "last_validated_date": "2025-06-18T19:13:18+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 128.68, + "teardown": 0.14, + "total": 128.82 + } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_mappings_with_static_fields": { - "last_validated_date": "2025-04-24T17:40:56+00:00" + "last_validated_date": "2025-06-18T19:11:09+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 124.56, + "teardown": 0.14, + "total": 124.7 + } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_parameter_changes": { - "last_validated_date": "2025-04-24T17:38:55+00:00" + "last_validated_date": "2025-06-18T19:09:04+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 124.46, + "teardown": 0.14, + "total": 124.6 + } }, "tests/aws/services/cloudformation/v2/test_change_sets.py::test_single_resource_static_update": { "last_validated_date": "2025-03-18T16:52:35+00:00" From e67072f32b48d09faa307f36493a954b9d5d4ca8 Mon Sep 17 00:00:00 2001 From: Greg Furman <31275503+gregfurman@users.noreply.github.com> Date: Fri, 20 Jun 2025 12:09:30 +0200 Subject: [PATCH 45/74] chore(utils): Fix typo when forwarding envars to container (#12778) --- localstack-core/localstack/utils/bootstrap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/localstack-core/localstack/utils/bootstrap.py b/localstack-core/localstack/utils/bootstrap.py index eb9c0c6600653..6d65ef30db0f1 100644 --- a/localstack-core/localstack/utils/bootstrap.py +++ b/localstack-core/localstack/utils/bootstrap.py @@ -523,7 +523,7 @@ def config_env_vars(cfg: ContainerConfiguration): # Show a deprecation warning for each individual env var collected above LOG.warning( "Non-prefixed environment variable %(env_var)s is forwarded to the LocalStack container! " - "Please use `LOCALSTACK_%(env_var)s` instead of %(env_var)s to explicitly mark this environment variable to be forwarded form the CLI to the LocalStack Runtime.", + "Please use `LOCALSTACK_%(env_var)s` instead of %(env_var)s to explicitly mark this environment variable to be forwarded from the CLI to the LocalStack Runtime.", {"env_var": non_prefixed_env_var}, ) From 6348947e8c9a1a50614c1425dbc6c1129f132040 Mon Sep 17 00:00:00 2001 From: victor-martin-santiago <32511495+victor-martin-santiago@users.noreply.github.com> Date: Fri, 20 Jun 2025 13:52:15 +0200 Subject: [PATCH 46/74] Add KMS ReEncrypt Operation (#12637) --- .../localstack/services/kms/provider.py | 34 +++++++- tests/aws/services/kms/test_kms.py | 87 ++++++++++++++++++- tests/aws/services/kms/test_kms.snapshot.json | 48 ++++++++++ .../aws/services/kms/test_kms.validation.json | 21 +++-- 4 files changed, 182 insertions(+), 8 deletions(-) diff --git a/localstack-core/localstack/services/kms/provider.py b/localstack-core/localstack/services/kms/provider.py index 02d8eb20f3261..a243e1d7fcea6 100644 --- a/localstack-core/localstack/services/kms/provider.py +++ b/localstack-core/localstack/services/kms/provider.py @@ -959,7 +959,39 @@ def re_encrypt( **kwargs, ) -> ReEncryptResponse: # TODO: when implementing, ensure cross-account support for source_key_id and destination_key_id - raise NotImplementedError + # Parse and fetch source Key + account_id, region_name, source_key_id = self._parse_key_id(source_key_id, context) + source_key = self._get_kms_key(account_id, region_name, source_key_id) + # Decrypt using source key + decrypt_response = self.decrypt( + context=context, + ciphertext_blob=ciphertext_blob, + encryption_context=source_encryption_context, + encryption_algorithm=source_encryption_algorithm, + key_id=source_key_id, + grant_tokens=grant_tokens, + ) + # Parse and fetch destination key + account_id, region_name, destination_key_id = self._parse_key_id( + destination_key_id, context + ) + destination_key = self._get_kms_key(account_id, region_name, destination_key_id) + # Encrypt using destination key + encrypt_response = self.encrypt( + context=context, + encryption_context=destination_encryption_context, + key_id=destination_key_id, + plaintext=decrypt_response["Plaintext"], + grant_tokens=grant_tokens, + dry_run=dry_run, + ) + return ReEncryptResponse( + CiphertextBlob=encrypt_response["CiphertextBlob"], + SourceKeyId=source_key.metadata.get("Arn"), + KeyId=destination_key.metadata.get("Arn"), + SourceEncryptionAlgorithm=source_encryption_algorithm, + DestinationEncryptionAlgorithm=destination_encryption_algorithm, + ) def encrypt( self, diff --git a/tests/aws/services/kms/test_kms.py b/tests/aws/services/kms/test_kms.py index 4b68dd9c38dce..92fcf1f085139 100644 --- a/tests/aws/services/kms/test_kms.py +++ b/tests/aws/services/kms/test_kms.py @@ -871,6 +871,91 @@ def test_encrypt_decrypt(self, kms_create_key, key_spec, algo, aws_client): )["Plaintext"] assert base64.b64decode(plaintext) == message + @pytest.mark.parametrize( + "key_spec,algo", + [ + ("SYMMETRIC_DEFAULT", "SYMMETRIC_DEFAULT"), + ("RSA_2048", "RSAES_OAEP_SHA_256"), + ], + ) + @markers.aws.validated + def test_re_encrypt(self, kms_create_key, key_spec, algo, aws_client, snapshot): + message = b"test message 123 !%$@ 1234567890" + source_key_id = kms_create_key(KeyUsage="ENCRYPT_DECRYPT", KeySpec=key_spec)["KeyId"] + destination_key_id = kms_create_key(KeyUsage="ENCRYPT_DECRYPT", KeySpec=key_spec)["KeyId"] + # Encrypt the message using the source key + ciphertext = aws_client.kms.encrypt( + KeyId=source_key_id, Plaintext=base64.b64encode(message), EncryptionAlgorithm=algo + )["CiphertextBlob"] + # Re-encrypt the previously encryted message using the destination key + result = aws_client.kms.re_encrypt( + SourceKeyId=source_key_id, + DestinationKeyId=destination_key_id, + CiphertextBlob=ciphertext, + SourceEncryptionAlgorithm=algo, + DestinationEncryptionAlgorithm=algo, + ) + snapshot.match("test_re_encrypt", result) + # Decrypt using the source key + source_key_plaintext = aws_client.kms.decrypt( + KeyId=source_key_id, CiphertextBlob=ciphertext, EncryptionAlgorithm=algo + )["Plaintext"] + # Decrypt using the destination key + destination_key_plaintext = aws_client.kms.decrypt( + KeyId=destination_key_id, + CiphertextBlob=result["CiphertextBlob"], + EncryptionAlgorithm=algo, + )["Plaintext"] + # Both source and destination plain texts should match the original + assert base64.b64decode(source_key_plaintext) == message + assert base64.b64decode(destination_key_plaintext) == message + + @markers.aws.validated + def test_re_encrypt_incorrect_source_key(self, kms_create_key, aws_client, snapshot): + algo = "SYMMETRIC_DEFAULT" + message = b"test message 123 !%$@ 1234567890" + source_key_id = kms_create_key(KeyUsage="ENCRYPT_DECRYPT", KeySpec=algo)["KeyId"] + ciphertext = aws_client.kms.encrypt( + KeyId=source_key_id, Plaintext=base64.b64encode(message), EncryptionAlgorithm=algo + )["CiphertextBlob"] + invalid_key_id = kms_create_key( + Description="test hmac key", + KeySpec="HMAC_224", + KeyUsage="GENERATE_VERIFY_MAC", + )["KeyId"] + + with pytest.raises(ClientError) as exc: + aws_client.kms.re_encrypt( + SourceKeyId=invalid_key_id, + DestinationKeyId=invalid_key_id, + CiphertextBlob=ciphertext, + SourceEncryptionAlgorithm=algo, + DestinationEncryptionAlgorithm=algo, + ) + snapshot.match("incorrect-source-key", exc.value.response) + + @markers.aws.validated + def test_re_encrypt_invalid_destination_key(self, kms_create_key, aws_client): + algo = "SYMMETRIC_DEFAULT" + message = b"test message 123 !%$@ 1234567890" + source_key_id = kms_create_key(KeyUsage="ENCRYPT_DECRYPT", KeySpec=algo)["KeyId"] + ciphertext = aws_client.kms.encrypt( + KeyId=source_key_id, Plaintext=base64.b64encode(message), EncryptionAlgorithm=algo + )["CiphertextBlob"] + invalid_key_id = kms_create_key(KeyUsage="SIGN_VERIFY", KeySpec="ECC_NIST_P256")["KeyId"] + with pytest.raises(ClientError) as exc: + aws_client.kms.re_encrypt( + SourceKeyId=source_key_id, + DestinationKeyId=invalid_key_id, + CiphertextBlob=ciphertext, + SourceEncryptionAlgorithm=algo, + DestinationEncryptionAlgorithm=algo, + ) + # TODO: Determine where 'context.operation.name' is being set to 'ReEncryptTo' as the expected AWS operation name is 'ReEncrypt' + # Then enable the snapshot check + # snapshot.match("invalid-destination-key-usage", exc.value.response) + assert exc.match("InvalidKeyUsageException") + @pytest.mark.parametrize( "key_spec,algo", [ @@ -1881,7 +1966,7 @@ def test_cross_accounts_access( # - GenerateDataKeyPairWithoutPlaintext # - GenerateDataKeyWithoutPlaintext # - GenerateMac - # - ReEncrypt (NOT IMPLEMENTED IN LOCALSTACK) + # - ReEncrypt # - Sign # - Verify # - VerifyMac diff --git a/tests/aws/services/kms/test_kms.snapshot.json b/tests/aws/services/kms/test_kms.snapshot.json index 17ebf79f26bb7..0d4f5ff03be92 100644 --- a/tests/aws/services/kms/test_kms.snapshot.json +++ b/tests/aws/services/kms/test_kms.snapshot.json @@ -2238,5 +2238,53 @@ } } } + }, + "tests/aws/services/kms/test_kms.py::TestKMS::test_re_encrypt[SYMMETRIC_DEFAULT-SYMMETRIC_DEFAULT]": { + "recorded-date": "09-06-2025, 12:52:58", + "recorded-content": { + "test_re_encrypt": { + "CiphertextBlob": "ciphertext-blob", + "DestinationEncryptionAlgorithm": "SYMMETRIC_DEFAULT", + "KeyId": "", + "SourceEncryptionAlgorithm": "SYMMETRIC_DEFAULT", + "SourceKeyId": "", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } + }, + "tests/aws/services/kms/test_kms.py::TestKMS::test_re_encrypt[RSA_2048-RSAES_OAEP_SHA_256]": { + "recorded-date": "09-06-2025, 12:53:00", + "recorded-content": { + "test_re_encrypt": { + "CiphertextBlob": "ciphertext-blob", + "DestinationEncryptionAlgorithm": "RSAES_OAEP_SHA_256", + "KeyId": "", + "SourceEncryptionAlgorithm": "RSAES_OAEP_SHA_256", + "SourceKeyId": "", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } + }, + "tests/aws/services/kms/test_kms.py::TestKMS::test_re_encrypt_incorrect_source_key": { + "recorded-date": "09-06-2025, 12:53:24", + "recorded-content": { + "incorrect-source-key": { + "Error": { + "Code": "IncorrectKeyException", + "Message": "The key ID in the request does not identify a CMK that can perform this operation." + }, + "message": "The key ID in the request does not identify a CMK that can perform this operation.", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 400 + } + } + } } } diff --git a/tests/aws/services/kms/test_kms.validation.json b/tests/aws/services/kms/test_kms.validation.json index fb082e9a3265d..df19dfe77dbba 100644 --- a/tests/aws/services/kms/test_kms.validation.json +++ b/tests/aws/services/kms/test_kms.validation.json @@ -200,6 +200,15 @@ "tests/aws/services/kms/test_kms.py::TestKMS::test_plaintext_size_for_encrypt": { "last_validated_date": "2024-04-11T15:54:20+00:00" }, + "tests/aws/services/kms/test_kms.py::TestKMS::test_re_encrypt[RSA_2048-RSAES_OAEP_SHA_256]": { + "last_validated_date": "2025-06-09T12:53:00+00:00" + }, + "tests/aws/services/kms/test_kms.py::TestKMS::test_re_encrypt[SYMMETRIC_DEFAULT-SYMMETRIC_DEFAULT]": { + "last_validated_date": "2025-06-09T12:52:58+00:00" + }, + "tests/aws/services/kms/test_kms.py::TestKMS::test_re_encrypt_incorrect_source_key": { + "last_validated_date": "2025-06-09T12:53:24+00:00" + }, "tests/aws/services/kms/test_kms.py::TestKMS::test_replicate_key": { "last_validated_date": "2024-04-11T15:53:44+00:00" }, @@ -323,16 +332,16 @@ "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_generate_data_key_pair": { "last_validated_date": "2024-04-11T15:54:29+00:00" }, - "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_generate_data_key_pair_without_plaintext": { - "last_validated_date": "2024-04-11T15:54:28+00:00" - }, - "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_generate_data_key_without_plaintext": { - "last_validated_date": "2024-04-11T15:54:31+00:00" - }, "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_generate_data_key_pair_dry_run": { "last_validated_date": "2025-04-06T11:54:20+00:00" }, + "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_generate_data_key_pair_without_plaintext": { + "last_validated_date": "2024-04-11T15:54:28+00:00" + }, "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_generate_data_key_pair_without_plaintext_dry_run": { "last_validated_date": "2025-04-13T15:44:57+00:00" + }, + "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_generate_data_key_without_plaintext": { + "last_validated_date": "2024-04-11T15:54:31+00:00" } } From b36bb1adfd077de56ff33a1210449f317b3ef9d9 Mon Sep 17 00:00:00 2001 From: LocalStack Bot <88328844+localstack-bot@users.noreply.github.com> Date: Mon, 23 Jun 2025 09:55:19 +0200 Subject: [PATCH 47/74] Update ASF APIs, update s3 provider signatures (#12785) Co-authored-by: LocalStack Bot Co-authored-by: Alexander Rashed --- .../localstack/aws/api/acm/__init__.py | 27 +++++++ .../localstack/aws/api/lambda_/__init__.py | 45 +++++++++++ .../localstack/aws/api/logs/__init__.py | 19 +++++ .../localstack/aws/api/s3/__init__.py | 74 ++++++++++++++++++- .../localstack/services/s3/provider.py | 22 +++++- pyproject.toml | 4 +- requirements-base-runtime.txt | 4 +- requirements-dev.txt | 6 +- requirements-runtime.txt | 6 +- requirements-test.txt | 6 +- requirements-typehint.txt | 6 +- 11 files changed, 198 insertions(+), 21 deletions(-) diff --git a/localstack-core/localstack/aws/api/acm/__init__.py b/localstack-core/localstack/aws/api/acm/__init__.py index 9971a0d3ab338..b62d3c2508d96 100644 --- a/localstack-core/localstack/aws/api/acm/__init__.py +++ b/localstack-core/localstack/aws/api/acm/__init__.py @@ -23,6 +23,11 @@ ValidationExceptionMessage = str +class CertificateExport(StrEnum): + ENABLED = "ENABLED" + DISABLED = "DISABLED" + + class CertificateManagedBy(StrEnum): CLOUDFRONT = "CLOUDFRONT" @@ -273,6 +278,7 @@ class AddTagsToCertificateRequest(ServiceRequest): class CertificateOptions(TypedDict, total=False): CertificateTransparencyLoggingPreference: Optional[CertificateTransparencyLoggingPreference] + Export: Optional[CertificateExport] class ExtendedKeyUsage(TypedDict, total=False): @@ -374,6 +380,7 @@ class CertificateSummary(TypedDict, total=False): KeyAlgorithm: Optional[KeyAlgorithm] KeyUsages: Optional[KeyUsageNames] ExtendedKeyUsages: Optional[ExtendedKeyUsageNames] + ExportOption: Optional[CertificateExport] InUse: Optional[NullableBoolean] Exported: Optional[NullableBoolean] RenewalEligibility: Optional[RenewalEligibility] @@ -436,6 +443,7 @@ class Filters(TypedDict, total=False): extendedKeyUsage: Optional[ExtendedKeyUsageFilterList] keyUsage: Optional[KeyUsageFilterList] keyTypes: Optional[KeyAlgorithmList] + exportOption: Optional[CertificateExport] managedBy: Optional[CertificateManagedBy] @@ -526,6 +534,15 @@ class ResendValidationEmailRequest(ServiceRequest): ValidationDomain: DomainNameString +class RevokeCertificateRequest(ServiceRequest): + CertificateArn: Arn + RevocationReason: RevocationReason + + +class RevokeCertificateResponse(TypedDict, total=False): + CertificateArn: Optional[Arn] + + class UpdateCertificateOptionsRequest(ServiceRequest): CertificateArn: Arn Options: CertificateOptions @@ -651,6 +668,16 @@ def resend_validation_email( ) -> None: raise NotImplementedError + @handler("RevokeCertificate") + def revoke_certificate( + self, + context: RequestContext, + certificate_arn: Arn, + revocation_reason: RevocationReason, + **kwargs, + ) -> RevokeCertificateResponse: + raise NotImplementedError + @handler("UpdateCertificateOptions") def update_certificate_options( self, context: RequestContext, certificate_arn: Arn, options: CertificateOptions, **kwargs diff --git a/localstack-core/localstack/aws/api/lambda_/__init__.py b/localstack-core/localstack/aws/api/lambda_/__init__.py index 178a1609135a9..0f1e716980e9e 100644 --- a/localstack-core/localstack/aws/api/lambda_/__init__.py +++ b/localstack-core/localstack/aws/api/lambda_/__init__.py @@ -84,6 +84,7 @@ S3Bucket = str S3Key = str S3ObjectVersion = str +SchemaRegistryUri = str SecurityGroupId = str SensitiveString = str SourceOwner = str @@ -171,6 +172,17 @@ class InvokeMode(StrEnum): RESPONSE_STREAM = "RESPONSE_STREAM" +class KafkaSchemaRegistryAuthType(StrEnum): + BASIC_AUTH = "BASIC_AUTH" + CLIENT_CERTIFICATE_TLS_AUTH = "CLIENT_CERTIFICATE_TLS_AUTH" + SERVER_ROOT_CA_CERTIFICATE = "SERVER_ROOT_CA_CERTIFICATE" + + +class KafkaSchemaValidationAttribute(StrEnum): + KEY = "KEY" + VALUE = "VALUE" + + class LastUpdateStatus(StrEnum): Successful = "Successful" Failed = "Failed" @@ -276,6 +288,11 @@ class Runtime(StrEnum): nodejs22_x = "nodejs22.x" +class SchemaRegistryEventRecordFormat(StrEnum): + JSON = "JSON" + SOURCE = "SOURCE" + + class SnapStartApplyOn(StrEnum): PublishedVersions = "PublishedVersions" None_ = "None" @@ -706,8 +723,31 @@ class AllowedPublishers(TypedDict, total=False): SigningProfileVersionArns: SigningProfileVersionArns +class KafkaSchemaValidationConfig(TypedDict, total=False): + Attribute: Optional[KafkaSchemaValidationAttribute] + + +KafkaSchemaValidationConfigList = List[KafkaSchemaValidationConfig] + + +class KafkaSchemaRegistryAccessConfig(TypedDict, total=False): + Type: Optional[KafkaSchemaRegistryAuthType] + URI: Optional[Arn] + + +KafkaSchemaRegistryAccessConfigList = List[KafkaSchemaRegistryAccessConfig] + + +class KafkaSchemaRegistryConfig(TypedDict, total=False): + SchemaRegistryURI: Optional[SchemaRegistryUri] + EventRecordFormat: Optional[SchemaRegistryEventRecordFormat] + AccessConfigs: Optional[KafkaSchemaRegistryAccessConfigList] + SchemaValidationConfigs: Optional[KafkaSchemaValidationConfigList] + + class AmazonManagedKafkaEventSourceConfig(TypedDict, total=False): ConsumerGroupId: Optional[URI] + SchemaRegistryConfig: Optional[KafkaSchemaRegistryConfig] ArchitecturesList = List[Architecture] @@ -795,6 +835,7 @@ class ScalingConfig(TypedDict, total=False): class SelfManagedKafkaEventSourceConfig(TypedDict, total=False): ConsumerGroupId: Optional[URI] + SchemaRegistryConfig: Optional[KafkaSchemaRegistryConfig] FunctionResponseTypeList = List[FunctionResponseType] @@ -1758,6 +1799,8 @@ class UpdateEventSourceMappingRequest(ServiceRequest): TumblingWindowInSeconds: Optional[TumblingWindowInSeconds] FunctionResponseTypes: Optional[FunctionResponseTypeList] ScalingConfig: Optional[ScalingConfig] + AmazonManagedKafkaEventSourceConfig: Optional[AmazonManagedKafkaEventSourceConfig] + SelfManagedKafkaEventSourceConfig: Optional[SelfManagedKafkaEventSourceConfig] DocumentDBEventSourceConfig: Optional[DocumentDBEventSourceConfig] KMSKeyArn: Optional[KMSKeyArn] MetricsConfig: Optional[EventSourceMappingMetricsConfig] @@ -2520,6 +2563,8 @@ def update_event_source_mapping( tumbling_window_in_seconds: TumblingWindowInSeconds | None = None, function_response_types: FunctionResponseTypeList | None = None, scaling_config: ScalingConfig | None = None, + amazon_managed_kafka_event_source_config: AmazonManagedKafkaEventSourceConfig | None = None, + self_managed_kafka_event_source_config: SelfManagedKafkaEventSourceConfig | None = None, document_db_event_source_config: DocumentDBEventSourceConfig | None = None, kms_key_arn: KMSKeyArn | None = None, metrics_config: EventSourceMappingMetricsConfig | None = None, diff --git a/localstack-core/localstack/aws/api/logs/__init__.py b/localstack-core/localstack/aws/api/logs/__init__.py index 66088f97bc672..1d93648315038 100644 --- a/localstack-core/localstack/aws/api/logs/__init__.py +++ b/localstack-core/localstack/aws/api/logs/__init__.py @@ -198,6 +198,14 @@ class EvaluationFrequency(StrEnum): ONE_HOUR = "ONE_HOUR" +class EventSource(StrEnum): + CloudTrail = "CloudTrail" + Route53Resolver = "Route53Resolver" + VPCFlow = "VPCFlow" + EKSAudit = "EKSAudit" + AWSWAF = "AWSWAF" + + class ExportTaskStatusCode(StrEnum): CANCELLED = "CANCELLED" COMPLETED = "COMPLETED" @@ -237,6 +245,10 @@ class LogGroupClass(StrEnum): DELIVERY = "DELIVERY" +class OCSFVersion(StrEnum): + V1_1 = "V1.1" + + class OpenSearchResourceStatusType(StrEnum): ACTIVE = "ACTIVE" NOT_FOUND = "NOT_FOUND" @@ -1605,6 +1617,12 @@ class ParsePostgres(TypedDict, total=False): source: Optional[Source] +class ParseToOCSF(TypedDict, total=False): + source: Optional[Source] + eventSource: EventSource + ocsfVersion: OCSFVersion + + class ParseRoute53(TypedDict, total=False): source: Optional[Source] @@ -1676,6 +1694,7 @@ class Processor(TypedDict, total=False): parseJSON: Optional[ParseJSON] parseKeyValue: Optional[ParseKeyValue] parseRoute53: Optional[ParseRoute53] + parseToOCSF: Optional[ParseToOCSF] parsePostgres: Optional[ParsePostgres] parseVPC: Optional[ParseVPC] parseWAF: Optional[ParseWAF] diff --git a/localstack-core/localstack/aws/api/s3/__init__.py b/localstack-core/localstack/aws/api/s3/__init__.py index 55e5b0771dd8b..07f26771311af 100644 --- a/localstack-core/localstack/aws/api/s3/__init__.py +++ b/localstack-core/localstack/aws/api/s3/__init__.py @@ -26,6 +26,7 @@ ChecksumCRC64NVME = str ChecksumSHA1 = str ChecksumSHA256 = str +ClientToken = str CloudFunction = str CloudFunctionInvocationRole = str Code = str @@ -133,6 +134,9 @@ Range = str RecordDelimiter = str Region = str +RenameSource = str +RenameSourceIfMatch = str +RenameSourceIfNoneMatch = str ReplaceKeyPrefixWith = str ReplaceKeyWith = str ReplicaKmsKeyID = str @@ -652,6 +656,12 @@ class EncryptionTypeMismatch(ServiceException): status_code: int = 400 +class IdempotencyParameterMismatch(ServiceException): + code: str = "IdempotencyParameterMismatch" + sender_fault: bool = False + status_code: int = 400 + + class InvalidObjectState(ServiceException): code: str = "InvalidObjectState" sender_fault: bool = False @@ -1643,6 +1653,7 @@ class DeleteBucketEncryptionRequest(ServiceRequest): class DeleteBucketIntelligentTieringConfigurationRequest(ServiceRequest): Bucket: BucketName Id: IntelligentTieringId + ExpectedBucketOwner: Optional[AccountId] class DeleteBucketInventoryConfigurationRequest(ServiceRequest): @@ -1952,6 +1963,7 @@ class GetBucketIntelligentTieringConfigurationOutput(TypedDict, total=False): class GetBucketIntelligentTieringConfigurationRequest(ServiceRequest): Bucket: BucketName Id: IntelligentTieringId + ExpectedBucketOwner: Optional[AccountId] class InventorySchedule(TypedDict, total=False): @@ -2557,6 +2569,7 @@ class HeadObjectOutput(TypedDict, total=False): RequestCharged: Optional[RequestCharged] ReplicationStatus: Optional[ReplicationStatus] PartsCount: Optional[PartsCount] + TagCount: Optional[TagCount] ObjectLockMode: Optional[ObjectLockMode] ObjectLockRetainUntilDate: Optional[ObjectLockRetainUntilDate] ObjectLockLegalHoldStatus: Optional[ObjectLockLegalHoldStatus] @@ -2663,6 +2676,7 @@ class ListBucketIntelligentTieringConfigurationsOutput(TypedDict, total=False): class ListBucketIntelligentTieringConfigurationsRequest(ServiceRequest): Bucket: BucketName ContinuationToken: Optional[Token] + ExpectedBucketOwner: Optional[AccountId] class ListBucketInventoryConfigurationsOutput(TypedDict, total=False): @@ -3074,6 +3088,7 @@ class PutBucketEncryptionRequest(ServiceRequest): class PutBucketIntelligentTieringConfigurationRequest(ServiceRequest): Bucket: BucketName Id: IntelligentTieringId + ExpectedBucketOwner: Optional[AccountId] IntelligentTieringConfiguration: IntelligentTieringConfiguration @@ -3369,6 +3384,29 @@ class RecordsEvent(TypedDict, total=False): Payload: Optional[Body] +class RenameObjectOutput(TypedDict, total=False): + pass + + +RenameSourceIfUnmodifiedSince = datetime +RenameSourceIfModifiedSince = datetime + + +class RenameObjectRequest(ServiceRequest): + Bucket: BucketName + Key: ObjectKey + RenameSource: RenameSource + DestinationIfMatch: Optional[IfMatch] + DestinationIfNoneMatch: Optional[IfNoneMatch] + DestinationIfModifiedSince: Optional[IfModifiedSince] + DestinationIfUnmodifiedSince: Optional[IfUnmodifiedSince] + SourceIfMatch: Optional[RenameSourceIfMatch] + SourceIfNoneMatch: Optional[RenameSourceIfNoneMatch] + SourceIfModifiedSince: Optional[RenameSourceIfModifiedSince] + SourceIfUnmodifiedSince: Optional[RenameSourceIfUnmodifiedSince] + ClientToken: Optional[ClientToken] + + class RequestProgress(TypedDict, total=False): Enabled: Optional[EnableRequestProgress] @@ -3814,7 +3852,12 @@ def delete_bucket_encryption( @handler("DeleteBucketIntelligentTieringConfiguration") def delete_bucket_intelligent_tiering_configuration( - self, context: RequestContext, bucket: BucketName, id: IntelligentTieringId, **kwargs + self, + context: RequestContext, + bucket: BucketName, + id: IntelligentTieringId, + expected_bucket_owner: AccountId | None = None, + **kwargs, ) -> None: raise NotImplementedError @@ -4019,7 +4062,12 @@ def get_bucket_encryption( @handler("GetBucketIntelligentTieringConfiguration") def get_bucket_intelligent_tiering_configuration( - self, context: RequestContext, bucket: BucketName, id: IntelligentTieringId, **kwargs + self, + context: RequestContext, + bucket: BucketName, + id: IntelligentTieringId, + expected_bucket_owner: AccountId | None = None, + **kwargs, ) -> GetBucketIntelligentTieringConfigurationOutput: raise NotImplementedError @@ -4383,6 +4431,7 @@ def list_bucket_intelligent_tiering_configurations( context: RequestContext, bucket: BucketName, continuation_token: Token | None = None, + expected_bucket_owner: AccountId | None = None, **kwargs, ) -> ListBucketIntelligentTieringConfigurationsOutput: raise NotImplementedError @@ -4596,6 +4645,7 @@ def put_bucket_intelligent_tiering_configuration( bucket: BucketName, id: IntelligentTieringId, intelligent_tiering_configuration: IntelligentTieringConfiguration, + expected_bucket_owner: AccountId | None = None, **kwargs, ) -> None: raise NotImplementedError @@ -4930,6 +4980,26 @@ def put_public_access_block( ) -> None: raise NotImplementedError + @handler("RenameObject") + def rename_object( + self, + context: RequestContext, + bucket: BucketName, + key: ObjectKey, + rename_source: RenameSource, + destination_if_match: IfMatch | None = None, + destination_if_none_match: IfNoneMatch | None = None, + destination_if_modified_since: IfModifiedSince | None = None, + destination_if_unmodified_since: IfUnmodifiedSince | None = None, + source_if_match: RenameSourceIfMatch | None = None, + source_if_none_match: RenameSourceIfNoneMatch | None = None, + source_if_modified_since: RenameSourceIfModifiedSince | None = None, + source_if_unmodified_since: RenameSourceIfUnmodifiedSince | None = None, + client_token: ClientToken | None = None, + **kwargs, + ) -> RenameObjectOutput: + raise NotImplementedError + @handler("RestoreObject") def restore_object( self, diff --git a/localstack-core/localstack/services/s3/provider.py b/localstack-core/localstack/services/s3/provider.py index bfd335ad7bf0e..5e96c64e39f93 100644 --- a/localstack-core/localstack/services/s3/provider.py +++ b/localstack-core/localstack/services/s3/provider.py @@ -3454,8 +3454,10 @@ def put_bucket_intelligent_tiering_configuration( bucket: BucketName, id: IntelligentTieringId, intelligent_tiering_configuration: IntelligentTieringConfiguration, + expected_bucket_owner: AccountId | None = None, **kwargs, ) -> None: + # TODO add support for expected_bucket_owner store, s3_bucket = self._get_cross_account_bucket(context, bucket) validate_bucket_intelligent_tiering_configuration(id, intelligent_tiering_configuration) @@ -3463,8 +3465,14 @@ def put_bucket_intelligent_tiering_configuration( s3_bucket.intelligent_tiering_configurations[id] = intelligent_tiering_configuration def get_bucket_intelligent_tiering_configuration( - self, context: RequestContext, bucket: BucketName, id: IntelligentTieringId, **kwargs + self, + context: RequestContext, + bucket: BucketName, + id: IntelligentTieringId, + expected_bucket_owner: AccountId | None = None, + **kwargs, ) -> GetBucketIntelligentTieringConfigurationOutput: + # TODO add support for expected_bucket_owner store, s3_bucket = self._get_cross_account_bucket(context, bucket) if not (itier_config := s3_bucket.intelligent_tiering_configurations.get(id)): @@ -3475,8 +3483,14 @@ def get_bucket_intelligent_tiering_configuration( ) def delete_bucket_intelligent_tiering_configuration( - self, context: RequestContext, bucket: BucketName, id: IntelligentTieringId, **kwargs + self, + context: RequestContext, + bucket: BucketName, + id: IntelligentTieringId, + expected_bucket_owner: AccountId | None = None, + **kwargs, ) -> None: + # TODO add support for expected_bucket_owner store, s3_bucket = self._get_cross_account_bucket(context, bucket) if not s3_bucket.intelligent_tiering_configurations.pop(id, None): @@ -3486,9 +3500,11 @@ def list_bucket_intelligent_tiering_configurations( self, context: RequestContext, bucket: BucketName, - continuation_token: Token = None, + continuation_token: Token | None = None, + expected_bucket_owner: AccountId | None = None, **kwargs, ) -> ListBucketIntelligentTieringConfigurationsOutput: + # TODO add support for expected_bucket_owner store, s3_bucket = self._get_cross_account_bucket(context, bucket) return ListBucketIntelligentTieringConfigurationsOutput( diff --git a/pyproject.toml b/pyproject.toml index 40556c7264e5e..6ba4cd7a8eca1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,9 +53,9 @@ Issues = "https://github.com/localstack/localstack/issues" # minimal required to actually run localstack on the host for services natively implemented in python base-runtime = [ # pinned / updated by ASF update action - "boto3==1.38.36", + "boto3==1.38.41", # pinned / updated by ASF update action - "botocore==1.38.36", + "botocore==1.38.41", "awscrt>=0.13.14,!=0.27.1", "cbor2>=5.5.0", "dnspython>=1.16.0", diff --git a/requirements-base-runtime.txt b/requirements-base-runtime.txt index 385d78ed99a03..33338aded8aef 100644 --- a/requirements-base-runtime.txt +++ b/requirements-base-runtime.txt @@ -11,9 +11,9 @@ attrs==25.3.0 # referencing awscrt==0.27.2 # via localstack-core (pyproject.toml) -boto3==1.38.36 +boto3==1.38.41 # via localstack-core (pyproject.toml) -botocore==1.38.36 +botocore==1.38.41 # via # boto3 # localstack-core (pyproject.toml) diff --git a/requirements-dev.txt b/requirements-dev.txt index 3b9cc3c1a0034..ec09b77618e09 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -39,17 +39,17 @@ aws-sam-translator==1.98.0 # localstack-core aws-xray-sdk==2.14.0 # via moto-ext -awscli==1.40.35 +awscli==1.40.40 # via localstack-core awscrt==0.27.2 # via localstack-core -boto3==1.38.36 +boto3==1.38.41 # via # aws-sam-translator # kclpy-ext # localstack-core # moto-ext -botocore==1.38.36 +botocore==1.38.41 # via # aws-xray-sdk # awscli diff --git a/requirements-runtime.txt b/requirements-runtime.txt index 52934e5c2933c..54daa60c01820 100644 --- a/requirements-runtime.txt +++ b/requirements-runtime.txt @@ -27,17 +27,17 @@ aws-sam-translator==1.98.0 # localstack-core (pyproject.toml) aws-xray-sdk==2.14.0 # via moto-ext -awscli==1.40.35 +awscli==1.40.40 # via localstack-core (pyproject.toml) awscrt==0.27.2 # via localstack-core -boto3==1.38.36 +boto3==1.38.41 # via # aws-sam-translator # kclpy-ext # localstack-core # moto-ext -botocore==1.38.36 +botocore==1.38.41 # via # aws-xray-sdk # awscli diff --git a/requirements-test.txt b/requirements-test.txt index 8d938fc6d63a6..2c75c80367598 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -39,17 +39,17 @@ aws-sam-translator==1.98.0 # localstack-core aws-xray-sdk==2.14.0 # via moto-ext -awscli==1.40.35 +awscli==1.40.40 # via localstack-core awscrt==0.27.2 # via localstack-core -boto3==1.38.36 +boto3==1.38.41 # via # aws-sam-translator # kclpy-ext # localstack-core # moto-ext -botocore==1.38.36 +botocore==1.38.41 # via # aws-xray-sdk # awscli diff --git a/requirements-typehint.txt b/requirements-typehint.txt index d2248fecdd13d..5c5190685c3b4 100644 --- a/requirements-typehint.txt +++ b/requirements-typehint.txt @@ -39,11 +39,11 @@ aws-sam-translator==1.98.0 # localstack-core aws-xray-sdk==2.14.0 # via moto-ext -awscli==1.40.35 +awscli==1.40.40 # via localstack-core awscrt==0.27.2 # via localstack-core -boto3==1.38.36 +boto3==1.38.41 # via # aws-sam-translator # kclpy-ext @@ -51,7 +51,7 @@ boto3==1.38.36 # moto-ext boto3-stubs==1.38.37 # via localstack-core (pyproject.toml) -botocore==1.38.36 +botocore==1.38.41 # via # aws-xray-sdk # awscli From 4e1dd98bdca4851101ad163a33e7c024c9ac1d14 Mon Sep 17 00:00:00 2001 From: Simon Walker Date: Mon, 23 Jun 2025 12:31:01 +0100 Subject: [PATCH 48/74] CFNv2: implement create_stack (#12779) --- .../services/cloudformation/v2/entities.py | 27 +-- .../services/cloudformation/v2/provider.py | 154 +++++++++++++----- template.yml | 6 + .../v2/ported_from_v1/api/test_changesets.py | 1 + .../v2/ported_from_v1/api/test_templates.py | 1 - .../resources/test_stack_sets.py | 1 + .../v2/ported_from_v1/test_template_engine.py | 8 +- 7 files changed, 138 insertions(+), 60 deletions(-) create mode 100644 template.yml diff --git a/localstack-core/localstack/services/cloudformation/v2/entities.py b/localstack-core/localstack/services/cloudformation/v2/entities.py index b0d12706c89a2..4d50076c52f05 100644 --- a/localstack-core/localstack/services/cloudformation/v2/entities.py +++ b/localstack-core/localstack/services/cloudformation/v2/entities.py @@ -1,10 +1,11 @@ from datetime import datetime, timezone -from typing import Optional, TypedDict +from typing import NotRequired, Optional, TypedDict from localstack.aws.api.cloudformation import ( ChangeSetStatus, ChangeSetType, CreateChangeSetInput, + CreateStackInput, ExecutionStatus, Output, Parameter, @@ -21,7 +22,6 @@ ) from localstack.services.cloudformation.engine.entities import ( StackIdentifier, - StackTemplate, ) from localstack.services.cloudformation.engine.v2.change_set_model import ( NodeTemplate, @@ -38,7 +38,6 @@ class Stack: stack_name: str parameters: list[Parameter] change_set_id: str | None - change_set_name: str | None status: StackStatus status_reason: StackStatusReason | None stack_id: str @@ -56,10 +55,9 @@ def __init__( self, account_id: str, region_name: str, - request_payload: CreateChangeSetInput, - template: StackTemplate | None = None, + request_payload: CreateChangeSetInput | CreateStackInput, + template: dict | None = None, template_body: str | None = None, - change_set_ids: list[str] | None = None, ): self.account_id = account_id self.region_name = region_name @@ -67,12 +65,12 @@ def __init__( self.template_body = template_body self.status = StackStatus.CREATE_IN_PROGRESS self.status_reason = None - self.change_set_ids = change_set_ids or [] + self.change_set_ids = [] self.creation_time = datetime.now(tz=timezone.utc) self.deletion_time = None + self.change_set_id = None self.stack_name = request_payload["StackName"] - self.change_set_name = request_payload.get("ChangeSetName") self.parameters = request_payload.get("Parameters", []) self.stack_id = arns.cloudformation_stack_arn( self.stack_name, @@ -159,7 +157,6 @@ def _store_event( def describe_details(self) -> ApiStack: result = { - "ChangeSetId": self.change_set_id, "CreationTime": self.creation_time, "DeletionTime": self.deletion_time, "StackId": self.stack_id, @@ -176,6 +173,9 @@ def describe_details(self) -> ApiStack: "RollbackConfiguration": {}, "Tags": [], } + if change_set_id := self.change_set_id: + result["ChangeSetId"] = change_set_id + if self.resolved_outputs: describe_outputs = [] for key, value in self.resolved_outputs.items(): @@ -191,6 +191,11 @@ def describe_details(self) -> ApiStack: return result +class ChangeSetRequestPayload(TypedDict, total=False): + ChangeSetName: str + ChangeSetType: NotRequired[ChangeSetType] + + class ChangeSet: change_set_name: str change_set_id: str @@ -203,8 +208,8 @@ class ChangeSet: def __init__( self, stack: Stack, - request_payload: CreateChangeSetInput, - template: StackTemplate | None = None, + request_payload: ChangeSetRequestPayload, + template: dict | None = None, ): self.stack = stack self.template = template diff --git a/localstack-core/localstack/services/cloudformation/v2/provider.py b/localstack-core/localstack/services/cloudformation/v2/provider.py index 8dfa504e0fdad..32970c3b9d1c1 100644 --- a/localstack-core/localstack/services/cloudformation/v2/provider.py +++ b/localstack-core/localstack/services/cloudformation/v2/provider.py @@ -13,6 +13,8 @@ ClientRequestToken, CreateChangeSetInput, CreateChangeSetOutput, + CreateStackInput, + CreateStackOutput, DeletionMode, DescribeChangeSetOutput, DescribeStackEventsOutput, @@ -74,7 +76,12 @@ def is_changeset_arn(change_set_name_or_id: str) -> bool: return ARN_CHANGESET_REGEX.match(change_set_name_or_id) is not None -def find_stack_v2(state: CloudFormationStore, stack_name: str | None) -> Stack: +class StackNotFoundError(ValidationError): + def __init__(self, stack_name: str): + super().__init__(f"Stack with id {stack_name} does not exist") + + +def find_stack_v2(state: CloudFormationStore, stack_name: str | None) -> Stack | None: if stack_name: if is_stack_arn(stack_name): return state.stacks_v2[stack_name] @@ -84,7 +91,7 @@ def find_stack_v2(state: CloudFormationStore, stack_name: str | None) -> Stack: if stack.stack_name == stack_name and stack.status != StackStatus.DELETE_COMPLETE: stack_candidates.append(stack) if len(stack_candidates) == 0: - raise ValidationError(f"No stack with name {stack_name} found") + return None elif len(stack_candidates) > 1: raise RuntimeError("Programing error, duplicate stacks found") else: @@ -96,37 +103,21 @@ def find_stack_v2(state: CloudFormationStore, stack_name: str | None) -> Stack: def find_change_set_v2( state: CloudFormationStore, change_set_name: str, stack_name: str | None = None ) -> ChangeSet | None: - change_set: ChangeSet | None = None if is_changeset_arn(change_set_name): - change_set = state.change_sets[change_set_name] + return state.change_sets[change_set_name] else: if stack_name is not None: - stack: Stack | None = None - if is_stack_arn(stack_name): - stack = state.stacks_v2[stack_name] - else: - for stack_candidate in state.stacks_v2.values(): - # TODO: check for active stacks - if ( - stack_candidate.stack_name == stack_name - and stack_candidate.status != StackStatus.DELETE_COMPLETE - ): - stack = stack_candidate - break - + stack = find_stack_v2(state, stack_name) if not stack: - raise NotImplementedError(f"no stack found for change set {change_set_name}") + raise StackNotFoundError(stack_name) for change_set_id in stack.change_set_ids: change_set_candidate = state.change_sets[change_set_id] if change_set_candidate.change_set_name == change_set_name: - change_set = change_set_candidate - break + return change_set_candidate else: raise NotImplementedError - return change_set - class CloudformationProviderV2(CloudformationProvider): @staticmethod @@ -270,8 +261,6 @@ def create_change_set( ) raise ValidationError(msg) - # TDOO: transformations - # TODO: reconsider the way parameters are modelled in the update graph process. # The options might be reduce to using the current style, or passing the extra information # as a metadata object. The choice should be made considering when the extra information @@ -303,7 +292,7 @@ def create_change_set( change_set.set_change_set_status(ChangeSetStatus.CREATE_COMPLETE) stack.change_set_id = change_set.change_set_id - stack.change_set_id = change_set.change_set_id + stack.change_set_ids.append(change_set.change_set_id) state.change_sets[change_set.change_set_id] = change_set return CreateChangeSetOutput(StackId=stack.stack_id, Id=change_set.change_set_id) @@ -433,6 +422,94 @@ def describe_change_set( ) return result + @handler("CreateStack", expand=False) + def create_stack(self, context: RequestContext, request: CreateStackInput) -> CreateStackOutput: + try: + stack_name = request["StackName"] + except KeyError: + # TODO: proper exception + raise ValidationError("StackName must be specified") + + state = get_cloudformation_store(context.account_id, context.region) + # TODO: copied from create_change_set, consider unifying + template_body = request.get("TemplateBody") + # s3 or secretsmanager url + template_url = request.get("TemplateURL") + + # validate and resolve template + if template_body and template_url: + raise ValidationError( + "Specify exactly one of 'TemplateBody' or 'TemplateUrl'" + ) # TODO: check proper message + + if not template_body and not template_url: + raise ValidationError( + "Specify exactly one of 'TemplateBody' or 'TemplateUrl'" + ) # TODO: check proper message + + template_body = api_utils.extract_template_body(request) + structured_template = template_preparer.parse_template(template_body) + + stack = Stack( + account_id=context.account_id, + region_name=context.region, + request_payload=request, + template=structured_template, + template_body=template_body, + ) + # TODO: what is the correct initial status? + state.stacks_v2[stack.stack_id] = stack + + # TODO: reconsider the way parameters are modelled in the update graph process. + # The options might be reduce to using the current style, or passing the extra information + # as a metadata object. The choice should be made considering when the extra information + # is needed for the update graph building, or only looked up in downstream tasks (metadata). + request_parameters = request.get("Parameters", list()) + # TODO: handle parameter defaults and resolution + after_parameters: dict[str, Any] = { + parameter["ParameterKey"]: parameter["ParameterValue"] + for parameter in request_parameters + } + after_template = structured_template + + # Create internal change set to execute + change_set = ChangeSet( + stack, + {"ChangeSetName": f"cs-{stack_name}-create", "ChangeSetType": ChangeSetType.CREATE}, + template=after_template, + ) + self._setup_change_set_model( + change_set=change_set, + before_template=None, + after_template=after_template, + before_parameters=None, + after_parameters=after_parameters, + ) + + # deployment process + stack.set_stack_status(StackStatus.CREATE_IN_PROGRESS) + change_set_executor = ChangeSetModelExecutor(change_set) + + def _run(*args): + try: + result = change_set_executor.execute() + stack.set_stack_status(StackStatus.CREATE_COMPLETE) + stack.resolved_resources = result.resources + stack.resolved_parameters = result.parameters + stack.resolved_outputs = result.outputs + # if the deployment succeeded, update the stack's template representation to that + # which was just deployed + stack.template = change_set.template + except Exception as e: + LOG.error( + "Create Stack set failed: %s", e, exc_info=LOG.isEnabledFor(logging.WARNING) + ) + stack.set_stack_status(StackStatus.CREATE_FAILED) + + start_worker_thread(_run) + + return CreateStackOutput(StackId=stack.stack_id) + @handler("DescribeStacks") def describe_stacks( self, @@ -443,6 +520,8 @@ def describe_stacks( ) -> DescribeStacksOutput: state = get_cloudformation_store(context.account_id, context.region) stack = find_stack_v2(state, stack_name) + if not stack: + raise StackNotFoundError(stack_name) return DescribeStacksOutput(Stacks=[stack.describe_details()]) @handler("DescribeStackResources") @@ -458,6 +537,8 @@ def describe_stack_resources( raise ValidationError("Cannot specify both StackName and PhysicalResourceId") state = get_cloudformation_store(context.account_id, context.region) stack = find_stack_v2(state, stack_name) + if not stack: + raise StackNotFoundError(stack_name) # TODO: filter stack by PhysicalResourceId! statuses = [] for resource_id, resource_status in stack.resource_states.items(): @@ -477,6 +558,8 @@ def describe_stack_events( ) -> DescribeStackEventsOutput: state = get_cloudformation_store(context.account_id, context.region) stack = find_stack_v2(state, stack_name) + if not stack: + raise StackNotFoundError(stack_name) return DescribeStackEventsOutput(StackEvents=stack.events) @handler("DeleteStack") @@ -491,26 +574,7 @@ def delete_stack( **kwargs, ) -> None: state = get_cloudformation_store(context.account_id, context.region) - if stack_name: - if is_stack_arn(stack_name): - stack = state.stacks_v2[stack_name] - else: - stack_candidates = [] - for stack in state.stacks_v2.values(): - if ( - stack.stack_name == stack_name - and stack.status != StackStatus.DELETE_COMPLETE - ): - stack_candidates.append(stack) - if len(stack_candidates) == 0: - raise ValidationError(f"No stack with name {stack_name} found") - elif len(stack_candidates) > 1: - raise RuntimeError("Programing error, duplicate stacks found") - else: - stack = stack_candidates[0] - else: - raise NotImplementedError - + stack = find_stack_v2(state, stack_name) if not stack: # aws will silently ignore invalid stack names - we should do the same return diff --git a/template.yml b/template.yml new file mode 100644 index 0000000000000..fdf209f0b421f --- /dev/null +++ b/template.yml @@ -0,0 +1,6 @@ +Resources: + MyParameter: + Type: AWS::SSM::Parameter + Properties: + Type: String + Value: foo diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py index 0d513d4b2a89e..d4e8a55a2d292 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py @@ -906,6 +906,7 @@ def _check_changeset_available(): snapshot.match("postdelete_changeset_notfound", e.value) +@pytest.mark.skip("CFNV2:Capabilities") @markers.aws.validated def test_autoexpand_capability_requirement(cleanups, aws_client): stack_name = f"test-stack-{short_uid()}" diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_templates.py b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_templates.py index 8a0724f49fa38..b50a3bc691e77 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_templates.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_templates.py @@ -39,7 +39,6 @@ def test_get_template_summary(deploy_cfn_template, snapshot, aws_client): snapshot.match("template-summary", res) -@pytest.mark.skip(reason="CFNV2:Other") @markers.aws.validated @pytest.mark.parametrize("url_style", ["s3_url", "http_path", "http_host", "http_invalid"]) def test_create_stack_from_s3_template_url( diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_stack_sets.py b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_stack_sets.py index 528e7e2c1e956..bae95c05ec516 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_stack_sets.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_stack_sets.py @@ -30,6 +30,7 @@ def _operation_is_ready(): return waiter +@pytest.mark.skip("CFNV2:StackSets") @markers.aws.validated def test_create_stack_set_with_stack_instances( account_id, diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py b/tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py index 7ab6b8ec37c18..542d28c39a52f 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py @@ -644,7 +644,7 @@ def test_macro_deployment( snapshot.match("stack_outputs", stack_with_macro.outputs) snapshot.match("stack_resource_descriptions", description) - @pytest.mark.skip(reason="CFNV2:Provider create_stack not ported") + @pytest.mark.skip("CFNV2:GetTemplate") @markers.aws.validated @markers.snapshot.skip_snapshot_verify( paths=[ @@ -914,7 +914,7 @@ def test_capabilities_requirements( snapshot.add_transformer(snapshot.transform.key_value("RoleName", "role-name")) snapshot.match("processed_template", processed_template) - @pytest.mark.skip(reason="CFNV2:Provider create_stack not ported") + @pytest.mark.skip("CFNV2:GetTemplate") @markers.aws.validated @markers.snapshot.skip_snapshot_verify( paths=[ @@ -976,6 +976,7 @@ def test_validate_lambda_internals( processed_template["TemplateBody"]["Resources"]["Parameter"]["Properties"]["Value"], ) + @pytest.mark.skip("CFNV2:Validation") @markers.aws.validated def test_to_validate_template_limit_for_macro( self, deploy_cfn_template, create_lambda_function, snapshot, aws_client @@ -1029,6 +1030,7 @@ def test_to_validate_template_limit_for_macro( ) snapshot.match("error_response", response) + @pytest.mark.skip("CFNV2:Validation") @markers.aws.validated def test_error_pass_macro_as_reference(self, snapshot, aws_client): """ @@ -1050,7 +1052,7 @@ def test_error_pass_macro_as_reference(self, snapshot, aws_client): ) snapshot.match("error", ex.value.response) - @pytest.mark.skip(reason="CFNV2:Provider create_stack not ported") + @pytest.mark.skip("CFNV2:GetTemplate") @markers.aws.validated def test_functions_and_references_during_transformation( self, deploy_cfn_template, create_lambda_function, snapshot, cleanups, aws_client From 0a43548bac8b44626730163dda2263e20b87b775 Mon Sep 17 00:00:00 2001 From: Simon Walker Date: Mon, 23 Jun 2025 13:42:43 +0100 Subject: [PATCH 49/74] CFNv2: implement update stack (#12781) --- .../services/cloudformation/v2/provider.py | 109 ++++++++++++++++++ .../v2/ported_from_v1/api/test_stacks.py | 1 - 2 files changed, 109 insertions(+), 1 deletion(-) diff --git a/localstack-core/localstack/services/cloudformation/v2/provider.py b/localstack-core/localstack/services/cloudformation/v2/provider.py index 32970c3b9d1c1..404f9e9f946de 100644 --- a/localstack-core/localstack/services/cloudformation/v2/provider.py +++ b/localstack-core/localstack/services/cloudformation/v2/provider.py @@ -36,11 +36,14 @@ StackName, StackNameOrId, StackStatus, + UpdateStackInput, + UpdateStackOutput, ) from localstack.services.cloudformation import api_utils from localstack.services.cloudformation.engine import template_preparer from localstack.services.cloudformation.engine.v2.change_set_model import ( ChangeSetModel, + ChangeType, NodeTemplate, ) from localstack.services.cloudformation.engine.v2.change_set_model_describer import ( @@ -562,6 +565,112 @@ def describe_stack_events( raise StackNotFoundError(stack_name) return DescribeStackEventsOutput(StackEvents=stack.events) + @handler("UpdateStack", expand=False) + def update_stack( + self, + context: RequestContext, + request: UpdateStackInput, + ) -> UpdateStackOutput: + try: + stack_name = request["StackName"] + except KeyError: + # TODO: proper exception + raise ValidationError("StackName must be specified") + state = get_cloudformation_store(context.account_id, context.region) + template_body = request.get("TemplateBody") + # s3 or secretsmanager url + template_url = request.get("TemplateURL") + + # validate and resolve template + if template_body and template_url: + raise ValidationError( + "Specify exactly one of 'TemplateBody' or 'TemplateUrl'" + ) # TODO: check proper message + + if not template_body and not template_url: + raise ValidationError( + "Specify exactly one of 'TemplateBody' or 'TemplateUrl'" + ) # TODO: check proper message + + template_body = api_utils.extract_template_body(request) + structured_template = template_preparer.parse_template(template_body) + + # this is intentionally not in a util yet. Let's first see how the different operations deal with these before generalizing + # handle ARN stack_name here (not valid for initial CREATE, since stack doesn't exist yet) + stack: Stack + if is_stack_arn(stack_name): + stack = state.stacks_v2.get(stack_name) + if not stack: + raise ValidationError(f"Stack '{stack_name}' does not exist.") + + else: + # stack name specified, so fetch the stack by name + stack_candidates: list[Stack] = [ + s for stack_arn, s in state.stacks_v2.items() if s.stack_name == stack_name + ] + active_stack_candidates = [ + s for s in stack_candidates if self._stack_status_is_active(s.status) + ] + + if not active_stack_candidates: + raise ValidationError(f"Stack '{stack_name}' does not exist.") + elif len(active_stack_candidates) > 1: + raise RuntimeError("Multiple stacks matched, update matching logic") + stack = active_stack_candidates[0] + + # TODO: proper status modeling + before_parameters = stack.resolved_parameters + # TODO: reconsider the way parameters are modelled in the update graph process. + # The options might be reduce to using the current style, or passing the extra information + # as a metadata object. The choice should be made considering when the extra information + # is needed for the update graph building, or only looked up in downstream tasks (metadata). + request_parameters = request.get("Parameters", list()) + # TODO: handle parameter defaults and resolution + after_parameters: dict[str, Any] = { + parameter["ParameterKey"]: parameter["ParameterValue"] + for parameter in request_parameters + } + before_template = stack.template + after_template = structured_template + + change_set = ChangeSet( + stack, + {"ChangeSetName": f"cs-{stack_name}-create", "ChangeSetType": ChangeSetType.CREATE}, + template=after_template, + ) + self._setup_change_set_model( + change_set=change_set, + before_template=before_template, + after_template=after_template, + before_parameters=before_parameters, + after_parameters=after_parameters, + ) + + if change_set.update_model.change_type == ChangeType.UNCHANGED: + raise ValidationError("No updates are to be performed.") + + stack.set_stack_status(StackStatus.UPDATE_IN_PROGRESS) + change_set_executor = ChangeSetModelExecutor(change_set) + + def _run(*args): + try: + result = change_set_executor.execute() + stack.set_stack_status(StackStatus.UPDATE_COMPLETE) + stack.resolved_resources = result.resources + stack.resolved_parameters = result.parameters + stack.resolved_outputs = result.outputs + # if the deployment succeeded, update the stack's template representation to that + # which was just deployed + stack.template = change_set.template + except Exception as e: + LOG.error("Update Stack failed: %s", e, exc_info=LOG.isEnabledFor(logging.WARNING)) + stack.set_stack_status(StackStatus.UPDATE_FAILED) + + start_worker_thread(_run) + + # TODO: stack id + return UpdateStackOutput(StackId=stack.stack_id) + @handler("DeleteStack") def delete_stack( self, diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py index ce401e102cd21..a2d262a76e8e0 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py @@ -261,7 +261,6 @@ def test_list_stack_resources_for_removed_resource(self, deploy_cfn_template, aw statuses = {res["ResourceStatus"] for res in resources} assert statuses == {"UPDATE_COMPLETE"} - @pytest.mark.skip(reason="CFNV2:Validation") @markers.aws.validated def test_update_stack_with_same_template_withoutchange( self, deploy_cfn_template, aws_client, snapshot From faccbb592281e33a0753659a6c704cbc99aed99c Mon Sep 17 00:00:00 2001 From: LocalStack Bot <88328844+localstack-bot@users.noreply.github.com> Date: Tue, 24 Jun 2025 10:01:11 +0200 Subject: [PATCH 50/74] Upgrade pinned dependencies, fix opensearch-py usage (#12790) Co-authored-by: LocalStack Bot Co-authored-by: Alexander Rashed --- .pre-commit-config.yaml | 4 +- requirements-base-runtime.txt | 8 +-- requirements-basic.txt | 6 +- requirements-dev.txt | 24 ++++---- requirements-runtime.txt | 14 ++--- requirements-test.txt | 22 ++++---- requirements-typehint.txt | 56 +++++++++---------- .../services/opensearch/test_opensearch.py | 12 ++-- 8 files changed, 73 insertions(+), 73 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 52bdb9e2f0fee..3d5de8acf3314 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,7 +3,7 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.11.13 + rev: v0.12.0 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] @@ -11,7 +11,7 @@ repos: - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.16.0 + rev: v1.16.1 hooks: - id: mypy entry: bash -c 'cd localstack-core && mypy --install-types --non-interactive' diff --git a/requirements-base-runtime.txt b/requirements-base-runtime.txt index 33338aded8aef..3602f2b83edf5 100644 --- a/requirements-base-runtime.txt +++ b/requirements-base-runtime.txt @@ -9,7 +9,7 @@ attrs==25.3.0 # jsonschema # localstack-twisted # referencing -awscrt==0.27.2 +awscrt==0.27.4 # via localstack-core (pyproject.toml) boto3==1.38.41 # via localstack-core (pyproject.toml) @@ -128,7 +128,7 @@ psutil==7.0.0 # via localstack-core (pyproject.toml) pycparser==2.22 # via cffi -pygments==2.19.1 +pygments==2.19.2 # via rich pyopenssl==25.1.0 # via @@ -138,7 +138,7 @@ pyproject-hooks==1.2.0 # via build python-dateutil==2.9.0.post0 # via botocore -python-dotenv==1.1.0 +python-dotenv==1.1.1 # via localstack-core (pyproject.toml) pyyaml==6.0.2 # via @@ -186,7 +186,7 @@ typing-extensions==4.14.0 # pyopenssl # readerwriterlock # referencing -urllib3==2.4.0 +urllib3==2.5.0 # via # botocore # docker diff --git a/requirements-basic.txt b/requirements-basic.txt index f086ba98a6999..34e9d957f0d8b 100644 --- a/requirements-basic.txt +++ b/requirements-basic.txt @@ -38,11 +38,11 @@ psutil==7.0.0 # via localstack-core (pyproject.toml) pycparser==2.22 # via cffi -pygments==2.19.1 +pygments==2.19.2 # via rich pyproject-hooks==1.2.0 # via build -python-dotenv==1.1.0 +python-dotenv==1.1.1 # via localstack-core (pyproject.toml) pyyaml==6.0.2 # via localstack-core (pyproject.toml) @@ -54,5 +54,5 @@ semver==3.0.4 # via localstack-core (pyproject.toml) tailer==0.4.1 # via localstack-core (pyproject.toml) -urllib3==2.4.0 +urllib3==2.5.0 # via requests diff --git a/requirements-dev.txt b/requirements-dev.txt index ec09b77618e09..10776fabd03b8 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -25,15 +25,15 @@ attrs==25.3.0 # jsonschema # localstack-twisted # referencing -aws-cdk-asset-awscli-v1==2.2.237 +aws-cdk-asset-awscli-v1==2.2.240 # via aws-cdk-lib aws-cdk-asset-node-proxy-agent-v6==2.1.0 # via aws-cdk-lib -aws-cdk-cloud-assembly-schema==44.5.0 +aws-cdk-cloud-assembly-schema==44.7.0 # via aws-cdk-lib -aws-cdk-lib==2.201.0 +aws-cdk-lib==2.202.0 # via localstack-core -aws-sam-translator==1.98.0 +aws-sam-translator==1.99.0 # via # cfn-lint # localstack-core @@ -41,7 +41,7 @@ aws-xray-sdk==2.14.0 # via moto-ext awscli==1.40.40 # via localstack-core -awscrt==0.27.2 +awscrt==0.27.4 # via localstack-core boto3==1.38.41 # via @@ -80,7 +80,7 @@ cffi==1.17.1 # via cryptography cfgv==3.4.0 # via pre-commit -cfn-lint==1.36.0 +cfn-lint==1.36.1 # via moto-ext charset-normalizer==3.4.2 # via requests @@ -277,7 +277,7 @@ openapi-spec-validator==0.7.2 # localstack-core (pyproject.toml) # moto-ext # openapi-core -opensearch-py==2.8.0 +opensearch-py==3.0.0 # via localstack-core orderly-set==5.4.1 # via deepdiff @@ -341,7 +341,7 @@ pydantic==2.11.7 # via aws-sam-translator pydantic-core==2.33.2 # via pydantic -pygments==2.19.1 +pygments==2.19.2 # via # pytest # rich @@ -357,7 +357,7 @@ pyparsing==3.2.3 # via moto-ext pyproject-hooks==1.2.0 # via build -pytest==8.4.0 +pytest==8.4.1 # via # localstack-core # pytest-rerunfailures @@ -377,7 +377,7 @@ python-dateutil==2.9.0.post0 # jsii # moto-ext # opensearch-py -python-dotenv==1.1.0 +python-dotenv==1.1.1 # via # localstack-core # localstack-core (pyproject.toml) @@ -433,7 +433,7 @@ rsa==4.7.2 # via awscli rstr==3.2.2 # via localstack-core (pyproject.toml) -ruff==0.11.13 +ruff==0.12.0 # via localstack-core (pyproject.toml) s3transfer==0.13.0 # via @@ -481,7 +481,7 @@ typing-extensions==4.14.0 # typing-inspection typing-inspection==0.4.1 # via pydantic -urllib3==2.4.0 +urllib3==2.5.0 # via # botocore # docker diff --git a/requirements-runtime.txt b/requirements-runtime.txt index 54daa60c01820..7e991ea99a7e8 100644 --- a/requirements-runtime.txt +++ b/requirements-runtime.txt @@ -21,7 +21,7 @@ attrs==25.3.0 # jsonschema # localstack-twisted # referencing -aws-sam-translator==1.98.0 +aws-sam-translator==1.99.0 # via # cfn-lint # localstack-core (pyproject.toml) @@ -29,7 +29,7 @@ aws-xray-sdk==2.14.0 # via moto-ext awscli==1.40.40 # via localstack-core (pyproject.toml) -awscrt==0.27.2 +awscrt==0.27.4 # via localstack-core boto3==1.38.41 # via @@ -62,7 +62,7 @@ certifi==2025.6.15 # requests cffi==1.17.1 # via cryptography -cfn-lint==1.36.0 +cfn-lint==1.36.1 # via moto-ext charset-normalizer==3.4.2 # via requests @@ -206,7 +206,7 @@ openapi-spec-validator==0.7.2 # via # moto-ext # openapi-core -opensearch-py==2.8.0 +opensearch-py==3.0.0 # via localstack-core (pyproject.toml) packaging==25.0 # via @@ -243,7 +243,7 @@ pydantic==2.11.7 # via aws-sam-translator pydantic-core==2.33.2 # via pydantic -pygments==2.19.1 +pygments==2.19.2 # via rich pymongo==4.13.2 # via localstack-core (pyproject.toml) @@ -261,7 +261,7 @@ python-dateutil==2.9.0.post0 # botocore # moto-ext # opensearch-py -python-dotenv==1.1.0 +python-dotenv==1.1.1 # via # localstack-core # localstack-core (pyproject.toml) @@ -345,7 +345,7 @@ typing-extensions==4.14.0 # typing-inspection typing-inspection==0.4.1 # via pydantic -urllib3==2.4.0 +urllib3==2.5.0 # via # botocore # docker diff --git a/requirements-test.txt b/requirements-test.txt index 2c75c80367598..8e4a301f50006 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -25,15 +25,15 @@ attrs==25.3.0 # jsonschema # localstack-twisted # referencing -aws-cdk-asset-awscli-v1==2.2.237 +aws-cdk-asset-awscli-v1==2.2.240 # via aws-cdk-lib aws-cdk-asset-node-proxy-agent-v6==2.1.0 # via aws-cdk-lib -aws-cdk-cloud-assembly-schema==44.5.0 +aws-cdk-cloud-assembly-schema==44.7.0 # via aws-cdk-lib -aws-cdk-lib==2.201.0 +aws-cdk-lib==2.202.0 # via localstack-core (pyproject.toml) -aws-sam-translator==1.98.0 +aws-sam-translator==1.99.0 # via # cfn-lint # localstack-core @@ -41,7 +41,7 @@ aws-xray-sdk==2.14.0 # via moto-ext awscli==1.40.40 # via localstack-core -awscrt==0.27.2 +awscrt==0.27.4 # via localstack-core boto3==1.38.41 # via @@ -78,7 +78,7 @@ certifi==2025.6.15 # requests cffi==1.17.1 # via cryptography -cfn-lint==1.36.0 +cfn-lint==1.36.1 # via moto-ext charset-normalizer==3.4.2 # via requests @@ -252,7 +252,7 @@ openapi-spec-validator==0.7.2 # via # moto-ext # openapi-core -opensearch-py==2.8.0 +opensearch-py==3.0.0 # via localstack-core orderly-set==5.4.1 # via deepdiff @@ -305,7 +305,7 @@ pydantic==2.11.7 # via aws-sam-translator pydantic-core==2.33.2 # via pydantic -pygments==2.19.1 +pygments==2.19.2 # via # pytest # rich @@ -319,7 +319,7 @@ pyparsing==3.2.3 # via moto-ext pyproject-hooks==1.2.0 # via build -pytest==8.4.0 +pytest==8.4.1 # via # localstack-core (pyproject.toml) # pytest-rerunfailures @@ -339,7 +339,7 @@ python-dateutil==2.9.0.post0 # jsii # moto-ext # opensearch-py -python-dotenv==1.1.0 +python-dotenv==1.1.1 # via # localstack-core # localstack-core (pyproject.toml) @@ -436,7 +436,7 @@ typing-extensions==4.14.0 # typing-inspection typing-inspection==0.4.1 # via pydantic -urllib3==2.4.0 +urllib3==2.5.0 # via # botocore # docker diff --git a/requirements-typehint.txt b/requirements-typehint.txt index 5c5190685c3b4..58f5c0c7fc085 100644 --- a/requirements-typehint.txt +++ b/requirements-typehint.txt @@ -25,15 +25,15 @@ attrs==25.3.0 # jsonschema # localstack-twisted # referencing -aws-cdk-asset-awscli-v1==2.2.237 +aws-cdk-asset-awscli-v1==2.2.240 # via aws-cdk-lib aws-cdk-asset-node-proxy-agent-v6==2.1.0 # via aws-cdk-lib -aws-cdk-cloud-assembly-schema==44.5.0 +aws-cdk-cloud-assembly-schema==44.7.0 # via aws-cdk-lib -aws-cdk-lib==2.201.0 +aws-cdk-lib==2.202.0 # via localstack-core -aws-sam-translator==1.98.0 +aws-sam-translator==1.99.0 # via # cfn-lint # localstack-core @@ -41,7 +41,7 @@ aws-xray-sdk==2.14.0 # via moto-ext awscli==1.40.40 # via localstack-core -awscrt==0.27.2 +awscrt==0.27.4 # via localstack-core boto3==1.38.41 # via @@ -49,7 +49,7 @@ boto3==1.38.41 # kclpy-ext # localstack-core # moto-ext -boto3-stubs==1.38.37 +boto3-stubs==1.38.42 # via localstack-core (pyproject.toml) botocore==1.38.41 # via @@ -84,7 +84,7 @@ cffi==1.17.1 # via cryptography cfgv==3.4.0 # via pre-commit -cfn-lint==1.36.0 +cfn-lint==1.36.1 # via moto-ext charset-normalizer==3.4.2 # via requests @@ -262,7 +262,7 @@ multipart==1.2.1 # via moto-ext mypy==1.16.1 # via localstack-core -mypy-boto3-acm==1.38.4 +mypy-boto3-acm==1.38.38 # via boto3-stubs mypy-boto3-acm-pca==1.38.0 # via boto3-stubs @@ -282,9 +282,9 @@ mypy-boto3-appsync==1.38.33 # via boto3-stubs mypy-boto3-athena==1.38.28 # via boto3-stubs -mypy-boto3-autoscaling==1.38.26 +mypy-boto3-autoscaling==1.38.39 # via boto3-stubs -mypy-boto3-backup==1.38.28 +mypy-boto3-backup==1.38.38 # via boto3-stubs mypy-boto3-batch==1.38.0 # via boto3-stubs @@ -316,7 +316,7 @@ mypy-boto3-cognito-identity==1.38.0 # via boto3-stubs mypy-boto3-cognito-idp==1.38.16 # via boto3-stubs -mypy-boto3-dms==1.38.17 +mypy-boto3-dms==1.38.38 # via boto3-stubs mypy-boto3-docdb==1.38.0 # via boto3-stubs @@ -328,7 +328,7 @@ mypy-boto3-ec2==1.38.33 # via boto3-stubs mypy-boto3-ecr==1.38.37 # via boto3-stubs -mypy-boto3-ecs==1.38.36 +mypy-boto3-ecs==1.38.41 # via boto3-stubs mypy-boto3-efs==1.38.33 # via boto3-stubs @@ -342,7 +342,7 @@ mypy-boto3-elbv2==1.38.0 # via boto3-stubs mypy-boto3-emr==1.38.18 # via boto3-stubs -mypy-boto3-emr-serverless==1.38.36 +mypy-boto3-emr-serverless==1.38.40 # via boto3-stubs mypy-boto3-es==1.38.0 # via boto3-stubs @@ -354,7 +354,7 @@ mypy-boto3-fis==1.38.0 # via boto3-stubs mypy-boto3-glacier==1.38.0 # via boto3-stubs -mypy-boto3-glue==1.38.22 +mypy-boto3-glue==1.38.42 # via boto3-stubs mypy-boto3-iam==1.38.14 # via boto3-stubs @@ -380,13 +380,13 @@ mypy-boto3-kms==1.38.36 # via boto3-stubs mypy-boto3-lakeformation==1.38.0 # via boto3-stubs -mypy-boto3-lambda==1.38.0 +mypy-boto3-lambda==1.38.40 # via boto3-stubs -mypy-boto3-logs==1.38.16 +mypy-boto3-logs==1.38.39 # via boto3-stubs mypy-boto3-managedblockchain==1.38.0 # via boto3-stubs -mypy-boto3-mediaconvert==1.38.30 +mypy-boto3-mediaconvert==1.38.41 # via boto3-stubs mypy-boto3-mediastore==1.38.0 # via boto3-stubs @@ -398,7 +398,7 @@ mypy-boto3-neptune==1.38.18 # via boto3-stubs mypy-boto3-opensearch==1.38.0 # via boto3-stubs -mypy-boto3-organizations==1.38.0 +mypy-boto3-organizations==1.38.38 # via boto3-stubs mypy-boto3-pi==1.38.0 # via boto3-stubs @@ -426,11 +426,11 @@ mypy-boto3-route53==1.38.32 # via boto3-stubs mypy-boto3-route53resolver==1.38.0 # via boto3-stubs -mypy-boto3-s3==1.38.26 +mypy-boto3-s3==1.38.39 # via boto3-stubs mypy-boto3-s3control==1.38.14 # via boto3-stubs -mypy-boto3-sagemaker==1.38.37 +mypy-boto3-sagemaker==1.38.40 # via boto3-stubs mypy-boto3-sagemaker-runtime==1.38.0 # via boto3-stubs @@ -454,7 +454,7 @@ mypy-boto3-sso-admin==1.38.12 # via boto3-stubs mypy-boto3-stepfunctions==1.38.0 # via boto3-stubs -mypy-boto3-sts==1.38.0 +mypy-boto3-sts==1.38.38 # via boto3-stubs mypy-boto3-timestream-query==1.38.10 # via boto3-stubs @@ -464,7 +464,7 @@ mypy-boto3-transcribe==1.38.30 # via boto3-stubs mypy-boto3-verifiedpermissions==1.38.7 # via boto3-stubs -mypy-boto3-wafv2==1.38.35 +mypy-boto3-wafv2==1.38.38 # via boto3-stubs mypy-boto3-xray==1.38.0 # via boto3-stubs @@ -487,7 +487,7 @@ openapi-spec-validator==0.7.2 # localstack-core # moto-ext # openapi-core -opensearch-py==2.8.0 +opensearch-py==3.0.0 # via localstack-core orderly-set==5.4.1 # via deepdiff @@ -551,7 +551,7 @@ pydantic==2.11.7 # via aws-sam-translator pydantic-core==2.33.2 # via pydantic -pygments==2.19.1 +pygments==2.19.2 # via # pytest # rich @@ -567,7 +567,7 @@ pyparsing==3.2.3 # via moto-ext pyproject-hooks==1.2.0 # via build -pytest==8.4.0 +pytest==8.4.1 # via # localstack-core # pytest-rerunfailures @@ -587,7 +587,7 @@ python-dateutil==2.9.0.post0 # jsii # moto-ext # opensearch-py -python-dotenv==1.1.0 +python-dotenv==1.1.1 # via # localstack-core # localstack-core (pyproject.toml) @@ -643,7 +643,7 @@ rsa==4.7.2 # via awscli rstr==3.2.2 # via localstack-core -ruff==0.11.13 +ruff==0.12.0 # via localstack-core s3transfer==0.13.0 # via @@ -799,7 +799,7 @@ typing-extensions==4.14.0 # typing-inspection typing-inspection==0.4.1 # via pydantic -urllib3==2.4.0 +urllib3==2.5.0 # via # botocore # docker diff --git a/tests/aws/services/opensearch/test_opensearch.py b/tests/aws/services/opensearch/test_opensearch.py index 1cbf7c14980a0..9e3054a6e2982 100644 --- a/tests/aws/services/opensearch/test_opensearch.py +++ b/tests/aws/services/opensearch/test_opensearch.py @@ -202,8 +202,8 @@ def test_security_plugin(self, opensearch_create_domain, aws_client): test_index_id = "new-index-id" test_document = {"test-key": "test-value"} admin_client = OpenSearch(hosts=endpoint, http_auth=master_user_auth) - admin_client.create(test_index_name, id=test_index_id, body={}) - admin_client.index(test_index_name, body=test_document) + admin_client.create(index=test_index_name, id=test_index_id, body={}) + admin_client.index(index=test_index_name, body=test_document) # create a new "readall" rolemapping test_rolemapping = {"backend_roles": ["readall"], "users": []} @@ -238,10 +238,10 @@ def _search(): retry(_search, sleep=0.5, retries=3) with pytest.raises(AuthorizationException): - test_user_client.create("new-index2", id="new-index-id2", body={}) + test_user_client.create(index="new-index2", id="new-index-id2", body={}) with pytest.raises(AuthorizationException): - test_user_client.index(test_index_name, body={"test-key1": "test-value1"}) + test_user_client.index(index=test_index_name, body={"test-key1": "test-value1"}) # add the user to the all_access role rolemappins_patch = [{"op": "add", "path": "/users/-", "value": "test_user"}] @@ -253,8 +253,8 @@ def _search(): assert response.status_code == 200 # ensure the user can now write and create a new index - test_user_client.create("new-index2", id="new-index-id2", body={}) - test_user_client.index(test_index_name, body={"test-key1": "test-value1"}) + test_user_client.create(index="new-index2", id="new-index-id2", body={}) + test_user_client.index(index=test_index_name, body={"test-key1": "test-value1"}) @markers.aws.validated def test_sql_plugin(self, opensearch_create_domain, aws_client, snapshot, account_id): From c8d9c9e42127baacc91b432ee0f9d2d6d9fa7827 Mon Sep 17 00:00:00 2001 From: Viren Nadkarni Date: Tue, 24 Jun 2025 16:37:35 +0530 Subject: [PATCH 51/74] Bump moto-ext to 5.1.6.post2 (#12760) --- .../localstack/services/iam/provider.py | 11 +++++---- pyproject.toml | 2 +- requirements-dev.txt | 2 +- requirements-runtime.txt | 2 +- requirements-test.txt | 2 +- requirements-typehint.txt | 2 +- .../cloudformation/api/test_nested_stacks.py | 1 + .../iam/aws_iam_user/test_parity.py | 3 +++ tests/aws/services/iam/test_iam.py | 24 ++++++++++++++++++- tests/aws/services/iam/test_iam.snapshot.json | 4 ++-- .../aws/services/iam/test_iam.validation.json | 16 +++++++++++-- tests/aws/services/sts/test_sts.py | 11 ++++++++- 12 files changed, 64 insertions(+), 16 deletions(-) diff --git a/localstack-core/localstack/services/iam/provider.py b/localstack-core/localstack/services/iam/provider.py index 312a2a714aafc..ef640fbc9c051 100644 --- a/localstack-core/localstack/services/iam/provider.py +++ b/localstack-core/localstack/services/iam/provider.py @@ -335,7 +335,7 @@ def list_instance_profile_tags( backend = get_iam_backend(context) profile = backend.get_instance_profile(instance_profile_name) response = ListInstanceProfileTagsResponse() - response["Tags"] = [Tag(Key=k, Value=v) for k, v in profile.tags.items()] + response["Tags"] = profile.tags return response def tag_instance_profile( @@ -347,8 +347,10 @@ def tag_instance_profile( ) -> None: backend = get_iam_backend(context) profile = backend.get_instance_profile(instance_profile_name) - value_by_key = {tag["Key"]: tag["Value"] for tag in tags} - profile.tags.update(value_by_key) + new_keys = [tag["Key"] for tag in tags] + updated_tags = [tag for tag in profile.tags if tag["Key"] not in new_keys] + updated_tags.extend(tags) + profile.tags = updated_tags def untag_instance_profile( self, @@ -359,8 +361,7 @@ def untag_instance_profile( ) -> None: backend = get_iam_backend(context) profile = backend.get_instance_profile(instance_profile_name) - for tag in tag_keys: - profile.tags.pop(tag, None) + profile.tags = [tag for tag in profile.tags if tag["Key"] not in tag_keys] def create_service_linked_role( self, diff --git a/pyproject.toml b/pyproject.toml index 6ba4cd7a8eca1..53ba567b75633 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -93,7 +93,7 @@ runtime = [ "json5>=0.9.11", "jsonpath-ng>=1.6.1", "jsonpath-rw>=1.4.0", - "moto-ext[all]==5.1.5.post1", + "moto-ext[all]==5.1.6.post2", "opensearch-py>=2.4.1", "pymongo>=4.2.0", "pyopenssl>=23.0.0", diff --git a/requirements-dev.txt b/requirements-dev.txt index 10776fabd03b8..461d13f1edb31 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -250,7 +250,7 @@ mdurl==0.1.2 # via markdown-it-py more-itertools==10.7.0 # via openapi-core -moto-ext==5.1.5.post1 +moto-ext==5.1.6.post2 # via localstack-core mpmath==1.3.0 # via sympy diff --git a/requirements-runtime.txt b/requirements-runtime.txt index 7e991ea99a7e8..c39cf45709156 100644 --- a/requirements-runtime.txt +++ b/requirements-runtime.txt @@ -188,7 +188,7 @@ mdurl==0.1.2 # via markdown-it-py more-itertools==10.7.0 # via openapi-core -moto-ext==5.1.5.post1 +moto-ext==5.1.6.post2 # via localstack-core (pyproject.toml) mpmath==1.3.0 # via sympy diff --git a/requirements-test.txt b/requirements-test.txt index 8e4a301f50006..34aafd8ae2eae 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -234,7 +234,7 @@ mdurl==0.1.2 # via markdown-it-py more-itertools==10.7.0 # via openapi-core -moto-ext==5.1.5.post1 +moto-ext==5.1.6.post2 # via localstack-core mpmath==1.3.0 # via sympy diff --git a/requirements-typehint.txt b/requirements-typehint.txt index 58f5c0c7fc085..784140de5f81f 100644 --- a/requirements-typehint.txt +++ b/requirements-typehint.txt @@ -254,7 +254,7 @@ mdurl==0.1.2 # via markdown-it-py more-itertools==10.7.0 # via openapi-core -moto-ext==5.1.5.post1 +moto-ext==5.1.6.post2 # via localstack-core mpmath==1.3.0 # via sympy diff --git a/tests/aws/services/cloudformation/api/test_nested_stacks.py b/tests/aws/services/cloudformation/api/test_nested_stacks.py index c52b173a1ec80..f6b622bc65fd0 100644 --- a/tests/aws/services/cloudformation/api/test_nested_stacks.py +++ b/tests/aws/services/cloudformation/api/test_nested_stacks.py @@ -174,6 +174,7 @@ def _assert_bucket_is_deleted(): "$..Role.Description", "$..Role.MaxSessionDuration", "$..Role.AssumeRolePolicyDocument..Action", + "$..Role.Tags", # Moto returns an empty list for no tags ] ) @markers.aws.validated diff --git a/tests/aws/services/cloudformation/resource_providers/iam/aws_iam_user/test_parity.py b/tests/aws/services/cloudformation/resource_providers/iam/aws_iam_user/test_parity.py index c3e6024d1cdc5..a9c467e6f7c3c 100644 --- a/tests/aws/services/cloudformation/resource_providers/iam/aws_iam_user/test_parity.py +++ b/tests/aws/services/cloudformation/resource_providers/iam/aws_iam_user/test_parity.py @@ -22,6 +22,9 @@ class TestParity: """ @markers.aws.validated + @markers.snapshot.skip_snapshot_verify( + paths=["$..IsTruncated"] + ) # Moto always returns this pagination-related field, AWS only when true def test_create_with_full_properties(self, aws_client, deploy_cfn_template, snapshot, cleanups): """A sort of smoke test that simply covers as many properties as possible""" # TODO: keep extending this test with more properties for higher parity with the official resource on AWS diff --git a/tests/aws/services/iam/test_iam.py b/tests/aws/services/iam/test_iam.py index ef6b6ad5f6ce4..ef10f0165416b 100755 --- a/tests/aws/services/iam/test_iam.py +++ b/tests/aws/services/iam/test_iam.py @@ -160,6 +160,9 @@ def test_create_role_with_malformed_assume_role_policy_document(self, aws_client snapshot.match("invalid-json", e.value.response) @markers.aws.validated + @markers.snapshot.skip_snapshot_verify( + paths=["$..Role.Tags"] + ) # Moto returns an empty list for no tags def test_role_with_path_lifecycle(self, aws_client, snapshot): snapshot.add_transformer(snapshot.transform.iam_api()) role_name = f"role-{short_uid()}" @@ -586,6 +589,9 @@ def test_service_linked_role_name_should_match_aws( aws_client.iam.delete_service_linked_role(RoleName=role_name) @markers.aws.validated + @markers.snapshot.skip_snapshot_verify( + paths=["$..Role.Tags"] + ) # Moto returns an empty list for no tags def test_update_assume_role_policy(self, snapshot, aws_client): snapshot.add_transformer(snapshot.transform.iam_api()) @@ -616,6 +622,9 @@ def test_update_assume_role_policy(self, snapshot, aws_client): aws_client.iam.delete_role(RoleName=role_name) @markers.aws.validated + @markers.snapshot.skip_snapshot_verify( + paths=["$..Role.Tags"] + ) # Moto returns an empty list for no tags def test_create_describe_role(self, snapshot, aws_client, create_role, cleanups): snapshot.add_transformer(snapshot.transform.iam_api()) path_prefix = f"/{short_uid()}/" @@ -644,6 +653,9 @@ def test_create_describe_role(self, snapshot, aws_client, create_role, cleanups) snapshot.match("list_roles_result", list_roles_result) @markers.aws.validated + @markers.snapshot.skip_snapshot_verify( + paths=["$..Role.Tags"] + ) # Moto returns an empty list for no tags def test_list_roles_with_permission_boundary( self, snapshot, aws_client, create_role, create_policy, cleanups ): @@ -692,6 +704,7 @@ def test_list_roles_with_permission_boundary( "$..Policy.IsAttachable", "$..Policy.PermissionsBoundaryUsageCount", "$..Policy.Tags", + "$..Policy.Description", ] ) def test_role_attach_policy(self, snapshot, aws_client, create_role, create_policy): @@ -748,6 +761,7 @@ def test_role_attach_policy(self, snapshot, aws_client, create_role, create_poli "$..Policy.IsAttachable", "$..Policy.PermissionsBoundaryUsageCount", "$..Policy.Tags", + "$..Policy.Description", ] ) def test_user_attach_policy(self, snapshot, aws_client, create_user, create_policy): @@ -819,6 +833,9 @@ def test_put_user_policy_encoding(self, snapshot, aws_client, create_user, regio snapshot.match("get-policy-response", get_policy_response) @markers.aws.validated + @markers.snapshot.skip_snapshot_verify( + paths=["$..Role.Tags"] + ) # Moto returns an empty list for no tags def test_put_role_policy_encoding(self, snapshot, aws_client, create_role, region_name): snapshot.add_transformer(snapshot.transform.iam_api()) @@ -1369,7 +1386,9 @@ def snapshot_transformers(self, snapshot): @markers.aws.validated # last used and the description depend on whether the role was created in the snapshot account by a service or manually - @markers.snapshot.skip_snapshot_verify(paths=["$..Role.RoleLastUsed", "$..Role.Description"]) + @markers.snapshot.skip_snapshot_verify( + paths=["$..Role.RoleLastUsed", "$..Role.Description", "$..Role.Tags"] + ) @pytest.mark.parametrize( "service_name", [pytest.param(service, marks=marker) for service, marker in SERVICES.items()], @@ -1390,6 +1409,9 @@ def test_service_role_lifecycle( snapshot.match("attached-role-policies", response) @markers.aws.validated + @markers.snapshot.skip_snapshot_verify( + paths=["$..Role.Tags"] + ) # Moto returns an empty list for no tags @pytest.mark.parametrize("service_name", SERVICES_CUSTOM_SUFFIX) def test_service_role_lifecycle_custom_suffix( self, aws_client, snapshot, create_service_linked_role, service_name diff --git a/tests/aws/services/iam/test_iam.snapshot.json b/tests/aws/services/iam/test_iam.snapshot.json index 8fd4e2790a27d..6e37bcdd431cf 100644 --- a/tests/aws/services/iam/test_iam.snapshot.json +++ b/tests/aws/services/iam/test_iam.snapshot.json @@ -201,7 +201,7 @@ } }, "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_role_attach_policy": { - "recorded-date": "06-03-2025, 12:25:04", + "recorded-date": "19-06-2025, 11:47:40", "recorded-content": { "create_policy_response": { "Policy": { @@ -325,7 +325,7 @@ } }, "tests/aws/services/iam/test_iam.py::TestIAMExtensions::test_role_with_path_lifecycle": { - "recorded-date": "06-03-2025, 12:24:45", + "recorded-date": "19-06-2025, 11:39:59", "recorded-content": { "create-role-response": { "Role": { diff --git a/tests/aws/services/iam/test_iam.validation.json b/tests/aws/services/iam/test_iam.validation.json index a1858c4acfeaf..41312b6a29073 100644 --- a/tests/aws/services/iam/test_iam.validation.json +++ b/tests/aws/services/iam/test_iam.validation.json @@ -15,7 +15,13 @@ "last_validated_date": "2025-03-06T12:24:26+00:00" }, "tests/aws/services/iam/test_iam.py::TestIAMExtensions::test_role_with_path_lifecycle": { - "last_validated_date": "2025-03-06T12:24:45+00:00" + "last_validated_date": "2025-06-19T11:39:59+00:00", + "durations_in_seconds": { + "setup": 1.34, + "call": 2.25, + "teardown": 0.01, + "total": 3.6 + } }, "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_attach_detach_role_policy": { "last_validated_date": "2025-03-06T12:24:54+00:00" @@ -45,7 +51,13 @@ "last_validated_date": "2025-03-06T12:24:48+00:00" }, "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_role_attach_policy": { - "last_validated_date": "2025-03-06T12:25:03+00:00" + "last_validated_date": "2025-06-19T11:47:40+00:00", + "durations_in_seconds": { + "setup": 1.46, + "call": 5.22, + "teardown": 2.05, + "total": 8.73 + } }, "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_simulate_principle_policy[group]": { "last_validated_date": "2025-04-21T20:07:37+00:00" diff --git a/tests/aws/services/sts/test_sts.py b/tests/aws/services/sts/test_sts.py index 9299d88bbcba4..9e430bbe8b489 100644 --- a/tests/aws/services/sts/test_sts.py +++ b/tests/aws/services/sts/test_sts.py @@ -96,7 +96,10 @@ class TestSTSIntegrations: @markers.aws.validated @markers.snapshot.skip_snapshot_verify( - paths=["$..PackedPolicySize"], + paths=[ + "$..PackedPolicySize", + "$..Role.Tags", # Moto returns an empty list for no tags + ], ) def test_assume_role(self, aws_client, create_role, account_id, snapshot): snapshot.add_transformers_list( @@ -326,6 +329,9 @@ def test_get_caller_identity_role_access_key( class TestSTSAssumeRoleTagging: @markers.aws.validated + @markers.snapshot.skip_snapshot_verify( + paths=["$..Role.Tags"] + ) # Moto returns an empty list for no tags def test_iam_role_chaining_override_transitive_tags( self, aws_client, @@ -408,6 +414,9 @@ def test_iam_role_chaining_override_transitive_tags( snapshot.match("override-transitive-tag-case-ignore-error", e.value.response) @markers.aws.validated + @markers.snapshot.skip_snapshot_verify( + paths=["$..Role.Tags"] + ) # Moto returns an empty list for no tags def test_assume_role_tag_validation( self, aws_client, From 0eddecc6b88f760876c6196d5eb7f9100f2a43c4 Mon Sep 17 00:00:00 2001 From: Anastasia Dusak <61540676+k-a-il@users.noreply.github.com> Date: Tue, 24 Jun 2025 14:03:23 +0200 Subject: [PATCH 52/74] CI: correct test selection propagation for service-specific tests and run them conditionally (#12749) --- .github/workflows/aws-tests.yml | 51 +++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/.github/workflows/aws-tests.yml b/.github/workflows/aws-tests.yml index e44f6a59bc80c..164289732f56e 100644 --- a/.github/workflows/aws-tests.yml +++ b/.github/workflows/aws-tests.yml @@ -201,6 +201,11 @@ jobs: test-preflight: name: "Preflight & Unit-Tests" runs-on: ubuntu-latest + outputs: + cloudwatch-v1: ${{ steps.changes.outputs.cloudwatch-v1 }} + dynamodb-v2: ${{ steps.changes.outputs.dynamodb-v2 }} + events-v1: ${{ steps.changes.outputs.events-v1 }} + cloudformation-v2: ${{ steps.changes.outputs.cloudformation-v2 }} steps: - name: Checkout uses: actions/checkout@v4 @@ -241,6 +246,28 @@ jobs: dist/testselection/test-selection.txt retention-days: 1 + # This step determines which services were affected by changes of the modified files + # The output from this step is later used in combination with the test-selection file + # + # The test-selection file specifies which tests to run for each service, + # while this step allows skipping entire jobs when no relevant services have changed + - name: Determine services affected by change + uses: dorny/paths-filter@v3.0.2 + id: changes + with: + token: ${{ secrets.GITHUB_TOKEN }} + filters: | + cloudwatch-v1: + - 'tests/aws/services/cloudwatch/**' + dynamodb-v2: + - 'tests/aws/services/dynamodb/**' + - 'tests/aws/services/dynamodbstreams/**' + - 'tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py' + events-v1: + - 'tests/aws/services/events/**' + cloudformation-v2: + - 'tests/aws/services/cloudformation/v2/**' + - name: Run Unit Tests timeout-minutes: 8 env: @@ -493,7 +520,6 @@ jobs: test_file_prefix: "-/opt/code/localstack/" action_fail_on_inconclusive: true - test-acceptance: name: "Acceptance Tests (${{ contains(matrix.runner, 'arm') && 'ARM64' || 'AMD64' }})" needs: @@ -608,7 +634,7 @@ jobs: test-cloudwatch-v1: name: Test CloudWatch V1 - if: ${{ !inputs.onlyAcceptanceTests }} + if: ${{ !inputs.onlyAcceptanceTests && (github.ref == 'refs/heads/master' || needs.test-preflight.outputs.cloudwatch-v1 == 'true') }} runs-on: ubuntu-latest needs: - test-preflight @@ -625,6 +651,13 @@ jobs: - name: Prepare Local Test Environment uses: ./.github/actions/setup-tests-env + - name: Download Test Selection + if: ${{ env.TESTSELECTION_PYTEST_ARGS }} + uses: actions/download-artifact@v4 + with: + name: test-selection + path: dist/testselection/ + - name: Run Cloudwatch v1 Provider Tests timeout-minutes: 30 env: @@ -634,7 +667,7 @@ jobs: COVERAGE_FILE: ".coverage.cloudwatch_v1" TEST_PATH: "tests/aws/services/cloudwatch/" JUNIT_REPORTS_FILE: "pytest-junit-cloudwatch-v1.xml" - PYTEST_ARGS: "${{ env.TINYBIRD_PYTEST_ARGS }} --reruns 3 -o junit_suite_name=cloudwatch_v1" + PYTEST_ARGS: "${{ env.TINYBIRD_PYTEST_ARGS }}${{ env.TESTSELECTION_PYTEST_ARGS }} --reruns 3 -o junit_suite_name=cloudwatch_v1" PROVIDER_OVERRIDE_CLOUDWATCH: "v1" run: make test-coverage @@ -651,7 +684,7 @@ jobs: test-ddb-v2: name: Test DynamoDB(Streams) v2 - if: ${{ !inputs.onlyAcceptanceTests }} + if: ${{ !inputs.onlyAcceptanceTests && (github.ref == 'refs/heads/master' || needs.test-preflight.outputs.dynamodb-v2 == 'true') }} runs-on: ubuntu-latest needs: - test-preflight @@ -683,7 +716,7 @@ jobs: COVERAGE_FILE: ".coverage.dynamodb_v2" TEST_PATH: "tests/aws/services/dynamodb/ tests/aws/services/dynamodbstreams/ tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py" JUNIT_REPORTS_FILE: "pytest-junit-dynamodb-v2.xml" - PYTEST_ARGS: "${{ env.TINYBIRD_PYTEST_ARGS }} --reruns 3 -o junit_suite_name=dynamodb_v2" + PYTEST_ARGS: "${{ env.TINYBIRD_PYTEST_ARGS }}${{ env.TESTSELECTION_PYTEST_ARGS }} --reruns 3 -o junit_suite_name=dynamodb_v2" PROVIDER_OVERRIDE_DYNAMODB: "v2" run: make test-coverage @@ -700,7 +733,7 @@ jobs: test-events-v1: name: Test EventBridge v1 - if: ${{ !inputs.onlyAcceptanceTests }} + if: ${{ !inputs.onlyAcceptanceTests && (github.ref == 'refs/heads/master' || needs.test-preflight.outputs.events-v1 == 'true') }} runs-on: ubuntu-latest needs: - test-preflight @@ -733,7 +766,7 @@ jobs: COVERAGE_FILE: ".coverage.events_v1" TEST_PATH: "tests/aws/services/events/" JUNIT_REPORTS_FILE: "pytest-junit-events-v1.xml" - PYTEST_ARGS: "${{ env.TINYBIRD_PYTEST_ARGS }} --reruns 3 -o junit_suite_name=events_v1" + PYTEST_ARGS: "${{ env.TINYBIRD_PYTEST_ARGS }}${{ env.TESTSELECTION_PYTEST_ARGS }} --reruns 3 -o junit_suite_name=events_v1" PROVIDER_OVERRIDE_EVENTS: "v1" run: make test-coverage @@ -749,7 +782,7 @@ jobs: test-cfn-v2-engine: name: Test CloudFormation Engine v2 - if: ${{ !inputs.onlyAcceptanceTests }} + if: ${{ !inputs.onlyAcceptanceTests && ( github.ref == 'refs/heads/master' || needs.test-preflight.outputs.cloudformation-v2 == 'true' )}} runs-on: ubuntu-latest needs: - test-preflight @@ -781,7 +814,7 @@ jobs: # add the GitHub API token to avoid rate limit issues GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} TEST_PATH: "tests/aws/services/cloudformation/v2" - PYTEST_ARGS: "${{ env.TINYBIRD_PYTEST_ARGS }} --reruns 3 -o junit_suite_name='cloudformation_v2'" + PYTEST_ARGS: "${{ env.TINYBIRD_PYTEST_ARGS }}${{ env.TESTSELECTION_PYTEST_ARGS }} --reruns 3 -o junit_suite_name='cloudformation_v2'" PROVIDER_OVERRIDE_CLOUDFORMATION: "engine-v2" run: make test-coverage From fec3c9a0b160d86d3a5bf7edb4dd184c4eee9b51 Mon Sep 17 00:00:00 2001 From: Silvio Vasiljevic Date: Tue, 24 Jun 2025 14:49:49 +0200 Subject: [PATCH 53/74] Fix workflows for forked repositories (#12786) --- .github/workflows/aws-tests.yml | 27 ++++++++++++--------- .github/workflows/tests-cli.yml | 2 +- .github/workflows/tests-podman.yml | 4 +-- .github/workflows/tests-pro-integration.yml | 4 +-- .github/workflows/tests-s3-image.yml | 4 +-- 5 files changed, 23 insertions(+), 18 deletions(-) diff --git a/.github/workflows/aws-tests.yml b/.github/workflows/aws-tests.yml index 164289732f56e..0cc667da7113e 100644 --- a/.github/workflows/aws-tests.yml +++ b/.github/workflows/aws-tests.yml @@ -132,7 +132,7 @@ env: CI_COMMIT_SHA: ${{ github.sha }} CI_JOB_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/attempts/${{ github.run_attempt }} # report to tinybird if executed on master - TINYBIRD_PYTEST_ARGS: "${{ github.ref == 'refs/heads/master' && '--report-to-tinybird ' || '' }}" + TINYBIRD_PYTEST_ARGS: "${{ github.repository == 'localstack/localstack' && github.ref == 'refs/heads/master' && '--report-to-tinybird ' || '' }}" DOCKER_PULL_SECRET_AVAILABLE: ${{ secrets.DOCKERHUB_PULL_USERNAME != '' && secrets.DOCKERHUB_PULL_TOKEN != '' && 'true' || 'false' }} @@ -148,8 +148,9 @@ jobs: - ubuntu-latest - ubuntu-24.04-arm exclude: - # skip the ARM integration tests in case we are not on the master and not on the upgrade-dependencies branch and forceARMTests is not set to true - - runner: ${{ (github.ref != 'refs/heads/master' && github.ref != 'upgrade-dependencies' && inputs.forceARMTests == false) && 'ubuntu-24.04-arm' || ''}} + # skip the ARM integration tests in forks, and also if not on master/upgrade-dependencies and forceARMTests is not set to true + # TODO ARM runners are not yet available for private repositories; skip them for potential private forks + - runner: ${{ ((github.repository != 'localstack/localstack') || (github.ref != 'refs/heads/master' && github.ref != 'upgrade-dependencies' && inputs.forceARMTests == false)) && 'ubuntu-24.04-arm' || ''}} fail-fast: false runs-on: ${{ matrix.runner }} steps: @@ -335,8 +336,9 @@ jobs: - ubuntu-latest - ubuntu-24.04-arm exclude: - # skip the ARM integration tests in case we are not on the master and not on the upgrade-dependencies branch and forceARMTests is not set to true - - runner: ${{ (github.ref != 'refs/heads/master' && github.ref != 'upgrade-dependencies' && inputs.forceARMTests == false) && 'ubuntu-24.04-arm' || ''}} + # skip the ARM integration tests in forks, and also if not on master/upgrade-dependencies and forceARMTests is not set to true + # TODO ARM runners are not yet available for private repositories; skip them for potential private forks + - runner: ${{ ((github.repository != 'localstack/localstack') || (github.ref != 'refs/heads/master' && github.ref != 'upgrade-dependencies' && inputs.forceARMTests == false)) && 'ubuntu-24.04-arm' || ''}} fail-fast: false runs-on: ${{ matrix.runner }} env: @@ -485,8 +487,9 @@ jobs: - amd64 - arm64 exclude: - # skip the ARM integration tests in case we are not on the master and not on the upgrade-dependencies branch and forceARMTests is not set to true - - arch: ${{ (github.ref != 'refs/heads/master' && github.ref != 'upgrade-dependencies' && inputs.forceARMTests == false) && 'arm64' || ''}} + # skip the ARM integration tests in forks, and also if not on master/upgrade-dependencies and forceARMTests is not set to true + # TODO ARM runners are not yet available for private repositories; skip them for potential private forks + - arch: ${{ ((github.repository != 'localstack/localstack') || (github.ref != 'refs/heads/master' && github.ref != 'upgrade-dependencies' && inputs.forceARMTests == false)) && 'arm64' || ''}} needs: - test-integration - test-bootstrap @@ -530,8 +533,9 @@ jobs: - ubuntu-latest - ubuntu-24.04-arm exclude: - # skip the ARM integration tests in case we are not on the master and not on the upgrade-dependencies branch and forceARMTests is not set to true - - runner: ${{ (github.ref != 'refs/heads/master' && github.ref != 'upgrade-dependencies' && inputs.forceARMTests == false) && 'ubuntu-24.04-arm' || ''}} + # skip the ARM integration tests in forks, and also if not on master/upgrade-dependencies and forceARMTests is not set to true + # TODO ARM runners are not yet available for private repositories; skip them for potential private forks + - runner: ${{ ((github.repository != 'localstack/localstack') || (github.ref != 'refs/heads/master' && github.ref != 'upgrade-dependencies' && inputs.forceARMTests == false)) && 'ubuntu-24.04-arm' || ''}} fail-fast: false runs-on: ${{ matrix.runner }} env: @@ -604,8 +608,9 @@ jobs: - amd64 - arm64 exclude: - # skip the ARM integration tests in case we are not on the master and not on the upgrade-dependencies branch and forceARMTests is not set to true - - arch: ${{ (github.ref != 'refs/heads/master' && github.ref != 'upgrade-dependencies' && inputs.forceARMTests == false) && 'arm64' || ''}} + # skip the ARM integration tests in forks, and also if not on master/upgrade-dependencies and forceARMTests is not set to true + # TODO ARM runners are not yet available for private repositories; skip them for potential private forks + - arch: ${{ ((github.repository != 'localstack/localstack') || (github.ref != 'refs/heads/master' && github.ref != 'upgrade-dependencies' && inputs.forceARMTests == false)) && 'arm64' || ''}} needs: - test-acceptance runs-on: ubuntu-latest diff --git a/.github/workflows/tests-cli.yml b/.github/workflows/tests-cli.yml index 9dda7f376e9d1..68eca09252eaf 100644 --- a/.github/workflows/tests-cli.yml +++ b/.github/workflows/tests-cli.yml @@ -65,7 +65,7 @@ env: CI_COMMIT_SHA: ${{ github.sha }} CI_JOB_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/attempts/${{ github.run_attempt }} # report to tinybird if executed on master - TINYBIRD_PYTEST_ARGS: "${{ github.ref == 'refs/heads/master' && '--report-to-tinybird ' || '' }}" + TINYBIRD_PYTEST_ARGS: "${{ github.repository == 'localstack/localstack' && github.ref == 'refs/heads/master' && '--report-to-tinybird ' || '' }}" permissions: contents: read # checkout the repository diff --git a/.github/workflows/tests-podman.yml b/.github/workflows/tests-podman.yml index edd8aeb2926d7..664de59630750 100644 --- a/.github/workflows/tests-podman.yml +++ b/.github/workflows/tests-podman.yml @@ -25,7 +25,7 @@ env: CI_COMMIT_SHA: ${{ github.sha }} CI_JOB_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/attempts/${{ github.run_attempt }} # report to tinybird if executed on master - TINYBIRD_PYTEST_ARGS: "${{ github.ref == 'refs/heads/master' && '--report-to-tinybird ' || '' }}" + TINYBIRD_PYTEST_ARGS: "${{ github.repository == 'localstack/localstack' && github.ref == 'refs/heads/master' && '--report-to-tinybird ' || '' }}" jobs: podman-tests: @@ -77,7 +77,7 @@ jobs: DOCKER_HOST=$podmanSocket make test push-to-tinybird: - if: always() && github.ref == 'refs/heads/master' + if: always() && github.ref == 'refs/heads/master' && github.repository == 'localstack/localstack' runs-on: ubuntu-latest needs: podman-tests steps: diff --git a/.github/workflows/tests-pro-integration.yml b/.github/workflows/tests-pro-integration.yml index 466a470956538..22fe1a82b138e 100644 --- a/.github/workflows/tests-pro-integration.yml +++ b/.github/workflows/tests-pro-integration.yml @@ -102,7 +102,7 @@ env: CI_COMMIT_SHA: ${{ github.sha }} CI_JOB_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/attempts/${{ github.run_attempt }} # report to tinybird if executed on master on community AND pro (targetRef not set) - TINYBIRD_PYTEST_ARGS: "${{ github.ref == 'refs/heads/master' && inputs.targetRef == '' && '--report-to-tinybird ' || '' }}" + TINYBIRD_PYTEST_ARGS: "${{ github.repository == 'localstack/localstack' && github.ref == 'refs/heads/master' && inputs.targetRef == '' && '--report-to-tinybird ' || '' }}" # enable test selection if not running on master and test selection is not explicitly disabled TESTSELECTION_PYTEST_ARGS: "${{ !inputs.disableTestSelection && '--path-filter=../../localstack/target/testselection/test-selection.txt ' || '' }}" @@ -399,7 +399,7 @@ jobs: action_fail_on_inconclusive: true push-to-tinybird: - if: always() && github.ref == 'refs/heads/master' + if: always() && github.ref == 'refs/heads/master' && github.repository == 'localstack/localstack' runs-on: ubuntu-latest needs: publish-pro-test-results steps: diff --git a/.github/workflows/tests-s3-image.yml b/.github/workflows/tests-s3-image.yml index 7d233f79c8aa7..92c8e636e15ff 100644 --- a/.github/workflows/tests-s3-image.yml +++ b/.github/workflows/tests-s3-image.yml @@ -72,7 +72,7 @@ env: CI_COMMIT_SHA: ${{ github.sha }} CI_JOB_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/attempts/${{ github.run_attempt }} # report to tinybird if executed on master - TINYBIRD_PYTEST_ARGS: "${{ github.ref == 'refs/heads/master' && '--report-to-tinybird ' || '' }}" + TINYBIRD_PYTEST_ARGS: "${{ github.repository == 'localstack/localstack' && github.ref == 'refs/heads/master' && '--report-to-tinybird ' || '' }}" jobs: @@ -268,7 +268,7 @@ jobs: failOnError: false push-to-tinybird: - if: always() && github.ref == 'refs/heads/master' + if: always() && github.ref == 'refs/heads/master' && github.repository == 'localstack/localstack' runs-on: ubuntu-latest needs: push-s3-image steps: From 62f162f258aa2da317573ffbae8f83a82ecc5810 Mon Sep 17 00:00:00 2001 From: Ben Simon Hartung <42031100+bentsku@users.noreply.github.com> Date: Tue, 24 Jun 2025 15:05:26 +0200 Subject: [PATCH 54/74] S3: add error for DeleteObject preconditions for regular buckets (#12787) --- .../localstack/services/s3/provider.py | 18 ++++++ tests/aws/services/s3/test_s3_api.py | 48 ++++++++++++++ .../aws/services/s3/test_s3_api.snapshot.json | 64 +++++++++++++++++++ .../services/s3/test_s3_api.validation.json | 36 +++++++++++ 4 files changed, 166 insertions(+) diff --git a/localstack-core/localstack/services/s3/provider.py b/localstack-core/localstack/services/s3/provider.py index 5e96c64e39f93..fa7e3e8377b24 100644 --- a/localstack-core/localstack/services/s3/provider.py +++ b/localstack-core/localstack/services/s3/provider.py @@ -1195,6 +1195,24 @@ def delete_object( ArgumentName="x-amz-bypass-governance-retention", ) + # TODO: this is only supported for Directory Buckets + non_supported_precondition = None + if if_match: + non_supported_precondition = "If-Match" + if if_match_size: + non_supported_precondition = "x-amz-if-match-size" + if if_match_last_modified_time: + non_supported_precondition = "x-amz-if-match-last-modified-time" + if non_supported_precondition: + LOG.warning( + "DeleteObject Preconditions is only supported for Directory Buckets. " + "LocalStack does not support Directory Buckets yet." + ) + raise NotImplementedException( + "A header you provided implies functionality that is not implemented", + Header=non_supported_precondition, + ) + if s3_bucket.versioning_status is None: if version_id and version_id != "null": raise InvalidArgument( diff --git a/tests/aws/services/s3/test_s3_api.py b/tests/aws/services/s3/test_s3_api.py index 8841a94c0e222..8bf43c0ed7bd2 100644 --- a/tests/aws/services/s3/test_s3_api.py +++ b/tests/aws/services/s3/test_s3_api.py @@ -1,3 +1,4 @@ +import datetime import json import string from operator import itemgetter @@ -2341,3 +2342,50 @@ def test_delete_metrics_configuration_twice(self, s3_bucket, aws_client, snapsho with pytest.raises(ClientError) as delete_err: aws_client.s3.delete_bucket_metrics_configuration(Bucket=s3_bucket, Id=metric_id) snapshot.match("delete_bucket_metrics_configuration_2", delete_err.value.response) + + +class TestS3DeletePrecondition: + @markers.aws.validated + def test_delete_object_if_match_non_express(self, s3_bucket, aws_client, snapshot): + key = "test-precondition" + aws_client.s3.put_object(Bucket=s3_bucket, Key=key) + + with pytest.raises(ClientError) as e: + aws_client.s3.delete_object(Bucket=s3_bucket, Key=key, IfMatch="badvalue") + snapshot.match("delete-obj-if-match", e.value.response) + + @markers.aws.validated + def test_delete_object_if_match_modified_non_express(self, s3_bucket, aws_client, snapshot): + key = "test-precondition" + aws_client.s3.put_object(Bucket=s3_bucket, Key=key) + + earlier = datetime.datetime.now(tz=datetime.UTC) - datetime.timedelta(days=1) + + with pytest.raises(ClientError) as e: + aws_client.s3.delete_object(Bucket=s3_bucket, Key=key, IfMatchLastModifiedTime=earlier) + snapshot.match("delete-obj-if-match-last-modified", e.value.response) + + @markers.aws.validated + def test_delete_object_if_match_size_non_express(self, s3_bucket, aws_client, snapshot): + key = "test-precondition" + aws_client.s3.put_object(Bucket=s3_bucket, Key=key) + + with pytest.raises(ClientError) as e: + aws_client.s3.delete_object(Bucket=s3_bucket, Key=key, IfMatchSize=10) + snapshot.match("delete-obj-if-match-size", e.value.response) + + @markers.aws.validated + def test_delete_object_if_match_all_non_express(self, s3_bucket, aws_client, snapshot): + key = "test-precondition" + aws_client.s3.put_object(Bucket=s3_bucket, Key=key) + earlier = datetime.datetime.now(tz=datetime.UTC) - datetime.timedelta(days=1) + + with pytest.raises(ClientError) as e: + aws_client.s3.delete_object( + Bucket=s3_bucket, + Key=key, + IfMatchSize=10, + IfMatch="badvalue", + IfMatchLastModifiedTime=earlier, + ) + snapshot.match("delete-obj-if-match-all", e.value.response) diff --git a/tests/aws/services/s3/test_s3_api.snapshot.json b/tests/aws/services/s3/test_s3_api.snapshot.json index 9c1ecc9115109..8af164cc18edb 100644 --- a/tests/aws/services/s3/test_s3_api.snapshot.json +++ b/tests/aws/services/s3/test_s3_api.snapshot.json @@ -4601,5 +4601,69 @@ } } } + }, + "tests/aws/services/s3/test_s3_api.py::TestS3DeletePrecondition::test_delete_object_if_match_non_express": { + "recorded-date": "23-06-2025, 08:53:20", + "recorded-content": { + "delete-obj-if-match": { + "Error": { + "Code": "NotImplemented", + "Header": "If-Match", + "Message": "A header you provided implies functionality that is not implemented" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 501 + } + } + } + }, + "tests/aws/services/s3/test_s3_api.py::TestS3DeletePrecondition::test_delete_object_if_match_modified_non_express": { + "recorded-date": "23-06-2025, 09:05:52", + "recorded-content": { + "delete-obj-if-match-last-modified": { + "Error": { + "Code": "NotImplemented", + "Header": "x-amz-if-match-last-modified-time", + "Message": "A header you provided implies functionality that is not implemented" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 501 + } + } + } + }, + "tests/aws/services/s3/test_s3_api.py::TestS3DeletePrecondition::test_delete_object_if_match_size_non_express": { + "recorded-date": "23-06-2025, 09:05:59", + "recorded-content": { + "delete-obj-if-match-size": { + "Error": { + "Code": "NotImplemented", + "Header": "x-amz-if-match-size", + "Message": "A header you provided implies functionality that is not implemented" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 501 + } + } + } + }, + "tests/aws/services/s3/test_s3_api.py::TestS3DeletePrecondition::test_delete_object_if_match_all_non_express": { + "recorded-date": "23-06-2025, 09:06:41", + "recorded-content": { + "delete-obj-if-match-all": { + "Error": { + "Code": "NotImplemented", + "Header": "x-amz-if-match-last-modified-time", + "Message": "A header you provided implies functionality that is not implemented" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 501 + } + } + } } } diff --git a/tests/aws/services/s3/test_s3_api.validation.json b/tests/aws/services/s3/test_s3_api.validation.json index 2868dd1906731..b39060bcf5199 100644 --- a/tests/aws/services/s3/test_s3_api.validation.json +++ b/tests/aws/services/s3/test_s3_api.validation.json @@ -68,6 +68,42 @@ "tests/aws/services/s3/test_s3_api.py::TestS3BucketVersioning::test_object_version_id_format": { "last_validated_date": "2025-01-21T18:10:31+00:00" }, + "tests/aws/services/s3/test_s3_api.py::TestS3DeletePrecondition::test_delete_object_if_match_all_non_express": { + "last_validated_date": "2025-06-23T09:06:43+00:00", + "durations_in_seconds": { + "setup": 0.96, + "call": 0.24, + "teardown": 1.13, + "total": 2.33 + } + }, + "tests/aws/services/s3/test_s3_api.py::TestS3DeletePrecondition::test_delete_object_if_match_modified_non_express": { + "last_validated_date": "2025-06-23T09:05:53+00:00", + "durations_in_seconds": { + "setup": 1.05, + "call": 0.23, + "teardown": 1.16, + "total": 2.44 + } + }, + "tests/aws/services/s3/test_s3_api.py::TestS3DeletePrecondition::test_delete_object_if_match_non_express": { + "last_validated_date": "2025-06-23T08:53:21+00:00", + "durations_in_seconds": { + "setup": 1.05, + "call": 0.24, + "teardown": 1.1, + "total": 2.39 + } + }, + "tests/aws/services/s3/test_s3_api.py::TestS3DeletePrecondition::test_delete_object_if_match_size_non_express": { + "last_validated_date": "2025-06-23T09:06:00+00:00", + "durations_in_seconds": { + "setup": 0.98, + "call": 0.22, + "teardown": 1.17, + "total": 2.37 + } + }, "tests/aws/services/s3/test_s3_api.py::TestS3MetricsConfiguration::test_delete_metrics_configuration": { "last_validated_date": "2025-06-13T08:33:19+00:00" }, From 3d56935cbb820982c67c49b0e135f88d519c18d6 Mon Sep 17 00:00:00 2001 From: Daniel Fangl Date: Wed, 25 Jun 2025 10:48:44 +0200 Subject: [PATCH 55/74] Update lambda runtime init, fix legacy ENV format in dockerfile (#12795) --- Dockerfile | 2 +- localstack-core/localstack/services/lambda_/packages.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 6c27ed582e78d..f36c3b327fb4a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -57,7 +57,7 @@ RUN ARCH= && dpkgArch="$(dpkg --print-architecture)" \ && test ! $(which python3.9) SHELL [ "/bin/bash", "-c" ] -ENV LANG C.UTF-8 +ENV LANG=C.UTF-8 # set workdir RUN mkdir -p /opt/code/localstack diff --git a/localstack-core/localstack/services/lambda_/packages.py b/localstack-core/localstack/services/lambda_/packages.py index fd549c1c7ad34..0600b4310ae30 100644 --- a/localstack-core/localstack/services/lambda_/packages.py +++ b/localstack-core/localstack/services/lambda_/packages.py @@ -13,7 +13,7 @@ """Customized LocalStack version of the AWS Lambda Runtime Interface Emulator (RIE). https://github.com/localstack/lambda-runtime-init/blob/localstack/README-LOCALSTACK.md """ -LAMBDA_RUNTIME_DEFAULT_VERSION = "v0.1.33-pre" +LAMBDA_RUNTIME_DEFAULT_VERSION = "v0.1.34-pre" LAMBDA_RUNTIME_VERSION = config.LAMBDA_INIT_RELEASE_VERSION or LAMBDA_RUNTIME_DEFAULT_VERSION LAMBDA_RUNTIME_INIT_URL = "https://github.com/localstack/lambda-runtime-init/releases/download/{version}/aws-lambda-rie-{arch}" From 25552f276e1bf6611a10d23af5796053fe825a0b Mon Sep 17 00:00:00 2001 From: Greg Furman <31275503+gregfurman@users.noreply.github.com> Date: Wed, 25 Jun 2025 18:58:14 +0200 Subject: [PATCH 56/74] feat(handler): Add custom header to all AWS responses from LocalStack (#12769) --- .../localstack/aws/handlers/response.py | 28 ++++++++++++++++ localstack-core/localstack/config.py | 4 +++ localstack-core/localstack/constants.py | 2 ++ .../testing/snapshots/transformer_utility.py | 21 ++++++++++++ tests/aws/conftest.py | 3 ++ .../unit/aws/handlers/response_enrichment.py | 32 +++++++++++++++++++ 6 files changed, 90 insertions(+) create mode 100644 localstack-core/localstack/aws/handlers/response.py create mode 100644 tests/unit/aws/handlers/response_enrichment.py diff --git a/localstack-core/localstack/aws/handlers/response.py b/localstack-core/localstack/aws/handlers/response.py new file mode 100644 index 0000000000000..65046f164d9d7 --- /dev/null +++ b/localstack-core/localstack/aws/handlers/response.py @@ -0,0 +1,28 @@ +import logging + +from localstack import config, constants +from localstack.aws.api import RequestContext +from localstack.aws.chain import Handler, HandlerChain +from localstack.http import Response +from localstack.runtime import hooks + +LOG = logging.getLogger(__name__) + + +class ResponseMetadataEnricher(Handler): + """ + A handler that adds extra metadata to a Response. + """ + + def __call__(self, chain: HandlerChain, context: RequestContext, response: Response): + # Currently, we just add 'x-localstack' in response headers. + response.headers[constants.HEADER_LOCALSTACK_IDENTIFIER] = "true" + + +@hooks.on_infra_start(should_load=config.LOCALSTACK_RESPONSE_HEADER_ENABLED) +def init_response_mutation_handler(): + from localstack.aws.handlers import run_custom_response_handlers + + # inject enricher into handler chain + enricher = ResponseMetadataEnricher() + run_custom_response_handlers.append(enricher) diff --git a/localstack-core/localstack/config.py b/localstack-core/localstack/config.py index c7986b22daa3f..fd26d64c35776 100644 --- a/localstack-core/localstack/config.py +++ b/localstack-core/localstack/config.py @@ -1245,6 +1245,9 @@ def use_custom_dns(): # This flag enables `connect_to` to be in-memory only and not do networking calls IN_MEMORY_CLIENT = is_env_true("IN_MEMORY_CLIENT") +# This flag enables all responses from LocalStack to contain a `x-localstack` HTTP header. +LOCALSTACK_RESPONSE_HEADER_ENABLED = is_env_not_false("LOCALSTACK_RESPONSE_HEADER_ENABLED") + # List of environment variable names used for configuration that are passed from the host into the LocalStack container. # => Synchronize this list with the above and the configuration docs: # https://docs.localstack.cloud/references/configuration/ @@ -1351,6 +1354,7 @@ def use_custom_dns(): "LOCALSTACK_API_KEY", "LOCALSTACK_AUTH_TOKEN", "LOCALSTACK_HOST", + "LOCALSTACK_RESPONSE_HEADER_ENABLED", "LOG_LICENSE_ISSUES", "LS_LOG", "MAIN_CONTAINER_NAME", diff --git a/localstack-core/localstack/constants.py b/localstack-core/localstack/constants.py index f5d43d2bab1e9..c8833e557fced 100644 --- a/localstack-core/localstack/constants.py +++ b/localstack-core/localstack/constants.py @@ -7,6 +7,8 @@ # HTTP headers used to forward proxy request URLs HEADER_LOCALSTACK_EDGE_URL = "x-localstack-edge" HEADER_LOCALSTACK_REQUEST_URL = "x-localstack-request-url" +# HTTP header optionally added to LocalStack responses +HEADER_LOCALSTACK_IDENTIFIER = "x-localstack" # xXx custom localstack authorization header only used in ext HEADER_LOCALSTACK_AUTHORIZATION = "x-localstack-authorization" HEADER_LOCALSTACK_TARGET = "x-localstack-target" diff --git a/localstack-core/localstack/testing/snapshots/transformer_utility.py b/localstack-core/localstack/testing/snapshots/transformer_utility.py index 562cc9e097646..6e6d35ba70689 100644 --- a/localstack-core/localstack/testing/snapshots/transformer_utility.py +++ b/localstack-core/localstack/testing/snapshots/transformer_utility.py @@ -7,6 +7,7 @@ from localstack_snapshot.snapshots.transformer import ( PATTERN_ISO8601, + GenericTransformer, JsonpathTransformer, KeyValueBasedTransformer, RegexTransformer, @@ -109,6 +110,26 @@ def regex(regex: str | Pattern[str], replacement: str): """ return RegexTransformer(regex, replacement) + @staticmethod + def remove_key(key: str): + """Creates a new GenericTransformer that removes all instances of the specified key. + + :param key: the name of the key which should be removed from all responses + :return: GenericTransformer + """ + + def _remove_key_recursive(snapshot_content: dict, *_) -> dict: + def _remove_key_from_data(data): + if isinstance(data, dict): + return {k: _remove_key_from_data(v) for k, v in data.items() if k != key} + elif isinstance(data, list): + return [_remove_key_from_data(item) for item in data] + return data + + return {k: _remove_key_from_data(v) for k, v in snapshot_content.items()} + + return GenericTransformer(_remove_key_recursive) + # TODO add more utility functions? e.g. key_value with function as parameter? @staticmethod diff --git a/tests/aws/conftest.py b/tests/aws/conftest.py index 3292bc6523de5..9ee30b5b925a0 100644 --- a/tests/aws/conftest.py +++ b/tests/aws/conftest.py @@ -118,6 +118,9 @@ def snapshot(request, _snapshot_session: SnapshotSession, account_id, region_nam RegexTransformer(f"arn:{get_partition(region_name)}:", "arn::"), priority=2 ) + # Removes the 'x-localstack' header from all responses + _snapshot_session.add_transformer(_snapshot_session.transform.remove_key("x-localstack")) + # TODO: temporary to migrate to new default transformers. # remove this after all exemptions are gone exemptions = [ diff --git a/tests/unit/aws/handlers/response_enrichment.py b/tests/unit/aws/handlers/response_enrichment.py new file mode 100644 index 0000000000000..4f5f3d7e8ab6d --- /dev/null +++ b/tests/unit/aws/handlers/response_enrichment.py @@ -0,0 +1,32 @@ +import pytest + +from localstack.aws.chain import HandlerChain +from localstack.aws.forwarder import create_aws_request_context +from localstack.aws.handlers.response import ResponseMetadataEnricher +from localstack.constants import HEADER_LOCALSTACK_IDENTIFIER +from localstack.http import Response + + +@pytest.fixture +def response_handler_chain() -> HandlerChain: + return HandlerChain(response_handlers=[ResponseMetadataEnricher()]) + + +class TestResponseMetadataEnricher: + def test_adds_header_to_successful_response(self, response_handler_chain): + context = create_aws_request_context("s3", "ListBuckets") + response = Response("success", 200) + + response_handler_chain.handle(context, response) + + assert response.headers[HEADER_LOCALSTACK_IDENTIFIER] == "true" + + def test_adds_header_to_error_response(self, response_handler_chain): + context = create_aws_request_context( + "opensearch", "DescribeDomain", {"DomainName": "foobar"} + ) + response = Response(b'{"__type": "ResourceNotFoundException"}', 409) + + response_handler_chain.handle(context, response) + + assert response.headers[HEADER_LOCALSTACK_IDENTIFIER] == "true" From 5783fa3f2633f08451f6c47743cea3472e6d446c Mon Sep 17 00:00:00 2001 From: Ben Simon Hartung <42031100+bentsku@users.noreply.github.com> Date: Thu, 26 Jun 2025 10:05:37 +0200 Subject: [PATCH 57/74] S3: add validation around Retention Mode & consider COMPLIANCE when updating (#12782) --- .../localstack/services/s3/provider.py | 55 +++++-- tests/aws/services/s3/test_s3.py | 151 ++++++++++++++++- tests/aws/services/s3/test_s3.snapshot.json | 155 +++++++++++++++++- tests/aws/services/s3/test_s3.validation.json | 42 ++++- tests/aws/services/s3/test_s3_api.py | 15 ++ .../aws/services/s3/test_s3_api.snapshot.json | 12 +- .../services/s3/test_s3_api.validation.json | 8 +- 7 files changed, 414 insertions(+), 24 deletions(-) diff --git a/localstack-core/localstack/services/s3/provider.py b/localstack-core/localstack/services/s3/provider.py index fa7e3e8377b24..b7f1831fa35e0 100644 --- a/localstack-core/localstack/services/s3/provider.py +++ b/localstack-core/localstack/services/s3/provider.py @@ -326,6 +326,7 @@ STORAGE_CLASSES = get_class_attrs_from_spec_class(StorageClass) SSE_ALGORITHMS = get_class_attrs_from_spec_class(ServerSideEncryption) OBJECT_OWNERSHIPS = get_class_attrs_from_spec_class(ObjectOwnership) +OBJECT_LOCK_MODES = get_class_attrs_from_spec_class(ObjectLockMode) DEFAULT_S3_TMP_DIR = "/tmp/localstack-s3-storage" @@ -3702,6 +3703,9 @@ def put_object_lock_configuration( ): raise MalformedXML() + if default_retention["Mode"] not in OBJECT_LOCK_MODES: + raise MalformedXML() + s3_bucket.object_lock_default_retention = default_retention if not s3_bucket.object_lock_enabled: s3_bucket.object_lock_enabled = True @@ -3826,8 +3830,9 @@ def put_object_retention( http_method="PUT", ) - if retention and not validate_dict_fields( - retention, required_fields={"Mode", "RetainUntilDate"} + if retention and ( + not validate_dict_fields(retention, required_fields={"Mode", "RetainUntilDate"}) + or retention["Mode"] not in OBJECT_LOCK_MODES ): raise MalformedXML() @@ -3841,11 +3846,19 @@ def put_object_retention( ArgumentValue=pst_datetime.strftime("%a %b %d %H:%M:%S %Z %Y"), ) - if ( + is_request_reducing_locking = ( not retention or (s3_object.lock_until and s3_object.lock_until > retention["RetainUntilDate"]) - ) and not ( - bypass_governance_retention and s3_object.lock_mode == ObjectLockMode.GOVERNANCE + or ( + retention["Mode"] == ObjectLockMode.GOVERNANCE + and s3_object.lock_mode == ObjectLockMode.COMPLIANCE + ) + ) + if is_request_reducing_locking and ( + s3_object.lock_mode == ObjectLockMode.COMPLIANCE + or ( + s3_object.lock_mode == ObjectLockMode.GOVERNANCE and not bypass_governance_retention + ) ): raise AccessDenied("Access Denied because object protected by object lock.") @@ -4718,18 +4731,34 @@ def get_object_lock_parameters_from_bucket_and_request( request: PutObjectRequest | CopyObjectRequest | CreateMultipartUploadRequest, s3_bucket: S3Bucket, ): - # TODO: also validate here? lock_mode = request.get("ObjectLockMode") lock_legal_status = request.get("ObjectLockLegalHoldStatus") lock_until = request.get("ObjectLockRetainUntilDate") - if default_retention := s3_bucket.object_lock_default_retention: - lock_mode = lock_mode or default_retention.get("Mode") - if lock_mode and not lock_until: - lock_until = get_retention_from_now( - days=default_retention.get("Days"), - years=default_retention.get("Years"), - ) + if lock_mode and not lock_until: + raise InvalidArgument( + "x-amz-object-lock-retain-until-date and x-amz-object-lock-mode must both be supplied", + ArgumentName="x-amz-object-lock-retain-until-date", + ) + elif not lock_mode and lock_until: + raise InvalidArgument( + "x-amz-object-lock-retain-until-date and x-amz-object-lock-mode must both be supplied", + ArgumentName="x-amz-object-lock-mode", + ) + + if lock_mode and lock_mode not in OBJECT_LOCK_MODES: + raise InvalidArgument( + "Unknown wormMode directive.", + ArgumentName="x-amz-object-lock-mode", + ArgumentValue=lock_mode, + ) + + if (default_retention := s3_bucket.object_lock_default_retention) and not lock_mode: + lock_mode = default_retention["Mode"] + lock_until = get_retention_from_now( + days=default_retention.get("Days"), + years=default_retention.get("Years"), + ) return ObjectLockParameters(lock_until, lock_legal_status, lock_mode) diff --git a/tests/aws/services/s3/test_s3.py b/tests/aws/services/s3/test_s3.py index 0a16f083aaf8b..eec48136ee923 100644 --- a/tests/aws/services/s3/test_s3.py +++ b/tests/aws/services/s3/test_s3.py @@ -9206,6 +9206,16 @@ def test_s3_object_retention_exc(self, aws_client, s3_create_bucket, snapshot): ) snapshot.match("update-retention-past-date", e.value.response) + # update a retention with a bad ObjectLock Mode + with pytest.raises(ClientError) as e: + aws_client.s3.put_object_retention( + Bucket=s3_bucket_locked, + Key=object_key, + VersionId=version_id, + Retention={"Mode": "BAD-VALUE", "RetainUntilDate": future_datetime}, + ) + snapshot.match("update-retention-bad-value", e.value.response) + s3_bucket_basic = s3_create_bucket(ObjectLockEnabledForBucket=False) # same as default aws_client.s3.put_object(Bucket=s3_bucket_basic, Key=object_key, Body="test") # put object retention in a object in bucket without lock configured @@ -9261,7 +9271,6 @@ def test_s3_object_retention(self, aws_client, s3_create_bucket, snapshot): BypassGovernanceRetention=True, ) snapshot.match("delete-obj-locked-bypass", response) - # TODO: add retention on delete marker? todo add delete marker on locked object? put_obj_2 = aws_client.s3.put_object( Bucket=s3_bucket_lock, @@ -9280,7 +9289,8 @@ def test_s3_object_retention(self, aws_client, s3_create_bucket, snapshot): Key=object_key, Retention={ "Mode": "GOVERNANCE", - "RetainUntilDate": datetime.datetime.utcnow() + datetime.timedelta(seconds=5), + "RetainUntilDate": datetime.datetime.now(tz=datetime.UTC) + + datetime.timedelta(seconds=5), }, ) snapshot.match("update-retention-locked-object", e.value.response) @@ -9299,7 +9309,8 @@ def test_s3_object_retention(self, aws_client, s3_create_bucket, snapshot): Key=object_key, Retention={ "Mode": "GOVERNANCE", - "RetainUntilDate": datetime.datetime.utcnow() + datetime.timedelta(seconds=5), + "RetainUntilDate": datetime.datetime.now(tz=datetime.UTC) + + datetime.timedelta(seconds=5), }, ) snapshot.match("update-retention-object", update_retention) @@ -9400,6 +9411,15 @@ def test_bucket_config_default_retention(self, s3_create_bucket, snapshot, aws_c head_object = aws_client.s3.head_object(Bucket=bucket_name, Key=object_key) snapshot.match("head-object-with-lock", head_object) + with pytest.raises(ClientError) as e: + aws_client.s3.put_object( + Bucket=bucket_name, + Key=object_key + "2", + Body="test-put-object-lock", + ObjectLockMode="GOVERNANCE", + ) + snapshot.match("put-object-with-lock-no-date", e.value.response) + @markers.aws.validated def test_object_lock_delete_markers(self, s3_create_bucket, snapshot, aws_client): snapshot.add_transformer(snapshot.transform.key_value("VersionId")) @@ -9490,6 +9510,131 @@ def test_object_lock_extend_duration(self, s3_create_bucket, snapshot, aws_clien ) snapshot.match("put-object-retention-reduce", e.value.response) + @markers.aws.validated + def test_s3_object_retention_compliance_mode(self, aws_client, s3_create_bucket, snapshot): + # BEWARE of this test! + # using `COMPLIANCE` will make the object virtually *impossible* to delete, so don't set a long duration + # for the `RetainUntilDate` + # only way to delete the object and indirectly the bucket will be to delete the AWS Account + # see https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lock.html#object-lock-overview + # > The only way to delete an object under the compliance mode before its retention date expires is to delete + # > the associated AWS account. + snapshot.add_transformer(snapshot.transform.key_value("VersionId")) + object_key = "test-retention-locked-object" + + s3_bucket_lock = s3_create_bucket(ObjectLockEnabledForBucket=True) + put_obj_1 = aws_client.s3.put_object(Bucket=s3_bucket_lock, Key=object_key, Body="test") + snapshot.match("put-obj-locked-1", put_obj_1) + + version_id = put_obj_1["VersionId"] + + short_future = datetime.datetime.now(tz=datetime.UTC) + datetime.timedelta(seconds=5) + + update_retention = aws_client.s3.put_object_retention( + Bucket=s3_bucket_lock, + Key=object_key, + Retention={ + "Mode": "COMPLIANCE", + "RetainUntilDate": short_future, + }, + ) + snapshot.match("add-compliance-retention", update_retention) + + # delete object with retention lock without bypass before 5 seconds + with pytest.raises(ClientError) as e: + aws_client.s3.delete_object(Bucket=s3_bucket_lock, Key=object_key, VersionId=version_id) + snapshot.match("delete-locked-1", e.value.response) + + put_delete_marker = aws_client.s3.delete_object(Bucket=s3_bucket_lock, Key=object_key) + snapshot.match("put-delete-marker", put_delete_marker) + + # delete object with retention lock with bypass before 5 seconds + with pytest.raises(ClientError) as e: + aws_client.s3.delete_object( + Bucket=s3_bucket_lock, + Key=object_key, + VersionId=version_id, + BypassGovernanceRetention=True, + ) + snapshot.match("delete-locked-2", e.value.response) + + # update a retention to be lower than the existing one without bypass + earlier_datetime = short_future - datetime.timedelta(seconds=1) + with pytest.raises(ClientError) as e: + aws_client.s3.put_object_retention( + Bucket=s3_bucket_lock, + Key=object_key, + VersionId=version_id, + Retention={"Mode": "COMPLIANCE", "RetainUntilDate": earlier_datetime}, + ) + snapshot.match("update-retention-shortened", e.value.response) + + # update a retention to be less restrictive than COMPLIANCE + earlier_datetime = short_future + datetime.timedelta(seconds=1) + with pytest.raises(ClientError) as e: + aws_client.s3.put_object_retention( + Bucket=s3_bucket_lock, + Key=object_key, + VersionId=version_id, + Retention={"Mode": "GOVERNANCE", "RetainUntilDate": earlier_datetime}, + ) + snapshot.match("update-retention-less-restrictive", e.value.response) + + # delete object with lock without bypass after 5 seconds + sleep = 10 if is_aws_cloud() else 6 + time.sleep(sleep) + + response = aws_client.s3.delete_object( + Bucket=s3_bucket_lock, + Key=object_key, + VersionId=version_id, + ) + snapshot.match("delete-obj-after-lock-expiration", response) + + @markers.aws.validated + def test_s3_object_lock_mode_validation(self, aws_client, s3_create_bucket, snapshot): + snapshot.add_transformer(snapshot.transform.key_value("VersionId")) + object_key = "test-retention-validation" + + s3_bucket_lock = s3_create_bucket(ObjectLockEnabledForBucket=True) + + with pytest.raises(ClientError) as e: + aws_client.s3.put_object( + Bucket=s3_bucket_lock, + Key=object_key, + Body="test", + ObjectLockMode="BAD-VALUE", + ) + snapshot.match("put-obj-locked-error-no-retain-date", e.value.response) + + with pytest.raises(ClientError) as e: + aws_client.s3.put_object( + Bucket=s3_bucket_lock, + Key=object_key, + Body="test", + ObjectLockRetainUntilDate=datetime.datetime.now() + datetime.timedelta(minutes=10), + ) + snapshot.match("put-obj-locked-error-no-mode", e.value.response) + + with pytest.raises(ClientError) as e: + aws_client.s3.put_object( + Bucket=s3_bucket_lock, + Key=object_key, + Body="test", + ObjectLockMode="BAD-VALUE", + ObjectLockRetainUntilDate=datetime.datetime.now() + datetime.timedelta(minutes=10), + ) + snapshot.match("put-obj-locked-bad-value", e.value.response) + + with pytest.raises(ClientError) as e: + aws_client.s3.create_multipart_upload( + Bucket=s3_bucket_lock, + Key=object_key, + ObjectLockMode="BAD-VALUE", + ObjectLockRetainUntilDate=datetime.datetime.now() + datetime.timedelta(minutes=10), + ) + snapshot.match("create-mpu-locked-bad-value", e.value.response) + class TestS3ObjectLockLegalHold: @markers.aws.validated diff --git a/tests/aws/services/s3/test_s3.snapshot.json b/tests/aws/services/s3/test_s3.snapshot.json index 5bdf50c8c4091..dff76f017a6a5 100644 --- a/tests/aws/services/s3/test_s3.snapshot.json +++ b/tests/aws/services/s3/test_s3.snapshot.json @@ -9574,7 +9574,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3ObjectLockRetention::test_s3_object_retention_exc": { - "recorded-date": "23-01-2025, 11:12:34", + "recorded-date": "20-06-2025, 16:29:06", "recorded-content": { "put-object-retention-no-bucket": { "Error": { @@ -9640,6 +9640,16 @@ "HTTPStatusCode": 400 } }, + "update-retention-bad-value": { + "Error": { + "Code": "MalformedXML", + "Message": "The XML you provided was not well-formed or did not validate against our published schema" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 400 + } + }, "put-object-retention-regular-bucket": { "Error": { "Code": "InvalidRequest", @@ -9723,7 +9733,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3ObjectLockRetention::test_s3_object_retention": { - "recorded-date": "21-01-2025, 18:17:58", + "recorded-date": "20-06-2025, 17:02:01", "recorded-content": { "put-obj-locked-1": { "ChecksumCRC32": "2H9+DA==", @@ -9821,7 +9831,7 @@ } }, "tests/aws/services/s3/test_s3.py::TestS3ObjectLockRetention::test_bucket_config_default_retention": { - "recorded-date": "21-01-2025, 18:18:03", + "recorded-date": "20-06-2025, 17:35:52", "recorded-content": { "put-lock-config": { "ResponseMetadata": { @@ -9882,6 +9892,17 @@ "HTTPHeaders": {}, "HTTPStatusCode": 200 } + }, + "put-object-with-lock-no-date": { + "Error": { + "ArgumentName": "x-amz-object-lock-retain-until-date", + "Code": "InvalidArgument", + "Message": "x-amz-object-lock-retain-until-date and x-amz-object-lock-mode must both be supplied" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 400 + } } } }, @@ -17795,5 +17816,133 @@ } } } + }, + "tests/aws/services/s3/test_s3.py::TestS3ObjectLockRetention::test_s3_object_retention_compliance_mode": { + "recorded-date": "20-06-2025, 17:19:56", + "recorded-content": { + "put-obj-locked-1": { + "ChecksumCRC32": "2H9+DA==", + "ChecksumType": "FULL_OBJECT", + "ETag": "\"098f6bcd4621d373cade4e832627b4f6\"", + "ServerSideEncryption": "AES256", + "VersionId": "", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "add-compliance-retention": { + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "delete-locked-1": { + "Error": { + "Code": "AccessDenied", + "Message": "Access Denied because object protected by object lock." + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 403 + } + }, + "put-delete-marker": { + "DeleteMarker": true, + "VersionId": "", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 204 + } + }, + "delete-locked-2": { + "Error": { + "Code": "AccessDenied", + "Message": "Access Denied because object protected by object lock." + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 403 + } + }, + "update-retention-shortened": { + "Error": { + "Code": "AccessDenied", + "Message": "Access Denied because object protected by object lock." + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 403 + } + }, + "update-retention-less-restrictive": { + "Error": { + "Code": "AccessDenied", + "Message": "Access Denied because object protected by object lock." + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 403 + } + }, + "delete-obj-after-lock-expiration": { + "VersionId": "", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 204 + } + } + } + }, + "tests/aws/services/s3/test_s3.py::TestS3ObjectLockRetention::test_s3_object_lock_mode_validation": { + "recorded-date": "20-06-2025, 17:33:40", + "recorded-content": { + "put-obj-locked-error-no-retain-date": { + "Error": { + "ArgumentName": "x-amz-object-lock-retain-until-date", + "Code": "InvalidArgument", + "Message": "x-amz-object-lock-retain-until-date and x-amz-object-lock-mode must both be supplied" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 400 + } + }, + "put-obj-locked-error-no-mode": { + "Error": { + "ArgumentName": "x-amz-object-lock-mode", + "Code": "InvalidArgument", + "Message": "x-amz-object-lock-retain-until-date and x-amz-object-lock-mode must both be supplied" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 400 + } + }, + "put-obj-locked-bad-value": { + "Error": { + "ArgumentName": "x-amz-object-lock-mode", + "ArgumentValue": "BAD-VALUE", + "Code": "InvalidArgument", + "Message": "Unknown wormMode directive." + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 400 + } + }, + "create-mpu-locked-bad-value": { + "Error": { + "ArgumentName": "x-amz-object-lock-mode", + "ArgumentValue": "BAD-VALUE", + "Code": "InvalidArgument", + "Message": "Unknown wormMode directive." + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 400 + } + } + } } } diff --git a/tests/aws/services/s3/test_s3.validation.json b/tests/aws/services/s3/test_s3.validation.json index ecfb962312509..0f24173899c38 100644 --- a/tests/aws/services/s3/test_s3.validation.json +++ b/tests/aws/services/s3/test_s3.validation.json @@ -900,7 +900,13 @@ "last_validated_date": "2025-01-21T18:17:18+00:00" }, "tests/aws/services/s3/test_s3.py::TestS3ObjectLockRetention::test_bucket_config_default_retention": { - "last_validated_date": "2025-01-21T18:18:03+00:00" + "last_validated_date": "2025-06-20T17:35:53+00:00", + "durations_in_seconds": { + "setup": 0.48, + "call": 1.55, + "teardown": 1.78, + "total": 3.81 + } }, "tests/aws/services/s3/test_s3.py::TestS3ObjectLockRetention::test_object_lock_delete_markers": { "last_validated_date": "2025-01-21T18:18:05+00:00" @@ -911,11 +917,41 @@ "tests/aws/services/s3/test_s3.py::TestS3ObjectLockRetention::test_s3_copy_object_retention_lock": { "last_validated_date": "2025-01-21T18:18:00+00:00" }, + "tests/aws/services/s3/test_s3.py::TestS3ObjectLockRetention::test_s3_object_lock_mode_validation": { + "last_validated_date": "2025-06-20T17:33:41+00:00", + "durations_in_seconds": { + "setup": 0.43, + "call": 1.68, + "teardown": 0.86, + "total": 2.97 + } + }, "tests/aws/services/s3/test_s3.py::TestS3ObjectLockRetention::test_s3_object_retention": { - "last_validated_date": "2025-01-21T18:17:58+00:00" + "last_validated_date": "2025-06-20T17:02:02+00:00", + "durations_in_seconds": { + "setup": 0.47, + "call": 12.42, + "teardown": 0.62, + "total": 13.51 + } + }, + "tests/aws/services/s3/test_s3.py::TestS3ObjectLockRetention::test_s3_object_retention_compliance_mode": { + "last_validated_date": "2025-06-20T17:19:57+00:00", + "durations_in_seconds": { + "setup": 0.44, + "call": 11.7, + "teardown": 1.29, + "total": 13.43 + } }, "tests/aws/services/s3/test_s3.py::TestS3ObjectLockRetention::test_s3_object_retention_exc": { - "last_validated_date": "2025-01-23T11:12:34+00:00" + "last_validated_date": "2025-06-20T16:29:08+00:00", + "durations_in_seconds": { + "setup": 0.5, + "call": 3.38, + "teardown": 2.69, + "total": 6.57 + } }, "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_default_checksum": { "last_validated_date": "2025-03-17T21:46:24+00:00" diff --git a/tests/aws/services/s3/test_s3_api.py b/tests/aws/services/s3/test_s3_api.py index 8bf43c0ed7bd2..533be5cd2b30e 100644 --- a/tests/aws/services/s3/test_s3_api.py +++ b/tests/aws/services/s3/test_s3_api.py @@ -1432,6 +1432,21 @@ def test_put_object_lock_configuration_exc(self, s3_create_bucket, aws_client, s ) snapshot.match("put-lock-config-no-days", e.value.response) + with pytest.raises(ClientError) as e: + aws_client.s3.put_object_lock_configuration( + Bucket=s3_bucket, + ObjectLockConfiguration={ + "ObjectLockEnabled": "Enabled", + "Rule": { + "DefaultRetention": { + "Mode": "BAD-VALUE", + "Days": 1, + } + }, + }, + ) + snapshot.match("put-lock-config-bad-mode", e.value.response) + with pytest.raises(ClientError) as e: aws_client.s3.put_object_lock_configuration( Bucket=s3_bucket, diff --git a/tests/aws/services/s3/test_s3_api.snapshot.json b/tests/aws/services/s3/test_s3_api.snapshot.json index 8af164cc18edb..a12844bbb8c67 100644 --- a/tests/aws/services/s3/test_s3_api.snapshot.json +++ b/tests/aws/services/s3/test_s3_api.snapshot.json @@ -2489,7 +2489,7 @@ } }, "tests/aws/services/s3/test_s3_api.py::TestS3ObjectLock::test_put_object_lock_configuration_exc": { - "recorded-date": "21-01-2025, 18:11:40", + "recorded-date": "20-06-2025, 17:03:24", "recorded-content": { "put-lock-config-no-enabled": { "Error": { @@ -2541,6 +2541,16 @@ "HTTPStatusCode": 400 } }, + "put-lock-config-bad-mode": { + "Error": { + "Code": "MalformedXML", + "Message": "The XML you provided was not well-formed or did not validate against our published schema" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 400 + } + }, "put-lock-config-both-days-years": { "Error": { "Code": "MalformedXML", diff --git a/tests/aws/services/s3/test_s3_api.validation.json b/tests/aws/services/s3/test_s3_api.validation.json index b39060bcf5199..ba2d226ba406f 100644 --- a/tests/aws/services/s3/test_s3_api.validation.json +++ b/tests/aws/services/s3/test_s3_api.validation.json @@ -186,7 +186,13 @@ "last_validated_date": "2025-01-21T18:11:37+00:00" }, "tests/aws/services/s3/test_s3_api.py::TestS3ObjectLock::test_put_object_lock_configuration_exc": { - "last_validated_date": "2025-01-21T18:11:40+00:00" + "last_validated_date": "2025-06-20T17:03:25+00:00", + "durations_in_seconds": { + "setup": 0.55, + "call": 2.64, + "teardown": 0.83, + "total": 4.02 + } }, "tests/aws/services/s3/test_s3_api.py::TestS3ObjectLock::test_put_object_lock_configuration_on_existing_bucket": { "last_validated_date": "2025-01-21T18:11:36+00:00" From 21b3a065cdadfc5f93a0e23bdf2aa18815793f97 Mon Sep 17 00:00:00 2001 From: Daniel Fangl Date: Thu, 26 Jun 2025 15:00:41 +0200 Subject: [PATCH 58/74] Fix logging placeholder for apigateway openapi import (#12800) --- localstack-core/localstack/services/apigateway/helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/localstack-core/localstack/services/apigateway/helpers.py b/localstack-core/localstack/services/apigateway/helpers.py index 6cb103d50f637..8e69a9218e6e2 100644 --- a/localstack-core/localstack/services/apigateway/helpers.py +++ b/localstack-core/localstack/services/apigateway/helpers.py @@ -739,7 +739,7 @@ def add_path_methods(rel_path: str, parts: List[str], parent_id=""): model_ref = media_type.get("schema", {}).get("$ref") continue LOG.warning( - "Found '%s' content-type for the MethodResponse model for path '%s' and method '', not adding the model as currently not supported", + "Found '%s' content-type for the MethodResponse model for path '%s' and method '%s', not adding the model as currently not supported", content_type, rel_path, method_name, From 019d5ec1e33ad4dceec01d50c2c0046f925df284 Mon Sep 17 00:00:00 2001 From: Paolo Salvatori Date: Thu, 26 Jun 2025 16:38:58 +0200 Subject: [PATCH 59/74] Add In_WSL function to check whether the host runs on WSL (#12799) --- .gitignore | 1 + localstack-core/localstack/config.py | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/.gitignore b/.gitignore index 548059743cd07..eebbe6e846c4f 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ .coverage.* htmlcov *.orig +*.sln # ignore .vs files that store temproray cache of visual studio workspace settings .vs diff --git a/localstack-core/localstack/config.py b/localstack-core/localstack/config.py index fd26d64c35776..efbfbf83e6fd3 100644 --- a/localstack-core/localstack/config.py +++ b/localstack-core/localstack/config.py @@ -277,6 +277,10 @@ def is_windows() -> bool: return platform.system().lower() == "windows" +def is_wsl() -> bool: + return platform.system().lower() == "linux" and os.environ.get("WSL_DISTRO_NAME") is not None + + def ping(host): """Returns True if the host responds to a ping request""" is_in_windows = is_windows() @@ -384,6 +388,8 @@ def in_docker(): is_in_docker = in_docker() is_in_linux = is_linux() is_in_macos = is_macos() +is_in_windows = is_windows() +is_in_wsl = is_wsl() default_ip = "0.0.0.0" if is_in_docker else "127.0.0.1" # CLI specific: the configuration profile to load From 1860a5448c24c29512bd0105dfbb4de80cc0cfe5 Mon Sep 17 00:00:00 2001 From: Arthur Akhadov <48313237+ArthurAkh@users.noreply.github.com> Date: Fri, 27 Jun 2025 00:33:52 +0200 Subject: [PATCH 60/74] APIGW: add negative tests for IntegrationResponse and improve error handling in PutIntegrationResponse and GetIntegrationResponse (#12773) --- .../services/apigateway/legacy/provider.py | 51 ++++- .../apigateway/test_apigateway_api.py | 207 ++++++++++++++++++ .../test_apigateway_api.snapshot.json | 164 ++++++++++++++ .../test_apigateway_api.validation.json | 63 ++++++ 4 files changed, 477 insertions(+), 8 deletions(-) diff --git a/localstack-core/localstack/services/apigateway/legacy/provider.py b/localstack-core/localstack/services/apigateway/legacy/provider.py index aede11a1580d8..f8e1c3b3d141c 100644 --- a/localstack-core/localstack/services/apigateway/legacy/provider.py +++ b/localstack-core/localstack/services/apigateway/legacy/provider.py @@ -2059,17 +2059,40 @@ def get_integration_response( status_code: StatusCode, **kwargs, ) -> IntegrationResponse: + if not re.fullmatch(r"[1-5]\d\d", status_code): + raise CommonServiceException( + code="ValidationException", + message=f"1 validation error detected: Value '{status_code}' at 'statusCode' failed to " + f"satisfy constraint: Member must satisfy regular expression pattern: [1-5]\\d\\d", + ) + try: + moto_rest_api = get_moto_rest_api(context, rest_api_id) + except NotFoundException: + raise NotFoundException("Invalid Resource identifier specified") + + if not (moto_resource := moto_rest_api.resources.get(resource_id)): + raise NotFoundException("Invalid Resource identifier specified") + + if not (moto_method := moto_resource.resource_methods.get(http_method)): + raise NotFoundException("Invalid Method identifier specified") + + if not moto_method.method_integration: + raise NotFoundException("Invalid Integration identifier specified") + if not ( + integration_responses := moto_method.method_integration.integration_responses + ) or not (integration_response := integration_responses.get(status_code)): + raise NotFoundException("Invalid Response status code specified") + response: IntegrationResponse = call_moto(context) remove_empty_attributes_from_integration_response(response) # moto does not return selectionPattern is set to an empty string # TODO: fix upstream - if "selectionPattern" not in response: - moto_rest_api = get_moto_rest_api(context, rest_api_id) - moto_resource = moto_rest_api.resources.get(resource_id) - method_integration = moto_resource.resource_methods[http_method].method_integration - integration_response = method_integration.integration_responses[status_code] - if integration_response.selection_pattern is not None: - response["selectionPattern"] = integration_response.selection_pattern + if ( + "selectionPattern" not in response + and integration_response + and integration_response.selection_pattern is not None + ): + response["selectionPattern"] = integration_response.selection_pattern return response @handler("PutIntegrationResponse", expand=False) @@ -2078,7 +2101,19 @@ def put_integration_response( context: RequestContext, request: PutIntegrationResponseRequest, ) -> IntegrationResponse: - moto_rest_api = get_moto_rest_api(context=context, rest_api_id=request.get("restApiId")) + status_code = request.get("statusCode") + if not re.fullmatch(r"[1-5]\d\d", status_code): + raise CommonServiceException( + code="ValidationException", + message=f"1 validation error detected: Value '{status_code}' at 'statusCode' failed to " + f"satisfy constraint: Member must satisfy regular expression pattern: [1-5]\\d\\d", + ) + try: + # put integration response doesn't return the right exception compared to AWS + moto_rest_api = get_moto_rest_api(context=context, rest_api_id=request.get("restApiId")) + except NotFoundException: + raise NotFoundException("Invalid Resource identifier specified") + moto_resource = moto_rest_api.resources.get(request.get("resourceId")) if not moto_resource: raise NotFoundException("Invalid Resource identifier specified") diff --git a/tests/aws/services/apigateway/test_apigateway_api.py b/tests/aws/services/apigateway/test_apigateway_api.py index 71f6aaa1886f8..ca64cf8169b03 100644 --- a/tests/aws/services/apigateway/test_apigateway_api.py +++ b/tests/aws/services/apigateway/test_apigateway_api.py @@ -2635,6 +2635,213 @@ def test_put_integration_request_parameter_bool_type( ) snapshot.match("put-integration-request-param-bool-value", e.value.response) + @markers.aws.validated + def test_integration_response_wrong_api(self, aws_client, apigw_create_rest_api, snapshot): + with pytest.raises(ClientError) as e: + aws_client.apigateway.put_integration_response( + restApiId="wrong-api", resourceId="dummy-value", httpMethod="GET", statusCode="200" + ) + snapshot.match("put-integration-response-wrong-api", e.value.response) + + with pytest.raises(ClientError) as e: + aws_client.apigateway.get_integration_response( + restApiId="wrong-api", resourceId="dummy-value", httpMethod="GET", statusCode="200" + ) + snapshot.match("get-integration-response-wrong-api", e.value.response) + + @markers.aws.validated + def test_integration_response_wrong_resource(self, aws_client, apigw_create_rest_api, snapshot): + response = apigw_create_rest_api( + name=f"test-api-{short_uid()}", + description="APIGW test Integration Resource", + ) + api_id = response["id"] + + with pytest.raises(ClientError) as e: + aws_client.apigateway.put_integration_response( + restApiId=api_id, resourceId="wrong-resource", httpMethod="GET", statusCode="200" + ) + snapshot.match("put-integration-response-wrong-resource", e.value.response) + + with pytest.raises(ClientError) as e: + aws_client.apigateway.get_integration_response( + restApiId=api_id, resourceId="wrong-resource", httpMethod="GET", statusCode="200" + ) + snapshot.match("get-integration-response-wrong-resource", e.value.response) + + @markers.aws.validated + def test_integration_response_wrong_method(self, aws_client, apigw_create_rest_api, snapshot): + response = apigw_create_rest_api( + name=f"test-api-{short_uid()}", + description="APIGW test Integration Method", + ) + api_id = response["id"] + root_resource_id = response["rootResourceId"] + + with pytest.raises(ClientError) as e: + aws_client.apigateway.put_integration_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="wrong-method", + statusCode="200", + ) + snapshot.match("put-integration-response-wrong-method", e.value.response) + + with pytest.raises(ClientError) as e: + aws_client.apigateway.get_integration_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="wrong-method", + statusCode="200", + ) + snapshot.match("get-integration-response-wrong-method", e.value.response) + + @markers.aws.validated + def test_integration_response_invalid_statuscode( + self, aws_client, apigw_create_rest_api, snapshot + ): + response = apigw_create_rest_api( + name=f"test-api-{short_uid()}", + description="APIGW test Integration Invalid StatusCode", + ) + api_id = response["id"] + root_resource_id = response["rootResourceId"] + + with pytest.raises(ClientError) as e: + aws_client.apigateway.put_integration_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="wrong", + responseTemplates={"application/json": '"created"'}, + selectionPattern="", + ) + snapshot.match("put-integration-response-invalid-statusCode", e.value.response) + + with pytest.raises(ClientError) as e: + aws_client.apigateway.get_integration_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="wrong", + ) + snapshot.match("get-integration-response-invalid-statusCode", e.value.response) + + @markers.aws.validated + @pytest.mark.skipif( + condition=not is_aws_cloud(), reason="Validation not yet implemented in LocalStack" + ) + def test_integration_response_invalid_responsetemplates( + self, aws_client, aws_client_factory, apigw_create_rest_api, snapshot + ): + apigw_client = aws_client_factory(config=Config(parameter_validation=False)).apigateway + response = apigw_create_rest_api( + name=f"test-api-{short_uid()}", + description="APIGW test wrong api", + ) + api_id = response["id"] + root_resource_id = response["rootResourceId"] + + apigw_client.put_method( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + authorizationType="NONE", + ) + apigw_client.put_integration( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + integrationHttpMethod="GET", + type="MOCK", + requestTemplates={"application/json": '{"statusCode": 200}'}, + ) + + with pytest.raises(ClientError) as e: + apigw_client.put_integration_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + selectionPattern="", + responseTemplates={"application/json": 123}, + ) + # TODO: AWS returns a SerializationException + # But LocalStack currently doesn't raise any Error + snapshot.match("put-integration-response-invalid-responseTemplates-1", e.value.response) + + with pytest.raises(ClientError) as e: + apigw_client.put_integration_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + selectionPattern="", + responseTemplates={123: '{"statusCode": 200}'}, + ) + # TODO: AWS returns a BadRequestException + # But LocalStack currently doesn't raise any Error + snapshot.match("put-integration-response-invalid-responseTemplates-2", e.value.response) + + @markers.aws.validated + def test_integration_response_invalid_integration( + self, aws_client, apigw_create_rest_api, snapshot + ): + snapshot.add_transformer(snapshot.transform.key_value("cacheNamespace")) + apigw_client = aws_client.apigateway + response = apigw_create_rest_api(name=f"test-api-{short_uid()}") + api_id = response["id"] + root_resource_id = response["rootResourceId"] + + apigw_client.put_method( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + authorizationType="NONE", + ) + + with pytest.raises(ClientError) as e: + apigw_client.get_integration_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + ) + snapshot.match("get-integration-response-without-integration", e.value.response) + + @markers.aws.validated + def test_integration_response_wrong_status_code( + self, aws_client, apigw_create_rest_api, snapshot + ): + snapshot.add_transformer(snapshot.transform.key_value("cacheNamespace")) + apigw_client = aws_client.apigateway + response = apigw_create_rest_api(name=f"test-api-{short_uid()}") + api_id = response["id"] + root_resource_id = response["rootResourceId"] + + apigw_client.put_method( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + authorizationType="NONE", + ) + apigw_client.put_integration( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + type="MOCK", + requestTemplates={"application/json": '{"statusCode": 200}'}, + ) + + with pytest.raises(ClientError) as e: + apigw_client.get_integration_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="201", + ) + snapshot.match("get-integration-response-wrong-status-code", e.value.response) + @markers.aws.validated def test_lifecycle_integration_response(self, aws_client, apigw_create_rest_api, snapshot): snapshot.add_transformer(snapshot.transform.key_value("cacheNamespace")) diff --git a/tests/aws/services/apigateway/test_apigateway_api.snapshot.json b/tests/aws/services/apigateway/test_apigateway_api.snapshot.json index 665d8ee288c33..4b03f9f2baffe 100644 --- a/tests/aws/services/apigateway/test_apigateway_api.snapshot.json +++ b/tests/aws/services/apigateway/test_apigateway_api.snapshot.json @@ -3714,5 +3714,169 @@ } } } + }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_integration_response_wrong_api": { + "recorded-date": "18-06-2025, 12:28:55", + "recorded-content": { + "put-integration-response-wrong-api": { + "Error": { + "Code": "NotFoundException", + "Message": "Invalid Resource identifier specified" + }, + "message": "Invalid Resource identifier specified", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 404 + } + }, + "get-integration-response-wrong-api": { + "Error": { + "Code": "NotFoundException", + "Message": "Invalid Resource identifier specified" + }, + "message": "Invalid Resource identifier specified", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 404 + } + } + } + }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_integration_response_wrong_resource": { + "recorded-date": "18-06-2025, 12:28:25", + "recorded-content": { + "put-integration-response-wrong-resource": { + "Error": { + "Code": "NotFoundException", + "Message": "Invalid Resource identifier specified" + }, + "message": "Invalid Resource identifier specified", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 404 + } + }, + "get-integration-response-wrong-resource": { + "Error": { + "Code": "NotFoundException", + "Message": "Invalid Resource identifier specified" + }, + "message": "Invalid Resource identifier specified", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 404 + } + } + } + }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_integration_response_wrong_method": { + "recorded-date": "18-06-2025, 11:47:00", + "recorded-content": { + "put-integration-response-wrong-method": { + "Error": { + "Code": "NotFoundException", + "Message": "Invalid Method identifier specified" + }, + "message": "Invalid Method identifier specified", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 404 + } + }, + "get-integration-response-wrong-method": { + "Error": { + "Code": "NotFoundException", + "Message": "Invalid Method identifier specified" + }, + "message": "Invalid Method identifier specified", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 404 + } + } + } + }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_integration_response_invalid_statuscode": { + "recorded-date": "18-06-2025, 11:51:51", + "recorded-content": { + "put-integration-response-invalid-statusCode": { + "Error": { + "Code": "ValidationException", + "Message": "1 validation error detected: Value 'wrong' at 'statusCode' failed to satisfy constraint: Member must satisfy regular expression pattern: [1-5]\\d\\d" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 400 + } + }, + "get-integration-response-invalid-statusCode": { + "Error": { + "Code": "ValidationException", + "Message": "1 validation error detected: Value 'wrong' at 'statusCode' failed to satisfy constraint: Member must satisfy regular expression pattern: [1-5]\\d\\d" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 400 + } + } + } + }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_integration_response_invalid_responsetemplates": { + "recorded-date": "18-06-2025, 13:03:29", + "recorded-content": { + "put-integration-response-invalid-responseTemplates-1": { + "Error": { + "Code": "SerializationException", + "Message": "class com.amazon.coral.value.json.numbers.TruncatingBigNumber can not be converted to an String" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 400 + } + }, + "put-integration-response-invalid-responseTemplates-2": { + "Error": { + "Code": "BadRequestException", + "Message": "Validation Result: warnings : [], errors : [Invalid content type specified: 123]" + }, + "message": "Validation Result: warnings : [], errors : [Invalid content type specified: 123]", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 400 + } + } + } + }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_integration_response_invalid_integration": { + "recorded-date": "26-06-2025, 11:21:05", + "recorded-content": { + "get-integration-response-without-integration": { + "Error": { + "Code": "NotFoundException", + "Message": "Invalid Integration identifier specified" + }, + "message": "Invalid Integration identifier specified", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 404 + } + } + } + }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_integration_response_wrong_status_code": { + "recorded-date": "26-06-2025, 11:21:43", + "recorded-content": { + "get-integration-response-wrong-status-code": { + "Error": { + "Code": "NotFoundException", + "Message": "Invalid Response status code specified" + }, + "message": "Invalid Response status code specified", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 404 + } + } + } } } diff --git a/tests/aws/services/apigateway/test_apigateway_api.validation.json b/tests/aws/services/apigateway/test_apigateway_api.validation.json index df3c6379daf87..3bb989388a4a6 100644 --- a/tests/aws/services/apigateway/test_apigateway_api.validation.json +++ b/tests/aws/services/apigateway/test_apigateway_api.validation.json @@ -131,6 +131,69 @@ "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayGatewayResponse::test_update_gateway_response": { "last_validated_date": "2024-04-15T20:47:11+00:00" }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_integration_response_invalid_integration": { + "last_validated_date": "2025-06-26T11:21:05+00:00", + "durations_in_seconds": { + "setup": 1.63, + "call": 1.17, + "teardown": 0.4, + "total": 3.2 + } + }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_integration_response_invalid_responsetemplates": { + "last_validated_date": "2025-06-18T13:03:29+00:00", + "durations_in_seconds": { + "setup": 1.43, + "call": 2.04, + "teardown": 0.33, + "total": 3.8 + } + }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_integration_response_invalid_statuscode": { + "last_validated_date": "2025-06-18T11:51:51+00:00", + "durations_in_seconds": { + "setup": 1.61, + "call": 1.31, + "teardown": 0.41, + "total": 3.33 + } + }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_integration_response_wrong_api": { + "last_validated_date": "2025-06-18T12:28:55+00:00", + "durations_in_seconds": { + "setup": 1.08, + "call": 0.32, + "teardown": 0.0, + "total": 1.4 + } + }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_integration_response_wrong_method": { + "last_validated_date": "2025-06-18T11:47:00+00:00", + "durations_in_seconds": { + "setup": 1.42, + "call": 1.17, + "teardown": 0.37, + "total": 2.96 + } + }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_integration_response_wrong_resource": { + "last_validated_date": "2025-06-18T12:28:25+00:00", + "durations_in_seconds": { + "setup": 1.35, + "call": 1.22, + "teardown": 0.41, + "total": 2.98 + } + }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_integration_response_wrong_status_code": { + "last_validated_date": "2025-06-26T11:21:43+00:00", + "durations_in_seconds": { + "setup": 1.58, + "call": 1.41, + "teardown": 0.41, + "total": 3.4 + } + }, "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_lifecycle_integration_response": { "last_validated_date": "2025-06-11T09:12:54+00:00", "durations_in_seconds": { From 093ddbed9e8b807b244cfbdf5e3356671a8a864e Mon Sep 17 00:00:00 2001 From: Macwan Nevil Date: Fri, 27 Jun 2025 10:25:05 +0530 Subject: [PATCH 61/74] refactored archive installer (#12771) --- localstack-core/localstack/packages/core.py | 81 +++-- localstack-core/localstack/packages/ffmpeg.py | 7 +- .../localstack/packages/terraform.py | 6 + localstack-core/localstack/utils/archives.py | 50 ++- localstack-core/localstack/utils/checksum.py | 313 ++++++++++++++++++ localstack-core/localstack/utils/files.py | 2 +- tests/unit/test_checksum.py | 311 +++++++++++++++++ 7 files changed, 745 insertions(+), 25 deletions(-) create mode 100644 localstack-core/localstack/utils/checksum.py create mode 100644 tests/unit/test_checksum.py diff --git a/localstack-core/localstack/packages/core.py b/localstack-core/localstack/packages/core.py index 5b8996deaa844..fde294492cc3a 100644 --- a/localstack-core/localstack/packages/core.py +++ b/localstack-core/localstack/packages/core.py @@ -63,7 +63,12 @@ def _install(self, target: InstallTarget) -> None: class ArchiveDownloadAndExtractInstaller(ExecutableInstaller): - def __init__(self, name: str, version: str, extract_single_directory: bool = False): + def __init__( + self, + name: str, + version: str, + extract_single_directory: bool = False, + ): """ :param name: technical package name, f.e. "opensearch" :param version: version of the package to install @@ -78,6 +83,16 @@ def _get_install_marker_path(self, install_dir: str) -> str: def _get_download_url(self) -> str: raise NotImplementedError() + def _get_checksum_url(self) -> str | None: + """ + Checksum URL for the archive. This is used to verify the integrity of the downloaded archive. + This method can be implemented by subclasses to provide the correct URL for the checksum file. + If not implemented, checksum verification will be skipped. + + :return: URL to the checksum file for the archive, or None if not available. + """ + return None + def get_installed_dir(self) -> str | None: installed_dir = super().get_installed_dir() subdir = self._get_archive_subdir() @@ -107,29 +122,55 @@ def get_executable_path(self) -> str | None: return self._get_install_marker_path(install_dir) return None - def _install(self, target: InstallTarget) -> None: + def _handle_single_directory_extraction(self, target_directory: str) -> None: + """ + Handle extraction of archives that contain a single root directory. + Moves the contents up one level if extract_single_directory is True. + + :param target_directory: The target extraction directory + :return: None + """ + if not self.extract_single_directory: + return + + dir_contents = os.listdir(target_directory) + if len(dir_contents) != 1: + return + target_subdir = os.path.join(target_directory, dir_contents[0]) + if not os.path.isdir(target_subdir): + return + os.rename(target_subdir, f"{target_directory}.backup") + rm_rf(target_directory) + os.rename(f"{target_directory}.backup", target_directory) + + def _download_archive( + self, + target: InstallTarget, + download_url: str, + ) -> None: target_directory = self._get_install_dir(target) mkdir(target_directory) - download_url = self._get_download_url() + download_url = download_url or self._get_download_url() archive_name = os.path.basename(download_url) archive_path = os.path.join(config.dirs.tmp, archive_name) - download_and_extract( - download_url, - retries=3, - tmp_archive=archive_path, - target_dir=target_directory, - ) - rm_rf(archive_path) - if self.extract_single_directory: - dir_contents = os.listdir(target_directory) - if len(dir_contents) != 1: - return - target_subdir = os.path.join(target_directory, dir_contents[0]) - if not os.path.isdir(target_subdir): - return - os.rename(target_subdir, f"{target_directory}.backup") - rm_rf(target_directory) - os.rename(f"{target_directory}.backup", target_directory) + + # Get checksum info if available + checksum_url = self._get_checksum_url() + + try: + download_and_extract( + download_url, + retries=3, + tmp_archive=archive_path, + target_dir=target_directory, + checksum_url=checksum_url, + ) + self._handle_single_directory_extraction(target_directory) + finally: + rm_rf(archive_path) + + def _install(self, target: InstallTarget) -> None: + self._download_archive(target, self._get_download_url()) class PermissionDownloadInstaller(DownloadInstaller, ABC): diff --git a/localstack-core/localstack/packages/ffmpeg.py b/localstack-core/localstack/packages/ffmpeg.py index af9a18b544fb5..230d114347b68 100644 --- a/localstack-core/localstack/packages/ffmpeg.py +++ b/localstack-core/localstack/packages/ffmpeg.py @@ -9,7 +9,9 @@ ARCH_MAPPING = {Arch.amd64: "linux64", Arch.arm64: "linuxarm64"} # Download URL template for ffmpeg 7.1 LGPL builds from BtbN GitHub Releases -FFMPEG_STATIC_BIN_URL = "https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-n{version}-latest-{arch}-lgpl-{version}.tar.xz" +FFMPEG_BASE_URL = "https://github.com/BtbN/FFmpeg-Builds/releases/download/latest" +FFMPEG_STATIC_BIN_URL = FFMPEG_BASE_URL + "/ffmpeg-n{version}-latest-{arch}-lgpl-{version}.tar.xz" +FFMPEG_STATIC_CHECKSUM_URL = FFMPEG_BASE_URL + "/checksums.sha256" class FfmpegPackage(Package["FfmpegPackageInstaller"]): @@ -42,5 +44,8 @@ def get_ffmpeg_path(self) -> str: def get_ffprobe_path(self) -> str: return os.path.join(self.get_installed_dir(), "bin", "ffprobe") # type: ignore[arg-type] + def _get_checksum_url(self) -> str | None: + return FFMPEG_STATIC_CHECKSUM_URL + ffmpeg_package = FfmpegPackage() diff --git a/localstack-core/localstack/packages/terraform.py b/localstack-core/localstack/packages/terraform.py index 6ee590f0387b5..2a5da95b8472a 100644 --- a/localstack-core/localstack/packages/terraform.py +++ b/localstack-core/localstack/packages/terraform.py @@ -11,6 +11,9 @@ TERRAFORM_URL_TEMPLATE = ( "https://releases.hashicorp.com/terraform/{version}/terraform_{version}_{os}_{arch}.zip" ) +TERRAFORM_CHECKSUM_URL_TEMPLATE = ( + "https://releases.hashicorp.com/terraform/{version}/terraform_{version}_SHA256SUMS" +) class TerraformPackage(Package["TerraformPackageInstaller"]): @@ -37,5 +40,8 @@ def _install(self, target: InstallTarget) -> None: super()._install(target) chmod_r(self.get_executable_path(), 0o777) # type: ignore[arg-type] + def _get_checksum_url(self) -> str | None: + return TERRAFORM_CHECKSUM_URL_TEMPLATE.format(version=TERRAFORM_VERSION) + terraform_package = TerraformPackage() diff --git a/localstack-core/localstack/utils/archives.py b/localstack-core/localstack/utils/archives.py index 97477f6d86c74..e3b3673541a80 100644 --- a/localstack-core/localstack/utils/archives.py +++ b/localstack-core/localstack/utils/archives.py @@ -15,6 +15,7 @@ from localstack.utils.http import download from localstack.utils.run import run +from .checksum import verify_local_file_with_checksum_url from .run import is_command_available from .strings import truncate @@ -176,7 +177,22 @@ def download_and_extract( retries: Optional[int] = 0, sleep: Optional[int] = 3, tmp_archive: Optional[str] = None, + checksum_url: Optional[str] = None, ) -> None: + """ + Download and extract an archive to a target directory with optional checksum verification. + + Checksum verification is only performed if a `checksum_url` is provided. + Else, the archive is downloaded and extracted without verification. + + :param archive_url: URL of the archive to download + :param target_dir: Directory to extract the archive contents to + :param retries: Number of download retries (default: 0) + :param sleep: Sleep time between retries in seconds (default: 3) + :param tmp_archive: Optional path for the temporary archive file + :param checksum_url: Optional URL of the checksum file for verification + :return: None + """ mkdir(target_dir) _, ext = os.path.splitext(tmp_archive or archive_url) @@ -204,6 +220,19 @@ def download_and_extract( if os.path.getsize(tmp_archive) <= 0: raise Exception("Failed to download archive from %s: . Retries exhausted", archive_url) + # Verify checksum if provided + if checksum_url: + LOG.info("Verifying archive integrity...") + try: + verify_local_file_with_checksum_url( + file_path=tmp_archive, + checksum_url=checksum_url, + ) + except Exception as e: + # clean up the corrupted download + rm_rf(tmp_archive) + raise e + if ext == ".zip": unzip(tmp_archive, target_dir) elif ext in ( @@ -217,11 +246,26 @@ def download_and_extract( raise Exception(f"Unsupported archive format: {ext}") -def download_and_extract_with_retry(archive_url, tmp_archive, target_dir): +def download_and_extract_with_retry( + archive_url, + tmp_archive, + target_dir, + checksum_url: Optional[str] = None, +): try: - download_and_extract(archive_url, target_dir, tmp_archive=tmp_archive) + download_and_extract( + archive_url, + target_dir, + tmp_archive=tmp_archive, + checksum_url=checksum_url, + ) except Exception as e: # try deleting and re-downloading the zip file LOG.info("Unable to extract file, re-downloading ZIP archive %s: %s", tmp_archive, e) rm_rf(tmp_archive) - download_and_extract(archive_url, target_dir, tmp_archive=tmp_archive) + download_and_extract( + archive_url, + target_dir, + tmp_archive=tmp_archive, + checksum_url=checksum_url, + ) diff --git a/localstack-core/localstack/utils/checksum.py b/localstack-core/localstack/utils/checksum.py new file mode 100644 index 0000000000000..81de3b0ee60ee --- /dev/null +++ b/localstack-core/localstack/utils/checksum.py @@ -0,0 +1,313 @@ +import hashlib +import logging +import os +import re +import tempfile +from abc import ABC, abstractmethod + +from localstack.utils.files import load_file, rm_rf + +# Setup logger +LOG = logging.getLogger(__name__) + + +class ChecksumException(Exception): + """Base exception for checksum errors.""" + + pass + + +class ChecksumFormat(ABC): + """Abstract base class for checksum format parsers.""" + + @abstractmethod + def can_parse(self, content: str) -> bool: + """ + Check if this parser can handle the given content. + + :param content: The content to check + :return: True if parser can handle content, False otherwise + """ + pass + + @abstractmethod + def parse(self, content: str) -> dict[str, str]: + """ + Parse the content and return filename to checksum mapping. + + :param content: The content to parse + :return: Dictionary mapping filenames to checksums + """ + pass + + +class StandardFormat(ChecksumFormat): + """ + Handles standard checksum format. + + Supports formats like: + + * ``checksum filename`` + * ``checksum *filename`` + """ + + def can_parse(self, content: str) -> bool: + lines = content.strip().split("\n") + for line in lines[:5]: # Check first 5 lines + if re.match(r"^[a-fA-F0-9]{32,128}\s+\S+", line.strip()): + return True + return False + + def parse(self, content: str) -> dict[str, str]: + checksums = {} + for line in content.strip().split("\n"): + line = line.strip() + if not line or line.startswith("#"): + continue + + # Match: checksum (whitespace) filename + match = re.match(r"^([a-fA-F0-9]{32,128})\s+(\*?)(.+)$", line) + if match: + checksum, star, filename = match.groups() + checksums[filename.strip()] = checksum.lower() + + return checksums + + +class BSDFormat(ChecksumFormat): + """ + Handles BSD-style checksum format. + + Format: ``SHA512 (filename) = checksum`` + """ + + def can_parse(self, content: str) -> bool: + lines = content.strip().split("\n") + for line in lines[:5]: + if re.match(r"^(MD5|SHA1|SHA256|SHA512)\s*\(.+\)\s*=\s*[a-fA-F0-9]+", line): + return True + return False + + def parse(self, content: str) -> dict[str, str]: + checksums = {} + for line in content.strip().split("\n"): + line = line.strip() + if not line: + continue + + # Match: ALGORITHM (filename) = checksum + match = re.match(r"^(MD5|SHA1|SHA256|SHA512)\s*\((.+)\)\s*=\s*([a-fA-F0-9]+)$", line) + if match: + algo, filename, checksum = match.groups() + checksums[filename.strip()] = checksum.lower() + + return checksums + + +class ApacheBSDFormat(ChecksumFormat): + """ + Handles Apache's BSD-style format with split checksums. + + Format:: + + filename: CHECKSUM_PART1 + CHECKSUM_PART2 + CHECKSUM_PART3 + """ + + def can_parse(self, content: str) -> bool: + lines = content.strip().split("\n") + if lines and ":" in lines[0]: + # Check if it looks like filename: hex_data + parts = lines[0].split(":", 1) + if len(parts) == 2 and re.search(r"[a-fA-F0-9\s]+", parts[1]): + return True + return False + + def parse(self, content: str) -> dict[str, str]: + checksums = {} + lines = content.strip().split("\n") + + current_file = None + checksum_parts = [] + + for line in lines: + if ":" in line and not line.startswith(" "): + # New file entry + if current_file and checksum_parts: + # Save previous file's checksum + full_checksum = "".join(checksum_parts).replace(" ", "").lower() + if re.match(r"^[a-fA-F0-9]+$", full_checksum): + checksums[current_file] = full_checksum + + # Start new file + parts = line.split(":", 1) + current_file = parts[0].strip() + checksum_part = parts[1].strip() + checksum_parts = [checksum_part] + elif line.strip() and current_file: + # Continuation of checksum + checksum_parts.append(line.strip()) + + # Don't forget the last file + if current_file and checksum_parts: + full_checksum = "".join(checksum_parts).replace(" ", "").lower() + if re.match(r"^[a-fA-F0-9]+$", full_checksum): + checksums[current_file] = full_checksum + + return checksums + + +class ChecksumParser: + """Main parser that tries different checksum formats.""" + + def __init__(self): + """Initialize parser with available format parsers.""" + self.formats = [ + StandardFormat(), + BSDFormat(), + ApacheBSDFormat(), + ] + + def parse(self, content: str) -> dict[str, str]: + """ + Try each format parser until one works. + + :param content: The content to parse + :return: Dictionary mapping filenames to checksums + """ + for format_parser in self.formats: + if format_parser.can_parse(content): + result = format_parser.parse(content) + if result: + return result + + return {} + + +def parse_checksum_file_from_url(checksum_url: str) -> dict[str, str]: + """ + Parse a SHA checksum file from a URL using multiple format parsers. + + :param checksum_url: URL of the checksum file + :return: Dictionary mapping filenames to checksums + """ + # import here to avoid circular dependency issues + from localstack.utils.http import download + + checksum_name = os.path.basename(checksum_url) + checksum_path = os.path.join(tempfile.gettempdir(), checksum_name) + try: + download(checksum_url, checksum_path) + checksum_content = load_file(checksum_path) + + parser = ChecksumParser() + checksums = parser.parse(checksum_content) + + return checksums + finally: + rm_rf(checksum_path) + + +def calculate_file_checksum(file_path: str, algorithm: str = "sha256") -> str: + """ + Calculate checksum of a local file. + + :param file_path: Path to the file + :param algorithm: Hash algorithm to use + :return: Calculated checksum as hexadecimal string + + note: Supported algorithms: 'md5', 'sha1', 'sha256', 'sha512' + """ + hash_func = getattr(hashlib, algorithm)() + + with open(file_path, "rb") as f: + # Read file in chunks to handle large files efficiently + for chunk in iter(lambda: f.read(8192), b""): + hash_func.update(chunk) + + return hash_func.hexdigest() + + +def verify_local_file_with_checksum_url(file_path: str, checksum_url: str, filename=None) -> bool: + """ + Verify a local file against checksums from an online checksum file. + + :param file_path: Path to the local file to verify + :param checksum_url: URL of the checksum file + :param filename: Filename to look for in checksum file (defaults to basename of file_path) + :return: True if verification succeeds, False otherwise + + note: The algorithm is automatically detected based on checksum length: + + * 32 characters: MD5 + * 40 characters: SHA1 + * 64 characters: SHA256 + * 128 characters: SHA512 + """ + # Get checksums from URL + LOG.debug("Fetching checksums from %s...", checksum_url) + checksums = parse_checksum_file_from_url(checksum_url) + + if not checksums: + raise ChecksumException(f"No checksums found in {checksum_url}") + + # Determine filename to look for + if filename is None: + filename = os.path.basename(file_path) + + # Find checksum for our file + if filename not in checksums: + # Try with different path variations + possible_names = [ + filename, + os.path.basename(filename), # just filename without path + filename.replace("\\", "/"), # Unix-style paths + filename.replace("/", "\\"), # Windows-style paths + ] + + found = False + for name in possible_names: + if name in checksums: + filename = name + found = True + break + + if not found: + raise ChecksumException(f"Checksum for {filename} not found in {checksum_url}") + + expected_checksum = checksums[filename] + + # Detect algorithm based on checksum length + checksum_length = len(expected_checksum) + if checksum_length == 32: + algorithm = "md5" + elif checksum_length == 40: + algorithm = "sha1" + elif checksum_length == 64: + algorithm = "sha256" + elif checksum_length == 128: + algorithm = "sha512" + else: + raise ChecksumException(f"Unsupported checksum length: {checksum_length}") + + # Calculate checksum of local file + LOG.debug("Calculating %s checksum of %s...", algorithm, file_path) + calculated_checksum = calculate_file_checksum(file_path, algorithm) + + is_valid = calculated_checksum == expected_checksum.lower() + + if not is_valid: + LOG.error( + "Checksum mismatch for %s: calculated %s, expected %s", + file_path, + calculated_checksum, + expected_checksum, + ) + raise ChecksumException( + f"Checksum mismatch for {file_path}: calculated {calculated_checksum}, expected {expected_checksum}" + ) + LOG.debug("Checksum verification successful for %s", file_path) + + # Compare checksums + return calculated_checksum == expected_checksum.lower() diff --git a/localstack-core/localstack/utils/files.py b/localstack-core/localstack/utils/files.py index 212eee0e48ee1..7b71e26ca8664 100644 --- a/localstack-core/localstack/utils/files.py +++ b/localstack-core/localstack/utils/files.py @@ -81,7 +81,7 @@ def _opener(path, flags): f.flush() -def load_file(file_path, default=None, mode=None): +def load_file(file_path: str, default=None, mode=None): if not os.path.isfile(file_path): return default if not mode: diff --git a/tests/unit/test_checksum.py b/tests/unit/test_checksum.py new file mode 100644 index 0000000000000..b13bbb61de6c6 --- /dev/null +++ b/tests/unit/test_checksum.py @@ -0,0 +1,311 @@ +from localstack.utils.checksum import ( + ApacheBSDFormat, + BSDFormat, + ChecksumParser, + StandardFormat, +) + + +class TestStandardFormat: + """Test cases for StandardFormat parser.""" + + def test_can_parse_standard_format(self): + """Test detection of standard checksum format.""" + parser = StandardFormat() + + # Valid standard formats + assert parser.can_parse("d41d8cd98f00b204e9800998ecf8427e file.txt") + assert parser.can_parse( + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 test.zip" + ) + assert parser.can_parse("da39a3ee5e6b4b0d3255bfef95601890afd80709 *binary.exe") + + # Multiple lines + content = """ +d41d8cd98f00b204e9800998ecf8427e file1.txt +e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 file2.zip +""" + assert parser.can_parse(content) + + # Invalid formats + assert not parser.can_parse("SHA256 (file.txt) = d41d8cd98f00b204e9800998ecf8427e") + assert not parser.can_parse("file.txt: d41d8cd98f00b204e9800998ecf8427e") + assert not parser.can_parse("just some random text") + assert not parser.can_parse("") + + def test_parse_standard_format(self): + """Test parsing of standard checksum format.""" + parser = StandardFormat() + + content = """ +d41d8cd98f00b204e9800998ecf8427e file1.txt +e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 file2.zip +# This is a comment +da39a3ee5e6b4b0d3255bfef95601890afd80709 *binary.exe + +1234567890abcdef1234567890abcdef12345678 file with spaces.txt +ABCDEF1234567890ABCDEF1234567890ABCDEF12 UPPERCASE.TXT + """ + + result = parser.parse(content) + + assert len(result) == 5 + assert result["file1.txt"] == "d41d8cd98f00b204e9800998ecf8427e" + assert ( + result["file2.zip"] + == "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ) + assert result["binary.exe"] == "da39a3ee5e6b4b0d3255bfef95601890afd80709" + assert result["file with spaces.txt"] == "1234567890abcdef1234567890abcdef12345678" + assert ( + result["UPPERCASE.TXT"] == "abcdef1234567890abcdef1234567890abcdef12" + ) # Should be lowercase + + def test_parse_empty_content(self): + """Test parsing empty content.""" + parser = StandardFormat() + result = parser.parse("") + assert result == {} + + def test_parse_comments_only(self): + """Test parsing content with only comments.""" + parser = StandardFormat() + content = """ +# Comment 1 +# Comment 2 + """ + result = parser.parse(content) + assert result == {} + + +class TestBSDFormat: + """Test cases for BSDFormat parser.""" + + def test_can_parse_bsd_format(self): + """Test detection of BSD checksum format.""" + parser = BSDFormat() + + # Valid BSD formats + assert parser.can_parse("MD5 (file.txt) = d41d8cd98f00b204e9800998ecf8427e") + assert parser.can_parse( + "SHA256 (test.zip) = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ) + assert parser.can_parse( + "SHA512 (binary.exe) = cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" + ) + assert parser.can_parse("SHA1 (test) = da39a3ee5e6b4b0d3255bfef95601890afd80709") + + # With spaces + assert parser.can_parse( + "SHA256 (file with spaces.txt) = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ) + + # Invalid formats + assert not parser.can_parse("d41d8cd98f00b204e9800998ecf8427e file.txt") + assert not parser.can_parse("file.txt: d41d8cd98f00b204e9800998ecf8427e") + assert not parser.can_parse( + "SHA3 (file.txt) = d41d8cd98f00b204e9800998ecf8427e" + ) # Unsupported algorithm + + def test_parse_bsd_format(self): + """Test parsing of BSD checksum format.""" + parser = BSDFormat() + + content = """ +MD5 (file1.txt) = d41d8cd98f00b204e9800998ecf8427e +SHA256 (file2.zip) = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +SHA1 (binary.exe) = da39a3ee5e6b4b0d3255bfef95601890afd80709 +SHA512 (large.bin) = cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e +SHA256 (file with (parentheses).txt) = 1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef +MD5 (UPPERCASE.TXT) = ABCDEF1234567890ABCDEF1234567890 + """ + + result = parser.parse(content) + + assert len(result) == 6 + assert result["file1.txt"] == "d41d8cd98f00b204e9800998ecf8427e" + assert ( + result["file2.zip"] + == "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ) + assert result["binary.exe"] == "da39a3ee5e6b4b0d3255bfef95601890afd80709" + assert ( + result["large.bin"] + == "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" + ) + assert ( + result["file with (parentheses).txt"] + == "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" + ) + assert result["UPPERCASE.TXT"] == "abcdef1234567890abcdef1234567890" # Should be lowercase + + def test_parse_mixed_algorithms(self): + """Test parsing BSD format with mixed algorithms.""" + parser = BSDFormat() + + content = """ +MD5 (file1.txt) = d41d8cd98f00b204e9800998ecf8427e +SHA1 (file1.txt) = da39a3ee5e6b4b0d3255bfef95601890afd80709 +SHA256 (file1.txt) = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 + """ + + result = parser.parse(content) + + # Should keep the last one for duplicate filenames + assert len(result) == 1 + assert ( + result["file1.txt"] + == "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ) + + +class TestApacheBSDFormat: + """Test cases for ApacheBSDFormat parser.""" + + def test_can_parse_apache_bsd_format(self): + """Test detection of Apache BSD checksum format.""" + parser = ApacheBSDFormat() + + # Valid Apache BSD format + assert parser.can_parse("file.txt: d41d8cd9 8f00b204\n e9800998 ecf8427e") + assert parser.can_parse("test.zip: e3b0c442 98fc1c14") + assert parser.can_parse("file: abcd1234") + + # Invalid formats + assert not parser.can_parse("d41d8cd98f00b204e9800998ecf8427e file.txt") + assert not parser.can_parse("MD5 (file.txt) = d41d8cd98f00b204e9800998ecf8427e") + assert not parser.can_parse("no colon here") + assert not parser.can_parse("") + + def test_parse_apache_bsd_format_single_line(self): + """Test parsing Apache BSD format with single-line checksums.""" + parser = ApacheBSDFormat() + + content = """ +file1.txt: d41d8cd98f00b204e9800998ecf8427e +file2.zip: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 + """ + + result = parser.parse(content) + + assert len(result) == 2 + assert result["file1.txt"] == "d41d8cd98f00b204e9800998ecf8427e" + assert ( + result["file2.zip"] + == "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ) + + def test_parse_apache_bsd_format_multi_line(self): + """Test parsing Apache BSD format with multi-line checksums.""" + parser = ApacheBSDFormat() + + content = """ +file1.txt: d41d8cd9 8f00b204 + e9800998 ecf8427e +file2.zip: e3b0c442 98fc1c14 9afbf4c8 996fb924 + 27ae41e4 649b934c a495991b 7852b855 +binary.exe: da39a3ee 5e6b4b0d + 3255bfef 95601890 + afd80709 +single.txt: 1234567890abcdef1234567890abcdef12345678 + """ + + result = parser.parse(content) + + assert len(result) == 4 + assert result["file1.txt"] == "d41d8cd98f00b204e9800998ecf8427e" + assert ( + result["file2.zip"] + == "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ) + assert result["binary.exe"] == "da39a3ee5e6b4b0d3255bfef95601890afd80709" + assert result["single.txt"] == "1234567890abcdef1234567890abcdef12345678" + + def test_parse_apache_bsd_format_with_spaces(self): + """Test parsing Apache BSD format with various spacing.""" + parser = ApacheBSDFormat() + + content = """ +file with spaces.txt: d41d8cd9 8f00b204 + e9800998 ecf8427e +another file.zip: ABCD1234 5678ABCD + 9012ABCD 3456CDEF + """ + + result = parser.parse(content) + + assert len(result) == 2 + assert result["file with spaces.txt"] == "d41d8cd98f00b204e9800998ecf8427e" + assert ( + result["another file.zip"] == "abcd12345678abcd9012abcd3456cdef" + ) # Should be lowercase + + def test_parse_apache_bsd_invalid_checksum(self): + """Test parsing Apache BSD format with invalid checksums.""" + parser = ApacheBSDFormat() + + content = """ +valid.txt: d41d8cd98f00b204e9800998ecf8427e +invalid.txt: this is not a valid checksum! +mixed.txt: d41d8cd9 NOTVALID + e9800998 ecf8427e + """ + + result = parser.parse(content) + + # Only valid checksums should be included + assert len(result) == 1 + assert result["valid.txt"] == "d41d8cd98f00b204e9800998ecf8427e" + assert "invalid.txt" not in result + assert "mixed.txt" not in result + + +class TestChecksumParser: + """Test cases for the main ChecksumParser.""" + + def test_parse_standard_format(self): + """Test parser with standard format.""" + parser = ChecksumParser() + + content = "d41d8cd98f00b204e9800998ecf8427e file.txt" + result = parser.parse(content) + + assert result["file.txt"] == "d41d8cd98f00b204e9800998ecf8427e" + + def test_parse_bsd_format(self): + """Test parser with BSD format.""" + parser = ChecksumParser() + + content = ( + "SHA256 (file.txt) = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ) + result = parser.parse(content) + + assert ( + result["file.txt"] == "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ) + + def test_parse_apache_bsd_format(self): + """Test parser with Apache BSD format.""" + parser = ChecksumParser() + + content = """file.txt: d41d8cd9 8f00b204 + e9800998 ecf8427e""" + result = parser.parse(content) + + assert result["file.txt"] == "d41d8cd98f00b204e9800998ecf8427e" + + def test_parse_empty_content(self): + """Test parser with empty content.""" + parser = ChecksumParser() + + result = parser.parse("") + assert result == {} + + def test_parse_unknown_format(self): + """Test parser with unknown format.""" + parser = ChecksumParser() + + content = "This is not a valid checksum format" + result = parser.parse(content) + assert result == {} From 5b0180cbf277936f83334c7a61e1f63f18e9c01e Mon Sep 17 00:00:00 2001 From: Simon Walker Date: Fri, 27 Jun 2025 06:16:17 +0100 Subject: [PATCH 62/74] CFNv2: implement get_template_summary (#12784) --- .../services/cloudformation/v2/entities.py | 4 ++ .../services/cloudformation/v2/provider.py | 68 ++++++++++++++++++- template.yml | 6 -- .../v2/ported_from_v1/api/test_changesets.py | 1 - .../v2/ported_from_v1/api/test_templates.py | 1 - 5 files changed, 69 insertions(+), 11 deletions(-) delete mode 100644 template.yml diff --git a/localstack-core/localstack/services/cloudformation/v2/entities.py b/localstack-core/localstack/services/cloudformation/v2/entities.py index 4d50076c52f05..a9e617b21819b 100644 --- a/localstack-core/localstack/services/cloudformation/v2/entities.py +++ b/localstack-core/localstack/services/cloudformation/v2/entities.py @@ -31,6 +31,7 @@ class ResolvedResource(TypedDict): + Type: str Properties: dict @@ -190,6 +191,9 @@ def describe_details(self) -> ApiStack: result["Outputs"] = describe_outputs return result + def is_active(self) -> bool: + return self.status != StackStatus.DELETE_COMPLETE + class ChangeSetRequestPayload(TypedDict, total=False): ChangeSetName: str diff --git a/localstack-core/localstack/services/cloudformation/v2/provider.py b/localstack-core/localstack/services/cloudformation/v2/provider.py index 404f9e9f946de..b55b989a838d3 100644 --- a/localstack-core/localstack/services/cloudformation/v2/provider.py +++ b/localstack-core/localstack/services/cloudformation/v2/provider.py @@ -1,5 +1,6 @@ import copy import logging +from collections import defaultdict from datetime import datetime, timezone from typing import Any, Optional @@ -23,6 +24,8 @@ DisableRollback, ExecuteChangeSetOutput, ExecutionStatus, + GetTemplateSummaryInput, + GetTemplateSummaryOutput, IncludePropertyValues, InvalidChangeSetStatusException, LogicalResourceId, @@ -211,9 +214,7 @@ def create_change_set( stack_candidates: list[Stack] = [ s for stack_arn, s in state.stacks_v2.items() if s.stack_name == stack_name ] - active_stack_candidates = [ - s for s in stack_candidates if self._stack_status_is_active(s.status) - ] + active_stack_candidates = [s for s in stack_candidates if s.is_active()] # on a CREATE an empty Stack should be generated if we didn't find an active one if not active_stack_candidates and change_set_type == ChangeSetType.CREATE: @@ -565,6 +566,67 @@ def describe_stack_events( raise StackNotFoundError(stack_name) return DescribeStackEventsOutput(StackEvents=stack.events) + @handler("GetTemplateSummary", expand=False) + def get_template_summary( + self, + context: RequestContext, + request: GetTemplateSummaryInput, + ) -> GetTemplateSummaryOutput: + state = get_cloudformation_store(context.account_id, context.region) + stack_name = request.get("StackName") + + if stack_name: + stack = find_stack_v2(state, stack_name) + if not stack: + raise StackNotFoundError(stack_name) + template = stack.template + else: + template_body = request.get("TemplateBody") + # s3 or secretsmanager url + template_url = request.get("TemplateURL") + + # validate and resolve template + if template_body and template_url: + raise ValidationError( + "Specify exactly one of 'TemplateBody' or 'TemplateUrl'" + ) # TODO: check proper message + + if not template_body and not template_url: + raise ValidationError( + "Specify exactly one of 'TemplateBody' or 'TemplateUrl'" + ) # TODO: check proper message + + template_body = api_utils.extract_template_body(request) + template = template_preparer.parse_template(template_body) + + id_summaries = defaultdict(list) + for resource_id, resource in template["Resources"].items(): + res_type = resource["Type"] + id_summaries[res_type].append(resource_id) + + summarized_parameters = [] + for parameter_id, parameter_body in template.get("Parameters", {}).items(): + summarized_parameters.append( + { + "ParameterKey": parameter_id, + "DefaultValue": parameter_body.get("Default"), + "ParameterType": parameter_body["Type"], + "Description": parameter_body.get("Description"), + } + ) + result = GetTemplateSummaryOutput( + Parameters=summarized_parameters, + Metadata=template.get("Metadata"), + ResourceIdentifierSummaries=[ + {"ResourceType": key, "LogicalResourceIds": values} + for key, values in id_summaries.items() + ], + ResourceTypes=list(id_summaries.keys()), + Version=template.get("AWSTemplateFormatVersion", "2010-09-09"), + ) + + return result + @handler("UpdateStack", expand=False) def update_stack( self, diff --git a/template.yml b/template.yml deleted file mode 100644 index fdf209f0b421f..0000000000000 --- a/template.yml +++ /dev/null @@ -1,6 +0,0 @@ -Resources: - MyParameter: - Type: AWS::SSM::Parameter - Properties: - Type: String - Value: foo diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py index d4e8a55a2d292..466a3165ab6cd 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py @@ -645,7 +645,6 @@ def test_create_and_then_remove_non_supported_resource_change_set(deploy_cfn_tem ) -@pytest.mark.skip("CFNV2:Other") @markers.aws.validated def test_create_and_then_update_refreshes_template_metadata( aws_client, diff --git a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_templates.py b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_templates.py index b50a3bc691e77..fbfe9d191a009 100644 --- a/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_templates.py +++ b/tests/aws/services/cloudformation/v2/ported_from_v1/api/test_templates.py @@ -17,7 +17,6 @@ ) -@pytest.mark.skip(reason="CFNV2:Provider") @markers.aws.validated @markers.snapshot.skip_snapshot_verify( paths=["$..ResourceIdentifierSummaries..ResourceIdentifiers", "$..Parameters"] From 27dd3b20e1d7435dc16bd46334a53b7d7ce7aaa6 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Palma <64580864+MEPalma@users.noreply.github.com> Date: Fri, 27 Jun 2025 16:22:04 +0200 Subject: [PATCH 63/74] CloudFormation v2 Engine: Runtime Caching Support (#12807) --- .../engine/v2/change_set_model.py | 28 +- .../engine/v2/change_set_model_describer.py | 28 +- .../engine/v2/change_set_model_executor.py | 3 +- .../engine/v2/change_set_model_preproc.py | 433 +++++++++--------- .../engine/v2/change_set_model_transform.py | 51 ++- .../services/cloudformation/v2/entities.py | 6 +- .../services/cloudformation/v2/provider.py | 42 +- .../v2/test_change_set_global_macros.py | 185 +++++++- ...est_change_set_global_macros.snapshot.json | 251 +++++----- ...t_change_set_global_macros.validation.json | 19 +- 10 files changed, 682 insertions(+), 364 deletions(-) diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model.py index c898c3d4bf4de..ce0cd63f00912 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model.py @@ -147,6 +147,22 @@ class ChangeSetNode(ChangeSetEntity, abc.ABC): ... class ChangeSetTerminal(ChangeSetEntity, abc.ABC): ... +class UpdateModel: + # TODO: may be expanded to keep track of other runtime values such as resolved_parameters. + + node_template: Final[NodeTemplate] + before_runtime_cache: Final[dict] + after_runtime_cache: Final[dict] + + def __init__( + self, + node_template: NodeTemplate, + ): + self.node_template = node_template + self.before_runtime_cache = dict() + self.after_runtime_cache = dict() + + class NodeTemplate(ChangeSetNode): transform: Final[NodeTransform] mappings: Final[NodeMappings] @@ -515,9 +531,8 @@ def __init__( ) # TODO: need to do template preprocessing e.g. parameter resolution, conditions etc. - def get_update_model(self) -> NodeTemplate: - # TODO: rethink naming of this for outer utils - return self._node_template + def get_update_model(self) -> UpdateModel: + return UpdateModel(node_template=self._node_template) def _visit_terminal_value( self, scope: Scope, before_value: Maybe[Any], after_value: Maybe[Any] @@ -548,8 +563,9 @@ def _visit_intrinsic_function( node_intrinsic_function = self._visited_scopes.get(scope) if isinstance(node_intrinsic_function, NodeIntrinsicFunction): return node_intrinsic_function + arguments_scope = scope.open_scope("args") arguments = self._visit_value( - scope=scope, before_value=before_arguments, after_value=after_arguments + scope=arguments_scope, before_value=before_arguments, after_value=after_arguments ) if is_created(before=before_arguments, after=after_arguments): change_type = ChangeType.CREATED @@ -777,7 +793,7 @@ def _visit_value( self._safe_access_in(scope, dominant_type_name, before_value, after_value) ) value = self._visit_intrinsic_function( - scope=scope, + scope=intrinsic_function_scope, intrinsic_function=dominant_type_name, before_arguments=before_arguments, after_arguments=after_arguments, @@ -937,7 +953,7 @@ def _visit_mappings( scope, mapping_name, before_mappings, after_mappings ) mapping = self._visit_mapping( - scope=scope, + scope=scope_mapping, name=mapping_name, before_mapping=before_mapping, after_mapping=after_mapping, diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_describer.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_describer.py index 8c5f19b900a16..14535d44a6f40 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_describer.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_describer.py @@ -8,6 +8,7 @@ NodeIntrinsicFunction, NodeProperty, NodeResource, + NodeResources, PropertiesKey, is_nothing, ) @@ -40,6 +41,20 @@ def get_changes(self) -> cfn_api.Changes: self.process() return self._changes + def _setup_runtime_cache(self) -> None: + # The describer can output {{changeSet:KNOWN_AFTER_APPLY}} values as not every field + # is computable at describe time. Until a filtering logic or executor override logic + # is available, the describer cannot benefit of previous evaluations to compute + # change set resource changes. + pass + + def _save_runtime_cache(self) -> None: + # The describer can output {{changeSet:KNOWN_AFTER_APPLY}} values as not every field + # is computable at describe time. Until a filtering logic or executor override logic + # is available, there are no benefits in having the describer saving its runtime cache + # for future changes chains. + pass + def _resolve_attribute(self, arguments: str | list[str], select_before: bool) -> str: if select_before: return super()._resolve_attribute(arguments=arguments, select_before=select_before) @@ -57,7 +72,8 @@ def _resolve_attribute(self, arguments: str | list[str], select_before: bool) -> attribute_name = arguments_list[1] node_resource = self._get_node_resource_for( - resource_name=logical_name_of_resource, node_template=self._node_template + resource_name=logical_name_of_resource, + node_template=self._change_set.update_model.node_template, ) node_property: Optional[NodeProperty] = self._get_node_property_for( property_name=attribute_name, node_resource=node_resource @@ -182,6 +198,13 @@ def _describe_resource_change( after_properties=after.properties, ) + def visit_node_resources(self, node_resources: NodeResources) -> None: + for node_resource in node_resources.resources: + delta_resource = self.visit(node_resource) + self._describe_resource_change( + name=node_resource.name, before=delta_resource.before, after=delta_resource.after + ) + def visit_node_resource( self, node_resource: NodeResource ) -> PreprocEntityDelta[PreprocResource, PreprocResource]: @@ -189,7 +212,4 @@ def visit_node_resource( after_resource = delta.after if not is_nothing(after_resource) and after_resource.physical_resource_id is None: after_resource.physical_resource_id = CHANGESET_KNOWN_AFTER_APPLY - self._describe_resource_change( - name=node_resource.name, before=delta.before, after=delta.after - ) return delta diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py index ff0485df2cf46..99603edf027a0 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py @@ -159,7 +159,8 @@ def visit_node_depends_on(self, node_depends_on: NodeDependsOn) -> PreprocEntity depends_on_resource_logical_ids.update(array_identifiers_delta.after) for depends_on_resource_logical_id in depends_on_resource_logical_ids: node_resource = self._get_node_resource_for( - resource_name=depends_on_resource_logical_id, node_template=self._node_template + resource_name=depends_on_resource_logical_id, + node_template=self._change_set.update_model.node_template, ) self.visit(node_resource) diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py index 5ec1b58e8bcf3..abaae139c741f 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_preproc.py @@ -1,8 +1,9 @@ from __future__ import annotations import base64 +import copy import re -from typing import Any, Final, Generic, Optional, TypeVar +from typing import Any, Callable, Final, Generic, Optional, TypeVar from botocore.exceptions import ClientError @@ -33,6 +34,7 @@ NodeResource, NodeTemplate, Nothing, + NothingType, Scope, TerminalValue, TerminalValueCreated, @@ -165,19 +167,44 @@ def __eq__(self, other): class ChangeSetModelPreproc(ChangeSetModelVisitor): _change_set: Final[ChangeSet] - _node_template: Final[NodeTemplate] _before_resolved_resources: Final[dict] - _processed: dict[Scope, Any] + _before_cache: Final[dict[Scope, Any]] + _after_cache: Final[dict[Scope, Any]] def __init__(self, change_set: ChangeSet): self._change_set = change_set - self._node_template = change_set.update_model self._before_resolved_resources = change_set.stack.resolved_resources - self._processed = dict() + self._before_cache = dict() + self._after_cache = dict() + + def _setup_runtime_cache(self) -> None: + runtime_cache_key = self.__class__.__name__ + + self._before_cache.clear() + self._after_cache.clear() + + before_runtime_cache = self._change_set.update_model.before_runtime_cache + if cache := before_runtime_cache.get(runtime_cache_key): + self._before_cache.update(cache) + + after_runtime_cache = self._change_set.update_model.after_runtime_cache + if cache := after_runtime_cache.get(runtime_cache_key): + self._after_cache.update(cache) + + def _save_runtime_cache(self) -> None: + runtime_cache_key = self.__class__.__name__ + + before_runtime_cache = self._change_set.update_model.before_runtime_cache + before_runtime_cache[runtime_cache_key] = copy.deepcopy(self._before_cache) + + after_runtime_cache = self._change_set.update_model.after_runtime_cache + after_runtime_cache[runtime_cache_key] = copy.deepcopy(self._after_cache) def process(self) -> None: - self._processed.clear() - self.visit(self._node_template) + self._setup_runtime_cache() + node_template = self._change_set.update_model.node_template + self.visit(node_template) + self._save_runtime_cache() def _get_node_resource_for( self, resource_name: str, node_template: NodeTemplate @@ -209,7 +236,8 @@ def _deployed_property_value_of( # be accessible through delta objects, to ensure computation is always complete at # every level. _ = self._get_node_resource_for( - resource_name=resource_logical_id, node_template=self._node_template + resource_name=resource_logical_id, + node_template=self._change_set.update_model.node_template, ) resolved_resource = resolved_resources.get(resource_logical_id) if resolved_resource is None: @@ -241,7 +269,7 @@ def _after_deployed_property_value_of( ) def _get_node_mapping(self, map_name: str) -> NodeMapping: - mappings: list[NodeMapping] = self._node_template.mappings.mappings + mappings: list[NodeMapping] = self._change_set.update_model.node_template.mappings.mappings # TODO: another scenarios suggesting property lookups might be preferable. for mapping in mappings: if mapping.name == map_name: @@ -250,7 +278,9 @@ def _get_node_mapping(self, map_name: str) -> NodeMapping: raise RuntimeError(f"Undefined '{map_name}' mapping") def _get_node_parameter_if_exists(self, parameter_name: str) -> Maybe[NodeParameter]: - parameters: list[NodeParameter] = self._node_template.parameters.parameters + parameters: list[NodeParameter] = ( + self._change_set.update_model.node_template.parameters.parameters + ) # TODO: another scenarios suggesting property lookups might be preferable. for parameter in parameters: if parameter.name == parameter_name: @@ -259,7 +289,9 @@ def _get_node_parameter_if_exists(self, parameter_name: str) -> Maybe[NodeParame return Nothing def _get_node_condition_if_exists(self, condition_name: str) -> Maybe[NodeCondition]: - conditions: list[NodeCondition] = self._node_template.conditions.conditions + conditions: list[NodeCondition] = ( + self._change_set.update_model.node_template.conditions.conditions + ) # TODO: another scenarios suggesting property lookups might be preferable. for condition in conditions: if condition.name == condition_name: @@ -307,7 +339,7 @@ def _resolve_reference(self, logical_id: str) -> PreprocEntityDelta: return parameter_delta node_resource = self._get_node_resource_for( - resource_name=logical_id, node_template=self._node_template + resource_name=logical_id, node_template=self._change_set.update_model.node_template ) resource_delta = self.visit(node_resource) before = resource_delta.before @@ -327,14 +359,65 @@ def _resolve_mapping( return mapping_value_delta def visit(self, change_set_entity: ChangeSetEntity) -> PreprocEntityDelta: - scope = change_set_entity.scope - if scope in self._processed: - delta = self._processed[scope] - return delta + entity_scope = change_set_entity.scope + if entity_scope in self._before_cache and entity_scope in self._after_cache: + before = self._before_cache[entity_scope] + after = self._after_cache[entity_scope] + return PreprocEntityDelta(before=before, after=after) delta = super().visit(change_set_entity=change_set_entity) - self._processed[scope] = delta + if isinstance(delta, PreprocEntityDelta): + self._before_cache[entity_scope] = delta.before + self._after_cache[entity_scope] = delta.after return delta + def _cached_apply( + self, scope: Scope, arguments_delta: PreprocEntityDelta, resolver: Callable[[Any], Any] + ) -> PreprocEntityDelta: + """ + Applies the resolver function to the given input delta if and only if the required + values are not already present in the runtime caches. This function handles both + the 'before' and 'after' components of the delta independently. + + The resolver function receives either the 'before' or 'after' value from the input + delta and returns a resolved value. If the result returned by the resolver is + itself a PreprocEntityDelta, the function automatically extracts the appropriate + component from it: the 'before' value if the input was 'before', and the 'after' + value if the input was 'after'. + + This function only reads from the cache and does not update it. It is the caller's + responsibility to handle caching, either manually or via the upstream visit method + of this class. + + Args: + scope (Scope): The current scope used as a key for cache lookup. + arguments_delta (PreprocEntityDelta): The delta containing 'before' and 'after' values to resolve. + resolver (Callable[[Any], Any]): Function to apply on uncached 'before' or 'after' argument values. + + Returns: + PreprocEntityDelta: A new delta with resolved 'before' and 'after' values. + """ + + # TODO: Update all visit_* methods in this class and its subclasses to use this function. + # This ensures maximal reuse of precomputed 'before' (and 'after') values from + # prior runtimes on the change sets template, thus avoiding unnecessary recomputation. + + arguments_before = arguments_delta.before + arguments_after = arguments_delta.after + + before = self._before_cache.get(scope, Nothing) + if is_nothing(before) and not is_nothing(arguments_before): + before = resolver(arguments_before) + if isinstance(before, PreprocEntityDelta): + before = before.before + + after = self._after_cache.get(scope, Nothing) + if is_nothing(after) and not is_nothing(arguments_after): + after = resolver(arguments_after) + if isinstance(after, PreprocEntityDelta): + after = after.after + + return PreprocEntityDelta(before=before, after=after) + def visit_terminal_value_modified( self, terminal_value_modified: TerminalValueModified ) -> PreprocEntityDelta: @@ -391,7 +474,8 @@ def _resolve_attribute(self, arguments: str | list[str], select_before: bool) -> attribute_name = arguments_list[1] node_resource = self._get_node_resource_for( - resource_name=logical_name_of_resource, node_template=self._node_template + resource_name=logical_name_of_resource, + node_template=self._change_set.update_model.node_template, ) node_property: Optional[NodeProperty] = self._get_node_property_for( property_name=attribute_name, node_resource=node_resource @@ -423,12 +507,12 @@ def visit_node_intrinsic_function_fn_get_att( before_arguments: Maybe[str | list[str]] = arguments_delta.before after_arguments: Maybe[str | list[str]] = arguments_delta.after - before = Nothing - if not is_nothing(before_arguments): + before = self._before_cache.get(node_intrinsic_function.scope, Nothing) + if is_nothing(before) and not is_nothing(before_arguments): before = self._resolve_attribute(arguments=before_arguments, select_before=True) - after = Nothing - if not is_nothing(after_arguments): + after = self._after_cache.get(node_intrinsic_function.scope, Nothing) + if is_nothing(after) and not is_nothing(after_arguments): after = self._resolve_attribute(arguments=after_arguments, select_before=False) return PreprocEntityDelta(before=before, after=after) @@ -436,24 +520,21 @@ def visit_node_intrinsic_function_fn_get_att( def visit_node_intrinsic_function_fn_equals( self, node_intrinsic_function: NodeIntrinsicFunction ) -> PreprocEntityDelta: + # TODO: add argument shape validation. + def _compute_fn_equals(args: list[Any]) -> bool: + return args[0] == args[1] + arguments_delta = self.visit(node_intrinsic_function.arguments) - before_values = arguments_delta.before - after_values = arguments_delta.after - before = Nothing - if before_values: - before = before_values[0] == before_values[1] - after = Nothing - if after_values: - after = after_values[0] == after_values[1] - return PreprocEntityDelta(before=before, after=after) + delta = self._cached_apply( + scope=node_intrinsic_function.scope, + arguments_delta=arguments_delta, + resolver=_compute_fn_equals, + ) + return delta def visit_node_intrinsic_function_fn_if( self, node_intrinsic_function: NodeIntrinsicFunction ) -> PreprocEntityDelta: - arguments_delta = self.visit(node_intrinsic_function.arguments) - arguments_before = arguments_delta.before - arguments_after = arguments_delta.after - def _compute_delta_for_if_statement(args: list[Any]) -> PreprocEntityDelta: condition_name = args[0] boolean_expression_delta = self._resolve_condition(logical_id=condition_name) @@ -462,74 +543,57 @@ def _compute_delta_for_if_statement(args: list[Any]) -> PreprocEntityDelta: after=args[1] if boolean_expression_delta.after else args[2], ) - # TODO: add support for this being created or removed. - before = Nothing - if not is_nothing(arguments_before): - before_outcome_delta = _compute_delta_for_if_statement(arguments_before) - before = before_outcome_delta.before - after = Nothing - if not is_nothing(arguments_after): - after_outcome_delta = _compute_delta_for_if_statement(arguments_after) - after = after_outcome_delta.after - return PreprocEntityDelta(before=before, after=after) + arguments_delta = self.visit(node_intrinsic_function.arguments) + delta = self._cached_apply( + scope=node_intrinsic_function.scope, + arguments_delta=arguments_delta, + resolver=_compute_delta_for_if_statement, + ) + return delta def visit_node_intrinsic_function_fn_and( self, node_intrinsic_function: NodeIntrinsicFunction ) -> PreprocEntityDelta: - arguments_delta = self.visit(node_intrinsic_function.arguments) - arguments_before = arguments_delta.before - arguments_after = arguments_delta.after - - def _compute_fn_and(args: list[bool]): + def _compute_fn_and(args: list[bool]) -> bool: result = all(args) return result - before = Nothing - if not is_nothing(arguments_before): - before = _compute_fn_and(arguments_before) - - after = Nothing - if not is_nothing(arguments_after): - after = _compute_fn_and(arguments_after) - - return PreprocEntityDelta(before=before, after=after) + arguments_delta = self.visit(node_intrinsic_function.arguments) + delta = self._cached_apply( + scope=node_intrinsic_function.scope, + arguments_delta=arguments_delta, + resolver=_compute_fn_and, + ) + return delta def visit_node_intrinsic_function_fn_or( self, node_intrinsic_function: NodeIntrinsicFunction ) -> PreprocEntityDelta: - arguments_delta = self.visit(node_intrinsic_function.arguments) - arguments_before = arguments_delta.before - arguments_after = arguments_delta.after - - def _compute_fn_and(args: list[bool]): + def _compute_fn_or(args: list[bool]): result = any(args) return result - before = Nothing - if not is_nothing(arguments_before): - before = _compute_fn_and(arguments_before) - - after = Nothing - if not is_nothing(arguments_after): - after = _compute_fn_and(arguments_after) - return PreprocEntityDelta(before=before, after=after) + arguments_delta = self.visit(node_intrinsic_function.arguments) + delta = self._cached_apply( + scope=node_intrinsic_function.scope, + arguments_delta=arguments_delta, + resolver=_compute_fn_or, + ) + return delta def visit_node_intrinsic_function_fn_not( self, node_intrinsic_function: NodeIntrinsicFunction ) -> PreprocEntityDelta: + def _compute_fn_not(arg: bool) -> bool: + return not arg + arguments_delta = self.visit(node_intrinsic_function.arguments) - before_condition = arguments_delta.before - after_condition = arguments_delta.after - before = Nothing - if not is_nothing(before_condition): - before_condition_outcome = before_condition[0] - before = not before_condition_outcome - after = Nothing - if not is_nothing(after_condition): - after_condition_outcome = after_condition[0] - after = not after_condition_outcome - # Implicit change type computation. - return PreprocEntityDelta(before=before, after=after) + delta = self._cached_apply( + scope=node_intrinsic_function.scope, + arguments_delta=arguments_delta, + resolver=_compute_fn_not, + ) + return delta def _compute_fn_transform(self, args: dict[str, Any]) -> Any: # TODO: add typing to arguments before this level. @@ -583,33 +647,16 @@ def visit_node_intrinsic_function_fn_transform( self, node_intrinsic_function: NodeIntrinsicFunction ) -> PreprocEntityDelta: arguments_delta = self.visit(node_intrinsic_function.arguments) - arguments_before = arguments_delta.before - arguments_after = arguments_delta.after - - # TODO: review the use of cache in self.precessed from the 'before' run to - # ensure changes to the lambda (such as after UpdateFunctionCode) do not - # generalise tot he before value at this depth (thus making it seems as - # though for this transformation before==after). Another options may be to - # have specialised caching for transformations. - - # TODO: add tests to review the behaviour of CFN with changes to transformation - # function code and no changes to the template. - - before = Nothing - if not is_nothing(arguments_before): - before = self._compute_fn_transform(args=arguments_before) - after = Nothing - if not is_nothing(arguments_after): - after = self._compute_fn_transform(args=arguments_after) - return PreprocEntityDelta(before=before, after=after) + delta = self._cached_apply( + scope=node_intrinsic_function.scope, + arguments_delta=arguments_delta, + resolver=self._compute_fn_transform, + ) + return delta def visit_node_intrinsic_function_fn_sub( self, node_intrinsic_function: NodeIntrinsicFunction ) -> PreprocEntityDelta: - arguments_delta = self.visit(node_intrinsic_function.arguments) - arguments_before = arguments_delta.before - arguments_after = arguments_delta.after - def _compute_sub(args: str | list[Any], select_before: bool) -> str: # TODO: add further schema validation. string_template: str @@ -695,24 +742,25 @@ def _compute_sub(args: str | list[Any], select_before: bool) -> str: result = sub_string return result - before = Nothing - if not is_nothing(arguments_before): + arguments_delta = self.visit(node_intrinsic_function.arguments) + arguments_before = arguments_delta.before + arguments_after = arguments_delta.after + before = self._before_cache.get(node_intrinsic_function.scope, Nothing) + if is_nothing(before) and not is_nothing(arguments_before): before = _compute_sub(args=arguments_before, select_before=True) - after = Nothing - if not is_nothing(arguments_after): + after = self._after_cache.get(node_intrinsic_function.scope, Nothing) + if is_nothing(after) and not is_nothing(arguments_after): after = _compute_sub(args=arguments_after, select_before=False) return PreprocEntityDelta(before=before, after=after) def visit_node_intrinsic_function_fn_join( self, node_intrinsic_function: NodeIntrinsicFunction ) -> PreprocEntityDelta: - arguments_delta = self.visit(node_intrinsic_function.arguments) - arguments_before = arguments_delta.before - arguments_after = arguments_delta.after - - def _compute_join(args: list[Any]) -> str: - # TODO: add support for schema validation. - # TODO: add tests for joining non string values. + # TODO: add support for schema validation. + # TODO: add tests for joining non string values. + def _compute_fn_join(args: list[Any]) -> str | NothingType: + if not (isinstance(args, list) and len(args) == 2): + return Nothing delimiter: str = str(args[0]) values: list[Any] = args[1] if not isinstance(values, list): @@ -731,22 +779,18 @@ def _compute_join(args: list[Any]) -> str: join_result = delimiter.join(str_values) return join_result - before = Nothing - if isinstance(arguments_before, list) and len(arguments_before) == 2: - before = _compute_join(arguments_before) - after = Nothing - if isinstance(arguments_after, list) and len(arguments_after) == 2: - after = _compute_join(arguments_after) - return PreprocEntityDelta(before=before, after=after) + arguments_delta = self.visit(node_intrinsic_function.arguments) + delta = self._cached_apply( + scope=node_intrinsic_function.scope, + arguments_delta=arguments_delta, + resolver=_compute_fn_join, + ) + return delta def visit_node_intrinsic_function_fn_select( self, node_intrinsic_function: NodeIntrinsicFunction ): # TODO: add further support for schema validation - arguments_delta = self.visit(node_intrinsic_function.arguments) - arguments_before = arguments_delta.before - arguments_after = arguments_delta.after - def _compute_fn_select(args: list[Any]) -> Any: values: list[Any] = args[1] if not isinstance(values, list) or not values: @@ -758,24 +802,18 @@ def _compute_fn_select(args: list[Any]) -> Any: selection = values[index] return selection - before = Nothing - if not is_nothing(arguments_before): - before = _compute_fn_select(arguments_before) - - after = Nothing - if not is_nothing(arguments_after): - after = _compute_fn_select(arguments_after) - - return PreprocEntityDelta(before=before, after=after) + arguments_delta = self.visit(node_intrinsic_function.arguments) + delta = self._cached_apply( + scope=node_intrinsic_function.scope, + arguments_delta=arguments_delta, + resolver=_compute_fn_select, + ) + return delta def visit_node_intrinsic_function_fn_split( self, node_intrinsic_function: NodeIntrinsicFunction ): # TODO: add further support for schema validation - arguments_delta = self.visit(node_intrinsic_function.arguments) - arguments_before = arguments_delta.before - arguments_after = arguments_delta.after - def _compute_fn_split(args: list[Any]) -> Any: delimiter = args[0] if not isinstance(delimiter, str) or not delimiter: @@ -786,23 +824,18 @@ def _compute_fn_split(args: list[Any]) -> Any: split_string = source_string.split(delimiter) return split_string - before = Nothing - if not is_nothing(arguments_before): - before = _compute_fn_split(arguments_before) - - after = Nothing - if not is_nothing(arguments_after): - after = _compute_fn_split(arguments_after) - - return PreprocEntityDelta(before=before, after=after) + arguments_delta = self.visit(node_intrinsic_function.arguments) + delta = self._cached_apply( + scope=node_intrinsic_function.scope, + arguments_delta=arguments_delta, + resolver=_compute_fn_split, + ) + return delta def visit_node_intrinsic_function_fn_get_a_zs( self, node_intrinsic_function: NodeIntrinsicFunction ) -> PreprocEntityDelta: # TODO: add further support for schema validation - arguments_delta = self.visit(node_intrinsic_function.arguments) - arguments_before = arguments_delta.before - arguments_after = arguments_delta.after def _compute_fn_get_a_zs(region) -> Any: if not isinstance(region, str): @@ -827,24 +860,18 @@ def _compute_fn_get_a_zs(region) -> Any: azs = [az["ZoneName"] for az in availability_zones] return azs - before = Nothing - if not is_nothing(arguments_before): - before = _compute_fn_get_a_zs(arguments_before) - - after = Nothing - if not is_nothing(arguments_after): - after = _compute_fn_get_a_zs(arguments_after) - - return PreprocEntityDelta(before=before, after=after) + arguments_delta = self.visit(node_intrinsic_function.arguments) + delta = self._cached_apply( + scope=node_intrinsic_function.scope, + arguments_delta=arguments_delta, + resolver=_compute_fn_get_a_zs, + ) + return delta def visit_node_intrinsic_function_fn_base64( self, node_intrinsic_function: NodeIntrinsicFunction ) -> PreprocEntityDelta: # TODO: add further support for schema validation - arguments_delta = self.visit(node_intrinsic_function.arguments) - arguments_before = arguments_delta.before - arguments_after = arguments_delta.after - def _compute_fn_base_64(string) -> Any: if not isinstance(string, str): raise RuntimeError(f"Invalid valueToEncode for Fn::Base64: '{string}'") @@ -852,15 +879,13 @@ def _compute_fn_base_64(string) -> Any: base64_string = to_str(base64.b64encode(to_bytes(string))) return base64_string - before = Nothing - if not is_nothing(arguments_before): - before = _compute_fn_base_64(arguments_before) - - after = Nothing - if not is_nothing(arguments_after): - after = _compute_fn_base_64(arguments_after) - - return PreprocEntityDelta(before=before, after=after) + arguments_delta = self.visit(node_intrinsic_function.arguments) + delta = self._cached_apply( + scope=node_intrinsic_function.scope, + arguments_delta=arguments_delta, + resolver=_compute_fn_base_64, + ) + return delta def visit_node_intrinsic_function_fn_find_in_map( self, node_intrinsic_function: NodeIntrinsicFunction @@ -941,52 +966,40 @@ def _after_resource_physical_id(self, resource_logical_id: str) -> str: def visit_node_intrinsic_function_ref( self, node_intrinsic_function: NodeIntrinsicFunction ) -> PreprocEntityDelta: - arguments_delta = self.visit(node_intrinsic_function.arguments) - before_logical_id = arguments_delta.before - after_logical_id = arguments_delta.after - - # TODO: extend this to support references to other types. - before = Nothing - if not is_nothing(before_logical_id): - before_delta = self._resolve_reference(logical_id=before_logical_id) - before = before_delta.before - if isinstance(before, PreprocResource): - before = before.physical_resource_id - - after = Nothing - if not is_nothing(after_logical_id): - after_delta = self._resolve_reference(logical_id=after_logical_id) - after = after_delta.after - if isinstance(after, PreprocResource): - after = after.physical_resource_id + def _compute_fn_ref(logical_id: str) -> PreprocEntityDelta: + reference_delta: PreprocEntityDelta = self._resolve_reference(logical_id=logical_id) + if isinstance(before := reference_delta.before, PreprocResource): + reference_delta.before = before.physical_resource_id + if isinstance(after := reference_delta.after, PreprocResource): + reference_delta.after = after.physical_resource_id + return reference_delta - return PreprocEntityDelta(before=before, after=after) + arguments_delta = self.visit(node_intrinsic_function.arguments) + delta = self._cached_apply( + scope=node_intrinsic_function.scope, + arguments_delta=arguments_delta, + resolver=_compute_fn_ref, + ) + return delta def visit_node_intrinsic_function_condition( self, node_intrinsic_function: NodeIntrinsicFunction ) -> PreprocEntityDelta: arguments_delta = self.visit(node_intrinsic_function.arguments) - before_condition_name = arguments_delta.before - after_condition_name = arguments_delta.after def _delta_of_condition(name: str) -> PreprocEntityDelta: node_condition = self._get_node_condition_if_exists(condition_name=name) if is_nothing(node_condition): raise RuntimeError(f"Undefined condition '{name}'") - delta = self.visit(node_condition) - return delta - - before = Nothing - if not is_nothing(before_condition_name): - before_delta = _delta_of_condition(before_condition_name) - before = before_delta.before - - after = Nothing - if not is_nothing(after_condition_name): - after_delta = _delta_of_condition(after_condition_name) - after = after_delta.after + condition_delta = self.visit(node_condition) + return condition_delta - return PreprocEntityDelta(before=before, after=after) + delta = self._cached_apply( + resolver=_delta_of_condition, + scope=node_intrinsic_function.scope, + arguments_delta=arguments_delta, + ) + return delta def visit_node_array(self, node_array: NodeArray) -> PreprocEntityDelta: node_change_type = node_array.change_type diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_transform.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_transform.py index 4ba3e43c5c700..70981d014747c 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_transform.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_transform.py @@ -18,6 +18,7 @@ NodeParameter, NodeTransform, Nothing, + Scope, is_nothing, ) from localstack.services.cloudformation.engine.v2.change_set_model_preproc import ( @@ -33,6 +34,8 @@ EXTENSIONS_TRANSFORM = "AWS::LanguageExtensions" SECRETSMANAGER_TRANSFORM = "AWS::SecretsManager-2020-07-23" +_SCOPE_TRANSFORM_TEMPLATE_OUTCOME: Final[Scope] = Scope("TRANSFORM_TEMPLATE_OUTCOME") + # TODO: evaluate the use of subtypes to represent and validate types of transforms class GlobalTransform: @@ -190,35 +193,47 @@ def _apply_global_transform( return transformed_template def transform(self) -> tuple[dict, dict]: - parameters_delta = self.visit_node_parameters(self._node_template.parameters) + self._setup_runtime_cache() + + node_template = self._change_set.update_model.node_template + + parameters_delta = self.visit_node_parameters(node_template.parameters) parameters_before = parameters_delta.before parameters_after = parameters_delta.after transform_delta: PreprocEntityDelta[list[GlobalTransform], list[GlobalTransform]] = ( - self.visit_node_transform(self._node_template.transform) + self.visit_node_transform(node_template.transform) ) transform_before: Maybe[list[GlobalTransform]] = transform_delta.before transform_after: Maybe[list[GlobalTransform]] = transform_delta.after transformed_before_template = self._before_template - if not is_nothing(transform_before) and not is_nothing(self._before_template): - transformed_before_template = self._before_template - for before_global_transform in transform_before: - transformed_before_template = self._apply_global_transform( - global_transform=before_global_transform, - parameters=parameters_before, - template=transformed_before_template, - ) + if transform_before and not is_nothing(self._before_template): + transformed_before_template = self._before_cache.get(_SCOPE_TRANSFORM_TEMPLATE_OUTCOME) + if not transformed_before_template: + transformed_before_template = self._before_template + for before_global_transform in transform_before: + transformed_before_template = self._apply_global_transform( + global_transform=before_global_transform, + parameters=parameters_before, + template=transformed_before_template, + ) + self._before_cache[_SCOPE_TRANSFORM_TEMPLATE_OUTCOME] = transformed_before_template transformed_after_template = self._after_template - if not is_nothing(transform_after) and not is_nothing(self._after_template): - transformed_after_template = self._after_template - for after_global_transform in transform_after: - transformed_after_template = self._apply_global_transform( - global_transform=after_global_transform, - parameters=parameters_after, - template=transformed_after_template, - ) + if transform_after and not is_nothing(self._after_template): + transformed_after_template = self._after_cache.get(_SCOPE_TRANSFORM_TEMPLATE_OUTCOME) + if not transformed_after_template: + transformed_after_template = self._after_template + for after_global_transform in transform_after: + transformed_after_template = self._apply_global_transform( + global_transform=after_global_transform, + parameters=parameters_after, + template=transformed_after_template, + ) + self._after_cache[_SCOPE_TRANSFORM_TEMPLATE_OUTCOME] = transformed_after_template + + self._save_runtime_cache() return transformed_before_template, transformed_after_template diff --git a/localstack-core/localstack/services/cloudformation/v2/entities.py b/localstack-core/localstack/services/cloudformation/v2/entities.py index a9e617b21819b..0d44ae1276ade 100644 --- a/localstack-core/localstack/services/cloudformation/v2/entities.py +++ b/localstack-core/localstack/services/cloudformation/v2/entities.py @@ -24,7 +24,7 @@ StackIdentifier, ) from localstack.services.cloudformation.engine.v2.change_set_model import ( - NodeTemplate, + UpdateModel, ) from localstack.utils.aws import arns from localstack.utils.strings import long_uid, short_uid @@ -204,7 +204,7 @@ class ChangeSet: change_set_name: str change_set_id: str change_set_type: ChangeSetType - update_model: Optional[NodeTemplate] + update_model: Optional[UpdateModel] status: ChangeSetStatus execution_status: ExecutionStatus creation_time: datetime @@ -231,7 +231,7 @@ def __init__( region_name=self.stack.region_name, ) - def set_update_model(self, update_model: NodeTemplate) -> None: + def set_update_model(self, update_model: UpdateModel) -> None: self.update_model = update_model def set_change_set_status(self, status: ChangeSetStatus): diff --git a/localstack-core/localstack/services/cloudformation/v2/provider.py b/localstack-core/localstack/services/cloudformation/v2/provider.py index b55b989a838d3..5e96a743780b0 100644 --- a/localstack-core/localstack/services/cloudformation/v2/provider.py +++ b/localstack-core/localstack/services/cloudformation/v2/provider.py @@ -47,7 +47,7 @@ from localstack.services.cloudformation.engine.v2.change_set_model import ( ChangeSetModel, ChangeType, - NodeTemplate, + UpdateModel, ) from localstack.services.cloudformation.engine.v2.change_set_model_describer import ( ChangeSetModelDescriber, @@ -133,6 +133,7 @@ def _setup_change_set_model( after_template: Optional[dict], before_parameters: Optional[dict], after_parameters: Optional[dict], + previous_update_model: Optional[UpdateModel], ): # Create and preprocess the update graph for this template update. change_set_model = ChangeSetModel( @@ -141,7 +142,12 @@ def _setup_change_set_model( before_parameters=before_parameters, after_parameters=after_parameters, ) - raw_update_model: NodeTemplate = change_set_model.get_update_model() + raw_update_model: UpdateModel = change_set_model.get_update_model() + # If there exists an update model which operated in the 'before' version of this change set, + # port the runtime values computed for the before version into this latest update model. + if previous_update_model: + raw_update_model.before_runtime_cache.clear() + raw_update_model.before_runtime_cache.update(previous_update_model.after_runtime_cache) change_set.set_update_model(raw_update_model) # Apply global transforms. @@ -165,6 +171,12 @@ def _setup_change_set_model( after_parameters=after_parameters, ) update_model = change_set_model.get_update_model() + # Bring the cache for the previous operations forward in the update graph for this version + # of the templates. This enables downstream update graph visitors to access runtime + # information computed whilst evaluating the previous version of this template, and during + # the transformations. + update_model.before_runtime_cache.update(raw_update_model.before_runtime_cache) + update_model.after_runtime_cache.update(raw_update_model.after_runtime_cache) change_set.set_update_model(update_model) @handler("CreateChangeSet", expand=False) @@ -284,6 +296,15 @@ def create_change_set( before_template = stack.template after_template = structured_template + previous_update_model = None + try: + # FIXME: 'change_set_id' for 'stack' objects is dynamically attributed + if previous_change_set := find_change_set_v2(state, stack.change_set_id): + previous_update_model = previous_change_set.update_model + except Exception: + # No change set available on this stack. + pass + # create change set for the stack and apply changes change_set = ChangeSet(stack, request, template=after_template) self._setup_change_set_model( @@ -292,6 +313,7 @@ def create_change_set( after_template=after_template, before_parameters=before_parameters, after_parameters=after_parameters, + previous_update_model=previous_update_model, ) change_set.set_change_set_status(ChangeSetStatus.CREATE_COMPLETE) @@ -488,6 +510,7 @@ def create_stack(self, context: RequestContext, request: CreateStackInput) -> Cr after_template=after_template, before_parameters=None, after_parameters=after_parameters, + previous_update_model=None, ) # deployment process @@ -695,6 +718,10 @@ def update_stack( before_template = stack.template after_template = structured_template + previous_update_model = None + if previous_change_set := find_change_set_v2(state, stack.change_set_id): + previous_update_model = previous_change_set.update_model + change_set = ChangeSet( stack, {"ChangeSetName": f"cs-{stack_name}-create", "ChangeSetType": ChangeSetType.CREATE}, @@ -706,9 +733,13 @@ def update_stack( after_template=after_template, before_parameters=before_parameters, after_parameters=after_parameters, + previous_update_model=previous_update_model, ) - if change_set.update_model.change_type == ChangeType.UNCHANGED: + # TODO: some changes are only detectable at runtime; consider using + # the ChangeSetModelDescriber, or a new custom visitors, to + # pick-up on runtime changes. + if change_set.update_model.node_template.change_type == ChangeType.UNCHANGED: raise ValidationError("No updates are to be performed.") stack.set_stack_status(StackStatus.UPDATE_IN_PROGRESS) @@ -757,6 +788,10 @@ def delete_stack( stack.deletion_time = datetime.now(tz=timezone.utc) return + previous_update_model = None + if previous_change_set := find_change_set_v2(state, stack.change_set_id): + previous_update_model = previous_change_set.update_model + # create a dummy change set change_set = ChangeSet(stack, {"ChangeSetName": f"delete-stack_{stack.stack_name}"}) # noqa self._setup_change_set_model( @@ -765,6 +800,7 @@ def delete_stack( after_template=None, before_parameters=stack.resolved_parameters, after_parameters=None, + previous_update_model=previous_update_model, ) change_set_executor = ChangeSetModelExecutor(change_set) diff --git a/tests/aws/services/cloudformation/v2/test_change_set_global_macros.py b/tests/aws/services/cloudformation/v2/test_change_set_global_macros.py index c557cc1ad6334..ef31281f2096e 100644 --- a/tests/aws/services/cloudformation/v2/test_change_set_global_macros.py +++ b/tests/aws/services/cloudformation/v2/test_change_set_global_macros.py @@ -1,12 +1,15 @@ +import json import os import pytest -from localstack_snapshot.snapshots.transformer import JsonpathTransformer +from localstack_snapshot.snapshots.transformer import JsonpathTransformer, RegexTransformer from localstack.aws.api.lambda_ import Runtime from localstack.services.cloudformation.v2.utils import is_v2_engine from localstack.testing.aws.util import is_aws_cloud from localstack.testing.pytest import markers +from localstack.testing.pytest.cloudformation.fixtures import _normalise_describe_change_set_output +from localstack.utils.functions import call_safe from localstack.utils.strings import short_uid @@ -31,9 +34,6 @@ ) class TestChangeSetGlobalMacros: @markers.aws.validated - @pytest.mark.skip( - reason="CFNV2:Other deletion of CFN macro is received before the template update event" - ) def test_base_global_macro( self, aws_client, @@ -94,8 +94,183 @@ def test_base_global_macro( }, }, "Outputs": { - "ParameterName": {"Value": {"Ref": "Parameter"}}, "Parameter2Name": {"Value": {"Ref": "Parameter2"}}, }, } capture_update_process(snapshot, template_1, template_2) + + @markers.aws.validated + def test_update_after_macro_for_before_version_is_deleted( + self, + aws_client, + aws_client_no_retry, + cleanups, + snapshot, + deploy_cfn_template, + create_lambda_function, + capture_update_process, + ): + snapshot.add_transformer( + JsonpathTransformer( + jsonpath="$..Outputs..OutputValue", + replacement="output-value", + replace_reference=True, + ) + ) + snapshot.add_transformer(snapshot.transform.cloudformation_api()) + macro_function_path = os.path.join( + os.path.dirname(__file__), "../../../templates/macros/format_template.py" + ) + + # Create the macro to be used in the first version of the template. + macro_name_first = f"SubstitutionMacroFirst-{short_uid()}" + snapshot.add_transformer(RegexTransformer(macro_name_first, "macro-name-first")) + func_name = f"test_lambda_{short_uid()}" + create_lambda_function( + func_name=func_name, + handler_file=macro_function_path, + runtime=Runtime.python3_12, + client=aws_client.lambda_, + timeout=1, + ) + macro_stack_first = deploy_cfn_template( + template_path=os.path.join( + os.path.dirname(__file__), "../../../templates/macro_resource.yml" + ), + parameters={"FunctionName": func_name, "MacroName": macro_name_first}, + ) + + # Create the first version of the stack. + template_1 = { + "Transform": macro_name_first, + "Parameters": {"Substitution": {"Type": "String", "Default": "SubstitutionDefault"}}, + "Resources": { + "Parameter": { + "Type": "AWS::SSM::Parameter", + "Properties": {"Value": "{Substitution}", "Type": "String"}, + } + }, + "Outputs": {"ParameterName": {"Value": {"Ref": "Parameter"}}}, + } + # Create + stack_name = f"stack-{short_uid()}" + change_set_name = f"cs-{short_uid()}" + change_set_details = aws_client_no_retry.cloudformation.create_change_set( + StackName=stack_name, + ChangeSetName=change_set_name, + TemplateBody=json.dumps(template_1), + ChangeSetType="CREATE", + Parameters=list(), + ) + stack_id = change_set_details["StackId"] + change_set_id = change_set_details["Id"] + aws_client_no_retry.cloudformation.get_waiter("change_set_create_complete").wait( + ChangeSetName=change_set_id + ) + cleanups.append( + lambda: call_safe( + aws_client_no_retry.cloudformation.delete_change_set, + kwargs=dict(ChangeSetName=change_set_id), + ) + ) + # Describe + describe_change_set_with_prop_values = ( + aws_client_no_retry.cloudformation.describe_change_set( + ChangeSetName=change_set_id, IncludePropertyValues=True + ) + ) + _normalise_describe_change_set_output(describe_change_set_with_prop_values) + snapshot.match("describe-change-set-1-prop-values", describe_change_set_with_prop_values) + # Execute. + execute_results = aws_client_no_retry.cloudformation.execute_change_set( + ChangeSetName=change_set_id + ) + snapshot.match("execute-change-set-1", execute_results) + aws_client_no_retry.cloudformation.get_waiter("stack_create_complete").wait( + StackName=stack_id + ) + # ensure stack deletion + cleanups.append( + lambda: call_safe( + aws_client_no_retry.cloudformation.delete_stack, kwargs=dict(StackName=stack_id) + ) + ) + describe = aws_client_no_retry.cloudformation.describe_stacks(StackName=stack_id)["Stacks"][ + 0 + ] + snapshot.match("post-create-1-describe", describe) + + # Delete the macro used in the v1 template. + macro_stack_first.destroy() + + # Create the macro to be used in the second version of the template. + macro_name_second = f"SubstitutionMacroSecond-{short_uid()}" + snapshot.add_transformer(RegexTransformer(macro_name_second, "macro-name-second")) + func_name = f"test_lambda_{short_uid()}" + create_lambda_function( + func_name=func_name, + handler_file=macro_function_path, + runtime=Runtime.python3_12, + client=aws_client.lambda_, + timeout=1, + ) + macro_stack_second = deploy_cfn_template( + template_path=os.path.join( + os.path.dirname(__file__), "../../../templates/macro_resource.yml" + ), + parameters={"FunctionName": func_name, "MacroName": macro_name_second}, + ) + + # Update + template_2 = { + "Transform": macro_name_second, + "Parameters": {"Substitution": {"Type": "String", "Default": "SubstitutionDefault"}}, + "Resources": { + "Parameter": { + "Type": "AWS::SSM::Parameter", + "Properties": {"Value": "{Substitution}", "Type": "String"}, + }, + "Parameter2": { + "Type": "AWS::SSM::Parameter", + "Properties": {"Value": "{Substitution}", "Type": "String"}, + }, + }, + "Outputs": { + "Parameter2Name": {"Value": {"Ref": "Parameter2"}}, + }, + } + change_set_details = aws_client_no_retry.cloudformation.create_change_set( + StackName=stack_name, + ChangeSetName=change_set_name, + TemplateBody=json.dumps(template_2), + ChangeSetType="UPDATE", + Parameters=list(), + ) + stack_id = change_set_details["StackId"] + change_set_id = change_set_details["Id"] + aws_client_no_retry.cloudformation.get_waiter("change_set_create_complete").wait( + ChangeSetName=change_set_id + ) + # Describe + describe_change_set_with_prop_values = ( + aws_client_no_retry.cloudformation.describe_change_set( + ChangeSetName=change_set_id, IncludePropertyValues=True + ) + ) + _normalise_describe_change_set_output(describe_change_set_with_prop_values) + snapshot.match("describe-change-set-2-prop-values", describe_change_set_with_prop_values) + # Execute + execute_results = aws_client_no_retry.cloudformation.execute_change_set( + ChangeSetName=change_set_id + ) + snapshot.match("execute-change-set-2", execute_results) + aws_client_no_retry.cloudformation.get_waiter("stack_update_complete").wait( + StackName=stack_id + ) + + # delete stacks + macro_stack_second.destroy() + aws_client_no_retry.cloudformation.delete_stack(StackName=stack_id) + aws_client_no_retry.cloudformation.get_waiter("stack_delete_complete").wait( + StackName=stack_id + ) diff --git a/tests/aws/services/cloudformation/v2/test_change_set_global_macros.snapshot.json b/tests/aws/services/cloudformation/v2/test_change_set_global_macros.snapshot.json index a89dd887a9621..686fa970b25f9 100644 --- a/tests/aws/services/cloudformation/v2/test_change_set_global_macros.snapshot.json +++ b/tests/aws/services/cloudformation/v2/test_change_set_global_macros.snapshot.json @@ -1,6 +1,6 @@ { "tests/aws/services/cloudformation/v2/test_change_set_global_macros.py::TestChangeSetGlobalMacros::test_base_global_macro": { - "recorded-date": "16-06-2025, 09:52:28", + "recorded-date": "24-06-2025, 15:16:22", "recorded-content": { "create-change-set-1": { "Id": "arn::cloudformation::111111111111:changeSet/", @@ -221,10 +221,6 @@ "LastUpdatedTime": "datetime", "NotificationARNs": [], "Outputs": [ - { - "OutputKey": "ParameterName", - "OutputValue": "" - }, { "OutputKey": "Parameter2Name", "OutputValue": "" @@ -242,180 +238,170 @@ "StackStatus": "UPDATE_COMPLETE", "Tags": [] }, + "delete-describe": { + "CreationTime": "datetime", + "DeletionTime": "datetime", + "DisableRollback": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + }, + "LastUpdatedTime": "datetime", + "NotificationARNs": [], + "Outputs": [ + { + "OutputKey": "Parameter2Name", + "OutputValue": "" + } + ], + "Parameters": [ + { + "ParameterKey": "Substitution", + "ParameterValue": "SubstitutionDefault" + } + ], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "StackStatus": "DELETE_COMPLETE", + "Tags": [] + }, "per-resource-events": { "Parameter": [ { - "EventId": "Parameter-CREATE_COMPLETE-date", "LogicalResourceId": "Parameter", - "PhysicalResourceId": "", - "ResourceProperties": { - "Type": "String", - "Value": "SubstitutionDefault" - }, - "ResourceStatus": "CREATE_COMPLETE", - "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Parameter-CREATE_IN_PROGRESS-date", - "LogicalResourceId": "Parameter", - "PhysicalResourceId": "", - "ResourceProperties": { - "Type": "String", - "Value": "SubstitutionDefault" - }, + "PhysicalResourceId": "", "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Parameter-CREATE_IN_PROGRESS-date", "LogicalResourceId": "Parameter", - "PhysicalResourceId": "", - "ResourceProperties": { - "Type": "String", - "Value": "SubstitutionDefault" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", + "PhysicalResourceId": "", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } ], "Parameter2": [ { - "EventId": "Parameter2-CREATE_COMPLETE-date", - "LogicalResourceId": "Parameter2", - "PhysicalResourceId": "", - "ResourceProperties": { - "Type": "String", - "Value": "SubstitutionDefault" - }, - "ResourceStatus": "CREATE_COMPLETE", - "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "Parameter2-CREATE_IN_PROGRESS-date", "LogicalResourceId": "Parameter2", - "PhysicalResourceId": "", - "ResourceProperties": { - "Type": "String", - "Value": "SubstitutionDefault" - }, + "PhysicalResourceId": "", "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "Resource creation Initiated", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "Parameter2-CREATE_IN_PROGRESS-date", "LogicalResourceId": "Parameter2", - "PhysicalResourceId": "", - "ResourceProperties": { - "Type": "String", - "Value": "SubstitutionDefault" - }, - "ResourceStatus": "CREATE_IN_PROGRESS", + "PhysicalResourceId": "", + "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::SSM::Parameter", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } ], - "": [ + "Stack": [ { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE", - "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", - "Timestamp": "timestamp" - }, - { - "EventId": "", - "LogicalResourceId": "", - "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", + "ResourceStatus": "REVIEW_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "UPDATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "CREATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", "ResourceStatus": "CREATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "CREATE_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_IN_PROGRESS", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" }, { - "EventId": "", "LogicalResourceId": "", "PhysicalResourceId": "arn::cloudformation::111111111111:stack//", - "ResourceStatus": "REVIEW_IN_PROGRESS", - "ResourceStatusReason": "User Initiated", + "ResourceStatus": "UPDATE_COMPLETE", "ResourceType": "AWS::CloudFormation::Stack", - "StackId": "arn::cloudformation::111111111111:stack//", - "StackName": "", "Timestamp": "timestamp" } ] + } + } + }, + "tests/aws/services/cloudformation/v2/test_change_set_global_macros.py::TestChangeSetGlobalMacros::test_update_after_macro_for_before_version_is_deleted": { + "recorded-date": "26-06-2025, 11:59:06", + "recorded-content": { + "describe-change-set-1-prop-values": { + "Capabilities": [], + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "ChangeSetName": "", + "Changes": [ + { + "ResourceChange": { + "Action": "Add", + "AfterContext": { + "Properties": { + "Value": "SubstitutionDefault", + "Type": "String" + } + }, + "Details": [], + "LogicalResourceId": "Parameter", + "ResourceType": "AWS::SSM::Parameter", + "Scope": [] + }, + "Type": "Resource" + } + ], + "CreationTime": "datetime", + "ExecutionStatus": "AVAILABLE", + "IncludeNestedStacks": false, + "NotificationARNs": [], + "Parameters": [ + { + "ParameterKey": "Substitution", + "ParameterValue": "SubstitutionDefault" + } + ], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Status": "CREATE_COMPLETE", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } }, - "delete-describe": { + "execute-change-set-1": { + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "post-create-1-describe": { + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", "CreationTime": "datetime", - "DeletionTime": "datetime", "DisableRollback": false, "DriftInformation": { "StackDriftStatus": "NOT_CHECKED" }, + "EnableTerminationProtection": false, "LastUpdatedTime": "datetime", "NotificationARNs": [], "Outputs": [ { "OutputKey": "ParameterName", "OutputValue": "" - }, - { - "OutputKey": "Parameter2Name", - "OutputValue": "" } ], "Parameters": [ @@ -427,8 +413,55 @@ "RollbackConfiguration": {}, "StackId": "arn::cloudformation::111111111111:stack//", "StackName": "", - "StackStatus": "DELETE_COMPLETE", + "StackStatus": "CREATE_COMPLETE", "Tags": [] + }, + "describe-change-set-2-prop-values": { + "Capabilities": [], + "ChangeSetId": "arn::cloudformation::111111111111:changeSet/", + "ChangeSetName": "", + "Changes": [ + { + "ResourceChange": { + "Action": "Add", + "AfterContext": { + "Properties": { + "Value": "SubstitutionDefault", + "Type": "String" + } + }, + "Details": [], + "LogicalResourceId": "Parameter2", + "ResourceType": "AWS::SSM::Parameter", + "Scope": [] + }, + "Type": "Resource" + } + ], + "CreationTime": "datetime", + "ExecutionStatus": "AVAILABLE", + "IncludeNestedStacks": false, + "NotificationARNs": [], + "Parameters": [ + { + "ParameterKey": "Substitution", + "ParameterValue": "SubstitutionDefault" + } + ], + "RollbackConfiguration": {}, + "StackId": "arn::cloudformation::111111111111:stack//", + "StackName": "", + "Status": "CREATE_COMPLETE", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "execute-change-set-2": { + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } } } } diff --git a/tests/aws/services/cloudformation/v2/test_change_set_global_macros.validation.json b/tests/aws/services/cloudformation/v2/test_change_set_global_macros.validation.json index 4580e6cbeb1cb..d88f126525af3 100644 --- a/tests/aws/services/cloudformation/v2/test_change_set_global_macros.validation.json +++ b/tests/aws/services/cloudformation/v2/test_change_set_global_macros.validation.json @@ -1,11 +1,20 @@ { "tests/aws/services/cloudformation/v2/test_change_set_global_macros.py::TestChangeSetGlobalMacros::test_base_global_macro": { - "last_validated_date": "2025-06-16T09:52:29+00:00", + "last_validated_date": "2025-06-24T15:16:22+00:00", "durations_in_seconds": { - "setup": 12.19, - "call": 37.41, - "teardown": 5.9, - "total": 55.5 + "setup": 11.62, + "call": 34.97, + "teardown": 5.44, + "total": 52.03 + } + }, + "tests/aws/services/cloudformation/v2/test_change_set_global_macros.py::TestChangeSetGlobalMacros::test_update_after_macro_for_before_version_is_deleted": { + "last_validated_date": "2025-06-26T11:59:07+00:00", + "durations_in_seconds": { + "setup": 11.46, + "call": 52.25, + "teardown": 1.78, + "total": 65.49 } } } From 05a922a4ffd2de1088fa9dd4f2b40c6b81e7434b Mon Sep 17 00:00:00 2001 From: Ben Simon Hartung <42031100+bentsku@users.noreply.github.com> Date: Fri, 27 Jun 2025 22:53:43 +0200 Subject: [PATCH 64/74] SQS: add automatic propagation of AWSTraceHeader attribute when sending message (#12810) --- .../localstack/services/sqs/provider.py | 7 ++++ tests/aws/services/sqs/test_sqs.py | 39 +++++++++++++++++++ tests/aws/services/sqs/test_sqs.snapshot.json | 38 ++++++++++++++++++ .../aws/services/sqs/test_sqs.validation.json | 18 +++++++++ 4 files changed, 102 insertions(+) diff --git a/localstack-core/localstack/services/sqs/provider.py b/localstack-core/localstack/services/sqs/provider.py index 6afd18f0d8fe5..0dfcc41a047d2 100644 --- a/localstack-core/localstack/services/sqs/provider.py +++ b/localstack-core/localstack/services/sqs/provider.py @@ -1679,6 +1679,13 @@ def _create_message_attributes( MessageSystemAttributeName.SenderId: context.account_id, # not the account ID in AWS MessageSystemAttributeName.SentTimestamp: str(now(millis=True)), } + # we are not using the `context.trace_context` here as it is automatically populated + # AWS only adds the `AWSTraceHeader` attribute if the header is explicitly present + # TODO: check maybe with X-Ray Active mode? + if "X-Amzn-Trace-Id" in context.request.headers: + result[MessageSystemAttributeName.AWSTraceHeader] = str( + context.request.headers["X-Amzn-Trace-Id"] + ) if message_system_attributes is not None: for attr in message_system_attributes: diff --git a/tests/aws/services/sqs/test_sqs.py b/tests/aws/services/sqs/test_sqs.py index af49bd993504a..db4cf4180f6f3 100644 --- a/tests/aws/services/sqs/test_sqs.py +++ b/tests/aws/services/sqs/test_sqs.py @@ -3530,6 +3530,45 @@ def test_system_attributes_have_no_effect_on_attr_md5(self, sqs_create_queue, aw == "5ae4d5d7636402d80f4eb6d213245a88" ) + @markers.aws.validated + def test_aws_trace_header_propagation(self, sqs_create_queue, aws_sqs_client, snapshot): + def add_xray_header(request, **_kwargs): + request.headers["X-Amzn-Trace-Id"] = ( + "Root=1-3152b799-8954dae64eda91bc9a23a7e8;Parent=7fa8c0f79203be72;Sampled=1" + ) + + try: + aws_sqs_client.meta.events.register("before-send.sqs.SendMessage", add_xray_header) + + queue_url = sqs_create_queue() + + msg_attrs_provider = { + "timestamp": {"StringValue": "1493147359900", "DataType": "Number"} + } + + aws_sqs_client.send_message( + QueueUrl=queue_url, MessageBody="test", MessageAttributes=msg_attrs_provider + ) + + response = aws_sqs_client.receive_message( + QueueUrl=queue_url, + AttributeNames=["SentTimestamp", "AWSTraceHeader"], + MaxNumberOfMessages=1, + MessageAttributeNames=["All"], + VisibilityTimeout=2, + WaitTimeSeconds=2, + ) + + assert len(response["Messages"]) == 1 + message = response["Messages"][0] + snapshot.match("xray-msg", message) + assert ( + message["Attributes"]["AWSTraceHeader"] + == "Root=1-3152b799-8954dae64eda91bc9a23a7e8;Parent=7fa8c0f79203be72;Sampled=1" + ) + finally: + aws_sqs_client.meta.events.unregister("before-send.sqs.SendMessage", add_xray_header) + @markers.aws.validated def test_inflight_message_requeue(self, sqs_create_queue, aws_client): visibility_timeout = 3 diff --git a/tests/aws/services/sqs/test_sqs.snapshot.json b/tests/aws/services/sqs/test_sqs.snapshot.json index 3f98e7ec95cd8..744d4972c8d56 100644 --- a/tests/aws/services/sqs/test_sqs.snapshot.json +++ b/tests/aws/services/sqs/test_sqs.snapshot.json @@ -3974,5 +3974,43 @@ } } } + }, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_aws_trace_header_propagation[sqs]": { + "recorded-date": "27-06-2025, 10:55:55", + "recorded-content": { + "xray-msg": { + "Attributes": { + "AWSTraceHeader": "Root=1-3152b799-8954dae64eda91bc9a23a7e8;Parent=7fa8c0f79203be72;Sampled=1", + "SentTimestamp": "timestamp" + }, + "Body": "test", + "MD5OfBody": "098f6bcd4621d373cade4e832627b4f6", + "MD5OfMessageAttributes": "235c5c510d26fb653d073faed50ae77c", + "MessageAttributes": { + "timestamp": "timestamp" + }, + "MessageId": "", + "ReceiptHandle": "" + } + } + }, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_aws_trace_header_propagation[sqs_query]": { + "recorded-date": "27-06-2025, 10:55:56", + "recorded-content": { + "xray-msg": { + "Attributes": { + "AWSTraceHeader": "Root=1-3152b799-8954dae64eda91bc9a23a7e8;Parent=7fa8c0f79203be72;Sampled=1", + "SentTimestamp": "timestamp" + }, + "Body": "test", + "MD5OfBody": "098f6bcd4621d373cade4e832627b4f6", + "MD5OfMessageAttributes": "235c5c510d26fb653d073faed50ae77c", + "MessageAttributes": { + "timestamp": "timestamp" + }, + "MessageId": "", + "ReceiptHandle": "" + } + } } } diff --git a/tests/aws/services/sqs/test_sqs.validation.json b/tests/aws/services/sqs/test_sqs.validation.json index f8dba2d87c978..c74eae7b6ad37 100644 --- a/tests/aws/services/sqs/test_sqs.validation.json +++ b/tests/aws/services/sqs/test_sqs.validation.json @@ -1,4 +1,22 @@ { + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_aws_trace_header_propagation[sqs]": { + "last_validated_date": "2025-06-27T10:55:55+00:00", + "durations_in_seconds": { + "setup": 0.47, + "call": 0.71, + "teardown": 0.15, + "total": 1.33 + } + }, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_aws_trace_header_propagation[sqs_query]": { + "last_validated_date": "2025-06-27T10:55:56+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 0.68, + "teardown": 0.15, + "total": 0.83 + } + }, "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_change_message_visibility_after_visibility_timeout_expiration[sqs]": { "last_validated_date": "2024-04-30T13:33:26+00:00" }, From 24d0f8f20979b59f326c5884479817b0e3e2faef Mon Sep 17 00:00:00 2001 From: LocalStack Bot <88328844+localstack-bot@users.noreply.github.com> Date: Mon, 30 Jun 2025 08:41:12 +0200 Subject: [PATCH 65/74] [Testing] Update test durations (#12815) Co-authored-by: LocalStack Bot --- .test_durations | 10031 ++++++++++++++++++++++++---------------------- 1 file changed, 5234 insertions(+), 4797 deletions(-) diff --git a/.test_durations b/.test_durations index 08c2d52ba5f8b..5148a5e6696aa 100644 --- a/.test_durations +++ b/.test_durations @@ -1,4799 +1,5236 @@ { - "tests/aws/scenario/bookstore/test_bookstore.py::TestBookstoreApplication::test_lambda_dynamodb": 1.8306775939999795, - "tests/aws/scenario/bookstore/test_bookstore.py::TestBookstoreApplication::test_opensearch_crud": 3.4609082799999555, - "tests/aws/scenario/bookstore/test_bookstore.py::TestBookstoreApplication::test_search_books": 60.73045058200003, - "tests/aws/scenario/bookstore/test_bookstore.py::TestBookstoreApplication::test_setup": 93.035824546, - "tests/aws/scenario/kinesis_firehose/test_kinesis_firehose.py::TestKinesisFirehoseScenario::test_kinesis_firehose_s3": 0.012874760000045171, - "tests/aws/scenario/lambda_destination/test_lambda_destination_scenario.py::TestLambdaDestinationScenario::test_destination_sns": 5.604998042999966, - "tests/aws/scenario/lambda_destination/test_lambda_destination_scenario.py::TestLambdaDestinationScenario::test_infra": 13.293676268000013, - "tests/aws/scenario/loan_broker/test_loan_broker.py::TestLoanBrokerScenario::test_prefill_dynamodb_table": 30.708885502999976, - "tests/aws/scenario/loan_broker/test_loan_broker.py::TestLoanBrokerScenario::test_stepfunctions_input_recipient_list[step_function_input0-SUCCEEDED]": 3.9920143719999714, - "tests/aws/scenario/loan_broker/test_loan_broker.py::TestLoanBrokerScenario::test_stepfunctions_input_recipient_list[step_function_input1-SUCCEEDED]": 2.8442309750000163, - "tests/aws/scenario/loan_broker/test_loan_broker.py::TestLoanBrokerScenario::test_stepfunctions_input_recipient_list[step_function_input2-FAILED]": 0.9125211790000094, - "tests/aws/scenario/loan_broker/test_loan_broker.py::TestLoanBrokerScenario::test_stepfunctions_input_recipient_list[step_function_input3-FAILED]": 0.6815302869999869, - "tests/aws/scenario/loan_broker/test_loan_broker.py::TestLoanBrokerScenario::test_stepfunctions_input_recipient_list[step_function_input4-FAILED]": 0.5234817729999577, - "tests/aws/scenario/mythical_mysfits/test_mythical_misfits.py::TestMythicalMisfitsScenario::test_deployed_infra_state": 0.0026562400000216257, - "tests/aws/scenario/mythical_mysfits/test_mythical_misfits.py::TestMythicalMisfitsScenario::test_populate_data": 0.001706896999962737, - "tests/aws/scenario/mythical_mysfits/test_mythical_misfits.py::TestMythicalMisfitsScenario::test_user_clicks_are_stored": 0.001825970000027155, - "tests/aws/scenario/note_taking/test_note_taking.py::TestNoteTakingScenario::test_notes_rest_api": 4.533551982999995, - "tests/aws/scenario/note_taking/test_note_taking.py::TestNoteTakingScenario::test_validate_infra_setup": 34.25136890600004, - "tests/aws/services/acm/test_acm.py::TestACM::test_boto_wait_for_certificate_validation": 1.2082726290000778, - "tests/aws/services/acm/test_acm.py::TestACM::test_certificate_for_subdomain_wildcard": 2.2963858519999576, - "tests/aws/services/acm/test_acm.py::TestACM::test_create_certificate_for_multiple_alternative_domains": 11.193298594999987, - "tests/aws/services/acm/test_acm.py::TestACM::test_domain_validation": 0.24601558099999465, - "tests/aws/services/acm/test_acm.py::TestACM::test_import_certificate": 1.0255106409999826, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiAuthorizer::test_authorizer_crud_no_api": 0.03166019600001846, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiDocumentationPart::test_doc_parts_crud_no_api": 0.032727379999982986, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiDocumentationPart::test_documentation_part_lifecycle": 0.0691414789999385, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiDocumentationPart::test_import_documentation_parts": 0.1256413830000156, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiDocumentationPart::test_invalid_create_documentation_part_operations": 0.03903247199997395, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiDocumentationPart::test_invalid_delete_documentation_part": 0.05247172699995417, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiDocumentationPart::test_invalid_get_documentation_part": 0.04592164300004242, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiDocumentationPart::test_invalid_get_documentation_parts": 0.01543583700004092, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiDocumentationPart::test_invalid_update_documentation_part": 0.05624032400004353, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiMethod::test_method_lifecycle": 0.07278596300000117, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiMethod::test_method_request_parameters": 0.048786912000025495, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiMethod::test_put_method_model": 0.27825750099992774, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiMethod::test_put_method_validation": 0.06997209599995813, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiMethod::test_update_method": 0.07143810400003758, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiMethod::test_update_method_validation": 0.13446594900000264, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiModels::test_model_lifecycle": 0.06994636100000662, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiModels::test_model_validation": 0.0998845069999561, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiModels::test_update_model": 0.06950375700006362, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRequestValidator::test_create_request_validator_invalid_api_id": 0.01457731400000739, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRequestValidator::test_invalid_delete_request_validator": 0.04277879500000381, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRequestValidator::test_invalid_get_request_validator": 0.04435944799996605, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRequestValidator::test_invalid_get_request_validators": 0.013965928000061467, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRequestValidator::test_invalid_update_request_validator_operations": 0.06056790800005274, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRequestValidator::test_request_validator_lifecycle": 0.09003225700007533, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRequestValidator::test_validators_crud_no_api": 0.03163985399999092, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiResource::test_create_proxy_resource": 0.11610522900002707, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiResource::test_create_proxy_resource_validation": 0.07638203299995894, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiResource::test_create_resource_parent_invalid": 0.03004573599997684, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiResource::test_delete_resource": 0.06689559799991684, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiResource::test_resource_lifecycle": 0.10818160799999532, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiResource::test_update_resource_behaviour": 0.14371496300003628, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRestApi::test_create_rest_api_with_binary_media_types": 0.024210735999986355, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRestApi::test_create_rest_api_with_optional_params": 0.07354736299998876, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRestApi::test_create_rest_api_with_tags": 0.04265929800004642, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRestApi::test_get_api_case_insensitive": 0.001909983999951237, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRestApi::test_list_and_delete_apis": 0.08450191100001803, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRestApi::test_update_rest_api_behaviour": 0.05373609100001886, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRestApi::test_update_rest_api_compression": 0.09015043199997308, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRestApi::test_update_rest_api_invalid_api_id": 0.014741459999981998, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRestApi::test_update_rest_api_operation_add_remove": 0.05077170300000944, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayGatewayResponse::test_gateway_response_crud": 0.09927309100004322, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayGatewayResponse::test_gateway_response_put": 0.09819665999998506, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayGatewayResponse::test_gateway_response_validation": 0.10285701900005506, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayGatewayResponse::test_update_gateway_response": 0.1202379620000329, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_put_integration_request_parameter_bool_type": 0.001880082000013772, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_put_integration_response_validation": 0.07398715900001207, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_put_integration_wrong_type": 0.040084112999977606, - "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayTestInvoke::test_invoke_test_method": 0.18814763500000709, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_api_account": 0.04275905000008606, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_api_gateway_authorizer_crud": 0.0019337829999699352, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_api_gateway_handle_domain_name": 0.24127724000010176, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_api_gateway_http_integration_with_path_request_parameter": 0.002243820000046526, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_api_gateway_lambda_asynchronous_invocation": 1.3724172019999514, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_api_gateway_lambda_integration_aws_type": 7.87926492400004, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_api_gateway_lambda_proxy_integration[/lambda/foo1]": 0.0017643870000370043, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_api_gateway_lambda_proxy_integration[/lambda/{test_param1}]": 0.0017631050000090909, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_api_gateway_lambda_proxy_integration_any_method": 0.0018373920000271937, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_api_gateway_lambda_proxy_integration_any_method_with_path_param": 0.0018090690000462928, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_api_gateway_lambda_proxy_integration_with_is_base_64_encoded": 0.0018574299999727373, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_api_gateway_mock_integration": 0.06236799600003451, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_api_mock_integration_response_params": 0.00182911500002092, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_apigateway_with_custom_authorization_method": 15.373010333000025, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_apigw_stage_variables[dev]": 1.6355085530000224, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_apigw_stage_variables[local]": 1.60974901000003, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_apigw_test_invoke_method_api": 2.2329229609999857, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_base_path_mapping": 0.17674683599994978, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_base_path_mapping_root": 0.1587198959999796, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_create_rest_api_with_custom_id[host_based_url]": 0.06318539300002612, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_create_rest_api_with_custom_id[localstack_path_based_url]": 0.06370467900006815, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_create_rest_api_with_custom_id[path_based_url]": 0.06739443399999345, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_delete_rest_api_with_invalid_id": 0.012518495999984225, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_invoke_endpoint_cors_headers[http://allowed-False-UrlType.HOST_BASED]": 0.07240681199999699, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_invoke_endpoint_cors_headers[http://allowed-False-UrlType.LS_PATH_BASED]": 0.07386598499994079, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_invoke_endpoint_cors_headers[http://allowed-False-UrlType.PATH_BASED]": 0.07220304300005864, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_invoke_endpoint_cors_headers[http://allowed-True-UrlType.HOST_BASED]": 0.0934850259999962, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_invoke_endpoint_cors_headers[http://allowed-True-UrlType.LS_PATH_BASED]": 0.07008028300003843, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_invoke_endpoint_cors_headers[http://allowed-True-UrlType.PATH_BASED]": 0.06892254500002082, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_invoke_endpoint_cors_headers[http://denied-False-UrlType.HOST_BASED]": 0.07596852300002865, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_invoke_endpoint_cors_headers[http://denied-False-UrlType.LS_PATH_BASED]": 0.07553099599999769, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_invoke_endpoint_cors_headers[http://denied-False-UrlType.PATH_BASED]": 0.0795212809999839, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_invoke_endpoint_cors_headers[http://denied-True-UrlType.HOST_BASED]": 0.070245946, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_invoke_endpoint_cors_headers[http://denied-True-UrlType.LS_PATH_BASED]": 0.07018232599995144, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_invoke_endpoint_cors_headers[http://denied-True-UrlType.PATH_BASED]": 0.06969378799999504, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_multiple_api_keys_validate": 27.627488958000015, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_put_integration_dynamodb_proxy_validation_with_request_template": 0.0017333970000095178, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_put_integration_dynamodb_proxy_validation_without_request_template": 0.0017808249999688996, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_response_headers_invocation_with_apigw": 1.7913326810000285, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_update_rest_api_deployment": 0.07151520300004677, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_api_gateway_http_integrations[custom]": 0.0017788210000162508, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_api_gateway_http_integrations[proxy]": 0.0018017259999965063, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_mock_integration_response[NEVER-UrlType.HOST_BASED-GET]": 0.09223141100000021, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_mock_integration_response[NEVER-UrlType.HOST_BASED-POST]": 0.09137564200005954, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_mock_integration_response[NEVER-UrlType.PATH_BASED-GET]": 0.09194332000004124, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_mock_integration_response[NEVER-UrlType.PATH_BASED-POST]": 0.09345741000004182, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_mock_integration_response[WHEN_NO_MATCH-UrlType.HOST_BASED-GET]": 0.09004916399999274, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_mock_integration_response[WHEN_NO_MATCH-UrlType.HOST_BASED-POST]": 0.09237544999996317, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_mock_integration_response[WHEN_NO_MATCH-UrlType.PATH_BASED-GET]": 0.0936843439999393, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_mock_integration_response[WHEN_NO_MATCH-UrlType.PATH_BASED-POST]": 0.09075120699992567, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_mock_integration_response[WHEN_NO_TEMPLATES-UrlType.HOST_BASED-GET]": 0.09080804499990336, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_mock_integration_response[WHEN_NO_TEMPLATES-UrlType.HOST_BASED-POST]": 0.0925549039999396, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_mock_integration_response[WHEN_NO_TEMPLATES-UrlType.PATH_BASED-GET]": 0.0920941589999984, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_mock_integration_response[WHEN_NO_TEMPLATES-UrlType.PATH_BASED-POST]": 0.09429839000000584, - "tests/aws/services/apigateway/test_apigateway_basic.py::TestTagging::test_tag_api": 0.06903556700001445, - "tests/aws/services/apigateway/test_apigateway_basic.py::test_apigw_call_api_with_aws_endpoint_url": 0.013104117999944265, - "tests/aws/services/apigateway/test_apigateway_basic.py::test_rest_api_multi_region[UrlType.HOST_BASED-ANY]": 3.409972497999945, - "tests/aws/services/apigateway/test_apigateway_basic.py::test_rest_api_multi_region[UrlType.HOST_BASED-GET]": 3.4051879659999713, - "tests/aws/services/apigateway/test_apigateway_basic.py::test_rest_api_multi_region[path_based_url-ANY]": 3.460962833999986, - "tests/aws/services/apigateway/test_apigateway_basic.py::test_rest_api_multi_region[path_based_url-GET]": 9.564439794000009, - "tests/aws/services/apigateway/test_apigateway_common.py::TestApiGatewayCommon::test_api_gateway_request_validator": 2.4409245159999955, - "tests/aws/services/apigateway/test_apigateway_common.py::TestApiGatewayCommon::test_api_gateway_request_validator_with_ref_models": 0.16870720400004302, - "tests/aws/services/apigateway/test_apigateway_common.py::TestApiGatewayCommon::test_api_gateway_request_validator_with_ref_one_ofmodels": 0.17983501700001625, - "tests/aws/services/apigateway/test_apigateway_common.py::TestApiGatewayCommon::test_input_body_formatting": 3.420733691999942, - "tests/aws/services/apigateway/test_apigateway_common.py::TestApiGatewayCommon::test_input_path_template_formatting": 0.45992290800006685, - "tests/aws/services/apigateway/test_apigateway_common.py::TestApiGatewayCommon::test_integration_request_parameters_mapping": 0.10416832400011344, - "tests/aws/services/apigateway/test_apigateway_common.py::TestApiGatewayCommon::test_invocation_trace_id": 3.0983578250000505, - "tests/aws/services/apigateway/test_apigateway_common.py::TestApigatewayRouting::test_api_not_existing": 0.023232739999969, - "tests/aws/services/apigateway/test_apigateway_common.py::TestApigatewayRouting::test_proxy_routing_with_hardcoded_resource_sibling": 0.24598954499992942, - "tests/aws/services/apigateway/test_apigateway_common.py::TestApigatewayRouting::test_routing_not_found": 0.11063040700003057, - "tests/aws/services/apigateway/test_apigateway_common.py::TestApigatewayRouting::test_routing_with_custom_api_id": 0.0979436220000025, - "tests/aws/services/apigateway/test_apigateway_common.py::TestApigatewayRouting::test_routing_with_hardcoded_resource_sibling_order": 0.2238018699999884, - "tests/aws/services/apigateway/test_apigateway_common.py::TestDeployments::test_create_delete_deployments[False]": 0.4042067909999787, - "tests/aws/services/apigateway/test_apigateway_common.py::TestDeployments::test_create_delete_deployments[True]": 0.43591541299997516, - "tests/aws/services/apigateway/test_apigateway_common.py::TestDeployments::test_create_update_deployments": 0.33989664600005653, - "tests/aws/services/apigateway/test_apigateway_common.py::TestDocumentations::test_documentation_parts_and_versions": 0.10777894000005972, - "tests/aws/services/apigateway/test_apigateway_common.py::TestStages::test_create_update_stages": 0.33117468599994027, - "tests/aws/services/apigateway/test_apigateway_common.py::TestStages::test_update_stage_remove_wildcard": 0.31000804499996093, - "tests/aws/services/apigateway/test_apigateway_common.py::TestUsagePlans::test_api_key_required_for_methods": 0.19657758199997488, - "tests/aws/services/apigateway/test_apigateway_common.py::TestUsagePlans::test_usage_plan_crud": 0.18532574699997895, - "tests/aws/services/apigateway/test_apigateway_custom_ids.py::test_apigateway_custom_ids": 0.06122678899998846, - "tests/aws/services/apigateway/test_apigateway_dynamodb.py::test_error_aws_proxy_not_supported": 0.19541213900004095, - "tests/aws/services/apigateway/test_apigateway_dynamodb.py::test_rest_api_to_dynamodb_integration[PutItem]": 0.4285630210000022, - "tests/aws/services/apigateway/test_apigateway_dynamodb.py::test_rest_api_to_dynamodb_integration[Query]": 0.4974042979999922, - "tests/aws/services/apigateway/test_apigateway_dynamodb.py::test_rest_api_to_dynamodb_integration[Scan]": 0.4045932010000115, - "tests/aws/services/apigateway/test_apigateway_eventbridge.py::test_apigateway_to_eventbridge": 0.2640418709999608, - "tests/aws/services/apigateway/test_apigateway_extended.py::TestApigatewayApiKeysCrud::test_get_api_keys": 0.16527851800003646, - "tests/aws/services/apigateway/test_apigateway_extended.py::TestApigatewayApiKeysCrud::test_get_usage_plan_api_keys": 14.565750925999907, - "tests/aws/services/apigateway/test_apigateway_extended.py::test_create_domain_names": 0.07502431400001797, - "tests/aws/services/apigateway/test_apigateway_extended.py::test_export_oas30_openapi[TEST_IMPORT_PETSTORE_SWAGGER]": 0.40482689199996, - "tests/aws/services/apigateway/test_apigateway_extended.py::test_export_oas30_openapi[TEST_IMPORT_PETS]": 0.3155974850000689, - "tests/aws/services/apigateway/test_apigateway_extended.py::test_export_swagger_openapi[TEST_IMPORT_PETSTORE_SWAGGER]": 0.4057825730000104, - "tests/aws/services/apigateway/test_apigateway_extended.py::test_export_swagger_openapi[TEST_IMPORT_PETS]": 0.31219083899992484, - "tests/aws/services/apigateway/test_apigateway_extended.py::test_get_domain_name": 0.0702157470000202, - "tests/aws/services/apigateway/test_apigateway_extended.py::test_get_domain_names": 0.07257708399998819, - "tests/aws/services/apigateway/test_apigateway_http.py::test_http_integration_invoke_status_code_passthrough[HTTP]": 1.7505127640000637, - "tests/aws/services/apigateway/test_apigateway_http.py::test_http_integration_invoke_status_code_passthrough[HTTP_PROXY]": 1.7139310940000314, - "tests/aws/services/apigateway/test_apigateway_http.py::test_http_integration_method[HTTP]": 2.0455031299998154, - "tests/aws/services/apigateway/test_apigateway_http.py::test_http_integration_method[HTTP_PROXY]": 2.0076948039998115, - "tests/aws/services/apigateway/test_apigateway_http.py::test_http_integration_with_lambda[HTTP]": 2.170325814999842, - "tests/aws/services/apigateway/test_apigateway_http.py::test_http_integration_with_lambda[HTTP_PROXY]": 2.1961897050000516, - "tests/aws/services/apigateway/test_apigateway_http.py::test_http_proxy_integration_request_data_mappings": 1.9682702049999534, - "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_and_validate_rest_api[openapi.spec.tf.json]": 0.3610307600000624, - "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_and_validate_rest_api[swagger-mock-cors.json]": 0.43036976299993057, - "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_rest_api": 0.06505610099998194, - "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_rest_api_with_base_path_oas30[ignore]": 0.8735227780000514, - "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_rest_api_with_base_path_oas30[prepend]": 0.8828890079998928, - "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_rest_api_with_base_path_oas30[split]": 0.8768331999999646, - "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_rest_apis_with_base_path_swagger[ignore]": 0.6047385670000267, - "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_rest_apis_with_base_path_swagger[prepend]": 0.5968512279999914, - "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_rest_apis_with_base_path_swagger[split]": 0.6075581729999158, - "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_swagger_api": 0.7781904249999343, - "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_with_circular_models": 0.2820640759998696, - "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_with_circular_models_and_request_validation": 0.38850159200012513, - "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_with_cognito_auth_identity_source": 0.3859413489999497, - "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_with_global_api_key_authorizer": 0.2785899169998629, - "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_with_http_method_integration": 1.1279415980000067, - "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_with_integer_http_status_code": 0.17820217300004515, - "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_with_stage_variables": 1.6937769980000894, - "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_put_rest_api_mode_binary_media_types[merge]": 0.33803668999996717, - "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_put_rest_api_mode_binary_media_types[overwrite]": 0.3404845199999045, - "tests/aws/services/apigateway/test_apigateway_integrations.py::TestApiGatewayHeaderRemapping::test_apigateway_header_remapping_aws[AWS]": 2.445959500000072, - "tests/aws/services/apigateway/test_apigateway_integrations.py::TestApiGatewayHeaderRemapping::test_apigateway_header_remapping_aws[AWS_PROXY]": 2.4442483880000054, - "tests/aws/services/apigateway/test_apigateway_integrations.py::TestApiGatewayHeaderRemapping::test_apigateway_header_remapping_http[HTTP]": 0.8168622240000332, - "tests/aws/services/apigateway/test_apigateway_integrations.py::TestApiGatewayHeaderRemapping::test_apigateway_header_remapping_http[HTTP_PROXY]": 0.8228991810000252, - "tests/aws/services/apigateway/test_apigateway_integrations.py::test_create_execute_api_vpc_endpoint": 5.51742650999995, - "tests/aws/services/apigateway/test_apigateway_integrations.py::test_http_integration_status_code_selection": 0.11978421399999206, - "tests/aws/services/apigateway/test_apigateway_integrations.py::test_integration_mock_with_path_param": 0.0945010299999467, - "tests/aws/services/apigateway/test_apigateway_integrations.py::test_integration_mock_with_request_overrides_in_response_template": 0.11433569400003307, - "tests/aws/services/apigateway/test_apigateway_integrations.py::test_integration_mock_with_response_override_in_request_template[False]": 0.0865096940000285, - "tests/aws/services/apigateway/test_apigateway_integrations.py::test_integration_mock_with_response_override_in_request_template[True]": 0.08682158499993875, - "tests/aws/services/apigateway/test_apigateway_integrations.py::test_put_integration_response_with_response_template": 1.2003933639999786, - "tests/aws/services/apigateway/test_apigateway_integrations.py::test_put_integration_responses": 0.16711714799987476, - "tests/aws/services/apigateway/test_apigateway_integrations.py::test_put_integration_validation": 0.20105003500009389, - "tests/aws/services/apigateway/test_apigateway_kinesis.py::test_apigateway_to_kinesis[PutRecord]": 1.158917444999929, - "tests/aws/services/apigateway/test_apigateway_kinesis.py::test_apigateway_to_kinesis[PutRecords]": 1.1512200410001014, - "tests/aws/services/apigateway/test_apigateway_lambda.py::test_aws_proxy_binary_response": 3.7535720319999655, - "tests/aws/services/apigateway/test_apigateway_lambda.py::test_aws_proxy_response_payload_format_validation": 4.91831154700003, - "tests/aws/services/apigateway/test_apigateway_lambda.py::test_lambda_aws_integration": 1.7392398289999846, - "tests/aws/services/apigateway/test_apigateway_lambda.py::test_lambda_aws_integration_response_with_mapping_templates": 1.9345927329999313, - "tests/aws/services/apigateway/test_apigateway_lambda.py::test_lambda_aws_integration_with_request_template": 1.8528378119999616, - "tests/aws/services/apigateway/test_apigateway_lambda.py::test_lambda_aws_proxy_integration": 4.085220950999997, - "tests/aws/services/apigateway/test_apigateway_lambda.py::test_lambda_aws_proxy_integration_non_post_method": 1.3365963490000468, - "tests/aws/services/apigateway/test_apigateway_lambda.py::test_lambda_aws_proxy_integration_request_data_mapping": 2.878076430999954, - "tests/aws/services/apigateway/test_apigateway_lambda.py::test_lambda_aws_proxy_response_format": 2.0462573719999, - "tests/aws/services/apigateway/test_apigateway_lambda.py::test_lambda_rust_proxy_integration": 1.7800068810000766, - "tests/aws/services/apigateway/test_apigateway_lambda.py::test_lambda_selection_patterns": 2.0459635729999945, - "tests/aws/services/apigateway/test_apigateway_lambda.py::test_put_integration_aws_proxy_uri": 1.3439045939999232, - "tests/aws/services/apigateway/test_apigateway_lambda_cfn.py::TestApigatewayLambdaIntegration::test_scenario_validate_infra": 7.642166891000102, - "tests/aws/services/apigateway/test_apigateway_s3.py::TestApiGatewayS3BinarySupport::test_apigw_s3_binary_support_request[CONVERT_TO_TEXT]": 0.5738120400000071, - "tests/aws/services/apigateway/test_apigateway_s3.py::TestApiGatewayS3BinarySupport::test_apigw_s3_binary_support_request[None]": 0.5696421239999836, - "tests/aws/services/apigateway/test_apigateway_s3.py::TestApiGatewayS3BinarySupport::test_apigw_s3_binary_support_request_convert_to_binary": 0.5192244249999476, - "tests/aws/services/apigateway/test_apigateway_s3.py::TestApiGatewayS3BinarySupport::test_apigw_s3_binary_support_request_convert_to_binary_with_request_template": 0.3489556839998613, - "tests/aws/services/apigateway/test_apigateway_s3.py::TestApiGatewayS3BinarySupport::test_apigw_s3_binary_support_response_convert_to_binary": 0.5803233399999499, - "tests/aws/services/apigateway/test_apigateway_s3.py::TestApiGatewayS3BinarySupport::test_apigw_s3_binary_support_response_convert_to_binary_with_request_template": 0.3874819389999402, - "tests/aws/services/apigateway/test_apigateway_s3.py::TestApiGatewayS3BinarySupport::test_apigw_s3_binary_support_response_convert_to_text": 0.5868586699999696, - "tests/aws/services/apigateway/test_apigateway_s3.py::TestApiGatewayS3BinarySupport::test_apigw_s3_binary_support_response_no_content_handling": 0.601561848000074, - "tests/aws/services/apigateway/test_apigateway_s3.py::test_apigateway_s3_any": 0.4845440180000651, - "tests/aws/services/apigateway/test_apigateway_s3.py::test_apigateway_s3_method_mapping": 0.5188475739998921, - "tests/aws/services/apigateway/test_apigateway_sqs.py::test_sqs_amz_json_protocol": 1.079206910000039, - "tests/aws/services/apigateway/test_apigateway_sqs.py::test_sqs_aws_integration": 1.2227715730000455, - "tests/aws/services/apigateway/test_apigateway_sqs.py::test_sqs_aws_integration_with_message_attribute[MessageAttribute]": 0.31224277800004074, - "tests/aws/services/apigateway/test_apigateway_sqs.py::test_sqs_aws_integration_with_message_attribute[MessageAttributes]": 0.3740195999999969, - "tests/aws/services/apigateway/test_apigateway_sqs.py::test_sqs_request_and_response_xml_templates_integration": 0.40435537899998053, - "tests/aws/services/apigateway/test_apigateway_ssm.py::test_get_parameter_query_protocol": 0.0018512760000248818, - "tests/aws/services/apigateway/test_apigateway_ssm.py::test_ssm_aws_integration": 0.28434512699993775, - "tests/aws/services/apigateway/test_apigateway_stepfunctions.py::TestApigatewayStepfunctions::test_apigateway_with_step_function_integration[DeleteStateMachine]": 1.4979481660000147, - "tests/aws/services/apigateway/test_apigateway_stepfunctions.py::TestApigatewayStepfunctions::test_apigateway_with_step_function_integration[StartExecution]": 1.5652199209999935, - "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceApi::test_api_exceptions": 0.001882635000015398, - "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceApi::test_create_exceptions": 0.0017371530000218627, - "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceApi::test_create_invalid_desiredstate": 0.0021124749999898995, - "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceApi::test_double_create_with_client_token": 0.0017514999999548309, - "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceApi::test_lifecycle": 0.0020145920000231854, - "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceApi::test_list_resources": 0.0018738190000249233, - "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceApi::test_list_resources_with_resource_model": 0.0017670600000201375, - "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceApi::test_update": 0.00176567599999089, - "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceRequestApi::test_cancel_edge_cases[FAIL]": 0.0019104479999896284, - "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceRequestApi::test_cancel_edge_cases[SUCCESS]": 0.00176282099994296, - "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceRequestApi::test_cancel_request": 0.0017456990000255246, - "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceRequestApi::test_get_request_status": 0.0017219849999037251, - "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceRequestApi::test_invalid_request_token_exc": 0.001783229000011488, - "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceRequestApi::test_list_request_status": 0.0017618890000221654, - "tests/aws/services/cloudformation/api/test_changesets.py::TestUpdates::test_deleting_resource": 0.0017535739999630096, - "tests/aws/services/cloudformation/api/test_changesets.py::TestUpdates::test_simple_update_single_resource": 4.196529728000087, - "tests/aws/services/cloudformation/api/test_changesets.py::TestUpdates::test_simple_update_two_resources": 0.0018102889999909166, - "tests/aws/services/cloudformation/api/test_changesets.py::test_autoexpand_capability_requirement": 0.052010827999993126, - "tests/aws/services/cloudformation/api/test_changesets.py::test_create_and_then_remove_non_supported_resource_change_set": 20.378889379000043, - "tests/aws/services/cloudformation/api/test_changesets.py::test_create_and_then_remove_supported_resource_change_set": 21.948498336000057, - "tests/aws/services/cloudformation/api/test_changesets.py::test_create_and_then_update_refreshes_template_metadata": 2.146562182000139, - "tests/aws/services/cloudformation/api/test_changesets.py::test_create_change_set_create_existing": 0.0018562049999673036, - "tests/aws/services/cloudformation/api/test_changesets.py::test_create_change_set_invalid_params": 0.015462386000081096, - "tests/aws/services/cloudformation/api/test_changesets.py::test_create_change_set_missing_stackname": 0.004812114000060319, - "tests/aws/services/cloudformation/api/test_changesets.py::test_create_change_set_update_nonexisting": 0.017314134000002923, - "tests/aws/services/cloudformation/api/test_changesets.py::test_create_change_set_update_without_parameters": 0.0017991189999975177, - "tests/aws/services/cloudformation/api/test_changesets.py::test_create_change_set_with_ssm_parameter": 1.1564679650000471, - "tests/aws/services/cloudformation/api/test_changesets.py::test_create_change_set_without_parameters": 0.08757776800007377, - "tests/aws/services/cloudformation/api/test_changesets.py::test_create_changeset_with_stack_id": 0.23805133400003342, - "tests/aws/services/cloudformation/api/test_changesets.py::test_create_delete_create": 2.1519617240001025, - "tests/aws/services/cloudformation/api/test_changesets.py::test_create_while_in_review": 0.0017839809999031786, - "tests/aws/services/cloudformation/api/test_changesets.py::test_delete_change_set_exception": 0.02096512899993286, - "tests/aws/services/cloudformation/api/test_changesets.py::test_deleted_changeset": 0.049388910000061514, - "tests/aws/services/cloudformation/api/test_changesets.py::test_describe_change_set_nonexisting": 0.012799164000171004, - "tests/aws/services/cloudformation/api/test_changesets.py::test_describe_change_set_with_similarly_named_stacks": 0.04916203100003713, - "tests/aws/services/cloudformation/api/test_changesets.py::test_empty_changeset": 1.3261853109999038, - "tests/aws/services/cloudformation/api/test_changesets.py::test_execute_change_set": 0.0017581129999371115, - "tests/aws/services/cloudformation/api/test_changesets.py::test_multiple_create_changeset": 0.3539821809999921, - "tests/aws/services/cloudformation/api/test_changesets.py::test_name_conflicts": 1.920425201999933, - "tests/aws/services/cloudformation/api/test_drift_detection.py::test_drift_detection_on_lambda": 0.00176567599999089, - "tests/aws/services/cloudformation/api/test_extensions_api.py::TestExtensionsApi::test_crud_extension[HOOK-LocalStack::Testing::TestHook-hooks/localstack-testing-testhook.zip]": 0.0017668899999989662, - "tests/aws/services/cloudformation/api/test_extensions_api.py::TestExtensionsApi::test_crud_extension[MODULE-LocalStack::Testing::TestModule::MODULE-modules/localstack-testing-testmodule-module.zip]": 0.0016984799999590905, - "tests/aws/services/cloudformation/api/test_extensions_api.py::TestExtensionsApi::test_crud_extension[RESOURCE-LocalStack::Testing::TestResource-resourcetypes/localstack-testing-testresource.zip]": 0.0017344190000585513, - "tests/aws/services/cloudformation/api/test_extensions_api.py::TestExtensionsApi::test_extension_not_complete": 0.0017399890000433516, - "tests/aws/services/cloudformation/api/test_extensions_api.py::TestExtensionsApi::test_extension_type_configuration": 0.0019829820000722975, - "tests/aws/services/cloudformation/api/test_extensions_api.py::TestExtensionsApi::test_extension_versioning": 0.0017593559999795616, - "tests/aws/services/cloudformation/api/test_extensions_hooks.py::TestExtensionsHooks::test_hook_deployment[FAIL]": 0.0017226470000650806, - "tests/aws/services/cloudformation/api/test_extensions_hooks.py::TestExtensionsHooks::test_hook_deployment[WARN]": 0.001798459000042385, - "tests/aws/services/cloudformation/api/test_extensions_modules.py::TestExtensionsModules::test_module_usage": 0.0018429900000000998, - "tests/aws/services/cloudformation/api/test_extensions_resourcetypes.py::TestExtensionsResourceTypes::test_deploy_resource_type": 0.0018800809999675039, - "tests/aws/services/cloudformation/api/test_nested_stacks.py::test_deletion_of_failed_nested_stack": 15.350770300999898, - "tests/aws/services/cloudformation/api/test_nested_stacks.py::test_lifecycle_nested_stack": 0.0021995160000187752, - "tests/aws/services/cloudformation/api/test_nested_stacks.py::test_nested_output_in_params": 12.641020147000177, - "tests/aws/services/cloudformation/api/test_nested_stacks.py::test_nested_stack": 6.2213530239999955, - "tests/aws/services/cloudformation/api/test_nested_stacks.py::test_nested_stack_output_refs": 6.2761850989999175, - "tests/aws/services/cloudformation/api/test_nested_stacks.py::test_nested_stacks_conditions": 6.2567680759999575, - "tests/aws/services/cloudformation/api/test_nested_stacks.py::test_nested_with_nested_stack": 12.337127311999893, - "tests/aws/services/cloudformation/api/test_reference_resolving.py::test_nested_getatt_ref[TopicArn]": 2.1014168770001334, - "tests/aws/services/cloudformation/api/test_reference_resolving.py::test_nested_getatt_ref[TopicName]": 2.101390884999887, - "tests/aws/services/cloudformation/api/test_reference_resolving.py::test_reference_unsupported_resource": 2.098655693000069, - "tests/aws/services/cloudformation/api/test_reference_resolving.py::test_sub_resolving": 2.0988583500000004, - "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_create_stack_with_policy": 0.002271279000069626, - "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_different_action_attribute": 0.0017548660000556993, - "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_different_principal_attribute": 0.0017775479999500021, - "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_empty_policy": 0.0017465700000229845, - "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_not_json_policy": 0.001994643999978507, - "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_policy_during_update": 0.0017814069999531057, - "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_policy_lifecycle": 0.0018537520001018493, - "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_prevent_deletion[resource0]": 0.0018573380000361794, - "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_prevent_deletion[resource1]": 0.0018445540000584515, - "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_prevent_modifying_with_policy_specifying_resource_id": 0.0018868720000000394, - "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_prevent_replacement": 0.0018853090000447992, - "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_prevent_resource_deletion": 0.0017691330000388916, - "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_prevent_stack_update": 0.001864780999994764, - "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_prevent_update[AWS::S3::Bucket]": 0.001758482000013828, - "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_prevent_update[AWS::SNS::Topic]": 0.0018557650000730064, - "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_set_empty_policy_with_url": 0.0017498570000498148, - "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_set_invalid_policy_with_url": 0.0017550960000107807, - "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_set_policy_both_policy_and_url": 0.001786254999956327, - "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_set_policy_with_update_operation": 0.0018222019999711847, - "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_set_policy_with_url": 0.0017320429999472253, - "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_update_with_empty_policy": 0.0017254020000336823, - "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_update_with_overlapping_policies[False]": 0.0017582519999450597, - "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_update_with_overlapping_policies[True]": 0.0017700239999385303, - "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_update_with_policy": 0.0017607180000140943, - "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_create_stack_with_custom_id": 1.0559966970000687, - "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_failure_options_for_stack_creation[False-0]": 0.0018337939999355513, - "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_failure_options_for_stack_creation[True-1]": 0.0017637629999853743, - "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_failure_options_for_stack_update[False-2]": 0.001741630999958943, - "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_failure_options_for_stack_update[True-1]": 0.0017651050000040414, - "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_get_template_using_changesets[json]": 2.105596587999912, - "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_get_template_using_changesets[yaml]": 2.1046691750000264, - "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_get_template_using_create_stack[json]": 1.0526410160000523, - "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_get_template_using_create_stack[yaml]": 1.0544800710000573, - "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_list_events_after_deployment": 2.1765725430000202, - "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_list_stack_resources_for_removed_resource": 19.326889136999966, - "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_stack_description_special_chars": 2.2758553199998914, - "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_stack_lifecycle": 4.352378526999928, - "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_stack_name_creation": 0.08427486799996586, - "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_stack_update_resources": 4.437022683000009, - "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_update_stack_actual_update": 4.1820604830001, - "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_update_stack_with_same_template_withoutchange": 2.0940700359999482, - "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_update_stack_with_same_template_withoutchange_transformation": 2.268722933000049, - "tests/aws/services/cloudformation/api/test_stacks.py::test_blocked_stack_deletion": 0.0018409469998914574, - "tests/aws/services/cloudformation/api/test_stacks.py::test_describe_stack_events_errors": 0.022376310000026933, - "tests/aws/services/cloudformation/api/test_stacks.py::test_events_resource_types": 2.1492800989999523, - "tests/aws/services/cloudformation/api/test_stacks.py::test_linting_error_during_creation": 0.00192160699998567, - "tests/aws/services/cloudformation/api/test_stacks.py::test_list_parameter_type": 2.1055781279999337, - "tests/aws/services/cloudformation/api/test_stacks.py::test_name_conflicts": 2.3835621590000073, - "tests/aws/services/cloudformation/api/test_stacks.py::test_no_echo_parameter": 3.873515685999905, - "tests/aws/services/cloudformation/api/test_stacks.py::test_notifications": 0.0016597890000866755, - "tests/aws/services/cloudformation/api/test_stacks.py::test_stack_deploy_order[A-B-C]": 2.383064138000009, - "tests/aws/services/cloudformation/api/test_stacks.py::test_stack_deploy_order[A-C-B]": 2.380424416999972, - "tests/aws/services/cloudformation/api/test_stacks.py::test_stack_deploy_order[B-A-C]": 2.3827266380000083, - "tests/aws/services/cloudformation/api/test_stacks.py::test_stack_deploy_order[B-C-A]": 2.3803099059999795, - "tests/aws/services/cloudformation/api/test_stacks.py::test_stack_deploy_order[C-A-B]": 2.3788139250000313, - "tests/aws/services/cloudformation/api/test_stacks.py::test_stack_deploy_order[C-B-A]": 2.3846599639999795, - "tests/aws/services/cloudformation/api/test_stacks.py::test_stack_resource_not_found": 2.098759487000166, - "tests/aws/services/cloudformation/api/test_stacks.py::test_update_termination_protection": 2.1327872100000604, - "tests/aws/services/cloudformation/api/test_stacks.py::test_updating_an_updated_stack_sets_status": 6.363665179999998, - "tests/aws/services/cloudformation/api/test_templates.py::test_create_stack_from_s3_template_url[http_host]": 1.1344928610001261, - "tests/aws/services/cloudformation/api/test_templates.py::test_create_stack_from_s3_template_url[http_invalid]": 0.08959796399994957, - "tests/aws/services/cloudformation/api/test_templates.py::test_create_stack_from_s3_template_url[http_path]": 1.1345376420000548, - "tests/aws/services/cloudformation/api/test_templates.py::test_create_stack_from_s3_template_url[s3_url]": 0.09286828100005096, - "tests/aws/services/cloudformation/api/test_templates.py::test_get_template_summary": 2.25313603699999, - "tests/aws/services/cloudformation/api/test_templates.py::test_validate_invalid_json_template_should_fail": 0.09109408300002997, - "tests/aws/services/cloudformation/api/test_templates.py::test_validate_template": 0.09100720799995088, - "tests/aws/services/cloudformation/api/test_transformers.py::test_duplicate_resources": 2.3662468609999223, - "tests/aws/services/cloudformation/api/test_transformers.py::test_transformer_individual_resource_level": 3.194674485000064, - "tests/aws/services/cloudformation/api/test_transformers.py::test_transformer_property_level": 2.284263168999928, - "tests/aws/services/cloudformation/api/test_update_stack.py::test_basic_update": 3.125625504000027, - "tests/aws/services/cloudformation/api/test_update_stack.py::test_diff_after_update": 3.1404758170000378, - "tests/aws/services/cloudformation/api/test_update_stack.py::test_no_parameters_update": 3.124363280000125, - "tests/aws/services/cloudformation/api/test_update_stack.py::test_no_template_error": 0.0019216560000359095, - "tests/aws/services/cloudformation/api/test_update_stack.py::test_set_notification_arn_with_update": 0.001721301999964453, - "tests/aws/services/cloudformation/api/test_update_stack.py::test_update_tags": 0.00171792700007245, - "tests/aws/services/cloudformation/api/test_update_stack.py::test_update_using_template_url": 3.203632647999939, - "tests/aws/services/cloudformation/api/test_update_stack.py::test_update_with_capabilities[capability0]": 0.0017446150000068883, - "tests/aws/services/cloudformation/api/test_update_stack.py::test_update_with_capabilities[capability1]": 0.0017631810000011683, - "tests/aws/services/cloudformation/api/test_update_stack.py::test_update_with_invalid_rollback_configuration_errors": 0.001744726000083574, - "tests/aws/services/cloudformation/api/test_update_stack.py::test_update_with_previous_parameter_value": 3.124280088999967, - "tests/aws/services/cloudformation/api/test_update_stack.py::test_update_with_previous_template": 0.0018315590000383963, - "tests/aws/services/cloudformation/api/test_update_stack.py::test_update_with_resource_types": 0.0017438440000887567, - "tests/aws/services/cloudformation/api/test_update_stack.py::test_update_with_role_without_permissions": 0.0018293130000301971, - "tests/aws/services/cloudformation/api/test_update_stack.py::test_update_with_rollback_configuration": 0.001732110999910219, - "tests/aws/services/cloudformation/api/test_validations.py::test_invalid_output_structure[missing-def]": 0.0018139359999622684, - "tests/aws/services/cloudformation/api/test_validations.py::test_invalid_output_structure[multiple-nones]": 0.001792424000086612, - "tests/aws/services/cloudformation/api/test_validations.py::test_invalid_output_structure[none-value]": 0.0017990090000239434, - "tests/aws/services/cloudformation/api/test_validations.py::test_missing_resources_block": 0.0017251100000521546, - "tests/aws/services/cloudformation/api/test_validations.py::test_resources_blocks[invalid-key]": 0.0017480929999464934, - "tests/aws/services/cloudformation/api/test_validations.py::test_resources_blocks[missing-type]": 0.0017456279999805702, - "tests/aws/services/cloudformation/engine/test_attributes.py::TestResourceAttributes::test_dependency_on_attribute_with_dot_notation": 2.112357287000009, - "tests/aws/services/cloudformation/engine/test_attributes.py::TestResourceAttributes::test_invalid_getatt_fails": 0.0019695250001632303, - "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_condition_on_outputs": 2.1153574870000966, - "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_conditional_att_to_conditional_resources[create]": 2.1353610309998885, - "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_conditional_att_to_conditional_resources[no-create]": 2.1248854049998727, - "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_conditional_in_conditional[dev-us-west-2]": 2.1032438119999597, - "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_conditional_in_conditional[production-us-east-1]": 2.1032077810000374, - "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_conditional_with_select": 2.1520674490001284, - "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_dependency_in_non_evaluated_if_branch[None-FallbackParamValue]": 2.1277103380000426, - "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_dependency_in_non_evaluated_if_branch[false-DefaultParamValue]": 2.130122330999825, - "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_dependency_in_non_evaluated_if_branch[true-FallbackParamValue]": 2.1288366360000737, - "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_dependent_ref": 0.0019138630000270496, - "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_dependent_ref_intrinsic_fn_condition": 0.0017891790000703622, - "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_dependent_ref_with_macro": 0.0018284929999481392, - "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_nested_conditions[prod-bucket-policy]": 0.0018843970001398702, - "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_nested_conditions[prod-nobucket-nopolicy]": 0.0016492589999188567, - "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_nested_conditions[test-bucket-nopolicy]": 0.0016613720000577814, - "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_nested_conditions[test-nobucket-nopolicy]": 0.0018229629999950703, - "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_output_reference_to_skipped_resource": 0.0017153110001117966, - "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_simple_condition_evaluation_deploys_resource": 2.103323440000054, - "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_simple_condition_evaluation_doesnt_deploy_resource": 0.08259069799998997, - "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_simple_intrinsic_fn_condition_evaluation[nope]": 2.090143433999856, - "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_simple_intrinsic_fn_condition_evaluation[yep]": 2.0917195000000675, - "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_sub_in_conditions": 2.120622045999994, - "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_update_conditions": 4.222562855000092, - "tests/aws/services/cloudformation/engine/test_mappings.py::TestCloudFormationMappings::test_async_mapping_error_first_level": 2.0750502189999906, - "tests/aws/services/cloudformation/engine/test_mappings.py::TestCloudFormationMappings::test_async_mapping_error_second_level": 2.0752019890001066, - "tests/aws/services/cloudformation/engine/test_mappings.py::TestCloudFormationMappings::test_aws_refs_in_mappings": 2.0958832930000426, - "tests/aws/services/cloudformation/engine/test_mappings.py::TestCloudFormationMappings::test_mapping_maximum_nesting_depth": 0.001891971999953057, - "tests/aws/services/cloudformation/engine/test_mappings.py::TestCloudFormationMappings::test_mapping_minimum_nesting_depth": 0.001748793999922782, - "tests/aws/services/cloudformation/engine/test_mappings.py::TestCloudFormationMappings::test_mapping_ref_map_key[should-deploy]": 2.11758444599991, - "tests/aws/services/cloudformation/engine/test_mappings.py::TestCloudFormationMappings::test_mapping_ref_map_key[should-not-deploy]": 2.094160716999909, - "tests/aws/services/cloudformation/engine/test_mappings.py::TestCloudFormationMappings::test_mapping_with_invalid_refs": 0.001843891999897096, - "tests/aws/services/cloudformation/engine/test_mappings.py::TestCloudFormationMappings::test_mapping_with_nonexisting_key": 0.0018103990000781778, - "tests/aws/services/cloudformation/engine/test_mappings.py::TestCloudFormationMappings::test_simple_mapping_working": 2.107490318000032, - "tests/aws/services/cloudformation/engine/test_references.py::TestDependsOn::test_depends_on_with_missing_reference": 0.0019252039999173576, - "tests/aws/services/cloudformation/engine/test_references.py::TestFnSub::test_fn_sub_cases": 2.1138797079998994, - "tests/aws/services/cloudformation/engine/test_references.py::TestFnSub::test_non_string_parameter_in_sub": 2.1105347760001223, - "tests/aws/services/cloudformation/engine/test_references.py::test_resolve_transitive_placeholders_in_strings": 2.125672932000043, - "tests/aws/services/cloudformation/engine/test_references.py::test_useful_error_when_invalid_ref": 0.01652718200000436, - "tests/aws/services/cloudformation/resource_providers/ec2/aws_ec2_networkacl/test_basic.py::TestBasicCRD::test_black_box": 2.5685301569998273, - "tests/aws/services/cloudformation/resource_providers/ec2/test_ec2.py::test_deploy_instance_with_key_pair": 2.405798582999978, - "tests/aws/services/cloudformation/resource_providers/ec2/test_ec2.py::test_deploy_prefix_list": 7.200325427999928, - "tests/aws/services/cloudformation/resource_providers/ec2/test_ec2.py::test_deploy_security_group_with_tags": 2.1093900880000547, - "tests/aws/services/cloudformation/resource_providers/ec2/test_ec2.py::test_deploy_vpc_endpoint": 2.520110026999987, - "tests/aws/services/cloudformation/resource_providers/iam/aws_iam_user/test_basic.py::TestBasicCRD::test_autogenerated_values": 2.0992482510000627, - "tests/aws/services/cloudformation/resource_providers/iam/aws_iam_user/test_basic.py::TestBasicCRD::test_black_box": 2.137619917000052, - "tests/aws/services/cloudformation/resource_providers/iam/aws_iam_user/test_basic.py::TestBasicCRD::test_getatt": 2.1388723600000503, - "tests/aws/services/cloudformation/resource_providers/iam/aws_iam_user/test_basic.py::TestUpdates::test_update_without_replacement": 0.0019185800000514064, - "tests/aws/services/cloudformation/resource_providers/iam/aws_iam_user/test_exploration.py::TestAttributeAccess::test_getatt[Arn]": 0.0017445659999566487, - "tests/aws/services/cloudformation/resource_providers/iam/aws_iam_user/test_exploration.py::TestAttributeAccess::test_getatt[Id]": 0.0018389420000630707, - "tests/aws/services/cloudformation/resource_providers/iam/aws_iam_user/test_exploration.py::TestAttributeAccess::test_getatt[Path]": 0.001958625999918695, - "tests/aws/services/cloudformation/resource_providers/iam/aws_iam_user/test_exploration.py::TestAttributeAccess::test_getatt[PermissionsBoundary]": 0.00184952200004318, - "tests/aws/services/cloudformation/resource_providers/iam/aws_iam_user/test_exploration.py::TestAttributeAccess::test_getatt[UserName]": 0.0018481409998685194, - "tests/aws/services/cloudformation/resource_providers/iam/aws_iam_user/test_parity.py::TestParity::test_create_with_full_properties": 2.2165678659998775, - "tests/aws/services/cloudformation/resource_providers/iam/test_iam.py::test_cfn_handle_iam_role_resource_no_role_name": 2.144215430999907, - "tests/aws/services/cloudformation/resource_providers/iam/test_iam.py::test_delete_role_detaches_role_policy": 4.211569410000038, - "tests/aws/services/cloudformation/resource_providers/iam/test_iam.py::test_iam_user_access_key": 4.227820584000028, - "tests/aws/services/cloudformation/resource_providers/iam/test_iam.py::test_iam_username_defaultname": 2.1740530550000585, - "tests/aws/services/cloudformation/resource_providers/iam/test_iam.py::test_managed_policy_with_empty_resource": 2.4698332770000206, - "tests/aws/services/cloudformation/resource_providers/iam/test_iam.py::test_policy_attachments": 2.390306246000023, - "tests/aws/services/cloudformation/resource_providers/iam/test_iam.py::test_server_certificate": 2.2643900259998873, - "tests/aws/services/cloudformation/resource_providers/iam/test_iam.py::test_update_inline_policy": 4.313741876000222, - "tests/aws/services/cloudformation/resource_providers/iam/test_iam.py::test_updating_stack_with_iam_role": 12.258247151999967, - "tests/aws/services/cloudformation/resource_providers/opensearch/test_domain.py::TestAttributeAccess::test_getattr[Arn]": 0.0018629469999495996, - "tests/aws/services/cloudformation/resource_providers/opensearch/test_domain.py::TestAttributeAccess::test_getattr[DomainArn]": 0.0017269339999756994, - "tests/aws/services/cloudformation/resource_providers/opensearch/test_domain.py::TestAttributeAccess::test_getattr[DomainEndpoint]": 0.0018614240000260907, - "tests/aws/services/cloudformation/resource_providers/opensearch/test_domain.py::TestAttributeAccess::test_getattr[DomainName]": 0.002206458000046041, - "tests/aws/services/cloudformation/resource_providers/opensearch/test_domain.py::TestAttributeAccess::test_getattr[EngineVersion]": 0.0018871130000661651, - "tests/aws/services/cloudformation/resource_providers/opensearch/test_domain.py::TestAttributeAccess::test_getattr[Id]": 0.0018559239999831334, - "tests/aws/services/cloudformation/resource_providers/scheduler/test_scheduler.py::test_schedule_and_group": 2.517786729999898, - "tests/aws/services/cloudformation/resource_providers/ssm/test_parameter.py::TestBasicCRD::test_black_box": 0.002046890000087842, - "tests/aws/services/cloudformation/resource_providers/ssm/test_parameter.py::TestUpdates::test_update_without_replacement": 0.001878295999972579, - "tests/aws/services/cloudformation/resource_providers/ssm/test_parameter_getatt_exploration.py::TestAttributeAccess::test_getattr[AllowedPattern]": 0.0017524399999047091, - "tests/aws/services/cloudformation/resource_providers/ssm/test_parameter_getatt_exploration.py::TestAttributeAccess::test_getattr[DataType]": 0.0017280450000498604, - "tests/aws/services/cloudformation/resource_providers/ssm/test_parameter_getatt_exploration.py::TestAttributeAccess::test_getattr[Description]": 0.0017853519999562195, - "tests/aws/services/cloudformation/resource_providers/ssm/test_parameter_getatt_exploration.py::TestAttributeAccess::test_getattr[Id]": 0.0018674349998946127, - "tests/aws/services/cloudformation/resource_providers/ssm/test_parameter_getatt_exploration.py::TestAttributeAccess::test_getattr[Name]": 0.001911548000066432, - "tests/aws/services/cloudformation/resource_providers/ssm/test_parameter_getatt_exploration.py::TestAttributeAccess::test_getattr[Policies]": 0.0019131010000137394, - "tests/aws/services/cloudformation/resource_providers/ssm/test_parameter_getatt_exploration.py::TestAttributeAccess::test_getattr[Tier]": 0.0024335220000466506, - "tests/aws/services/cloudformation/resource_providers/ssm/test_parameter_getatt_exploration.py::TestAttributeAccess::test_getattr[Type]": 0.0018974309999748584, - "tests/aws/services/cloudformation/resource_providers/ssm/test_parameter_getatt_exploration.py::TestAttributeAccess::test_getattr[Value]": 0.0018926419999161226, - "tests/aws/services/cloudformation/resources/test_acm.py::test_cfn_acm_certificate": 2.098762726000132, - "tests/aws/services/cloudformation/resources/test_apigateway.py::TestServerlessApigwLambda::test_serverless_like_deployment_with_update": 14.49226775999989, - "tests/aws/services/cloudformation/resources/test_apigateway.py::test_account": 2.153776676999996, - "tests/aws/services/cloudformation/resources/test_apigateway.py::test_api_gateway_with_policy_as_dict": 2.1061227029999827, - "tests/aws/services/cloudformation/resources/test_apigateway.py::test_cfn_apigateway_aws_integration": 2.3175775240000576, - "tests/aws/services/cloudformation/resources/test_apigateway.py::test_cfn_apigateway_rest_api": 2.3077696399999468, - "tests/aws/services/cloudformation/resources/test_apigateway.py::test_cfn_apigateway_swagger_import": 2.326086852999879, - "tests/aws/services/cloudformation/resources/test_apigateway.py::test_cfn_deploy_apigateway_from_s3_swagger": 2.6908184880001045, - "tests/aws/services/cloudformation/resources/test_apigateway.py::test_cfn_deploy_apigateway_integration": 2.22699852300002, - "tests/aws/services/cloudformation/resources/test_apigateway.py::test_cfn_deploy_apigateway_models": 2.303220736000185, - "tests/aws/services/cloudformation/resources/test_apigateway.py::test_cfn_with_apigateway_resources": 2.3367225529999587, - "tests/aws/services/cloudformation/resources/test_apigateway.py::test_rest_api_serverless_ref_resolving": 9.935634518000143, - "tests/aws/services/cloudformation/resources/test_apigateway.py::test_update_apigateway_stage": 4.533738938000056, - "tests/aws/services/cloudformation/resources/test_apigateway.py::test_update_usage_plan": 4.481719889000033, - "tests/aws/services/cloudformation/resources/test_apigateway.py::test_url_output": 2.1886793730000136, - "tests/aws/services/cloudformation/resources/test_cdk.py::TestCdkInit::test_cdk_bootstrap[10]": 8.637828602000013, - "tests/aws/services/cloudformation/resources/test_cdk.py::TestCdkInit::test_cdk_bootstrap[11]": 8.654450194999981, - "tests/aws/services/cloudformation/resources/test_cdk.py::TestCdkInit::test_cdk_bootstrap[12]": 8.646710715000154, - "tests/aws/services/cloudformation/resources/test_cdk.py::TestCdkInit::test_cdk_bootstrap_redeploy": 5.6206864220000625, - "tests/aws/services/cloudformation/resources/test_cdk.py::TestCdkSampleApp::test_cdk_sample": 2.4335871789999146, - "tests/aws/services/cloudformation/resources/test_cloudformation.py::test_create_macro": 3.2008875340002305, - "tests/aws/services/cloudformation/resources/test_cloudformation.py::test_waitcondition": 2.2037635749998117, - "tests/aws/services/cloudformation/resources/test_cloudwatch.py::test_alarm_creation": 2.0897039149999728, - "tests/aws/services/cloudformation/resources/test_cloudwatch.py::test_alarm_ext_statistic": 2.1282291350000833, - "tests/aws/services/cloudformation/resources/test_cloudwatch.py::test_composite_alarm_creation": 2.41192090599975, - "tests/aws/services/cloudformation/resources/test_dynamodb.py::test_billing_mode_as_conditional[PAY_PER_REQUEST]": 2.486900565000269, - "tests/aws/services/cloudformation/resources/test_dynamodb.py::test_billing_mode_as_conditional[PROVISIONED]": 2.4783113580001555, - "tests/aws/services/cloudformation/resources/test_dynamodb.py::test_default_name_for_table": 2.4844214730001113, - "tests/aws/services/cloudformation/resources/test_dynamodb.py::test_deploy_stack_with_dynamodb_table": 2.2221644940002534, - "tests/aws/services/cloudformation/resources/test_dynamodb.py::test_global_table": 2.473494157999994, - "tests/aws/services/cloudformation/resources/test_dynamodb.py::test_global_table_with_ttl_and_sse": 2.1470889489996807, - "tests/aws/services/cloudformation/resources/test_dynamodb.py::test_globalindex_read_write_provisioned_throughput_dynamodb_table": 2.190173730000197, - "tests/aws/services/cloudformation/resources/test_dynamodb.py::test_table_with_ttl_and_sse": 2.1644178489998467, - "tests/aws/services/cloudformation/resources/test_dynamodb.py::test_ttl_cdk": 1.2528888779997942, - "tests/aws/services/cloudformation/resources/test_ec2.py::test_cfn_update_ec2_instance_type": 0.0018424890001824679, - "tests/aws/services/cloudformation/resources/test_ec2.py::test_cfn_with_multiple_route_table_associations": 2.478730465999888, - "tests/aws/services/cloudformation/resources/test_ec2.py::test_cfn_with_multiple_route_tables": 2.2018559599998753, - "tests/aws/services/cloudformation/resources/test_ec2.py::test_dhcp_options": 2.317622851999886, - "tests/aws/services/cloudformation/resources/test_ec2.py::test_ec2_security_group_id_with_vpc": 2.1502568599998995, - "tests/aws/services/cloudformation/resources/test_ec2.py::test_internet_gateway_ref_and_attr": 2.3001288079997266, - "tests/aws/services/cloudformation/resources/test_ec2.py::test_keypair_create_import": 2.2231779139999617, - "tests/aws/services/cloudformation/resources/test_ec2.py::test_simple_route_table_creation": 2.2253968999998506, - "tests/aws/services/cloudformation/resources/test_ec2.py::test_simple_route_table_creation_without_vpc": 2.230643093000026, - "tests/aws/services/cloudformation/resources/test_ec2.py::test_transit_gateway_attachment": 2.832816616000173, - "tests/aws/services/cloudformation/resources/test_ec2.py::test_vpc_creates_default_sg": 2.3920583259998693, - "tests/aws/services/cloudformation/resources/test_ec2.py::test_vpc_with_route_table": 3.318580466999947, - "tests/aws/services/cloudformation/resources/test_elasticsearch.py::test_cfn_handle_elasticsearch_domain": 4.3498726689999785, - "tests/aws/services/cloudformation/resources/test_events.py::test_cfn_event_api_destination_resource": 16.384498511999936, - "tests/aws/services/cloudformation/resources/test_events.py::test_cfn_event_bus_resource": 2.1521314340000117, - "tests/aws/services/cloudformation/resources/test_events.py::test_event_rule_creation_without_target": 2.111316350999914, - "tests/aws/services/cloudformation/resources/test_events.py::test_event_rule_to_logs": 2.2256746699999894, - "tests/aws/services/cloudformation/resources/test_events.py::test_eventbus_policies": 13.487565034000227, - "tests/aws/services/cloudformation/resources/test_events.py::test_eventbus_policy_statement": 2.1132986090001395, - "tests/aws/services/cloudformation/resources/test_events.py::test_rule_pattern_transformation": 2.1338719820000733, - "tests/aws/services/cloudformation/resources/test_events.py::test_rule_properties": 2.1355004029999236, - "tests/aws/services/cloudformation/resources/test_firehose.py::test_firehose_stack_with_kinesis_as_source": 35.56209035200004, - "tests/aws/services/cloudformation/resources/test_integration.py::test_events_sqs_sns_lambda": 19.844008825000174, - "tests/aws/services/cloudformation/resources/test_kinesis.py::test_cfn_handle_kinesis_firehose_resources": 11.388530570000285, - "tests/aws/services/cloudformation/resources/test_kinesis.py::test_default_parameters_kinesis": 11.323054620999983, - "tests/aws/services/cloudformation/resources/test_kinesis.py::test_describe_template": 0.1332682659999591, - "tests/aws/services/cloudformation/resources/test_kinesis.py::test_dynamodb_stream_response_with_cf": 11.343470431999776, - "tests/aws/services/cloudformation/resources/test_kinesis.py::test_kinesis_stream_consumer_creations": 17.28398102699998, - "tests/aws/services/cloudformation/resources/test_kinesis.py::test_stream_creation": 11.333802713000068, - "tests/aws/services/cloudformation/resources/test_kms.py::test_cfn_with_kms_resources": 2.138225700000021, - "tests/aws/services/cloudformation/resources/test_kms.py::test_deploy_stack_with_kms": 2.118486591999954, - "tests/aws/services/cloudformation/resources/test_kms.py::test_kms_key_disabled": 2.1124727069998244, - "tests/aws/services/cloudformation/resources/test_lambda.py::TestCfnLambdaDestinations::test_generic_destination_routing[sqs-sqs]": 19.64750861499988, - "tests/aws/services/cloudformation/resources/test_lambda.py::TestCfnLambdaIntegrations::test_cfn_lambda_dynamodb_source": 11.855835591000186, - "tests/aws/services/cloudformation/resources/test_lambda.py::TestCfnLambdaIntegrations::test_cfn_lambda_kinesis_source": 21.492579937000073, - "tests/aws/services/cloudformation/resources/test_lambda.py::TestCfnLambdaIntegrations::test_cfn_lambda_permissions": 7.868035635999831, - "tests/aws/services/cloudformation/resources/test_lambda.py::TestCfnLambdaIntegrations::test_cfn_lambda_sqs_source": 8.277830662999804, - "tests/aws/services/cloudformation/resources/test_lambda.py::TestCfnLambdaIntegrations::test_lambda_dynamodb_event_filter": 7.457770513000014, - "tests/aws/services/cloudformation/resources/test_lambda.py::test_cfn_function_url": 7.509122528000034, - "tests/aws/services/cloudformation/resources/test_lambda.py::test_event_invoke_config": 6.2687003840001125, - "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_alias": 12.507668946999956, - "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_cfn_dead_letter_config_async_invocation": 11.059224843000266, - "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_cfn_run": 6.589569919000041, - "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_cfn_run_with_empty_string_replacement_deny_list": 6.181614047000039, - "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_cfn_run_with_non_empty_string_replacement_deny_list": 6.184070529999644, - "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_code_signing_config": 2.1988878289998866, - "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_function_tags": 6.5545346639999025, - "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_layer_crud": 6.268580348999876, - "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_logging_config": 6.207673469999918, - "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_version": 6.777706895999927, - "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_version_provisioned_concurrency": 12.573623398000109, - "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_vpc": 0.0020456120000744704, - "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_w_dynamodb_event_filter": 11.456557058000044, - "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_w_dynamodb_event_filter_update": 12.669036426000048, - "tests/aws/services/cloudformation/resources/test_lambda.py::test_multiple_lambda_permissions_for_singlefn": 6.2270152460000645, - "tests/aws/services/cloudformation/resources/test_lambda.py::test_python_lambda_code_deployed_via_s3": 6.673998299999994, - "tests/aws/services/cloudformation/resources/test_lambda.py::test_update_lambda_function": 8.283082080000213, - "tests/aws/services/cloudformation/resources/test_lambda.py::test_update_lambda_function_name": 12.321207600999742, - "tests/aws/services/cloudformation/resources/test_lambda.py::test_update_lambda_permissions": 10.30459449, - "tests/aws/services/cloudformation/resources/test_logs.py::test_cfn_handle_log_group_resource": 2.4024696149999727, - "tests/aws/services/cloudformation/resources/test_logs.py::test_logstream": 2.1257465450000836, - "tests/aws/services/cloudformation/resources/test_opensearch.py::test_domain": 0.001924993999864455, - "tests/aws/services/cloudformation/resources/test_opensearch.py::test_domain_with_alternative_types": 17.474204570999973, - "tests/aws/services/cloudformation/resources/test_redshift.py::test_redshift_cluster": 2.12974065100002, - "tests/aws/services/cloudformation/resources/test_resource_groups.py::test_group_defaults": 2.263483554000004, - "tests/aws/services/cloudformation/resources/test_route53.py::test_create_health_check": 2.2625588040000366, - "tests/aws/services/cloudformation/resources/test_route53.py::test_create_record_set_via_id": 2.1883058050000272, - "tests/aws/services/cloudformation/resources/test_route53.py::test_create_record_set_via_name": 2.191496281999889, - "tests/aws/services/cloudformation/resources/test_route53.py::test_create_record_set_without_resource_record": 2.1765871050001806, - "tests/aws/services/cloudformation/resources/test_s3.py::test_bucket_autoname": 2.1080159870000443, - "tests/aws/services/cloudformation/resources/test_s3.py::test_bucket_versioning": 2.1148543650001557, - "tests/aws/services/cloudformation/resources/test_s3.py::test_bucketpolicy": 22.380472424000118, - "tests/aws/services/cloudformation/resources/test_s3.py::test_cfn_handle_s3_notification_configuration": 2.166626836999967, - "tests/aws/services/cloudformation/resources/test_s3.py::test_cors_configuration": 2.5143907990000116, - "tests/aws/services/cloudformation/resources/test_s3.py::test_object_lock_configuration": 2.5105491490000986, - "tests/aws/services/cloudformation/resources/test_s3.py::test_website_configuration": 2.491483969000001, - "tests/aws/services/cloudformation/resources/test_sam.py::test_cfn_handle_serverless_api_resource": 6.626443895000193, - "tests/aws/services/cloudformation/resources/test_sam.py::test_sam_policies": 6.330364576999955, - "tests/aws/services/cloudformation/resources/test_sam.py::test_sam_sqs_event": 13.458627152999952, - "tests/aws/services/cloudformation/resources/test_sam.py::test_sam_template": 6.623674772999948, - "tests/aws/services/cloudformation/resources/test_secretsmanager.py::test_cdk_deployment_generates_secret_value_if_no_value_is_provided": 1.2643974790000811, - "tests/aws/services/cloudformation/resources/test_secretsmanager.py::test_cfn_handle_secretsmanager_secret": 2.2789812999999413, - "tests/aws/services/cloudformation/resources/test_secretsmanager.py::test_cfn_secret_policy[default]": 2.1201289959999485, - "tests/aws/services/cloudformation/resources/test_secretsmanager.py::test_cfn_secret_policy[true]": 2.12221052599989, - "tests/aws/services/cloudformation/resources/test_secretsmanager.py::test_cfn_secretsmanager_gen_secret": 2.269230380000181, - "tests/aws/services/cloudformation/resources/test_sns.py::test_deploy_stack_with_sns_topic": 2.138133092999851, - "tests/aws/services/cloudformation/resources/test_sns.py::test_sns_subscription": 2.1216770040000483, - "tests/aws/services/cloudformation/resources/test_sns.py::test_sns_subscription_region": 2.1463481320001847, - "tests/aws/services/cloudformation/resources/test_sns.py::test_sns_topic_fifo_with_deduplication": 2.3422328910000942, - "tests/aws/services/cloudformation/resources/test_sns.py::test_sns_topic_fifo_without_suffix_fails": 2.084280650999972, - "tests/aws/services/cloudformation/resources/test_sns.py::test_sns_topic_with_attributes": 1.218109590999802, - "tests/aws/services/cloudformation/resources/test_sns.py::test_update_subscription": 4.246193758000118, - "tests/aws/services/cloudformation/resources/test_sqs.py::test_cfn_handle_sqs_resource": 2.137934492000113, - "tests/aws/services/cloudformation/resources/test_sqs.py::test_sqs_fifo_queue_generates_valid_name": 2.1252054359999875, - "tests/aws/services/cloudformation/resources/test_sqs.py::test_sqs_non_fifo_queue_generates_valid_name": 2.1065768149999258, - "tests/aws/services/cloudformation/resources/test_sqs.py::test_sqs_queue_policy": 2.141209419000006, - "tests/aws/services/cloudformation/resources/test_sqs.py::test_update_queue_no_change": 4.237422981000009, - "tests/aws/services/cloudformation/resources/test_sqs.py::test_update_sqs_queuepolicy": 4.219287260999863, - "tests/aws/services/cloudformation/resources/test_ssm.py::test_deploy_patch_baseline": 2.267168947000073, - "tests/aws/services/cloudformation/resources/test_ssm.py::test_maintenance_window": 2.1746278509999684, - "tests/aws/services/cloudformation/resources/test_ssm.py::test_parameter_defaults": 2.295981041000232, - "tests/aws/services/cloudformation/resources/test_ssm.py::test_update_ssm_parameter_tag": 4.198255159000155, - "tests/aws/services/cloudformation/resources/test_ssm.py::test_update_ssm_parameters": 4.185427828000002, - "tests/aws/services/cloudformation/resources/test_stack_sets.py::test_create_stack_set_with_stack_instances": 1.1310859690001962, - "tests/aws/services/cloudformation/resources/test_stepfunctions.py::test_apigateway_invoke": 9.557532390000233, - "tests/aws/services/cloudformation/resources/test_stepfunctions.py::test_apigateway_invoke_localhost": 9.581219253999734, - "tests/aws/services/cloudformation/resources/test_stepfunctions.py::test_apigateway_invoke_localhost_with_path": 15.732532609999907, - "tests/aws/services/cloudformation/resources/test_stepfunctions.py::test_apigateway_invoke_with_path": 15.657945656999573, - "tests/aws/services/cloudformation/resources/test_stepfunctions.py::test_cfn_statemachine_default_s3_location": 4.8114790120000634, - "tests/aws/services/cloudformation/resources/test_stepfunctions.py::test_cfn_statemachine_with_dependencies": 2.1811768110003413, - "tests/aws/services/cloudformation/resources/test_stepfunctions.py::test_nested_statemachine_with_sync2": 15.517835608000041, - "tests/aws/services/cloudformation/resources/test_stepfunctions.py::test_retry_and_catch": 0.0026324739999381563, - "tests/aws/services/cloudformation/resources/test_stepfunctions.py::test_statemachine_create_with_logging_configuration": 2.6860395779999635, - "tests/aws/services/cloudformation/resources/test_stepfunctions.py::test_statemachine_definitionsubstitution": 7.329174582000178, - "tests/aws/services/cloudformation/test_cloudformation_ui.py::TestCloudFormationUi::test_get_cloudformation_ui": 0.06807541500006664, - "tests/aws/services/cloudformation/test_cloudtrail_trace.py::test_cloudtrail_trace_example": 0.0017879920001178107, - "tests/aws/services/cloudformation/test_template_engine.py::TestImportValues::test_cfn_with_exports": 2.1138366009997753, - "tests/aws/services/cloudformation/test_template_engine.py::TestImportValues::test_import_values_across_stacks": 4.211213168000086, - "tests/aws/services/cloudformation/test_template_engine.py::TestImports::test_stack_imports": 4.2440654379997795, - "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_and_or_functions[Fn::And-0-0-False]": 0.08343559300033121, - "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_and_or_functions[Fn::And-0-1-False]": 0.08199512299984235, - "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_and_or_functions[Fn::And-1-0-False]": 0.08608951199994408, - "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_and_or_functions[Fn::And-1-1-True]": 2.1222193590001552, - "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_and_or_functions[Fn::Or-0-0-False]": 0.08740726199994242, - "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_and_or_functions[Fn::Or-0-1-True]": 2.118739531000074, - "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_and_or_functions[Fn::Or-1-0-True]": 2.12064257899965, - "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_and_or_functions[Fn::Or-1-1-True]": 2.1242548129998795, - "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_base64_sub_and_getatt_functions": 2.1098992900001576, - "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_cfn_template_with_short_form_fn_sub": 2.103283777999877, - "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_cidr_function": 0.0018178129998887016, - "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_find_map_function": 2.1033613459999287, - "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_get_azs_function[ap-northeast-1]": 2.110484255000074, - "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_get_azs_function[ap-southeast-2]": 2.111640680999926, - "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_get_azs_function[eu-central-1]": 2.1183154960001502, - "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_get_azs_function[eu-west-1]": 2.1158879589997923, - "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_get_azs_function[us-east-1]": 2.1006706389996452, - "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_get_azs_function[us-east-2]": 2.1282096619995627, - "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_get_azs_function[us-west-1]": 2.1162471860000096, - "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_get_azs_function[us-west-2]": 2.113929403999691, - "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_join_no_value_construct": 2.1123614599998746, - "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_split_length_and_join_functions": 2.1526951109999573, - "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_sub_not_ready": 2.1231209659997603, - "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_sub_number_type": 2.102127057999951, - "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_to_json_functions": 0.0018358570000600594, - "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_attribute_uses_macro": 5.735985774000028, - "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_capabilities_requirements": 5.315919531999953, - "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_error_pass_macro_as_reference": 0.02531915100007609, - "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_failed_state[raise_error.py]": 3.6651639330000307, - "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_failed_state[return_invalid_template.py]": 3.6395147020000422, - "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_failed_state[return_unsuccessful_with_message.py]": 3.6578095429997575, - "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_failed_state[return_unsuccessful_without_message.py]": 3.6497722999997677, - "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_functions_and_references_during_transformation": 4.6440179409996745, - "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_global_scope": 5.157553655999891, - "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_macro_deployment": 3.217075732000012, - "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_pyplate_param_type_list": 8.722933005999948, - "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_scope_order_and_parameters": 0.0020229159999871626, - "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_snipped_scope[transformation_snippet_topic.json]": 5.7310024369999155, - "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_snipped_scope[transformation_snippet_topic.yml]": 5.7371070310000505, - "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_to_validate_template_limit_for_macro": 3.7732982930001526, - "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_validate_lambda_internals": 5.207202487000131, - "tests/aws/services/cloudformation/test_template_engine.py::TestPreviousValues::test_parameter_usepreviousvalue_behavior": 0.0018823330001396243, - "tests/aws/services/cloudformation/test_template_engine.py::TestPseudoParameters::test_stack_id": 2.1179285240002628, - "tests/aws/services/cloudformation/test_template_engine.py::TestSecretsManagerParameters::test_resolve_secretsmanager[resolve_secretsmanager.yaml]": 2.10832378699979, - "tests/aws/services/cloudformation/test_template_engine.py::TestSecretsManagerParameters::test_resolve_secretsmanager[resolve_secretsmanager_full.yaml]": 2.115484737000088, - "tests/aws/services/cloudformation/test_template_engine.py::TestSecretsManagerParameters::test_resolve_secretsmanager[resolve_secretsmanager_partial.yaml]": 2.1134552200001053, - "tests/aws/services/cloudformation/test_template_engine.py::TestSsmParameters::test_create_change_set_with_ssm_parameter_list": 2.165984060000028, - "tests/aws/services/cloudformation/test_template_engine.py::TestSsmParameters::test_create_stack_with_ssm_parameters": 2.1709209520001878, - "tests/aws/services/cloudformation/test_template_engine.py::TestSsmParameters::test_resolve_ssm": 2.124466400999836, - "tests/aws/services/cloudformation/test_template_engine.py::TestSsmParameters::test_resolve_ssm_secure": 2.1261801399998603, - "tests/aws/services/cloudformation/test_template_engine.py::TestSsmParameters::test_resolve_ssm_with_version": 2.157614990999946, - "tests/aws/services/cloudformation/test_template_engine.py::TestSsmParameters::test_ssm_nested_with_nested_stack": 6.244212256000083, - "tests/aws/services/cloudformation/test_template_engine.py::TestStackEvents::test_invalid_stack_deploy": 2.3772469789998922, - "tests/aws/services/cloudformation/test_template_engine.py::TestTypes::test_implicit_type_conversion": 2.1600746910000908, - "tests/aws/services/cloudformation/test_unsupported.py::test_unsupported": 2.0943378629999643, - "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_acm.py::test_cfn_acm_certificate": 2.10233101599988, - "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::TestServerlessApigwLambda::test_serverless_like_deployment_with_update": 0.00200961899986396, - "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::test_account": 0.001725080000142043, - "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::test_api_gateway_with_policy_as_dict": 0.0017991069998970488, - "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::test_cfn_apigateway_aws_integration": 0.0018477080000138812, - "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::test_cfn_apigateway_rest_api": 0.0018644489998678182, - "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::test_cfn_apigateway_swagger_import": 0.00184930099999292, - "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::test_cfn_deploy_apigateway_from_s3_swagger": 0.0019742039996799576, - "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::test_cfn_deploy_apigateway_integration": 0.0017334949998257798, - "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::test_cfn_deploy_apigateway_models": 0.0017409689996839006, - "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::test_cfn_with_apigateway_resources": 0.0018320580002182396, - "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::test_rest_api_serverless_ref_resolving": 0.00182958300001701, - "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::test_update_apigateway_stage": 0.001749664000044504, - "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::test_update_usage_plan": 0.0017710150000311842, - "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::test_url_output": 0.0017774869997992937, - "tests/aws/services/cloudformation/v2/test_change_set_conditions.py::TestChangeSetConditions::test_condition_add_new_negative_condition_to_existent_resource": 0.0018329499998799292, - "tests/aws/services/cloudformation/v2/test_change_set_conditions.py::TestChangeSetConditions::test_condition_add_new_positive_condition_to_existent_resource": 0.001876010999922073, - "tests/aws/services/cloudformation/v2/test_change_set_conditions.py::TestChangeSetConditions::test_condition_update_adds_resource": 0.001869437999857837, - "tests/aws/services/cloudformation/v2/test_change_set_conditions.py::TestChangeSetConditions::test_condition_update_removes_resource": 0.0018861799999285722, - "tests/aws/services/cloudformation/v2/test_change_set_depends_on.py::TestChangeSetDependsOn::test_multiple_dependencies_addition": 0.0018484389997865946, - "tests/aws/services/cloudformation/v2/test_change_set_depends_on.py::TestChangeSetDependsOn::test_multiple_dependencies_deletion": 0.001761878000024808, - "tests/aws/services/cloudformation/v2/test_change_set_depends_on.py::TestChangeSetDependsOn::test_update_depended_resource": 0.001873685999726149, - "tests/aws/services/cloudformation/v2/test_change_set_depends_on.py::TestChangeSetDependsOn::test_update_depended_resource_list": 0.0019989200000054552, - "tests/aws/services/cloudformation/v2/test_change_set_fn_get_attr.py::TestChangeSetFnGetAttr::test_direct_attribute_value_change": 0.0018331700000544515, - "tests/aws/services/cloudformation/v2/test_change_set_fn_get_attr.py::TestChangeSetFnGetAttr::test_direct_attribute_value_change_in_get_attr_chain": 0.0017451159997108334, - "tests/aws/services/cloudformation/v2/test_change_set_fn_get_attr.py::TestChangeSetFnGetAttr::test_direct_attribute_value_change_with_dependent_addition": 0.0019097939998573565, - "tests/aws/services/cloudformation/v2/test_change_set_fn_get_attr.py::TestChangeSetFnGetAttr::test_immutable_property_update_causes_resource_replacement": 0.0017883470000015222, - "tests/aws/services/cloudformation/v2/test_change_set_fn_get_attr.py::TestChangeSetFnGetAttr::test_resource_addition": 0.0018732769999587617, - "tests/aws/services/cloudformation/v2/test_change_set_fn_get_attr.py::TestChangeSetFnGetAttr::test_resource_deletion": 0.0018501220001780894, - "tests/aws/services/cloudformation/v2/test_change_set_fn_join.py::TestChangeSetFnJoin::test_indirect_update_refence_argument": 0.0017313309999735793, - "tests/aws/services/cloudformation/v2/test_change_set_fn_join.py::TestChangeSetFnJoin::test_update_refence_argument": 0.0018505240002468781, - "tests/aws/services/cloudformation/v2/test_change_set_fn_join.py::TestChangeSetFnJoin::test_update_string_literal_argument": 0.0018277520000538061, - "tests/aws/services/cloudformation/v2/test_change_set_fn_join.py::TestChangeSetFnJoin::test_update_string_literal_arguments_empty": 0.0016952229998423718, - "tests/aws/services/cloudformation/v2/test_change_set_fn_join.py::TestChangeSetFnJoin::test_update_string_literal_delimiter": 0.0018080150002788287, - "tests/aws/services/cloudformation/v2/test_change_set_fn_join.py::TestChangeSetFnJoin::test_update_string_literal_delimiter_empty": 0.0017082580000078451, - "tests/aws/services/cloudformation/v2/test_change_set_mappings.py::TestChangeSetMappings::test_mapping_addition_with_resource": 0.0016650679999656859, - "tests/aws/services/cloudformation/v2/test_change_set_mappings.py::TestChangeSetMappings::test_mapping_deletion_with_resource_remap": 0.0017001220001020556, - "tests/aws/services/cloudformation/v2/test_change_set_mappings.py::TestChangeSetMappings::test_mapping_key_addition_with_resource": 0.0017040289999386005, - "tests/aws/services/cloudformation/v2/test_change_set_mappings.py::TestChangeSetMappings::test_mapping_key_deletion_with_resource_remap": 0.0018867299997964437, - "tests/aws/services/cloudformation/v2/test_change_set_mappings.py::TestChangeSetMappings::test_mapping_key_update": 0.0017021860001023015, - "tests/aws/services/cloudformation/v2/test_change_set_mappings.py::TestChangeSetMappings::test_mapping_leaf_update": 0.001736801000106425, - "tests/aws/services/cloudformation/v2/test_change_set_parameters.py::TestChangeSetParameters::test_update_parameter_default_value": 0.0017071849999865663, - "tests/aws/services/cloudformation/v2/test_change_set_parameters.py::TestChangeSetParameters::test_update_parameter_default_value_with_dynamic_overrides": 0.0017946590000974538, - "tests/aws/services/cloudformation/v2/test_change_set_parameters.py::TestChangeSetParameters::test_update_parameter_with_added_default_value": 0.0016956030001438194, - "tests/aws/services/cloudformation/v2/test_change_set_parameters.py::TestChangeSetParameters::test_update_parameter_with_removed_default_value": 0.0018518859997129766, - "tests/aws/services/cloudformation/v2/test_change_set_ref.py::TestChangeSetRef::test_direct_attribute_value_change": 0.0022207030001482053, - "tests/aws/services/cloudformation/v2/test_change_set_ref.py::TestChangeSetRef::test_direct_attribute_value_change_in_ref_chain": 0.0018306270003449754, - "tests/aws/services/cloudformation/v2/test_change_set_ref.py::TestChangeSetRef::test_direct_attribute_value_change_with_dependent_addition": 0.001839482999912434, - "tests/aws/services/cloudformation/v2/test_change_set_ref.py::TestChangeSetRef::test_immutable_property_update_causes_resource_replacement": 0.001823271000148452, - "tests/aws/services/cloudformation/v2/test_change_set_ref.py::TestChangeSetRef::test_resource_addition": 0.001844641999923624, - "tests/aws/services/cloudformation/v2/test_change_set_ref.py::TestChangeSetRef::test_supported_pseudo_parameter": 0.0018045269998765434, - "tests/aws/services/cloudformation/v2/test_change_set_values.py::TestChangeSetValues::test_property_empy_list": 0.0018414460000713007, - "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_base_dynamic_parameter_scenarios[change_dynamic]": 0.0017058729999916977, - "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_base_dynamic_parameter_scenarios[change_parameter_for_condition_create_resource]": 0.0017133169999397069, - "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_base_dynamic_parameter_scenarios[change_unrelated_property]": 0.0017007940000439703, - "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_base_dynamic_parameter_scenarios[change_unrelated_property_not_create_only]": 0.0017330740001852973, - "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_base_mapping_scenarios[update_string_referencing_resource]": 0.0016935700000431098, - "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_conditions": 0.0017063939999388822, - "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_direct_update": 0.0018126229999779753, - "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_dynamic_update": 0.001887060999933965, - "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_execute_with_ref": 0.0017103210000186664, - "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_mappings_with_parameter_lookup": 0.0017087489998175442, - "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_mappings_with_static_fields": 0.0017003929999646061, - "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_parameter_changes": 0.001718406000009054, - "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_unrelated_changes_requires_replacement": 0.0018811210002240841, - "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_unrelated_changes_update_propagation": 0.0017523310000342462, - "tests/aws/services/cloudformation/v2/test_change_sets.py::test_single_resource_static_update": 0.0018459540001458663, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_alarm_lambda_target": 1.6562972769997941, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_anomaly_detector_lifecycle": 0.0017303390000051877, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_aws_sqs_metrics_created": 2.3561451519999537, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_breaching_alarm_actions": 5.315173837999964, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_create_metric_stream": 0.0017867550000119081, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_dashboard_lifecycle": 0.13976651100028903, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_default_ordering": 0.11865985300005377, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_delete_alarm": 0.08834847999992235, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_describe_alarms_converts_date_format_correctly": 0.07610015199998088, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_describe_minimal_metric_alarm": 0.07895568599974467, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_enable_disable_alarm_actions": 10.252386452999872, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data": 2.0664516419999472, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data_different_units_no_unit_in_query[metric_data0]": 0.001755468000055771, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data_different_units_no_unit_in_query[metric_data1]": 0.0018299750001915527, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data_different_units_no_unit_in_query[metric_data2]": 0.0017313620001004892, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data_for_multiple_metrics": 1.0501973240000098, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data_pagination": 2.1895978130000913, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data_stats[Average]": 0.03697230799980389, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data_stats[Maximum]": 0.03341490999991947, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data_stats[Minimum]": 0.03451932399980251, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data_stats[SampleCount]": 0.03471026800002619, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data_stats[Sum]": 0.03285757200023909, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data_with_different_units": 0.025698459999830447, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data_with_dimensions": 0.04028229799996552, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data_with_zero_and_labels": 0.036694415000056324, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_statistics": 0.174754799999846, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_with_no_results": 0.055523277000020244, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_with_null_dimensions": 0.029771298000014212, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_handle_different_units": 0.028799445999993623, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_insight_rule": 0.0017249300001367374, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_invalid_amount_of_datapoints": 0.5659814650002772, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_invalid_dashboard_name": 0.01653278699996008, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_label_generation[input_pairs0]": 0.03048673700004656, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_label_generation[input_pairs1]": 0.030162031999907413, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_label_generation[input_pairs2]": 0.030369012999699407, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_label_generation[input_pairs3]": 0.03048409799998808, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_label_generation[input_pairs4]": 0.03251482299992858, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_label_generation[input_pairs5]": 0.029859354000109306, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_label_generation[input_pairs6]": 0.035607351999942694, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_list_metrics_pagination": 5.071531530999891, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_list_metrics_uniqueness": 2.0565704170001027, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_list_metrics_with_filters": 4.076339343999962, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_metric_widget": 0.001732204000290949, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_multiple_dimensions": 2.1120178590001615, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_multiple_dimensions_statistics": 0.05055155900004138, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_parallel_put_metric_data_list_metrics": 0.2461613790001138, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_put_composite_alarm_describe_alarms": 0.08745154299958813, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_put_metric_alarm": 10.625812600000017, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_put_metric_alarm_escape_character": 0.06964230500011581, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_put_metric_data_gzip": 0.023371349999933955, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_put_metric_data_validation": 0.04073372800007746, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_put_metric_data_values_list": 0.033487205999790604, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_put_metric_uses_utc": 0.031193712999993295, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_raw_metric_data": 0.023490482999932283, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_set_alarm": 2.3453569420000804, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_set_alarm_invalid_input": 0.08128622100002758, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_store_tags": 0.11573074500006442, - "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_trigger_composite_alarm": 4.6893139920002795, - "tests/aws/services/cloudwatch/test_cloudwatch_metrics.py::TestCloudWatchLambdaMetrics::test_lambda_invoke_error": 2.5403738699999394, - "tests/aws/services/cloudwatch/test_cloudwatch_metrics.py::TestCloudWatchLambdaMetrics::test_lambda_invoke_successful": 2.5082642019997365, - "tests/aws/services/cloudwatch/test_cloudwatch_metrics.py::TestSQSMetrics::test_alarm_number_of_messages_sent": 61.247869282000465, - "tests/aws/services/cloudwatch/test_cloudwatch_metrics.py::TestSqsApproximateMetrics::test_sqs_approximate_metrics": 51.88358154000002, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_batch_write_binary": 0.09177013299949976, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_batch_write_items": 0.09424574400009078, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_batch_write_items_streaming": 1.1564454270001079, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_batch_write_not_existing_table": 0.21025506300020425, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_batch_write_not_matching_schema": 0.10724185499975647, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_binary_data_with_stream": 0.761922931999834, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_continuous_backup_update": 0.28909025299981295, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_create_duplicate_table": 0.09464845999991667, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_data_encoding_consistency": 0.9118225570005052, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_delete_table": 0.10892664799985141, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_batch_execute_statement": 0.1304326510003193, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_create_table_with_class": 0.1566640109999753, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_create_table_with_partial_sse_specification": 0.11557827299975543, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_create_table_with_sse_specification": 0.06654137499981516, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_execute_statement_empy_parameter": 0.1046366560003662, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_execute_transaction": 0.1720096419994661, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_get_batch_items": 0.07983857100043679, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_idempotent_writing": 0.1361674580007275, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_partiql_missing": 0.11271423600055641, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_pay_per_request": 0.039187814999877446, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_stream_records_with_update_item": 0.0019804359999398002, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_stream_shard_iterator": 0.8397359150003467, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_stream_stream_view_type": 1.3205458950005777, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_streams_describe_with_exclusive_start_shard_id": 0.7749845120001737, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_streams_shard_iterator_format": 2.866550348000146, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_update_table_without_sse_specification_change": 0.10528765599974577, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_with_kinesis_stream": 1.4520149569998466, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_empty_and_binary_values": 0.07746314900032303, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_global_tables": 0.10020428899997569, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_global_tables_version_2019": 0.4411483870003394, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_gsi_with_billing_mode[PAY_PER_REQUEST]": 0.3438232949997655, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_gsi_with_billing_mode[PROVISIONED]": 0.32098216400027013, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_invalid_query_index": 0.06514302199957456, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_large_data_download": 0.35469851700008803, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_list_tags_of_resource": 0.0804153889994268, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_more_than_20_global_secondary_indexes": 0.18373203600003762, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_multiple_update_expressions": 0.1347740079995674, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_non_ascii_chars": 0.13263165700027457, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_nosql_workbench_localhost_region": 0.07289402399965184, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_query_on_deleted_resource": 0.13519505499971274, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_return_values_in_put_item": 0.11949022500039064, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_return_values_on_conditions_check_failure": 0.2235762930004057, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_stream_destination_records": 11.875390118999803, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_streams_on_global_tables": 1.2194378479998704, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_time_to_live": 0.23857906800049022, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_time_to_live_deletion": 0.41164486099978603, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_transact_get_items": 0.10089816400022755, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_transact_write_items_streaming": 1.2731577180006752, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_transact_write_items_streaming_for_different_tables": 1.1924018999998225, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_transaction_write_binary_data": 0.08746691499982262, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_transaction_write_canceled": 0.10035997100021632, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_transaction_write_items": 0.10124066400021547, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_valid_local_secondary_index": 0.12044929400008186, - "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_valid_query_index": 0.07351502400024401, - "tests/aws/services/dynamodbstreams/test_dynamodb_streams.py::TestDynamoDBStreams::test_enable_kinesis_streaming_destination": 0.0021923620006418787, - "tests/aws/services/dynamodbstreams/test_dynamodb_streams.py::TestDynamoDBStreams::test_non_existent_stream": 0.02157774499937659, - "tests/aws/services/dynamodbstreams/test_dynamodb_streams.py::TestDynamoDBStreams::test_stream_spec_and_region_replacement": 2.284901014999832, - "tests/aws/services/dynamodbstreams/test_dynamodb_streams.py::TestDynamoDBStreams::test_table_v2_stream": 1.5296037000002798, - "tests/aws/services/ec2/test_ec2.py::TestEc2FlowLogs::test_ec2_flow_logs_s3": 0.6261745950000659, - "tests/aws/services/ec2/test_ec2.py::TestEc2FlowLogs::test_ec2_flow_logs_s3_validation": 0.20289563699998325, - "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_create_route_table_association": 1.4424575839998397, - "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_create_security_group_with_custom_id[False-id_manager]": 0.0643671389998417, - "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_create_security_group_with_custom_id[False-tag]": 0.06609410300006857, - "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_create_security_group_with_custom_id[True-id_manager]": 0.054568017999827134, - "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_create_security_group_with_custom_id[True-tag]": 0.056784187000175734, - "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_create_subnet_with_custom_id": 0.055776436000087415, - "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_create_subnet_with_custom_id_and_vpc_id": 0.05558282899983169, - "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_create_subnet_with_tags": 0.046136478000335046, - "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_create_vpc_endpoint": 0.12393221499996798, - "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_create_vpc_with_custom_id": 0.04365278700061026, - "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_describe_vpc_endpoints_with_filter": 0.4085332259992356, - "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_describe_vpn_gateways_filter_by_vpc": 0.45407857400005014, - "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_get_security_groups_for_vpc": 0.32327668900006756, - "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_modify_launch_template[id]": 0.06806467800015525, - "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_modify_launch_template[name]": 0.052498016000299685, - "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_reserved_instance_api": 0.03173591499989925, - "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_vcp_peering_difference_regions": 1.1522469299998193, - "tests/aws/services/ec2/test_ec2.py::test_create_specific_vpc_id": 0.027142632000959566, - "tests/aws/services/ec2/test_ec2.py::test_describe_availability_zones_filter_with_zone_ids": 0.3183840209999289, - "tests/aws/services/ec2/test_ec2.py::test_describe_availability_zones_filter_with_zone_names": 0.31069076099993254, - "tests/aws/services/ec2/test_ec2.py::test_describe_availability_zones_filters": 0.3105533560005824, - "tests/aws/services/ec2/test_ec2.py::test_pickle_ec2_backend": 6.753004867000072, - "tests/aws/services/ec2/test_ec2.py::test_raise_create_volume_without_size": 0.01854568399994605, - "tests/aws/services/ec2/test_ec2.py::test_raise_duplicate_launch_template_name": 0.036855320000540814, - "tests/aws/services/ec2/test_ec2.py::test_raise_invalid_launch_template_name": 0.012870111000211182, - "tests/aws/services/ec2/test_ec2.py::test_raise_modify_to_invalid_default_version": 0.03441840100049376, - "tests/aws/services/ec2/test_ec2.py::test_raise_when_launch_template_data_missing": 0.014335335999930976, - "tests/aws/services/es/test_es.py::TestElasticsearchProvider::test_create_domain": 0.0017180360000565997, - "tests/aws/services/es/test_es.py::TestElasticsearchProvider::test_create_existing_domain_causes_exception": 0.0017167949999929988, - "tests/aws/services/es/test_es.py::TestElasticsearchProvider::test_describe_domains": 0.001966601000276569, - "tests/aws/services/es/test_es.py::TestElasticsearchProvider::test_domain_version": 0.0017161330001727038, - "tests/aws/services/es/test_es.py::TestElasticsearchProvider::test_get_compatible_version_for_domain": 0.001792185000340396, - "tests/aws/services/es/test_es.py::TestElasticsearchProvider::test_get_compatible_versions": 0.001757519999955548, - "tests/aws/services/es/test_es.py::TestElasticsearchProvider::test_list_versions": 0.0018160890003855457, - "tests/aws/services/es/test_es.py::TestElasticsearchProvider::test_path_endpoint_strategy": 0.003560866000043461, - "tests/aws/services/es/test_es.py::TestElasticsearchProvider::test_update_domain_config": 0.0018106989996340417, - "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeApiDestinations::test_api_destinations[auth0]": 0.10497536200000468, - "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeApiDestinations::test_api_destinations[auth1]": 0.09172505000015008, - "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeApiDestinations::test_api_destinations[auth2]": 0.09275838500025202, - "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeApiDestinations::test_create_api_destination_invalid_parameters": 0.014739471000211779, - "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeApiDestinations::test_create_api_destination_name_validation": 0.044317429999864544, - "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeConnections::test_connection_secrets[api-key]": 0.05362064100063435, - "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeConnections::test_connection_secrets[basic]": 0.05430716399996527, - "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeConnections::test_connection_secrets[oauth]": 0.054552220000005036, - "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeConnections::test_create_connection": 0.04780620800011093, - "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeConnections::test_create_connection_invalid_parameters": 0.014339193000523665, - "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeConnections::test_create_connection_name_validation": 0.014927361999980349, - "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeConnections::test_create_connection_with_auth[auth_params0]": 0.04642291699974521, - "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeConnections::test_create_connection_with_auth[auth_params1]": 0.04870649999975285, - "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeConnections::test_create_connection_with_auth[auth_params2]": 0.047930428000199754, - "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeConnections::test_delete_connection": 0.08697680500017668, - "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeConnections::test_list_connections": 0.04682411500016315, - "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeConnections::test_update_connection": 0.08871798900008798, - "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_create_archive_error_duplicate[custom]": 0.08656890800057226, - "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_create_archive_error_duplicate[default]": 0.06000677500014717, - "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_create_archive_error_unknown_event_bus": 0.014690129999962664, - "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_create_list_describe_update_delete_archive[custom]": 0.11999544499985859, - "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_create_list_describe_update_delete_archive[default]": 0.09399019500006034, - "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_delete_archive_error_unknown_archive": 0.015460305999567936, - "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_describe_archive_error_unknown_archive": 0.013643455000419635, - "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_list_archive_error_unknown_source_arn": 0.013840231999893149, - "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_list_archive_state_enabled[custom]": 0.08754905700016025, - "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_list_archive_state_enabled[default]": 0.06098668899994664, - "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_list_archive_with_events[False-custom]": 0.5490299370003413, - "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_list_archive_with_events[False-default]": 0.5190136659998643, - "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_list_archive_with_events[True-custom]": 0.5465816740002083, - "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_list_archive_with_events[True-default]": 0.5391682560002664, - "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_list_archive_with_name_prefix[custom]": 0.10474025299981804, - "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_list_archive_with_name_prefix[default]": 0.07315604899986283, - "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_list_archive_with_source_arn[custom]": 0.08801144299968655, - "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_list_archive_with_source_arn[default]": 0.05940677099988534, - "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_update_archive_error_unknown_archive": 0.001770274000136851, - "tests/aws/services/events/test_archive_and_replay.py::TestReplay::test_describe_replay_error_unknown_replay": 0.014375452999502158, - "tests/aws/services/events/test_archive_and_replay.py::TestReplay::test_list_replay_with_limit": 0.2105469480006832, - "tests/aws/services/events/test_archive_and_replay.py::TestReplay::test_list_replays_with_event_source_arn": 0.10008236999965447, - "tests/aws/services/events/test_archive_and_replay.py::TestReplay::test_list_replays_with_prefix": 0.1544209079997927, - "tests/aws/services/events/test_archive_and_replay.py::TestReplay::test_start_list_describe_canceled_replay[custom]": 0.0018586490004963707, - "tests/aws/services/events/test_archive_and_replay.py::TestReplay::test_start_list_describe_canceled_replay[default]": 0.0018564450006124389, - "tests/aws/services/events/test_archive_and_replay.py::TestReplay::test_start_replay_error_duplicate_different_archive": 0.11742461699986961, - "tests/aws/services/events/test_archive_and_replay.py::TestReplay::test_start_replay_error_duplicate_name_same_archive": 0.07102074700014782, - "tests/aws/services/events/test_archive_and_replay.py::TestReplay::test_start_replay_error_invalid_end_time[0]": 0.06306003099962254, - "tests/aws/services/events/test_archive_and_replay.py::TestReplay::test_start_replay_error_invalid_end_time[10]": 0.06310144499911985, - "tests/aws/services/events/test_archive_and_replay.py::TestReplay::test_start_replay_error_unknown_archive": 0.014163215000280616, - "tests/aws/services/events/test_archive_and_replay.py::TestReplay::test_start_replay_error_unknown_event_bus": 0.09424151799976244, - "tests/aws/services/events/test_archive_and_replay.py::TestReplay::tests_concurrency_error_too_many_active_replays": 0.0018376089997218514, - "tests/aws/services/events/test_events.py::TestEventBus::test_create_list_describe_delete_custom_event_buses[False-regions0]": 0.041058904999772494, - "tests/aws/services/events/test_events.py::TestEventBus::test_create_list_describe_delete_custom_event_buses[False-regions1]": 0.11359104000030129, - "tests/aws/services/events/test_events.py::TestEventBus::test_create_list_describe_delete_custom_event_buses[True-regions0]": 0.0439350619999459, - "tests/aws/services/events/test_events.py::TestEventBus::test_create_list_describe_delete_custom_event_buses[True-regions1]": 0.13147821900020062, - "tests/aws/services/events/test_events.py::TestEventBus::test_create_multiple_event_buses_same_name": 0.042483622999952786, - "tests/aws/services/events/test_events.py::TestEventBus::test_delete_default_event_bus": 0.013493736000327772, - "tests/aws/services/events/test_events.py::TestEventBus::test_describe_delete_not_existing_event_bus": 0.02241585799947643, - "tests/aws/services/events/test_events.py::TestEventBus::test_list_event_buses_with_limit": 0.2337072220002483, - "tests/aws/services/events/test_events.py::TestEventBus::test_list_event_buses_with_prefix": 0.08371832699958759, - "tests/aws/services/events/test_events.py::TestEventBus::test_put_events_bus_to_bus[domain]": 0.4679558650004765, - "tests/aws/services/events/test_events.py::TestEventBus::test_put_events_bus_to_bus[path]": 0.38720547500088287, - "tests/aws/services/events/test_events.py::TestEventBus::test_put_events_bus_to_bus[standard]": 0.42474314300034166, - "tests/aws/services/events/test_events.py::TestEventBus::test_put_events_nonexistent_event_bus": 0.1613012190000518, - "tests/aws/services/events/test_events.py::TestEventBus::test_put_events_to_default_eventbus_for_custom_eventbus": 1.1305221899997377, - "tests/aws/services/events/test_events.py::TestEventBus::test_put_permission[custom]": 0.2807020720001674, - "tests/aws/services/events/test_events.py::TestEventBus::test_put_permission[default]": 0.09424568200029171, - "tests/aws/services/events/test_events.py::TestEventBus::test_put_permission_non_existing_event_bus": 0.014297827999598667, - "tests/aws/services/events/test_events.py::TestEventBus::test_remove_permission[custom]": 0.08592664199977662, - "tests/aws/services/events/test_events.py::TestEventBus::test_remove_permission[default]": 0.06366937599977973, - "tests/aws/services/events/test_events.py::TestEventBus::test_remove_permission_non_existing_sid[False-custom]": 0.0443572630001654, - "tests/aws/services/events/test_events.py::TestEventBus::test_remove_permission_non_existing_sid[False-default]": 0.02382721199955995, - "tests/aws/services/events/test_events.py::TestEventBus::test_remove_permission_non_existing_sid[True-custom]": 0.0559759259999737, - "tests/aws/services/events/test_events.py::TestEventBus::test_remove_permission_non_existing_sid[True-default]": 0.03218266800013225, - "tests/aws/services/events/test_events.py::TestEventPattern::test_put_events_pattern_nested": 10.23310065699934, - "tests/aws/services/events/test_events.py::TestEventPattern::test_put_events_pattern_with_values_in_array": 5.2905671160001475, - "tests/aws/services/events/test_events.py::TestEventRule::test_delete_rule_with_targets": 0.06829100599998128, - "tests/aws/services/events/test_events.py::TestEventRule::test_describe_nonexistent_rule": 0.015559552000013355, - "tests/aws/services/events/test_events.py::TestEventRule::test_disable_re_enable_rule[custom]": 0.08714107599962517, - "tests/aws/services/events/test_events.py::TestEventRule::test_disable_re_enable_rule[default]": 0.05974590999994689, - "tests/aws/services/events/test_events.py::TestEventRule::test_list_rule_names_by_target[custom]": 0.21872128799986967, - "tests/aws/services/events/test_events.py::TestEventRule::test_list_rule_names_by_target[default]": 0.16141433800066807, - "tests/aws/services/events/test_events.py::TestEventRule::test_list_rule_names_by_target_no_matches[custom]": 0.12437036699975579, - "tests/aws/services/events/test_events.py::TestEventRule::test_list_rule_names_by_target_no_matches[default]": 0.09590354300007675, - "tests/aws/services/events/test_events.py::TestEventRule::test_list_rule_names_by_target_with_limit[custom]": 0.3012586889999511, - "tests/aws/services/events/test_events.py::TestEventRule::test_list_rule_names_by_target_with_limit[default]": 0.26739966099967205, - "tests/aws/services/events/test_events.py::TestEventRule::test_list_rule_with_limit": 0.21756955800037758, - "tests/aws/services/events/test_events.py::TestEventRule::test_process_pattern_to_single_matching_rules_single_target": 7.361631890999888, - "tests/aws/services/events/test_events.py::TestEventRule::test_process_to_multiple_matching_rules_different_targets": 0.5192189300000791, - "tests/aws/services/events/test_events.py::TestEventRule::test_process_to_multiple_matching_rules_single_target": 4.3265443200002665, - "tests/aws/services/events/test_events.py::TestEventRule::test_process_to_single_matching_rules_single_target": 10.438614465999763, - "tests/aws/services/events/test_events.py::TestEventRule::test_put_list_with_prefix_describe_delete_rule[custom]": 0.0823999090007419, - "tests/aws/services/events/test_events.py::TestEventRule::test_put_list_with_prefix_describe_delete_rule[default]": 0.056042330999844125, - "tests/aws/services/events/test_events.py::TestEventRule::test_put_multiple_rules_with_same_name": 0.07862212099962562, - "tests/aws/services/events/test_events.py::TestEventRule::test_update_rule_with_targets": 0.09162942299963106, - "tests/aws/services/events/test_events.py::TestEventTarget::test_add_exceed_fife_targets_per_rule": 0.09443016599971088, - "tests/aws/services/events/test_events.py::TestEventTarget::test_list_target_by_rule_limit": 0.141175540000404, - "tests/aws/services/events/test_events.py::TestEventTarget::test_put_list_remove_target[custom]": 0.11029364500018346, - "tests/aws/services/events/test_events.py::TestEventTarget::test_put_list_remove_target[default]": 0.07932587200048147, - "tests/aws/services/events/test_events.py::TestEventTarget::test_put_multiple_targets_with_same_arn_across_different_rules": 0.11062044599975707, - "tests/aws/services/events/test_events.py::TestEventTarget::test_put_multiple_targets_with_same_arn_single_rule": 0.07958796199955032, - "tests/aws/services/events/test_events.py::TestEventTarget::test_put_multiple_targets_with_same_id_across_different_rules": 0.1093770990005396, - "tests/aws/services/events/test_events.py::TestEventTarget::test_put_multiple_targets_with_same_id_single_rule": 0.07687321699995664, - "tests/aws/services/events/test_events.py::TestEventTarget::test_put_target_id_validation": 0.08936333799965723, - "tests/aws/services/events/test_events.py::TestEvents::test_create_connection_validations": 0.013928547999967122, - "tests/aws/services/events/test_events.py::TestEvents::test_events_written_to_disk_are_timestamp_prefixed_for_chronological_ordering": 0.0017446070000914915, - "tests/aws/services/events/test_events.py::TestEvents::test_put_event_malformed_detail[ARRAY]": 0.01445282499980749, - "tests/aws/services/events/test_events.py::TestEvents::test_put_event_malformed_detail[MALFORMED_JSON]": 0.01535081999918475, - "tests/aws/services/events/test_events.py::TestEvents::test_put_event_malformed_detail[SERIALIZED_STRING]": 0.014503579999654903, - "tests/aws/services/events/test_events.py::TestEvents::test_put_event_malformed_detail[STRING]": 0.015173661000517313, - "tests/aws/services/events/test_events.py::TestEvents::test_put_event_with_too_big_detail": 0.0189416639996125, - "tests/aws/services/events/test_events.py::TestEvents::test_put_event_without_detail": 0.013359425000089686, - "tests/aws/services/events/test_events.py::TestEvents::test_put_event_without_detail_type": 0.013376565000271512, - "tests/aws/services/events/test_events.py::TestEvents::test_put_events_exceed_limit_ten_entries[custom]": 0.0447677940005633, - "tests/aws/services/events/test_events.py::TestEvents::test_put_events_exceed_limit_ten_entries[default]": 0.016592216999924858, - "tests/aws/services/events/test_events.py::TestEvents::test_put_events_response_entries_order": 0.29709257099966635, - "tests/aws/services/events/test_events.py::TestEvents::test_put_events_time": 0.3087999519998448, - "tests/aws/services/events/test_events.py::TestEvents::test_put_events_with_target_delivery_failure": 1.1529659890002222, - "tests/aws/services/events/test_events.py::TestEvents::test_put_events_with_time_field": 0.19011642400027995, - "tests/aws/services/events/test_events.py::TestEvents::test_put_events_without_source": 0.013693557000351575, - "tests/aws/services/events/test_events_cross_account_region.py::TestEventsCrossAccountRegion::test_put_events[custom-account]": 0.154568842000117, - "tests/aws/services/events/test_events_cross_account_region.py::test_event_bus_to_event_bus_cross_account_region[custom-account]": 0.5313974360001339, - "tests/aws/services/events/test_events_cross_account_region.py::test_event_bus_to_event_bus_cross_account_region[custom-region]": 0.5293333190002159, - "tests/aws/services/events/test_events_cross_account_region.py::test_event_bus_to_event_bus_cross_account_region[custom-region_account]": 0.5935376539991921, - "tests/aws/services/events/test_events_cross_account_region.py::test_event_bus_to_event_bus_cross_account_region[default-account]": 0.6588710400005766, - "tests/aws/services/events/test_events_cross_account_region.py::test_event_bus_to_event_bus_cross_account_region[default-region]": 0.5707647809995251, - "tests/aws/services/events/test_events_cross_account_region.py::test_event_bus_to_event_bus_cross_account_region[default-region_account]": 0.5647931890002837, - "tests/aws/services/events/test_events_inputs.py::TestInputPath::test_put_events_with_input_path": 0.19062565200010795, - "tests/aws/services/events/test_events_inputs.py::TestInputPath::test_put_events_with_input_path_max_level_depth": 0.18728926299991144, - "tests/aws/services/events/test_events_inputs.py::TestInputPath::test_put_events_with_input_path_multiple_targets": 0.2904533500004618, - "tests/aws/services/events/test_events_inputs.py::TestInputPath::test_put_events_with_input_path_nested[event_detail0]": 0.18644244000006438, - "tests/aws/services/events/test_events_inputs.py::TestInputPath::test_put_events_with_input_path_nested[event_detail1]": 0.18782627599966872, - "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement[\" multiple list items\"]": 0.23253303399997094, - "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement[\" single list item multiple list items system account id payload user id\"]": 0.2891287659995214, - "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement[\" single list item\"]": 0.23068815000033283, - "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement[\"Payload of with path users-service/users/ and \"]": 0.23035630200047308, - "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement[{\"id\" : \"\"}]": 0.23625393800011807, - "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement[{\"id\" : }]": 0.22930544199971337, - "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement[{\"method\": \"PUT\", \"nested\": {\"level1\": {\"level2\": {\"level3\": \"users-service/users/\"} } }, \"bod\": \"\"}]": 0.22854297200001383, - "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement[{\"method\": \"PUT\", \"path\": \"users-service/users/\", \"bod\": }]": 0.22698753199983912, - "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement[{\"method\": \"PUT\", \"path\": \"users-service/users/\", \"bod\": [, \"hardcoded\"]}]": 0.23164883400022518, - "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement[{\"method\": \"PUT\", \"path\": \"users-service/users/\", \"id\": , \"body\": }]": 0.22737938499994925, - "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement[{\"multi_replacement\": \"users//second/\"}]": 0.262962398000127, - "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement[{\"singlelistitem\": }]": 0.2644530110001142, - "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement_not_valid[{\"not_valid\": \"users-service/users/\", \"bod\": }]": 5.151510896000218, - "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement_not_valid[{\"payload\": \"\"}]": 5.16533248199994, - "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement_not_valid[{\"singlelistitem\": \"\"}]": 5.160441324000203, - "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_predefined_variables[\"Message containing all pre defined variables \"]": 0.215058503000364, - "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_predefined_variables[{\"originalEvent\": , \"originalEventJson\": }]": 0.2300798230003238, - "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_put_events_with_input_transformer_input_template_json": 0.40584139500015226, - "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_put_events_with_input_transformer_input_template_string[\"Event of type, at time , info extracted from detail \"]": 0.4091627820002941, - "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_put_events_with_input_transformer_input_template_string[\"{[/Check with special starting characters for event of type\"]": 0.41758063400038736, - "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_put_events_with_input_transformer_missing_keys": 0.10544481099987024, - "tests/aws/services/events/test_events_inputs.py::test_put_event_input_path_and_input_transformer": 0.10090126600061922, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_array_event_payload": 0.024163090999962833, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[arrays]": 0.014366328000050999, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[arrays_NEG]": 0.0151099360000444, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[arrays_empty_EXC]": 0.0883018709996577, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[arrays_empty_null_NEG]": 0.014507431000311044, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[boolean]": 0.014003691000652907, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[boolean_NEG]": 0.018200722000074165, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[complex_many_rules]": 0.01509119100001044, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[complex_multi_match]": 0.01660753800024395, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[complex_multi_match_NEG]": 0.01576589399974182, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[complex_or]": 0.014712684000187437, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[complex_or_NEG]": 0.015046812999571557, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_ignorecase]": 0.014955588000248099, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_ignorecase_EXC]": 0.09441616100002648, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_ignorecase_NEG]": 0.014506498999708128, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_ignorecase_list]": 0.014255311999932019, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_ignorecase_list_EXC]": 0.09954963700010921, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_ignorecase_list_NEG]": 0.01459531499995137, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_number]": 0.017142863000572106, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_number_NEG]": 0.019750936000036745, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_number_list]": 0.014563537999947584, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_number_list_NEG]": 0.016350050999790255, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_number_zero]": 0.014620442999785155, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_string]": 0.014361530000314815, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_string_NEG]": 0.014473861000169563, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_string_list]": 0.015617373999702977, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_string_list_NEG]": 0.017018526999891037, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_string_null]": 0.016268472999854566, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_prefix]": 0.014246215000184748, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_prefix_NEG]": 0.015357249999851774, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_prefix_empty_EXC]": 0.09162877100015976, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_prefix_ignorecase_EXC]": 0.09029513899986341, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_prefix_int_EXC]": 0.08941883399938888, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_prefix_list]": 0.01632266799970239, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_prefix_list_NEG]": 0.014961357999254687, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_prefix_list_type_EXC]": 0.09603154299975358, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_suffix]": 0.01404967700045745, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_suffix_NEG]": 0.014552737000030902, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_suffix_empty_EXC]": 0.09075959800020428, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_suffix_ignorecase_EXC]": 0.09895774400001756, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_suffix_int_EXC]": 0.09087590099943554, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_suffix_list]": 0.014350929000556789, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_suffix_list_NEG]": 0.01438755500021216, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_suffix_list_type_EXC]": 0.08821051700033422, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_wildcard]": 0.015964863000590412, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_wildcard_NEG]": 0.014593642000363616, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_wildcard_empty]": 0.014877718999741774, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_wildcard_list]": 0.015403785000216885, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_wildcard_list_NEG]": 0.014523671000461036, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_wildcard_list_type_EXC]": 0.08891777799999545, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_wildcard_type_EXC]": 0.1005086389995995, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_exists]": 0.018940203999591176, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_exists_NEG]": 0.014712234999933571, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_exists_false]": 0.014818493000348099, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_exists_false_NEG]": 0.017383874999723048, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ignorecase]": 0.014360126000156015, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ignorecase_EXC]": 0.0904330060002394, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ignorecase_NEG]": 0.014466587000697473, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ignorecase_empty]": 0.014270400999976118, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ignorecase_empty_NEG]": 0.014511764999951993, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ignorecase_list_EXC]": 0.09074027899987414, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ip_address]": 0.014668252999854303, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ip_address_EXC]": 0.09324683600016215, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ip_address_NEG]": 0.01463065500047378, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ip_address_bad_ip_EXC]": 0.08950988300011886, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ip_address_bad_mask_EXC]": 0.09005268600003546, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ip_address_type_EXC]": 0.09098421299995607, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ip_address_v6]": 0.015589851000186172, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ip_address_v6_NEG]": 0.01508403800016822, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ip_address_v6_bad_ip_EXC]": 0.09354183200048283, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_numeric_EXC]": 0.09040531499977078, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_numeric_and]": 0.01520829999981288, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_numeric_and_NEG]": 0.014678198000183329, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_numeric_number_EXC]": 0.08982489799927862, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_numeric_operatorcasing_EXC]": 0.08962194199966689, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_numeric_syntax_EXC]": 0.0892361390001497, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_prefix]": 0.0148785190003764, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_prefix_NEG]": 0.014535805000377877, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_prefix_empty]": 0.014453622000019095, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_prefix_ignorecase]": 0.01476574000025721, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_prefix_int_EXC]": 0.08957038599919542, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_prefix_list_EXC]": 0.09717926100074692, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_suffix]": 0.017292940000061208, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_suffix_NEG]": 0.015598793999743066, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_suffix_empty]": 0.4864429810004367, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_suffix_ignorecase]": 0.014630471000145917, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_suffix_ignorecase_NEG]": 0.014445436999722006, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_suffix_int_EXC]": 0.09193720199982636, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_suffix_list_EXC]": 0.08950159399955737, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_wildcard_complex_EXC]": 0.09009113799947954, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_wildcard_empty_NEG]": 0.01447798800018063, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_wildcard_int_EXC]": 0.089753218000169, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_wildcard_list_EXC]": 0.08950578599979053, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_wildcard_nonrepeating]": 0.014594204000331956, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_wildcard_nonrepeating_NEG]": 0.015809605999947962, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_wildcard_repeating]": 0.014596408000215888, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_wildcard_repeating_NEG]": 0.014158491999751277, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_wildcard_repeating_star_EXC]": 0.08902763400010372, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_wildcard_simplified]": 0.014567866000106733, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[dot_joining_event]": 0.01830412699973749, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[dot_joining_event_NEG]": 0.014533519999531563, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[dot_joining_pattern]": 0.014424317999782943, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[dot_joining_pattern_NEG]": 0.014286480000464508, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[dynamodb]": 0.015795414999956847, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[exists_dynamodb]": 0.01439097499996933, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[exists_dynamodb_NEG]": 0.01471696399994471, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[exists_list_empty_NEG]": 0.014547034999395692, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[int_nolist_EXC]": 0.09011327200005326, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[key_case_sensitive_NEG]": 0.014654464999694028, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[list_within_dict]": 0.014604102000248531, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[minimal]": 0.014487335000467283, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[nested_json_NEG]": 0.014577422999082046, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[null_value]": 0.015336198999648332, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[null_value_NEG]": 0.015005141000074218, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[number_comparison_float]": 0.01454752700010431, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[numeric-int-float]": 0.014677869000479404, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[numeric-null_NEG]": 0.01464140200005204, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[numeric-string_NEG]": 0.014529282999774296, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[operator_case_sensitive_EXC]": 1.3203036390000307, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[operator_multiple_list]": 0.014457429000231059, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[or-anything-but]": 0.015076505000251927, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[or-exists-parent]": 0.01650718200016854, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[or-exists]": 0.01472511299971302, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[or-numeric-anything-but]": 0.015244353000070987, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[or-numeric-anything-but_NEG]": 0.01640343799999755, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[prefix]": 0.014789898999424622, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[sample1]": 0.014226488000076642, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[string]": 0.014969643999847904, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[string_empty]": 0.014602770000237797, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[string_nolist_EXC]": 0.09042796200083103, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern_source": 0.1926675950000174, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern_with_escape_characters": 0.023069314000025543, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern_with_multi_key": 0.5657805140000107, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_with_large_and_complex_payload": 0.048353817999981175, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_invalid_event_payload": 0.025385768000035114, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_invalid_json_event_pattern[[\"not\", \"a\", \"dict\", \"but valid json\"]]": 0.09987239899996325, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_invalid_json_event_pattern[this is valid json but not a dict]": 0.13852553500001363, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_invalid_json_event_pattern[{\"not\": closed mark\"]": 0.09962711399995783, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_invalid_json_event_pattern[{'bad': 'quotation'}]": 0.10898782900002857, - "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_plain_string_payload": 0.02502368000000388, - "tests/aws/services/events/test_events_patterns.py::TestRuleWithPattern::test_put_event_with_content_base_rule_in_pattern": 0.3600304810000239, - "tests/aws/services/events/test_events_patterns.py::TestRuleWithPattern::test_put_events_with_rule_pattern_anything_but": 5.926419674999977, - "tests/aws/services/events/test_events_patterns.py::TestRuleWithPattern::test_put_events_with_rule_pattern_exists_false": 5.399349487999984, - "tests/aws/services/events/test_events_patterns.py::TestRuleWithPattern::test_put_events_with_rule_pattern_exists_true": 5.281080843000012, - "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::test_schedule_cron_target_sqs": 0.0016724649999844132, - "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_invalid_schedule_cron[cron(0 1 * * * *)]": 0.013317363000027171, - "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_invalid_schedule_cron[cron(0 dummy ? * MON-FRI *)]": 0.013041198000024679, - "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_invalid_schedule_cron[cron(7 20 * * NOT *)]": 0.013944086999998717, - "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_invalid_schedule_cron[cron(71 8 1 * ? *)]": 0.012949215999981334, - "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_invalid_schedule_cron[cron(INVALID)]": 0.013403435000014952, - "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(* * ? * SAT#3 *)]": 0.0367952629999877, - "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0 10 * * ? *)]": 0.03588348100001326, - "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0 12 * * ? *)]": 0.03580996199997344, - "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0 18 ? * MON-FRI *)]": 0.035646597999999585, - "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0 2 ? * SAT *)]": 0.03633224699999005, - "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0 2 ? * SAT#3 *)]": 0.03661005799997952, - "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0 8 1 * ? *)]": 0.03553979699998422, - "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0/10 * ? * MON-FRI *)]": 0.0356632180000247, - "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0/15 * * * ? *)]": 0.03553851499998473, - "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0/30 0-2 ? * MON-FRI *)]": 0.03616909199999441, - "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0/30 20-23 ? * MON-FRI *)]": 0.03696543100002714, - "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0/5 5 ? JAN 1-5 2022)]": 0.03598665300003745, - "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0/5 8-17 ? * MON-FRI *)]": 0.03921749900001714, - "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(15 10 ? * 6L 2002-2005)]": 0.036535440000022845, - "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(15 12 * * ? *)]": 0.03544156399999565, - "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(5,35 14 * * ? *)]": 0.035832505999962905, - "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[ rate(10 minutes)]": 0.021905833999994684, - "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate( 10 minutes )]": 0.018352662000012288, - "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate()]": 0.018937344999983452, - "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(-10 minutes)]": 0.019241194000017003, - "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(0 minutes)]": 0.02163773499998456, - "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(1 days)]": 0.020529962000011892, - "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(1 hours)]": 0.01793091400000435, - "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(1 minutes)]": 0.019627125000027945, - "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(10 MINUTES)]": 0.042094459999987066, - "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(10 day)]": 0.016751596000005975, - "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(10 hour)]": 0.020734223999994583, - "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(10 minute)]": 0.036397849999985965, - "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(10 minutess)]": 0.021380859999965196, - "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(10 seconds)]": 0.018660197999963657, - "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(10 years)]": 0.015076919000023281, - "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(10)]": 0.018818713000001708, - "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(foo minutes)]": 0.0330008980000116, - "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_schedule_rate": 0.06742087999998603, - "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_scheduled_rule_logs": 0.0016907489999766767, - "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::tests_put_rule_with_schedule_custom_event_bus": 0.07864557599998534, - "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::tests_schedule_rate_custom_input_target_sqs": 60.200367938, - "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::tests_schedule_rate_target_sqs": 0.0028407709999953568, - "tests/aws/services/events/test_events_tags.py::TestEventBusTags::test_create_event_bus_with_tags": 0.04281578200001945, - "tests/aws/services/events/test_events_tags.py::TestEventBusTags::test_list_tags_for_deleted_event_bus": 0.035389196000011225, - "tests/aws/services/events/test_events_tags.py::TestRuleTags::test_list_tags_for_deleted_rule": 0.06261820700001408, - "tests/aws/services/events/test_events_tags.py::TestRuleTags::test_put_rule_with_tags": 0.0650481660000537, - "tests/aws/services/events/test_events_tags.py::test_recreate_tagged_resource_without_tags[event_bus-event_bus_custom]": 0.06747288599999024, - "tests/aws/services/events/test_events_tags.py::test_recreate_tagged_resource_without_tags[event_bus-event_bus_default]": 0.019651499000019612, - "tests/aws/services/events/test_events_tags.py::test_recreate_tagged_resource_without_tags[rule-event_bus_custom]": 0.09323643200002607, - "tests/aws/services/events/test_events_tags.py::test_recreate_tagged_resource_without_tags[rule-event_bus_default]": 0.06048868499999571, - "tests/aws/services/events/test_events_tags.py::tests_tag_list_untag_not_existing_resource[not_existing_event_bus]": 0.027392001999970716, - "tests/aws/services/events/test_events_tags.py::tests_tag_list_untag_not_existing_resource[not_existing_rule]": 0.028400630999982468, - "tests/aws/services/events/test_events_tags.py::tests_tag_untag_resource[event_bus-event_bus_custom]": 0.07042766700001835, - "tests/aws/services/events/test_events_tags.py::tests_tag_untag_resource[event_bus-event_bus_default]": 0.04449530999997364, - "tests/aws/services/events/test_events_tags.py::tests_tag_untag_resource[rule-event_bus_custom]": 0.09103599900001313, - "tests/aws/services/events/test_events_tags.py::tests_tag_untag_resource[rule-event_bus_default]": 0.06379281299999207, - "tests/aws/services/events/test_events_targets.py::TestEventsTargetApiDestination::test_put_events_to_target_api_destinations[auth0]": 0.21254704500000798, - "tests/aws/services/events/test_events_targets.py::TestEventsTargetApiDestination::test_put_events_to_target_api_destinations[auth1]": 0.10834632899999974, - "tests/aws/services/events/test_events_targets.py::TestEventsTargetApiDestination::test_put_events_to_target_api_destinations[auth2]": 0.11475955200000953, - "tests/aws/services/events/test_events_targets.py::TestEventsTargetApiGateway::test_put_events_with_target_api_gateway": 24.167259080000008, - "tests/aws/services/events/test_events_targets.py::TestEventsTargetCloudWatchLogs::test_put_events_with_target_cloudwatch_logs": 0.20370585999998525, - "tests/aws/services/events/test_events_targets.py::TestEventsTargetEvents::test_put_events_with_target_events[bus_combination0]": 0.320737658999974, - "tests/aws/services/events/test_events_targets.py::TestEventsTargetEvents::test_put_events_with_target_events[bus_combination1]": 0.34837638999999854, - "tests/aws/services/events/test_events_targets.py::TestEventsTargetEvents::test_put_events_with_target_events[bus_combination2]": 0.3235109530000102, - "tests/aws/services/events/test_events_targets.py::TestEventsTargetFirehose::test_put_events_with_target_firehose": 1.0781683589999602, - "tests/aws/services/events/test_events_targets.py::TestEventsTargetKinesis::test_put_events_with_target_kinesis": 2.3475366209999606, - "tests/aws/services/events/test_events_targets.py::TestEventsTargetLambda::test_put_events_with_target_lambda": 4.228319082000013, - "tests/aws/services/events/test_events_targets.py::TestEventsTargetLambda::test_put_events_with_target_lambda_list_entries_partial_match": 4.316509587000041, - "tests/aws/services/events/test_events_targets.py::TestEventsTargetLambda::test_put_events_with_target_lambda_list_entry": 4.274450865000006, - "tests/aws/services/events/test_events_targets.py::TestEventsTargetSns::test_put_events_with_target_sns[domain]": 0.2224870139999382, - "tests/aws/services/events/test_events_targets.py::TestEventsTargetSns::test_put_events_with_target_sns[path]": 0.23126015200000438, - "tests/aws/services/events/test_events_targets.py::TestEventsTargetSns::test_put_events_with_target_sns[standard]": 0.5043940230000317, - "tests/aws/services/events/test_events_targets.py::TestEventsTargetSqs::test_put_events_with_target_sqs": 0.17410735500001806, - "tests/aws/services/events/test_events_targets.py::TestEventsTargetSqs::test_put_events_with_target_sqs_event_detail_match": 5.219334032000006, - "tests/aws/services/events/test_events_targets.py::TestEventsTargetStepFunctions::test_put_events_with_target_statefunction_machine": 4.301268860999983, - "tests/aws/services/events/test_x_ray_trace_propagation.py::test_xray_trace_propagation_events_api_gateway": 5.782144335999988, - "tests/aws/services/events/test_x_ray_trace_propagation.py::test_xray_trace_propagation_events_events[bus_combination0]": 4.432974792000039, - "tests/aws/services/events/test_x_ray_trace_propagation.py::test_xray_trace_propagation_events_events[bus_combination1]": 4.465967387999967, - "tests/aws/services/events/test_x_ray_trace_propagation.py::test_xray_trace_propagation_events_events[bus_combination2]": 4.429581522000035, - "tests/aws/services/events/test_x_ray_trace_propagation.py::test_xray_trace_propagation_events_lambda": 4.245061544000009, - "tests/aws/services/firehose/test_firehose.py::TestFirehoseIntegration::test_kinesis_firehose_elasticsearch_s3_backup": 0.001859577000061563, - "tests/aws/services/firehose/test_firehose.py::TestFirehoseIntegration::test_kinesis_firehose_kinesis_as_source": 37.31791386800006, - "tests/aws/services/firehose/test_firehose.py::TestFirehoseIntegration::test_kinesis_firehose_kinesis_as_source_multiple_delivery_streams": 68.78578922000003, - "tests/aws/services/firehose/test_firehose.py::TestFirehoseIntegration::test_kinesis_firehose_opensearch_s3_backup[domain]": 0.0017180130000156169, - "tests/aws/services/firehose/test_firehose.py::TestFirehoseIntegration::test_kinesis_firehose_opensearch_s3_backup[path]": 0.0017173510000247916, - "tests/aws/services/firehose/test_firehose.py::TestFirehoseIntegration::test_kinesis_firehose_opensearch_s3_backup[port]": 0.0017864300000383082, - "tests/aws/services/firehose/test_firehose.py::TestFirehoseIntegration::test_kinesis_firehose_s3_as_destination_with_file_extension": 1.2255300639999973, - "tests/aws/services/firehose/test_firehose.py::test_kinesis_firehose_http[False]": 0.07193922099992278, - "tests/aws/services/firehose/test_firehose.py::test_kinesis_firehose_http[True]": 1.5787196120001, - "tests/aws/services/iam/test_iam.py::TestIAMExtensions::test_create_role_with_malformed_assume_role_policy_document": 0.01908091799992917, - "tests/aws/services/iam/test_iam.py::TestIAMExtensions::test_create_user_add_permission_boundary_afterwards": 0.1091912630000138, - "tests/aws/services/iam/test_iam.py::TestIAMExtensions::test_create_user_with_permission_boundary": 0.1019029330000194, - "tests/aws/services/iam/test_iam.py::TestIAMExtensions::test_get_user_without_username_as_role": 0.16335394100002532, - "tests/aws/services/iam/test_iam.py::TestIAMExtensions::test_get_user_without_username_as_root": 0.04053984199998695, - "tests/aws/services/iam/test_iam.py::TestIAMExtensions::test_get_user_without_username_as_user": 0.22668798600005857, - "tests/aws/services/iam/test_iam.py::TestIAMExtensions::test_role_with_path_lifecycle": 0.13767578900007038, - "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_attach_detach_role_policy": 0.13019357500002116, - "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_attach_iam_role_to_new_iam_user": 0.09810707999992019, - "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_create_describe_role": 0.15578965299999936, - "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_create_role_with_assume_role_policy": 0.26821167099996046, - "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_create_user_with_tags": 0.030298220000020137, - "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_delete_non_existent_policy_returns_no_such_entity": 0.014730707999945025, - "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_instance_profile_tags": 0.1795794550000096, - "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_list_roles_with_permission_boundary": 0.14082706799996458, - "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_recreate_iam_role": 0.10532210399998121, - "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_role_attach_policy": 0.3854157429999532, - "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_service_linked_role_name_should_match_aws[ecs.amazonaws.com-AWSServiceRoleForECS]": 0.0018936910000206808, - "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_service_linked_role_name_should_match_aws[eks.amazonaws.com-AWSServiceRoleForAmazonEKS]": 0.001711490999923626, - "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_simulate_principle_policy[group]": 0.19148357299997087, - "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_simulate_principle_policy[role]": 0.2657201519999717, - "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_simulate_principle_policy[user]": 0.22818100600005664, - "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_update_assume_role_policy": 0.08320352599997705, - "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_user_attach_policy": 0.35281626099998675, - "tests/aws/services/iam/test_iam.py::TestIAMPolicyEncoding::test_put_group_policy_encoding": 0.06450350499994784, - "tests/aws/services/iam/test_iam.py::TestIAMPolicyEncoding::test_put_role_policy_encoding": 0.19202468800006045, - "tests/aws/services/iam/test_iam.py::TestIAMPolicyEncoding::test_put_user_policy_encoding": 0.09203308399997923, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_already_exists": 0.03146810000004052, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_deletion": 8.185213659999988, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[accountdiscovery.ssm.amazonaws.com]": 0.2503151570000455, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[acm.amazonaws.com]": 0.24826324800000066, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[appmesh.amazonaws.com]": 0.25143184699993526, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[autoscaling-plans.amazonaws.com]": 0.25113668599993844, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[autoscaling.amazonaws.com]": 0.24329662100001315, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[backup.amazonaws.com]": 0.24825244400000201, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[batch.amazonaws.com]": 0.2538547659999608, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[cassandra.application-autoscaling.amazonaws.com]": 0.24560335400002486, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[cks.kms.amazonaws.com]": 0.2529298829999789, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[cloudtrail.amazonaws.com]": 0.24672017000000324, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[codestar-notifications.amazonaws.com]": 0.2488984720000076, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[config.amazonaws.com]": 0.2505461739999646, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[connect.amazonaws.com]": 0.24960557499991864, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[dms-fleet-advisor.amazonaws.com]": 0.25124973900000214, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[dms.amazonaws.com]": 0.2500574430000029, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[docdb-elastic.amazonaws.com]": 0.24541355500002737, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[ec2-instance-connect.amazonaws.com]": 0.2460029650000024, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[ec2.application-autoscaling.amazonaws.com]": 0.2468373069999643, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[ecr.amazonaws.com]": 0.24660436199997093, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[ecs.amazonaws.com]": 0.25588165099992466, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[eks-connector.amazonaws.com]": 0.26263512799999944, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[eks-fargate.amazonaws.com]": 0.25252039499997636, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[eks-nodegroup.amazonaws.com]": 0.250703996000027, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[eks.amazonaws.com]": 0.2463002430000074, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[elasticache.amazonaws.com]": 0.24749133299997084, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[elasticbeanstalk.amazonaws.com]": 0.24774551900003416, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[elasticfilesystem.amazonaws.com]": 0.24729713599998604, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[elasticloadbalancing.amazonaws.com]": 0.2511354310000229, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[email.cognito-idp.amazonaws.com]": 0.24491904500001738, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[emr-containers.amazonaws.com]": 0.2483637290000047, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[emrwal.amazonaws.com]": 0.2535895820000178, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[fis.amazonaws.com]": 0.24476532300002418, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[grafana.amazonaws.com]": 0.9849745239999947, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[imagebuilder.amazonaws.com]": 0.24767623800005367, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[iotmanagedintegrations.amazonaws.com]": 0.3210199620000367, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[kafka.amazonaws.com]": 0.24990994300003422, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[kafkaconnect.amazonaws.com]": 0.2516197950000105, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[lakeformation.amazonaws.com]": 0.2532271979999905, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[lex.amazonaws.com]": 0.32130032999992864, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[lexv2.amazonaws.com]": 0.24943478900001992, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[lightsail.amazonaws.com]": 0.24866275200002974, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[m2.amazonaws.com]": 0.25177049100000204, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[memorydb.amazonaws.com]": 0.2533998669999846, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[mq.amazonaws.com]": 0.2511052829999585, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[mrk.kms.amazonaws.com]": 0.24900876800001015, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[notifications.amazonaws.com]": 0.2512501570000154, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[observability.aoss.amazonaws.com]": 0.2590940570000271, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[opensearchservice.amazonaws.com]": 0.24787942299991528, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[ops.apigateway.amazonaws.com]": 0.25255256299999473, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[ops.emr-serverless.amazonaws.com]": 0.2523570970000151, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[opsdatasync.ssm.amazonaws.com]": 0.2511042909999901, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[opsinsights.ssm.amazonaws.com]": 0.2490185259999862, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[pullthroughcache.ecr.amazonaws.com]": 0.2482416710000166, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[ram.amazonaws.com]": 0.24693440599997984, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[rds.amazonaws.com]": 0.2588130089999936, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[redshift.amazonaws.com]": 0.2542601660000514, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[replication.cassandra.amazonaws.com]": 0.2545088280000414, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[replication.ecr.amazonaws.com]": 0.25897045600004276, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[repository.sync.codeconnections.amazonaws.com]": 0.27914542299998857, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[resource-explorer-2.amazonaws.com]": 0.2599244529999396, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[rolesanywhere.amazonaws.com]": 0.2523633899999709, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[s3-outposts.amazonaws.com]": 0.25398562499998434, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[ses.amazonaws.com]": 0.2605283490000829, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[shield.amazonaws.com]": 0.2504347550000716, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[ssm-incidents.amazonaws.com]": 0.2511386610000841, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[ssm-quicksetup.amazonaws.com]": 0.25504782199999454, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[ssm.amazonaws.com]": 0.2507565669999394, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[sso.amazonaws.com]": 0.2513790909999898, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[vpcorigin.cloudfront.amazonaws.com]": 0.2491454529999828, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[waf.amazonaws.com]": 0.25117880799990644, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[wafv2.amazonaws.com]": 0.25279129100005093, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix[autoscaling.amazonaws.com]": 0.09972745700002861, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix[connect.amazonaws.com]": 0.09943000700002358, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix[lexv2.amazonaws.com]": 0.09926826199995276, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[accountdiscovery.ssm.amazonaws.com]": 0.015672055000038654, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[acm.amazonaws.com]": 0.015390606999972078, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[appmesh.amazonaws.com]": 0.015015048000009301, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[autoscaling-plans.amazonaws.com]": 0.014573630999962006, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[backup.amazonaws.com]": 0.015678739000009045, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[batch.amazonaws.com]": 0.015273754000077133, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[cassandra.application-autoscaling.amazonaws.com]": 0.015609188999974322, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[cks.kms.amazonaws.com]": 0.014976123999986157, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[cloudtrail.amazonaws.com]": 0.014931561000025795, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[codestar-notifications.amazonaws.com]": 0.014890413999978591, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[config.amazonaws.com]": 0.015052108000020326, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[dms-fleet-advisor.amazonaws.com]": 0.014964502000054836, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[dms.amazonaws.com]": 0.015224176999993233, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[docdb-elastic.amazonaws.com]": 0.0147535969999808, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[ec2-instance-connect.amazonaws.com]": 0.01575034299997924, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[ec2.application-autoscaling.amazonaws.com]": 0.01457196999996313, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[ecr.amazonaws.com]": 0.015176085999996758, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[ecs.amazonaws.com]": 0.01565656799999715, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[eks-connector.amazonaws.com]": 0.014800042999979723, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[eks-fargate.amazonaws.com]": 0.014543751999951837, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[eks-nodegroup.amazonaws.com]": 0.01872053700003562, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[eks.amazonaws.com]": 0.015366405000008854, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[elasticache.amazonaws.com]": 0.014820551999946474, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[elasticbeanstalk.amazonaws.com]": 0.01513644400006342, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[elasticfilesystem.amazonaws.com]": 0.014867078999941441, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[elasticloadbalancing.amazonaws.com]": 0.015028170999983104, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[email.cognito-idp.amazonaws.com]": 0.01489119600006461, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[emr-containers.amazonaws.com]": 0.01463460800005123, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[emrwal.amazonaws.com]": 0.014460800999984258, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[fis.amazonaws.com]": 0.014850252999963232, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[grafana.amazonaws.com]": 0.015608948999954464, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[imagebuilder.amazonaws.com]": 0.01567979899994043, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[iotmanagedintegrations.amazonaws.com]": 0.016285100000004604, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[kafka.amazonaws.com]": 0.016921149999973295, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[kafkaconnect.amazonaws.com]": 0.0147939839999367, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[lakeformation.amazonaws.com]": 0.01619699800005492, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[lex.amazonaws.com]": 0.014613504999999805, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[lightsail.amazonaws.com]": 0.016529978999926698, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[m2.amazonaws.com]": 0.01672951199992667, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[memorydb.amazonaws.com]": 0.015849497000033352, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[mq.amazonaws.com]": 0.01488383899999235, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[mrk.kms.amazonaws.com]": 0.01506386700003759, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[notifications.amazonaws.com]": 0.014825512000015806, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[observability.aoss.amazonaws.com]": 0.015109153000025799, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[opensearchservice.amazonaws.com]": 0.015986723000082748, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[ops.apigateway.amazonaws.com]": 0.015186040000003231, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[ops.emr-serverless.amazonaws.com]": 0.015306652000049326, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[opsdatasync.ssm.amazonaws.com]": 0.015226611999992201, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[opsinsights.ssm.amazonaws.com]": 0.017403544999979204, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[pullthroughcache.ecr.amazonaws.com]": 0.015247772000009263, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[ram.amazonaws.com]": 0.015155189000040536, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[rds.amazonaws.com]": 0.0164425629999414, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[redshift.amazonaws.com]": 0.014593929999989541, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[replication.cassandra.amazonaws.com]": 0.015560126999901058, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[replication.ecr.amazonaws.com]": 0.015098052000041662, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[repository.sync.codeconnections.amazonaws.com]": 0.014964693000024454, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[resource-explorer-2.amazonaws.com]": 0.014934847999938938, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[rolesanywhere.amazonaws.com]": 0.014645407000045907, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[s3-outposts.amazonaws.com]": 0.014840410999966025, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[ses.amazonaws.com]": 0.01559427800003732, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[shield.amazonaws.com]": 0.015449418000002879, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[ssm-incidents.amazonaws.com]": 0.01478175300002249, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[ssm-quicksetup.amazonaws.com]": 0.014619625000023007, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[ssm.amazonaws.com]": 0.015304750999916905, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[sso.amazonaws.com]": 0.015551802000061343, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[vpcorigin.cloudfront.amazonaws.com]": 0.015150870999946164, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[waf.amazonaws.com]": 0.014506033000031948, - "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[wafv2.amazonaws.com]": 0.014900775999990401, - "tests/aws/services/iam/test_iam.py::TestIAMServiceSpecificCredentials::test_create_service_specific_credential_invalid_service": 0.07945431500002087, - "tests/aws/services/iam/test_iam.py::TestIAMServiceSpecificCredentials::test_create_service_specific_credential_invalid_user": 0.0240474879998942, - "tests/aws/services/iam/test_iam.py::TestIAMServiceSpecificCredentials::test_delete_user_after_service_credential_created": 0.07808046999997487, - "tests/aws/services/iam/test_iam.py::TestIAMServiceSpecificCredentials::test_id_match_user_mismatch": 0.09510834000002433, - "tests/aws/services/iam/test_iam.py::TestIAMServiceSpecificCredentials::test_invalid_update_parameters": 0.08102366799994343, - "tests/aws/services/iam/test_iam.py::TestIAMServiceSpecificCredentials::test_list_service_specific_credential_different_service": 0.07782901699994227, - "tests/aws/services/iam/test_iam.py::TestIAMServiceSpecificCredentials::test_service_specific_credential_lifecycle[cassandra.amazonaws.com]": 0.10360224399994422, - "tests/aws/services/iam/test_iam.py::TestIAMServiceSpecificCredentials::test_service_specific_credential_lifecycle[codecommit.amazonaws.com]": 0.11067704699996739, - "tests/aws/services/iam/test_iam.py::TestIAMServiceSpecificCredentials::test_user_match_id_mismatch[satisfiesregexbutstillinvalid]": 0.09622222500001953, - "tests/aws/services/iam/test_iam.py::TestIAMServiceSpecificCredentials::test_user_match_id_mismatch[totally-wrong-credential-id-with-hyphens]": 0.09377804599989759, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_add_tags_to_stream": 0.6752841809999381, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_cbor_blob_handling": 0.6632380830000102, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_create_stream_without_shard_count": 0.6681083039999862, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_create_stream_without_stream_name_raises": 0.03939180400004716, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_get_records": 0.7486135160000345, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_get_records_empty_stream": 0.660961430000043, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_get_records_next_shard_iterator": 0.6695270460000415, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_get_records_shard_iterator_with_surrounding_quotes": 0.6669586800000502, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_record_lifecycle_data_integrity": 0.8726582599999801, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_stream_consumers": 1.3228941919999784, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_subscribe_to_shard": 4.5397800560000405, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_subscribe_to_shard_cbor_at_timestamp": 4.345565760999989, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_subscribe_to_shard_timeout": 6.304834170999982, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_subscribe_to_shard_with_at_timestamp": 4.517233273000045, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_subscribe_to_shard_with_at_timestamp_cbor": 0.6462730840000859, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_subscribe_to_shard_with_sequence_number_as_iterator": 4.583152622, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesisJavaSDK::test_subscribe_to_shard_with_java_sdk_v2_lambda": 9.602098788999967, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_add_tags_to_stream": 0.6603676790000463, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_cbor_blob_handling": 0.6641956660000119, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_create_stream_without_shard_count": 0.6537117530000387, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_create_stream_without_stream_name_raises": 0.04420862000000625, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_get_records": 0.7233153559999437, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_get_records_empty_stream": 0.6639757489999738, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_get_records_next_shard_iterator": 0.6733806220000247, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_get_records_shard_iterator_with_surrounding_quotes": 0.671002165999937, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_record_lifecycle_data_integrity": 0.9045747150000238, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_stream_consumers": 1.2881085079999366, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_subscribe_to_shard": 4.464565977999996, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_subscribe_to_shard_cbor_at_timestamp": 1.3078095669999925, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_subscribe_to_shard_timeout": 6.3155584989999625, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_subscribe_to_shard_with_at_timestamp": 4.468366357999969, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_subscribe_to_shard_with_at_timestamp_cbor": 0.6353966270000342, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_subscribe_to_shard_with_sequence_number_as_iterator": 4.471479870000053, - "tests/aws/services/kinesis/test_kinesis.py::TestKinesisPythonClient::test_run_kcl": 21.198555870000007, - "tests/aws/services/kms/test_kms.py::TestKMS::test_all_types_of_key_id_can_be_used_for_encryption": 0.06882434000010562, - "tests/aws/services/kms/test_kms.py::TestKMS::test_cant_delete_deleted_key": 0.033398734999991575, - "tests/aws/services/kms/test_kms.py::TestKMS::test_cant_use_disabled_or_deleted_keys": 0.0532975119999719, - "tests/aws/services/kms/test_kms.py::TestKMS::test_create_alias": 0.21628013199995166, - "tests/aws/services/kms/test_kms.py::TestKMS::test_create_custom_key_asymmetric": 0.03718806799986396, - "tests/aws/services/kms/test_kms.py::TestKMS::test_create_grant_with_invalid_key": 0.0234872800000403, - "tests/aws/services/kms/test_kms.py::TestKMS::test_create_grant_with_same_name_two_keys": 0.06173549199979789, - "tests/aws/services/kms/test_kms.py::TestKMS::test_create_grant_with_valid_key": 0.04165101300020524, - "tests/aws/services/kms/test_kms.py::TestKMS::test_create_key": 0.13529521300006309, - "tests/aws/services/kms/test_kms.py::TestKMS::test_create_key_custom_id": 0.02653041599990047, - "tests/aws/services/kms/test_kms.py::TestKMS::test_create_key_custom_key_material_hmac": 0.03497891800009256, - "tests/aws/services/kms/test_kms.py::TestKMS::test_create_key_custom_key_material_symmetric_decrypt": 0.02917435300003035, - "tests/aws/services/kms/test_kms.py::TestKMS::test_create_key_with_invalid_tag_key[lowercase_prefix]": 0.08731881000005615, - "tests/aws/services/kms/test_kms.py::TestKMS::test_create_key_with_invalid_tag_key[too_long_key]": 0.08721343999991404, - "tests/aws/services/kms/test_kms.py::TestKMS::test_create_key_with_invalid_tag_key[uppercase_prefix]": 0.08816220300002442, - "tests/aws/services/kms/test_kms.py::TestKMS::test_create_key_with_tag_and_untag": 0.15710906999981944, - "tests/aws/services/kms/test_kms.py::TestKMS::test_create_key_with_too_many_tags_raises_error": 0.09089254000002711, - "tests/aws/services/kms/test_kms.py::TestKMS::test_create_list_delete_alias": 0.06014152600005218, - "tests/aws/services/kms/test_kms.py::TestKMS::test_create_multi_region_key": 0.1729672330000085, - "tests/aws/services/kms/test_kms.py::TestKMS::test_derive_shared_secret": 0.20512131800012412, - "tests/aws/services/kms/test_kms.py::TestKMS::test_describe_and_list_sign_key": 0.04224582299991653, - "tests/aws/services/kms/test_kms.py::TestKMS::test_disable_and_enable_key": 0.055155246000026636, - "tests/aws/services/kms/test_kms.py::TestKMS::test_encrypt_decrypt[RSA_2048-RSAES_OAEP_SHA_256]": 0.10684238599992568, - "tests/aws/services/kms/test_kms.py::TestKMS::test_encrypt_decrypt[SYMMETRIC_DEFAULT-SYMMETRIC_DEFAULT]": 0.03326282900013666, - "tests/aws/services/kms/test_kms.py::TestKMS::test_encrypt_decrypt_encryption_context": 0.192759780000074, - "tests/aws/services/kms/test_kms.py::TestKMS::test_encrypt_validate_plaintext_size_per_key_type[RSA_2048-RSAES_OAEP_SHA_1]": 0.18369019700014633, - "tests/aws/services/kms/test_kms.py::TestKMS::test_encrypt_validate_plaintext_size_per_key_type[RSA_2048-RSAES_OAEP_SHA_256]": 0.13942732999998952, - "tests/aws/services/kms/test_kms.py::TestKMS::test_encrypt_validate_plaintext_size_per_key_type[RSA_3072-RSAES_OAEP_SHA_1]": 0.14611602899992704, - "tests/aws/services/kms/test_kms.py::TestKMS::test_encrypt_validate_plaintext_size_per_key_type[RSA_3072-RSAES_OAEP_SHA_256]": 0.2567056150001008, - "tests/aws/services/kms/test_kms.py::TestKMS::test_encrypt_validate_plaintext_size_per_key_type[RSA_4096-RSAES_OAEP_SHA_1]": 0.3409618790000195, - "tests/aws/services/kms/test_kms.py::TestKMS::test_encrypt_validate_plaintext_size_per_key_type[RSA_4096-RSAES_OAEP_SHA_256]": 0.2962016170000652, - "tests/aws/services/kms/test_kms.py::TestKMS::test_error_messaging_for_invalid_keys": 0.1956505540000535, - "tests/aws/services/kms/test_kms.py::TestKMS::test_generate_and_verify_mac[HMAC_224-HMAC_SHA_224]": 0.12264651800001047, - "tests/aws/services/kms/test_kms.py::TestKMS::test_generate_and_verify_mac[HMAC_256-HMAC_SHA_256]": 0.12527270099997168, - "tests/aws/services/kms/test_kms.py::TestKMS::test_generate_and_verify_mac[HMAC_384-HMAC_SHA_384]": 0.12465172199983954, - "tests/aws/services/kms/test_kms.py::TestKMS::test_generate_and_verify_mac[HMAC_512-HMAC_SHA_512]": 0.12703361599994878, - "tests/aws/services/kms/test_kms.py::TestKMS::test_generate_random[1024]": 0.08568717500008916, - "tests/aws/services/kms/test_kms.py::TestKMS::test_generate_random[12]": 0.0868620529998907, - "tests/aws/services/kms/test_kms.py::TestKMS::test_generate_random[1]": 0.08640832499986573, - "tests/aws/services/kms/test_kms.py::TestKMS::test_generate_random[44]": 0.08461749299988242, - "tests/aws/services/kms/test_kms.py::TestKMS::test_generate_random[91]": 0.08601101200008543, - "tests/aws/services/kms/test_kms.py::TestKMS::test_generate_random_invalid_number_of_bytes[0]": 0.08707461099993452, - "tests/aws/services/kms/test_kms.py::TestKMS::test_generate_random_invalid_number_of_bytes[1025]": 0.0865907260001677, - "tests/aws/services/kms/test_kms.py::TestKMS::test_generate_random_invalid_number_of_bytes[None]": 0.09500209800012271, - "tests/aws/services/kms/test_kms.py::TestKMS::test_get_key_does_not_exist": 0.11944896300008168, - "tests/aws/services/kms/test_kms.py::TestKMS::test_get_key_in_different_region": 0.13502488299991455, - "tests/aws/services/kms/test_kms.py::TestKMS::test_get_key_invalid_uuid": 0.8772165550000182, - "tests/aws/services/kms/test_kms.py::TestKMS::test_get_parameters_for_import": 0.5383217609999065, - "tests/aws/services/kms/test_kms.py::TestKMS::test_get_public_key": 0.07742839999991702, - "tests/aws/services/kms/test_kms.py::TestKMS::test_get_put_list_key_policies": 0.04767327499996554, - "tests/aws/services/kms/test_kms.py::TestKMS::test_hmac_create_key": 0.11864194800000405, - "tests/aws/services/kms/test_kms.py::TestKMS::test_hmac_create_key_invalid_operations": 0.10198916100000588, - "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_asymmetric": 0.2486944610000137, - "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_symmetric": 0.33896871800016015, - "tests/aws/services/kms/test_kms.py::TestKMS::test_invalid_generate_mac[HMAC_224-HMAC_SHA_256]": 0.10179681199997503, - "tests/aws/services/kms/test_kms.py::TestKMS::test_invalid_generate_mac[HMAC_256-INVALID]": 0.10167004400000224, - "tests/aws/services/kms/test_kms.py::TestKMS::test_invalid_key_usage": 0.6011124310000469, - "tests/aws/services/kms/test_kms.py::TestKMS::test_invalid_verify_mac[HMAC_256-HMAC_SHA_256-some different important message]": 0.1821894339999517, - "tests/aws/services/kms/test_kms.py::TestKMS::test_invalid_verify_mac[HMAC_256-HMAC_SHA_512-some important message]": 0.1830470539999851, - "tests/aws/services/kms/test_kms.py::TestKMS::test_invalid_verify_mac[HMAC_256-INVALID-some important message]": 0.1807466679999834, - "tests/aws/services/kms/test_kms.py::TestKMS::test_key_enable_rotation_status[180]": 0.10810678399991502, - "tests/aws/services/kms/test_kms.py::TestKMS::test_key_enable_rotation_status[90]": 0.10811265100005585, - "tests/aws/services/kms/test_kms.py::TestKMS::test_key_rotation_status": 0.05635859099993468, - "tests/aws/services/kms/test_kms.py::TestKMS::test_key_rotations_encryption_decryption": 0.1308526500000653, - "tests/aws/services/kms/test_kms.py::TestKMS::test_key_rotations_limits": 0.226590943999895, - "tests/aws/services/kms/test_kms.py::TestKMS::test_key_with_long_tag_value_raises_error": 0.08871406700006901, - "tests/aws/services/kms/test_kms.py::TestKMS::test_list_aliases_of_key": 0.0651076159999775, - "tests/aws/services/kms/test_kms.py::TestKMS::test_list_grants_with_invalid_key": 0.013692503000015677, - "tests/aws/services/kms/test_kms.py::TestKMS::test_list_keys": 0.028060510999921462, - "tests/aws/services/kms/test_kms.py::TestKMS::test_list_retirable_grants": 0.06852108099985799, - "tests/aws/services/kms/test_kms.py::TestKMS::test_non_multi_region_keys_should_not_have_multi_region_properties": 0.1693470589999606, - "tests/aws/services/kms/test_kms.py::TestKMS::test_plaintext_size_for_encrypt": 0.10044427100001485, - "tests/aws/services/kms/test_kms.py::TestKMS::test_replicate_key": 0.5171905270000252, - "tests/aws/services/kms/test_kms.py::TestKMS::test_retire_grant_with_grant_id_and_key_id": 0.05559706200006076, - "tests/aws/services/kms/test_kms.py::TestKMS::test_retire_grant_with_grant_token": 0.05700450400001955, - "tests/aws/services/kms/test_kms.py::TestKMS::test_revoke_grant": 0.0570737669997925, - "tests/aws/services/kms/test_kms.py::TestKMS::test_rotate_key_on_demand_modifies_key_material": 0.11398178799993275, - "tests/aws/services/kms/test_kms.py::TestKMS::test_rotate_key_on_demand_raises_error_given_key_is_disabled": 0.6874510360000841, - "tests/aws/services/kms/test_kms.py::TestKMS::test_rotate_key_on_demand_raises_error_given_key_that_does_not_exist": 0.08736365599997953, - "tests/aws/services/kms/test_kms.py::TestKMS::test_rotate_key_on_demand_raises_error_given_key_with_imported_key_material": 0.10144614499995441, - "tests/aws/services/kms/test_kms.py::TestKMS::test_rotate_key_on_demand_raises_error_given_non_symmetric_key": 0.562883392000117, - "tests/aws/services/kms/test_kms.py::TestKMS::test_rotate_key_on_demand_with_symmetric_key_and_automatic_rotation_disabled": 0.11789540500001294, - "tests/aws/services/kms/test_kms.py::TestKMS::test_rotate_key_on_demand_with_symmetric_key_and_automatic_rotation_enabled": 0.13391452400003345, - "tests/aws/services/kms/test_kms.py::TestKMS::test_schedule_and_cancel_key_deletion": 0.04717978100006803, - "tests/aws/services/kms/test_kms.py::TestKMS::test_sign_verify[ECC_NIST_P256-ECDSA_SHA_256]": 0.30471233699995537, - "tests/aws/services/kms/test_kms.py::TestKMS::test_sign_verify[ECC_NIST_P384-ECDSA_SHA_384]": 0.3106582499999604, - "tests/aws/services/kms/test_kms.py::TestKMS::test_sign_verify[ECC_SECG_P256K1-ECDSA_SHA_256]": 0.3111983410000221, - "tests/aws/services/kms/test_kms.py::TestKMS::test_sign_verify[RSA_2048-RSASSA_PSS_SHA_256]": 0.68845701500004, - "tests/aws/services/kms/test_kms.py::TestKMS::test_sign_verify[RSA_2048-RSASSA_PSS_SHA_384]": 0.7201158150000992, - "tests/aws/services/kms/test_kms.py::TestKMS::test_sign_verify[RSA_2048-RSASSA_PSS_SHA_512]": 0.7328560440000729, - "tests/aws/services/kms/test_kms.py::TestKMS::test_sign_verify[RSA_4096-RSASSA_PKCS1_V1_5_SHA_256]": 3.2564057839999805, - "tests/aws/services/kms/test_kms.py::TestKMS::test_sign_verify[RSA_4096-RSASSA_PKCS1_V1_5_SHA_512]": 3.7212225820001095, - "tests/aws/services/kms/test_kms.py::TestKMS::test_symmetric_encrypt_offline_decrypt_online[RSA_2048-RSAES_OAEP_SHA_1]": 0.09630264200006877, - "tests/aws/services/kms/test_kms.py::TestKMS::test_symmetric_encrypt_offline_decrypt_online[RSA_2048-RSAES_OAEP_SHA_256]": 0.12804407299995546, - "tests/aws/services/kms/test_kms.py::TestKMS::test_symmetric_encrypt_offline_decrypt_online[RSA_3072-RSAES_OAEP_SHA_1]": 0.39022589099988636, - "tests/aws/services/kms/test_kms.py::TestKMS::test_symmetric_encrypt_offline_decrypt_online[RSA_3072-RSAES_OAEP_SHA_256]": 0.19546406499989644, - "tests/aws/services/kms/test_kms.py::TestKMS::test_symmetric_encrypt_offline_decrypt_online[RSA_4096-RSAES_OAEP_SHA_1]": 1.496203234999939, - "tests/aws/services/kms/test_kms.py::TestKMS::test_symmetric_encrypt_offline_decrypt_online[RSA_4096-RSAES_OAEP_SHA_256]": 0.47949251899990486, - "tests/aws/services/kms/test_kms.py::TestKMS::test_tag_existing_key_and_untag": 0.1336913289999302, - "tests/aws/services/kms/test_kms.py::TestKMS::test_tag_existing_key_with_invalid_tag_key": 0.10076715400009562, - "tests/aws/services/kms/test_kms.py::TestKMS::test_tag_key_with_duplicate_tag_keys_raises_error": 0.1022515200000953, - "tests/aws/services/kms/test_kms.py::TestKMS::test_untag_key_partially": 0.11641112000006615, - "tests/aws/services/kms/test_kms.py::TestKMS::test_update_alias": 0.06893375099991772, - "tests/aws/services/kms/test_kms.py::TestKMS::test_update_and_add_tags_on_tagged_key": 0.11751015900006223, - "tests/aws/services/kms/test_kms.py::TestKMS::test_update_key_description": 0.0403989220000085, - "tests/aws/services/kms/test_kms.py::TestKMS::test_verify_salt_length[ECC_NIST_P256-ECDSA_SHA_256]": 0.04064752900001167, - "tests/aws/services/kms/test_kms.py::TestKMS::test_verify_salt_length[ECC_NIST_P384-ECDSA_SHA_384]": 0.04231501400010984, - "tests/aws/services/kms/test_kms.py::TestKMS::test_verify_salt_length[ECC_SECG_P256K1-ECDSA_SHA_256]": 0.04243452299999717, - "tests/aws/services/kms/test_kms.py::TestKMS::test_verify_salt_length[RSA_2048-RSASSA_PSS_SHA_256]": 0.13781162799989488, - "tests/aws/services/kms/test_kms.py::TestKMS::test_verify_salt_length[RSA_2048-RSASSA_PSS_SHA_384]": 0.15267230100005236, - "tests/aws/services/kms/test_kms.py::TestKMS::test_verify_salt_length[RSA_2048-RSASSA_PSS_SHA_512]": 0.18987592500002393, - "tests/aws/services/kms/test_kms.py::TestKMS::test_verify_salt_length[RSA_4096-RSASSA_PKCS1_V1_5_SHA_256]": 0.8823382750001656, - "tests/aws/services/kms/test_kms.py::TestKMS::test_verify_salt_length[RSA_4096-RSASSA_PKCS1_V1_5_SHA_512]": 1.1594449030000078, - "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_encryption_context_generate_data_key": 0.18915193599991653, - "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_encryption_context_generate_data_key_pair": 0.1523963139999296, - "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_encryption_context_generate_data_key_pair_without_plaintext": 0.16959266600008505, - "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_encryption_context_generate_data_key_without_plaintext": 0.1900157699999454, - "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_generate_data_key": 0.03815599799997926, - "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_generate_data_key_pair": 0.0973009719999709, - "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_generate_data_key_pair_dry_run": 0.03006914900004176, - "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_generate_data_key_pair_without_plaintext": 0.12797566100005042, - "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_generate_data_key_pair_without_plaintext_dry_run": 0.06234219199996005, - "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_generate_data_key_without_plaintext": 0.030817501999990782, - "tests/aws/services/kms/test_kms.py::TestKMSMultiAccounts::test_cross_accounts_access": 1.765722727999787, - "tests/aws/services/lambda_/event_source_mapping/test_cfn_resource.py::test_adding_tags": 17.638575529999912, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_deletion_event_source_mapping_with_dynamodb": 6.170832594000103, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_disabled_dynamodb_event_source_mapping": 12.31730443299989, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_duplicate_event_source_mappings": 5.586305728999946, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_event_filter[content_filter_type]": 12.848958127999936, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_event_filter[content_multiple_filters]": 0.006968690000007882, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_event_filter[content_or_filter]": 12.85321188599994, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_event_filter[date_time_conversion]": 12.831042073999924, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_event_filter[exists_false_filter]": 13.688327391999906, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_event_filter[exists_filter_type]": 12.771388665000018, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_event_filter[insert_same_entry_twice]": 12.790709150000112, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_event_filter[numeric_filter]": 12.810148600000161, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_event_filter[prefix_filter]": 12.789718105999896, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_event_source_mapping": 15.676845379999918, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_event_source_mapping_with_on_failure_destination_config": 11.397867447999943, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_event_source_mapping_with_s3_on_failure_destination": 11.571674562999988, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_event_source_mapping_with_sns_on_failure_destination_config": 11.426628025000127, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_invalid_event_filter[[{\"eventName\": [\"INSERT\"=123}]]": 4.537032810000028, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_invalid_event_filter[single-string]": 4.580779370999949, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_report_batch_item_failure_scenarios[empty_string_item_identifier_failure]": 14.817250082999976, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_report_batch_item_failure_scenarios[invalid_key_foo_failure]": 14.799305921000041, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_report_batch_item_failure_scenarios[invalid_key_foo_null_value_failure]": 14.843591520000018, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_report_batch_item_failure_scenarios[item_identifier_not_present_failure]": 14.808220079999955, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_report_batch_item_failure_scenarios[null_item_identifier_failure]": 14.800821747999976, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_report_batch_item_failure_scenarios[unhandled_exception_in_function]": 14.858337190999919, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_report_batch_item_failures": 15.25717239800008, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_report_batch_item_success_scenarios[empty_batch_item_failure_success]": 9.787422263000053, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_report_batch_item_success_scenarios[empty_dict_success]": 9.728968930999827, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_report_batch_item_success_scenarios[empty_list_success]": 9.748021979999862, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_report_batch_item_success_scenarios[null_batch_item_failure_success]": 9.763338308000016, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_report_batch_item_success_scenarios[null_success]": 9.79778437999994, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_esm_with_not_existing_dynamodb_stream": 1.851036315999977, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisEventFiltering::test_kinesis_event_filtering_json_pattern": 9.31211859699988, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_create_kinesis_event_source_mapping": 12.14590697799997, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_create_kinesis_event_source_mapping_multiple_lambdas_single_kinesis_event_stream": 19.421371248000014, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_disable_kinesis_event_source_mapping": 29.265496796999855, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_duplicate_event_source_mappings": 3.4017732680000563, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_esm_with_not_existing_kinesis_stream": 1.425101042999927, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_empty_provided": 9.260025009999708, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_event_source_mapping_with_async_invocation": 20.193658653999705, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_event_source_mapping_with_on_failure_destination_config": 9.262561967000238, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_event_source_mapping_with_s3_on_failure_destination": 9.320659097999851, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_event_source_mapping_with_sns_on_failure_destination_config": 9.27424224299989, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_event_source_trim_horizon": 26.303340179999964, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_maximum_record_age_exceeded[expire-before-ingestion]": 14.344580303000157, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_maximum_record_age_exceeded[expire-while-retrying]": 9.299457927000049, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_maximum_record_age_exceeded_discard_records": 19.419136923999986, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_report_batch_item_failure_scenarios[empty_string_item_identifier_failure]": 13.075377776000323, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_report_batch_item_failure_scenarios[invalid_key_foo_failure]": 12.179363073999866, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_report_batch_item_failure_scenarios[invalid_key_foo_null_value_failure]": 12.192900912000141, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_report_batch_item_failure_scenarios[item_identifier_not_present_failure]": 12.172738373999891, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_report_batch_item_failure_scenarios[null_item_identifier_failure]": 12.18095697700005, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_report_batch_item_failure_scenarios[unhandled_exception_in_function]": 12.180816703999653, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_report_batch_item_failures": 17.368877388000328, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_report_batch_item_success_scenarios[empty_batch_item_failure_success]": 7.11514787100009, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_report_batch_item_success_scenarios[empty_dict_success]": 7.135200515000179, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_report_batch_item_success_scenarios[empty_list_success]": 7.132734821000213, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_report_batch_item_success_scenarios[empty_string_success]": 7.127354783999635, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_report_batch_item_success_scenarios[null_batch_item_failure_success]": 7.138279181000144, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_report_batch_item_success_scenarios[null_success]": 7.1128590410000925, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_duplicate_event_source_mappings": 2.6105943840000236, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_event_source_mapping_default_batch_size": 3.460284768000065, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_filter[and]": 6.428960865999898, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_filter[exists]": 6.44431293599996, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_filter[numeric-bigger]": 6.4406876029997875, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_filter[numeric-range]": 6.439136788000042, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_filter[numeric-smaller]": 6.427905940999835, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_filter[or]": 6.424111809999658, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_filter[plain-string-filter]": 0.002015228000118441, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_filter[plain-string-matching]": 0.002816222000092239, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_filter[prefix]": 6.445062804999907, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_filter[single]": 6.448771473999841, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_filter[valid-json-filter]": 6.438209316000211, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_source_mapping": 6.372904106000078, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_source_mapping_batch_size[10000]": 9.557955466000067, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_source_mapping_batch_size[1000]": 9.576256149999836, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_source_mapping_batch_size[100]": 9.555571795999867, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_source_mapping_batch_size[15]": 9.559413996000103, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_source_mapping_batch_size_override[10000]": 50.166936663000115, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_source_mapping_batch_size_override[1000]": 9.84782876700001, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_source_mapping_batch_size_override[100]": 6.637811828000167, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_source_mapping_batch_size_override[20]": 6.435833736000177, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_source_mapping_batching_reserved_concurrency": 8.700370003999979, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_source_mapping_batching_window_size_override": 27.60035112200012, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_source_mapping_update": 11.682036982, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_invalid_event_filter[None]": 1.2600650990000304, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_invalid_event_filter[invalid_filter2]": 1.257216680000056, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_invalid_event_filter[invalid_filter3]": 1.2344059659999402, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_invalid_event_filter[simple string]": 1.2343287780004175, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::test_esm_with_not_existing_sqs_queue": 1.1894653759998164, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::test_failing_lambda_retries_after_visibility_timeout": 17.85165343099993, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::test_fifo_message_group_parallelism": 63.495032326, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::test_message_body_and_attributes_passed_correctly": 6.768202993000386, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::test_redrive_policy_with_failing_lambda": 18.47574258999998, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::test_report_batch_item_failures": 23.23761417300011, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::test_report_batch_item_failures_empty_json_batch_succeeds": 9.935343049999801, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::test_report_batch_item_failures_invalid_result_json_batch_fails": 15.868418494000025, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::test_report_batch_item_failures_on_lambda_error": 8.381487519000075, - "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::test_sqs_queue_as_lambda_dead_letter_queue": 6.267675840000038, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaAliases::test_alias_routingconfig": 3.2918021880000197, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaAliases::test_lambda_alias_moving": 3.410876468999959, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaBaseFeatures::test_assume_role[1]": 3.4328520960000333, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaBaseFeatures::test_assume_role[2]": 3.39216228999976, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaBaseFeatures::test_function_state": 1.700168821999796, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaBaseFeatures::test_lambda_different_iam_keys_environment": 5.921658551000064, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaBaseFeatures::test_lambda_large_response": 2.93001124899979, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaBaseFeatures::test_lambda_too_large_response": 3.562876879999976, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaBaseFeatures::test_lambda_too_large_response_but_with_custom_limit": 2.835244094000018, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaBaseFeatures::test_large_payloads": 3.2608969230000184, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaBehavior::test_ignore_architecture": 2.9581719330001306, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaBehavior::test_lambda_cache_local[nodejs]": 9.4063971449998, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaBehavior::test_lambda_cache_local[python]": 3.4075550420000127, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaBehavior::test_lambda_init_environment": 6.831238581999969, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaBehavior::test_lambda_invoke_no_timeout": 5.196857975000057, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaBehavior::test_lambda_invoke_timed_out_environment_reuse": 0.0321427629999107, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaBehavior::test_lambda_invoke_with_timeout": 5.795239934999927, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaBehavior::test_mixed_architecture": 0.025358354999980293, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaBehavior::test_runtime_introspection_arm": 0.017498378999789566, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaBehavior::test_runtime_introspection_x86": 3.5531777740002326, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaBehavior::test_runtime_ulimits": 3.1285540659998787, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaCleanup::test_delete_lambda_during_sync_invoke": 0.0017440170001918887, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaCleanup::test_recreate_function": 3.4161329300000034, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaConcurrency::test_lambda_concurrency_block": 17.364219408999816, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaConcurrency::test_lambda_concurrency_crud": 1.2346419329996934, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaConcurrency::test_lambda_concurrency_update": 2.296258390000048, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaConcurrency::test_lambda_provisioned_concurrency_moves_with_alias": 0.003036435000012716, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaConcurrency::test_lambda_provisioned_concurrency_scheduling": 8.516381729000159, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaConcurrency::test_provisioned_concurrency": 2.898677791999944, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaConcurrency::test_provisioned_concurrency_on_alias": 2.93960954399995, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaConcurrency::test_reserved_concurrency": 16.405836706000173, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaConcurrency::test_reserved_concurrency_async_queue": 3.9214294349999363, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaConcurrency::test_reserved_provisioned_overlap": 5.227813992999927, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaErrors::test_lambda_handler_error": 1.595507729000019, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaErrors::test_lambda_handler_exit": 0.002719772999853376, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaErrors::test_lambda_invoke_payload_encoding_error[body-n\\x87r\\x9e\\xe9\\xb5\\xd7I\\xee\\x9bmt]": 1.3708861630000229, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaErrors::test_lambda_invoke_payload_encoding_error[message-\\x99\\xeb,j\\x07\\xa1zYh]": 1.3723986510001396, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaErrors::test_lambda_runtime_error": 7.694419942999957, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaErrors::test_lambda_runtime_exit": 0.0017995330001667753, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaErrors::test_lambda_runtime_exit_segfault": 0.0016608819998964464, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaErrors::test_lambda_runtime_startup_error": 1.6028169619999062, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaErrors::test_lambda_runtime_startup_timeout": 41.81982029200003, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaErrors::test_lambda_runtime_wrapper_not_found": 0.0021420109999326087, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_type_dry_run[nodejs16.x]": 0.0029489390001344873, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_type_dry_run[python3.10]": 0.0030282859997896594, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_type_event[nodejs16.x]": 2.281449830999918, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_type_event[python3.10]": 2.295798087000094, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_type_event_error": 0.002092257999947833, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_type_no_return_payload[nodejs-Event]": 2.294005343000208, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_type_no_return_payload[nodejs-RequestResponse]": 8.68759877399998, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_type_no_return_payload[python-Event]": 2.2996057009997912, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_type_no_return_payload[python-RequestResponse]": 2.61801069299986, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_type_request_response[nodejs16.x]": 2.7696100320001733, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_type_request_response[python3.10]": 1.6132022680001228, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_with_logs[nodejs16.x]": 17.465238027999703, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_with_logs[python3.10]": 9.380066224999837, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_with_qualifier": 1.8426856979999684, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invoke_exceptions": 0.3093109880001066, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_lambda_with_context": 0.0025391830001808557, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_upload_lambda_from_s3": 2.200014587999931, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaMultiAccounts::test_delete_function": 1.1548962980000397, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaMultiAccounts::test_function_alias": 1.1588942490000136, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaMultiAccounts::test_function_concurrency": 1.1523486229998525, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaMultiAccounts::test_function_invocation": 1.558888128000035, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaMultiAccounts::test_function_tags": 1.1541276440002548, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaMultiAccounts::test_get_function": 1.1455450769999516, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaMultiAccounts::test_get_function_configuration": 1.144430131000263, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaMultiAccounts::test_get_lambda_layer": 0.20711446500013153, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaMultiAccounts::test_list_versions_by_function": 1.1493176050003058, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaMultiAccounts::test_publish_version": 1.1956735449998632, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaPermissions::test_lambda_permission_url_invocation": 0.025083545000143204, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_update_function_url_config": 2.152666870000303, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_echo_http_fixture_default": 3.9822867999998834, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_echo_http_fixture_trim_x_headers": 3.891536488999918, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_echo_invoke[BUFFERED]": 3.607789464999769, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_echo_invoke[None]": 3.494224434000216, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_echo_invoke[RESPONSE_STREAM]": 0.14303240100002768, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_form_payload": 4.400915970000369, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_headers_and_status": 2.9954989220002517, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_invalid_invoke_mode": 2.0611565080000673, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_invocation[boolean]": 4.575936626000157, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_invocation[dict]": 3.6651487589997487, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_invocation[float]": 3.580048043000261, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_invocation[http-response-json]": 3.4686210530001063, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_invocation[http-response]": 3.671196407000025, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_invocation[integer]": 3.526429435999944, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_invocation[list-mixed]": 3.570913467999844, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_invocation[string]": 3.7383310850002545, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_invocation_custom_id": 2.888942402999646, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_invocation_custom_id_aliased": 3.131158947999893, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_invocation_exception": 3.7414350939998258, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_non_existing_url": 0.16399357500017686, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_persists_after_alias_delete": 5.697754753000254, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaVersions::test_async_invoke_queue_upon_function_update": 98.75175207500024, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaVersions::test_function_update_during_invoke": 0.002173371999788287, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaVersions::test_lambda_handler_update": 2.2258366930000193, - "tests/aws/services/lambda_/test_lambda.py::TestLambdaVersions::test_lambda_versions_with_code_changes": 5.560721653999963, - "tests/aws/services/lambda_/test_lambda.py::TestRequestIdHandling::test_request_id_async_invoke_with_retry": 11.274393451999913, - "tests/aws/services/lambda_/test_lambda.py::TestRequestIdHandling::test_request_id_format": 0.02900219699995432, - "tests/aws/services/lambda_/test_lambda.py::TestRequestIdHandling::test_request_id_invoke": 3.6768631099998856, - "tests/aws/services/lambda_/test_lambda.py::TestRequestIdHandling::test_request_id_invoke_url": 3.595541804000277, - "tests/aws/services/lambda_/test_lambda_api.py::TestCodeSigningConfig::test_code_signing_not_found_excs": 1.3382098199999746, - "tests/aws/services/lambda_/test_lambda_api.py::TestCodeSigningConfig::test_function_code_signing_config": 1.2807681620001858, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaAccountSettings::test_account_settings": 0.0957911140003489, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaAccountSettings::test_account_settings_total_code_size": 1.4477420340003846, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaAccountSettings::test_account_settings_total_code_size_config_update": 1.3024633039995024, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaAlias::test_alias_lifecycle": 1.5311286540004403, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaAlias::test_alias_naming": 1.6426531739998609, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaAlias::test_non_existent_alias_deletion": 1.2091474189996916, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaAlias::test_non_existent_alias_update": 1.2119617649996144, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaAlias::test_notfound_and_invalid_routingconfigs": 1.4384066560000974, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaEventInvokeConfig::test_lambda_eventinvokeconfig_exceptions": 2.7691686680000203, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaEventInvokeConfig::test_lambda_eventinvokeconfig_lifecycle": 1.3731996350002191, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaEventSourceMappings::test_create_event_filter_criteria_validation": 3.5121567929995763, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaEventSourceMappings::test_create_event_source_self_managed": 0.001897559000099136, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaEventSourceMappings::test_create_event_source_validation": 3.3937178969999877, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaEventSourceMappings::test_create_event_source_validation_kinesis": 1.8873261889998503, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaEventSourceMappings::test_event_source_mapping_exceptions": 0.15674208799964617, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaEventSourceMappings::test_event_source_mapping_lifecycle": 4.194944569000199, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaEventSourceMappings::test_event_source_mapping_lifecycle_delete_function": 6.06619584200007, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaEventSourceMappings::test_function_name_variations": 16.075417395000386, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_create_lambda_exceptions": 0.1629552599993076, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_delete_on_nonexisting_version": 1.2552365810001902, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_arns": 2.5610976499997378, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_lifecycle": 2.4647596569993766, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[full_arn_and_qualifier_too_long_and_invalid_region-create_function]": 0.10542240799986757, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[full_arn_and_qualifier_too_long_and_invalid_region-delete_function]": 0.09121035499993013, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[full_arn_and_qualifier_too_long_and_invalid_region-get_function]": 0.09177350199979628, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[full_arn_and_qualifier_too_long_and_invalid_region-invoke]": 0.09068421899974055, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[full_arn_with_multiple_qualifiers-create_function]": 0.1075875120004639, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[full_arn_with_multiple_qualifiers-delete_function]": 0.09169966299987209, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[full_arn_with_multiple_qualifiers-get_function]": 0.09162844000002224, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[full_arn_with_multiple_qualifiers-invoke]": 0.09312551799939683, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[function_name_is_single_invalid-create_function]": 0.10493958399911207, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[function_name_is_single_invalid-delete_function]": 0.09097538800006078, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[function_name_is_single_invalid-get_function]": 0.09035388199981753, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[function_name_is_single_invalid-invoke]": 0.0914392339996084, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[function_name_too_long-create_function]": 0.10661792800010517, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[function_name_too_long-delete_function]": 0.09543345800011593, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[function_name_too_long-get_function]": 0.09408235700038858, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[function_name_too_long-invoke]": 0.009586961000422889, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[function_name_too_long_and_invalid_region-create_function]": 0.10619075700014946, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[function_name_too_long_and_invalid_region-delete_function]": 0.09056839899994884, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[function_name_too_long_and_invalid_region-get_function]": 0.09142040100050508, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[function_name_too_long_and_invalid_region-invoke]": 0.09067390700056421, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[incomplete_arn-create_function]": 0.008148833999712224, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[incomplete_arn-delete_function]": 0.09738297800004148, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[incomplete_arn-get_function]": 0.0917599340000379, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[incomplete_arn-invoke]": 0.009680809000201407, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_account_id_in_partial_arn-create_function]": 0.10928267799999958, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_account_id_in_partial_arn-delete_function]": 0.0954810630000793, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_account_id_in_partial_arn-get_function]": 0.10553466599958483, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_account_id_in_partial_arn-invoke]": 0.11368783799935045, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_characters_in_function_name-create_function]": 0.1059799669997119, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_characters_in_function_name-delete_function]": 0.09127622999994855, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_characters_in_function_name-get_function]": 0.09500060800019128, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_characters_in_function_name-invoke]": 0.09242355800006408, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_characters_in_qualifier-create_function]": 0.10736567499952798, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_characters_in_qualifier-delete_function]": 0.089982315999805, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_characters_in_qualifier-get_function]": 0.09092404599959991, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_characters_in_qualifier-invoke]": 0.09161254199989344, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_region_in_arn-create_function]": 0.10760217600000033, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_region_in_arn-delete_function]": 0.09327655600009166, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_region_in_arn-get_function]": 0.09180636400014919, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_region_in_arn-invoke]": 0.09168878299988137, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[latest_version_with_additional_qualifier-create_function]": 0.10677013700023963, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[latest_version_with_additional_qualifier-delete_function]": 0.09517563199960932, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[latest_version_with_additional_qualifier-get_function]": 0.09299611600044955, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[latest_version_with_additional_qualifier-invoke]": 0.0957649400002083, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[lowercase_latest_qualifier-create_function]": 0.11067506800009141, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[lowercase_latest_qualifier-delete_function]": 0.00979453900072258, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[lowercase_latest_qualifier-get_function]": 0.09434537400011322, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[lowercase_latest_qualifier-invoke]": 0.09167496600048253, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[missing_account_id_in_arn-create_function]": 0.10372553300021536, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[missing_account_id_in_arn-delete_function]": 0.0909642880001229, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[missing_account_id_in_arn-get_function]": 0.09568574500008253, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[missing_account_id_in_arn-invoke]": 0.08953327200015337, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[missing_region_in_arn-create_function]": 0.10678431099995578, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[missing_region_in_arn-delete_function]": 0.09070618799978547, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[missing_region_in_arn-get_function]": 0.09530334499913806, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[missing_region_in_arn-invoke]": 0.08970098100007817, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[misspelled_latest_in_arn-create_function]": 0.10281141400037086, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[misspelled_latest_in_arn-delete_function]": 0.09155749599995033, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[misspelled_latest_in_arn-get_function]": 0.09352978300012182, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[misspelled_latest_in_arn-invoke]": 0.08972116400036612, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[non_lambda_arn-create_function]": 0.10474713499979771, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[non_lambda_arn-delete_function]": 0.09121160099994086, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[non_lambda_arn-get_function]": 0.09238412300010168, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[non_lambda_arn-invoke]": 0.09070389199996498, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[partial_arn_with_extra_qualifier-create_function]": 0.1075452300001416, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[partial_arn_with_extra_qualifier-delete_function]": 0.0917112739998629, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[partial_arn_with_extra_qualifier-get_function]": 0.09053356200001872, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[partial_arn_with_extra_qualifier-invoke]": 0.09123025499957294, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[qualifier_too_long-create_function]": 0.12172845899931417, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[qualifier_too_long-delete_function]": 0.0899813180003548, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[qualifier_too_long-get_function]": 0.09238021700002719, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[qualifier_too_long-invoke]": 0.10163692300056937, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_get_function_wrong_region[delete_function]": 1.208929459000501, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_get_function_wrong_region[get_function]": 1.207991779999702, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_get_function_wrong_region[get_function_code_signing_config]": 1.2138526149997233, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_get_function_wrong_region[get_function_concurrency]": 1.246716725999704, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_get_function_wrong_region[get_function_configuration]": 1.216159682999205, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_get_function_wrong_region[get_function_event_invoke_config]": 1.2136000079999576, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_get_function_wrong_region[get_function_url_config]": 1.214201263999712, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_get_function_wrong_region[invoke]": 1.226063807000628, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_invalid_invoke": 1.1215012580000803, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_invalid_vpc_config_security_group": 0.002020827000251302, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_invalid_vpc_config_subnet": 0.633147975999691, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_lambda_code_location_s3": 1.4669219440002053, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_lambda_code_location_zipfile": 2.384736683999563, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_lambda_concurrent_code_updates": 2.3004994600000828, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_lambda_concurrent_config_updates": 2.263344257999961, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_list_functions": 2.4700689490000514, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_ops_on_nonexisting_fn[delete_function]": 0.09266082800013464, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_ops_on_nonexisting_fn[get_function]": 0.09119824400067955, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_ops_on_nonexisting_fn[get_function_code_signing_config]": 0.09201760500036471, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_ops_on_nonexisting_fn[get_function_concurrency]": 0.09064667200073018, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_ops_on_nonexisting_fn[get_function_configuration]": 0.09445719499990446, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_ops_on_nonexisting_fn[get_function_event_invoke_config]": 0.08943433700005698, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_ops_on_nonexisting_fn[get_function_url_config]": 0.09202277400027015, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_ops_on_nonexisting_version[get_function]": 1.197288696000669, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_ops_on_nonexisting_version[get_function_configuration]": 1.2172399539999788, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_ops_on_nonexisting_version[get_function_event_invoke_config]": 1.2195386999997027, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_ops_with_arn_qualifier_mismatch[delete_function]": 0.10233985900049447, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_ops_with_arn_qualifier_mismatch[get_function]": 0.10111153599973477, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_ops_with_arn_qualifier_mismatch[get_function_configuration]": 0.10047562299951096, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_redundant_updates": 1.315357160000076, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_update_lambda_exceptions": 1.2173563470000772, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_vpc_config": 3.313852114999918, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaImages::test_lambda_image_and_image_config_crud": 0.465917726999578, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaImages::test_lambda_image_crud": 3.0020065359994987, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaImages::test_lambda_image_versions": 0.5501115460006076, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaImages::test_lambda_zip_file_to_image": 1.3746185909994892, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaLayer::test_layer_compatibilities[runtimes0]": 0.1323196829994231, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaLayer::test_layer_compatibilities[runtimes1]": 0.13564235499961796, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaLayer::test_layer_deterministic_version": 0.06057928400014134, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaLayer::test_layer_exceptions": 0.2958905169998616, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaLayer::test_layer_function_exceptions": 17.49226157799967, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaLayer::test_layer_function_quota_exception": 16.382776365000154, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaLayer::test_layer_lifecycle": 1.4527833710003506, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaLayer::test_layer_policy_exceptions": 0.23518577200002255, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaLayer::test_layer_policy_lifecycle": 0.1754178950000096, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaLayer::test_layer_s3_content": 0.21353340099994966, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaPermissions::test_add_lambda_permission_aws": 1.2445636669999658, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaPermissions::test_add_lambda_permission_fields": 1.3054153600000973, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaPermissions::test_create_multiple_lambda_permissions": 1.2320565539998825, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaPermissions::test_lambda_permission_fn_versioning": 1.4047097590000703, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaPermissions::test_permission_exceptions": 1.3277942289996645, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaPermissions::test_remove_multi_permissions": 1.2803662670007725, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaProvisionedConcurrency::test_lambda_provisioned_lifecycle": 2.4635976090007716, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaProvisionedConcurrency::test_provisioned_concurrency_exceptions": 1.3849405759997353, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaProvisionedConcurrency::test_provisioned_concurrency_limits": 1.263370051000038, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaRecursion::test_put_function_recursion_config_allow": 1.2293864019998182, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaRecursion::test_put_function_recursion_config_default_terminate": 1.2154534869991949, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaRecursion::test_put_function_recursion_config_invalid_value": 1.21867625699997, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaReservedConcurrency::test_function_concurrency": 1.2519868189997396, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaReservedConcurrency::test_function_concurrency_exceptions": 1.2256378880001648, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaReservedConcurrency::test_function_concurrency_limits": 1.2400140240001747, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaRevisions::test_function_revisions_basic": 15.68819863699946, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaRevisions::test_function_revisions_permissions": 1.2829905199996574, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaRevisions::test_function_revisions_version_and_alias": 1.3540807560002577, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSizeLimits::test_lambda_envvars_near_limit_succeeds": 1.292404870000155, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSizeLimits::test_large_environment_fails_multiple_keys": 16.2169111850003, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSizeLimits::test_large_environment_variables_fails": 16.22153647999994, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSizeLimits::test_large_lambda": 12.793866835000244, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSizeLimits::test_oversized_request_create_lambda": 3.6983165540004848, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSizeLimits::test_oversized_unzipped_lambda": 4.872836943000493, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSizeLimits::test_oversized_zipped_create_lambda": 1.8063840369995887, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSnapStart::test_snapstart_exceptions": 0.10625641799970253, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSnapStart::test_snapstart_lifecycle[dotnet8]": 4.308500883999841, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSnapStart::test_snapstart_lifecycle[java11]": 3.3020375400005832, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSnapStart::test_snapstart_lifecycle[java17]": 1.2817461300001014, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSnapStart::test_snapstart_lifecycle[java21]": 2.300159917000201, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSnapStart::test_snapstart_lifecycle[python3.12]": 1.2680537219998769, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSnapStart::test_snapstart_lifecycle[python3.13]": 1.256969361999836, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSnapStart::test_snapstart_update_function_configuration[dotnet8]": 1.2271871210000427, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSnapStart::test_snapstart_update_function_configuration[java11]": 1.2262587579994033, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSnapStart::test_snapstart_update_function_configuration[java17]": 1.252001521999773, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSnapStart::test_snapstart_update_function_configuration[java21]": 1.2419912030004525, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSnapStart::test_snapstart_update_function_configuration[python3.12]": 1.233809797000049, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSnapStart::test_snapstart_update_function_configuration[python3.13]": 1.2344359409994468, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaTag::test_create_tag_on_esm_create": 1.362441009000122, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaTag::test_create_tag_on_fn_create": 1.2314037439996355, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaTag::test_tag_exceptions[event_source_mapping]": 0.12472489300034795, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaTag::test_tag_exceptions[lambda_function]": 0.1255774520000159, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaTag::test_tag_lifecycle[event_source_mapping]": 1.419460906000495, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaTag::test_tag_lifecycle[lambda_function]": 1.3042137789998378, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaTag::test_tag_nonexisting_resource": 1.2478810700004033, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaTags::test_tag_exceptions": 1.3193846259996462, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaTags::test_tag_lifecycle": 1.3720121429996652, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaTags::test_tag_limits": 1.4009362379997583, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaTags::test_tag_versions": 1.2744509009994545, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaUrl::test_create_url_config_custom_id_tag": 1.1367676539998683, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaUrl::test_create_url_config_custom_id_tag_alias": 3.4105405720001727, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaUrl::test_create_url_config_custom_id_tag_invalid_id": 1.1345518109997101, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaUrl::test_url_config_deletion_without_qualifier": 1.355174494000039, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaUrl::test_url_config_exceptions": 1.5725105500005157, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaUrl::test_url_config_lifecycle": 1.3130491750002875, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaUrl::test_url_config_list_paging": 1.3855393809999441, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaVersions::test_publish_version_on_create": 3.268549532000179, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaVersions::test_publish_with_update": 1.3698806679999507, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaVersions::test_publish_with_wrong_sha256": 1.2586902369998825, - "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaVersions::test_version_lifecycle": 2.4837877310001204, - "tests/aws/services/lambda_/test_lambda_api.py::TestLoggingConfig::test_advanced_logging_configuration_format_switch": 1.3314498630002163, - "tests/aws/services/lambda_/test_lambda_api.py::TestLoggingConfig::test_function_advanced_logging_configuration": 1.2893146979999983, - "tests/aws/services/lambda_/test_lambda_api.py::TestLoggingConfig::test_function_partial_advanced_logging_configuration_update[partial_config0]": 2.297276863999741, - "tests/aws/services/lambda_/test_lambda_api.py::TestLoggingConfig::test_function_partial_advanced_logging_configuration_update[partial_config1]": 1.316500466999969, - "tests/aws/services/lambda_/test_lambda_api.py::TestLoggingConfig::test_function_partial_advanced_logging_configuration_update[partial_config2]": 1.2908780370003115, - "tests/aws/services/lambda_/test_lambda_api.py::TestLoggingConfig::test_function_partial_advanced_logging_configuration_update[partial_config3]": 2.3045099720002327, - "tests/aws/services/lambda_/test_lambda_api.py::TestPartialARNMatching::test_cross_region_arn_function_access": 1.1494904910000514, - "tests/aws/services/lambda_/test_lambda_api.py::TestPartialARNMatching::test_update_function_configuration_full_arn": 1.2352551269991636, - "tests/aws/services/lambda_/test_lambda_api.py::TestRuntimeValidation::test_create_deprecated_function_runtime_with_validation_disabled": 15.200725250000687, - "tests/aws/services/lambda_/test_lambda_api.py::TestRuntimeValidation::test_create_deprecated_function_runtime_with_validation_enabled[dotnetcore3.1]": 0.10496614300063811, - "tests/aws/services/lambda_/test_lambda_api.py::TestRuntimeValidation::test_create_deprecated_function_runtime_with_validation_enabled[go1.x]": 0.10590375699985088, - "tests/aws/services/lambda_/test_lambda_api.py::TestRuntimeValidation::test_create_deprecated_function_runtime_with_validation_enabled[java8]": 0.10713243700047315, - "tests/aws/services/lambda_/test_lambda_api.py::TestRuntimeValidation::test_create_deprecated_function_runtime_with_validation_enabled[nodejs12.x]": 0.1082241799995245, - "tests/aws/services/lambda_/test_lambda_api.py::TestRuntimeValidation::test_create_deprecated_function_runtime_with_validation_enabled[nodejs14.x]": 0.11058480099973167, - "tests/aws/services/lambda_/test_lambda_api.py::TestRuntimeValidation::test_create_deprecated_function_runtime_with_validation_enabled[provided]": 0.10660791600048469, - "tests/aws/services/lambda_/test_lambda_api.py::TestRuntimeValidation::test_create_deprecated_function_runtime_with_validation_enabled[python3.7]": 0.10678785400068591, - "tests/aws/services/lambda_/test_lambda_api.py::TestRuntimeValidation::test_create_deprecated_function_runtime_with_validation_enabled[ruby2.7]": 0.10672012700024425, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[dotnet6]": 3.06352365799998, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[dotnet8]": 4.894699070999934, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[java11]": 6.886372956999992, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[java17]": 6.045630055999936, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[java21]": 6.073045132999994, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[java8.al2]": 5.987005355999997, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[nodejs16.x]": 8.86302933899998, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[nodejs18.x]": 6.797295017999971, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[nodejs20.x]": 6.737347848999946, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[nodejs22.x]": 1.649954269000034, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[python3.10]": 1.6996792870000377, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[python3.11]": 7.772360727000006, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[python3.12]": 1.7074608609999586, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[python3.13]": 1.7068148949999795, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[python3.8]": 1.7247304230000395, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[python3.9]": 6.764890964000017, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[ruby3.2]": 2.3380247210000107, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[ruby3.3]": 2.0157003520000103, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[ruby3.4]": 2.0860391279999817, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[dotnet6]": 3.5172545260002153, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[dotnet8]": 2.4834033889997045, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[java11]": 2.4450301440001567, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[java17]": 2.3982822569996642, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[java21]": 2.415967052000724, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[java8.al2]": 5.492264927999713, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[nodejs16.x]": 2.424582855999688, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[nodejs18.x]": 2.464710259999265, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[nodejs20.x]": 3.4792536249997283, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[nodejs22.x]": 7.456292094000219, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[provided.al2023]": 3.2485664700002417, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[provided.al2]": 4.096848258000136, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[python3.10]": 2.493533157999991, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[python3.11]": 2.5446987099999205, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[python3.12]": 2.53268901499996, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[python3.13]": 2.5572105699998247, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[python3.8]": 2.7412445979998665, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[python3.9]": 6.593621324000196, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[ruby3.2]": 8.505687551999927, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[ruby3.3]": 8.599851978999595, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[ruby3.4]": 10.594274528999904, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[dotnet6]": 3.643416814000375, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[dotnet8]": 3.610863486999733, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[java11]": 3.7023230979998516, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[java17]": 3.617223881999962, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[java21]": 3.6980749199997263, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[java8.al2]": 3.9022132559994134, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[nodejs16.x]": 3.5389829720002126, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[nodejs18.x]": 3.4956912620000367, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[nodejs20.x]": 3.48594349699988, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[nodejs22.x]": 3.48520464000012, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[provided.al2023]": 3.54740929899981, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[provided.al2]": 3.5130286399999022, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[python3.10]": 3.553406668000207, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[python3.11]": 4.680043130000286, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[python3.12]": 3.487204077000115, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[python3.13]": 3.480162788999678, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[python3.8]": 3.5251213839997035, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[python3.9]": 3.5234952969994993, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[ruby3.2]": 4.788849405999827, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[ruby3.3]": 3.6056958599997415, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[ruby3.4]": 3.5955227210001794, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[java11]": 2.304434307000065, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[java21]": 1.8318432669998401, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[java8.al2]": 9.241412450000013, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[nodejs16.x]": 1.7096603129998584, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[nodejs18.x]": 1.7307644819998131, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[nodejs20.x]": 1.688494534000256, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[nodejs22.x]": 18.49859306799999, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[python3.10]": 6.73107275000001, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[python3.11]": 1.6557294540007206, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[python3.12]": 8.969660962000006, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[python3.13]": 12.428941578999996, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[python3.8]": 11.831267334000017, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[python3.9]": 1.675758656999733, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[ruby3.2]": 7.834567620999991, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[ruby3.3]": 10.270646988000038, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[ruby3.4]": 7.8768723939999745, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[dotnet6]": 1.848842147999676, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[dotnet8]": 1.8224175709997326, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[java11]": 2.018225147999601, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[java17]": 1.838537517000077, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[java21]": 3.045464458999959, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[java8.al2]": 2.100969334000183, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[nodejs16.x]": 1.7112399080001524, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[nodejs18.x]": 1.7403566210000463, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[nodejs20.x]": 1.7062675109996235, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[nodejs22.x]": 1.697925266999846, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[provided.al2023]": 1.746255986000051, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[provided.al2]": 1.7340155249999043, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[python3.10]": 1.7122417780001342, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[python3.11]": 1.6905850059997647, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[python3.12]": 1.7078953320001347, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[python3.13]": 1.697866336000061, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[python3.8]": 1.7039431319999494, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[python3.9]": 1.6750110779998977, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[ruby3.2]": 1.7591462340001272, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[ruby3.3]": 1.767142593999779, - "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[ruby3.4]": 1.7665523680007027, - "tests/aws/services/lambda_/test_lambda_destinations.py::TestLambdaDLQ::test_dead_letter_queue": 20.82205074700005, - "tests/aws/services/lambda_/test_lambda_destinations.py::TestLambdaDestinationEventbridge::test_invoke_lambda_eventbridge": 15.639352481000003, - "tests/aws/services/lambda_/test_lambda_destinations.py::TestLambdaDestinationSqs::test_assess_lambda_destination_invocation[payload0]": 1.8589550149999923, - "tests/aws/services/lambda_/test_lambda_destinations.py::TestLambdaDestinationSqs::test_assess_lambda_destination_invocation[payload1]": 1.8565729229999306, - "tests/aws/services/lambda_/test_lambda_destinations.py::TestLambdaDestinationSqs::test_lambda_destination_default_retries": 18.198687576000054, - "tests/aws/services/lambda_/test_lambda_destinations.py::TestLambdaDestinationSqs::test_maxeventage": 63.680891202, - "tests/aws/services/lambda_/test_lambda_destinations.py::TestLambdaDestinationSqs::test_retries": 22.489840888999993, - "tests/aws/services/lambda_/test_lambda_developer_tools.py::TestDockerFlags::test_additional_docker_flags": 1.5487824900000078, - "tests/aws/services/lambda_/test_lambda_developer_tools.py::TestDockerFlags::test_lambda_docker_networks": 5.633000799999991, - "tests/aws/services/lambda_/test_lambda_developer_tools.py::TestHotReloading::test_hot_reloading[nodejs20.x]": 3.396451893999995, - "tests/aws/services/lambda_/test_lambda_developer_tools.py::TestHotReloading::test_hot_reloading[python3.12]": 3.358170538999957, - "tests/aws/services/lambda_/test_lambda_developer_tools.py::TestHotReloading::test_hot_reloading_environment_placeholder": 0.4042654529999936, - "tests/aws/services/lambda_/test_lambda_developer_tools.py::TestHotReloading::test_hot_reloading_error_path_not_absolute": 0.027339747000041825, - "tests/aws/services/lambda_/test_lambda_developer_tools.py::TestHotReloading::test_hot_reloading_publish_version": 1.098378410999885, - "tests/aws/services/lambda_/test_lambda_developer_tools.py::TestLambdaDNS::test_lambda_localhost_localstack_cloud_connectivity": 1.5464117399999964, - "tests/aws/services/lambda_/test_lambda_integration_xray.py::test_traceid_outside_handler[Active]": 2.5713510069999757, - "tests/aws/services/lambda_/test_lambda_integration_xray.py::test_traceid_outside_handler[PassThrough]": 2.569453714999952, - "tests/aws/services/lambda_/test_lambda_integration_xray.py::test_xray_trace_propagation": 1.512666779999961, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestCloudwatchLogs::test_multi_line_prints": 3.5940208359999133, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestGoProvidedRuntimes::test_manual_endpoint_injection[provided.al2023]": 1.8460767790001, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestGoProvidedRuntimes::test_manual_endpoint_injection[provided.al2]": 1.8306617480000114, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestGoProvidedRuntimes::test_uncaught_exception_invoke[provided.al2023]": 2.944431734999853, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestGoProvidedRuntimes::test_uncaught_exception_invoke[provided.al2]": 2.9872691719999693, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestJavaRuntimes::test_java_custom_handler_method_specification[cloud.localstack.sample.LambdaHandlerWithInterfaceAndCustom-INTERFACE]": 2.9969425369999954, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestJavaRuntimes::test_java_custom_handler_method_specification[cloud.localstack.sample.LambdaHandlerWithInterfaceAndCustom::handleRequest-INTERFACE]": 3.000272019000022, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestJavaRuntimes::test_java_custom_handler_method_specification[cloud.localstack.sample.LambdaHandlerWithInterfaceAndCustom::handleRequestCustom-CUSTOM]": 2.993511850999994, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestJavaRuntimes::test_java_lambda_subscribe_sns_topic": 8.821029194000062, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestJavaRuntimes::test_java_runtime_with_lib": 5.582461848999969, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestJavaRuntimes::test_serializable_input_object[java11]": 2.632787815000029, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestJavaRuntimes::test_serializable_input_object[java17]": 2.5455394519999572, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestJavaRuntimes::test_serializable_input_object[java21]": 2.7563983769999822, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestJavaRuntimes::test_serializable_input_object[java8.al2]": 2.785033191000025, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestJavaRuntimes::test_stream_handler[java11]": 1.720159057999922, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestJavaRuntimes::test_stream_handler[java17]": 1.6748605850001468, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestJavaRuntimes::test_stream_handler[java21]": 1.7263662630000454, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestJavaRuntimes::test_stream_handler[java8.al2]": 1.7039376080001603, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestNodeJSRuntimes::test_invoke_nodejs_es6_lambda[nodejs16.x]": 4.687620160999984, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestNodeJSRuntimes::test_invoke_nodejs_es6_lambda[nodejs18.x]": 4.6949735459999715, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestNodeJSRuntimes::test_invoke_nodejs_es6_lambda[nodejs20.x]": 5.295323750000023, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestNodeJSRuntimes::test_invoke_nodejs_es6_lambda[nodejs22.x]": 4.654764755000031, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestPythonRuntimes::test_handler_in_submodule[python3.10]": 1.626008560999935, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestPythonRuntimes::test_handler_in_submodule[python3.11]": 1.624617876000002, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestPythonRuntimes::test_handler_in_submodule[python3.12]": 1.6280238340000324, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestPythonRuntimes::test_handler_in_submodule[python3.13]": 1.6293802899999719, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestPythonRuntimes::test_handler_in_submodule[python3.8]": 1.644360182000014, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestPythonRuntimes::test_handler_in_submodule[python3.9]": 1.6594063140000799, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestPythonRuntimes::test_python_runtime_correct_versions[python3.10]": 1.594542821999994, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestPythonRuntimes::test_python_runtime_correct_versions[python3.11]": 1.4873011860000815, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestPythonRuntimes::test_python_runtime_correct_versions[python3.12]": 1.521954580000056, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestPythonRuntimes::test_python_runtime_correct_versions[python3.13]": 1.5288136179999583, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestPythonRuntimes::test_python_runtime_correct_versions[python3.8]": 1.5343686050000542, - "tests/aws/services/lambda_/test_lambda_runtimes.py::TestPythonRuntimes::test_python_runtime_correct_versions[python3.9]": 1.5117436019999104, - "tests/aws/services/logs/test_logs.py::TestCloudWatchLogs::test_create_and_delete_log_group": 0.09708713800011992, - "tests/aws/services/logs/test_logs.py::TestCloudWatchLogs::test_create_and_delete_log_stream": 0.378011698000023, - "tests/aws/services/logs/test_logs.py::TestCloudWatchLogs::test_delivery_logs_for_sns": 1.083698217999995, - "tests/aws/services/logs/test_logs.py::TestCloudWatchLogs::test_filter_log_events_response_header": 0.05299736099993879, - "tests/aws/services/logs/test_logs.py::TestCloudWatchLogs::test_list_tags_log_group": 0.1806159589999652, - "tests/aws/services/logs/test_logs.py::TestCloudWatchLogs::test_metric_filters": 0.0018212810000477475, - "tests/aws/services/logs/test_logs.py::TestCloudWatchLogs::test_put_events_multi_bytes_msg": 0.05479535400002078, - "tests/aws/services/logs/test_logs.py::TestCloudWatchLogs::test_put_subscription_filter_firehose": 1.277328060000059, - "tests/aws/services/logs/test_logs.py::TestCloudWatchLogs::test_put_subscription_filter_kinesis": 3.9893233719999444, - "tests/aws/services/logs/test_logs.py::TestCloudWatchLogs::test_put_subscription_filter_lambda": 1.9045418090000794, - "tests/aws/services/logs/test_logs.py::TestCloudWatchLogs::test_resource_does_not_exist": 0.03757785800007696, - "tests/aws/services/opensearch/test_opensearch.py::TestCustomBackendManager::test_custom_backend": 0.13274039899999934, - "tests/aws/services/opensearch/test_opensearch.py::TestCustomBackendManager::test_custom_backend_with_custom_endpoint": 0.15808766400016339, - "tests/aws/services/opensearch/test_opensearch.py::TestEdgeProxiedOpensearchCluster::test_custom_endpoint": 9.944805999999971, - "tests/aws/services/opensearch/test_opensearch.py::TestEdgeProxiedOpensearchCluster::test_custom_endpoint_disabled": 9.937540264999939, - "tests/aws/services/opensearch/test_opensearch.py::TestEdgeProxiedOpensearchCluster::test_route_through_edge": 9.830893729000081, - "tests/aws/services/opensearch/test_opensearch.py::TestMultiClusterManager::test_multi_cluster": 15.089933439000106, - "tests/aws/services/opensearch/test_opensearch.py::TestMultiplexingClusterManager::test_multiplexing_cluster": 10.66446813399989, - "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_cloudformation_deployment": 12.242749403999937, - "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_create_domain": 8.935557865999954, - "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_create_domain_with_invalid_custom_endpoint": 0.01987989799999923, - "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_create_domain_with_invalid_name": 0.03136097399999471, - "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_create_existing_domain_causes_exception": 9.903089958999999, - "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_create_indices": 11.424432070999956, - "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_describe_domains": 10.475285815999996, - "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_domain_version": 9.946349076999809, - "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_endpoint_strategy_path": 10.437236412000061, - "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_endpoint_strategy_port": 9.871450047000053, - "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_exception_header_field": 0.011959559000047193, - "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_get_compatible_version_for_domain": 8.899670849999893, - "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_get_compatible_versions": 0.019791766999901483, - "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_get_document": 10.748720251000009, - "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_gzip_responses": 10.066440099000033, - "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_list_versions": 0.09416587600003368, - "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_search": 10.679478274000076, - "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_security_plugin": 14.391264812999907, - "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_sql_plugin": 13.578097041999968, - "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_update_domain_config": 9.9371915669999, - "tests/aws/services/opensearch/test_opensearch.py::TestSingletonClusterManager::test_endpoint_strategy_port_singleton_cluster": 10.261006193999947, - "tests/aws/services/redshift/test_redshift.py::TestRedshift::test_cluster_security_groups": 0.03353517200002898, - "tests/aws/services/redshift/test_redshift.py::TestRedshift::test_create_clusters": 0.2733527260000983, - "tests/aws/services/resource_groups/test_resource_groups.py::TestResourceGroups::test_cloudformation_query": 0.001642066000044906, - "tests/aws/services/resource_groups/test_resource_groups.py::TestResourceGroups::test_create_group": 5.851496790999931, - "tests/aws/services/resource_groups/test_resource_groups.py::TestResourceGroups::test_resource_groups_different_region": 0.0016634960001056243, - "tests/aws/services/resource_groups/test_resource_groups.py::TestResourceGroups::test_resource_groups_tag_query": 0.0018483210001249972, - "tests/aws/services/resource_groups/test_resource_groups.py::TestResourceGroups::test_resource_type_filters": 0.0016722530000379265, - "tests/aws/services/resource_groups/test_resource_groups.py::TestResourceGroups::test_search_resources": 0.0016380289999915476, - "tests/aws/services/resourcegroupstaggingapi/test_rgsa.py::TestRGSAIntegrations::test_get_resources": 1.50012173000016, - "tests/aws/services/route53/test_route53.py::TestRoute53::test_associate_vpc_with_hosted_zone": 0.34709645600003114, - "tests/aws/services/route53/test_route53.py::TestRoute53::test_create_hosted_zone": 0.5788926570000967, - "tests/aws/services/route53/test_route53.py::TestRoute53::test_create_hosted_zone_in_non_existent_vpc": 0.2219548369999984, - "tests/aws/services/route53/test_route53.py::TestRoute53::test_create_private_hosted_zone": 0.6881752939999615, - "tests/aws/services/route53/test_route53.py::TestRoute53::test_crud_health_check": 0.1219182910000427, - "tests/aws/services/route53/test_route53.py::TestRoute53::test_reusable_delegation_sets": 0.12226797400012401, - "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_associate_and_disassociate_resolver_rule": 0.5049689869999838, - "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_create_resolver_endpoint[INBOUND-5]": 0.7740201259999822, - "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_create_resolver_endpoint[OUTBOUND-10]": 0.29455660999985867, - "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_create_resolver_query_log_config": 0.2807152430000315, - "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_create_resolver_rule": 0.3883273060000647, - "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_create_resolver_rule_with_invalid_direction": 0.3157731880000938, - "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_delete_non_existent_resolver_endpoint": 0.08848305600008644, - "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_delete_non_existent_resolver_query_log_config": 0.16200261599999521, - "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_delete_non_existent_resolver_rule": 0.0888068189999558, - "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_delete_resolver_endpoint": 0.29264798099995915, - "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_disassociate_non_existent_association": 0.0930443509998895, - "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_list_firewall_domain_lists": 0.18944751499998347, - "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_list_firewall_rules": 0.3201784730000554, - "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_list_firewall_rules_for_empty_rule_group": 0.10579139300000406, - "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_list_firewall_rules_for_missing_rule_group": 0.16260305999992397, - "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_multipe_create_resolver_rule": 0.45431946400003653, - "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_multiple_create_resolver_endpoint_with_same_req_id": 0.30327258499983145, - "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_route53resolver_bad_create_endpoint_security_groups": 0.19378388799998447, - "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_update_resolver_endpoint": 0.3084415219999528, - "tests/aws/services/s3/test_s3.py::TestS3::test_access_bucket_different_region": 0.0017885900000464972, - "tests/aws/services/s3/test_s3.py::TestS3::test_bucket_availability": 0.03205274500010091, - "tests/aws/services/s3/test_s3.py::TestS3::test_bucket_does_not_exist": 0.44705748100000164, - "tests/aws/services/s3/test_s3.py::TestS3::test_bucket_exists": 0.24444104999997762, - "tests/aws/services/s3/test_s3.py::TestS3::test_bucket_name_with_dots": 0.5746830500000897, - "tests/aws/services/s3/test_s3.py::TestS3::test_bucket_operation_between_regions": 0.47619582000004357, - "tests/aws/services/s3/test_s3.py::TestS3::test_complete_multipart_parts_order": 0.4796090819999108, - "tests/aws/services/s3/test_s3.py::TestS3::test_copy_in_place_with_bucket_encryption": 0.13717745700012074, - "tests/aws/services/s3/test_s3.py::TestS3::test_copy_object_kms": 0.6655479559999549, - "tests/aws/services/s3/test_s3.py::TestS3::test_copy_object_special_character": 0.6620787100001735, - "tests/aws/services/s3/test_s3.py::TestS3::test_copy_object_special_character_plus_for_space": 0.09397022600012406, - "tests/aws/services/s3/test_s3.py::TestS3::test_create_bucket_head_bucket": 0.6826085360000889, - "tests/aws/services/s3/test_s3.py::TestS3::test_create_bucket_via_host_name": 0.03776567900013106, - "tests/aws/services/s3/test_s3.py::TestS3::test_create_bucket_with_existing_name": 0.4453400769999689, - "tests/aws/services/s3/test_s3.py::TestS3::test_delete_bucket_no_such_bucket": 0.01810665500011055, - "tests/aws/services/s3/test_s3.py::TestS3::test_delete_bucket_policy": 0.09701827899993987, - "tests/aws/services/s3/test_s3.py::TestS3::test_delete_bucket_policy_expected_bucket_owner": 0.10726119300011305, - "tests/aws/services/s3/test_s3.py::TestS3::test_delete_bucket_with_content": 0.7516324309999618, - "tests/aws/services/s3/test_s3.py::TestS3::test_delete_keys_in_versioned_bucket": 0.5457367810000733, - "tests/aws/services/s3/test_s3.py::TestS3::test_delete_non_existing_keys": 0.07811742399997001, - "tests/aws/services/s3/test_s3.py::TestS3::test_delete_non_existing_keys_in_non_existing_bucket": 0.02090906199998699, - "tests/aws/services/s3/test_s3.py::TestS3::test_delete_non_existing_keys_quiet": 0.07687170800011245, - "tests/aws/services/s3/test_s3.py::TestS3::test_delete_object_tagging": 0.10821172699979797, - "tests/aws/services/s3/test_s3.py::TestS3::test_delete_objects_encoding": 0.10816376599984778, - "tests/aws/services/s3/test_s3.py::TestS3::test_different_location_constraint": 0.6071483189999753, - "tests/aws/services/s3/test_s3.py::TestS3::test_download_fileobj_multiple_range_requests": 1.0801981570000407, - "tests/aws/services/s3/test_s3.py::TestS3::test_empty_bucket_fixture": 0.13972666800009392, - "tests/aws/services/s3/test_s3.py::TestS3::test_etag_on_get_object_call": 0.4767460140001276, - "tests/aws/services/s3/test_s3.py::TestS3::test_get_bucket_notification_configuration_no_such_bucket": 0.01908925900011127, - "tests/aws/services/s3/test_s3.py::TestS3::test_get_bucket_policy": 0.11971104799999921, - "tests/aws/services/s3/test_s3.py::TestS3::test_get_bucket_policy_invalid_account_id[0000000000020]": 0.06827678699994522, - "tests/aws/services/s3/test_s3.py::TestS3::test_get_bucket_policy_invalid_account_id[0000]": 0.06676561099993705, - "tests/aws/services/s3/test_s3.py::TestS3::test_get_bucket_policy_invalid_account_id[aa000000000$]": 0.06537631200001215, - "tests/aws/services/s3/test_s3.py::TestS3::test_get_bucket_policy_invalid_account_id[abcd]": 0.06618240599993896, - "tests/aws/services/s3/test_s3.py::TestS3::test_get_bucket_versioning_order": 0.5216435680000586, - "tests/aws/services/s3/test_s3.py::TestS3::test_get_object_after_deleted_in_versioned_bucket": 0.1191548709999779, - "tests/aws/services/s3/test_s3.py::TestS3::test_get_object_attributes": 0.3090210720000641, - "tests/aws/services/s3/test_s3.py::TestS3::test_get_object_attributes_versioned": 0.5129822259999628, - "tests/aws/services/s3/test_s3.py::TestS3::test_get_object_attributes_with_space": 0.0944196269999793, - "tests/aws/services/s3/test_s3.py::TestS3::test_get_object_content_length_with_virtual_host[False]": 0.09177258700003676, - "tests/aws/services/s3/test_s3.py::TestS3::test_get_object_content_length_with_virtual_host[True]": 0.09031660799996644, - "tests/aws/services/s3/test_s3.py::TestS3::test_get_object_no_such_bucket": 0.02095023399999718, - "tests/aws/services/s3/test_s3.py::TestS3::test_get_object_part": 0.2272735130000001, - "tests/aws/services/s3/test_s3.py::TestS3::test_get_object_with_anon_credentials": 0.49376050199987276, - "tests/aws/services/s3/test_s3.py::TestS3::test_get_range_object_headers": 0.08774943899993559, - "tests/aws/services/s3/test_s3.py::TestS3::test_head_object_fields": 0.10001195899997128, - "tests/aws/services/s3/test_s3.py::TestS3::test_invalid_range_error": 0.08723202399994534, - "tests/aws/services/s3/test_s3.py::TestS3::test_metadata_header_character_decoding": 0.4546980440001107, - "tests/aws/services/s3/test_s3.py::TestS3::test_multipart_and_list_parts": 0.18064903300000879, - "tests/aws/services/s3/test_s3.py::TestS3::test_multipart_complete_multipart_too_small": 0.10435315200004425, - "tests/aws/services/s3/test_s3.py::TestS3::test_multipart_complete_multipart_wrong_part": 0.09621364500003438, - "tests/aws/services/s3/test_s3.py::TestS3::test_multipart_copy_object_etag": 0.13136524900005497, - "tests/aws/services/s3/test_s3.py::TestS3::test_multipart_no_such_upload": 0.08644713399996817, - "tests/aws/services/s3/test_s3.py::TestS3::test_multipart_overwrite_key": 0.11739243499994245, - "tests/aws/services/s3/test_s3.py::TestS3::test_object_with_slashes_in_key[False]": 0.1832219680001117, - "tests/aws/services/s3/test_s3.py::TestS3::test_object_with_slashes_in_key[True]": 0.1809875760000068, - "tests/aws/services/s3/test_s3.py::TestS3::test_precondition_failed_error": 0.09724338800003807, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_and_get_object_with_content_language_disposition": 0.9336989019999464, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_and_get_object_with_hash_prefix": 0.46208280500002274, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_and_get_object_with_utf8_key": 0.46086802199988597, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_bucket_inventory_config_order": 0.15280903799998669, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_bucket_policy": 0.08965071400007218, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_bucket_policy_expected_bucket_owner": 0.2559648050001897, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_bucket_policy_invalid_account_id[0000000000020]": 0.0667482100000143, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_bucket_policy_invalid_account_id[0000]": 0.06896639400008553, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_bucket_policy_invalid_account_id[aa000000000$]": 0.067638653999893, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_bucket_policy_invalid_account_id[abcd]": 0.06894104299999526, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_get_object_single_character_trailing_slash": 0.14746239099997638, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_get_object_special_character[a/%F0%9F%98%80/]": 0.4838840310000023, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_get_object_special_character[file%2Fname]": 0.4727280060000112, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_get_object_special_character[test key//]": 0.5028983299998799, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_get_object_special_character[test key/]": 0.48334355099984805, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_get_object_special_character[test%123/]": 0.4697144519999483, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_get_object_special_character[test%123]": 0.4677152219999243, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_get_object_special_character[test%percent]": 0.4765962839999247, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_get_object_special_character[test@key/]": 1.3728039369999578, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_acl_on_delete_marker": 0.5369344969999474, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_chunked_checksum": 0.09996022099983293, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_chunked_content_encoding": 0.11309315300013623, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_chunked_newlines": 0.08243060700010574, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_chunked_newlines_no_sig": 0.0962269799998694, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_chunked_newlines_no_sig_empty_body": 0.08518394800012175, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_chunked_newlines_with_trailing_checksum": 0.1069947860000866, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_storage_class[DEEP_ARCHIVE-False]": 0.09836518300005537, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_storage_class[GLACIER-False]": 0.09812508599998182, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_storage_class[GLACIER_IR-True]": 0.0975631340000973, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_storage_class[INTELLIGENT_TIERING-True]": 0.10281046299996888, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_storage_class[ONEZONE_IA-True]": 0.09732538700006899, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_storage_class[REDUCED_REDUNDANCY-True]": 0.09938520699995479, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_storage_class[STANDARD-True]": 0.10212461599996914, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_storage_class[STANDARD_IA-True]": 0.10282870100002128, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_storage_class_outposts": 0.07947890699995241, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_tagging_empty_list": 0.12388491099989096, - "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_with_md5_and_chunk_signature": 0.08092732300008265, - "tests/aws/services/s3/test_s3.py::TestS3::test_putobject_with_multiple_keys": 0.45434921499997927, - "tests/aws/services/s3/test_s3.py::TestS3::test_range_header_body_length": 0.10391930600007981, - "tests/aws/services/s3/test_s3.py::TestS3::test_range_key_not_exists": 0.06891879199986306, - "tests/aws/services/s3/test_s3.py::TestS3::test_region_header_exists_outside_us_east_1": 0.5616825910000216, - "tests/aws/services/s3/test_s3.py::TestS3::test_response_structure": 0.16138114099999257, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_analytics_configurations": 0.21578360099999827, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_batch_delete_objects": 0.49507477700001346, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_batch_delete_objects_using_requests_with_acl": 0.001825118999931874, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_batch_delete_public_objects_using_requests": 0.4803460170001017, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_bucket_acl": 0.15159280399996078, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_bucket_acl_exceptions": 0.192852190999929, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_content_type_and_metadata": 0.5315559199999598, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_metadata_directive_copy": 0.4851788639999768, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_metadata_replace": 0.4858983870001339, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_in_place": 0.5423984249999876, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_in_place_metadata_directive": 1.4504762060000758, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_in_place_storage_class": 0.5024884460000294, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_in_place_suspended_only": 0.57903971799999, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_in_place_versioned": 0.6340627789999189, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_in_place_website_redirect_location": 0.48164891599992643, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_in_place_with_encryption": 0.7894213350000427, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_preconditions": 3.537738044999969, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_storage_class": 0.5094772470000635, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_with_checksum[CRC32C]": 0.49900077400002374, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_with_checksum[CRC32]": 0.4921227249999447, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_with_checksum[CRC64NVME]": 0.49542128799987495, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_with_checksum[SHA1]": 0.499934082999971, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_with_checksum[SHA256]": 0.4927889440000399, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_with_default_checksum[CRC32C]": 0.5072066860000177, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_with_default_checksum[CRC32]": 0.5032877149999422, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_with_default_checksum[CRC64NVME]": 0.5054753309999569, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_with_default_checksum[SHA1]": 0.5150518080000666, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_with_default_checksum[SHA256]": 0.5232877370000324, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_wrong_format": 0.4306888549999712, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_tagging_directive[COPY]": 0.4961443169999029, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_tagging_directive[None]": 0.5058024989998557, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_tagging_directive[REPLACE]": 0.49722797100002936, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_tagging_directive_versioned[COPY]": 0.5921784089999846, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_tagging_directive_versioned[None]": 0.6195109850000335, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_tagging_directive_versioned[REPLACE]": 0.5964300869998169, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_delete_object_with_version_id": 0.5218227929999557, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_delete_objects_trailing_slash": 0.07247084599998743, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_download_object_with_lambda": 4.239480436999884, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_get_object_header_overrides": 0.09062230200004251, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_get_object_headers": 0.15785621300005914, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_get_object_preconditions[get_object]": 3.563771599999882, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_get_object_preconditions[head_object]": 3.5464970869999206, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_hostname_with_subdomain": 0.018562334999955965, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_intelligent_tier_config": 0.15776487200014344, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_invalid_content_md5": 11.013065570000094, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_inventory_report_crud": 0.17120473399995717, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_lambda_integration": 10.460847323000053, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_multipart_upload_acls": 0.20364180199999282, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_multipart_upload_sse": 1.088049592999937, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_object_acl": 0.16983092400005262, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_object_acl_exceptions": 0.2300909350000211, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_object_expiry": 3.5588915170000064, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_put_inventory_report_exceptions": 0.16006295700003648, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_put_more_than_1000_items": 13.04194113699998, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_put_object_versioned": 0.6600110919999906, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_raw_request_routing": 0.10314055799983635, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_request_payer": 0.078118475999986, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_request_payer_exceptions": 0.07857127099998706, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_sse_bucket_key_default": 0.23111654399997406, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_sse_default_kms_key": 0.001837382999951842, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_sse_validate_kms_key": 0.270988513999896, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_sse_validate_kms_key_state": 0.30048308999982964, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_timestamp_precision": 0.10385880299998007, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_upload_download_gzip": 0.09252132699998583, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_uppercase_bucket_name": 1.3087115099999664, - "tests/aws/services/s3/test_s3.py::TestS3::test_s3_uppercase_key_names": 0.09707521400002861, - "tests/aws/services/s3/test_s3.py::TestS3::test_set_external_hostname": 0.13612426400004551, - "tests/aws/services/s3/test_s3.py::TestS3::test_upload_big_file": 0.6113825510001334, - "tests/aws/services/s3/test_s3.py::TestS3::test_upload_file_multipart": 0.5772937980000279, - "tests/aws/services/s3/test_s3.py::TestS3::test_upload_file_with_xml_preamble": 0.4548747510001476, - "tests/aws/services/s3/test_s3.py::TestS3::test_upload_part_chunked_cancelled_valid_etag": 0.14080931500006955, - "tests/aws/services/s3/test_s3.py::TestS3::test_upload_part_chunked_newlines_valid_etag": 0.09833168499994827, - "tests/aws/services/s3/test_s3.py::TestS3::test_url_encoded_key[False]": 0.14192265999997744, - "tests/aws/services/s3/test_s3.py::TestS3::test_url_encoded_key[True]": 0.14373728499992922, - "tests/aws/services/s3/test_s3.py::TestS3::test_virtual_host_proxy_does_not_decode_gzip": 0.09866926900008366, - "tests/aws/services/s3/test_s3.py::TestS3::test_virtual_host_proxying_headers": 0.09037830300007954, - "tests/aws/services/s3/test_s3.py::TestS3BucketLifecycle::test_bucket_lifecycle_configuration_date": 0.07618389100002787, - "tests/aws/services/s3/test_s3.py::TestS3BucketLifecycle::test_bucket_lifecycle_configuration_object_expiry": 0.11599016200011647, - "tests/aws/services/s3/test_s3.py::TestS3BucketLifecycle::test_bucket_lifecycle_configuration_object_expiry_versioned": 0.16947959900005571, - "tests/aws/services/s3/test_s3.py::TestS3BucketLifecycle::test_bucket_lifecycle_multiple_rules": 0.1213936049999802, - "tests/aws/services/s3/test_s3.py::TestS3BucketLifecycle::test_bucket_lifecycle_object_size_rules": 0.12056028899996818, - "tests/aws/services/s3/test_s3.py::TestS3BucketLifecycle::test_bucket_lifecycle_tag_rules": 0.18915143100002751, - "tests/aws/services/s3/test_s3.py::TestS3BucketLifecycle::test_delete_bucket_lifecycle_configuration": 0.10916020700005902, - "tests/aws/services/s3/test_s3.py::TestS3BucketLifecycle::test_delete_lifecycle_configuration_on_bucket_deletion": 0.11382781999998315, - "tests/aws/services/s3/test_s3.py::TestS3BucketLifecycle::test_lifecycle_expired_object_delete_marker": 0.10827164300008008, - "tests/aws/services/s3/test_s3.py::TestS3BucketLifecycle::test_object_expiry_after_bucket_lifecycle_configuration": 0.12880666799992468, - "tests/aws/services/s3/test_s3.py::TestS3BucketLifecycle::test_put_bucket_lifecycle_conf_exc": 0.13669959200012727, - "tests/aws/services/s3/test_s3.py::TestS3BucketLifecycle::test_s3_transition_default_minimum_object_size": 0.12029828799995812, - "tests/aws/services/s3/test_s3.py::TestS3BucketLogging::test_put_bucket_logging": 0.14388900799997373, - "tests/aws/services/s3/test_s3.py::TestS3BucketLogging::test_put_bucket_logging_accept_wrong_grants": 0.12971892200005186, - "tests/aws/services/s3/test_s3.py::TestS3BucketLogging::test_put_bucket_logging_cross_locations": 0.16366970600006425, - "tests/aws/services/s3/test_s3.py::TestS3BucketLogging::test_put_bucket_logging_wrong_target": 0.12043380499994782, - "tests/aws/services/s3/test_s3.py::TestS3BucketReplication::test_replication_config": 0.7409251609999501, - "tests/aws/services/s3/test_s3.py::TestS3BucketReplication::test_replication_config_without_filter": 0.7165504760000658, - "tests/aws/services/s3/test_s3.py::TestS3DeepArchive::test_s3_get_deep_archive_object_restore": 0.5476337010001089, - "tests/aws/services/s3/test_s3.py::TestS3DeepArchive::test_storage_class_deep_archive": 0.1623936920000233, - "tests/aws/services/s3/test_s3.py::TestS3MultiAccounts::test_cross_account_access": 0.1337059480000562, - "tests/aws/services/s3/test_s3.py::TestS3MultiAccounts::test_cross_account_copy_object": 0.09151060600004257, - "tests/aws/services/s3/test_s3.py::TestS3MultiAccounts::test_shared_bucket_namespace": 0.06617687099992509, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_composite[CRC32C]": 0.46805822700002864, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_composite[CRC32]": 0.4787641639998128, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_composite[SHA1]": 0.4886673530002099, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_composite[SHA256]": 0.4896884859999773, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_default": 0.21399080900005174, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_full_object[CRC32C]": 0.615525101999765, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_full_object[CRC32]": 0.5632634639998741, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_full_object[CRC64NVME]": 0.5750817720002033, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_full_object_default": 0.12975049599981503, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[COMPOSITE-CRC32C]": 0.0696272879999924, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[COMPOSITE-CRC32]": 0.07159759199998916, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[COMPOSITE-CRC64NVME]": 0.06798300800005563, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[COMPOSITE-SHA1]": 0.07135627999991812, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[COMPOSITE-SHA256]": 0.0693396889998894, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[FULL_OBJECT-CRC32C]": 0.06840707900005327, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[FULL_OBJECT-CRC32]": 0.06763015899991842, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[FULL_OBJECT-CRC64NVME]": 0.07023146500000621, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[FULL_OBJECT-SHA1]": 0.06831016800015277, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[FULL_OBJECT-SHA256]": 0.07014687900004901, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_default_for_checksum[CRC32C]": 0.06785457199998746, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_default_for_checksum[CRC32]": 0.06678958399993462, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_default_for_checksum[CRC64NVME]": 0.06769007000002603, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_default_for_checksum[SHA1]": 0.06769925699995838, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_default_for_checksum[SHA256]": 0.06704842599970107, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_parts_checksum_exceptions_composite": 9.24093647399991, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_parts_checksum_exceptions_full_object": 33.146282508999775, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_size_validation": 0.12038114899996799, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_checksum_exception[CRC32C]": 6.379795164999905, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_checksum_exception[CRC32]": 8.60838399599993, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_checksum_exception[CRC64NVME]": 7.317066115999751, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_checksum_exception[SHA1]": 9.91704858800017, - "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_checksum_exception[SHA256]": 6.125142803000017, - "tests/aws/services/s3/test_s3.py::TestS3ObjectLockLegalHold::test_delete_locked_object": 0.12091738799995255, - "tests/aws/services/s3/test_s3.py::TestS3ObjectLockLegalHold::test_put_get_object_legal_hold": 0.13208817599991107, - "tests/aws/services/s3/test_s3.py::TestS3ObjectLockLegalHold::test_put_object_legal_hold_exc": 0.16399912099984704, - "tests/aws/services/s3/test_s3.py::TestS3ObjectLockLegalHold::test_put_object_with_legal_hold": 0.10528819499995734, - "tests/aws/services/s3/test_s3.py::TestS3ObjectLockLegalHold::test_s3_copy_object_legal_hold": 0.5067295910000666, - "tests/aws/services/s3/test_s3.py::TestS3ObjectLockLegalHold::test_s3_legal_hold_lock_versioned": 0.5460817800000086, - "tests/aws/services/s3/test_s3.py::TestS3ObjectLockRetention::test_bucket_config_default_retention": 0.1311676789998728, - "tests/aws/services/s3/test_s3.py::TestS3ObjectLockRetention::test_object_lock_delete_markers": 0.12394048599981033, - "tests/aws/services/s3/test_s3.py::TestS3ObjectLockRetention::test_object_lock_extend_duration": 0.12435282200010533, - "tests/aws/services/s3/test_s3.py::TestS3ObjectLockRetention::test_s3_copy_object_retention_lock": 0.5126640740000994, - "tests/aws/services/s3/test_s3.py::TestS3ObjectLockRetention::test_s3_object_retention": 6.168016758999897, - "tests/aws/services/s3/test_s3.py::TestS3ObjectLockRetention::test_s3_object_retention_exc": 0.2423591750000469, - "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_default_checksum": 0.08904902199992648, - "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_policy_casing[s3]": 0.10192880900012824, - "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_policy_casing[s3v4]": 0.09814932699998735, - "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_policy_conditions_validation_eq": 0.33128157300006933, - "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_policy_conditions_validation_starts_with": 0.29175308399999267, - "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_policy_validation_size": 0.22562913700005538, - "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_with_file_as_string": 0.33509955399995306, - "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_with_files": 0.08985079699994003, - "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_with_metadata": 0.12602507100007188, - "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_with_storage_class": 0.33992777000014485, - "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_with_tags[invalid]": 1.1073294839999335, - "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_with_tags[list]": 0.16549929199982216, - "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_with_tags[notxml]": 0.18885971700001392, - "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_with_tags[single]": 0.16770689499992386, - "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_with_wrong_content_type": 0.1402285159999792, - "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_request_expires": 3.149206551000134, - "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_request_malformed_policy[s3]": 0.15236783999989711, - "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_request_malformed_policy[s3v4]": 0.1538662599999725, - "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_request_missing_fields[s3]": 0.16519374599988623, - "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_request_missing_fields[s3v4]": 0.16635775300005662, - "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_request_missing_signature[s3]": 0.15178323199995702, - "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_request_missing_signature[s3v4]": 0.15794395899990832, - "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_presigned_post_with_different_user_credentials": 0.26074631699998463, - "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_s3_presigned_post_success_action_redirect": 0.09627915099997608, - "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_s3_presigned_post_success_action_status_201_response": 0.08327630999997382, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_delete_has_empty_content_length_header": 0.09684576099994047, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_get_object_ignores_request_body": 0.08847620200003803, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_get_request_expires_ignored_if_validation_disabled": 3.108592306000105, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_head_has_correct_content_length_header": 0.0907802570000058, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_pre_signed_url_forward_slash_bucket": 0.0960320019999017, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_pre_signed_url_if_match": 0.09681477000003724, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_pre_signed_url_if_none_match": 0.09428241900002376, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presign_check_signature_validation_for_port_permutation": 0.10228652200009947, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presign_with_additional_query_params": 0.11112677200003418, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_double_encoded_credentials": 0.17126531899987185, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_signature_authentication[s3-False]": 0.2174588280000762, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_signature_authentication[s3-True]": 0.21783440299986978, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_signature_authentication[s3v4-False]": 0.22733316400012882, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_signature_authentication[s3v4-True]": 0.22959002499987946, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_signature_authentication_expired[s3-False]": 2.182121216999917, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_signature_authentication_expired[s3-True]": 2.1754841810000016, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_signature_authentication_expired[s3v4-False]": 2.1739774490000627, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_signature_authentication_expired[s3v4-True]": 2.1767032400000517, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_signature_authentication_multi_part[s3-False]": 0.11350193299983857, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_signature_authentication_multi_part[s3-True]": 0.11433681100015747, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_signature_authentication_multi_part[s3v4-False]": 0.11663568599999508, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_signature_authentication_multi_part[s3v4-True]": 0.1150663319999694, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_v4_signed_headers_in_qs": 1.9102292120002176, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_v4_x_amz_in_qs": 8.18852579199995, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_with_different_user_credentials": 0.2505322410000872, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_with_session_token": 0.11057153599983849, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_put_object": 0.4606241810000711, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_put_object_with_md5_and_chunk_signature_bad_headers[s3-False]": 0.093007512999975, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_put_object_with_md5_and_chunk_signature_bad_headers[s3-True]": 0.16838667399997576, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_put_object_with_md5_and_chunk_signature_bad_headers[s3v4-False]": 0.08986168700005237, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_put_object_with_md5_and_chunk_signature_bad_headers[s3v4-True]": 0.1655122999999321, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_put_url_metadata_with_sig_s3[False]": 0.5597614089999752, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_put_url_metadata_with_sig_s3[True]": 0.5522727649999979, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_put_url_metadata_with_sig_s3v4[False]": 0.5682459640000843, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_put_url_metadata_with_sig_s3v4[True]": 0.5819345799999383, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_copy_md5": 0.11185535000004165, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_get_response_case_sensitive_headers": 0.08252604999995583, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_get_response_content_type_same_as_upload_and_range": 0.09227117099987936, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_get_response_default_content_type": 0.08302412200009712, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_get_response_header_overrides[s3]": 0.09426893100010147, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_get_response_header_overrides[s3v4]": 0.09401309399993352, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_ignored_special_headers": 0.1209086409999145, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_presign_url_encoding[s3]": 0.09356509799999913, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_presign_url_encoding[s3v4]": 0.09580009100000098, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_presigned_url_expired[s3]": 3.1917944769999167, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_presigned_url_expired[s3v4]": 3.195220457000005, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_put_presigned_url_missing_sig_param[s3]": 0.17348154300009355, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_put_presigned_url_missing_sig_param[s3v4]": 0.17201115899990782, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_put_presigned_url_same_header_and_qs_parameter": 0.18312040699993304, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_put_presigned_url_with_different_headers[s3]": 1.310644095999919, - "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_put_presigned_url_with_different_headers[s3v4]": 0.21134955900004115, - "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_put_object_checksum[CRC32C]": 5.201910881000003, - "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_put_object_checksum[CRC32]": 5.305968125000049, - "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_put_object_checksum[CRC64NVME]": 10.549652295999977, - "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_put_object_checksum[SHA1]": 14.021193208999875, - "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_put_object_checksum[SHA256]": 12.465482541000029, - "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_s3_checksum_no_algorithm": 0.1168862749998425, - "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_s3_checksum_no_automatic_sdk_calculation": 0.25327124400018874, - "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_s3_checksum_with_content_encoding": 0.10944395600017742, - "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_s3_get_object_checksum[CRC32C]": 0.14029297599995516, - "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_s3_get_object_checksum[CRC32]": 0.12116925899999842, - "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_s3_get_object_checksum[CRC64NVME]": 0.13496736899992356, - "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_s3_get_object_checksum[None]": 0.1355099830002473, - "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_s3_get_object_checksum[SHA1]": 0.14435870100010106, - "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_s3_get_object_checksum[SHA256]": 0.12897446600004514, - "tests/aws/services/s3/test_s3.py::TestS3Routing::test_access_favicon_via_aws_endpoints[s3.amazonaws.com-False]": 0.09053808100009064, - "tests/aws/services/s3/test_s3.py::TestS3Routing::test_access_favicon_via_aws_endpoints[s3.amazonaws.com-True]": 0.09105075800005125, - "tests/aws/services/s3/test_s3.py::TestS3Routing::test_access_favicon_via_aws_endpoints[s3.us-west-2.amazonaws.com-False]": 0.09184225400008472, - "tests/aws/services/s3/test_s3.py::TestS3Routing::test_access_favicon_via_aws_endpoints[s3.us-west-2.amazonaws.com-True]": 0.09116254099990329, - "tests/aws/services/s3/test_s3.py::TestS3SSECEncryption::test_copy_object_with_sse_c": 0.22637970899995707, - "tests/aws/services/s3/test_s3.py::TestS3SSECEncryption::test_multipart_upload_sse_c": 0.45320781199995963, - "tests/aws/services/s3/test_s3.py::TestS3SSECEncryption::test_multipart_upload_sse_c_validation": 0.19378975800009357, - "tests/aws/services/s3/test_s3.py::TestS3SSECEncryption::test_object_retrieval_sse_c": 0.2522065909997764, - "tests/aws/services/s3/test_s3.py::TestS3SSECEncryption::test_put_object_default_checksum_with_sse_c": 0.19012682000004588, - "tests/aws/services/s3/test_s3.py::TestS3SSECEncryption::test_put_object_lifecycle_with_sse_c": 0.18114233699998294, - "tests/aws/services/s3/test_s3.py::TestS3SSECEncryption::test_put_object_validation_sse_c": 0.21026624899980106, - "tests/aws/services/s3/test_s3.py::TestS3SSECEncryption::test_sse_c_with_versioning": 0.2325339389999499, - "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_crud_website_configuration": 0.10675842099976762, - "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_object_website_redirect_location": 0.28853335500002686, - "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_routing_rules_conditions": 0.5538015839999844, - "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_routing_rules_empty_replace_prefix": 0.4218117580001035, - "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_routing_rules_order": 0.24566422099996998, - "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_routing_rules_redirects": 0.15418536399999994, - "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_s3_static_website_hosting": 0.5326743449999185, - "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_s3_static_website_index": 0.14098655499981305, - "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_validate_website_configuration": 0.21079172700001436, - "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_website_hosting_404": 0.23581469900011598, - "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_website_hosting_http_methods": 0.13805479300015122, - "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_website_hosting_index_lookup": 0.26538665000009587, - "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_website_hosting_no_such_website": 0.12971963100005723, - "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_website_hosting_redirect_all": 0.3008390950000148, - "tests/aws/services/s3/test_s3.py::TestS3TerraformRawRequests::test_terraform_request_sequence": 0.056355477999886716, - "tests/aws/services/s3/test_s3_api.py::TestS3BucketAccelerateConfiguration::test_bucket_acceleration_configuration_crud": 0.09775074600020162, - "tests/aws/services/s3/test_s3_api.py::TestS3BucketAccelerateConfiguration::test_bucket_acceleration_configuration_exc": 0.13171436600009656, - "tests/aws/services/s3/test_s3_api.py::TestS3BucketCRUD::test_delete_bucket_with_objects": 0.4439311880000787, - "tests/aws/services/s3/test_s3_api.py::TestS3BucketCRUD::test_delete_versioned_bucket_with_objects": 0.47611263499993584, - "tests/aws/services/s3/test_s3_api.py::TestS3BucketEncryption::test_s3_bucket_encryption_sse_kms": 0.22821970900008637, - "tests/aws/services/s3/test_s3_api.py::TestS3BucketEncryption::test_s3_bucket_encryption_sse_kms_aws_managed_key": 0.27376531200025056, - "tests/aws/services/s3/test_s3_api.py::TestS3BucketEncryption::test_s3_bucket_encryption_sse_s3": 0.10672454899963668, - "tests/aws/services/s3/test_s3_api.py::TestS3BucketEncryption::test_s3_default_bucket_encryption": 0.08906281300005503, - "tests/aws/services/s3/test_s3_api.py::TestS3BucketEncryption::test_s3_default_bucket_encryption_exc": 0.48615996800003813, - "tests/aws/services/s3/test_s3_api.py::TestS3BucketObjectTagging::test_bucket_tagging_crud": 0.1398659509998197, - "tests/aws/services/s3/test_s3_api.py::TestS3BucketObjectTagging::test_bucket_tagging_exc": 0.08230643900014911, - "tests/aws/services/s3/test_s3_api.py::TestS3BucketObjectTagging::test_object_tagging_crud": 0.17728362899993044, - "tests/aws/services/s3/test_s3_api.py::TestS3BucketObjectTagging::test_object_tagging_exc": 0.22738538999988123, - "tests/aws/services/s3/test_s3_api.py::TestS3BucketObjectTagging::test_object_tagging_versioned": 0.22540512499972465, - "tests/aws/services/s3/test_s3_api.py::TestS3BucketObjectTagging::test_object_tags_delete_or_overwrite_object": 0.13468218399998477, - "tests/aws/services/s3/test_s3_api.py::TestS3BucketObjectTagging::test_put_object_with_tags": 0.2008917159998873, - "tests/aws/services/s3/test_s3_api.py::TestS3BucketObjectTagging::test_tagging_validation": 0.18187249199968392, - "tests/aws/services/s3/test_s3_api.py::TestS3BucketOwnershipControls::test_bucket_ownership_controls_exc": 0.10597805799989146, - "tests/aws/services/s3/test_s3_api.py::TestS3BucketOwnershipControls::test_crud_bucket_ownership_controls": 0.15845459900015157, - "tests/aws/services/s3/test_s3_api.py::TestS3BucketPolicy::test_bucket_policy_crud": 0.11764532200004396, - "tests/aws/services/s3/test_s3_api.py::TestS3BucketPolicy::test_bucket_policy_exc": 0.09594770200010316, - "tests/aws/services/s3/test_s3_api.py::TestS3BucketVersioning::test_bucket_versioning_crud": 0.15372339300006388, - "tests/aws/services/s3/test_s3_api.py::TestS3BucketVersioning::test_object_version_id_format": 0.09473242800027037, - "tests/aws/services/s3/test_s3_api.py::TestS3Multipart::test_upload_part_copy_no_copy_source_range": 0.18377705399984734, - "tests/aws/services/s3/test_s3_api.py::TestS3Multipart::test_upload_part_copy_range": 0.3336242160000893, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectCRUD::test_delete_object": 0.09109001700016961, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectCRUD::test_delete_object_on_suspended_bucket": 0.5858443820000048, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectCRUD::test_delete_object_versioned": 0.5704800819999036, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectCRUD::test_delete_objects": 0.08501625799999601, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectCRUD::test_delete_objects_versioned": 0.4963833659996908, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectCRUD::test_get_object_range": 0.2887471030001052, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectCRUD::test_get_object_with_version_unversioned_bucket": 0.46709645299984004, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectCRUD::test_list_object_versions_order_unversioned": 0.49798668100015675, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectCRUD::test_put_object_on_suspended_bucket": 0.6245519540002533, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectLock::test_delete_object_with_no_locking": 0.10015097800010153, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectLock::test_disable_versioning_on_locked_bucket": 0.06885807800017574, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectLock::test_get_object_lock_configuration_exc": 0.07211001099994974, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectLock::test_get_put_object_lock_configuration": 0.0927555130001565, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectLock::test_put_object_lock_configuration_exc": 0.10475707799992051, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectLock::test_put_object_lock_configuration_on_existing_bucket": 0.11324670199974207, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_multipart_if_match_etag": 0.145411164999814, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_multipart_if_match_with_delete": 0.1377557609998803, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_multipart_if_match_with_put": 0.1574362670003211, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_multipart_if_match_with_put_identical": 0.1489100280000457, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_multipart_if_none_match_with_delete": 0.14991892500006543, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_multipart_if_none_match_with_put": 0.10574941100003343, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_put_object_if_match": 0.1260302099999535, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_put_object_if_match_and_if_none_match_validation": 0.06800320200022725, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_put_object_if_match_validation": 0.08781395200003317, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_put_object_if_match_versioned_bucket": 0.16666263499996603, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_put_object_if_none_match": 0.10531259399999726, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_put_object_if_none_match_validation": 0.08690508699987731, - "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_put_object_if_none_match_versioned_bucket": 0.13878056299995478, - "tests/aws/services/s3/test_s3_api.py::TestS3PublicAccessBlock::test_crud_public_access_block": 0.10442721799995525, - "tests/aws/services/s3/test_s3_concurrency.py::TestParallelBucketCreation::test_parallel_bucket_creation": 0.4091629090000879, - "tests/aws/services/s3/test_s3_concurrency.py::TestParallelBucketCreation::test_parallel_object_creation_and_listing": 0.3298581260000901, - "tests/aws/services/s3/test_s3_concurrency.py::TestParallelBucketCreation::test_parallel_object_creation_and_read": 1.4871105049999187, - "tests/aws/services/s3/test_s3_concurrency.py::TestParallelBucketCreation::test_parallel_object_read_range": 2.3781634839997423, - "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_cors_expose_headers": 0.26299601999994593, - "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_cors_http_get_no_config": 0.11059570299994448, - "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_cors_http_options_no_config": 0.19529026800000793, - "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_cors_http_options_non_existent_bucket": 0.16047766800011232, - "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_cors_http_options_non_existent_bucket_ls_allowed": 0.07630728799995268, - "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_cors_list_buckets": 0.08087982799997917, - "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_cors_match_headers": 0.7954543320001903, - "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_cors_match_methods": 0.791354389000162, - "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_cors_match_origins": 0.6468330230002266, - "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_cors_no_config_localstack_allowed": 0.10572714799968708, - "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_cors_options_fails_partial_origin": 0.46664108200002374, - "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_cors_options_match_partial_origin": 0.16238156700023865, - "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_delete_cors": 0.18879966000008608, - "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_get_cors": 0.16890101500007404, - "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_put_cors": 0.1612013199996909, - "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_put_cors_default_values": 0.49030464499992377, - "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_put_cors_empty_origin": 0.16651709100005974, - "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_put_cors_invalid_rules": 0.16392229900020538, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListBuckets::test_list_buckets_by_bucket_region": 0.5753617619998295, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListBuckets::test_list_buckets_by_prefix_with_case_sensitivity": 0.4877304020003521, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListBuckets::test_list_buckets_when_continuation_token_is_empty": 0.4774720579998757, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListBuckets::test_list_buckets_with_continuation_token": 0.5392010909999954, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListBuckets::test_list_buckets_with_max_buckets": 0.4702490340002896, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListMultipartUploads::test_list_multipart_uploads_marker_common_prefixes": 0.500815153000076, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListMultipartUploads::test_list_multiparts_next_marker": 0.6280706240002019, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListMultipartUploads::test_list_multiparts_with_prefix_and_delimiter": 0.5066884009997921, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListMultipartUploads::test_s3_list_multiparts_timestamp_precision": 0.07271794400003273, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjectVersions::test_list_object_versions_pagination_common_prefixes": 0.579160321000245, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjectVersions::test_list_objects_versions_markers": 0.6866955700002109, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjectVersions::test_list_objects_versions_with_prefix": 0.6085627460001888, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjectVersions::test_list_objects_versions_with_prefix_only_and_pagination": 0.6143905960002485, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjectVersions::test_list_objects_versions_with_prefix_only_and_pagination_many_versions": 1.0610067210000125, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjectVersions::test_s3_list_object_versions_timestamp_precision": 0.10010286999977325, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjects::test_list_objects_marker_common_prefixes": 0.549131609999904, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjects::test_list_objects_next_marker": 0.5247440110001662, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjects::test_list_objects_with_prefix[%2F]": 0.4620072339998842, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjects::test_list_objects_with_prefix[/]": 0.4578297090001797, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjects::test_list_objects_with_prefix[]": 0.4594256899999891, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjects::test_s3_list_objects_empty_marker": 0.43054569100013396, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjects::test_s3_list_objects_timestamp_precision[ListObjectsV2]": 0.08514955700024984, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjects::test_s3_list_objects_timestamp_precision[ListObjects]": 0.08230598800014377, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjectsV2::test_list_objects_v2_continuation_common_prefixes": 0.56343386799972, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjectsV2::test_list_objects_v2_continuation_start_after": 0.6733004320001328, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjectsV2::test_list_objects_v2_with_prefix": 0.5296367320001991, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjectsV2::test_list_objects_v2_with_prefix_and_delimiter": 0.5071900099997038, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListParts::test_list_parts_empty_part_number_marker": 0.10055853099993328, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListParts::test_list_parts_pagination": 0.13538326100024278, - "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListParts::test_s3_list_parts_timestamp_precision": 0.08032150999997612, - "tests/aws/services/s3/test_s3_notifications_eventbridge.py::TestS3NotificationsToEventBridge::test_object_created_put": 1.850579843999867, - "tests/aws/services/s3/test_s3_notifications_eventbridge.py::TestS3NotificationsToEventBridge::test_object_created_put_in_different_region": 1.859392261000039, - "tests/aws/services/s3/test_s3_notifications_eventbridge.py::TestS3NotificationsToEventBridge::test_object_created_put_versioned": 5.227331998999944, - "tests/aws/services/s3/test_s3_notifications_eventbridge.py::TestS3NotificationsToEventBridge::test_object_put_acl": 2.344023051000022, - "tests/aws/services/s3/test_s3_notifications_eventbridge.py::TestS3NotificationsToEventBridge::test_restore_object": 1.193712018000042, - "tests/aws/services/s3/test_s3_notifications_lambda.py::TestS3NotificationsToLambda::test_create_object_by_presigned_request_via_dynamodb": 6.219591825999942, - "tests/aws/services/s3/test_s3_notifications_lambda.py::TestS3NotificationsToLambda::test_create_object_put_via_dynamodb": 4.834613696999895, - "tests/aws/services/s3/test_s3_notifications_lambda.py::TestS3NotificationsToLambda::test_invalid_lambda_arn": 0.44969479099995624, - "tests/aws/services/s3/test_s3_notifications_sns.py::TestS3NotificationsToSns::test_bucket_not_exist": 0.3844694500000969, - "tests/aws/services/s3/test_s3_notifications_sns.py::TestS3NotificationsToSns::test_bucket_notifications_with_filter": 1.654540071999918, - "tests/aws/services/s3/test_s3_notifications_sns.py::TestS3NotificationsToSns::test_invalid_topic_arn": 0.2610798559999239, - "tests/aws/services/s3/test_s3_notifications_sns.py::TestS3NotificationsToSns::test_object_created_put": 1.7721063370001957, - "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_bucket_notification_with_invalid_filter_rules": 0.26806965000014316, - "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_delete_objects": 0.8091075930003626, - "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_filter_rules_case_insensitive": 0.09599278599989702, - "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_invalid_sqs_arn": 0.40466162800021266, - "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_key_encoding": 0.6360358449999239, - "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_multiple_invalid_sqs_arns": 1.6823811089998344, - "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_notifications_with_filter": 0.7374661579999611, - "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_object_created_and_object_removed": 0.8377570879999894, - "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_object_created_complete_multipart_upload": 0.6632929200002309, - "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_object_created_copy": 0.6879901029999473, - "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_object_created_put": 0.7117907859999377, - "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_object_created_put_versioned": 1.0795005669999682, - "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_object_created_put_with_presigned_url_upload": 0.9020984859996588, - "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_object_put_acl": 0.8210032889999184, - "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_object_tagging_delete_event": 0.6923809959998835, - "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_object_tagging_put_event": 0.675230984000109, - "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_restore_object": 0.8077008180000576, - "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_xray_header": 1.6257866280000144, - "tests/aws/services/s3control/test_s3control.py::TestLegacyS3Control::test_lifecycle_public_access_block": 0.2650822660002632, - "tests/aws/services/s3control/test_s3control.py::TestLegacyS3Control::test_public_access_block_validations": 0.030718367999497787, - "tests/aws/services/s3control/test_s3control.py::TestS3ControlAccessPoint::test_access_point_already_exists": 0.0016026309999688237, - "tests/aws/services/s3control/test_s3control.py::TestS3ControlAccessPoint::test_access_point_bucket_not_exists": 0.001582073000008677, - "tests/aws/services/s3control/test_s3control.py::TestS3ControlAccessPoint::test_access_point_lifecycle": 0.001585088999945583, - "tests/aws/services/s3control/test_s3control.py::TestS3ControlAccessPoint::test_access_point_name_validation": 0.0015785870000399882, - "tests/aws/services/s3control/test_s3control.py::TestS3ControlAccessPoint::test_access_point_pagination": 0.0015803010001036455, - "tests/aws/services/s3control/test_s3control.py::TestS3ControlAccessPoint::test_access_point_public_access_block_configuration": 0.0018258380000588659, - "tests/aws/services/s3control/test_s3control.py::TestS3ControlPublicAccessBlock::test_crud_public_access_block": 0.001616847999912352, - "tests/aws/services/s3control/test_s3control.py::TestS3ControlPublicAccessBlock::test_empty_public_access_block": 0.0015959299998939969, - "tests/aws/services/scheduler/test_scheduler.py::test_list_schedules": 0.06473654300020826, - "tests/aws/services/scheduler/test_scheduler.py::test_tag_resource": 0.03454401999988477, - "tests/aws/services/scheduler/test_scheduler.py::test_untag_resource": 0.029484995999837338, - "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[ rate(10 minutes)]": 0.014520168999979433, - "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[at(2021-12-31)]": 0.01406694300021627, - "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[at(2021-12-31T23:59:59Z)]": 0.014427985000111221, - "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[cron()]": 0.014644978999967861, - "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[cron(0 1 * * * *)]": 0.016722698999956265, - "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[cron(0 dummy ? * MON-FRI *)]": 0.014415511000152037, - "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[cron(7 20 * * NOT *)]": 0.014060159999871757, - "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[cron(71 8 1 * ? *)]": 0.014412186000072325, - "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[cron(INVALID)]": 0.014088298000160648, - "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[rate( 10 minutes )]": 0.014142964000257052, - "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[rate()]": 0.014129424999964613, - "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[rate(-10 minutes)]": 0.01426772699983303, - "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[rate(10 minutess)]": 0.014296861000048011, - "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[rate(10 seconds)]": 0.01541575000010198, - "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[rate(10 years)]": 0.01397083100027885, - "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[rate(10)]": 0.014251185999910376, - "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[rate(foo minutes)]": 0.014347674000191546, - "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_valid_schedule_expression": 0.17735617000016646, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_call_lists_secrets_multiple_times": 0.05588091200024792, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_call_lists_secrets_multiple_times_snapshots": 0.0017102839999552089, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_can_recreate_delete_secret": 0.05320144200004506, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_create_and_update_secret[Valid/_+=.@-Name-a1b2]": 0.08582245899992813, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_create_and_update_secret[Valid/_+=.@-Name-a1b2c3-]": 0.08400914399999238, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_create_and_update_secret[Valid/_+=.@-Name]": 0.08342649799988067, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_create_and_update_secret[s-c64bdc03]": 0.10617051899976104, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_create_multi_secrets": 0.10075378999999884, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_create_multi_secrets_snapshot": 0.0016527470002074551, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_create_secret_version_from_empty_secret": 0.0384154750001926, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_create_secret_with_custom_id": 0.02371935599990138, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_delete_non_existent_secret_returns_as_if_secret_exists": 0.01980243199977849, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_deprecated_secret_version": 0.8921311730000525, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_deprecated_secret_version_stage": 0.19598640299977887, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_exp_raised_on_creation_of_secret_scheduled_for_deletion": 0.04052524700000504, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_first_rotate_secret_with_missing_lambda_arn": 0.03415313899972716, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_force_delete_deleted_secret": 0.06343453800013776, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_get_random_exclude_characters_and_symbols": 0.014892497999881016, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_get_secret_value": 0.07929810399991766, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_get_secret_value_errors": 0.04186563900020701, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_http_put_secret_value_custom_client_request_token_new_version_stages": 0.052725326999734534, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_http_put_secret_value_duplicate_req": 0.04800665799984927, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_http_put_secret_value_null_client_request_token_new_version_stages": 0.05607259899989003, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_http_put_secret_value_with_duplicate_client_request_token": 0.04856977800000095, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_http_put_secret_value_with_non_provided_client_request_token": 0.048856093000040346, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_invalid_secret_name[ Inv *?!]Name\\\\-]": 0.0909093599998414, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_invalid_secret_name[ Inv Name]": 0.0884453230003146, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_invalid_secret_name[ Inv*Name? ]": 0.08812485299995387, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_invalid_secret_name[Inv Name]": 0.0910302340000726, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_last_accessed_date": 0.055901790999541845, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_last_updated_date": 0.0812705659996027, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_list_secrets_filtering": 0.19445825799994054, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_no_client_request_token[CreateSecret]": 0.021968806000131735, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_no_client_request_token[PutSecretValue]": 0.02215613599992139, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_no_client_request_token[RotateSecret]": 0.022228556000072786, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_no_client_request_token[UpdateSecret]": 0.021936485999731303, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_non_versioning_version_stages_no_replacement": 0.2212101539998912, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_non_versioning_version_stages_replacement": 0.21189784899979713, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_put_secret_value_with_new_custom_client_request_token": 0.04821817199990619, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_put_secret_value_with_version_stages": 0.09866570299982413, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_resource_policy": 0.04875536800022928, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_rotate_secret_invalid_lambda_arn": 0.22239830100011204, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_rotate_secret_multiple_times_with_lambda_success": 2.8074591529998543, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_rotate_secret_with_lambda_success[None]": 2.324457150999933, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_rotate_secret_with_lambda_success[True]": 2.3816204770000695, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_secret_exists": 0.047205203999965306, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_secret_exists_snapshots": 0.04743087700012438, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_secret_not_found": 0.02683596899987606, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_secret_restore": 0.0487191580000399, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_secret_tags": 0.12996591800015267, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_secret_version_not_found": 0.044084173999863197, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_update_secret_description": 0.10208813200028999, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_update_secret_version_stages_current_pending": 0.23170256100024744, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_update_secret_version_stages_current_pending_cycle": 0.2815906990001622, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_update_secret_version_stages_current_pending_cycle_custom_stages_1": 0.2815802969998913, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_update_secret_version_stages_current_pending_cycle_custom_stages_2": 0.3018662529998437, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_update_secret_version_stages_current_pending_cycle_custom_stages_3": 0.26345162399979927, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_update_secret_version_stages_current_previous": 0.2167801920002148, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_update_secret_version_stages_return_type": 0.04996867699969698, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_update_secret_with_non_provided_client_request_token": 0.04588817600006223, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManagerMultiAccounts::test_cross_account_access": 0.17556910000030257, - "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManagerMultiAccounts::test_cross_account_access_non_default_key": 0.11041321000016069, - "tests/aws/services/ses/test_ses.py::TestSES::test_cannot_create_event_for_no_topic": 0.03867402200012293, - "tests/aws/services/ses/test_ses.py::TestSES::test_clone_receipt_rule_set": 0.7420435919998454, - "tests/aws/services/ses/test_ses.py::TestSES::test_creating_event_destination_without_configuration_set": 0.06147218899991458, - "tests/aws/services/ses/test_ses.py::TestSES::test_delete_template": 0.055291385000145965, - "tests/aws/services/ses/test_ses.py::TestSES::test_deleting_non_existent_configuration_set": 0.014689517000078922, - "tests/aws/services/ses/test_ses.py::TestSES::test_deleting_non_existent_configuration_set_event_destination": 0.029288249000046562, - "tests/aws/services/ses/test_ses.py::TestSES::test_get_identity_verification_attributes_for_domain": 0.011184211999989202, - "tests/aws/services/ses/test_ses.py::TestSES::test_get_identity_verification_attributes_for_email": 0.02469231699978991, - "tests/aws/services/ses/test_ses.py::TestSES::test_invalid_tags_send_email[-]": 0.014504962999808413, - "tests/aws/services/ses/test_ses.py::TestSES::test_invalid_tags_send_email[-test]": 0.014120386000058716, - "tests/aws/services/ses/test_ses.py::TestSES::test_invalid_tags_send_email[test-]": 0.014140259999976479, - "tests/aws/services/ses/test_ses.py::TestSES::test_invalid_tags_send_email[test-test_invalid_value:123]": 0.014377645000195116, - "tests/aws/services/ses/test_ses.py::TestSES::test_invalid_tags_send_email[test_invalid_name:123-test]": 0.014859668000099191, - "tests/aws/services/ses/test_ses.py::TestSES::test_invalid_tags_send_email[test_invalid_name:123-test_invalid_value:123]": 0.014124752999805423, - "tests/aws/services/ses/test_ses.py::TestSES::test_invalid_tags_send_email[test_invalid_name_len]": 0.014895663000061177, - "tests/aws/services/ses/test_ses.py::TestSES::test_invalid_tags_send_email[test_invalid_value_len]": 0.014644154999814418, - "tests/aws/services/ses/test_ses.py::TestSES::test_invalid_tags_send_email[test_priority_name_value]": 0.01433585699987816, - "tests/aws/services/ses/test_ses.py::TestSES::test_list_templates": 0.12444623799979126, - "tests/aws/services/ses/test_ses.py::TestSES::test_sending_to_deleted_topic": 0.4519943149998653, - "tests/aws/services/ses/test_ses.py::TestSES::test_sent_message_counter": 0.11887601800003722, - "tests/aws/services/ses/test_ses.py::TestSES::test_ses_sns_topic_integration_send_email": 1.5249144230001548, - "tests/aws/services/ses/test_ses.py::TestSES::test_ses_sns_topic_integration_send_raw_email": 1.4808552409997446, - "tests/aws/services/ses/test_ses.py::TestSES::test_ses_sns_topic_integration_send_templated_email": 1.5348211740001716, - "tests/aws/services/ses/test_ses.py::TestSES::test_special_tags_send_email[ses:feedback-id-a-this-marketing-campaign]": 0.015946234000011827, - "tests/aws/services/ses/test_ses.py::TestSES::test_special_tags_send_email[ses:feedback-id-b-that-campaign]": 0.014738378999936685, - "tests/aws/services/ses/test_ses.py::TestSES::test_trying_to_delete_event_destination_from_non_existent_configuration_set": 0.0895421500001703, - "tests/aws/services/ses/test_ses.py::TestSESRetrospection::test_send_email_can_retrospect": 1.5535481340000388, - "tests/aws/services/ses/test_ses.py::TestSESRetrospection::test_send_templated_email_can_retrospect": 0.07046403099980125, - "tests/aws/services/sns/test_sns.py::TestSNSCertEndpoint::test_cert_endpoint_host[]": 0.1878086090000579, - "tests/aws/services/sns/test_sns.py::TestSNSCertEndpoint::test_cert_endpoint_host[sns.us-east-1.amazonaws.com]": 0.13135641799976838, - "tests/aws/services/sns/test_sns.py::TestSNSMultiAccounts::test_cross_account_access": 0.10840783799994824, - "tests/aws/services/sns/test_sns.py::TestSNSMultiAccounts::test_cross_account_publish_to_sqs": 0.45179786500011687, - "tests/aws/services/sns/test_sns.py::TestSNSPlatformEndpoint::test_create_platform_endpoint_check_idempotency": 0.0017134989998339734, - "tests/aws/services/sns/test_sns.py::TestSNSPlatformEndpoint::test_publish_disabled_endpoint": 0.1046066119997704, - "tests/aws/services/sns/test_sns.py::TestSNSPlatformEndpoint::test_publish_to_gcm": 0.0017196020000938006, - "tests/aws/services/sns/test_sns.py::TestSNSPlatformEndpoint::test_publish_to_platform_endpoint_is_dispatched": 0.14217512200048077, - "tests/aws/services/sns/test_sns.py::TestSNSPlatformEndpoint::test_subscribe_platform_endpoint": 0.14423287799991158, - "tests/aws/services/sns/test_sns.py::TestSNSPublishCrud::test_empty_sns_message": 0.08678343000019595, - "tests/aws/services/sns/test_sns.py::TestSNSPublishCrud::test_message_structure_json_exc": 0.06404937399997834, - "tests/aws/services/sns/test_sns.py::TestSNSPublishCrud::test_publish_batch_too_long_message": 0.072661442000026, - "tests/aws/services/sns/test_sns.py::TestSNSPublishCrud::test_publish_by_path_parameters": 0.13352023399988866, - "tests/aws/services/sns/test_sns.py::TestSNSPublishCrud::test_publish_message_before_subscribe_topic": 0.1414173689997824, - "tests/aws/services/sns/test_sns.py::TestSNSPublishCrud::test_publish_message_by_target_arn": 0.19437532699998883, - "tests/aws/services/sns/test_sns.py::TestSNSPublishCrud::test_publish_non_existent_target": 0.031349337999699856, - "tests/aws/services/sns/test_sns.py::TestSNSPublishCrud::test_publish_too_long_message": 0.07178752200002236, - "tests/aws/services/sns/test_sns.py::TestSNSPublishCrud::test_publish_with_empty_subject": 0.03905522100035341, - "tests/aws/services/sns/test_sns.py::TestSNSPublishCrud::test_publish_wrong_arn_format": 0.03202460600004997, - "tests/aws/services/sns/test_sns.py::TestSNSPublishCrud::test_topic_publish_another_region": 0.054487076999976125, - "tests/aws/services/sns/test_sns.py::TestSNSPublishCrud::test_unknown_topic_publish": 0.03910054600009971, - "tests/aws/services/sns/test_sns.py::TestSNSPublishDelivery::test_delivery_lambda": 2.2127511040000627, - "tests/aws/services/sns/test_sns.py::TestSNSRetrospectionEndpoints::test_publish_sms_can_retrospect": 0.2469280330001311, - "tests/aws/services/sns/test_sns.py::TestSNSRetrospectionEndpoints::test_publish_to_platform_endpoint_can_retrospect": 0.20070034400009718, - "tests/aws/services/sns/test_sns.py::TestSNSRetrospectionEndpoints::test_subscription_tokens_can_retrospect": 1.096987512999931, - "tests/aws/services/sns/test_sns.py::TestSNSSMS::test_publish_sms": 0.014801035000118645, - "tests/aws/services/sns/test_sns.py::TestSNSSMS::test_publish_sms_endpoint": 0.15681767200021568, - "tests/aws/services/sns/test_sns.py::TestSNSSMS::test_publish_wrong_phone_format": 0.04975588399997832, - "tests/aws/services/sns/test_sns.py::TestSNSSMS::test_subscribe_sms_endpoint": 0.04861617599976853, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionCrud::test_create_subscriptions_with_attributes": 0.099858033999908, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionCrud::test_list_subscriptions": 0.350389370999892, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionCrud::test_list_subscriptions_by_topic_pagination": 1.5278777490000266, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionCrud::test_not_found_error_on_set_subscription_attributes": 0.3210580019997451, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionCrud::test_sns_confirm_subscription_wrong_token": 0.1249307759999283, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionCrud::test_subscribe_idempotency": 0.1070053400001143, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionCrud::test_subscribe_with_invalid_protocol": 0.04329845199981719, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionCrud::test_subscribe_with_invalid_topic": 0.04962113800002044, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionCrud::test_unsubscribe_from_non_existing_subscription": 0.11622247699983745, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionCrud::test_unsubscribe_idempotency": 0.08891710200009584, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionCrud::test_unsubscribe_wrong_arn_format": 0.032772241999964535, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionCrud::test_validate_set_sub_attributes": 0.26919723600008183, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionFirehose::test_publish_to_firehose_with_s3": 1.4317156449999402, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionHttp::test_dlq_external_http_endpoint[False]": 2.6617399490000935, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionHttp::test_dlq_external_http_endpoint[True]": 2.670507843999758, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionHttp::test_http_subscription_response": 0.07583789999989676, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionHttp::test_multiple_subscriptions_http_endpoint": 1.7040643949999321, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionHttp::test_redrive_policy_http_subscription": 1.1431565089999367, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionHttp::test_subscribe_external_http_endpoint[False]": 1.6252535150001677, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionHttp::test_subscribe_external_http_endpoint[True]": 1.6278609450000658, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionHttp::test_subscribe_external_http_endpoint_content_type[False]": 1.6047981459996663, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionHttp::test_subscribe_external_http_endpoint_content_type[True]": 1.6102829020001082, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionHttp::test_subscribe_external_http_endpoint_lambda_url_sig_validation": 2.0652085029998943, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionLambda::test_publish_lambda_verify_signature[1]": 4.21052824100002, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionLambda::test_publish_lambda_verify_signature[2]": 4.220908935999887, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionLambda::test_python_lambda_subscribe_sns_topic": 4.201105062999886, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionLambda::test_redrive_policy_lambda_subscription": 2.281751922000012, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionLambda::test_sns_topic_as_lambda_dead_letter_queue": 2.3690748289998282, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSES::test_email_sender": 2.1062701610001113, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSES::test_topic_email_subscription_confirmation": 0.0613843190001262, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_attribute_raw_subscribe": 0.14043716200012568, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_empty_or_wrong_message_attributes": 0.30405770299989854, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_message_attributes_not_missing": 0.2165908980000495, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_message_attributes_prefixes": 0.16983573100037574, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_message_structure_json_to_sqs": 0.20383019400014746, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_publish_batch_exceptions": 0.06677737200016054, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_publish_batch_messages_from_sns_to_sqs": 0.718092976999742, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_publish_batch_messages_without_topic": 0.03269055300029322, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_publish_sqs_from_sns": 0.2729365349998716, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_publish_sqs_from_sns_with_xray_propagation": 0.13533737500006282, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_publish_sqs_verify_signature[1]": 0.1442182679995767, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_publish_sqs_verify_signature[2]": 0.14241411000011794, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_publish_unicode_chars": 0.13244771899985608, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_redrive_policy_sqs_queue_subscription[False]": 0.19105041500006337, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_redrive_policy_sqs_queue_subscription[True]": 0.2012307749998854, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_sqs_topic_subscription_confirmation": 0.07600934200013398, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_subscribe_sqs_queue": 0.17572893500005193, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_subscribe_to_sqs_with_queue_url": 0.04586082099990563, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_subscription_after_failure_to_deliver": 1.5154996649998793, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_fifo_topic_to_regular_sqs[False]": 0.2703268760001265, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_fifo_topic_to_regular_sqs[True]": 0.2743641579997984, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_message_to_fifo_sqs[False]": 1.1747691789998953, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_message_to_fifo_sqs[True]": 1.193225558999984, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_message_to_fifo_sqs_ordering": 2.6259913149999647, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_publish_batch_messages_from_fifo_topic_to_fifo_queue[False]": 3.6269530710001163, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_publish_batch_messages_from_fifo_topic_to_fifo_queue[True]": 3.670615330000146, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_publish_fifo_messages_to_dlq[False]": 1.57372833300019, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_publish_fifo_messages_to_dlq[True]": 1.5611228119998941, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_publish_to_fifo_topic_deduplication_on_topic_level": 1.6716114720002224, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_publish_to_fifo_topic_to_sqs_queue_no_content_dedup[False]": 0.270900101000052, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_publish_to_fifo_topic_to_sqs_queue_no_content_dedup[True]": 0.2791799069998433, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_publish_to_fifo_with_target_arn": 0.0314391759998216, - "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_validations_for_fifo": 0.2316779709999537, - "tests/aws/services/sns/test_sns.py::TestSNSTopicCrud::test_create_duplicate_topic_check_idempotency": 0.08675210199999128, - "tests/aws/services/sns/test_sns.py::TestSNSTopicCrud::test_create_duplicate_topic_with_more_tags": 0.03345725600024707, - "tests/aws/services/sns/test_sns.py::TestSNSTopicCrud::test_create_topic_after_delete_with_new_tags": 0.05247338799995305, - "tests/aws/services/sns/test_sns.py::TestSNSTopicCrud::test_create_topic_test_arn": 0.3040474520000771, - "tests/aws/services/sns/test_sns.py::TestSNSTopicCrud::test_create_topic_with_attributes": 0.2718563550001818, - "tests/aws/services/sns/test_sns.py::TestSNSTopicCrud::test_tags": 0.08366482899987204, - "tests/aws/services/sns/test_sns.py::TestSNSTopicCrud::test_topic_delivery_policy_crud": 0.00167188100022031, - "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyAttributes::test_exists_filter_policy": 0.3149271800000406, - "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyAttributes::test_exists_filter_policy_attributes_array": 4.2838500000000295, - "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyAttributes::test_filter_policy": 5.322538917999736, - "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyBody::test_filter_policy_empty_array_payload": 0.1681889940000474, - "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyBody::test_filter_policy_for_batch": 3.3817883949998304, - "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyBody::test_filter_policy_ip_address_condition": 0.34092294700008097, - "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyBody::test_filter_policy_large_complex_payload": 0.1901719229997525, - "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyBody::test_filter_policy_on_message_body[False]": 5.328785093000079, - "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyBody::test_filter_policy_on_message_body[True]": 5.335835105999649, - "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyBody::test_filter_policy_on_message_body_array_attributes": 0.6143658079997749, - "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyBody::test_filter_policy_on_message_body_array_of_object_attributes": 0.3447897080000075, - "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyBody::test_filter_policy_on_message_body_dot_attribute": 5.5711469849995865, - "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyBody::test_filter_policy_on_message_body_or_attribute": 0.8270905840001888, - "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyConditions::test_policy_complexity": 0.0531667440000092, - "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyConditions::test_policy_complexity_with_or": 0.056513677999873835, - "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyConditions::test_validate_policy": 0.12628794700026447, - "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyConditions::test_validate_policy_exists_operator": 0.11934459000008246, - "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyConditions::test_validate_policy_nested_anything_but_operator": 0.16385757700004433, - "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyConditions::test_validate_policy_numeric_operator": 0.22346381299985296, - "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyConditions::test_validate_policy_string_operators": 0.22188522400028887, - "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyCrud::test_set_subscription_filter_policy_scope": 0.12184251700000459, - "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyCrud::test_sub_filter_policy_nested_property": 0.10428378799997517, - "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyCrud::test_sub_filter_policy_nested_property_constraints": 0.1783609770000112, - "tests/aws/services/sqs/test_sqs.py::TestSQSMultiAccounts::test_cross_account_access[domain]": 0.0885092009998516, - "tests/aws/services/sqs/test_sqs.py::TestSQSMultiAccounts::test_cross_account_access[path]": 0.08965208599988728, - "tests/aws/services/sqs/test_sqs.py::TestSQSMultiAccounts::test_cross_account_access[standard]": 0.09186907399998745, - "tests/aws/services/sqs/test_sqs.py::TestSQSMultiAccounts::test_cross_account_get_queue_url[domain]": 0.028839548999940234, - "tests/aws/services/sqs/test_sqs.py::TestSQSMultiAccounts::test_cross_account_get_queue_url[path]": 0.028285440000217932, - "tests/aws/services/sqs/test_sqs.py::TestSQSMultiAccounts::test_cross_account_get_queue_url[standard]": 0.029450716000155808, - "tests/aws/services/sqs/test_sqs.py::TestSQSMultiAccounts::test_delete_queue_multi_account[sqs]": 0.08494125000015629, - "tests/aws/services/sqs/test_sqs.py::TestSQSMultiAccounts::test_delete_queue_multi_account[sqs_query]": 0.08715545899985955, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_approximate_number_of_messages_delayed[sqs]": 3.1285736219999762, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_approximate_number_of_messages_delayed[sqs_query]": 3.129290998999977, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_batch_send_with_invalid_char_should_succeed[sqs]": 0.1270908670001063, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_batch_send_with_invalid_char_should_succeed[sqs_query]": 0.22059923300002993, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_change_message_visibility_after_visibility_timeout_expiration[sqs]": 2.1004230799999277, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_change_message_visibility_after_visibility_timeout_expiration[sqs_query]": 2.104264710000052, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_change_message_visibility_batch_with_too_large_batch[sqs]": 0.6533817720003299, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_change_message_visibility_batch_with_too_large_batch[sqs_query]": 0.666144739000174, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_change_message_visibility_not_permanent[sqs]": 0.09872305599969877, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_change_message_visibility_not_permanent[sqs_query]": 0.10121720500001175, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_change_visibility_on_deleted_message_raises_invalid_parameter_value[sqs]": 0.09164700400015136, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_change_visibility_on_deleted_message_raises_invalid_parameter_value[sqs_query]": 0.09225993399991239, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_and_send_to_fifo_queue[sqs]": 0.0639245849999952, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_and_send_to_fifo_queue[sqs_query]": 0.06466771899999912, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_and_update_queue_attributes[sqs]": 0.08166042800053219, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_and_update_queue_attributes[sqs_query]": 0.0852419220000229, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_fifo_queue_with_different_attributes_raises_error[sqs]": 0.14237455399984356, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_fifo_queue_with_different_attributes_raises_error[sqs_query]": 0.14584794799975498, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_fifo_queue_with_same_attributes_is_idempotent": 0.03638546800016229, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_after_internal_attributes_changes_works[sqs]": 0.08461451900006978, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_after_internal_attributes_changes_works[sqs_query]": 0.08387791699988156, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_after_modified_attributes[sqs]": 0.0018473369998446287, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_after_modified_attributes[sqs_query]": 0.001742742999795155, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_after_send[sqs]": 0.1156049849998908, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_after_send[sqs_query]": 0.11399804399979985, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_and_get_attributes[sqs]": 0.0300713070000711, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_and_get_attributes[sqs_query]": 0.030713987000126508, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_recently_deleted[sqs]": 0.03490848999990703, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_recently_deleted[sqs_query]": 0.03759918199989443, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_recently_deleted_cache[sqs]": 1.5617488079999475, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_recently_deleted_cache[sqs_query]": 1.5537983030001215, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_recently_deleted_can_be_disabled[sqs]": 0.0437312290000591, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_recently_deleted_can_be_disabled[sqs_query]": 0.04178748599974824, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_with_default_arguments_works_with_modified_attributes[sqs]": 0.0017319819999102037, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_with_default_arguments_works_with_modified_attributes[sqs_query]": 0.0017637509999985923, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_with_default_attributes_is_idempotent": 0.037087251000230026, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_with_different_attributes_raises_exception[sqs]": 0.19841330899998866, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_with_different_attributes_raises_exception[sqs_query]": 0.19759350800018183, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_with_same_attributes_is_idempotent": 0.03681480100021872, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_with_tags[sqs]": 0.02771976100007123, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_with_tags[sqs_query]": 0.028128327000104036, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_without_attributes_is_idempotent": 0.03457833800007393, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_standard_queue_with_fifo_attribute_raises_error[sqs]": 0.07816115999958129, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_standard_queue_with_fifo_attribute_raises_error[sqs_query]": 0.07853448499986371, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_dead_letter_queue_chain[sqs]": 0.0016762899999775982, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_dead_letter_queue_chain[sqs_query]": 0.001691298999958235, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_dead_letter_queue_config": 0.035292416999936904, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_dead_letter_queue_execution_lambda_mapping_preserves_id[sqs]": 0.0017832300002282864, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_dead_letter_queue_execution_lambda_mapping_preserves_id[sqs_query]": 0.001706326000203262, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_dead_letter_queue_list_sources[sqs]": 0.05690664400003698, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_dead_letter_queue_list_sources[sqs_query]": 0.059426621000284285, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_dead_letter_queue_max_receive_count[sqs]": 0.12249692500017773, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_dead_letter_queue_max_receive_count[sqs_query]": 0.12670814600005542, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_dead_letter_queue_message_attributes": 0.7547270870002194, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_dead_letter_queue_with_fifo_and_content_based_deduplication[sqs]": 0.1716114559997095, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_dead_letter_queue_with_fifo_and_content_based_deduplication[sqs_query]": 0.17039014400006636, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_deduplication_interval[sqs]": 0.0018160620002163341, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_deduplication_interval[sqs_query]": 0.0016980219998004031, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_after_visibility_timeout[sqs]": 1.1238981879998846, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_after_visibility_timeout[sqs_query]": 1.12396465300003, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_batch_from_lambda[sqs]": 0.001824156000111543, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_batch_from_lambda[sqs_query]": 0.001676069000041025, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_batch_invalid_msg_id[sqs-]": 0.10434132299974408, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_batch_invalid_msg_id[sqs-invalid:id]": 0.09337309200009258, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_batch_invalid_msg_id[sqs-testLongIdtestLongIdtestLongIdtestLongIdtestLongIdtestLongIdtestLongIdtestLongIdtestLongIdtestLongId]": 0.0851970149999488, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_batch_invalid_msg_id[sqs_query-]": 0.08075875300005464, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_batch_invalid_msg_id[sqs_query-invalid:id]": 0.0700619810002081, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_batch_invalid_msg_id[sqs_query-testLongIdtestLongIdtestLongIdtestLongIdtestLongIdtestLongIdtestLongIdtestLongIdtestLongIdtestLongId]": 0.08519973500006017, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_batch_with_too_large_batch[sqs]": 0.6403513139996448, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_batch_with_too_large_batch[sqs_query]": 0.6511461169998256, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_deletes_with_change_visibility_timeout[sqs]": 0.12780724100048246, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_deletes_with_change_visibility_timeout[sqs_query]": 0.130821350999895, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_with_deleted_receipt_handle[sqs]": 0.10773744100015392, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_with_deleted_receipt_handle[sqs_query]": 0.11022989699995378, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_with_illegal_receipt_handle[sqs]": 0.030625260999840975, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_with_illegal_receipt_handle[sqs_query]": 0.029475284999989526, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_disallow_queue_name_with_slashes": 0.0017510960001345666, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_extend_message_visibility_timeout_set_in_queue[sqs]": 6.1763415559998975, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_extend_message_visibility_timeout_set_in_queue[sqs_query]": 6.99896832599984, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_external_endpoint[sqs]": 0.13332469899955868, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_external_endpoint[sqs_query]": 0.06357867199994871, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_external_host_via_header_complete_message_lifecycle": 0.08966200499980914, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_external_hostname_via_host_header": 0.030336982000108037, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_approx_number_of_messages[sqs]": 0.2440396839999721, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_approx_number_of_messages[sqs_query]": 0.24859574299989617, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_change_to_high_throughput_after_creation[sqs]": 0.3252113610001288, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_change_to_high_throughput_after_creation[sqs_query]": 0.3285393009998643, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_change_to_regular_throughput_after_creation[sqs]": 0.22915429699992274, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_change_to_regular_throughput_after_creation[sqs_query]": 0.23396986999978253, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_content_based_message_deduplication_arrives_once[sqs]": 1.096609318999981, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_content_based_message_deduplication_arrives_once[sqs_query]": 1.0993522509998002, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_deduplication_arrives_once_after_delete[sqs-False]": 1.1530038319999676, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_deduplication_arrives_once_after_delete[sqs-True]": 1.142957158999934, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_deduplication_arrives_once_after_delete[sqs_query-False]": 1.1538362839999081, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_deduplication_arrives_once_after_delete[sqs_query-True]": 1.1508683340000516, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_deduplication_not_on_message_group_id[sqs-False]": 1.1273222679999435, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_deduplication_not_on_message_group_id[sqs-True]": 1.125189490999901, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_deduplication_not_on_message_group_id[sqs_query-False]": 1.136232012000164, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_deduplication_not_on_message_group_id[sqs_query-True]": 1.1410946129999502, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_delete_after_visibility_timeout[sqs]": 1.1900849189996734, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_delete_after_visibility_timeout[sqs_query]": 1.1868489870003032, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_delete_message_with_expired_receipt_handle[sqs]": 0.0016842699999415345, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_delete_message_with_expired_receipt_handle[sqs_query]": 0.0016181760001927614, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_empty_message_groups_added_back_to_queue[sqs]": 0.18696485400005258, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_empty_message_groups_added_back_to_queue[sqs_query]": 0.20153134300016973, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_high_throughput_ordering[sqs]": 0.1605448459999934, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_high_throughput_ordering[sqs_query]": 0.1618325450001521, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_message_attributes[sqs]": 0.15777157200000147, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_message_attributes[sqs_query]": 0.15983810199986692, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_message_group_visibility": 2.116639133000035, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_message_group_visibility_after_change_message_visibility[sqs]": 2.1119719250000344, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_message_group_visibility_after_change_message_visibility[sqs_query]": 2.1323065569999926, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_message_group_visibility_after_delete[sqs]": 0.2861931179995736, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_message_group_visibility_after_delete[sqs_query]": 0.2792689949999385, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_message_group_visibility_after_partial_delete[sqs]": 0.2666657039999336, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_message_group_visibility_after_partial_delete[sqs_query]": 0.26278220699987287, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_message_group_visibility_after_terminate_visibility_timeout[sqs]": 0.1317856970001685, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_message_group_visibility_after_terminate_visibility_timeout[sqs_query]": 0.13611670099999174, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_messages_in_order_after_timeout[sqs]": 2.1200272959999893, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_messages_in_order_after_timeout[sqs_query]": 2.110146029999896, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_queue_requires_suffix": 0.014419339000141917, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_queue_send_message_with_delay_on_queue_works[sqs]": 4.1073976669999865, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_queue_send_message_with_delay_on_queue_works[sqs_query]": 4.103934449999997, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_queue_send_message_with_delay_seconds_fails[sqs]": 0.15873957599978894, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_queue_send_message_with_delay_seconds_fails[sqs_query]": 0.15844080500028213, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_queue_send_multiple_messages_multiple_single_receives[sqs]": 0.23905085400019743, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_queue_send_multiple_messages_multiple_single_receives[sqs_query]": 0.24499686600006498, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_receive_message_group_id_ordering[sqs]": 0.130339586999753, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_receive_message_group_id_ordering[sqs_query]": 0.13560452899992015, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_receive_message_visibility_timeout_shared_in_group[sqs]": 2.166630939000015, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_receive_message_visibility_timeout_shared_in_group[sqs_query]": 2.1870424009998715, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_receive_message_with_zero_visibility_timeout[sqs]": 0.17436443499968846, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_receive_message_with_zero_visibility_timeout[sqs_query]": 0.177297438000096, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_sequence_number_increases[sqs]": 0.09306234799987578, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_sequence_number_increases[sqs_query]": 0.09600766899984592, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_set_content_based_deduplication_strategy[sqs]": 0.08447075000003679, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_set_content_based_deduplication_strategy[sqs_query]": 0.08740954700010661, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_get_list_queues_with_query_auth": 0.020054235999623415, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_get_queue_url_contains_localstack_host[sqs]": 0.029148404000125083, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_get_queue_url_contains_localstack_host[sqs_query]": 0.03736458600019432, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_get_queue_url_multi_region[domain]": 0.05032721400016271, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_get_queue_url_multi_region[path]": 0.04982286899985411, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_get_queue_url_multi_region[standard]": 0.05133654500014018, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_get_specific_queue_attribute_response[sqs]": 0.05487656100035565, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_get_specific_queue_attribute_response[sqs_query]": 0.05602282099994227, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_inflight_message_requeue": 4.594766348000121, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_invalid_batch_id[sqs]": 0.14218042199991032, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_invalid_batch_id[sqs_query]": 0.14021204800019405, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_invalid_dead_letter_arn_rejected_before_lookup": 0.0017659989998719539, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_invalid_receipt_handle_should_return_error_message[sqs]": 0.034065012999690225, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_invalid_receipt_handle_should_return_error_message[sqs_query]": 0.04001393200042003, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_invalid_string_attributes_cause_invalid_parameter_value_error[sqs]": 0.02937050199989244, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_invalid_string_attributes_cause_invalid_parameter_value_error[sqs_query]": 0.029052900000351656, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_list_queue_tags[sqs]": 0.03548649400022441, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_list_queue_tags[sqs_query]": 0.03545024400023067, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_list_queues": 0.09656643399989662, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_list_queues_multi_region_with_endpoint_strategy_domain": 0.06551443199987261, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_list_queues_multi_region_with_endpoint_strategy_standard": 0.05901915499998722, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_list_queues_multi_region_without_endpoint_strategy": 0.06714502799991351, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_list_queues_pagination": 0.273624343000165, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_marker_serialization_json_protocol[\"{\\\\\"foo\\\\\": \\\\\"ba\\\\rr\\\\\"}\"]": 0.0782920600001944, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_marker_serialization_json_protocol[{\"foo\": \"ba\\rr\", \"foo2\": \"ba"r"\"}]": 0.0781768069998634, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_message_deduplication_id_too_long": 0.16585574699979588, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_message_group_id_too_long": 0.16494935300011093, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_message_retention": 3.079372381000212, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_message_retention_fifo": 3.06956698099998, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_message_retention_with_inflight": 5.607780848000175, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_message_system_attribute_names_with_attribute_names[sqs]": 0.12120940499994504, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_message_system_attribute_names_with_attribute_names[sqs_query]": 0.12016031999996812, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_message_with_attributes_should_be_enqueued[sqs]": 0.07769416399992224, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_message_with_attributes_should_be_enqueued[sqs_query]": 0.07211073899998155, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_message_with_carriage_return[sqs]": 0.06224843200016039, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_message_with_carriage_return[sqs_query]": 0.0630495200000496, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_non_existent_queue": 0.2103003729998818, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_posting_to_fifo_requires_deduplicationid_group_id[sqs]": 0.23616783300008137, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_posting_to_fifo_requires_deduplicationid_group_id[sqs_query]": 0.23538207599972338, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_posting_to_queue_via_queue_name[sqs]": 0.04631885000026159, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_posting_to_queue_via_queue_name[sqs_query]": 0.046134704000451165, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_publish_get_delete_message[sqs]": 0.09566594600005374, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_publish_get_delete_message[sqs_query]": 0.09304840200002218, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_publish_get_delete_message_batch[sqs]": 0.2508977639997738, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_publish_get_delete_message_batch[sqs_query]": 0.2473337899998569, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_purge_queue[sqs]": 1.2130526089999876, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_purge_queue[sqs_query]": 1.2271326029997454, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_purge_queue_clears_fifo_deduplication_cache[sqs]": 0.09395793500016225, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_purge_queue_clears_fifo_deduplication_cache[sqs_query]": 0.09408482699996057, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_purge_queue_deletes_delayed_messages[sqs]": 3.1578335469996546, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_purge_queue_deletes_delayed_messages[sqs_query]": 3.150445915000091, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_purge_queue_deletes_inflight_messages[sqs]": 4.239921435000042, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_purge_queue_deletes_inflight_messages[sqs_query]": 4.259177208999972, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_queue_list_nonexistent_tags[sqs]": 0.02744931699976405, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_queue_list_nonexistent_tags[sqs_query]": 0.03053503500041188, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_after_visibility_timeout[sqs]": 1.7357519829997727, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_after_visibility_timeout[sqs_query]": 1.9993890450000436, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_empty_queue[sqs]": 1.0934699649999402, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_empty_queue[sqs_query]": 1.0937296019999394, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_message_attribute_names_filters[sqs]": 0.23568316499972752, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_message_attribute_names_filters[sqs_query]": 0.23579489400026432, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_message_attributes_timestamp_types[sqs]": 0.0641738990000249, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_message_attributes_timestamp_types[sqs_query]": 0.06364502499991431, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_message_message_attribute_names_filters[sqs]": 0.260924138999826, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_message_message_attribute_names_filters[sqs_query]": 0.26576942599990616, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_message_message_system_attribute_names_filters[sqs]": 0.15556281399994987, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_message_message_system_attribute_names_filters[sqs_query]": 0.15865734800013342, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_message_wait_time_seconds_and_max_number_of_messages_does_not_block[sqs]": 0.09221760599984918, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_message_wait_time_seconds_and_max_number_of_messages_does_not_block[sqs_query]": 0.10019635200001176, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_message_with_visibility_timeout_updates_timeout[sqs]": 0.08942372500018791, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_message_with_visibility_timeout_updates_timeout[sqs_query]": 0.09210011599998325, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_terminate_visibility_timeout[sqs]": 0.09255143700011104, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_terminate_visibility_timeout[sqs_query]": 0.09471740000003592, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_redrive_policy_attribute_validity[sqs]": 0.0016427070002009714, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_redrive_policy_attribute_validity[sqs_query]": 0.0016145750000760017, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_remove_message_with_old_receipt_handle[sqs]": 2.079922900999918, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_remove_message_with_old_receipt_handle[sqs_query]": 2.0788629090000086, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_batch_message_size": 0.2304874590001873, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_batch_missing_deduplication_id_for_fifo_queue[sqs]": 0.14121915499981696, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_batch_missing_deduplication_id_for_fifo_queue[sqs_query]": 0.1398020109998015, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_batch_missing_message_group_id_for_fifo_queue[sqs]": 0.14123457600021538, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_batch_missing_message_group_id_for_fifo_queue[sqs_query]": 0.14369791599983728, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_batch_receive_multiple[sqs]": 0.10470392299998821, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_batch_receive_multiple[sqs_query]": 0.10610120000001189, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_delay_and_wait_time[sqs]": 1.83068551700012, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_delay_and_wait_time[sqs_query]": 1.9986929220001457, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_empty_message[sqs]": 0.1411468659998718, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_empty_message[sqs_query]": 0.14524913099990044, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_batch[sqs]": 0.11198394099983489, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_batch[sqs_query]": 0.11284279600022273, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_batch_with_empty_list[sqs]": 0.029128603999879488, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_batch_with_empty_list[sqs_query]": 0.029053352000119048, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_batch_with_oversized_contents[sqs]": 0.14656391800031088, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_batch_with_oversized_contents[sqs_query]": 0.15372318899972015, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_batch_with_oversized_contents_with_updated_maximum_message_size[sqs]": 0.11996059400007653, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_batch_with_oversized_contents_with_updated_maximum_message_size[sqs_query]": 0.11482575600007294, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_to_standard_queue_with_empty_message_group_id": 0.0843245849998766, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_attributes[sqs]": 0.0619033830000717, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_attributes[sqs_query]": 0.06354190699994433, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_binary_attributes[sqs]": 0.1032633539998642, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_binary_attributes[sqs_query]": 0.10865792499998861, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_delay_0_works_for_fifo[sqs]": 0.06116502800023227, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_delay_0_works_for_fifo[sqs_query]": 0.06282179100003304, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_empty_string_attribute[sqs]": 0.1409212819999084, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_empty_string_attribute[sqs_query]": 0.1419540169999891, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_invalid_fifo_parameters[sqs]": 0.001704833000076178, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_invalid_fifo_parameters[sqs_query]": 0.0015828660000352102, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_invalid_payload_characters[sqs]": 0.028361683999946763, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_invalid_payload_characters[sqs_query]": 0.029091920999690046, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_invalid_string_attributes[sqs]": 0.12951364099967577, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_invalid_string_attributes[sqs_query]": 0.13666826300004686, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_updated_maximum_message_size[sqs]": 0.17548180400012825, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_updated_maximum_message_size[sqs_query]": 0.1780025170000954, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_oversized_message[sqs]": 0.14872975399998722, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_oversized_message[sqs_query]": 0.15144463799970254, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_receive_max_number_of_messages[sqs]": 0.16603263400020296, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_receive_max_number_of_messages[sqs_query]": 0.1647934919999443, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_receive_message[sqs]": 0.06343816400021751, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_receive_message[sqs_query]": 0.06542828500005271, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_receive_message_encoded_content[sqs]": 0.06171695800003363, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_receive_message_encoded_content[sqs_query]": 0.062285409999958574, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_receive_message_multiple_queues": 0.08913700200014318, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_receive_wait_time_seconds[sqs]": 0.23018267099973855, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_receive_wait_time_seconds[sqs_query]": 0.23131491300000562, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sent_message_retains_attributes_after_receive[sqs]": 0.09148719300014818, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sent_message_retains_attributes_after_receive[sqs_query]": 0.08191667899995991, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sequence_number[sqs]": 0.0846661140001288, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sequence_number[sqs_query]": 0.08630673999982719, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_set_empty_queue_policy[sqs]": 0.06252180099977522, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_set_empty_queue_policy[sqs_query]": 0.06527362600036213, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_set_empty_redrive_policy[sqs]": 0.06911295999975664, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_set_empty_redrive_policy[sqs_query]": 0.07062320800014277, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_set_queue_policy[sqs]": 0.04103634700004477, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_set_queue_policy[sqs_query]": 0.04448703799994291, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_set_unsupported_attribute_fifo[sqs]": 0.24487677100000838, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_set_unsupported_attribute_fifo[sqs_query]": 0.24417458199968678, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_set_unsupported_attribute_standard[sqs]": 0.21971754900027918, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_set_unsupported_attribute_standard[sqs_query]": 0.2244783090002329, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sqs_fifo_message_group_scope_no_throughput_setting[sqs]": 0.15856955499998548, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sqs_fifo_message_group_scope_no_throughput_setting[sqs_query]": 0.1586945190001643, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sqs_fifo_same_dedup_id_different_message_groups[sqs]": 0.15871796900000845, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sqs_fifo_same_dedup_id_different_message_groups[sqs_query]": 0.1584513949999291, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sqs_permission_lifecycle[sqs]": 0.2439868670001033, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sqs_permission_lifecycle[sqs_query]": 0.2773598139997375, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sse_kms_and_sqs_are_mutually_exclusive[sqs]": 0.0017553459999817278, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sse_kms_and_sqs_are_mutually_exclusive[sqs_query]": 0.0016104659998745774, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sse_queue_attributes[sqs]": 0.10239072200033661, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sse_queue_attributes[sqs_query]": 0.10263982600008603, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_standard_queue_cannot_have_fifo_suffix": 0.013417597000170645, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_successive_purge_calls_fail[sqs]": 0.1480879369999002, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_successive_purge_calls_fail[sqs_query]": 0.14974695700016127, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_system_attributes_have_no_effect_on_attr_md5[sqs]": 0.07050675699997555, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_system_attributes_have_no_effect_on_attr_md5[sqs_query]": 0.07163318099992466, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_tag_queue_overwrites_existing_tag[sqs]": 0.040126752999867676, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_tag_queue_overwrites_existing_tag[sqs_query]": 0.04116827699976966, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_tag_untag_queue[sqs]": 0.10257306300013624, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_tag_untag_queue[sqs_query]": 0.10596567800007506, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_tags_case_sensitive[sqs]": 0.034960533000003124, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_tags_case_sensitive[sqs_query]": 0.0358595640002477, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_terminate_visibility_timeout_after_receive[sqs]": 0.09747036500016293, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_terminate_visibility_timeout_after_receive[sqs_query]": 0.10153015799983223, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_too_many_entries_in_batch_request[sqs]": 1.202883624999913, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_too_many_entries_in_batch_request[sqs_query]": 0.1418133290003425, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_untag_queue_ignores_non_existing_tag[sqs]": 0.04163470799994684, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_untag_queue_ignores_non_existing_tag[sqs_query]": 0.042441385000302034, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_wait_time_seconds_queue_attribute_waits_correctly[sqs]": 1.06035360199985, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_wait_time_seconds_queue_attribute_waits_correctly[sqs_query]": 1.060866674999943, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_wait_time_seconds_waits_correctly[sqs]": 1.0629236440001932, - "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_wait_time_seconds_waits_correctly[sqs_query]": 1.0625854879997405, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_endpoint_strategy_with_multi_region[domain]": 0.12016148999987308, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_endpoint_strategy_with_multi_region[off]": 0.117180031000089, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_endpoint_strategy_with_multi_region[path]": 0.11707227099986994, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_endpoint_strategy_with_multi_region[standard]": 0.16994413800011898, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_create_queue_fails": 0.03213934900009008, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_delete_queue[domain]": 0.044069312999909016, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_delete_queue[path]": 0.04841333699982897, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_delete_queue[standard]": 0.044473791999962486, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_list_queues_fails": 0.03081042299982073, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_list_queues_fails_json_format": 0.0018364479999490868, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_on_deleted_queue_fails[sqs]": 0.05216581900003803, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_on_deleted_queue_fails[sqs_query]": 0.053054862999943, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_attributes_all": 0.049868779000007635, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_attributes_json_format": 0.0017271340000206692, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_attributes_of_fifo_queue": 0.03838333699991381, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_attributes_with_invalid_arg_returns_error": 0.038590367999859154, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_attributes_with_query_args": 0.03770597600009751, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_attributes_works_without_authparams[domain]": 0.03759939299970938, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_attributes_works_without_authparams[path]": 0.039019493000068906, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_attributes_works_without_authparams[standard]": 0.03723196200030543, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_url_work_for_different_queue[domain]": 0.053079875999856085, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_url_work_for_different_queue[path]": 0.053170555000178865, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_url_work_for_different_queue[standard]": 0.05345216099999561, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_url_works_for_same_queue[domain]": 0.038537932999815894, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_url_works_for_same_queue[path]": 0.04194190200018966, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_url_works_for_same_queue[standard]": 0.039632486000073186, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_send_and_receive_messages": 0.11578557900020314, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_without_query_json_format_returns_returns_xml": 0.028619582000146693, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_without_query_returns_unknown_operation": 0.029183132000071055, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_invalid_action_raises_exception": 0.030459909999990487, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_overwrite_queue_url_in_params": 0.05209754800011979, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_queue_url_format_path_strategy": 0.02189198700034467, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_send_message_via_queue_url_with_json_protocol": 1.08785309100017, - "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_valid_action_with_missing_parameter_raises_exception": 0.030162009999685324, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_fifo_list_messages_as_botocore_endpoint_url[json-domain]": 0.09995854500016321, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_fifo_list_messages_as_botocore_endpoint_url[json-path]": 0.09882505799987484, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_fifo_list_messages_as_botocore_endpoint_url[json-standard]": 0.10015845800012357, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_fifo_list_messages_as_botocore_endpoint_url[query-domain]": 0.1019700090000697, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_fifo_list_messages_as_botocore_endpoint_url[query-path]": 0.10289015600005769, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_fifo_list_messages_as_botocore_endpoint_url[query-standard]": 0.1001785179998933, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_as_botocore_endpoint_url[json-domain]": 0.07675527799983684, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_as_botocore_endpoint_url[json-path]": 0.07649979699999676, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_as_botocore_endpoint_url[json-standard]": 0.08343940200006728, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_as_botocore_endpoint_url[query-domain]": 0.07989415000020017, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_as_botocore_endpoint_url[query-path]": 0.0782456640001783, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_as_botocore_endpoint_url[query-standard]": 0.08314052700006869, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_as_json[domain]": 0.07769091800014394, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_as_json[path]": 0.07524303300010615, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_as_json[standard]": 0.07476482099991699, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_has_no_side_effects[domain]": 0.0969828409999991, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_has_no_side_effects[path]": 0.09637490599993725, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_has_no_side_effects[standard]": 0.09739994500000648, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_delayed_messages[domain]": 0.10563322199982395, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_delayed_messages[path]": 0.10420602699969095, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_delayed_messages[standard]": 0.10341498599996157, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_invalid_action_raises_error[json-domain]": 0.02774219699972491, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_invalid_action_raises_error[json-path]": 0.02775501099995381, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_invalid_action_raises_error[json-standard]": 0.0293243999999504, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_invalid_action_raises_error[query-domain]": 0.02788348900003257, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_invalid_action_raises_error[query-path]": 0.028325274999588146, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_invalid_action_raises_error[query-standard]": 0.03040905499983637, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_invalid_queue_url[domain]": 0.01781294199986405, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_invalid_queue_url[path]": 0.017977343000211476, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_invalid_queue_url[standard]": 0.019290456999897287, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_invisible_messages[domain]": 0.12260086700007378, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_invisible_messages[path]": 0.12060631200006355, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_invisible_messages[standard]": 0.12049991100025181, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_non_existent_queue[domain]": 0.02259441500018511, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_non_existent_queue[path]": 0.02256781199980651, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_non_existent_queue[standard]": 0.02256634400009716, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_queue_url_in_path[domain]": 0.0806629950000115, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_queue_url_in_path[path]": 0.0794753430000128, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_queue_url_in_path[standard]": 0.07870387499997378, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_without_queue_url[domain]": 0.017130400999803896, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_without_queue_url[path]": 0.016935114000034446, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_without_queue_url[standard]": 0.017896442000164825, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsOverrideHeaders::test_receive_message_override_max_number_of_messages": 0.4730863470001623, - "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsOverrideHeaders::test_receive_message_override_message_wait_time_seconds": 25.236502244999883, - "tests/aws/services/sqs/test_sqs_move_task.py::test_basic_move_task_workflow": 1.8188541050001277, - "tests/aws/services/sqs/test_sqs_move_task.py::test_cancel_with_invalid_source_arn_in_task_handle": 0.050512659000105486, - "tests/aws/services/sqs/test_sqs_move_task.py::test_cancel_with_invalid_task_handle": 0.054027649000090605, - "tests/aws/services/sqs/test_sqs_move_task.py::test_cancel_with_invalid_task_id_in_task_handle": 0.07478179100007765, - "tests/aws/services/sqs/test_sqs_move_task.py::test_destination_needs_to_exist": 0.10798726200005149, - "tests/aws/services/sqs/test_sqs_move_task.py::test_move_task_cancel": 1.830104909000056, - "tests/aws/services/sqs/test_sqs_move_task.py::test_move_task_delete_destination_queue_while_running": 1.872047072999976, - "tests/aws/services/sqs/test_sqs_move_task.py::test_move_task_with_throughput_limit": 3.3854972010001347, - "tests/aws/services/sqs/test_sqs_move_task.py::test_move_task_workflow_with_default_destination": 1.8002463529999204, - "tests/aws/services/sqs/test_sqs_move_task.py::test_move_task_workflow_with_multiple_sources_as_default_destination": 2.486964338999769, - "tests/aws/services/sqs/test_sqs_move_task.py::test_source_needs_redrive_policy": 0.09210000499979287, - "tests/aws/services/sqs/test_sqs_move_task.py::test_start_multiple_move_tasks": 0.6980477259999134, - "tests/aws/services/ssm/test_ssm.py::TestSSM::test_describe_parameters": 0.01527112999997371, - "tests/aws/services/ssm/test_ssm.py::TestSSM::test_get_inexistent_maintenance_window": 0.015372413000022789, - "tests/aws/services/ssm/test_ssm.py::TestSSM::test_get_inexistent_secret": 0.035112855000079435, - "tests/aws/services/ssm/test_ssm.py::TestSSM::test_get_parameter_by_arn": 0.059525974000052884, - "tests/aws/services/ssm/test_ssm.py::TestSSM::test_get_parameters_and_secrets": 0.12538370300012502, - "tests/aws/services/ssm/test_ssm.py::TestSSM::test_get_parameters_by_path_and_filter_by_labels": 0.06377923099989857, - "tests/aws/services/ssm/test_ssm.py::TestSSM::test_get_secret_parameter": 0.06594547800000328, - "tests/aws/services/ssm/test_ssm.py::TestSSM::test_hierarchical_parameter[///b//c]": 0.06198107999989588, - "tests/aws/services/ssm/test_ssm.py::TestSSM::test_hierarchical_parameter[/b/c]": 0.062209626000139906, - "tests/aws/services/ssm/test_ssm.py::TestSSM::test_parameters_with_path": 0.15899454299983518, - "tests/aws/services/ssm/test_ssm.py::TestSSM::test_put_parameters": 0.07763973700025417, - "tests/aws/services/ssm/test_ssm.py::TestSSM::test_trigger_event_on_systems_manager_change[domain]": 0.11642610900003092, - "tests/aws/services/ssm/test_ssm.py::TestSSM::test_trigger_event_on_systems_manager_change[path]": 0.11526392100017802, - "tests/aws/services/ssm/test_ssm.py::TestSSM::test_trigger_event_on_systems_manager_change[standard]": 0.12459161699985088, - "tests/aws/services/stepfunctions/v2/activities/test_activities.py::TestActivities::test_activity_task": 2.2069181659996957, - "tests/aws/services/stepfunctions/v2/activities/test_activities.py::TestActivities::test_activity_task_failure": 2.009260590000167, - "tests/aws/services/stepfunctions/v2/activities/test_activities.py::TestActivities::test_activity_task_no_worker_name": 1.9579327390001708, - "tests/aws/services/stepfunctions/v2/activities/test_activities.py::TestActivities::test_activity_task_on_deleted": 0.6052219810001134, - "tests/aws/services/stepfunctions/v2/activities/test_activities.py::TestActivities::test_activity_task_start_timeout": 7.105871753999736, - "tests/aws/services/stepfunctions/v2/activities/test_activities.py::TestActivities::test_activity_task_with_heartbeat": 6.267222732000164, - "tests/aws/services/stepfunctions/v2/arguments/test_arguments.py::TestArgumentsBase::test_base_cases[BASE_LAMBDA_EMPTY]": 2.353788852000207, - "tests/aws/services/stepfunctions/v2/arguments/test_arguments.py::TestArgumentsBase::test_base_cases[BASE_LAMBDA_EMPTY_GLOBAL_QL_JSONATA]": 2.427913883999963, - "tests/aws/services/stepfunctions/v2/arguments/test_arguments.py::TestArgumentsBase::test_base_cases[BASE_LAMBDA_EXPRESSION]": 6.2894217159996515, - "tests/aws/services/stepfunctions/v2/arguments/test_arguments.py::TestArgumentsBase::test_base_cases[BASE_LAMBDA_LITERALS]": 2.520435701999986, - "tests/aws/services/stepfunctions/v2/assign/test_assign_base.py::TestAssignBase::test_assign_in_choice[CONDITION_FALSE]": 0.8612657080002464, - "tests/aws/services/stepfunctions/v2/assign/test_assign_base.py::TestAssignBase::test_assign_in_choice[CONDITION_TRUE]": 1.1017684560001726, - "tests/aws/services/stepfunctions/v2/assign/test_assign_base.py::TestAssignBase::test_base_cases[BASE_CONSTANT_LITERALS]": 1.3073441670001102, - "tests/aws/services/stepfunctions/v2/assign/test_assign_base.py::TestAssignBase::test_base_cases[BASE_EMPTY]": 0.8401979770001162, - "tests/aws/services/stepfunctions/v2/assign/test_assign_base.py::TestAssignBase::test_base_cases[BASE_PATHS]": 1.1562338660000933, - "tests/aws/services/stepfunctions/v2/assign/test_assign_base.py::TestAssignBase::test_base_cases[BASE_SCOPE_MAP]": 1.1777725639997243, - "tests/aws/services/stepfunctions/v2/assign/test_assign_base.py::TestAssignBase::test_base_cases[BASE_VAR]": 1.4245392959999208, - "tests/aws/services/stepfunctions/v2/assign/test_assign_base.py::TestAssignBase::test_base_parallel_cases[BASE_SCOPE_PARALLEL]": 1.2446496620002563, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_assign_from_value[BASE_ASSIGN_FROM_INTRINSIC_FUNCTION]": 2.0346741050002493, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_assign_from_value[BASE_ASSIGN_FROM_PARAMETERS]": 1.0748879340001167, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_assign_from_value[BASE_ASSIGN_FROM_RESULT]": 1.0496478920001664, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_assign_in_catch_state": 2.4808853889996954, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_assign_in_choice_state[CORRECT]": 1.1540624289998505, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_assign_in_choice_state[INCORRECT]": 1.077054416999772, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_assign_in_wait_state": 0.832074423999984, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_assign[BASE_REFERENCE_IN_CHOICE]": 1.1471047669999734, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_assign[BASE_REFERENCE_IN_FAIL]": 1.076427927000168, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_assign[BASE_REFERENCE_IN_INPUTPATH]": 1.0688054990000637, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_assign[BASE_REFERENCE_IN_INTRINSIC_FUNCTION]": 1.3410011650000797, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_assign[BASE_REFERENCE_IN_ITERATOR_OUTER_SCOPE]": 3.1601409840000088, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_assign[BASE_REFERENCE_IN_OUTPUTPATH]": 1.0945666530003564, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_assign[BASE_REFERENCE_IN_PARAMETERS]": 1.1011698049999268, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_assign[BASE_REFERENCE_IN_WAIT]": 1.1009564239998326, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_in_map_state[MAP_STATE_REFERENCE_IN_INTRINSIC_FUNCTION]": 1.3825175860001764, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_in_map_state[MAP_STATE_REFERENCE_IN_ITEMS_PATH]": 1.4121712150001713, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_in_map_state[MAP_STATE_REFERENCE_IN_ITEM_SELECTOR]": 1.4507190999997874, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_in_map_state[MAP_STATE_REFERENCE_IN_MAX_CONCURRENCY_PATH]": 1.111834492000071, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_in_map_state[MAP_STATE_REFERENCE_IN_TOLERATED_FAILURE_PATH]": 1.2003370810000433, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_in_map_state_max_items_path[MAP_STATE_REFERENCE_IN_MAX_ITEMS_PATH]": 1.2720929830002206, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_in_map_state_max_items_path[MAP_STATE_REFERENCE_IN_MAX_PER_BATCH_PATH]": 0.0019308650000766647, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_state_assign_evaluation_order[BASE_EVALUATION_ORDER_PASS_STATE]": 0.0018191870003647637, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_undefined_reference[BASE_UNDEFINED_ARGUMENTS]": 0.0017252619998089358, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_undefined_reference[BASE_UNDEFINED_ARGUMENTS_FIELD]": 0.0017576720001670765, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_undefined_reference[BASE_UNDEFINED_ASSIGN]": 1.355792971000028, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_undefined_reference[BASE_UNDEFINED_OUTPUT]": 1.3681261239999003, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_undefined_reference[BASE_UNDEFINED_OUTPUT_FIELD]": 1.3864648230000967, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_undefined_reference[BASE_UNDEFINED_OUTPUT_MULTIPLE_STATES]": 1.4375884309997673, - "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_variables_in_lambda_task[BASE_ASSIGN_FROM_LAMBDA_TASK_RESULT]": 2.8240290300000197, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_decl_version_1_0": 0.6193016049999187, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_event_bridge_events_base": 2.7387259809997886, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_event_bridge_events_failure": 0.001994564000142418, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_execution_dateformat": 0.5361818819997097, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_access[$.items[0]]": 0.8096660480002811, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_access[$.items[10]]": 0.8072513950000939, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_wildcard_or_slice_with_no_input[$.item.items[*]]": 0.7903397309999036, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_wildcard_or_slice_with_no_input[$.item.items[1:5].itemValue]": 0.7916253759999563, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_wildcard_or_slice_with_no_input[$.item.items[1:5]]": 0.8081619759998375, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_wildcard_or_slice_with_no_input[$.item.items[1:]]": 0.8279964570001539, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_wildcard_or_slice_with_no_input[$.item.items[:1]]": 0.8262483379999139, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_wildcard_or_slice_with_no_input[$.items[*].itemValue]": 0.8237168020000354, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_wildcard_or_slice_with_no_input[$.items[*]]": 0.8208552739999959, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_wildcard_or_slice_with_no_input[$.items[1:].itemValue]": 0.7995492919999379, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_wildcard_or_slice_with_no_input[$.items[1:]]": 0.820396096000195, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_wildcard_or_slice_with_no_input[$.items[:1].itemValue]": 0.788394543999857, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_wildcard_or_slice_with_no_input[$.items[:1]]": 0.8160532519998469, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_wildcard_or_slice_with_no_input[$[*]]": 0.7389435919999414, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_query_context_object_values": 1.7147601939998367, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_state_fail": 0.8095693520001532, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_state_fail_empty": 0.7599169009997695, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_state_fail_intrinsic": 0.8054115949998959, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_state_fail_path": 0.8316051590002189, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_state_pass_regex_json_path": 0.0018942460001198924, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_state_pass_regex_json_path_base": 0.8442440769999848, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_state_pass_result": 1.7905188640002052, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_state_pass_result_jsonpaths": 0.5977238909999869, - "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_state_pass_result_null_input_output_paths": 0.8402912740002648, - "tests/aws/services/stepfunctions/v2/base/test_wait.py::TestSfnWait::test_base_wait_seconds_path[-1.5]": 0.8337240989999373, - "tests/aws/services/stepfunctions/v2/base/test_wait.py::TestSfnWait::test_base_wait_seconds_path[-1]": 0.788070499000014, - "tests/aws/services/stepfunctions/v2/base/test_wait.py::TestSfnWait::test_base_wait_seconds_path[0]": 0.8214760999999271, - "tests/aws/services/stepfunctions/v2/base/test_wait.py::TestSfnWait::test_base_wait_seconds_path[1.5]": 0.830697267000005, - "tests/aws/services/stepfunctions/v2/base/test_wait.py::TestSfnWait::test_base_wait_seconds_path[1]": 1.6550992539998788, - "tests/aws/services/stepfunctions/v2/base/test_wait.py::TestSfnWait::test_timestamp_too_far_in_future_boundary[24855]": 0.0017789209998682054, - "tests/aws/services/stepfunctions/v2/base/test_wait.py::TestSfnWait::test_timestamp_too_far_in_future_boundary[24856]": 0.0016297619999932067, - "tests/aws/services/stepfunctions/v2/base/test_wait.py::TestSfnWait::test_wait_timestamppath[.000000Z]": 0.8150028149998434, - "tests/aws/services/stepfunctions/v2/base/test_wait.py::TestSfnWait::test_wait_timestamppath[.000000]": 0.8130979939999179, - "tests/aws/services/stepfunctions/v2/base/test_wait.py::TestSfnWait::test_wait_timestamppath[.00Z]": 0.78193606800005, - "tests/aws/services/stepfunctions/v2/base/test_wait.py::TestSfnWait::test_wait_timestamppath[Z]": 0.6375744360000226, - "tests/aws/services/stepfunctions/v2/base/test_wait.py::TestSfnWait::test_wait_timestamppath[]": 0.820800853000037, - "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_multiple_executions_and_heartbeat_notifications": 0.0019874310000886908, - "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_multiple_heartbeat_notifications": 0.0028255380002519814, - "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_sns_publish_wait_for_task_token": 1.3860369020001144, - "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_sqs_failure_in_wait_for_task_tok_no_error_field[SQS_PARALLEL_WAIT_FOR_TASK_TOKEN]": 0.009760211000184427, - "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_sqs_failure_in_wait_for_task_tok_no_error_field[SQS_WAIT_FOR_TASK_TOKEN_CATCH]": 1.7981461099998342, - "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_sqs_failure_in_wait_for_task_token": 2.6496874140000273, - "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_sqs_wait_for_task_tok_with_heartbeat": 7.785913083000196, - "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_sqs_wait_for_task_token": 2.720705597000233, - "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_sqs_wait_for_task_token_call_chain": 4.384848078999994, - "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_sqs_wait_for_task_token_no_token_parameter": 5.876278859000195, - "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_sqs_wait_for_task_token_timeout": 5.9503942679998545, - "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_start_execution_sync": 2.5623033689996646, - "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_start_execution_sync2": 1.3660323009999047, - "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_start_execution_sync_delegate_failure": 1.3405132890000004, - "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_start_execution_sync_delegate_timeout": 7.816472562999934, - "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_sync_with_task_token": 3.355114002000164, - "tests/aws/services/stepfunctions/v2/choice_operators/test_boolean_equals.py::TestBooleanEquals::test_boolean_equals": 14.099266057999785, - "tests/aws/services/stepfunctions/v2/choice_operators/test_boolean_equals.py::TestBooleanEquals::test_boolean_equals_path": 15.191257033999818, - "tests/aws/services/stepfunctions/v2/choice_operators/test_is_operators.py::TestIsOperators::test_is_boolean": 13.987185100000033, - "tests/aws/services/stepfunctions/v2/choice_operators/test_is_operators.py::TestIsOperators::test_is_null": 13.964927731999978, - "tests/aws/services/stepfunctions/v2/choice_operators/test_is_operators.py::TestIsOperators::test_is_numeric": 14.216242634999844, - "tests/aws/services/stepfunctions/v2/choice_operators/test_is_operators.py::TestIsOperators::test_is_present": 14.172772205000228, - "tests/aws/services/stepfunctions/v2/choice_operators/test_is_operators.py::TestIsOperators::test_is_string": 15.423709084000166, - "tests/aws/services/stepfunctions/v2/choice_operators/test_is_operators.py::TestIsOperators::test_is_timestamp": 0.003717301000278894, - "tests/aws/services/stepfunctions/v2/choice_operators/test_numeric.py::TestNumerics::test_numeric_equals": 21.372023953000053, - "tests/aws/services/stepfunctions/v2/choice_operators/test_numeric.py::TestNumerics::test_numeric_equals_path": 22.623127365000073, - "tests/aws/services/stepfunctions/v2/choice_operators/test_numeric.py::TestNumerics::test_numeric_greater_than": 2.688769020999871, - "tests/aws/services/stepfunctions/v2/choice_operators/test_numeric.py::TestNumerics::test_numeric_greater_than_equals": 2.7447612799999206, - "tests/aws/services/stepfunctions/v2/choice_operators/test_numeric.py::TestNumerics::test_numeric_greater_than_equals_path": 2.7538474220000353, - "tests/aws/services/stepfunctions/v2/choice_operators/test_numeric.py::TestNumerics::test_numeric_greater_than_path": 2.7752832389999185, - "tests/aws/services/stepfunctions/v2/choice_operators/test_numeric.py::TestNumerics::test_numeric_less_than": 2.7625646209999104, - "tests/aws/services/stepfunctions/v2/choice_operators/test_numeric.py::TestNumerics::test_numeric_less_than_equals": 2.719124019999981, - "tests/aws/services/stepfunctions/v2/choice_operators/test_numeric.py::TestNumerics::test_numeric_less_than_equals_path": 2.715019416000132, - "tests/aws/services/stepfunctions/v2/choice_operators/test_numeric.py::TestNumerics::test_numeric_less_than_path": 2.6882484799998565, - "tests/aws/services/stepfunctions/v2/choice_operators/test_string_operators.py::TestStrings::test_string_equals": 6.5561934049997035, - "tests/aws/services/stepfunctions/v2/choice_operators/test_string_operators.py::TestStrings::test_string_equals_path": 1.6279018410002664, - "tests/aws/services/stepfunctions/v2/choice_operators/test_string_operators.py::TestStrings::test_string_greater_than": 1.991654545000074, - "tests/aws/services/stepfunctions/v2/choice_operators/test_string_operators.py::TestStrings::test_string_greater_than_equals": 1.606562115000088, - "tests/aws/services/stepfunctions/v2/choice_operators/test_string_operators.py::TestStrings::test_string_greater_than_equals_path": 1.626479125999822, - "tests/aws/services/stepfunctions/v2/choice_operators/test_string_operators.py::TestStrings::test_string_greater_than_path": 2.006198316000109, - "tests/aws/services/stepfunctions/v2/choice_operators/test_string_operators.py::TestStrings::test_string_less_than": 1.550570131999848, - "tests/aws/services/stepfunctions/v2/choice_operators/test_string_operators.py::TestStrings::test_string_less_than_equals": 1.6097117110002728, - "tests/aws/services/stepfunctions/v2/choice_operators/test_string_operators.py::TestStrings::test_string_less_than_equals_path": 1.6334538640001028, - "tests/aws/services/stepfunctions/v2/choice_operators/test_string_operators.py::TestStrings::test_string_less_than_path": 1.6235052429999541, - "tests/aws/services/stepfunctions/v2/choice_operators/test_timestamp_operators.py::TestTimestamps::test_timestamp_equals": 8.246174140999983, - "tests/aws/services/stepfunctions/v2/choice_operators/test_timestamp_operators.py::TestTimestamps::test_timestamp_equals_path": 1.6654537479996634, - "tests/aws/services/stepfunctions/v2/choice_operators/test_timestamp_operators.py::TestTimestamps::test_timestamp_greater_than": 1.6617902560001312, - "tests/aws/services/stepfunctions/v2/choice_operators/test_timestamp_operators.py::TestTimestamps::test_timestamp_greater_than_equals": 1.5686742270002014, - "tests/aws/services/stepfunctions/v2/choice_operators/test_timestamp_operators.py::TestTimestamps::test_timestamp_greater_than_equals_path": 0.8551340800001981, - "tests/aws/services/stepfunctions/v2/choice_operators/test_timestamp_operators.py::TestTimestamps::test_timestamp_greater_than_path": 0.8599438880000889, - "tests/aws/services/stepfunctions/v2/choice_operators/test_timestamp_operators.py::TestTimestamps::test_timestamp_less_than": 1.6227170140000453, - "tests/aws/services/stepfunctions/v2/choice_operators/test_timestamp_operators.py::TestTimestamps::test_timestamp_less_than_equals": 1.5980968149999626, - "tests/aws/services/stepfunctions/v2/choice_operators/test_timestamp_operators.py::TestTimestamps::test_timestamp_less_than_equals_path": 0.8222504139998819, - "tests/aws/services/stepfunctions/v2/choice_operators/test_timestamp_operators.py::TestTimestamps::test_timestamp_less_than_path": 0.863516964000155, - "tests/aws/services/stepfunctions/v2/comments/test_comments.py::TestComments::test_comment_in_parameters": 0.6430240790000425, - "tests/aws/services/stepfunctions/v2/comments/test_comments.py::TestComments::test_comments_as_per_docs": 7.72462464799969, - "tests/aws/services/stepfunctions/v2/context_object/test_context_object.py::TestSnfBase::test_error_cause_path": 1.197135784999773, - "tests/aws/services/stepfunctions/v2/context_object/test_context_object.py::TestSnfBase::test_input_path[$$.Execution.Input]": 1.2151304920000712, - "tests/aws/services/stepfunctions/v2/context_object/test_context_object.py::TestSnfBase::test_input_path[$$]": 0.9216381520002415, - "tests/aws/services/stepfunctions/v2/context_object/test_context_object.py::TestSnfBase::test_output_path[$$.Execution.Input]": 1.1726846319998003, - "tests/aws/services/stepfunctions/v2/context_object/test_context_object.py::TestSnfBase::test_output_path[$$]": 1.0104526379998333, - "tests/aws/services/stepfunctions/v2/context_object/test_context_object.py::TestSnfBase::test_result_selector": 2.860743783000089, - "tests/aws/services/stepfunctions/v2/context_object/test_context_object.py::TestSnfBase::test_variable": 1.2223827179996078, - "tests/aws/services/stepfunctions/v2/credentials/test_credentials_base.py::TestCredentialsBase::test_cross_account_lambda_task": 2.813157218000242, - "tests/aws/services/stepfunctions/v2/credentials/test_credentials_base.py::TestCredentialsBase::test_cross_account_service_lambda_invoke": 2.818888806999894, - "tests/aws/services/stepfunctions/v2/credentials/test_credentials_base.py::TestCredentialsBase::test_cross_account_service_lambda_invoke_retry": 6.2258848760002365, - "tests/aws/services/stepfunctions/v2/credentials/test_credentials_base.py::TestCredentialsBase::test_cross_account_states_start_sync_execution[SFN_START_EXECUTION_SYNC_ROLE_ARN_INTRINSIC]": 3.3932750619997023, - "tests/aws/services/stepfunctions/v2/credentials/test_credentials_base.py::TestCredentialsBase::test_cross_account_states_start_sync_execution[SFN_START_EXECUTION_SYNC_ROLE_ARN_JSONATA]": 1.8747454959998322, - "tests/aws/services/stepfunctions/v2/credentials/test_credentials_base.py::TestCredentialsBase::test_cross_account_states_start_sync_execution[SFN_START_EXECUTION_SYNC_ROLE_ARN_PATH]": 1.9509954210002434, - "tests/aws/services/stepfunctions/v2/credentials/test_credentials_base.py::TestCredentialsBase::test_cross_account_states_start_sync_execution[SFN_START_EXECUTION_SYNC_ROLE_ARN_PATH_CONTEXT]": 2.048667544999944, - "tests/aws/services/stepfunctions/v2/credentials/test_credentials_base.py::TestCredentialsBase::test_cross_account_states_start_sync_execution[SFN_START_EXECUTION_SYNC_ROLE_ARN_VARIABLE]": 2.1001691599999504, - "tests/aws/services/stepfunctions/v2/credentials/test_credentials_base.py::TestCredentialsBase::test_invalid_credentials_field[EMPTY_CREDENTIALS]": 1.0820302629997514, - "tests/aws/services/stepfunctions/v2/credentials/test_credentials_base.py::TestCredentialsBase::test_invalid_credentials_field[INVALID_CREDENTIALS_FIELD]": 1.0739671599999383, - "tests/aws/services/stepfunctions/v2/error_handling/test_aws_sdk.py::TestAwsSdk::test_dynamodb_invalid_param": 0.0018381909997060575, - "tests/aws/services/stepfunctions/v2/error_handling/test_aws_sdk.py::TestAwsSdk::test_dynamodb_put_item_no_such_table": 0.9602138170000671, - "tests/aws/services/stepfunctions/v2/error_handling/test_aws_sdk.py::TestAwsSdk::test_invalid_secret_name": 0.9445192999999108, - "tests/aws/services/stepfunctions/v2/error_handling/test_aws_sdk.py::TestAwsSdk::test_no_such_bucket": 0.8815493249999236, - "tests/aws/services/stepfunctions/v2/error_handling/test_aws_sdk.py::TestAwsSdk::test_s3_no_such_key": 0.9166455300000962, - "tests/aws/services/stepfunctions/v2/error_handling/test_states_errors.py::TestStatesErrors::test_service_task_lambada_catch_state_all_data_limit_exceeded_on_large_utf8_response": 2.4703153720001865, - "tests/aws/services/stepfunctions/v2/error_handling/test_states_errors.py::TestStatesErrors::test_service_task_lambada_data_limit_exceeded_on_large_utf8_response": 2.5278753219997725, - "tests/aws/services/stepfunctions/v2/error_handling/test_states_errors.py::TestStatesErrors::test_start_large_input": 4.956773299000133, - "tests/aws/services/stepfunctions/v2/error_handling/test_states_errors.py::TestStatesErrors::test_task_lambda_catch_state_all_data_limit_exceeded_on_large_utf8_response": 2.516982377999966, - "tests/aws/services/stepfunctions/v2/error_handling/test_states_errors.py::TestStatesErrors::test_task_lambda_data_limit_exceeded_on_large_utf8_response": 2.502299553999819, - "tests/aws/services/stepfunctions/v2/error_handling/test_task_lambda.py::TestTaskLambda::test_no_such_function": 2.5434937800000625, - "tests/aws/services/stepfunctions/v2/error_handling/test_task_lambda.py::TestTaskLambda::test_no_such_function_catch": 2.7376378790002036, - "tests/aws/services/stepfunctions/v2/error_handling/test_task_lambda.py::TestTaskLambda::test_raise_custom_exception": 2.384553780000033, - "tests/aws/services/stepfunctions/v2/error_handling/test_task_lambda.py::TestTaskLambda::test_raise_exception": 2.6669237020000764, - "tests/aws/services/stepfunctions/v2/error_handling/test_task_lambda.py::TestTaskLambda::test_raise_exception_catch": 2.684178824000128, - "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_dynamodb.py::TestTaskServiceDynamoDB::test_invalid_param": 0.9483351620001486, - "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_dynamodb.py::TestTaskServiceDynamoDB::test_put_item_invalid_table_name": 1.072161375000178, - "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_dynamodb.py::TestTaskServiceDynamoDB::test_put_item_no_such_table": 0.9329111299996384, - "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_lambda.py::TestTaskServiceLambda::test_invoke_timeout": 7.129512716000136, - "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_lambda.py::TestTaskServiceLambda::test_no_such_function": 2.14087731599966, - "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_lambda.py::TestTaskServiceLambda::test_no_such_function_catch": 3.3048075300002893, - "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_lambda.py::TestTaskServiceLambda::test_raise_custom_exception": 2.496753290000015, - "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_lambda.py::TestTaskServiceLambda::test_raise_exception": 2.491760032000002, - "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_lambda.py::TestTaskServiceLambda::test_raise_exception_catch": 2.6652558500002215, - "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_lambda.py::TestTaskServiceLambda::test_raise_exception_catch_output_path[$.Payload]": 2.5394133249999413, - "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_lambda.py::TestTaskServiceLambda::test_raise_exception_catch_output_path[$.no.such.path]": 2.509736076000081, - "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_lambda.py::TestTaskServiceLambda::test_raise_exception_catch_output_path[None]": 2.483388404999914, - "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_sfn.py::TestTaskServiceSfn::test_start_execution_no_such_arn": 1.3236926299998686, - "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_sqs.py::TestTaskServiceSqs::test_send_message_empty_body": 0.0017719979998673807, - "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_sqs.py::TestTaskServiceSqs::test_send_message_no_such_queue": 1.3316761549999683, - "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_sqs.py::TestTaskServiceSqs::test_send_message_no_such_queue_no_catch": 1.2701044060002005, - "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_sqs.py::TestTaskServiceSqs::test_sqs_failure_in_wait_for_task_tok": 2.8847892620001403, - "tests/aws/services/stepfunctions/v2/evaluate_jsonata/test_base_evaluate_expressions.py::TestBaseEvaluateJsonata::test_base_map[ITEMS]": 1.5124981090000347, - "tests/aws/services/stepfunctions/v2/evaluate_jsonata/test_base_evaluate_expressions.py::TestBaseEvaluateJsonata::test_base_map[ITEMS_DOUBLE_QUOTES]": 1.3074590539997644, - "tests/aws/services/stepfunctions/v2/evaluate_jsonata/test_base_evaluate_expressions.py::TestBaseEvaluateJsonata::test_base_map[MAX_CONCURRENCY]": 1.2635960329998852, - "tests/aws/services/stepfunctions/v2/evaluate_jsonata/test_base_evaluate_expressions.py::TestBaseEvaluateJsonata::test_base_map[TOLERATED_FAILURE_COUNT]": 5.982920723999996, - "tests/aws/services/stepfunctions/v2/evaluate_jsonata/test_base_evaluate_expressions.py::TestBaseEvaluateJsonata::test_base_map[TOLERATED_FAILURE_PERCENTAGE]": 1.2492021509999631, - "tests/aws/services/stepfunctions/v2/evaluate_jsonata/test_base_evaluate_expressions.py::TestBaseEvaluateJsonata::test_base_map_from_input[ITEMS]": 2.8936900949999824, - "tests/aws/services/stepfunctions/v2/evaluate_jsonata/test_base_evaluate_expressions.py::TestBaseEvaluateJsonata::test_base_map_from_input[MAX_CONCURRENCY]": 2.364839197000009, - "tests/aws/services/stepfunctions/v2/evaluate_jsonata/test_base_evaluate_expressions.py::TestBaseEvaluateJsonata::test_base_map_from_input[TOLERATED_FAILURE_COUNT]": 2.3520260450000308, - "tests/aws/services/stepfunctions/v2/evaluate_jsonata/test_base_evaluate_expressions.py::TestBaseEvaluateJsonata::test_base_map_from_input[TOLERATED_FAILURE_PERCENTAGE]": 2.864340380000016, - "tests/aws/services/stepfunctions/v2/evaluate_jsonata/test_base_evaluate_expressions.py::TestBaseEvaluateJsonata::test_base_task[HEARTBEAT_SECONDS]": 2.6900220970003375, - "tests/aws/services/stepfunctions/v2/evaluate_jsonata/test_base_evaluate_expressions.py::TestBaseEvaluateJsonata::test_base_task[TIMEOUT_SECONDS]": 0.002943756000149733, - "tests/aws/services/stepfunctions/v2/evaluate_jsonata/test_base_evaluate_expressions.py::TestBaseEvaluateJsonata::test_base_task_from_input[HEARTBEAT_SECONDS]": 19.219125480999992, - "tests/aws/services/stepfunctions/v2/evaluate_jsonata/test_base_evaluate_expressions.py::TestBaseEvaluateJsonata::test_base_task_from_input[TIMEOUT_SECONDS]": 0.00261609899999371, - "tests/aws/services/stepfunctions/v2/express/test_express_async.py::TestExpressAsync::test_base[BASE_PASS_RESULT]": 1.385742117999996, - "tests/aws/services/stepfunctions/v2/express/test_express_async.py::TestExpressAsync::test_base[BASE_RAISE_FAILURE]": 1.3235642460000179, - "tests/aws/services/stepfunctions/v2/express/test_express_async.py::TestExpressAsync::test_catch": 3.1208249539999997, - "tests/aws/services/stepfunctions/v2/express/test_express_async.py::TestExpressAsync::test_query_runtime_memory": 2.3189038050000192, - "tests/aws/services/stepfunctions/v2/express/test_express_async.py::TestExpressAsync::test_retry": 10.220456748999993, - "tests/aws/services/stepfunctions/v2/express/test_express_sync.py::TestExpressSync::test_base[BASE_PASS_RESULT]": 0.6488946609999857, - "tests/aws/services/stepfunctions/v2/express/test_express_sync.py::TestExpressSync::test_base[BASE_RAISE_FAILURE]": 0.5810687780000308, - "tests/aws/services/stepfunctions/v2/express/test_express_sync.py::TestExpressSync::test_catch": 2.3031642089999877, - "tests/aws/services/stepfunctions/v2/express/test_express_sync.py::TestExpressSync::test_query_runtime_memory": 1.4983592529999896, - "tests/aws/services/stepfunctions/v2/express/test_express_sync.py::TestExpressSync::test_retry": 9.518933849000007, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_array.py::TestArray::test_array_0": 0.7112540700000238, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_array.py::TestArray::test_array_2": 3.539180582, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_array.py::TestArray::test_array_contains": 3.274367464000022, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_array.py::TestArray::test_array_get_item": 0.7470074790000183, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_array.py::TestArray::test_array_length": 0.7250492139999949, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_array.py::TestArray::test_array_partition": 8.268853872000022, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_array.py::TestArray::test_array_range": 1.6389364770000157, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_array.py::TestArray::test_array_unique": 0.7151993699999935, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_array_jsonata.py::TestArrayJSONata::test_array_partition": 6.578431593999994, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_array_jsonata.py::TestArrayJSONata::test_array_range": 1.9384576600000116, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_encode_decode.py::TestEncodeDecode::test_base_64_decode": 1.0561480449999578, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_encode_decode.py::TestEncodeDecode::test_base_64_encode": 1.0773645479999914, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_generic.py::TestGeneric::test_context_json_path": 0.7347040760000141, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_generic.py::TestGeneric::test_escape_sequence": 0.4899449289999893, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_generic.py::TestGeneric::test_format_1": 2.57576478499999, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_generic.py::TestGeneric::test_format_2": 2.888833508999994, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_generic.py::TestGeneric::test_nested_calls_1": 0.7221621589999927, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_generic.py::TestGeneric::test_nested_calls_2": 0.7433459490000018, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_hash_calculations.py::TestHashCalculations::test_hash": 2.0014806189999774, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_json_manipulation.py::TestJsonManipulation::test_json_merge": 0.7392130110000039, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_json_manipulation.py::TestJsonManipulation::test_json_merge_escaped_argument": 0.7730180359999679, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_json_manipulation.py::TestJsonManipulation::test_json_to_string": 2.8707337919999816, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_json_manipulation.py::TestJsonManipulation::test_string_to_json": 3.5274148839999384, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_json_manipulation_jsonata.py::TestJsonManipulationJSONata::test_parse": 2.2068313350000324, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_math_operations.py::TestMathOperations::test_math_add": 7.682675031999992, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_math_operations.py::TestMathOperations::test_math_random": 1.4768367960000148, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_math_operations.py::TestMathOperations::test_math_random_seeded": 0.8083927330000051, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_math_operations_jsonata.py::TestMathOperationsJSONata::test_math_random_seeded": 0.0022870579999789697, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_string_operations.py::TestStringOperations::test_string_split": 2.6245983920000526, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_string_operations.py::TestStringOperations::test_string_split_context_object": 0.7277200239999502, - "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_unique_id_generation.py::TestUniqueIdGeneration::test_uuid": 0.5273850570000036, - "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_base[pass_result.json5_ALL_False]": 1.0991152099999795, - "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_base[pass_result.json5_ALL_True]": 1.1203211529999635, - "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_base[raise_failure.json5_ALL_False]": 1.0969936850000295, - "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_base[raise_failure.json5_ALL_True]": 1.122685502999957, - "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_base[wait_seconds_path.json5_ALL_False]": 1.1241086410000776, - "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_base[wait_seconds_path.json5_ALL_True]": 1.091840260999959, - "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_deleted_log_group": 1.112391792999972, - "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_log_group_with_multiple_runs": 1.6973937529999716, - "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[pass_result.json5_ERROR_False]": 0.8344910069999969, - "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[pass_result.json5_ERROR_True]": 1.0060469539999985, - "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[pass_result.json5_FATAL_False]": 0.8023937910000427, - "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[pass_result.json5_FATAL_True]": 0.8060499129999812, - "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[pass_result.json5_OFF_False]": 0.9939169280000328, - "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[pass_result.json5_OFF_True]": 0.7853987110000276, - "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[raise_failure.json5_ERROR_False]": 1.0878679320000515, - "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[raise_failure.json5_ERROR_True]": 1.0768040160000396, - "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[raise_failure.json5_FATAL_False]": 0.8679731189999984, - "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[raise_failure.json5_FATAL_True]": 1.524016210999946, - "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[raise_failure.json5_OFF_False]": 0.7912509780000505, - "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[raise_failure.json5_OFF_True]": 0.7940549290000263, - "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[wait_seconds_path.json5_ERROR_False]": 1.067117301000053, - "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[wait_seconds_path.json5_ERROR_True]": 1.0814539109999828, - "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[wait_seconds_path.json5_FATAL_False]": 1.093506686000012, - "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[wait_seconds_path.json5_FATAL_True]": 0.9094880190000367, - "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[wait_seconds_path.json5_OFF_False]": 1.003353427000036, - "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[wait_seconds_path.json5_OFF_True]": 1.000033411000004, - "tests/aws/services/stepfunctions/v2/mocking/test_aws_scenarios.py::TestBaseScenarios::test_lambda_sqs_integration_happy_path": 0.4298779609999883, - "tests/aws/services/stepfunctions/v2/mocking/test_aws_scenarios.py::TestBaseScenarios::test_lambda_sqs_integration_hybrid_path": 0.5882886379999945, - "tests/aws/services/stepfunctions/v2/mocking/test_aws_scenarios.py::TestBaseScenarios::test_lambda_sqs_integration_retry_path": 7.255779894, - "tests/aws/services/stepfunctions/v2/mocking/test_base_callbacks.py::TestBaseScenarios::test_sfn_start_execution_sync[SFN_SYNC2]": 2.508866942999987, - "tests/aws/services/stepfunctions/v2/mocking/test_base_callbacks.py::TestBaseScenarios::test_sfn_start_execution_sync[SFN_SYNC]": 1.8060861090000344, - "tests/aws/services/stepfunctions/v2/mocking/test_base_callbacks.py::TestBaseScenarios::test_sqs_wait_for_task_token": 1.6629305239999894, - "tests/aws/services/stepfunctions/v2/mocking/test_base_callbacks.py::TestBaseScenarios::test_sqs_wait_for_task_token_task_failure": 1.7959237549999898, - "tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py::TestBaseScenarios::test_dynamodb_put_get_item": 1.0967360960000292, - "tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py::TestBaseScenarios::test_events_put_events": 0.9760736130000396, - "tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py::TestBaseScenarios::test_lambda_invoke": 0.9727351920000729, - "tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py::TestBaseScenarios::test_lambda_invoke_retries": 3.4049586710000312, - "tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py::TestBaseScenarios::test_lambda_service_invoke": 1.0442268720000243, - "tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py::TestBaseScenarios::test_map_state_lambda": 1.6208897540000748, - "tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py::TestBaseScenarios::test_parallel_state_lambda": 1.323694504000116, - "tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py::TestBaseScenarios::test_sns_publish_base": 1.028937396999936, - "tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py::TestBaseScenarios::test_sqs_send_message": 1.089692545000048, - "tests/aws/services/stepfunctions/v2/mocking/test_mock_config_file.py::TestMockConfigFile::test_is_mock_config_flag_detected_set": 0.0047302640001021246, - "tests/aws/services/stepfunctions/v2/mocking/test_mock_config_file.py::TestMockConfigFile::test_is_mock_config_flag_detected_unset": 0.006179448000011689, - "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_cases[BASE_DIRECT_EXPR]": 1.0610666489999971, - "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_cases[BASE_EMPTY]": 0.7541225579999491, - "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_cases[BASE_EXPR]": 1.1091091870000582, - "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_cases[BASE_LITERALS]": 0.9570830819999401, - "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_lambda[BASE_LAMBDA]": 3.5011377289999928, - "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_output_any_non_dict[BOOL]": 0.9843170040000473, - "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_output_any_non_dict[FLOAT]": 0.9961758139999688, - "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_output_any_non_dict[INT]": 0.7578635230000259, - "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_output_any_non_dict[JSONATA_EXPR]": 0.9450328740000487, - "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_output_any_non_dict[LIST_EMPY]": 0.7390954169999304, - "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_output_any_non_dict[LIST_RICH]": 0.9663390250000248, - "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_output_any_non_dict[NULL]": 0.7527677370000561, - "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_output_any_non_dict[STR_LIT]": 0.9869880260000059, - "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_task_lambda[BASE_TASK_LAMBDA]": 3.0032340090000957, - "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_output_in_choice[CONDITION_FALSE]": 0.7934537460000115, - "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_output_in_choice[CONDITION_TRUE]": 0.8168202179999753, - "tests/aws/services/stepfunctions/v2/query_language/test_base_query_language.py::TestBaseQueryLanguage::test_base_query_language_field[JSONATA]": 0.5132882810000297, - "tests/aws/services/stepfunctions/v2/query_language/test_base_query_language.py::TestBaseQueryLanguage::test_base_query_language_field[JSON_PATH]": 0.5158672260000117, - "tests/aws/services/stepfunctions/v2/query_language/test_base_query_language.py::TestBaseQueryLanguage::test_jsonata_query_language_field_downgrade_exception": 0.0017928640000377527, - "tests/aws/services/stepfunctions/v2/query_language/test_base_query_language.py::TestBaseQueryLanguage::test_query_language_field_override[JSONATA_OVERRIDE]": 0.49603257400002576, - "tests/aws/services/stepfunctions/v2/query_language/test_base_query_language.py::TestBaseQueryLanguage::test_query_language_field_override[JSONATA_OVERRIDE_DEFAULT]": 0.703305677000003, - "tests/aws/services/stepfunctions/v2/query_language/test_mixed_query_language.py::TestMixedQueryLanguageFlow::test_lambda_task_resource_data_flow[TASK_LAMBDA_LEGACY_RESOURCE_JSONATA_TO_JSONPATH]": 2.5336430170000313, - "tests/aws/services/stepfunctions/v2/query_language/test_mixed_query_language.py::TestMixedQueryLanguageFlow::test_lambda_task_resource_data_flow[TASK_LAMBDA_LEGACY_RESOURCE_JSONPATH_TO_JSONATA]": 3.0987200990000474, - "tests/aws/services/stepfunctions/v2/query_language/test_mixed_query_language.py::TestMixedQueryLanguageFlow::test_lambda_task_resource_data_flow[TASK_LAMBDA_SDK_RESOURCE_JSONATA_TO_JSONPATH]": 2.3309422820000236, - "tests/aws/services/stepfunctions/v2/query_language/test_mixed_query_language.py::TestMixedQueryLanguageFlow::test_lambda_task_resource_data_flow[TASK_LAMBDA_SDK_RESOURCE_JSONPATH_TO_JSONATA]": 2.289668968000001, - "tests/aws/services/stepfunctions/v2/query_language/test_mixed_query_language.py::TestMixedQueryLanguageFlow::test_output_to_state[JSONATA_OUTPUT_TO_JSONPATH]": 0.9140576300000589, - "tests/aws/services/stepfunctions/v2/query_language/test_mixed_query_language.py::TestMixedQueryLanguageFlow::test_output_to_state[JSONPATH_OUTPUT_TO_JSONATA]": 0.9424557529999902, - "tests/aws/services/stepfunctions/v2/query_language/test_mixed_query_language.py::TestMixedQueryLanguageFlow::test_task_dataflow_to_state": 2.57403901400005, - "tests/aws/services/stepfunctions/v2/query_language/test_mixed_query_language.py::TestMixedQueryLanguageFlow::test_variable_sampling[JSONATA_ASSIGN_JSONPATH_REF]": 0.9069866300000058, - "tests/aws/services/stepfunctions/v2/query_language/test_mixed_query_language.py::TestMixedQueryLanguageFlow::test_variable_sampling[JSONPATH_ASSIGN_JSONATA_REF]": 0.897081490000005, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_catch_empty": 2.127353888000016, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_catch_states_runtime": 2.4533762840001145, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_choice_aws_docs_scenario[CHOICE_STATE_AWS_SCENARIO]": 0.9118220770000107, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_choice_aws_docs_scenario[CHOICE_STATE_AWS_SCENARIO_JSONATA]": 0.856970581999974, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_choice_condition_constant_jsonata": 1.2965167919999772, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_choice_singleton_composite[CHOICE_STATE_SINGLETON_COMPOSITE]": 0.8027653020000685, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_choice_singleton_composite[CHOICE_STATE_SINGLETON_COMPOSITE_JSONATA]": 0.8040931949999504, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_choice_singleton_composite[CHOICE_STATE_SINGLETON_COMPOSITE_LITERAL_JSONATA]": 0.6208838049999486, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_choice_unsorted_parameters_negative[CHOICE_STATE_UNSORTED_CHOICE_PARAMETERS]": 0.8631936680000081, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_choice_unsorted_parameters_negative[CHOICE_STATE_UNSORTED_CHOICE_PARAMETERS_JSONATA]": 0.7992374809999774, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_choice_unsorted_parameters_positive[CHOICE_STATE_UNSORTED_CHOICE_PARAMETERS]": 1.0150197530000469, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_choice_unsorted_parameters_positive[CHOICE_STATE_UNSORTED_CHOICE_PARAMETERS_JSONATA]": 0.8753280299999915, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_escape_sequence_parsing[ESCAPE_SEQUENCES_JSONATA_COMPARISON_ASSIGN]": 0.7874183390000553, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_escape_sequence_parsing[ESCAPE_SEQUENCES_JSONATA_COMPARISON_OUTPUT]": 0.7899693780000234, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_escape_sequence_parsing[ESCAPE_SEQUENCES_JSONPATH]": 0.8209627549999823, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_escape_sequence_parsing[ESCAPE_SEQUENCES_STRING_LITERALS]": 0.9027063820000194, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_fail_cause_jsonata": 0.7872426849999101, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_fail_error_jsonata": 0.8101193979999834, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_illegal_escapes[ESCAPE_SEQUENCES_ILLEGAL_INTRINSIC_FUNCTION]": 0.0020480299999690033, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_illegal_escapes[ESCAPE_SEQUENCES_ILLEGAL_INTRINSIC_FUNCTION_2]": 0.0015909170000441009, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_invalid_jsonpath[INVALID_JSONPATH_IN_ERRORPATH]": 0.7843457290000515, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_invalid_jsonpath[INVALID_JSONPATH_IN_STRING_EXPR_CONTEXTPATH]": 0.7890845709998757, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_invalid_jsonpath[INVALID_JSONPATH_IN_STRING_EXPR_JSONPATH]": 0.7637312040000097, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_invalid_jsonpath[ST.INVALID_JSONPATH_IN_CAUSEPATH]": 0.7857035229998246, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_invalid_jsonpath[ST.INVALID_JSONPATH_IN_HEARTBEATSECONDSPATH]": 0.0016274670000484548, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_invalid_jsonpath[ST.INVALID_JSONPATH_IN_INPUTPATH]": 0.7786313049998626, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_invalid_jsonpath[ST.INVALID_JSONPATH_IN_OUTPUTPATH]": 0.7969828709999547, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_invalid_jsonpath[ST.INVALID_JSONPATH_IN_TIMEOUTSECONDSPATH]": 0.0017937459999757266, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_lambda_empty_retry": 2.3361986039999465, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_lambda_invoke_with_retry_base": 9.685449987000027, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_lambda_invoke_with_retry_extended_input": 9.816028315999915, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_lambda_service_invoke_with_retry_extended_input": 10.068122916999982, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_batching_base_json_max_per_batch_jsonata": 0.0020172430000116037, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_base_csv_headers_decl": 0.9342256750000502, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_base_csv_headers_first_line": 0.9259451659999627, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_base_json": 0.8799753989999886, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_base_json_max_items": 0.8908522689999927, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_base_json_max_items_jsonata": 0.9775742319999949, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_base_json_with_items_path[INVALID_ITEMS_PATH]": 1.1868574659999922, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_base_json_with_items_path[VALID_ITEMS_PATH_FROM_ITEM_READER]": 1.104373690999978, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_base_json_with_items_path[VALID_ITEMS_PATH_FROM_PREVIOUS]": 1.7620481210000207, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_base_list_objects_v2": 0.920342317999939, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_csv_first_row_extra_fields": 0.8956037490000313, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_csv_headers_decl_duplicate_headers": 0.880209648999994, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_csv_headers_decl_extra_fields": 0.909124845000008, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_csv_headers_first_row_typed_headers": 0.893443278999996, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_csv_max_items[0]": 0.8930396150000774, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_csv_max_items[100000000]": 0.9011406380000722, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_csv_max_items[2]": 0.9068365100000619, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_csv_max_items_paths[-1]": 0.901848957000027, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_csv_max_items_paths[0]": 1.122109933000047, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_csv_max_items_paths[1.5]": 0.021534945999974298, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_csv_max_items_paths[100000000]": 1.1244338209999682, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_csv_max_items_paths[100000001]": 0.9100951719999557, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_csv_max_items_paths[2]": 0.8587545689999274, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_json_no_json_list_object": 0.9138318239999421, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state": 0.9021676799999909, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_break_condition": 0.9319269180000447, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_break_condition_legacy": 0.9219132339999305, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_catch": 1.5828382560000023, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_catch_empty_fail": 0.8348867340000083, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_catch_legacy": 0.816178389000072, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_config_distributed_item_selector": 0.8726636060000033, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_config_distributed_item_selector_parameters": 1.1619875570000318, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_config_distributed_items_path_from_previous": 0.8817333270000063, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_config_distributed_parameters": 0.9005068129999927, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_config_distributed_reentrant": 1.7203029819999642, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_config_distributed_reentrant_lambda": 2.9714986159999626, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_config_inline_item_selector": 0.8665574150001021, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_config_inline_parameters": 0.9104926609999779, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_item_selector[MAP_STATE_ITEM_SELECTOR]": 2.01728774999998, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_item_selector[MAP_STATE_ITEM_SELECTOR_JSONATA]": 0.823910264999995, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_item_selector_parameters": 1.1018301940000015, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_item_selector_singleton": 1.379092350999997, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata[empty]": 0.7443364420000194, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata[mixed]": 0.7585215819999576, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata[singleton]": 0.7431942860000618, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata_fail[boolean]": 0.8233383040000035, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata_fail[function]": 0.0019108139999843843, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata_fail[null]": 1.5184472420000361, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata_fail[number]": 0.6202659220000442, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata_fail[object]": 0.6193094079999923, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata_fail[string]": 0.7979415620000054, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata_variable_sampling_fail[boolean]": 0.8803093770000601, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata_variable_sampling_fail[null]": 0.8207496560000322, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata_variable_sampling_fail[number]": 0.8729903220000779, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata_variable_sampling_fail[object]": 1.478492378999988, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata_variable_sampling_fail[string]": 0.9278627799999981, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_input_array[empty]": 0.7715039409999349, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_input_array[mixed]": 0.7937926080000466, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_input_array[singleton]": 0.7719049730000052, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_input_types[boolean]": 1.0055935899999895, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_input_types[null]": 1.0376942850000432, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_input_types[number]": 1.0144505949999711, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_input_types[object]": 1.0150065149999818, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_input_types[string]": 1.0126865450000082, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_variable_sampling[boolean]": 0.8491785250000703, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_variable_sampling[null]": 0.8553098920000366, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_variable_sampling[number]": 0.8535434150000469, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_variable_sampling[object]": 0.8686161370000036, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_variable_sampling[string]": 0.8184311840000191, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_label": 0.7752743809999743, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_legacy": 0.9245326360000377, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_legacy_config_distributed": 0.8512868679999883, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_legacy_config_distributed_item_selector": 0.8858682039999621, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_legacy_config_distributed_parameters": 1.6015615369999523, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_legacy_config_inline": 0.8759511889999771, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_legacy_config_inline_item_selector": 0.8891641520000348, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_legacy_config_inline_parameters": 0.9217837090000103, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_legacy_reentrant": 1.7292490389999102, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_nested": 0.9526129700000183, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_nested_config_distributed": 0.9301677050000308, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_nested_config_distributed_no_max_max_concurrency": 10.49850474699997, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_no_processor_config": 0.8461344010000857, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_parameters_legacy": 1.9987706910000043, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_parameters_singleton_legacy": 1.3964725090000343, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_result_writer": 1.1968832370000655, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_retry": 3.7905137230000037, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_retry_legacy": 3.771064236999962, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_retry_multiple_retriers": 7.797399253000037, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_count_path[-1]": 0.7564521570000124, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_count_path[0]": 0.7770182189999559, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_count_path[1]": 0.7938085790000287, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_count_path[NoNumber]": 0.7770945209999809, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_count_path[tolerated_failure_count_value0]": 0.7890256630000181, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_percentage_path[-1.1]": 0.7790876360000425, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_percentage_path[-1]": 0.7841271589999224, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_percentage_path[0]": 0.7986977800000545, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_percentage_path[1.1]": 0.7926881330000128, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_percentage_path[100.1]": 1.4472125569999434, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_percentage_path[100]": 0.8202620320000165, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_percentage_path[1]": 0.7906418620000295, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_percentage_path[NoNumber]": 0.807930521000003, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_percentage_path[tolerated_failure_percentage_value0]": 0.8311843440000075, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_values[count_literal]": 0.7971971620000318, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_values[percentage_literal]": 0.7898400449999485, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_max_concurrency_path[0]": 0.8114140269999552, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_max_concurrency_path[1]": 0.7718252359999269, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_max_concurrency_path[NoNumber]": 0.7933895819999748, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_max_concurrency_path[max_concurrency_value0]": 0.7749181920000865, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_max_concurrency_path_negative": 0.8360408509999502, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_parallel_state[PARALLEL_STATE]": 0.8670177540000168, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_parallel_state[PARALLEL_STATE_PARAMETERS]": 0.7991589989999852, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_parallel_state_catch": 0.8015887449999468, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_parallel_state_fail": 0.7295432119999532, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_parallel_state_nested": 1.0682879039999875, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_parallel_state_order": 0.8956581660000893, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_parallel_state_retry": 3.7150253539999767, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_retry_interval_features": 6.854689269000005, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_retry_interval_features_jitter_none": 4.4824249079999845, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_retry_interval_features_max_attempts_zero": 2.4179820459999064, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_seconds_jsonata": 0.5606232650001175, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp[NANOSECONDS]": 0.5494174629999407, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp[SECONDS]": 0.5685417750000852, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_invalid[INVALID_DATE]": 0.47077886199986096, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_invalid[INVALID_ISO]": 0.4925717659999691, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_invalid[INVALID_TIME]": 0.5009299390000024, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_invalid[JSONATA]": 0.49709355000004507, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_invalid[NO_T]": 0.5341191719999188, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_invalid[NO_Z]": 1.2602082749999681, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_jsonata[INVALID_DATE]": 0.0016176479999785442, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_jsonata[INVALID_ISO]": 0.001612166999962028, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_jsonata[INVALID_TIME]": 0.0016243189999158858, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_jsonata[NANOSECONDS]": 0.764752772000179, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_jsonata[NO_T]": 0.0018718020000960678, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_jsonata[NO_Z]": 0.0016137190000335977, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_jsonata[SECONDS]": 0.7603305319998981, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_path[INVALID_DATE]": 0.7800436889999673, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_path[INVALID_ISO]": 0.7845425670001305, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_path[INVALID_TIME]": 0.7794426140001178, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_path[NANOSECONDS]": 0.7812388810000357, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_path[NO_T]": 0.7792963299999656, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_path[NO_Z]": 0.7701200210000252, - "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_path[SECONDS]": 0.7850010410001005, - "tests/aws/services/stepfunctions/v2/scenarios/test_sfn_scenarios.py::TestFundamental::test_path_based_on_data": 7.1810407560001295, - "tests/aws/services/stepfunctions/v2/scenarios/test_sfn_scenarios.py::TestFundamental::test_step_functions_calling_api_gateway": 11.47213118000002, - "tests/aws/services/stepfunctions/v2/scenarios/test_sfn_scenarios.py::TestFundamental::test_wait_for_callback": 19.634785126999873, - "tests/aws/services/stepfunctions/v2/services/test_apigetway_task_service.py::TestTaskApiGateway::test_invoke_base": 3.2372750849999647, - "tests/aws/services/stepfunctions/v2/services/test_apigetway_task_service.py::TestTaskApiGateway::test_invoke_error": 3.2119770099999414, - "tests/aws/services/stepfunctions/v2/services/test_apigetway_task_service.py::TestTaskApiGateway::test_invoke_with_body_post[HelloWorld]": 3.3159384650000447, - "tests/aws/services/stepfunctions/v2/services/test_apigetway_task_service.py::TestTaskApiGateway::test_invoke_with_body_post[None]": 4.302116198000135, - "tests/aws/services/stepfunctions/v2/services/test_apigetway_task_service.py::TestTaskApiGateway::test_invoke_with_body_post[]": 3.2289084220000177, - "tests/aws/services/stepfunctions/v2/services/test_apigetway_task_service.py::TestTaskApiGateway::test_invoke_with_body_post[request_body3]": 3.273048779000078, - "tests/aws/services/stepfunctions/v2/services/test_apigetway_task_service.py::TestTaskApiGateway::test_invoke_with_headers[custom_header1]": 3.3185169459999315, - "tests/aws/services/stepfunctions/v2/services/test_apigetway_task_service.py::TestTaskApiGateway::test_invoke_with_headers[custom_header2]": 3.316922142999829, - "tests/aws/services/stepfunctions/v2/services/test_apigetway_task_service.py::TestTaskApiGateway::test_invoke_with_headers[singleStringHeader]": 0.0032847590000528726, - "tests/aws/services/stepfunctions/v2/services/test_apigetway_task_service.py::TestTaskApiGateway::test_invoke_with_query_parameters": 3.637560958999984, - "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_dynamodb_put_delete_item": 2.063889763000134, - "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_dynamodb_put_get_item": 2.930973487999836, - "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_dynamodb_put_update_get_item": 1.4410318709999501, - "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_list_secrets": 1.0707105860000183, - "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_s3_get_object[binary]": 1.3676194119999536, - "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_s3_get_object[bytearray]": 1.2578233740000542, - "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_s3_get_object[empty_binary]": 1.2743115000001808, - "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_s3_get_object[empty_str]": 1.2727675630000022, - "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_s3_get_object[str]": 1.2479577740000423, - "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_s3_put_object[bool]": 1.3542705929999101, - "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_s3_put_object[dict]": 1.3002291529999184, - "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_s3_put_object[list]": 1.325375301000122, - "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_s3_put_object[num]": 1.3771391090000407, - "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_s3_put_object[str]": 1.2955481290000534, - "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_sfn_send_task_outcome_with_no_such_token[state_machine_template0]": 1.062097733000087, - "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_sfn_send_task_outcome_with_no_such_token[state_machine_template1]": 1.027511271999856, - "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_sfn_start_execution": 1.2197346759999164, - "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_sfn_start_execution_implicit_json_serialisation": 1.237098405000097, - "tests/aws/services/stepfunctions/v2/services/test_dynamodb_task_service.py::TestTaskServiceDynamoDB::test_base_integrations[DYNAMODB_PUT_DELETE_ITEM]": 1.3658884149999722, - "tests/aws/services/stepfunctions/v2/services/test_dynamodb_task_service.py::TestTaskServiceDynamoDB::test_base_integrations[DYNAMODB_PUT_GET_ITEM]": 1.3603615540000646, - "tests/aws/services/stepfunctions/v2/services/test_dynamodb_task_service.py::TestTaskServiceDynamoDB::test_base_integrations[DYNAMODB_PUT_QUERY]": 1.3715085019999833, - "tests/aws/services/stepfunctions/v2/services/test_dynamodb_task_service.py::TestTaskServiceDynamoDB::test_base_integrations[DYNAMODB_PUT_UPDATE_GET_ITEM]": 2.688038919000064, - "tests/aws/services/stepfunctions/v2/services/test_dynamodb_task_service.py::TestTaskServiceDynamoDB::test_invalid_integration": 0.6785854890000564, - "tests/aws/services/stepfunctions/v2/services/test_ecs_task_service.py::TestTaskServiceECS::test_run_task": 0.0018661310000425146, - "tests/aws/services/stepfunctions/v2/services/test_ecs_task_service.py::TestTaskServiceECS::test_run_task_raise_failure": 0.0018429689999948096, - "tests/aws/services/stepfunctions/v2/services/test_ecs_task_service.py::TestTaskServiceECS::test_run_task_sync": 0.0017047599999386875, - "tests/aws/services/stepfunctions/v2/services/test_ecs_task_service.py::TestTaskServiceECS::test_run_task_sync_raise_failure": 0.0017425200001071062, - "tests/aws/services/stepfunctions/v2/services/test_events_task_service.py::TestTaskServiceEvents::test_put_events_base": 2.1330921109999963, - "tests/aws/services/stepfunctions/v2/services/test_events_task_service.py::TestTaskServiceEvents::test_put_events_malformed_detail": 1.0477688399998897, - "tests/aws/services/stepfunctions/v2/services/test_events_task_service.py::TestTaskServiceEvents::test_put_events_mixed_malformed_detail": 1.0572384390000025, - "tests/aws/services/stepfunctions/v2/services/test_events_task_service.py::TestTaskServiceEvents::test_put_events_no_source": 31.922309869999935, - "tests/aws/services/stepfunctions/v2/services/test_lambda_task.py::TestTaskLambda::test_invoke_bytes_payload": 2.1567627590001166, - "tests/aws/services/stepfunctions/v2/services/test_lambda_task.py::TestTaskLambda::test_invoke_json_values[0.0]": 2.1660646919999635, - "tests/aws/services/stepfunctions/v2/services/test_lambda_task.py::TestTaskLambda::test_invoke_json_values[0_0]": 2.1574068959999977, - "tests/aws/services/stepfunctions/v2/services/test_lambda_task.py::TestTaskLambda::test_invoke_json_values[0_1]": 2.1662054089999856, - "tests/aws/services/stepfunctions/v2/services/test_lambda_task.py::TestTaskLambda::test_invoke_json_values[HelloWorld]": 2.1930020790001663, - "tests/aws/services/stepfunctions/v2/services/test_lambda_task.py::TestTaskLambda::test_invoke_json_values[True]": 2.143112401999929, - "tests/aws/services/stepfunctions/v2/services/test_lambda_task.py::TestTaskLambda::test_invoke_json_values[json_value5]": 2.158147387999975, - "tests/aws/services/stepfunctions/v2/services/test_lambda_task.py::TestTaskLambda::test_invoke_json_values[json_value6]": 2.198048435999908, - "tests/aws/services/stepfunctions/v2/services/test_lambda_task.py::TestTaskLambda::test_invoke_pipe": 3.809157419999906, - "tests/aws/services/stepfunctions/v2/services/test_lambda_task.py::TestTaskLambda::test_invoke_string_payload": 2.161412453999901, - "tests/aws/services/stepfunctions/v2/services/test_lambda_task.py::TestTaskLambda::test_lambda_task_filter_parameters_input": 2.437066474999938, - "tests/aws/services/stepfunctions/v2/services/test_lambda_task_service.py::TestTaskServiceLambda::test_invoke": 2.617546779999884, - "tests/aws/services/stepfunctions/v2/services/test_lambda_task_service.py::TestTaskServiceLambda::test_invoke_bytes_payload": 2.4323566979999214, - "tests/aws/services/stepfunctions/v2/services/test_lambda_task_service.py::TestTaskServiceLambda::test_invoke_json_values[0.0]": 3.6030644189999066, - "tests/aws/services/stepfunctions/v2/services/test_lambda_task_service.py::TestTaskServiceLambda::test_invoke_json_values[0_0]": 2.632834134999939, - "tests/aws/services/stepfunctions/v2/services/test_lambda_task_service.py::TestTaskServiceLambda::test_invoke_json_values[0_1]": 2.6459750610000583, - "tests/aws/services/stepfunctions/v2/services/test_lambda_task_service.py::TestTaskServiceLambda::test_invoke_json_values[HelloWorld]": 2.5823866819998784, - "tests/aws/services/stepfunctions/v2/services/test_lambda_task_service.py::TestTaskServiceLambda::test_invoke_json_values[True]": 2.663581646999887, - "tests/aws/services/stepfunctions/v2/services/test_lambda_task_service.py::TestTaskServiceLambda::test_invoke_json_values[json_value5]": 2.6687649639999336, - "tests/aws/services/stepfunctions/v2/services/test_lambda_task_service.py::TestTaskServiceLambda::test_invoke_json_values[json_value6]": 2.6483745560000216, - "tests/aws/services/stepfunctions/v2/services/test_lambda_task_service.py::TestTaskServiceLambda::test_invoke_unsupported_param": 2.6298553699998592, - "tests/aws/services/stepfunctions/v2/services/test_lambda_task_service.py::TestTaskServiceLambda::test_list_functions": 0.0027924789999360655, - "tests/aws/services/stepfunctions/v2/services/test_sfn_task_service.py::TestTaskServiceSfn::test_start_execution": 1.2591937419999795, - "tests/aws/services/stepfunctions/v2/services/test_sfn_task_service.py::TestTaskServiceSfn::test_start_execution_input_json": 1.2256195539999908, - "tests/aws/services/stepfunctions/v2/services/test_sns_task_service.py::TestTaskServiceSns::test_fifo_message_attribute[input_params0-True]": 1.3244576369999095, - "tests/aws/services/stepfunctions/v2/services/test_sns_task_service.py::TestTaskServiceSns::test_fifo_message_attribute[input_params1-False]": 1.0515114160000394, - "tests/aws/services/stepfunctions/v2/services/test_sns_task_service.py::TestTaskServiceSns::test_publish_base[1]": 0.9827651380001043, - "tests/aws/services/stepfunctions/v2/services/test_sns_task_service.py::TestTaskServiceSns::test_publish_base[HelloWorld]": 1.0639517439999508, - "tests/aws/services/stepfunctions/v2/services/test_sns_task_service.py::TestTaskServiceSns::test_publish_base[None]": 1.0646824670000115, - "tests/aws/services/stepfunctions/v2/services/test_sns_task_service.py::TestTaskServiceSns::test_publish_base[True]": 1.0150817599998163, - "tests/aws/services/stepfunctions/v2/services/test_sns_task_service.py::TestTaskServiceSns::test_publish_base[]": 1.092534255999908, - "tests/aws/services/stepfunctions/v2/services/test_sns_task_service.py::TestTaskServiceSns::test_publish_base[message1]": 1.010055293999926, - "tests/aws/services/stepfunctions/v2/services/test_sns_task_service.py::TestTaskServiceSns::test_publish_base_error_topic_arn": 1.042933230000017, - "tests/aws/services/stepfunctions/v2/services/test_sns_task_service.py::TestTaskServiceSns::test_publish_message_attributes[\"HelloWorld\"]": 1.3483258469998418, - "tests/aws/services/stepfunctions/v2/services/test_sns_task_service.py::TestTaskServiceSns::test_publish_message_attributes[HelloWorld]": 1.2223543759999984, - "tests/aws/services/stepfunctions/v2/services/test_sns_task_service.py::TestTaskServiceSns::test_publish_message_attributes[message_value3]": 2.2614442440000175, - "tests/aws/services/stepfunctions/v2/services/test_sns_task_service.py::TestTaskServiceSns::test_publish_message_attributes[{}]": 1.1499791620000224, - "tests/aws/services/stepfunctions/v2/services/test_sqs_task_service.py::TestTaskServiceSqs::test_send_message": 1.2444930250001107, - "tests/aws/services/stepfunctions/v2/services/test_sqs_task_service.py::TestTaskServiceSqs::test_send_message_attributes": 1.552836147999983, - "tests/aws/services/stepfunctions/v2/services/test_sqs_task_service.py::TestTaskServiceSqs::test_send_message_unsupported_parameters": 1.2420051190001686, - "tests/aws/services/stepfunctions/v2/states_variables/test_error_output.py::TestStateVariablesTemplate::test_catch_error_variable_sampling[TASK_CATCH_ERROR_VARIABLE_SAMPLING]": 2.6772251750001033, - "tests/aws/services/stepfunctions/v2/states_variables/test_error_output.py::TestStateVariablesTemplate::test_catch_error_variable_sampling[TASK_CATCH_ERROR_VARIABLE_SAMPLING_TO_JSONPATH]": 2.52065858200001, - "tests/aws/services/stepfunctions/v2/states_variables/test_error_output.py::TestStateVariablesTemplate::test_map_catch_error[MAP_CATCH_ERROR_OUTPUT]": 0.0028028579999954673, - "tests/aws/services/stepfunctions/v2/states_variables/test_error_output.py::TestStateVariablesTemplate::test_map_catch_error[MAP_CATCH_ERROR_OUTPUT_WITH_RETRY]": 0.0017257890000337284, - "tests/aws/services/stepfunctions/v2/states_variables/test_error_output.py::TestStateVariablesTemplate::test_map_catch_error[MAP_CATCH_ERROR_VARIABLE_SAMPLING]": 0.0017162020000114353, - "tests/aws/services/stepfunctions/v2/states_variables/test_error_output.py::TestStateVariablesTemplate::test_parallel_catch_error[PARALLEL_CATCH_ERROR_OUTPUT]": 0.0017203690000542338, - "tests/aws/services/stepfunctions/v2/states_variables/test_error_output.py::TestStateVariablesTemplate::test_parallel_catch_error[PARALLEL_CATCH_ERROR_OUTPUT_WITH_RETRY]": 0.0018743660000382079, - "tests/aws/services/stepfunctions/v2/states_variables/test_error_output.py::TestStateVariablesTemplate::test_parallel_catch_error[PARALLEL_CATCH_ERROR_VARIABLE_SAMPLING]": 0.0018528449999166696, - "tests/aws/services/stepfunctions/v2/states_variables/test_error_output.py::TestStateVariablesTemplate::test_task_catch_error_output[TASK_CATCH_ERROR_OUTPUT]": 2.441055682999945, - "tests/aws/services/stepfunctions/v2/states_variables/test_error_output.py::TestStateVariablesTemplate::test_task_catch_error_output[TASK_CATCH_ERROR_OUTPUT_TO_JSONPATH]": 2.4661862060000885, - "tests/aws/services/stepfunctions/v2/states_variables/test_error_output.py::TestStateVariablesTemplate::test_task_catch_error_with_retry[TASK_CATCH_ERROR_OUTPUT_WITH_RETRY]": 3.7022690969999985, - "tests/aws/services/stepfunctions/v2/states_variables/test_error_output.py::TestStateVariablesTemplate::test_task_catch_error_with_retry[TASK_CATCH_ERROR_OUTPUT_WITH_RETRY_TO_JSONPATH]": 3.6969504429999915, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_cloudformation_definition_create_describe[dump]": 1.5881436349999376, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_cloudformation_definition_create_describe[dumps]": 1.576368971000079, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_cloudformation_definition_string_create_describe[dump]": 1.553797421000013, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_cloudformation_definition_string_create_describe[dumps]": 1.5605832370000599, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_create_delete_invalid_sm": 0.6961708160000626, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_create_delete_valid_sm": 1.6919566930000656, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_create_duplicate_definition_format_sm": 0.5611284749999186, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_create_duplicate_sm_name": 0.602154779999978, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_create_exact_duplicate_sm": 0.6265577960000428, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_create_update_state_machine_base_definition": 0.6139535479999267, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_create_update_state_machine_base_definition_and_role": 0.9179003170000897, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_create_update_state_machine_base_role_arn": 0.9523478289999048, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_create_update_state_machine_base_update_none": 0.5811059049999585, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_create_update_state_machine_same_parameters": 0.803074760999948, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_delete_nonexistent_sm": 0.5612622969999848, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_describe_execution": 0.8532308579998471, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_describe_execution_arn_containing_punctuation": 0.8378504150000481, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_describe_execution_invalid_arn": 0.42182849099992836, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_describe_execution_no_such_state_machine": 0.8125546520001308, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_describe_invalid_arn_sm": 0.4286800000000994, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_describe_nonexistent_sm": 0.5518591449999803, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_describe_sm_arn_containing_punctuation": 0.5658289559999048, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_describe_state_machine_for_execution": 0.6573217249999743, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_get_execution_history_invalid_arn": 0.435370929999749, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_get_execution_history_no_such_execution": 0.6082120300001179, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_get_execution_history_reversed": 0.6439360819998683, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_invalid_start_execution_arn": 0.5699820519998866, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_invalid_start_execution_input": 0.9259551009999996, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_list_execution_invalid_arn": 0.42492491699999846, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_list_execution_no_such_state_machine": 0.5414465860000064, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_list_executions_pagination": 2.3908951109999634, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_list_executions_versions_pagination": 2.032395019999967, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_list_sms": 1.7774182319999454, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_list_sms_pagination": 1.0339373209999394, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_start_execution": 0.7167468789999702, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_start_execution_idempotent": 1.4154493189998902, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_start_sync_execution": 0.5716178250000894, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_state_machine_status_filter": 0.7285088309999992, - "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_stop_execution": 0.6345933199999081, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[\\x00activity]": 0.34831221500007814, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity name]": 1.4067500859999882, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity\"name]": 0.344950960999995, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity#name]": 0.345598306999932, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity$name]": 0.362341008000044, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity%name]": 0.3649620259998301, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity&name]": 0.3531558590000259, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity*name]": 0.34858276499994645, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity,name]": 0.34580451300007553, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity/name]": 0.3450719850001178, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity:name]": 0.33823142400012784, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity;name]": 0.341224994000072, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activityname]": 0.3462244620000092, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity?name]": 0.35119658899998285, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity[name]": 0.34867460700002084, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity\\\\name]": 0.37689796099994055, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity\\x1f]": 0.34322929200004637, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity\\x7f]": 0.35415321700008917, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity]name]": 0.33920537700009845, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity^name]": 0.34953446700001223, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity`name]": 0.35634314399987943, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity{name]": 0.33655065799985096, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity|name]": 0.3370144479998771, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity}name]": 0.3410622929999363, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity~name]": 0.35655057299993587, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_describe_delete_activity[ACTIVITY_NAME_ABC]": 0.43021359899989875, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_describe_delete_activity[Activity1]": 0.4208897789999355, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_describe_delete_activity[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]": 0.41945780699995794, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_describe_delete_activity[activity-name.1]": 0.41681878199995026, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_describe_delete_activity[activity-name_123]": 0.4096636390002004, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_describe_delete_activity[activity.name.v2]": 0.41834955300009824, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_describe_delete_activity[activity.name]": 0.4197662550001269, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_describe_delete_activity[activityName.with.dots]": 0.41866850200005956, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_describe_delete_activity[activity_123.name]": 0.4175606719999223, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_describe_activity_invalid_arn": 0.44914019299994834, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_describe_deleted_activity": 0.35904049100008706, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_get_activity_task_deleted": 0.3707353500000181, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_get_activity_task_invalid_arn": 0.43628677600008814, - "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_list_activities": 0.3721023289999721, - "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_base_create_alias_single_router_config": 0.8076415270001007, - "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_base_lifecycle_create_delete_list": 0.9577133400000548, - "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_base_lifecycle_create_invoke_describe_list": 1.1402098880000722, - "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_base_lifecycle_create_update_describe": 0.878736133999837, - "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_delete_no_such_alias_arn": 0.8725599350000266, - "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_delete_revision_with_alias": 1.9021881990000793, - "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_delete_version_with_alias": 0.8622258359997659, - "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_error_create_alias_invalid_name": 0.8431407589999935, - "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_error_create_alias_invalid_router_configs": 0.9765689229998316, - "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_error_create_alias_not_idempotent": 0.8493711649998659, - "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_error_create_alias_with_state_machine_arn": 0.7923267229999738, - "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_idempotent_create_alias": 0.8727633209999794, - "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_list_state_machine_aliases_pagination_invalid_next_token": 0.8502278880000631, - "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_list_state_machine_aliases_pagination_max_results[0]": 0.9624754760001224, - "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_list_state_machine_aliases_pagination_max_results[1]": 0.9358237839998083, - "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_update_no_such_alias_arn": 0.8257441810001183, - "tests/aws/services/stepfunctions/v2/test_sfn_api_express.py::TestSfnApiExpress::test_create_describe_delete": 0.8811360439999589, - "tests/aws/services/stepfunctions/v2/test_sfn_api_express.py::TestSfnApiExpress::test_illegal_activity_task": 1.0678905810000288, - "tests/aws/services/stepfunctions/v2/test_sfn_api_express.py::TestSfnApiExpress::test_illegal_callbacks[SYNC]": 0.9871877439999253, - "tests/aws/services/stepfunctions/v2/test_sfn_api_express.py::TestSfnApiExpress::test_illegal_callbacks[WAIT_FOR_TASK_TOKEN]": 1.0379468339999676, - "tests/aws/services/stepfunctions/v2/test_sfn_api_express.py::TestSfnApiExpress::test_start_async_describe_history_execution": 1.5414078940000309, - "tests/aws/services/stepfunctions/v2/test_sfn_api_express.py::TestSfnApiExpress::test_start_sync_execution": 0.9411656310001035, - "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_deleted_log_group": 0.7490657249999231, - "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_incomplete_logging_configuration[logging_configuration0]": 0.5569680209999888, - "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_incomplete_logging_configuration[logging_configuration1]": 0.5898548929999379, - "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_invalid_logging_configuration[logging_configuration0]": 0.5535597949999556, - "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_invalid_logging_configuration[logging_configuration1]": 0.542750725000019, - "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_invalid_logging_configuration[logging_configuration2]": 0.5267719570000509, - "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_logging_configuration[ALL-False]": 0.5959662820000631, - "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_logging_configuration[ALL-True]": 0.5937091839999766, - "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_logging_configuration[ERROR-False]": 0.6398123120000037, - "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_logging_configuration[ERROR-True]": 0.6105114679999133, - "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_logging_configuration[FATAL-False]": 0.6068447910000714, - "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_logging_configuration[FATAL-True]": 0.6250527820001253, - "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_logging_configuration[OFF-False]": 0.5994350810000242, - "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_logging_configuration[OFF-True]": 0.5889836359999663, - "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_multiple_destinations": 0.5746409659998335, - "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_update_logging_configuration": 0.7206022350000012, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_list_map_runs_and_describe_map_run": 0.913529161999918, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_empty_fail": 0.4624437969999917, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[ ]": 0.4390262320000602, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\"]": 0.43546999200009395, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[#]": 0.4114230699998416, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[$]": 0.44152975200006495, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[%]": 0.44155923599998914, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[&]": 0.4205980180000779, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[*]": 0.44624152700009745, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[,]": 1.539660063000042, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[:]": 0.45531433300004664, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[;]": 0.44653031899997586, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[<]": 0.44204617099990173, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[>]": 0.47471668399998634, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[?]": 0.44316829199988206, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[[]": 0.44151932700003726, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\\\]": 0.41022915099995316, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\n]": 0.4405837980000342, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\r]": 0.4353016129999787, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\t]": 0.43393141800004287, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x00]": 0.4424964040000532, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x01]": 0.44293309700003647, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x02]": 0.4467426019998584, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x03]": 0.44607877899989035, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x04]": 0.4743552710000358, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x05]": 0.5065495460000875, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x06]": 0.4411645290000479, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x07]": 0.4126873129999922, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x08]": 0.439054062000082, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x0b]": 0.4364733190000152, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x0c]": 0.4049070139999458, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x0e]": 0.41900308599997516, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x0f]": 0.41564771700006986, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x10]": 0.4421944460001441, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x11]": 0.4444982950001304, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x12]": 0.44182774099988364, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x13]": 0.44433604999994714, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x14]": 0.440342008000016, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x15]": 0.43890373899989754, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x16]": 0.4412134500000775, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x17]": 0.4380454860000782, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x18]": 0.44175520700002835, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x19]": 0.4413641909999342, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x1a]": 0.44511620099990523, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x1b]": 0.4497449329999199, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x1c]": 0.4728601509999635, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x1d]": 0.4994777059998796, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x1e]": 0.45321194600012404, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x1f]": 0.42449061399986476, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x7f]": 0.42654749099995115, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x80]": 0.4458500760000561, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x81]": 0.44860443599998234, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x82]": 0.4664083999999775, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x83]": 0.45917724200000976, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x84]": 0.4645919560000493, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x85]": 0.45990498800017576, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x86]": 0.45739347800008545, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x87]": 0.44846143699999175, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x88]": 0.46399504500004696, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x89]": 0.45173733700005414, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x8a]": 0.458943391000048, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x8b]": 0.4523218510001925, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x8c]": 0.447000700999979, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x8d]": 0.440195969999877, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x8e]": 0.4399009539999952, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x8f]": 0.41626861599991116, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x90]": 0.44992605799996, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x91]": 0.4527835879998747, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x92]": 0.4659891389999302, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x93]": 1.679945506000081, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x94]": 0.4449015430000145, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x95]": 0.4563248739999608, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x96]": 0.45332371500001045, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x97]": 0.44187052299992047, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x98]": 0.4450446960000818, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x99]": 0.4487664750000704, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x9a]": 0.4559016600001087, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x9b]": 0.4403175749999946, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x9c]": 0.44285795099995084, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x9d]": 0.45596737400001075, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x9e]": 0.4835678890000281, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x9f]": 0.4825932950001288, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[]]": 0.4456575550001389, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[^]": 0.4467860520001068, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[`]": 0.4074593200000436, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[{]": 0.48703024300004927, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[|]": 0.4468120539999063, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[}]": 0.469523590000108, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[~]": 0.4475361450000719, - "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_too_long_fail": 0.4621160809999765, - "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_create_state_machine": 0.47990492199994605, - "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_tag_invalid_state_machine[None]": 0.5027888899999198, - "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_tag_invalid_state_machine[tag_list1]": 0.46188935499992567, - "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_tag_invalid_state_machine[tag_list2]": 0.47276361000001543, - "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_tag_invalid_state_machine[tag_list3]": 0.44665474999999333, - "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_tag_state_machine[tag_list0]": 0.47957637400008934, - "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_tag_state_machine[tag_list1]": 0.4644884990000264, - "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_tag_state_machine[tag_list2]": 0.47781529600013073, - "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_tag_state_machine[tag_list3]": 0.47895795600015845, - "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_tag_state_machine[tag_list4]": 0.4866146739999522, - "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_tag_state_machine_version": 0.4972205030001078, - "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_untag_state_machine[tag_keys0]": 0.5025914579998698, - "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_untag_state_machine[tag_keys1]": 0.5058975549999332, - "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_untag_state_machine[tag_keys2]": 0.4908802639999976, - "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_untag_state_machine[tag_keys3]": 0.4919675250000637, - "tests/aws/services/stepfunctions/v2/test_sfn_api_validation.py::TestSfnApiValidation::test_validate_state_machine_definition_not_a_definition[EMPTY_DICT]": 0.34137656400002925, - "tests/aws/services/stepfunctions/v2/test_sfn_api_validation.py::TestSfnApiValidation::test_validate_state_machine_definition_not_a_definition[EMPTY_STRING]": 0.36556510700006584, - "tests/aws/services/stepfunctions/v2/test_sfn_api_validation.py::TestSfnApiValidation::test_validate_state_machine_definition_not_a_definition[NOT_A_DEF]": 0.35117432099991674, - "tests/aws/services/stepfunctions/v2/test_sfn_api_validation.py::TestSfnApiValidation::test_validate_state_machine_definition_type_express[ILLEGAL_WFTT]": 0.3634003939999957, - "tests/aws/services/stepfunctions/v2/test_sfn_api_validation.py::TestSfnApiValidation::test_validate_state_machine_definition_type_express[INVALID_BASE_NO_STARTAT]": 0.3474091620000763, - "tests/aws/services/stepfunctions/v2/test_sfn_api_validation.py::TestSfnApiValidation::test_validate_state_machine_definition_type_express[VALID_BASE_PASS]": 0.35285891499995614, - "tests/aws/services/stepfunctions/v2/test_sfn_api_validation.py::TestSfnApiValidation::test_validate_state_machine_definition_type_standard[INVALID_BASE_NO_STARTAT]": 0.3454583300000422, - "tests/aws/services/stepfunctions/v2/test_sfn_api_validation.py::TestSfnApiValidation::test_validate_state_machine_definition_type_standard[VALID_BASE_PASS]": 0.35159758299994337, - "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[BASE_ASSIGN_FROM_INTRINSIC_FUNCTION]": 2.291611816999989, - "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[BASE_ASSIGN_FROM_PARAMETERS]": 1.0574095979999356, - "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[BASE_ASSIGN_FROM_RESULT]": 1.024733347999927, - "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[BASE_EVALUATION_ORDER_PASS_STATE]": 1.1028663140001527, - "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[BASE_REFERENCE_IN_CHOICE]": 1.0781535400000166, - "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[BASE_REFERENCE_IN_FAIL]": 1.015891508999971, - "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[BASE_REFERENCE_IN_INPUTPATH]": 1.0027356359998976, - "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[BASE_REFERENCE_IN_INTRINSIC_FUNCTION]": 2.4251618270001245, - "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[BASE_REFERENCE_IN_ITERATOR_OUTER_SCOPE]": 1.7125802279999789, - "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[BASE_REFERENCE_IN_OUTPUTPATH]": 1.0773119740001675, - "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[BASE_REFERENCE_IN_PARAMETERS]": 1.0521146780000663, - "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[BASE_REFERENCE_IN_WAIT]": 1.0354283080000641, - "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[MAP_STATE_REFERENCE_IN_INTRINSIC_FUNCTION]": 1.3152867479999486, - "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[MAP_STATE_REFERENCE_IN_ITEMS_PATH]": 1.3520402379999723, - "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[MAP_STATE_REFERENCE_IN_ITEM_SELECTOR]": 1.0939213630000495, - "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[MAP_STATE_REFERENCE_IN_MAX_CONCURRENCY_PATH]": 1.0530996720000303, - "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[MAP_STATE_REFERENCE_IN_MAX_ITEMS_PATH]": 1.0533667500000092, - "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[MAP_STATE_REFERENCE_IN_TOLERATED_FAILURE_PATH]": 1.063767640999913, - "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_jsonata_template[CHOICE_CONDITION_CONSTANT_JSONATA]": 0.6561670259999346, - "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_jsonata_template[CHOICE_STATE_UNSORTED_CHOICE_PARAMETERS_JSONATA]": 0.7128758829999242, - "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_create_express_with_publish": 0.515161820000003, - "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_create_publish_describe_no_version_description": 0.6032489780000105, - "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_create_publish_describe_with_version_description": 0.6001900450000903, - "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_create_with_publish": 0.5545050370000126, - "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_create_with_version_description_no_publish": 0.5372420310000052, - "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_describe_state_machine_for_execution_of_version": 0.7051018650000742, - "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_describe_state_machine_for_execution_of_version_with_revision": 0.6689285399999108, - "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_empty_revision_with_publish_and_no_publish_on_creation": 0.5746610789998385, - "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_empty_revision_with_publish_and_publish_on_creation": 0.5932220470001539, - "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_idempotent_publish": 0.6239598270000215, - "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_list_delete_version": 0.6387162180001269, - "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_list_state_machine_versions_pagination": 1.0638426849999405, - "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_publish_state_machine_version": 0.6900166440001385, - "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_publish_state_machine_version_invalid_arn": 0.4360606100000268, - "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_publish_state_machine_version_no_such_machine": 0.5734867620000159, - "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_start_version_execution": 0.7279803089999177, - "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_update_state_machine": 0.6165976949999958, - "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_version_ids_between_deletions": 0.606336242999987, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_debug[BASE_CHOICE_STATE]": 1.1330601689999185, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_debug[BASE_FAIL_STATE]": 0.9457227380000859, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_debug[BASE_PASS_STATE]": 0.9389019269999608, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_debug[BASE_RESULT_PASS_STATE]": 0.946125130999917, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_debug[BASE_SUCCEED_STATE]": 0.9089541430000736, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_debug[IO_PASS_STATE]": 1.0390565709999464, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_debug[IO_RESULT_PASS_STATE]": 1.1096661049999739, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_info[BASE_CHOICE_STATE]": 0.8013421480000034, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_info[BASE_FAIL_STATE]": 0.6252068369999506, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_info[BASE_PASS_STATE]": 0.6085578259999238, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_info[BASE_RESULT_PASS_STATE]": 0.6346525859999019, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_info[BASE_SUCCEED_STATE]": 0.6039706509999405, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_info[IO_PASS_STATE]": 0.7100111859999743, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_info[IO_RESULT_PASS_STATE]": 1.9820721479999293, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_trace[BASE_CHOICE_STATE]": 1.121766505999858, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_trace[BASE_FAIL_STATE]": 0.9811297159999413, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_trace[BASE_PASS_STATE]": 0.9325923319998992, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_trace[BASE_RESULT_PASS_STATE]": 0.9571003349999501, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_trace[BASE_SUCCEED_STATE]": 0.9232873800001471, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_trace[IO_PASS_STATE]": 1.0535959229998753, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_trace[IO_RESULT_PASS_STATE]": 1.0591145270000197, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_lambda_service_task_state[DEBUG]": 3.75871285300002, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_lambda_service_task_state[INFO]": 2.6254382270001315, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_lambda_service_task_state[TRACE]": 2.523958900000025, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_lambda_task_state[DEBUG]": 2.5842549470000904, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_lambda_task_state[INFO]": 2.547250692000034, - "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_lambda_task_state[TRACE]": 2.536257831999933, - "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::TestStateMachine::test_create_choice_state_machine": 2.8739770209998596, - "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::TestStateMachine::test_create_run_map_state_machine": 1.1731952490000594, - "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::TestStateMachine::test_create_run_state_machine": 1.5738201579999895, - "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::TestStateMachine::test_create_state_machines_in_parallel": 2.0677397490003386, - "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::TestStateMachine::test_events_state_machine": 0.001791517999890857, - "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::TestStateMachine::test_intrinsic_functions": 1.254514391999919, - "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::TestStateMachine::test_try_catch_state_machine": 10.161825717999818, - "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::test_aws_sdk_task": 1.3621733940001377, - "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::test_default_logging_configuration": 0.1995053390000976, - "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::test_multiregion_nested[statemachine_definition0-eu-central-1]": 0.0016608579999228823, - "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::test_multiregion_nested[statemachine_definition0-eu-west-1]": 0.001660855999944033, - "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::test_multiregion_nested[statemachine_definition0-us-east-1]": 0.0025518289999126864, - "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::test_multiregion_nested[statemachine_definition0-us-east-2]": 0.0017199870001149975, - "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::test_run_aws_sdk_secrets_manager": 3.3415291080000316, - "tests/aws/services/stepfunctions/v2/timeouts/test_heartbeats.py::TestHeartbeats::test_heartbeat_no_timeout": 6.095898601000272, - "tests/aws/services/stepfunctions/v2/timeouts/test_heartbeats.py::TestHeartbeats::test_heartbeat_path_timeout": 6.205913035000094, - "tests/aws/services/stepfunctions/v2/timeouts/test_heartbeats.py::TestHeartbeats::test_heartbeat_timeout": 6.3017243029996735, - "tests/aws/services/stepfunctions/v2/timeouts/test_timeouts.py::TestTimeouts::test_fixed_timeout_lambda": 6.949242629999844, - "tests/aws/services/stepfunctions/v2/timeouts/test_timeouts.py::TestTimeouts::test_fixed_timeout_service_lambda": 6.996302237999998, - "tests/aws/services/stepfunctions/v2/timeouts/test_timeouts.py::TestTimeouts::test_fixed_timeout_service_lambda_with_path": 7.050686655999698, - "tests/aws/services/stepfunctions/v2/timeouts/test_timeouts.py::TestTimeouts::test_global_timeout": 5.714374802999828, - "tests/aws/services/stepfunctions/v2/timeouts/test_timeouts.py::TestTimeouts::test_service_lambda_map_timeout": 0.003185119999898234, - "tests/aws/services/sts/test_sts.py::TestSTSAssumeRoleTagging::test_assume_role_tag_validation": 0.20799444199997197, - "tests/aws/services/sts/test_sts.py::TestSTSAssumeRoleTagging::test_iam_role_chaining_override_transitive_tags": 0.39890159300011874, - "tests/aws/services/sts/test_sts.py::TestSTSIntegrations::test_assume_non_existent_role": 0.016097511999987546, - "tests/aws/services/sts/test_sts.py::TestSTSIntegrations::test_assume_role": 0.26473025500013136, - "tests/aws/services/sts/test_sts.py::TestSTSIntegrations::test_assume_role_with_saml": 0.0519469629998639, - "tests/aws/services/sts/test_sts.py::TestSTSIntegrations::test_assume_role_with_web_identity": 0.04102754699988509, - "tests/aws/services/sts/test_sts.py::TestSTSIntegrations::test_expiration_date_format": 0.01801258700015751, - "tests/aws/services/sts/test_sts.py::TestSTSIntegrations::test_get_caller_identity_role_access_key[False]": 0.19947775199989337, - "tests/aws/services/sts/test_sts.py::TestSTSIntegrations::test_get_caller_identity_role_access_key[True]": 0.22457528900008583, - "tests/aws/services/sts/test_sts.py::TestSTSIntegrations::test_get_caller_identity_root": 0.015528662000178883, - "tests/aws/services/sts/test_sts.py::TestSTSIntegrations::test_get_caller_identity_user_access_key[False]": 0.07802176199970745, - "tests/aws/services/sts/test_sts.py::TestSTSIntegrations::test_get_caller_identity_user_access_key[True]": 0.3180290329999025, - "tests/aws/services/sts/test_sts.py::TestSTSIntegrations::test_get_federation_token": 0.1302918789999694, - "tests/aws/services/support/test_support.py::TestConfigService::test_support_case_lifecycle": 0.06899514799988538, - "tests/aws/services/swf/test_swf.py::TestSwf::test_run_workflow": 0.20529056400005175, - "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_failing_deletion": 0.16679914500014092, - "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_failing_start_transcription_job": 0.3312099540003146, - "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_get_transcription_job": 2.2873154829999294, - "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_list_transcription_jobs": 2.3577102979998017, - "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_error_invalid_length": 32.02200791899986, - "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_error_speaker_labels": 0.001696116000175607, - "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_happy_path": 3.5277294709999296, - "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_speaker_diarization": 0.002241413000092507, - "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_start_job[None-None]": 2.412294025999927, - "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_start_job[test-output-bucket-2-None]": 4.612917553999978, - "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_start_job[test-output-bucket-3-test-output]": 4.94986339199977, - "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_start_job[test-output-bucket-4-test-output.json]": 4.973612471000024, - "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_start_job[test-output-bucket-5-test-files/test-output.json]": 4.935605785000234, - "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_start_job[test-output-bucket-6-test-files/test-output]": 4.951679161999891, - "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_start_job_same_name": 2.308895062999909, - "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_supported_media_formats[../../files/en-gb.amr-hello my name is]": 2.1630361349998566, - "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_supported_media_formats[../../files/en-gb.flac-hello my name is]": 2.1742246039998463, - "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_supported_media_formats[../../files/en-gb.mp3-hello my name is]": 2.1606591110003137, - "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_supported_media_formats[../../files/en-gb.mp4-hello my name is]": 2.180706547999989, - "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_supported_media_formats[../../files/en-gb.ogg-hello my name is]": 2.1736241880003035, - "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_supported_media_formats[../../files/en-gb.webm-hello my name is]": 2.2034048839998377, - "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_supported_media_formats[../../files/en-us_video.mkv-one of the most vital]": 2.189157536000039, - "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_supported_media_formats[../../files/en-us_video.mp4-one of the most vital]": 2.1696221879999484, - "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_unsupported_media_format_failure": 3.189110919000086, - "tests/aws/test_error_injection.py::TestErrorInjection::test_dynamodb_error_injection": 25.73772035700017, - "tests/aws/test_error_injection.py::TestErrorInjection::test_dynamodb_read_error_injection": 25.73765976100003, - "tests/aws/test_error_injection.py::TestErrorInjection::test_dynamodb_write_error_injection": 51.374003802999596, - "tests/aws/test_error_injection.py::TestErrorInjection::test_kinesis_error_injection": 2.0712776349998876, - "tests/aws/test_integration.py::TestIntegration::test_firehose_extended_s3": 0.19859066200001507, - "tests/aws/test_integration.py::TestIntegration::test_firehose_kinesis_to_s3": 21.337352958999645, - "tests/aws/test_integration.py::TestIntegration::test_firehose_s3": 0.3486078760001874, - "tests/aws/test_integration.py::TestIntegration::test_lambda_streams_batch_and_transactions": 41.787630144999866, - "tests/aws/test_integration.py::TestIntegration::test_scheduled_lambda": 51.37142296699972, - "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_put_item_to_dynamodb[python3.10]": 1.9085521249996873, - "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_put_item_to_dynamodb[python3.11]": 1.8927056700001685, - "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_put_item_to_dynamodb[python3.12]": 1.8963745969999763, - "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_put_item_to_dynamodb[python3.13]": 1.8995574890002445, - "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_put_item_to_dynamodb[python3.8]": 1.9571991299999354, - "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_put_item_to_dynamodb[python3.9]": 1.9070963090000532, - "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_send_message_to_sqs[python3.10]": 7.832791531999874, - "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_send_message_to_sqs[python3.11]": 7.796739921000153, - "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_send_message_to_sqs[python3.12]": 1.8249469110000973, - "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_send_message_to_sqs[python3.13]": 7.846692878999875, - "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_send_message_to_sqs[python3.8]": 15.880032444000335, - "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_send_message_to_sqs[python3.9]": 1.838076887999705, - "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_start_stepfunctions_execution[python3.10]": 3.9461678759998904, - "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_start_stepfunctions_execution[python3.11]": 3.908566732000054, - "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_start_stepfunctions_execution[python3.12]": 3.948684726000238, - "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_start_stepfunctions_execution[python3.13]": 3.9198617689999082, - "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_start_stepfunctions_execution[python3.8]": 3.9683208619999277, - "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_start_stepfunctions_execution[python3.9]": 3.924296864000098, - "tests/aws/test_integration.py::test_kinesis_lambda_forward_chain": 0.0033961459998863575, - "tests/aws/test_moto.py::test_call_include_response_metadata": 0.007640673999958381, - "tests/aws/test_moto.py::test_call_multi_region_backends": 0.020316019000119923, - "tests/aws/test_moto.py::test_call_non_implemented_operation": 0.04215984699976616, - "tests/aws/test_moto.py::test_call_s3_with_streaming_trait[IO[bytes]]": 0.025185122999801024, - "tests/aws/test_moto.py::test_call_s3_with_streaming_trait[bytes]": 0.024729422999826056, - "tests/aws/test_moto.py::test_call_s3_with_streaming_trait[str]": 0.051790354000104344, - "tests/aws/test_moto.py::test_call_sqs_invalid_call_raises_http_exception": 0.007976038000151675, - "tests/aws/test_moto.py::test_call_with_es_creates_state_correctly": 0.06390081699987604, - "tests/aws/test_moto.py::test_call_with_modified_request": 0.010939796000229762, - "tests/aws/test_moto.py::test_call_with_sns_with_full_uri": 0.005396828000129972, - "tests/aws/test_moto.py::test_call_with_sqs_creates_state_correctly": 3.2202947519999725, - "tests/aws/test_moto.py::test_call_with_sqs_invalid_call_raises_exception": 0.008190798999976323, - "tests/aws/test_moto.py::test_call_with_sqs_modifies_state_in_moto_backend": 0.009705065000161994, - "tests/aws/test_moto.py::test_call_with_sqs_returns_service_response": 0.007269841999686832, - "tests/aws/test_moto.py::test_moto_fallback_dispatcher": 0.0122353260003365, - "tests/aws/test_moto.py::test_moto_fallback_dispatcher_error_handling": 0.033808257999908164, - "tests/aws/test_moto.py::test_request_with_response_header_location_fields": 0.10541210499991394, - "tests/aws/test_multi_accounts.py::TestMultiAccounts::test_account_id_namespacing_for_localstack_backends": 0.1606827789998988, - "tests/aws/test_multi_accounts.py::TestMultiAccounts::test_account_id_namespacing_for_moto_backends": 1.6339140149998457, - "tests/aws/test_multi_accounts.py::TestMultiAccounts::test_multi_accounts_dynamodb": 0.3124309600000288, - "tests/aws/test_multi_accounts.py::TestMultiAccounts::test_multi_accounts_kinesis": 1.5109277660001226, - "tests/aws/test_multiregion.py::TestMultiRegion::test_multi_region_api_gateway": 0.5312057230000846, - "tests/aws/test_multiregion.py::TestMultiRegion::test_multi_region_sns": 0.08440524200000254, - "tests/aws/test_network_configuration.py::TestLambda::test_function_url": 1.1566875719997824, - "tests/aws/test_network_configuration.py::TestLambda::test_http_api_for_function_url": 0.0018730360000063229, - "tests/aws/test_network_configuration.py::TestOpenSearch::test_default_strategy": 10.292635048999955, - "tests/aws/test_network_configuration.py::TestOpenSearch::test_path_strategy": 10.532582949000016, - "tests/aws/test_network_configuration.py::TestOpenSearch::test_port_strategy": 10.44684026799996, - "tests/aws/test_network_configuration.py::TestS3::test_201_response": 0.09599747600009323, - "tests/aws/test_network_configuration.py::TestS3::test_multipart_upload": 0.11986569600026087, - "tests/aws/test_network_configuration.py::TestS3::test_non_us_east_1_location": 0.07766316499987624, - "tests/aws/test_network_configuration.py::TestSQS::test_domain_based_strategies[domain]": 0.024913650999906167, - "tests/aws/test_network_configuration.py::TestSQS::test_domain_based_strategies[standard]": 0.030973199999834833, - "tests/aws/test_network_configuration.py::TestSQS::test_off_strategy_with_external_port": 0.02685814900019068, - "tests/aws/test_network_configuration.py::TestSQS::test_off_strategy_without_external_port": 0.03286701500019262, - "tests/aws/test_network_configuration.py::TestSQS::test_path_strategy": 0.02213916200003041, - "tests/aws/test_notifications.py::TestNotifications::test_sns_to_sqs": 0.16352553900014755, - "tests/aws/test_notifications.py::TestNotifications::test_sqs_queue_names": 0.022554671000079907, - "tests/aws/test_serverless.py::TestServerless::test_apigateway_deployed": 0.034714342000143006, - "tests/aws/test_serverless.py::TestServerless::test_dynamodb_stream_handler_deployed": 0.04022864099965773, - "tests/aws/test_serverless.py::TestServerless::test_event_rules_deployed": 101.9997040730002, - "tests/aws/test_serverless.py::TestServerless::test_kinesis_stream_handler_deployed": 0.0018369959998381091, - "tests/aws/test_serverless.py::TestServerless::test_lambda_with_configs_deployed": 0.020771460999867486, - "tests/aws/test_serverless.py::TestServerless::test_queue_handler_deployed": 0.03538207700012208, - "tests/aws/test_serverless.py::TestServerless::test_s3_bucket_deployed": 27.6064715550001, - "tests/aws/test_terraform.py::TestTerraform::test_acm": 0.005597220000026937, - "tests/aws/test_terraform.py::TestTerraform::test_apigateway": 0.0016514100000222243, - "tests/aws/test_terraform.py::TestTerraform::test_apigateway_escaped_policy": 0.0017271409999466414, - "tests/aws/test_terraform.py::TestTerraform::test_bucket_exists": 0.004697059999898556, - "tests/aws/test_terraform.py::TestTerraform::test_dynamodb": 0.0016905429999951593, - "tests/aws/test_terraform.py::TestTerraform::test_event_source_mapping": 0.001681966999967699, - "tests/aws/test_terraform.py::TestTerraform::test_lambda": 0.0017064940000182105, - "tests/aws/test_terraform.py::TestTerraform::test_route53": 0.0016686429999026586, - "tests/aws/test_terraform.py::TestTerraform::test_security_groups": 0.0017573279999396618, - "tests/aws/test_terraform.py::TestTerraform::test_sqs": 0.0016967450001175166, - "tests/aws/test_validate.py::TestMissingParameter::test_elasticache": 0.0017614659998343996, - "tests/aws/test_validate.py::TestMissingParameter::test_opensearch": 0.0017614060000141762, - "tests/aws/test_validate.py::TestMissingParameter::test_sns": 0.0017908310001075733, - "tests/aws/test_validate.py::TestMissingParameter::test_sqs_create_queue": 0.00309020400004556, - "tests/aws/test_validate.py::TestMissingParameter::test_sqs_send_message": 0.0018044470000404544, - "tests/cli/test_cli.py::TestCliContainerLifecycle::test_container_starts_non_root": 0.0016721790000246983, - "tests/cli/test_cli.py::TestCliContainerLifecycle::test_custom_docker_flags": 0.0017374119997839443, - "tests/cli/test_cli.py::TestCliContainerLifecycle::test_logs": 0.003083592000166391, - "tests/cli/test_cli.py::TestCliContainerLifecycle::test_pulling_image_message": 0.001757678999865675, - "tests/cli/test_cli.py::TestCliContainerLifecycle::test_restart": 0.001692167000101108, - "tests/cli/test_cli.py::TestCliContainerLifecycle::test_start_already_running": 0.0016777790001469839, - "tests/cli/test_cli.py::TestCliContainerLifecycle::test_start_cli_within_container": 0.0016707860002043162, - "tests/cli/test_cli.py::TestCliContainerLifecycle::test_start_wait_stop": 0.0017819550000695017, - "tests/cli/test_cli.py::TestCliContainerLifecycle::test_status_services": 0.001756225999997696, - "tests/cli/test_cli.py::TestCliContainerLifecycle::test_volume_dir_mounted_correctly": 0.0016421529999206541, - "tests/cli/test_cli.py::TestCliContainerLifecycle::test_wait_timeout_raises_exception": 0.0016565590001391683, - "tests/cli/test_cli.py::TestDNSServer::test_dns_port_not_published_by_default": 0.00171745399984502, - "tests/cli/test_cli.py::TestDNSServer::test_dns_port_published_with_flag": 0.0030766299998958857, - "tests/cli/test_cli.py::TestHooks::test_prepare_host_hook_called_with_correct_dirs": 0.5608951789999992, - "tests/cli/test_cli.py::TestImports::test_import_venv": 0.007298142999843549, - "tests/integration/aws/test_app.py::TestExceptionHandlers::test_404_unfortunately_detected_as_s3_request": 0.030348488000299767, - "tests/integration/aws/test_app.py::TestExceptionHandlers::test_internal_failure_handler_http_errors": 0.019404805000249326, - "tests/integration/aws/test_app.py::TestExceptionHandlers::test_router_handler_get_http_errors": 0.0018957150000460388, - "tests/integration/aws/test_app.py::TestExceptionHandlers::test_router_handler_get_unexpected_errors": 0.0019758860000820277, - "tests/integration/aws/test_app.py::TestExceptionHandlers::test_router_handler_patch_http_errors": 0.10676300399995853, - "tests/integration/aws/test_app.py::TestHTTP2Support::test_http2_http": 0.10145176300011371, - "tests/integration/aws/test_app.py::TestHTTP2Support::test_http2_https": 0.10086322000006476, - "tests/integration/aws/test_app.py::TestHTTP2Support::test_http2_https_localhost": 0.06285744200022236, - "tests/integration/aws/test_app.py::TestHttps::test_default_cert_works": 0.0673779859998831, - "tests/integration/aws/test_app.py::TestWebSocketIntegration::test_return_response": 0.0018011490001299535, - "tests/integration/aws/test_app.py::TestWebSocketIntegration::test_ssl_websockets": 0.001830263999863746, - "tests/integration/aws/test_app.py::TestWebSocketIntegration::test_websocket_reject_through_edge_router": 0.0017720240000471676, - "tests/integration/aws/test_app.py::TestWebSocketIntegration::test_websockets_served_through_edge_router": 0.0018670520000796387, - "tests/integration/aws/test_app.py::TestWerkzeugIntegration::test_chunked_request_streaming": 0.11195998900006998, - "tests/integration/aws/test_app.py::TestWerkzeugIntegration::test_chunked_response_streaming": 0.13382102300010956, - "tests/integration/aws/test_app.py::TestWerkzeugIntegration::test_raw_header_handling": 0.10087241599967456, - "tests/integration/aws/test_app.py::TestWerkzeugIntegration::test_response_close_handlers_called_with_router": 0.10282093799992253, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_build_image[CmdDockerClient-False-False]": 0.004141584999842962, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_build_image[CmdDockerClient-False-True]": 0.0020053299999744922, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_build_image[CmdDockerClient-True-False]": 0.0019890599999143888, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_build_image[CmdDockerClient-True-True]": 0.0019258629999967525, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_build_image[SdkDockerClient-False-False]": 2.995095264000156, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_build_image[SdkDockerClient-False-True]": 3.001316029000236, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_build_image[SdkDockerClient-True-False]": 2.9942436089997955, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_build_image[SdkDockerClient-True-True]": 3.0290174179999667, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_container_lifecycle_commands[CmdDockerClient]": 0.001895646000320994, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_container_lifecycle_commands[SdkDockerClient]": 20.80559452999978, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_directory_content_into_container[CmdDockerClient]": 0.0019062849999045284, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_directory_content_into_container[SdkDockerClient]": 0.28907256799993775, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_directory_into_container[CmdDockerClient]": 0.0020184760001029645, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_directory_into_container[SdkDockerClient]": 0.20604141800004072, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_directory_structure_into_container[CmdDockerClient]": 0.0018867689998387505, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_directory_structure_into_container[SdkDockerClient]": 0.24904862900007174, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_from_container[CmdDockerClient]": 0.001918528999794944, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_from_container[SdkDockerClient]": 0.23689324099996156, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_from_container_into_directory[CmdDockerClient]": 0.004004520000080447, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_from_container_into_directory[SdkDockerClient]": 0.2496660790000078, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_from_container_to_different_file[CmdDockerClient]": 0.0020005310000215104, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_from_container_to_different_file[SdkDockerClient]": 0.24526184199976342, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_from_non_existent_container[CmdDockerClient]": 0.0019712460002665466, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_from_non_existent_container[SdkDockerClient]": 0.008152447999918877, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_into_container[CmdDockerClient]": 0.0020944460000009713, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_into_container[SdkDockerClient]": 0.20222857999988264, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_into_container_with_existing_target[CmdDockerClient]": 0.0021972090000872413, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_into_container_with_existing_target[SdkDockerClient]": 0.3398601520000284, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_into_container_without_target_filename[CmdDockerClient]": 0.001930561999870406, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_into_container_without_target_filename[SdkDockerClient]": 0.21186606000014763, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_into_non_existent_container[CmdDockerClient]": 0.0018674430000373832, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_into_non_existent_container[SdkDockerClient]": 0.007534474000067348, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_container_non_existing_image[CmdDockerClient]": 0.0019359509999503643, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_container_non_existing_image[SdkDockerClient]": 0.08028640200018344, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_container_remove_removes_container[CmdDockerClient]": 0.0018963280001571547, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_container_remove_removes_container[SdkDockerClient]": 1.192338739999741, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_container_with_init[CmdDockerClient]": 0.0018959760000143433, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_container_with_init[SdkDockerClient]": 0.025711641000043528, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_container_with_max_env_vars[CmdDockerClient]": 0.001958433000027071, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_container_with_max_env_vars[SdkDockerClient]": 0.23330542200005766, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_file_in_container[CmdDockerClient]": 0.0019150020002598467, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_file_in_container[SdkDockerClient]": 0.2064487929999359, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_start_container_with_stdin_to_file[CmdDockerClient-False]": 0.001958411999794407, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_start_container_with_stdin_to_file[CmdDockerClient-True]": 0.0018951740000829886, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_start_container_with_stdin_to_file[SdkDockerClient-False]": 0.1932389339999645, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_start_container_with_stdin_to_file[SdkDockerClient-True]": 0.20847888000002968, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_start_container_with_stdin_to_stdout[CmdDockerClient-False]": 0.0018283599999904254, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_start_container_with_stdin_to_stdout[CmdDockerClient-True]": 0.001999570999714706, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_start_container_with_stdin_to_stdout[SdkDockerClient-False]": 0.192862851999962, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_start_container_with_stdin_to_stdout[SdkDockerClient-True]": 0.20766703200024494, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_with_exposed_ports[CmdDockerClient]": 0.0018740469997737819, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_with_exposed_ports[SdkDockerClient]": 0.0045728799998414615, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_with_host_network[CmdDockerClient]": 0.0021264059998884477, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_with_host_network[SdkDockerClient]": 0.03267042900006345, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_with_port_mapping[CmdDockerClient]": 0.002283560000023499, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_with_port_mapping[SdkDockerClient]": 0.02535695300025509, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_with_volume[CmdDockerClient]": 0.0017768430000160151, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_with_volume[SdkDockerClient]": 0.001931533000060881, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_docker_image_names[CmdDockerClient]": 0.0019805239999186597, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_docker_image_names[SdkDockerClient]": 0.6015952650000145, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_docker_not_available[CmdDockerClient]": 0.006613075000132085, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_docker_not_available[SdkDockerClient]": 0.0058547410001210665, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_error_in_container[CmdDockerClient]": 0.001980975000151375, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_error_in_container[SdkDockerClient]": 0.2888057469999694, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container[CmdDockerClient]": 0.001963542000112284, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container[SdkDockerClient]": 0.24005105400010507, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container_not_running_raises_exception[CmdDockerClient]": 0.0019789809998655983, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container_not_running_raises_exception[SdkDockerClient]": 0.031903200999977344, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container_with_env[CmdDockerClient]": 0.001992335000068124, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container_with_env[SdkDockerClient]": 0.24737434400003622, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container_with_env_deletion[CmdDockerClient]": 0.0018659290001323825, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container_with_env_deletion[SdkDockerClient]": 0.31071927799985133, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container_with_stdin[CmdDockerClient]": 0.0037020659999598138, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container_with_stdin[SdkDockerClient]": 0.23487851600020804, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container_with_stdin_stdout_stderr[CmdDockerClient]": 0.002056535999827247, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container_with_stdin_stdout_stderr[SdkDockerClient]": 0.23832517799996822, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container_with_workdir[CmdDockerClient]": 0.0038977100000465725, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container_with_workdir[SdkDockerClient]": 0.2431706130000748, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_command[CmdDockerClient]": 0.0019820170000457438, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_command[SdkDockerClient]": 0.006033835000152976, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_command_non_existing_image[CmdDockerClient]": 0.0018499900002098002, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_command_non_existing_image[SdkDockerClient]": 0.07695360699995035, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_command_not_pulled_image[CmdDockerClient]": 0.001981275999924037, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_command_not_pulled_image[SdkDockerClient]": 0.4624340860002576, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_entrypoint[CmdDockerClient]": 0.0018947250000564964, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_entrypoint[SdkDockerClient]": 0.007305868000003102, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_entrypoint_non_existing_image[CmdDockerClient]": 0.003700824000134162, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_entrypoint_non_existing_image[SdkDockerClient]": 0.06580134099999668, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_entrypoint_not_pulled_image[CmdDockerClient]": 0.002031350000152088, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_entrypoint_not_pulled_image[SdkDockerClient]": 0.44566275000011046, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_id[CmdDockerClient]": 0.001965656000038507, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_id[SdkDockerClient]": 0.20011871399992742, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_id_not_existing[CmdDockerClient]": 0.0019611180002812034, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_id_not_existing[SdkDockerClient]": 0.006851654999763923, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_ip[CmdDockerClient]": 0.001957091000122091, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_ip[SdkDockerClient]": 0.20120309900016764, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_ip_for_host_network[CmdDockerClient]": 0.0019346589999713615, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_ip_for_host_network[SdkDockerClient]": 0.040100477999658324, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_ip_for_network[CmdDockerClient]": 0.001907997999978761, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_ip_for_network[SdkDockerClient]": 0.4493121250002332, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_ip_for_network_non_existent_network[CmdDockerClient]": 0.0036490459999640734, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_ip_for_network_non_existent_network[SdkDockerClient]": 0.19542863900005614, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_ip_for_network_wrong_network[CmdDockerClient]": 0.0019978059999630204, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_ip_for_network_wrong_network[SdkDockerClient]": 0.34893864700006816, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_ip_non_existing_container[CmdDockerClient]": 0.0019222959999751765, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_ip_non_existing_container[SdkDockerClient]": 0.006023245000278621, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_name[CmdDockerClient]": 0.0038048779999826365, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_name[SdkDockerClient]": 0.2145788709997305, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_name_not_existing[CmdDockerClient]": 0.0019839809999666613, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_name_not_existing[SdkDockerClient]": 0.007237971999984438, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_logs[CmdDockerClient]": 0.0019817750001038803, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_logs[SdkDockerClient]": 0.18366636899986588, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_logs_non_existent_container[CmdDockerClient]": 0.001964915000144174, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_logs_non_existent_container[SdkDockerClient]": 0.007136531999776707, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_network[CmdDockerClient]": 0.0020014930000797904, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_network[SdkDockerClient]": 0.02922286200009694, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_network_multiple_networks[CmdDockerClient]": 0.0018801580001763796, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_network_multiple_networks[SdkDockerClient]": 0.41844548600010967, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_network_non_existing_container[CmdDockerClient]": 0.001899923999872044, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_network_non_existing_container[SdkDockerClient]": 0.0066304879999279365, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_system_id[CmdDockerClient]": 0.0018595989999994345, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_system_id[SdkDockerClient]": 0.021663999000338663, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_system_info[CmdDockerClient]": 0.00364002000014807, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_system_info[SdkDockerClient]": 0.02722969399997055, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_inspect_container[CmdDockerClient]": 0.0020047400000748894, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_inspect_container[SdkDockerClient]": 0.2032476729998507, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_inspect_container_volumes[CmdDockerClient]": 0.0017758530000264727, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_inspect_container_volumes[SdkDockerClient]": 0.006013086999928419, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_inspect_container_volumes_with_no_volumes[CmdDockerClient]": 0.003788795999980721, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_inspect_container_volumes_with_no_volumes[SdkDockerClient]": 0.18806482099989807, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_inspect_image[CmdDockerClient]": 0.003796299999976327, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_inspect_image[SdkDockerClient]": 0.02786660199990365, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_inspect_network[CmdDockerClient]": 0.0019734910001716344, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_inspect_network[SdkDockerClient]": 0.12972114700005477, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_inspect_network_non_existent_network[CmdDockerClient]": 0.0020103100000596896, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_inspect_network_non_existent_network[SdkDockerClient]": 0.007151316999852497, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_is_container_running[CmdDockerClient]": 0.0018547189999935654, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_is_container_running[SdkDockerClient]": 20.412909238999873, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_list_containers[CmdDockerClient]": 0.004508859999759807, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_list_containers[SdkDockerClient]": 0.08931729799996901, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_list_containers_filter[CmdDockerClient]": 0.001924890000054802, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_list_containers_filter[SdkDockerClient]": 0.08665848399982679, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_list_containers_filter_illegal_filter[CmdDockerClient]": 0.0018766499997582287, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_list_containers_filter_illegal_filter[SdkDockerClient]": 0.006156785000257514, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_list_containers_filter_non_existing[CmdDockerClient]": 0.0019199509999907605, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_list_containers_filter_non_existing[SdkDockerClient]": 0.006631272000049648, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_list_containers_with_podman_image_ref_format[CmdDockerClient]": 0.001906095000094865, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_list_containers_with_podman_image_ref_format[SdkDockerClient]": 0.23721227999999428, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_pause_non_existing_container[CmdDockerClient]": 0.001938556000141034, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_pause_non_existing_container[SdkDockerClient]": 0.0056407550000585616, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_pull_docker_image[CmdDockerClient]": 0.0019696140000178275, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_pull_docker_image[SdkDockerClient]": 0.32487481900011517, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_pull_docker_image_with_hash[CmdDockerClient]": 0.0035774230000242824, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_pull_docker_image_with_hash[SdkDockerClient]": 0.32382332200018027, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_pull_docker_image_with_tag[CmdDockerClient]": 0.0018453820000559062, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_pull_docker_image_with_tag[SdkDockerClient]": 0.4061120740000206, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_pull_non_existent_docker_image[CmdDockerClient]": 0.0018666419996407058, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_pull_non_existent_docker_image[SdkDockerClient]": 0.07649629700017613, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_push_access_denied[CmdDockerClient]": 0.001912308000100893, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_push_access_denied[SdkDockerClient]": 0.2895498749999206, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_push_invalid_registry[CmdDockerClient]": 0.0019241889999648265, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_push_invalid_registry[SdkDockerClient]": 0.014607293999915782, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_push_non_existent_docker_image[CmdDockerClient]": 0.002009979999911593, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_push_non_existent_docker_image[SdkDockerClient]": 0.00724829199953092, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_remove_non_existing_container[CmdDockerClient]": 0.0020509739999852172, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_remove_non_existing_container[SdkDockerClient]": 0.005821060000016587, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_restart_non_existing_container[CmdDockerClient]": 0.002022061000161557, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_restart_non_existing_container[SdkDockerClient]": 0.005878531999769621, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_container[CmdDockerClient]": 0.004093345000001136, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_container[SdkDockerClient]": 0.19326594199969804, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_container_automatic_pull[CmdDockerClient]": 0.0018643680000423046, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_container_automatic_pull[SdkDockerClient]": 0.6158057180000469, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_container_error[CmdDockerClient]": 0.0020197670000925427, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_container_error[SdkDockerClient]": 0.11478227399993557, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_container_non_existent_image[CmdDockerClient]": 0.0019726789998912864, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_container_non_existent_image[SdkDockerClient]": 0.0897285739997642, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_container_with_init[CmdDockerClient]": 0.0018673419999686303, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_container_with_init[SdkDockerClient]": 0.19143987100028426, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_container_with_stdin[CmdDockerClient]": 0.001975474999881044, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_container_with_stdin[SdkDockerClient]": 0.17708290300015506, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_detached_with_logs[CmdDockerClient]": 0.0020140160002029006, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_detached_with_logs[SdkDockerClient]": 0.19486077000010482, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_running_container_names[CmdDockerClient]": 0.0018338009999752103, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_running_container_names[SdkDockerClient]": 10.634625412000105, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_set_container_entrypoint[CmdDockerClient-echo]": 0.0019157530000484257, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_set_container_entrypoint[CmdDockerClient-entrypoint1]": 0.001887940999949933, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_set_container_entrypoint[SdkDockerClient-echo]": 0.20084265300010884, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_set_container_entrypoint[SdkDockerClient-entrypoint1]": 0.19764563499984433, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_start_non_existing_container[CmdDockerClient]": 0.0019863159998294577, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_start_non_existing_container[SdkDockerClient]": 0.0055717730001560994, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_stop_non_existing_container[CmdDockerClient]": 0.0020056109999586624, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_stop_non_existing_container[SdkDockerClient]": 0.0064888039996731095, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_stream_logs[CmdDockerClient]": 0.0018738250000751577, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_stream_logs[SdkDockerClient]": 0.19955086599975402, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_stream_logs_non_existent_container[CmdDockerClient]": 0.0036469620001753356, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_stream_logs_non_existent_container[SdkDockerClient]": 0.005818804000000455, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_tag_image[CmdDockerClient]": 0.003789048000044204, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_tag_image[SdkDockerClient]": 0.15794090200006394, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_tag_non_existing_image[CmdDockerClient]": 0.0019169859999692562, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_tag_non_existing_image[SdkDockerClient]": 0.008020030999659866, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_unpause_non_existing_container[CmdDockerClient]": 0.004957625999850279, - "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_unpause_non_existing_container[SdkDockerClient]": 0.005480785000145261, - "tests/integration/docker_utils/test_docker.py::TestDockerImages::test_commit_creates_image_from_running_container[CmdDockerClient]": 0.0034776570003032248, - "tests/integration/docker_utils/test_docker.py::TestDockerImages::test_commit_creates_image_from_running_container[SdkDockerClient]": 0.5167643710001357, - "tests/integration/docker_utils/test_docker.py::TestDockerImages::test_commit_image_raises_for_nonexistent_container[CmdDockerClient]": 0.0019051140002375178, - "tests/integration/docker_utils/test_docker.py::TestDockerImages::test_commit_image_raises_for_nonexistent_container[SdkDockerClient]": 0.006317845000012312, - "tests/integration/docker_utils/test_docker.py::TestDockerImages::test_remove_image_raises_for_nonexistent_image[CmdDockerClient]": 0.001990052000110154, - "tests/integration/docker_utils/test_docker.py::TestDockerImages::test_remove_image_raises_for_nonexistent_image[SdkDockerClient]": 0.006786487999988822, - "tests/integration/docker_utils/test_docker.py::TestDockerLabels::test_create_container_with_labels[CmdDockerClient]": 0.003449254999850382, - "tests/integration/docker_utils/test_docker.py::TestDockerLabels::test_create_container_with_labels[SdkDockerClient]": 0.04260951800006296, - "tests/integration/docker_utils/test_docker.py::TestDockerLabels::test_get_container_stats[CmdDockerClient]": 0.0018848269999125478, - "tests/integration/docker_utils/test_docker.py::TestDockerLabels::test_get_container_stats[SdkDockerClient]": 1.2000897049999821, - "tests/integration/docker_utils/test_docker.py::TestDockerLabels::test_list_containers_with_labels[CmdDockerClient]": 0.0019074580000051355, - "tests/integration/docker_utils/test_docker.py::TestDockerLabels::test_list_containers_with_labels[SdkDockerClient]": 0.2057743580000988, - "tests/integration/docker_utils/test_docker.py::TestDockerLabels::test_run_container_with_labels[CmdDockerClient]": 0.0019015580000996124, - "tests/integration/docker_utils/test_docker.py::TestDockerLabels::test_run_container_with_labels[SdkDockerClient]": 0.19313940300003196, - "tests/integration/docker_utils/test_docker.py::TestDockerLogging::test_docker_logging_fluentbit[CmdDockerClient]": 0.0018733750000592408, - "tests/integration/docker_utils/test_docker.py::TestDockerLogging::test_docker_logging_fluentbit[SdkDockerClient]": 2.990178680999861, - "tests/integration/docker_utils/test_docker.py::TestDockerLogging::test_docker_logging_none_disables_logs[CmdDockerClient]": 0.0032958169997527875, - "tests/integration/docker_utils/test_docker.py::TestDockerLogging::test_docker_logging_none_disables_logs[SdkDockerClient]": 0.19901383199999145, - "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_connect_container_to_network[CmdDockerClient]": 0.005871623000302861, - "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_connect_container_to_network[SdkDockerClient]": 0.43204041600029086, - "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_connect_container_to_network_with_alias_and_disconnect[CmdDockerClient]": 0.0019517499999892607, - "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_connect_container_to_network_with_alias_and_disconnect[SdkDockerClient]": 0.864502899000172, - "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_connect_container_to_network_with_link_local_address[CmdDockerClient]": 0.002074599000025046, - "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_connect_container_to_network_with_link_local_address[SdkDockerClient]": 0.18537330200001634, - "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_connect_container_to_nonexistent_network[CmdDockerClient]": 0.0020503549999375537, - "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_connect_container_to_nonexistent_network[SdkDockerClient]": 0.22841053799970723, - "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_connect_nonexistent_container_to_network[CmdDockerClient]": 0.0019197220001387905, - "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_connect_nonexistent_container_to_network[SdkDockerClient]": 0.16316636100032156, - "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_disconnect_container_from_nonexistent_network[CmdDockerClient]": 0.0018649190001269744, - "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_disconnect_container_from_nonexistent_network[SdkDockerClient]": 0.20242660400003842, - "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_disconnect_nonexistent_container_from_network[CmdDockerClient]": 0.0019547859999420325, - "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_disconnect_nonexistent_container_from_network[SdkDockerClient]": 0.15831655999977556, - "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_docker_sdk_no_retries": 0.026616520000061428, - "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_docker_sdk_retries_after_init": 1.0671151779999946, - "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_docker_sdk_retries_on_init": 1.1294517810001707, - "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_docker_sdk_timeout_seconds": 0.020414975000448976, - "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_get_container_ip_with_network[CmdDockerClient]": 0.0019897120000678115, - "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_get_container_ip_with_network[SdkDockerClient]": 0.3574971589998768, - "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_network_lifecycle[CmdDockerClient]": 0.00334271700012323, - "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_network_lifecycle[SdkDockerClient]": 0.1595030199998746, - "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_set_container_workdir[CmdDockerClient]": 0.0019761270000344666, - "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_set_container_workdir[SdkDockerClient]": 0.18252414799985672, - "tests/integration/docker_utils/test_docker.py::TestDockerPermissions::test_container_with_cap_add[CmdDockerClient]": 0.003574037999896973, - "tests/integration/docker_utils/test_docker.py::TestDockerPermissions::test_container_with_cap_add[SdkDockerClient]": 0.4320345759999782, - "tests/integration/docker_utils/test_docker.py::TestDockerPermissions::test_container_with_cap_drop[CmdDockerClient]": 0.0019017579998035217, - "tests/integration/docker_utils/test_docker.py::TestDockerPermissions::test_container_with_cap_drop[SdkDockerClient]": 0.3700782690000324, - "tests/integration/docker_utils/test_docker.py::TestDockerPermissions::test_container_with_sec_opt[CmdDockerClient]": 0.00187565999999606, - "tests/integration/docker_utils/test_docker.py::TestDockerPermissions::test_container_with_sec_opt[SdkDockerClient]": 0.02765618000012182, - "tests/integration/docker_utils/test_docker.py::TestDockerPorts::test_container_port_can_be_bound[CmdDockerClient-None]": 0.0019256020002558216, - "tests/integration/docker_utils/test_docker.py::TestDockerPorts::test_container_port_can_be_bound[CmdDockerClient-tcp]": 0.0018887050000557792, - "tests/integration/docker_utils/test_docker.py::TestDockerPorts::test_container_port_can_be_bound[CmdDockerClient-udp]": 0.0018985119997978472, - "tests/integration/docker_utils/test_docker.py::TestDockerPorts::test_container_port_can_be_bound[SdkDockerClient-None]": 1.4848546409998562, - "tests/integration/docker_utils/test_docker.py::TestDockerPorts::test_container_port_can_be_bound[SdkDockerClient-tcp]": 1.4984671460001664, - "tests/integration/docker_utils/test_docker.py::TestDockerPorts::test_container_port_can_be_bound[SdkDockerClient-udp]": 1.4964931449999312, - "tests/integration/docker_utils/test_docker.py::TestDockerPorts::test_reserve_container_port[CmdDockerClient-None]": 0.0033610099999350496, - "tests/integration/docker_utils/test_docker.py::TestDockerPorts::test_reserve_container_port[CmdDockerClient-tcp]": 0.001973280999891358, - "tests/integration/docker_utils/test_docker.py::TestDockerPorts::test_reserve_container_port[CmdDockerClient-udp]": 0.002002886999889597, - "tests/integration/docker_utils/test_docker.py::TestDockerPorts::test_reserve_container_port[SdkDockerClient-None]": 2.601268305000076, - "tests/integration/docker_utils/test_docker.py::TestDockerPorts::test_reserve_container_port[SdkDockerClient-tcp]": 2.611378226999932, - "tests/integration/docker_utils/test_docker.py::TestDockerPorts::test_reserve_container_port[SdkDockerClient-udp]": 2.8516050480000104, - "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_additional_arguments[CmdDockerClient]": 0.003584026000226004, - "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_additional_arguments[SdkDockerClient]": 0.3908667119999336, - "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_additional_arguments_add_dns[CmdDockerClient-False]": 0.002028122999945481, - "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_additional_arguments_add_dns[CmdDockerClient-True]": 0.0020554349998747057, - "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_additional_arguments_add_dns[SdkDockerClient-False]": 0.1266307850000885, - "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_additional_arguments_add_dns[SdkDockerClient-True]": 0.12432772000011028, - "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_additional_arguments_add_host[CmdDockerClient]": 0.0018726929999957065, - "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_additional_arguments_add_host[SdkDockerClient]": 0.18973624999989624, - "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_additional_arguments_env_files[CmdDockerClient]": 0.001917736999985209, - "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_additional_arguments_env_files[SdkDockerClient]": 0.7136641140000393, - "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_additional_arguments_random_port[CmdDockerClient]": 0.0020228539999607165, - "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_additional_arguments_random_port[SdkDockerClient]": 0.2593425549998756, - "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_ulimit[CmdDockerClient]": 0.0019318839999868942, - "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_ulimit[SdkDockerClient]": 0.17863703600028202, - "tests/integration/services/test_internal.py::TestHealthResource::test_get": 0.021054101999880004, - "tests/integration/services/test_internal.py::TestHealthResource::test_head": 0.018252955999969345, - "tests/integration/services/test_internal.py::TestInfoEndpoint::test_get": 0.05460279399994761, - "tests/integration/services/test_internal.py::TestInitScriptsResource::test_query_individual_stage_completed[boot-True]": 0.020364598999776717, - "tests/integration/services/test_internal.py::TestInitScriptsResource::test_query_individual_stage_completed[ready-True]": 0.024893586999951367, - "tests/integration/services/test_internal.py::TestInitScriptsResource::test_query_individual_stage_completed[shutdown-False]": 0.019863297000256352, - "tests/integration/services/test_internal.py::TestInitScriptsResource::test_query_individual_stage_completed[start-True]": 0.0305466830000114, - "tests/integration/services/test_internal.py::TestInitScriptsResource::test_query_nonexisting_stage": 0.019501690999959465, - "tests/integration/services/test_internal.py::TestInitScriptsResource::test_stages_have_completed": 1.550047032999828, - "tests/integration/test_config_endpoint.py::test_config_endpoint": 0.048597999000094205, - "tests/integration/test_config_service.py::TestConfigService::test_put_configuration_recorder": 0.3496834580000723, - "tests/integration/test_config_service.py::TestConfigService::test_put_delivery_channel": 0.3099454869998226, - "tests/integration/test_forwarder.py::test_forwarding_fallback_dispatcher": 0.0063461790002747875, - "tests/integration/test_forwarder.py::test_forwarding_fallback_dispatcher_avoid_fallback": 0.004403954999816051, - "tests/integration/test_security.py::TestCSRF::test_CSRF": 0.09931153799993808, - "tests/integration/test_security.py::TestCSRF::test_additional_allowed_origins": 0.01958251399969413, - "tests/integration/test_security.py::TestCSRF::test_cors_apigw_not_applied": 0.048958045000063066, - "tests/integration/test_security.py::TestCSRF::test_cors_s3_override": 0.08057531500003279, - "tests/integration/test_security.py::TestCSRF::test_default_cors_headers": 0.015996739999991405, - "tests/integration/test_security.py::TestCSRF::test_disable_cors_checks": 0.016058246999818948, - "tests/integration/test_security.py::TestCSRF::test_disable_cors_headers": 0.019197955999970873, - "tests/integration/test_security.py::TestCSRF::test_internal_route_cors_headers[/_localstack/health]": 0.011076430999764852, - "tests/integration/test_security.py::TestCSRF::test_no_cors_without_origin_header": 0.01053124600002775, - "tests/integration/test_stores.py::test_nonstandard_regions": 0.14873483800010945, - "tests/integration/utils/test_diagnose.py::test_diagnose_resource": 0.23227979500029505 + "tests/aws/scenario/bookstore/test_bookstore.py::TestBookstoreApplication::test_lambda_dynamodb": 1.774174935000019, + "tests/aws/scenario/bookstore/test_bookstore.py::TestBookstoreApplication::test_opensearch_crud": 4.188032677000024, + "tests/aws/scenario/bookstore/test_bookstore.py::TestBookstoreApplication::test_search_books": 62.777827403999936, + "tests/aws/scenario/bookstore/test_bookstore.py::TestBookstoreApplication::test_setup": 91.94686440700008, + "tests/aws/scenario/kinesis_firehose/test_kinesis_firehose.py::TestKinesisFirehoseScenario::test_kinesis_firehose_s3": 0.0026821249999784413, + "tests/aws/scenario/lambda_destination/test_lambda_destination_scenario.py::TestLambdaDestinationScenario::test_destination_sns": 5.591605155000138, + "tests/aws/scenario/lambda_destination/test_lambda_destination_scenario.py::TestLambdaDestinationScenario::test_infra": 12.247395292999954, + "tests/aws/scenario/loan_broker/test_loan_broker.py::TestLoanBrokerScenario::test_prefill_dynamodb_table": 25.011540611999976, + "tests/aws/scenario/loan_broker/test_loan_broker.py::TestLoanBrokerScenario::test_stepfunctions_input_recipient_list[step_function_input0-SUCCEEDED]": 3.96880790299997, + "tests/aws/scenario/loan_broker/test_loan_broker.py::TestLoanBrokerScenario::test_stepfunctions_input_recipient_list[step_function_input1-SUCCEEDED]": 3.510866073000102, + "tests/aws/scenario/loan_broker/test_loan_broker.py::TestLoanBrokerScenario::test_stepfunctions_input_recipient_list[step_function_input2-FAILED]": 0.9160701010000594, + "tests/aws/scenario/loan_broker/test_loan_broker.py::TestLoanBrokerScenario::test_stepfunctions_input_recipient_list[step_function_input3-FAILED]": 0.6943013850001307, + "tests/aws/scenario/loan_broker/test_loan_broker.py::TestLoanBrokerScenario::test_stepfunctions_input_recipient_list[step_function_input4-FAILED]": 0.5673874430000296, + "tests/aws/scenario/mythical_mysfits/test_mythical_misfits.py::TestMythicalMisfitsScenario::test_deployed_infra_state": 0.0024610319999283092, + "tests/aws/scenario/mythical_mysfits/test_mythical_misfits.py::TestMythicalMisfitsScenario::test_populate_data": 0.0016395299999203417, + "tests/aws/scenario/mythical_mysfits/test_mythical_misfits.py::TestMythicalMisfitsScenario::test_user_clicks_are_stored": 0.0016330680000464781, + "tests/aws/scenario/note_taking/test_note_taking.py::TestNoteTakingScenario::test_notes_rest_api": 4.445216411000047, + "tests/aws/scenario/note_taking/test_note_taking.py::TestNoteTakingScenario::test_validate_infra_setup": 32.71862161399986, + "tests/aws/services/acm/test_acm.py::TestACM::test_boto_wait_for_certificate_validation": 1.1742757430000665, + "tests/aws/services/acm/test_acm.py::TestACM::test_certificate_for_subdomain_wildcard": 2.249788107000086, + "tests/aws/services/acm/test_acm.py::TestACM::test_create_certificate_for_multiple_alternative_domains": 11.223035717000243, + "tests/aws/services/acm/test_acm.py::TestACM::test_domain_validation": 0.3144873149999512, + "tests/aws/services/acm/test_acm.py::TestACM::test_import_certificate": 0.9889974630000324, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiAuthorizer::test_authorizer_crud_no_api": 0.032054351999931896, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiDocumentationPart::test_doc_parts_crud_no_api": 0.032097425999950246, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiDocumentationPart::test_documentation_part_lifecycle": 0.06799291200002244, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiDocumentationPart::test_import_documentation_parts": 0.12398722599994016, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiDocumentationPart::test_invalid_create_documentation_part_operations": 0.03752522400009184, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiDocumentationPart::test_invalid_delete_documentation_part": 0.05010647600010998, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiDocumentationPart::test_invalid_get_documentation_part": 0.044281275000003006, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiDocumentationPart::test_invalid_get_documentation_parts": 0.01411603400003969, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiDocumentationPart::test_invalid_update_documentation_part": 0.051182908000100724, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiMethod::test_method_lifecycle": 0.0735179190000963, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiMethod::test_method_request_parameters": 0.047906923000027746, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiMethod::test_put_method_model": 0.282410900000059, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiMethod::test_put_method_validation": 0.07072902300012629, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiMethod::test_update_method": 0.07212642199988295, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiMethod::test_update_method_validation": 0.1325490299999501, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiModels::test_model_lifecycle": 0.07037627600004726, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiModels::test_model_validation": 0.09698879299992313, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiModels::test_update_model": 0.07233992999999828, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRequestValidator::test_create_request_validator_invalid_api_id": 0.015360407999992276, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRequestValidator::test_invalid_delete_request_validator": 0.04334378199996536, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRequestValidator::test_invalid_get_request_validator": 0.04533572500008631, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRequestValidator::test_invalid_get_request_validators": 0.014843181000060213, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRequestValidator::test_invalid_update_request_validator_operations": 0.06182318900005157, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRequestValidator::test_request_validator_lifecycle": 0.09142566000002716, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRequestValidator::test_validators_crud_no_api": 0.03250887700016847, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiResource::test_create_proxy_resource": 0.11743454399993425, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiResource::test_create_proxy_resource_validation": 0.07749626999998327, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiResource::test_create_resource_parent_invalid": 0.030546739999977035, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiResource::test_delete_resource": 0.06632469499993476, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiResource::test_resource_lifecycle": 0.10687744699998802, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiResource::test_update_resource_behaviour": 0.14462112300009267, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRestApi::test_create_rest_api_with_binary_media_types": 0.025234737000005225, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRestApi::test_create_rest_api_with_optional_params": 0.07413011100015865, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRestApi::test_create_rest_api_with_tags": 0.043236650000039845, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRestApi::test_get_api_case_insensitive": 0.0019105050000689516, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRestApi::test_list_and_delete_apis": 0.08629874100006418, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRestApi::test_update_rest_api_behaviour": 0.05322892399988177, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRestApi::test_update_rest_api_compression": 0.09102434800001902, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRestApi::test_update_rest_api_invalid_api_id": 0.01458052200007387, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayApiRestApi::test_update_rest_api_operation_add_remove": 0.04955238399998052, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayGatewayResponse::test_gateway_response_crud": 0.0986877990000039, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayGatewayResponse::test_gateway_response_put": 0.09829287299999123, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayGatewayResponse::test_gateway_response_validation": 0.10610379500008094, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApiGatewayGatewayResponse::test_update_gateway_response": 0.12776197100015452, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_integration_response_invalid_integration": 0.03877107900007104, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_integration_response_invalid_responsetemplates": 0.001752610999915305, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_integration_response_invalid_statuscode": 0.03828175499995723, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_integration_response_wrong_api": 0.02340734499989594, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_integration_response_wrong_method": 0.03915888099993481, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_integration_response_wrong_resource": 0.03780062699991049, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_integration_response_wrong_status_code": 0.04878824300010365, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_lifecycle_integration_response": 0.09719447299994499, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_put_integration_request_parameter_bool_type": 0.0018161799999916184, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_put_integration_response_validation": 0.0746673279999186, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_put_integration_wrong_type": 0.040996380999899884, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayTestInvoke::test_invoke_test_method": 0.19373659799998677, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_api_account": 0.04383083300012913, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_api_gateway_authorizer_crud": 0.0018671359999871129, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_api_gateway_handle_domain_name": 1.004764127000044, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_api_gateway_http_integration_with_path_request_parameter": 0.0018798080000124173, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_api_gateway_lambda_asynchronous_invocation": 1.2995235109999612, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_api_gateway_lambda_integration_aws_type": 7.735148372000026, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_api_gateway_lambda_proxy_integration[/lambda/foo1]": 0.0017849219999561683, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_api_gateway_lambda_proxy_integration[/lambda/{test_param1}]": 0.0018247270000983917, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_api_gateway_lambda_proxy_integration_any_method": 0.0016822609999280758, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_api_gateway_lambda_proxy_integration_any_method_with_path_param": 0.0016414949999443706, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_api_gateway_lambda_proxy_integration_with_is_base_64_encoded": 0.001853550999953768, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_api_gateway_mock_integration": 0.062374845000022106, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_api_mock_integration_response_params": 0.0017541940001137846, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_apigateway_with_custom_authorization_method": 15.392572049000023, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_apigw_stage_variables[dev]": 1.6289083030000029, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_apigw_stage_variables[local]": 1.6239282209999146, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_apigw_test_invoke_method_api": 2.178941526000017, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_base_path_mapping": 0.19103752199987412, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_base_path_mapping_root": 0.16691426400007003, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_create_rest_api_with_custom_id[host_based_url]": 0.06415520300004118, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_create_rest_api_with_custom_id[localstack_path_based_url]": 0.06460418200003915, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_create_rest_api_with_custom_id[path_based_url]": 0.06691072399996756, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_delete_rest_api_with_invalid_id": 0.012235784999916177, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_invoke_endpoint_cors_headers[http://allowed-False-UrlType.HOST_BASED]": 0.07165065699985007, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_invoke_endpoint_cors_headers[http://allowed-False-UrlType.LS_PATH_BASED]": 0.07252210999990893, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_invoke_endpoint_cors_headers[http://allowed-False-UrlType.PATH_BASED]": 0.07317133099991224, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_invoke_endpoint_cors_headers[http://allowed-True-UrlType.HOST_BASED]": 0.0944483929999933, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_invoke_endpoint_cors_headers[http://allowed-True-UrlType.LS_PATH_BASED]": 0.06836799899997459, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_invoke_endpoint_cors_headers[http://allowed-True-UrlType.PATH_BASED]": 0.07048841399989669, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_invoke_endpoint_cors_headers[http://denied-False-UrlType.HOST_BASED]": 0.07218560399996932, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_invoke_endpoint_cors_headers[http://denied-False-UrlType.LS_PATH_BASED]": 0.07138026500001615, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_invoke_endpoint_cors_headers[http://denied-False-UrlType.PATH_BASED]": 0.07274514599998838, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_invoke_endpoint_cors_headers[http://denied-True-UrlType.HOST_BASED]": 0.06990109600008054, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_invoke_endpoint_cors_headers[http://denied-True-UrlType.LS_PATH_BASED]": 0.06727327700002661, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_invoke_endpoint_cors_headers[http://denied-True-UrlType.PATH_BASED]": 0.07096239700001661, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_multiple_api_keys_validate": 0.4509758350000084, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_put_integration_dynamodb_proxy_validation_with_request_template": 0.0017191790000197216, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_put_integration_dynamodb_proxy_validation_without_request_template": 0.0018871920000265163, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_response_headers_invocation_with_apigw": 1.7548002669999505, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_update_rest_api_deployment": 0.07330105199991976, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_api_gateway_http_integrations[custom]": 0.0019622930000195993, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_api_gateway_http_integrations[proxy]": 0.001769974000012553, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_mock_integration_response[NEVER-UrlType.HOST_BASED-GET]": 0.09360360599998785, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_mock_integration_response[NEVER-UrlType.HOST_BASED-POST]": 0.09086508299981233, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_mock_integration_response[NEVER-UrlType.PATH_BASED-GET]": 0.09245985099994414, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_mock_integration_response[NEVER-UrlType.PATH_BASED-POST]": 0.09100434499998755, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_mock_integration_response[WHEN_NO_MATCH-UrlType.HOST_BASED-GET]": 0.09301317999995717, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_mock_integration_response[WHEN_NO_MATCH-UrlType.HOST_BASED-POST]": 0.09417862200007221, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_mock_integration_response[WHEN_NO_MATCH-UrlType.PATH_BASED-GET]": 0.10537534699994922, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_mock_integration_response[WHEN_NO_MATCH-UrlType.PATH_BASED-POST]": 0.09397200199998679, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_mock_integration_response[WHEN_NO_TEMPLATES-UrlType.HOST_BASED-GET]": 0.09016126499989241, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_mock_integration_response[WHEN_NO_TEMPLATES-UrlType.HOST_BASED-POST]": 0.09307011099997453, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_mock_integration_response[WHEN_NO_TEMPLATES-UrlType.PATH_BASED-GET]": 0.09364651399994273, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestIntegrations::test_mock_integration_response[WHEN_NO_TEMPLATES-UrlType.PATH_BASED-POST]": 0.09236440700010462, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestTagging::test_tag_api": 0.06929817999991883, + "tests/aws/services/apigateway/test_apigateway_basic.py::test_apigw_call_api_with_aws_endpoint_url": 0.013851740999939466, + "tests/aws/services/apigateway/test_apigateway_basic.py::test_rest_api_multi_region[UrlType.HOST_BASED-ANY]": 3.3362138070001492, + "tests/aws/services/apigateway/test_apigateway_basic.py::test_rest_api_multi_region[UrlType.HOST_BASED-GET]": 3.3724849929999436, + "tests/aws/services/apigateway/test_apigateway_basic.py::test_rest_api_multi_region[path_based_url-ANY]": 3.4436701420000873, + "tests/aws/services/apigateway/test_apigateway_basic.py::test_rest_api_multi_region[path_based_url-GET]": 9.505666622000149, + "tests/aws/services/apigateway/test_apigateway_canary.py::TestCanaryDeployments::test_invoking_canary_deployment": 0.1217472439999483, + "tests/aws/services/apigateway/test_apigateway_canary.py::TestStageCrudCanary::test_create_canary_deployment": 0.1192010049998089, + "tests/aws/services/apigateway/test_apigateway_canary.py::TestStageCrudCanary::test_create_canary_deployment_by_stage_update": 0.12463569500005178, + "tests/aws/services/apigateway/test_apigateway_canary.py::TestStageCrudCanary::test_create_canary_deployment_validation": 0.08665870000004361, + "tests/aws/services/apigateway/test_apigateway_canary.py::TestStageCrudCanary::test_create_canary_deployment_with_stage": 0.10113417100001243, + "tests/aws/services/apigateway/test_apigateway_canary.py::TestStageCrudCanary::test_create_update_stages": 0.14211251000006087, + "tests/aws/services/apigateway/test_apigateway_canary.py::TestStageCrudCanary::test_update_stage_canary_deployment_validation": 0.14821565199986253, + "tests/aws/services/apigateway/test_apigateway_canary.py::TestStageCrudCanary::test_update_stage_with_copy_ops": 0.12839853700006643, + "tests/aws/services/apigateway/test_apigateway_common.py::TestApiGatewayCommon::test_api_gateway_request_validator": 2.4211700079998764, + "tests/aws/services/apigateway/test_apigateway_common.py::TestApiGatewayCommon::test_api_gateway_request_validator_with_ref_models": 0.17796587700013333, + "tests/aws/services/apigateway/test_apigateway_common.py::TestApiGatewayCommon::test_api_gateway_request_validator_with_ref_one_ofmodels": 0.17962174699994193, + "tests/aws/services/apigateway/test_apigateway_common.py::TestApiGatewayCommon::test_input_body_formatting": 3.4396255949999386, + "tests/aws/services/apigateway/test_apigateway_common.py::TestApiGatewayCommon::test_input_path_template_formatting": 0.617946553000138, + "tests/aws/services/apigateway/test_apigateway_common.py::TestApiGatewayCommon::test_integration_request_parameters_mapping": 0.10762667900007727, + "tests/aws/services/apigateway/test_apigateway_common.py::TestApiGatewayCommon::test_invocation_trace_id": 2.293089298000041, + "tests/aws/services/apigateway/test_apigateway_common.py::TestApigatewayRouting::test_api_not_existing": 0.023421269999971628, + "tests/aws/services/apigateway/test_apigateway_common.py::TestApigatewayRouting::test_proxy_routing_with_hardcoded_resource_sibling": 0.26257765500008645, + "tests/aws/services/apigateway/test_apigateway_common.py::TestApigatewayRouting::test_routing_not_found": 0.112718434000044, + "tests/aws/services/apigateway/test_apigateway_common.py::TestApigatewayRouting::test_routing_with_custom_api_id": 0.09697082100001353, + "tests/aws/services/apigateway/test_apigateway_common.py::TestApigatewayRouting::test_routing_with_hardcoded_resource_sibling_order": 0.22832977299992763, + "tests/aws/services/apigateway/test_apigateway_common.py::TestDeployments::test_create_delete_deployments[False]": 0.40530243700004576, + "tests/aws/services/apigateway/test_apigateway_common.py::TestDeployments::test_create_delete_deployments[True]": 0.44243031100006647, + "tests/aws/services/apigateway/test_apigateway_common.py::TestDeployments::test_create_update_deployments": 0.338331741999923, + "tests/aws/services/apigateway/test_apigateway_common.py::TestDocumentations::test_documentation_parts_and_versions": 0.10860929800003305, + "tests/aws/services/apigateway/test_apigateway_common.py::TestStages::test_create_update_stages": 0.31873912899993684, + "tests/aws/services/apigateway/test_apigateway_common.py::TestStages::test_update_stage_remove_wildcard": 0.30873247799991077, + "tests/aws/services/apigateway/test_apigateway_common.py::TestUsagePlans::test_api_key_required_for_methods": 0.19466703400007646, + "tests/aws/services/apigateway/test_apigateway_common.py::TestUsagePlans::test_usage_plan_crud": 0.1857037570001694, + "tests/aws/services/apigateway/test_apigateway_custom_ids.py::test_apigateway_custom_ids": 0.060232139000049756, + "tests/aws/services/apigateway/test_apigateway_dynamodb.py::test_error_aws_proxy_not_supported": 0.13853794700014532, + "tests/aws/services/apigateway/test_apigateway_dynamodb.py::test_rest_api_to_dynamodb_integration[PutItem]": 0.3636395339998444, + "tests/aws/services/apigateway/test_apigateway_dynamodb.py::test_rest_api_to_dynamodb_integration[Query]": 0.43876587800002653, + "tests/aws/services/apigateway/test_apigateway_dynamodb.py::test_rest_api_to_dynamodb_integration[Scan]": 0.33752269000001434, + "tests/aws/services/apigateway/test_apigateway_eventbridge.py::test_apigateway_to_eventbridge": 0.20199159700018754, + "tests/aws/services/apigateway/test_apigateway_extended.py::TestApigatewayApiKeysCrud::test_get_api_keys": 0.15804636500013203, + "tests/aws/services/apigateway/test_apigateway_extended.py::TestApigatewayApiKeysCrud::test_get_usage_plan_api_keys": 0.15930703900005483, + "tests/aws/services/apigateway/test_apigateway_extended.py::test_create_domain_names": 0.07469391799997993, + "tests/aws/services/apigateway/test_apigateway_extended.py::test_export_oas30_openapi[TEST_IMPORT_PETSTORE_SWAGGER]": 0.3998515130000442, + "tests/aws/services/apigateway/test_apigateway_extended.py::test_export_oas30_openapi[TEST_IMPORT_PETS]": 0.31327046299998074, + "tests/aws/services/apigateway/test_apigateway_extended.py::test_export_swagger_openapi[TEST_IMPORT_PETSTORE_SWAGGER]": 0.40580610800009254, + "tests/aws/services/apigateway/test_apigateway_extended.py::test_export_swagger_openapi[TEST_IMPORT_PETS]": 0.3112179229999583, + "tests/aws/services/apigateway/test_apigateway_extended.py::test_get_domain_name": 0.07200241699979415, + "tests/aws/services/apigateway/test_apigateway_extended.py::test_get_domain_names": 0.07290961999990486, + "tests/aws/services/apigateway/test_apigateway_http.py::test_http_integration_invoke_status_code_passthrough[HTTP]": 1.7544648880000295, + "tests/aws/services/apigateway/test_apigateway_http.py::test_http_integration_invoke_status_code_passthrough[HTTP_PROXY]": 1.7311674669999775, + "tests/aws/services/apigateway/test_apigateway_http.py::test_http_integration_method[HTTP]": 2.0389835719998928, + "tests/aws/services/apigateway/test_apigateway_http.py::test_http_integration_method[HTTP_PROXY]": 1.9992655199999945, + "tests/aws/services/apigateway/test_apigateway_http.py::test_http_integration_with_lambda[HTTP]": 2.176717202999953, + "tests/aws/services/apigateway/test_apigateway_http.py::test_http_integration_with_lambda[HTTP_PROXY]": 2.19055265399993, + "tests/aws/services/apigateway/test_apigateway_http.py::test_http_proxy_integration_request_data_mappings": 1.9648776599999564, + "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_and_validate_rest_api[openapi.spec.tf.json]": 0.3554284540000481, + "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_and_validate_rest_api[swagger-mock-cors.json]": 0.4291910670000334, + "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_rest_api": 0.06574510400002964, + "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_rest_api_with_base_path_oas30[ignore]": 0.8815420820001236, + "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_rest_api_with_base_path_oas30[prepend]": 0.8859803249999914, + "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_rest_api_with_base_path_oas30[split]": 0.8822843129999001, + "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_rest_apis_with_base_path_swagger[ignore]": 0.5964956300001631, + "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_rest_apis_with_base_path_swagger[prepend]": 0.6064789590000146, + "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_rest_apis_with_base_path_swagger[split]": 0.6518073049999202, + "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_swagger_api": 0.7556212110000615, + "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_with_circular_models": 0.2854119270001547, + "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_with_circular_models_and_request_validation": 0.39116003200001614, + "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_with_cognito_auth_identity_source": 0.3908478159999049, + "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_with_global_api_key_authorizer": 0.28044682699999157, + "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_with_http_method_integration": 0.2897036950000711, + "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_with_integer_http_status_code": 0.17809704799992687, + "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_import_with_stage_variables": 1.666869715999951, + "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_put_rest_api_mode_binary_media_types[merge]": 0.34145318100001987, + "tests/aws/services/apigateway/test_apigateway_import.py::TestApiGatewayImportRestApi::test_put_rest_api_mode_binary_media_types[overwrite]": 0.34144954800001415, + "tests/aws/services/apigateway/test_apigateway_integrations.py::TestApiGatewayHeaderRemapping::test_apigateway_header_remapping_aws[AWS]": 2.3941555169999447, + "tests/aws/services/apigateway/test_apigateway_integrations.py::TestApiGatewayHeaderRemapping::test_apigateway_header_remapping_aws[AWS_PROXY]": 2.4097596870001325, + "tests/aws/services/apigateway/test_apigateway_integrations.py::TestApiGatewayHeaderRemapping::test_apigateway_header_remapping_http[HTTP]": 0.8250421949999236, + "tests/aws/services/apigateway/test_apigateway_integrations.py::TestApiGatewayHeaderRemapping::test_apigateway_header_remapping_http[HTTP_PROXY]": 0.8046367670000336, + "tests/aws/services/apigateway/test_apigateway_integrations.py::test_create_execute_api_vpc_endpoint": 6.461000085000023, + "tests/aws/services/apigateway/test_apigateway_integrations.py::test_http_integration_status_code_selection": 0.12236149500006377, + "tests/aws/services/apigateway/test_apigateway_integrations.py::test_integration_mock_with_path_param": 0.09295678799981033, + "tests/aws/services/apigateway/test_apigateway_integrations.py::test_integration_mock_with_request_overrides_in_response_template": 0.11553227599983984, + "tests/aws/services/apigateway/test_apigateway_integrations.py::test_integration_mock_with_response_override_in_request_template[False]": 0.08344342699990648, + "tests/aws/services/apigateway/test_apigateway_integrations.py::test_integration_mock_with_response_override_in_request_template[True]": 0.08318761900011395, + "tests/aws/services/apigateway/test_apigateway_integrations.py::test_integration_mock_with_vtl_map_assignation": 0.08715639800004737, + "tests/aws/services/apigateway/test_apigateway_integrations.py::test_put_integration_response_with_response_template": 1.200542076000147, + "tests/aws/services/apigateway/test_apigateway_integrations.py::test_put_integration_responses": 0.17319964400007848, + "tests/aws/services/apigateway/test_apigateway_integrations.py::test_put_integration_validation": 0.19936792999999398, + "tests/aws/services/apigateway/test_apigateway_kinesis.py::test_apigateway_to_kinesis[PutRecord]": 1.1006660250000095, + "tests/aws/services/apigateway/test_apigateway_kinesis.py::test_apigateway_to_kinesis[PutRecords]": 1.085097233000056, + "tests/aws/services/apigateway/test_apigateway_lambda.py::test_aws_proxy_binary_response": 3.74460775, + "tests/aws/services/apigateway/test_apigateway_lambda.py::test_aws_proxy_response_payload_format_validation": 4.056282820999968, + "tests/aws/services/apigateway/test_apigateway_lambda.py::test_lambda_aws_integration": 1.6765193960000033, + "tests/aws/services/apigateway/test_apigateway_lambda.py::test_lambda_aws_integration_response_with_mapping_templates": 1.8619376199998214, + "tests/aws/services/apigateway/test_apigateway_lambda.py::test_lambda_aws_integration_with_request_template": 1.8032176179999624, + "tests/aws/services/apigateway/test_apigateway_lambda.py::test_lambda_aws_proxy_integration": 4.012986957999942, + "tests/aws/services/apigateway/test_apigateway_lambda.py::test_lambda_aws_proxy_integration_non_post_method": 1.2657008360000646, + "tests/aws/services/apigateway/test_apigateway_lambda.py::test_lambda_aws_proxy_integration_request_data_mapping": 2.805118160999996, + "tests/aws/services/apigateway/test_apigateway_lambda.py::test_lambda_aws_proxy_response_format": 1.9531311480000113, + "tests/aws/services/apigateway/test_apigateway_lambda.py::test_lambda_rust_proxy_integration": 1.7240970329999072, + "tests/aws/services/apigateway/test_apigateway_lambda.py::test_lambda_selection_patterns": 1.921528778000038, + "tests/aws/services/apigateway/test_apigateway_lambda.py::test_put_integration_aws_proxy_uri": 1.2929844359999834, + "tests/aws/services/apigateway/test_apigateway_lambda_cfn.py::TestApigatewayLambdaIntegration::test_scenario_validate_infra": 7.6463928719999785, + "tests/aws/services/apigateway/test_apigateway_s3.py::TestApiGatewayS3BinarySupport::test_apigw_s3_binary_support_request[CONVERT_TO_TEXT]": 0.5141590440000527, + "tests/aws/services/apigateway/test_apigateway_s3.py::TestApiGatewayS3BinarySupport::test_apigw_s3_binary_support_request[None]": 0.5035381779998716, + "tests/aws/services/apigateway/test_apigateway_s3.py::TestApiGatewayS3BinarySupport::test_apigw_s3_binary_support_request_convert_to_binary": 0.4835231529999646, + "tests/aws/services/apigateway/test_apigateway_s3.py::TestApiGatewayS3BinarySupport::test_apigw_s3_binary_support_request_convert_to_binary_with_request_template": 0.3378804260000834, + "tests/aws/services/apigateway/test_apigateway_s3.py::TestApiGatewayS3BinarySupport::test_apigw_s3_binary_support_response_convert_to_binary": 0.5184623279999414, + "tests/aws/services/apigateway/test_apigateway_s3.py::TestApiGatewayS3BinarySupport::test_apigw_s3_binary_support_response_convert_to_binary_with_request_template": 0.3206017210000027, + "tests/aws/services/apigateway/test_apigateway_s3.py::TestApiGatewayS3BinarySupport::test_apigw_s3_binary_support_response_convert_to_text": 0.5136951420000742, + "tests/aws/services/apigateway/test_apigateway_s3.py::TestApiGatewayS3BinarySupport::test_apigw_s3_binary_support_response_no_content_handling": 0.5268388959999584, + "tests/aws/services/apigateway/test_apigateway_s3.py::test_apigateway_s3_any": 0.4096973099999559, + "tests/aws/services/apigateway/test_apigateway_s3.py::test_apigateway_s3_method_mapping": 0.4508157750000237, + "tests/aws/services/apigateway/test_apigateway_sqs.py::test_sqs_amz_json_protocol": 0.9799824810000928, + "tests/aws/services/apigateway/test_apigateway_sqs.py::test_sqs_aws_integration": 1.1548697740000762, + "tests/aws/services/apigateway/test_apigateway_sqs.py::test_sqs_aws_integration_with_message_attribute[MessageAttribute]": 0.24280461500006822, + "tests/aws/services/apigateway/test_apigateway_sqs.py::test_sqs_aws_integration_with_message_attribute[MessageAttributes]": 0.2407205749999548, + "tests/aws/services/apigateway/test_apigateway_sqs.py::test_sqs_request_and_response_xml_templates_integration": 0.3269303789999185, + "tests/aws/services/apigateway/test_apigateway_ssm.py::test_get_parameter_query_protocol": 0.0018372590000126365, + "tests/aws/services/apigateway/test_apigateway_ssm.py::test_ssm_aws_integration": 0.21917708400007996, + "tests/aws/services/apigateway/test_apigateway_stepfunctions.py::TestApigatewayStepfunctions::test_apigateway_with_step_function_integration[DeleteStateMachine]": 1.333304336000083, + "tests/aws/services/apigateway/test_apigateway_stepfunctions.py::TestApigatewayStepfunctions::test_apigateway_with_step_function_integration[StartExecution]": 1.4411975130001338, + "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceApi::test_api_exceptions": 0.0018196259999285758, + "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceApi::test_create_exceptions": 0.0018796780000229774, + "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceApi::test_create_invalid_desiredstate": 0.0018017419998841433, + "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceApi::test_double_create_with_client_token": 0.0018665339999870412, + "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceApi::test_lifecycle": 0.0019491680000101042, + "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceApi::test_list_resources": 0.0018117519999805154, + "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceApi::test_list_resources_with_resource_model": 0.001840505000018311, + "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceApi::test_update": 0.0018010810000532729, + "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceRequestApi::test_cancel_edge_cases[FAIL]": 0.0017176660001041455, + "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceRequestApi::test_cancel_edge_cases[SUCCESS]": 0.0017192289999456989, + "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceRequestApi::test_cancel_request": 0.0018664140001192209, + "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceRequestApi::test_get_request_status": 0.0017111439999553113, + "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceRequestApi::test_invalid_request_token_exc": 0.0021705619999465853, + "tests/aws/services/cloudcontrol/test_cloudcontrol_api.py::TestCloudControlResourceRequestApi::test_list_request_status": 0.0017389049999110284, + "tests/aws/services/cloudformation/api/test_changesets.py::TestUpdates::test_deleting_resource": 0.00171347799994237, + "tests/aws/services/cloudformation/api/test_changesets.py::TestUpdates::test_simple_update_single_resource": 4.199171133999926, + "tests/aws/services/cloudformation/api/test_changesets.py::TestUpdates::test_simple_update_two_resources": 0.0018672749998813742, + "tests/aws/services/cloudformation/api/test_changesets.py::test_autoexpand_capability_requirement": 0.051655748000030144, + "tests/aws/services/cloudformation/api/test_changesets.py::test_create_and_then_remove_non_supported_resource_change_set": 11.191055830000096, + "tests/aws/services/cloudformation/api/test_changesets.py::test_create_and_then_remove_supported_resource_change_set": 19.86545361900005, + "tests/aws/services/cloudformation/api/test_changesets.py::test_create_and_then_update_refreshes_template_metadata": 2.1523711100001037, + "tests/aws/services/cloudformation/api/test_changesets.py::test_create_change_set_create_existing": 0.00171075299988388, + "tests/aws/services/cloudformation/api/test_changesets.py::test_create_change_set_invalid_params": 0.015901686999995945, + "tests/aws/services/cloudformation/api/test_changesets.py::test_create_change_set_missing_stackname": 0.0047017249999044, + "tests/aws/services/cloudformation/api/test_changesets.py::test_create_change_set_update_nonexisting": 0.015293330999952559, + "tests/aws/services/cloudformation/api/test_changesets.py::test_create_change_set_update_without_parameters": 0.0016982189998770991, + "tests/aws/services/cloudformation/api/test_changesets.py::test_create_change_set_with_ssm_parameter": 1.1479431669998803, + "tests/aws/services/cloudformation/api/test_changesets.py::test_create_change_set_without_parameters": 0.08980352200001107, + "tests/aws/services/cloudformation/api/test_changesets.py::test_create_changeset_with_stack_id": 0.23658561600007033, + "tests/aws/services/cloudformation/api/test_changesets.py::test_create_delete_create": 2.147189309000055, + "tests/aws/services/cloudformation/api/test_changesets.py::test_create_while_in_review": 0.0018361360000653804, + "tests/aws/services/cloudformation/api/test_changesets.py::test_delete_change_set_exception": 0.02118794499995147, + "tests/aws/services/cloudformation/api/test_changesets.py::test_deleted_changeset": 0.04883690700000898, + "tests/aws/services/cloudformation/api/test_changesets.py::test_describe_change_set_nonexisting": 0.012696727999923496, + "tests/aws/services/cloudformation/api/test_changesets.py::test_describe_change_set_with_similarly_named_stacks": 0.04807752100009566, + "tests/aws/services/cloudformation/api/test_changesets.py::test_empty_changeset": 1.3228727579999031, + "tests/aws/services/cloudformation/api/test_changesets.py::test_execute_change_set": 0.001837488999967718, + "tests/aws/services/cloudformation/api/test_changesets.py::test_multiple_create_changeset": 0.3525513649999539, + "tests/aws/services/cloudformation/api/test_changesets.py::test_name_conflicts": 2.894432517000155, + "tests/aws/services/cloudformation/api/test_drift_detection.py::test_drift_detection_on_lambda": 0.001751658000102907, + "tests/aws/services/cloudformation/api/test_extensions_api.py::TestExtensionsApi::test_crud_extension[HOOK-LocalStack::Testing::TestHook-hooks/localstack-testing-testhook.zip]": 0.0018857599999364538, + "tests/aws/services/cloudformation/api/test_extensions_api.py::TestExtensionsApi::test_crud_extension[MODULE-LocalStack::Testing::TestModule::MODULE-modules/localstack-testing-testmodule-module.zip]": 0.0018703099999584083, + "tests/aws/services/cloudformation/api/test_extensions_api.py::TestExtensionsApi::test_crud_extension[RESOURCE-LocalStack::Testing::TestResource-resourcetypes/localstack-testing-testresource.zip]": 0.0018172710000499137, + "tests/aws/services/cloudformation/api/test_extensions_api.py::TestExtensionsApi::test_extension_not_complete": 0.0017242679999753818, + "tests/aws/services/cloudformation/api/test_extensions_api.py::TestExtensionsApi::test_extension_type_configuration": 0.0017246180000256572, + "tests/aws/services/cloudformation/api/test_extensions_api.py::TestExtensionsApi::test_extension_versioning": 0.0017125859999396198, + "tests/aws/services/cloudformation/api/test_extensions_hooks.py::TestExtensionsHooks::test_hook_deployment[FAIL]": 0.0017206009999881644, + "tests/aws/services/cloudformation/api/test_extensions_hooks.py::TestExtensionsHooks::test_hook_deployment[WARN]": 0.0016834519999520126, + "tests/aws/services/cloudformation/api/test_extensions_modules.py::TestExtensionsModules::test_module_usage": 0.0017541030000529645, + "tests/aws/services/cloudformation/api/test_extensions_resourcetypes.py::TestExtensionsResourceTypes::test_deploy_resource_type": 0.0017085380000025907, + "tests/aws/services/cloudformation/api/test_nested_stacks.py::test_deletion_of_failed_nested_stack": 15.337427143000014, + "tests/aws/services/cloudformation/api/test_nested_stacks.py::test_lifecycle_nested_stack": 0.001965778999988288, + "tests/aws/services/cloudformation/api/test_nested_stacks.py::test_nested_output_in_params": 12.635364670000058, + "tests/aws/services/cloudformation/api/test_nested_stacks.py::test_nested_stack": 6.209913826000047, + "tests/aws/services/cloudformation/api/test_nested_stacks.py::test_nested_stack_output_refs": 6.2241487269999425, + "tests/aws/services/cloudformation/api/test_nested_stacks.py::test_nested_stacks_conditions": 6.230898927999874, + "tests/aws/services/cloudformation/api/test_nested_stacks.py::test_nested_with_nested_stack": 12.309064635000027, + "tests/aws/services/cloudformation/api/test_reference_resolving.py::test_nested_getatt_ref[TopicArn]": 2.1077836180000986, + "tests/aws/services/cloudformation/api/test_reference_resolving.py::test_nested_getatt_ref[TopicName]": 2.1248449209999762, + "tests/aws/services/cloudformation/api/test_reference_resolving.py::test_reference_unsupported_resource": 2.099017840000215, + "tests/aws/services/cloudformation/api/test_reference_resolving.py::test_sub_resolving": 2.100904586000297, + "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_create_stack_with_policy": 0.0017451469998377434, + "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_different_action_attribute": 0.001956993000021612, + "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_different_principal_attribute": 0.001813215000083801, + "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_empty_policy": 0.001826477999884446, + "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_not_json_policy": 0.0016580340000018623, + "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_policy_during_update": 0.0017119460001140396, + "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_policy_lifecycle": 0.0017992080001931754, + "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_prevent_deletion[resource0]": 0.0017233560001841397, + "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_prevent_deletion[resource1]": 0.0018136359999516571, + "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_prevent_modifying_with_policy_specifying_resource_id": 0.0018068619997393398, + "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_prevent_replacement": 0.0017413300001862808, + "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_prevent_resource_deletion": 0.0017496559999017336, + "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_prevent_stack_update": 0.0017653359998348606, + "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_prevent_update[AWS::S3::Bucket]": 0.0016614109999864013, + "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_prevent_update[AWS::SNS::Topic]": 0.0016511710000486346, + "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_set_empty_policy_with_url": 0.001700684999832447, + "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_set_invalid_policy_with_url": 0.001735338999878877, + "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_set_policy_both_policy_and_url": 0.0016917280001962354, + "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_set_policy_with_update_operation": 0.0017550859997754742, + "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_set_policy_with_url": 0.001714350000156628, + "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_update_with_empty_policy": 0.0017071760000817449, + "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_update_with_overlapping_policies[False]": 0.0017144699997970747, + "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_update_with_overlapping_policies[True]": 0.001811351000014838, + "tests/aws/services/cloudformation/api/test_stack_policies.py::TestStackPolicy::test_update_with_policy": 0.001711945000124615, + "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_create_stack_with_custom_id": 1.0584883209999134, + "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_failure_options_for_stack_creation[False-0]": 0.0017915329999595997, + "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_failure_options_for_stack_creation[True-1]": 0.001836117000266313, + "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_failure_options_for_stack_update[False-2]": 0.0018003199998020136, + "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_failure_options_for_stack_update[True-1]": 0.0018078030000197032, + "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_get_template_using_changesets[json]": 2.106135876999815, + "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_get_template_using_changesets[yaml]": 2.1022442660000706, + "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_get_template_using_create_stack[json]": 1.0515608939999765, + "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_get_template_using_create_stack[yaml]": 1.0562091649999275, + "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_list_events_after_deployment": 2.1787760780002827, + "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_list_stack_resources_for_removed_resource": 22.048658283999885, + "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_stack_description_special_chars": 2.2980417750000015, + "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_stack_lifecycle": 4.364199098000199, + "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_stack_name_creation": 0.08176858499996342, + "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_stack_update_resources": 4.433484471999918, + "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_update_stack_actual_update": 4.17949059700004, + "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_update_stack_with_same_template_withoutchange": 2.0915790289998313, + "tests/aws/services/cloudformation/api/test_stacks.py::TestStacksApi::test_update_stack_with_same_template_withoutchange_transformation": 2.2585118529998454, + "tests/aws/services/cloudformation/api/test_stacks.py::test_blocked_stack_deletion": 0.00184414199998173, + "tests/aws/services/cloudformation/api/test_stacks.py::test_describe_stack_events_errors": 0.02489297900024212, + "tests/aws/services/cloudformation/api/test_stacks.py::test_events_resource_types": 2.1487305919999926, + "tests/aws/services/cloudformation/api/test_stacks.py::test_linting_error_during_creation": 0.0017655350002314663, + "tests/aws/services/cloudformation/api/test_stacks.py::test_list_parameter_type": 2.1080757830002312, + "tests/aws/services/cloudformation/api/test_stacks.py::test_name_conflicts": 2.418252706999965, + "tests/aws/services/cloudformation/api/test_stacks.py::test_no_echo_parameter": 3.886963598000193, + "tests/aws/services/cloudformation/api/test_stacks.py::test_notifications": 0.0017228549997980735, + "tests/aws/services/cloudformation/api/test_stacks.py::test_stack_deploy_order[A-B-C]": 2.3904215419997854, + "tests/aws/services/cloudformation/api/test_stacks.py::test_stack_deploy_order[A-C-B]": 2.3892248670001663, + "tests/aws/services/cloudformation/api/test_stacks.py::test_stack_deploy_order[B-A-C]": 2.385444623000012, + "tests/aws/services/cloudformation/api/test_stacks.py::test_stack_deploy_order[B-C-A]": 2.3854307470001004, + "tests/aws/services/cloudformation/api/test_stacks.py::test_stack_deploy_order[C-A-B]": 2.3884971649999898, + "tests/aws/services/cloudformation/api/test_stacks.py::test_stack_deploy_order[C-B-A]": 2.3966020100001515, + "tests/aws/services/cloudformation/api/test_stacks.py::test_stack_resource_not_found": 2.1001758349998454, + "tests/aws/services/cloudformation/api/test_stacks.py::test_update_termination_protection": 2.1303280399997675, + "tests/aws/services/cloudformation/api/test_stacks.py::test_updating_an_updated_stack_sets_status": 6.370577009999806, + "tests/aws/services/cloudformation/api/test_templates.py::test_create_stack_from_s3_template_url[http_host]": 1.14158764900003, + "tests/aws/services/cloudformation/api/test_templates.py::test_create_stack_from_s3_template_url[http_invalid]": 0.09484701100018356, + "tests/aws/services/cloudformation/api/test_templates.py::test_create_stack_from_s3_template_url[http_path]": 1.140730104000113, + "tests/aws/services/cloudformation/api/test_templates.py::test_create_stack_from_s3_template_url[s3_url]": 0.0935569310001938, + "tests/aws/services/cloudformation/api/test_templates.py::test_get_template_summary": 2.249919842000054, + "tests/aws/services/cloudformation/api/test_templates.py::test_validate_invalid_json_template_should_fail": 0.08965043200009859, + "tests/aws/services/cloudformation/api/test_templates.py::test_validate_template": 0.09122441199997411, + "tests/aws/services/cloudformation/api/test_transformers.py::test_duplicate_resources": 2.3496317619999445, + "tests/aws/services/cloudformation/api/test_transformers.py::test_transformer_individual_resource_level": 2.2390034929999274, + "tests/aws/services/cloudformation/api/test_transformers.py::test_transformer_property_level": 2.2814669049998884, + "tests/aws/services/cloudformation/api/test_update_stack.py::test_basic_update": 3.127033572000073, + "tests/aws/services/cloudformation/api/test_update_stack.py::test_diff_after_update": 3.1426217529999576, + "tests/aws/services/cloudformation/api/test_update_stack.py::test_no_parameters_update": 3.1360889959998985, + "tests/aws/services/cloudformation/api/test_update_stack.py::test_no_template_error": 0.0017081480000342708, + "tests/aws/services/cloudformation/api/test_update_stack.py::test_set_notification_arn_with_update": 0.001809616999935315, + "tests/aws/services/cloudformation/api/test_update_stack.py::test_update_tags": 0.0017210519999935059, + "tests/aws/services/cloudformation/api/test_update_stack.py::test_update_using_template_url": 3.2141243959999883, + "tests/aws/services/cloudformation/api/test_update_stack.py::test_update_with_capabilities[capability0]": 0.001857938000057402, + "tests/aws/services/cloudformation/api/test_update_stack.py::test_update_with_capabilities[capability1]": 0.0017184869998345675, + "tests/aws/services/cloudformation/api/test_update_stack.py::test_update_with_invalid_rollback_configuration_errors": 0.001850154000294424, + "tests/aws/services/cloudformation/api/test_update_stack.py::test_update_with_previous_parameter_value": 3.132685844999969, + "tests/aws/services/cloudformation/api/test_update_stack.py::test_update_with_previous_template": 0.0020307099998717604, + "tests/aws/services/cloudformation/api/test_update_stack.py::test_update_with_resource_types": 0.0016960460000063904, + "tests/aws/services/cloudformation/api/test_update_stack.py::test_update_with_role_without_permissions": 0.0018994550000570598, + "tests/aws/services/cloudformation/api/test_update_stack.py::test_update_with_rollback_configuration": 0.0016549790000226494, + "tests/aws/services/cloudformation/api/test_validations.py::test_invalid_output_structure[missing-def]": 0.0017883089999486401, + "tests/aws/services/cloudformation/api/test_validations.py::test_invalid_output_structure[multiple-nones]": 0.001746650000086447, + "tests/aws/services/cloudformation/api/test_validations.py::test_invalid_output_structure[none-value]": 0.0017761149999842019, + "tests/aws/services/cloudformation/api/test_validations.py::test_missing_resources_block": 0.0017661969998243876, + "tests/aws/services/cloudformation/api/test_validations.py::test_resources_blocks[invalid-key]": 0.001829154000233757, + "tests/aws/services/cloudformation/api/test_validations.py::test_resources_blocks[missing-type]": 0.001752781999812214, + "tests/aws/services/cloudformation/engine/test_attributes.py::TestResourceAttributes::test_dependency_on_attribute_with_dot_notation": 2.1132554280002296, + "tests/aws/services/cloudformation/engine/test_attributes.py::TestResourceAttributes::test_invalid_getatt_fails": 0.0018181830000685295, + "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_condition_on_outputs": 2.1161659130000317, + "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_conditional_att_to_conditional_resources[create]": 2.1417871790001755, + "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_conditional_att_to_conditional_resources[no-create]": 2.121730375999732, + "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_conditional_in_conditional[dev-us-west-2]": 2.105140766999966, + "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_conditional_in_conditional[production-us-east-1]": 2.1020223590001024, + "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_conditional_with_select": 2.1045670329997392, + "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_dependency_in_non_evaluated_if_branch[None-FallbackParamValue]": 2.1306666020000193, + "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_dependency_in_non_evaluated_if_branch[false-DefaultParamValue]": 2.129160560999935, + "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_dependency_in_non_evaluated_if_branch[true-FallbackParamValue]": 2.1302700799997183, + "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_dependent_ref": 0.001901578999877529, + "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_dependent_ref_intrinsic_fn_condition": 0.0017380429999320768, + "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_dependent_ref_with_macro": 0.0019642060001388018, + "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_nested_conditions[prod-bucket-policy]": 0.0017218129999037046, + "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_nested_conditions[prod-nobucket-nopolicy]": 0.0017896889999065024, + "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_nested_conditions[test-bucket-nopolicy]": 0.001993681000158176, + "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_nested_conditions[test-nobucket-nopolicy]": 0.0027765519998865784, + "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_output_reference_to_skipped_resource": 0.0016922980000799726, + "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_simple_condition_evaluation_deploys_resource": 2.1123853850001524, + "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_simple_condition_evaluation_doesnt_deploy_resource": 0.10484798000015871, + "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_simple_intrinsic_fn_condition_evaluation[nope]": 2.09464205900008, + "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_simple_intrinsic_fn_condition_evaluation[yep]": 2.104260525999962, + "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_sub_in_conditions": 2.1235449620000963, + "tests/aws/services/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_update_conditions": 4.227673439999762, + "tests/aws/services/cloudformation/engine/test_mappings.py::TestCloudFormationMappings::test_async_mapping_error_first_level": 2.0736503039997842, + "tests/aws/services/cloudformation/engine/test_mappings.py::TestCloudFormationMappings::test_async_mapping_error_second_level": 2.073688442000048, + "tests/aws/services/cloudformation/engine/test_mappings.py::TestCloudFormationMappings::test_aws_refs_in_mappings": 2.0963027660002354, + "tests/aws/services/cloudformation/engine/test_mappings.py::TestCloudFormationMappings::test_mapping_maximum_nesting_depth": 0.0018992899999830115, + "tests/aws/services/cloudformation/engine/test_mappings.py::TestCloudFormationMappings::test_mapping_minimum_nesting_depth": 0.0018832010000551236, + "tests/aws/services/cloudformation/engine/test_mappings.py::TestCloudFormationMappings::test_mapping_ref_map_key[should-deploy]": 2.1096999799999594, + "tests/aws/services/cloudformation/engine/test_mappings.py::TestCloudFormationMappings::test_mapping_ref_map_key[should-not-deploy]": 2.0938686130000406, + "tests/aws/services/cloudformation/engine/test_mappings.py::TestCloudFormationMappings::test_mapping_with_invalid_refs": 0.0018227670000214857, + "tests/aws/services/cloudformation/engine/test_mappings.py::TestCloudFormationMappings::test_mapping_with_nonexisting_key": 0.001817968000068504, + "tests/aws/services/cloudformation/engine/test_mappings.py::TestCloudFormationMappings::test_simple_mapping_working": 2.109361415000194, + "tests/aws/services/cloudformation/engine/test_references.py::TestDependsOn::test_depends_on_with_missing_reference": 0.0018077039999297995, + "tests/aws/services/cloudformation/engine/test_references.py::TestFnSub::test_fn_sub_cases": 2.1162353629997597, + "tests/aws/services/cloudformation/engine/test_references.py::TestFnSub::test_non_string_parameter_in_sub": 2.109874543999922, + "tests/aws/services/cloudformation/engine/test_references.py::test_resolve_transitive_placeholders_in_strings": 2.1248022540000875, + "tests/aws/services/cloudformation/engine/test_references.py::test_useful_error_when_invalid_ref": 0.016691262999756873, + "tests/aws/services/cloudformation/resource_providers/ec2/aws_ec2_networkacl/test_basic.py::TestBasicCRD::test_black_box": 2.56948665300024, + "tests/aws/services/cloudformation/resource_providers/ec2/test_ec2.py::test_deploy_instance_with_key_pair": 2.395693227000038, + "tests/aws/services/cloudformation/resource_providers/ec2/test_ec2.py::test_deploy_prefix_list": 7.19732593599997, + "tests/aws/services/cloudformation/resource_providers/ec2/test_ec2.py::test_deploy_security_group_with_tags": 2.111868835000223, + "tests/aws/services/cloudformation/resource_providers/ec2/test_ec2.py::test_deploy_vpc_endpoint": 2.520584975000247, + "tests/aws/services/cloudformation/resource_providers/iam/aws_iam_user/test_basic.py::TestBasicCRD::test_autogenerated_values": 2.100525902000072, + "tests/aws/services/cloudformation/resource_providers/iam/aws_iam_user/test_basic.py::TestBasicCRD::test_black_box": 2.1347340709999116, + "tests/aws/services/cloudformation/resource_providers/iam/aws_iam_user/test_basic.py::TestBasicCRD::test_getatt": 2.1373287189999246, + "tests/aws/services/cloudformation/resource_providers/iam/aws_iam_user/test_basic.py::TestUpdates::test_update_without_replacement": 0.001810215999967113, + "tests/aws/services/cloudformation/resource_providers/iam/aws_iam_user/test_exploration.py::TestAttributeAccess::test_getatt[Arn]": 0.001700349999964601, + "tests/aws/services/cloudformation/resource_providers/iam/aws_iam_user/test_exploration.py::TestAttributeAccess::test_getatt[Id]": 0.0017384299997047492, + "tests/aws/services/cloudformation/resource_providers/iam/aws_iam_user/test_exploration.py::TestAttributeAccess::test_getatt[Path]": 0.0017161099999611906, + "tests/aws/services/cloudformation/resource_providers/iam/aws_iam_user/test_exploration.py::TestAttributeAccess::test_getatt[PermissionsBoundary]": 0.0016995690000385366, + "tests/aws/services/cloudformation/resource_providers/iam/aws_iam_user/test_exploration.py::TestAttributeAccess::test_getatt[UserName]": 0.0016998090000015509, + "tests/aws/services/cloudformation/resource_providers/iam/aws_iam_user/test_parity.py::TestParity::test_create_with_full_properties": 2.254321291000224, + "tests/aws/services/cloudformation/resource_providers/iam/test_iam.py::test_cfn_handle_iam_role_resource_no_role_name": 2.134501582000212, + "tests/aws/services/cloudformation/resource_providers/iam/test_iam.py::test_delete_role_detaches_role_policy": 4.2177426800001285, + "tests/aws/services/cloudformation/resource_providers/iam/test_iam.py::test_iam_user_access_key": 4.20251231300017, + "tests/aws/services/cloudformation/resource_providers/iam/test_iam.py::test_iam_username_defaultname": 2.171672115999854, + "tests/aws/services/cloudformation/resource_providers/iam/test_iam.py::test_managed_policy_with_empty_resource": 2.4902718500002266, + "tests/aws/services/cloudformation/resource_providers/iam/test_iam.py::test_policy_attachments": 2.300965790999726, + "tests/aws/services/cloudformation/resource_providers/iam/test_iam.py::test_server_certificate": 2.2446644229999038, + "tests/aws/services/cloudformation/resource_providers/iam/test_iam.py::test_update_inline_policy": 4.275954719000083, + "tests/aws/services/cloudformation/resource_providers/iam/test_iam.py::test_updating_stack_with_iam_role": 12.27303978499981, + "tests/aws/services/cloudformation/resource_providers/opensearch/test_domain.py::TestAttributeAccess::test_getattr[Arn]": 0.0016877569998996478, + "tests/aws/services/cloudformation/resource_providers/opensearch/test_domain.py::TestAttributeAccess::test_getattr[DomainArn]": 0.0016652959998282313, + "tests/aws/services/cloudformation/resource_providers/opensearch/test_domain.py::TestAttributeAccess::test_getattr[DomainEndpoint]": 0.0018356429998220847, + "tests/aws/services/cloudformation/resource_providers/opensearch/test_domain.py::TestAttributeAccess::test_getattr[DomainName]": 0.0019746620000660187, + "tests/aws/services/cloudformation/resource_providers/opensearch/test_domain.py::TestAttributeAccess::test_getattr[EngineVersion]": 0.001835211000070558, + "tests/aws/services/cloudformation/resource_providers/opensearch/test_domain.py::TestAttributeAccess::test_getattr[Id]": 0.0017133540000031644, + "tests/aws/services/cloudformation/resource_providers/scheduler/test_scheduler.py::test_schedule_and_group": 2.5015413449998505, + "tests/aws/services/cloudformation/resource_providers/ssm/test_parameter.py::TestBasicCRD::test_black_box": 0.0019020829997771216, + "tests/aws/services/cloudformation/resource_providers/ssm/test_parameter.py::TestUpdates::test_update_without_replacement": 0.0017978020000555262, + "tests/aws/services/cloudformation/resource_providers/ssm/test_parameter_getatt_exploration.py::TestAttributeAccess::test_getattr[AllowedPattern]": 0.0016744720001042879, + "tests/aws/services/cloudformation/resource_providers/ssm/test_parameter_getatt_exploration.py::TestAttributeAccess::test_getattr[DataType]": 0.0020186039998861816, + "tests/aws/services/cloudformation/resource_providers/ssm/test_parameter_getatt_exploration.py::TestAttributeAccess::test_getattr[Description]": 0.0018934300001092197, + "tests/aws/services/cloudformation/resource_providers/ssm/test_parameter_getatt_exploration.py::TestAttributeAccess::test_getattr[Id]": 0.0018288499998107, + "tests/aws/services/cloudformation/resource_providers/ssm/test_parameter_getatt_exploration.py::TestAttributeAccess::test_getattr[Name]": 0.001758008000024347, + "tests/aws/services/cloudformation/resource_providers/ssm/test_parameter_getatt_exploration.py::TestAttributeAccess::test_getattr[Policies]": 0.0016878369997357368, + "tests/aws/services/cloudformation/resource_providers/ssm/test_parameter_getatt_exploration.py::TestAttributeAccess::test_getattr[Tier]": 0.0016973250001228735, + "tests/aws/services/cloudformation/resource_providers/ssm/test_parameter_getatt_exploration.py::TestAttributeAccess::test_getattr[Type]": 0.001834448999943561, + "tests/aws/services/cloudformation/resource_providers/ssm/test_parameter_getatt_exploration.py::TestAttributeAccess::test_getattr[Value]": 0.0017280520000895194, + "tests/aws/services/cloudformation/resources/test_acm.py::test_cfn_acm_certificate": 2.1014465729997482, + "tests/aws/services/cloudformation/resources/test_apigateway.py::TestServerlessApigwLambda::test_serverless_like_deployment_with_update": 12.476120711000021, + "tests/aws/services/cloudformation/resources/test_apigateway.py::test_account": 2.1578289880001194, + "tests/aws/services/cloudformation/resources/test_apigateway.py::test_api_gateway_with_policy_as_dict": 2.106514567999966, + "tests/aws/services/cloudformation/resources/test_apigateway.py::test_cfn_apigateway_aws_integration": 2.3114912569999433, + "tests/aws/services/cloudformation/resources/test_apigateway.py::test_cfn_apigateway_rest_api": 2.3115814979996685, + "tests/aws/services/cloudformation/resources/test_apigateway.py::test_cfn_apigateway_swagger_import": 2.328982605999954, + "tests/aws/services/cloudformation/resources/test_apigateway.py::test_cfn_deploy_apigateway_from_s3_swagger": 2.6838310689997797, + "tests/aws/services/cloudformation/resources/test_apigateway.py::test_cfn_deploy_apigateway_integration": 2.2278782450002836, + "tests/aws/services/cloudformation/resources/test_apigateway.py::test_cfn_deploy_apigateway_models": 2.3059683480000785, + "tests/aws/services/cloudformation/resources/test_apigateway.py::test_cfn_with_apigateway_resources": 2.342270621000125, + "tests/aws/services/cloudformation/resources/test_apigateway.py::test_rest_api_serverless_ref_resolving": 9.955898627000124, + "tests/aws/services/cloudformation/resources/test_apigateway.py::test_update_apigateway_stage": 4.535268462000204, + "tests/aws/services/cloudformation/resources/test_apigateway.py::test_update_usage_plan": 4.48405067900012, + "tests/aws/services/cloudformation/resources/test_apigateway.py::test_url_output": 2.1875658880001083, + "tests/aws/services/cloudformation/resources/test_cdk.py::TestCdkInit::test_cdk_bootstrap[10]": 9.279000554000277, + "tests/aws/services/cloudformation/resources/test_cdk.py::TestCdkInit::test_cdk_bootstrap[11]": 8.63063205200001, + "tests/aws/services/cloudformation/resources/test_cdk.py::TestCdkInit::test_cdk_bootstrap[12]": 8.644152735000034, + "tests/aws/services/cloudformation/resources/test_cdk.py::TestCdkInit::test_cdk_bootstrap_redeploy": 5.57815410000012, + "tests/aws/services/cloudformation/resources/test_cdk.py::TestCdkSampleApp::test_cdk_sample": 2.433650228000033, + "tests/aws/services/cloudformation/resources/test_cloudformation.py::test_create_macro": 3.21402451400013, + "tests/aws/services/cloudformation/resources/test_cloudformation.py::test_waitcondition": 2.199912968000035, + "tests/aws/services/cloudformation/resources/test_cloudwatch.py::test_alarm_creation": 2.0903264689998196, + "tests/aws/services/cloudformation/resources/test_cloudwatch.py::test_alarm_ext_statistic": 2.125819067000066, + "tests/aws/services/cloudformation/resources/test_cloudwatch.py::test_composite_alarm_creation": 2.4122685070001353, + "tests/aws/services/cloudformation/resources/test_dynamodb.py::test_billing_mode_as_conditional[PAY_PER_REQUEST]": 2.497834793000038, + "tests/aws/services/cloudformation/resources/test_dynamodb.py::test_billing_mode_as_conditional[PROVISIONED]": 2.4623774290002984, + "tests/aws/services/cloudformation/resources/test_dynamodb.py::test_default_name_for_table": 2.4604889259999254, + "tests/aws/services/cloudformation/resources/test_dynamodb.py::test_deploy_stack_with_dynamodb_table": 2.2332855990000553, + "tests/aws/services/cloudformation/resources/test_dynamodb.py::test_global_table": 2.4657821250000325, + "tests/aws/services/cloudformation/resources/test_dynamodb.py::test_global_table_with_ttl_and_sse": 2.147350132999918, + "tests/aws/services/cloudformation/resources/test_dynamodb.py::test_globalindex_read_write_provisioned_throughput_dynamodb_table": 2.191064483999753, + "tests/aws/services/cloudformation/resources/test_dynamodb.py::test_table_with_ttl_and_sse": 2.1364181940000435, + "tests/aws/services/cloudformation/resources/test_dynamodb.py::test_ttl_cdk": 1.2562965100000838, + "tests/aws/services/cloudformation/resources/test_ec2.py::test_cfn_update_ec2_instance_type": 0.0018417569999655825, + "tests/aws/services/cloudformation/resources/test_ec2.py::test_cfn_with_multiple_route_table_associations": 2.473885676000009, + "tests/aws/services/cloudformation/resources/test_ec2.py::test_cfn_with_multiple_route_tables": 2.1977562350000426, + "tests/aws/services/cloudformation/resources/test_ec2.py::test_dhcp_options": 2.318513305999886, + "tests/aws/services/cloudformation/resources/test_ec2.py::test_ec2_security_group_id_with_vpc": 2.1527122259999487, + "tests/aws/services/cloudformation/resources/test_ec2.py::test_internet_gateway_ref_and_attr": 2.2926956700002847, + "tests/aws/services/cloudformation/resources/test_ec2.py::test_keypair_create_import": 2.222098581999944, + "tests/aws/services/cloudformation/resources/test_ec2.py::test_simple_route_table_creation": 2.225708639999766, + "tests/aws/services/cloudformation/resources/test_ec2.py::test_simple_route_table_creation_without_vpc": 2.2290391009998984, + "tests/aws/services/cloudformation/resources/test_ec2.py::test_transit_gateway_attachment": 2.7541959650002354, + "tests/aws/services/cloudformation/resources/test_ec2.py::test_vpc_creates_default_sg": 2.4026581690000057, + "tests/aws/services/cloudformation/resources/test_ec2.py::test_vpc_with_route_table": 2.3022071540001434, + "tests/aws/services/cloudformation/resources/test_elasticsearch.py::test_cfn_handle_elasticsearch_domain": 4.192081867999832, + "tests/aws/services/cloudformation/resources/test_events.py::test_cfn_event_api_destination_resource": 16.39686401100039, + "tests/aws/services/cloudformation/resources/test_events.py::test_cfn_event_bus_resource": 2.1514453010001944, + "tests/aws/services/cloudformation/resources/test_events.py::test_event_rule_creation_without_target": 2.107886077999865, + "tests/aws/services/cloudformation/resources/test_events.py::test_event_rule_to_logs": 2.225530039000205, + "tests/aws/services/cloudformation/resources/test_events.py::test_eventbus_policies": 19.90371246100017, + "tests/aws/services/cloudformation/resources/test_events.py::test_eventbus_policy_statement": 2.109278674000052, + "tests/aws/services/cloudformation/resources/test_events.py::test_rule_pattern_transformation": 2.1379104940001525, + "tests/aws/services/cloudformation/resources/test_events.py::test_rule_properties": 2.1493038880000768, + "tests/aws/services/cloudformation/resources/test_firehose.py::test_firehose_stack_with_kinesis_as_source": 35.567287005000026, + "tests/aws/services/cloudformation/resources/test_integration.py::test_events_sqs_sns_lambda": 20.228181071000108, + "tests/aws/services/cloudformation/resources/test_kinesis.py::test_cfn_handle_kinesis_firehose_resources": 11.369507056000202, + "tests/aws/services/cloudformation/resources/test_kinesis.py::test_default_parameters_kinesis": 11.321046097000135, + "tests/aws/services/cloudformation/resources/test_kinesis.py::test_describe_template": 0.13553349200014964, + "tests/aws/services/cloudformation/resources/test_kinesis.py::test_dynamodb_stream_response_with_cf": 11.356467359000135, + "tests/aws/services/cloudformation/resources/test_kinesis.py::test_kinesis_stream_consumer_creations": 17.292803592000155, + "tests/aws/services/cloudformation/resources/test_kinesis.py::test_stream_creation": 11.327829949000261, + "tests/aws/services/cloudformation/resources/test_kms.py::test_cfn_with_kms_resources": 2.137535995999997, + "tests/aws/services/cloudformation/resources/test_kms.py::test_deploy_stack_with_kms": 2.1171876660000635, + "tests/aws/services/cloudformation/resources/test_kms.py::test_kms_key_disabled": 2.115668352999819, + "tests/aws/services/cloudformation/resources/test_lambda.py::TestCfnLambdaDestinations::test_generic_destination_routing[sqs-sqs]": 15.654804871000124, + "tests/aws/services/cloudformation/resources/test_lambda.py::TestCfnLambdaIntegrations::test_cfn_lambda_dynamodb_source": 10.706290602000081, + "tests/aws/services/cloudformation/resources/test_lambda.py::TestCfnLambdaIntegrations::test_cfn_lambda_kinesis_source": 21.41805440400003, + "tests/aws/services/cloudformation/resources/test_lambda.py::TestCfnLambdaIntegrations::test_cfn_lambda_permissions": 7.890900242999805, + "tests/aws/services/cloudformation/resources/test_lambda.py::TestCfnLambdaIntegrations::test_cfn_lambda_sqs_source": 8.207554221999999, + "tests/aws/services/cloudformation/resources/test_lambda.py::TestCfnLambdaIntegrations::test_lambda_dynamodb_event_filter": 9.46874732900028, + "tests/aws/services/cloudformation/resources/test_lambda.py::test_cfn_function_url": 7.513252313000066, + "tests/aws/services/cloudformation/resources/test_lambda.py::test_event_invoke_config": 6.285937802000035, + "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_alias": 12.506691342000067, + "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_cfn_dead_letter_config_async_invocation": 11.081601942000134, + "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_cfn_run": 6.569740242000307, + "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_cfn_run_with_empty_string_replacement_deny_list": 6.188678643000003, + "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_cfn_run_with_non_empty_string_replacement_deny_list": 6.199821315000008, + "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_code_signing_config": 2.1982792630001313, + "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_function_tags": 6.5655345110001235, + "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_layer_crud": 6.284169316000316, + "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_logging_config": 6.205301257000201, + "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_version": 6.8059519850000925, + "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_version_provisioned_concurrency": 12.584820915999899, + "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_vpc": 0.001934761000029539, + "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_w_dynamodb_event_filter": 11.471297393999976, + "tests/aws/services/cloudformation/resources/test_lambda.py::test_lambda_w_dynamodb_event_filter_update": 12.690252031, + "tests/aws/services/cloudformation/resources/test_lambda.py::test_multiple_lambda_permissions_for_singlefn": 6.21942602099989, + "tests/aws/services/cloudformation/resources/test_lambda.py::test_python_lambda_code_deployed_via_s3": 6.689449878999994, + "tests/aws/services/cloudformation/resources/test_lambda.py::test_update_lambda_function": 8.291031585999917, + "tests/aws/services/cloudformation/resources/test_lambda.py::test_update_lambda_function_name": 12.305761918999679, + "tests/aws/services/cloudformation/resources/test_lambda.py::test_update_lambda_permissions": 8.312249647000044, + "tests/aws/services/cloudformation/resources/test_logs.py::test_cfn_handle_log_group_resource": 2.4138585009998224, + "tests/aws/services/cloudformation/resources/test_logs.py::test_logstream": 2.1222689500002616, + "tests/aws/services/cloudformation/resources/test_opensearch.py::test_domain": 0.001757510000061302, + "tests/aws/services/cloudformation/resources/test_opensearch.py::test_domain_with_alternative_types": 17.46437871499984, + "tests/aws/services/cloudformation/resources/test_redshift.py::test_redshift_cluster": 2.136997892999716, + "tests/aws/services/cloudformation/resources/test_resource_groups.py::test_group_defaults": 2.2595992440001282, + "tests/aws/services/cloudformation/resources/test_route53.py::test_create_health_check": 2.2621165340001426, + "tests/aws/services/cloudformation/resources/test_route53.py::test_create_record_set_via_id": 2.1905462400000033, + "tests/aws/services/cloudformation/resources/test_route53.py::test_create_record_set_via_name": 2.186591192000151, + "tests/aws/services/cloudformation/resources/test_route53.py::test_create_record_set_without_resource_record": 2.1804445810000743, + "tests/aws/services/cloudformation/resources/test_s3.py::test_bucket_autoname": 2.109160983000038, + "tests/aws/services/cloudformation/resources/test_s3.py::test_bucket_versioning": 2.1113980799998444, + "tests/aws/services/cloudformation/resources/test_s3.py::test_bucketpolicy": 19.956451668, + "tests/aws/services/cloudformation/resources/test_s3.py::test_cfn_handle_s3_notification_configuration": 2.178361655999879, + "tests/aws/services/cloudformation/resources/test_s3.py::test_cors_configuration": 2.531172430999959, + "tests/aws/services/cloudformation/resources/test_s3.py::test_object_lock_configuration": 2.520677640000031, + "tests/aws/services/cloudformation/resources/test_s3.py::test_website_configuration": 2.486643064999953, + "tests/aws/services/cloudformation/resources/test_sam.py::test_cfn_handle_serverless_api_resource": 6.632112160000133, + "tests/aws/services/cloudformation/resources/test_sam.py::test_sam_policies": 6.336812393999935, + "tests/aws/services/cloudformation/resources/test_sam.py::test_sam_sqs_event": 13.504537580000033, + "tests/aws/services/cloudformation/resources/test_sam.py::test_sam_template": 6.621015278999948, + "tests/aws/services/cloudformation/resources/test_secretsmanager.py::test_cdk_deployment_generates_secret_value_if_no_value_is_provided": 1.2585105440000461, + "tests/aws/services/cloudformation/resources/test_secretsmanager.py::test_cfn_handle_secretsmanager_secret": 2.2758313709998674, + "tests/aws/services/cloudformation/resources/test_secretsmanager.py::test_cfn_secret_policy[default]": 2.114891433000139, + "tests/aws/services/cloudformation/resources/test_secretsmanager.py::test_cfn_secret_policy[true]": 2.1274207129999922, + "tests/aws/services/cloudformation/resources/test_secretsmanager.py::test_cfn_secretsmanager_gen_secret": 2.276394583999945, + "tests/aws/services/cloudformation/resources/test_sns.py::test_deploy_stack_with_sns_topic": 2.1434261980002702, + "tests/aws/services/cloudformation/resources/test_sns.py::test_sns_subscription": 2.1211036519998743, + "tests/aws/services/cloudformation/resources/test_sns.py::test_sns_subscription_region": 2.153224049999835, + "tests/aws/services/cloudformation/resources/test_sns.py::test_sns_topic_fifo_with_deduplication": 3.4482858230001057, + "tests/aws/services/cloudformation/resources/test_sns.py::test_sns_topic_fifo_without_suffix_fails": 2.086922772999742, + "tests/aws/services/cloudformation/resources/test_sns.py::test_sns_topic_with_attributes": 1.2283839359997728, + "tests/aws/services/cloudformation/resources/test_sns.py::test_update_subscription": 4.237271185000054, + "tests/aws/services/cloudformation/resources/test_sqs.py::test_cfn_handle_sqs_resource": 2.141919506000022, + "tests/aws/services/cloudformation/resources/test_sqs.py::test_sqs_fifo_queue_generates_valid_name": 2.1010330010001326, + "tests/aws/services/cloudformation/resources/test_sqs.py::test_sqs_non_fifo_queue_generates_valid_name": 2.1049960869997904, + "tests/aws/services/cloudformation/resources/test_sqs.py::test_sqs_queue_policy": 2.114124574000016, + "tests/aws/services/cloudformation/resources/test_sqs.py::test_update_queue_no_change": 4.214706848000105, + "tests/aws/services/cloudformation/resources/test_sqs.py::test_update_sqs_queuepolicy": 4.221353079999972, + "tests/aws/services/cloudformation/resources/test_ssm.py::test_deploy_patch_baseline": 2.297224957999788, + "tests/aws/services/cloudformation/resources/test_ssm.py::test_maintenance_window": 2.173570681999763, + "tests/aws/services/cloudformation/resources/test_ssm.py::test_parameter_defaults": 2.319483476999949, + "tests/aws/services/cloudformation/resources/test_ssm.py::test_update_ssm_parameter_tag": 4.193952105000335, + "tests/aws/services/cloudformation/resources/test_ssm.py::test_update_ssm_parameters": 4.194405232999998, + "tests/aws/services/cloudformation/resources/test_stack_sets.py::test_create_stack_set_with_stack_instances": 1.136815376000186, + "tests/aws/services/cloudformation/resources/test_stepfunctions.py::test_apigateway_invoke": 9.536349742000311, + "tests/aws/services/cloudformation/resources/test_stepfunctions.py::test_apigateway_invoke_localhost": 9.57560516100034, + "tests/aws/services/cloudformation/resources/test_stepfunctions.py::test_apigateway_invoke_localhost_with_path": 15.66387834399984, + "tests/aws/services/cloudformation/resources/test_stepfunctions.py::test_apigateway_invoke_with_path": 15.645090374999882, + "tests/aws/services/cloudformation/resources/test_stepfunctions.py::test_cfn_statemachine_default_s3_location": 4.822607276999861, + "tests/aws/services/cloudformation/resources/test_stepfunctions.py::test_cfn_statemachine_with_dependencies": 2.1747703850001017, + "tests/aws/services/cloudformation/resources/test_stepfunctions.py::test_nested_statemachine_with_sync2": 15.492096413999889, + "tests/aws/services/cloudformation/resources/test_stepfunctions.py::test_retry_and_catch": 0.0023666470001444395, + "tests/aws/services/cloudformation/resources/test_stepfunctions.py::test_statemachine_create_with_logging_configuration": 2.6776661210001294, + "tests/aws/services/cloudformation/resources/test_stepfunctions.py::test_statemachine_definitionsubstitution": 7.297211262000019, + "tests/aws/services/cloudformation/test_cloudformation_ui.py::TestCloudFormationUi::test_get_cloudformation_ui": 0.06886270200084255, + "tests/aws/services/cloudformation/test_cloudtrail_trace.py::test_cloudtrail_trace_example": 0.0017755329995452485, + "tests/aws/services/cloudformation/test_template_engine.py::TestImportValues::test_cfn_with_exports": 2.1216688119998253, + "tests/aws/services/cloudformation/test_template_engine.py::TestImportValues::test_import_values_across_stacks": 4.205655351000132, + "tests/aws/services/cloudformation/test_template_engine.py::TestImports::test_stack_imports": 4.217057615999693, + "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_and_or_functions[Fn::And-0-0-False]": 0.08295729800011031, + "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_and_or_functions[Fn::And-0-1-False]": 0.0815101909997793, + "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_and_or_functions[Fn::And-1-0-False]": 0.08137335299943516, + "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_and_or_functions[Fn::And-1-1-True]": 2.1167219479993946, + "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_and_or_functions[Fn::Or-0-0-False]": 0.08679179099999601, + "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_and_or_functions[Fn::Or-0-1-True]": 2.114106410000204, + "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_and_or_functions[Fn::Or-1-0-True]": 2.117060790999858, + "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_and_or_functions[Fn::Or-1-1-True]": 2.1163927620000322, + "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_base64_sub_and_getatt_functions": 2.101469477000137, + "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_cfn_template_with_short_form_fn_sub": 2.098819227999684, + "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_cidr_function": 0.0017485729995314614, + "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_find_map_function": 2.1093688299997666, + "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_get_azs_function[ap-northeast-1]": 2.1098779439998907, + "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_get_azs_function[ap-southeast-2]": 2.114120818000629, + "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_get_azs_function[eu-central-1]": 2.1094575550000627, + "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_get_azs_function[eu-west-1]": 2.1094290030000593, + "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_get_azs_function[us-east-1]": 2.1008468310001263, + "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_get_azs_function[us-east-2]": 2.1102018399997178, + "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_get_azs_function[us-west-1]": 2.1078975229997923, + "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_get_azs_function[us-west-2]": 2.117389149999781, + "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_join_no_value_construct": 2.104429383000479, + "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_split_length_and_join_functions": 2.149541211000269, + "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_sub_not_ready": 2.117118671999833, + "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_sub_number_type": 2.1029108659995472, + "tests/aws/services/cloudformation/test_template_engine.py::TestIntrinsicFunctions::test_to_json_functions": 0.0017593729999134666, + "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_attribute_uses_macro": 5.716835697000079, + "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_capabilities_requirements": 5.335031079000146, + "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_error_pass_macro_as_reference": 0.02683448799962207, + "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_failed_state[raise_error.py]": 3.6984011519998603, + "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_failed_state[return_invalid_template.py]": 3.6684803939997437, + "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_failed_state[return_unsuccessful_with_message.py]": 3.6563220769999134, + "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_failed_state[return_unsuccessful_without_message.py]": 3.644854991000102, + "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_functions_and_references_during_transformation": 4.715263004999997, + "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_global_scope": 5.108229405000202, + "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_macro_deployment": 3.2337026769996555, + "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_pyplate_param_type_list": 8.747043876000134, + "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_scope_order_and_parameters": 0.0028817279999202583, + "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_snipped_scope[transformation_snippet_topic.json]": 5.737492932000805, + "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_snipped_scope[transformation_snippet_topic.yml]": 5.725411172000349, + "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_to_validate_template_limit_for_macro": 3.7737794500003474, + "tests/aws/services/cloudformation/test_template_engine.py::TestMacros::test_validate_lambda_internals": 5.228773063999597, + "tests/aws/services/cloudformation/test_template_engine.py::TestPreviousValues::test_parameter_usepreviousvalue_behavior": 0.0027805089998764743, + "tests/aws/services/cloudformation/test_template_engine.py::TestPseudoParameters::test_stack_id": 2.101383912000074, + "tests/aws/services/cloudformation/test_template_engine.py::TestSecretsManagerParameters::test_resolve_secretsmanager[resolve_secretsmanager.yaml]": 2.121211303999644, + "tests/aws/services/cloudformation/test_template_engine.py::TestSecretsManagerParameters::test_resolve_secretsmanager[resolve_secretsmanager_full.yaml]": 2.109713499999998, + "tests/aws/services/cloudformation/test_template_engine.py::TestSecretsManagerParameters::test_resolve_secretsmanager[resolve_secretsmanager_partial.yaml]": 2.1189003049994426, + "tests/aws/services/cloudformation/test_template_engine.py::TestSsmParameters::test_create_change_set_with_ssm_parameter_list": 2.1632102419998773, + "tests/aws/services/cloudformation/test_template_engine.py::TestSsmParameters::test_create_stack_with_ssm_parameters": 2.204802065000422, + "tests/aws/services/cloudformation/test_template_engine.py::TestSsmParameters::test_resolve_ssm": 2.145893449000141, + "tests/aws/services/cloudformation/test_template_engine.py::TestSsmParameters::test_resolve_ssm_secure": 2.127330013000119, + "tests/aws/services/cloudformation/test_template_engine.py::TestSsmParameters::test_resolve_ssm_with_version": 2.15171976099964, + "tests/aws/services/cloudformation/test_template_engine.py::TestSsmParameters::test_ssm_nested_with_nested_stack": 6.245040195000001, + "tests/aws/services/cloudformation/test_template_engine.py::TestStackEvents::test_invalid_stack_deploy": 2.379442761000064, + "tests/aws/services/cloudformation/test_template_engine.py::TestTypes::test_implicit_type_conversion": 2.159784585000125, + "tests/aws/services/cloudformation/test_unsupported.py::test_unsupported": 2.0955044559996168, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::TestUpdates::test_deleting_resource": 0.0016436079995401087, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::TestUpdates::test_simple_update_single_resource": 0.0016806759999781207, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::TestUpdates::test_simple_update_two_resources": 0.005109574000016437, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::test_autoexpand_capability_requirement": 0.0016188199997486663, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::test_create_and_then_remove_non_supported_resource_change_set": 0.0016565009996156732, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::test_create_and_then_remove_supported_resource_change_set": 0.001652373999604606, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::test_create_and_then_update_refreshes_template_metadata": 0.0016414919996350363, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::test_create_change_set_create_existing": 0.0016413319999628584, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::test_create_change_set_invalid_params": 0.001593511999999464, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::test_create_change_set_missing_stackname": 0.0016468629996779782, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::test_create_change_set_update_nonexisting": 0.001619502000266948, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::test_create_change_set_update_without_parameters": 0.0016306229999827337, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::test_create_change_set_with_ssm_parameter": 0.0016312440002366202, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::test_create_change_set_without_parameters": 0.0016208950000873301, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::test_create_changeset_with_stack_id": 0.0017564380000294477, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::test_create_delete_create": 0.0016503390002071683, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::test_create_while_in_review": 0.0017575290003151167, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::test_delete_change_set_exception": 0.0016311540002789116, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::test_deleted_changeset": 0.0016403510003328847, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::test_describe_change_set_nonexisting": 0.0016278670004794549, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::test_describe_change_set_with_similarly_named_stacks": 0.0017157510001197807, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::test_empty_changeset": 0.0016451900005449716, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::test_execute_change_set": 0.0016166659997907118, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::test_multiple_create_changeset": 0.0017652229998930125, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_changesets.py::test_name_conflicts": 0.0017495040001449524, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_drift_detection.py::test_drift_detection_on_lambda": 0.001748002000113047, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_extensions_api.py::TestExtensionsApi::test_crud_extension[HOOK-LocalStack::Testing::TestHook-hooks/localstack-testing-testhook.zip]": 0.001644088000375632, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_extensions_api.py::TestExtensionsApi::test_crud_extension[MODULE-LocalStack::Testing::TestModule::MODULE-modules/localstack-testing-testmodule-module.zip]": 0.0016417239999100275, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_extensions_api.py::TestExtensionsApi::test_crud_extension[RESOURCE-LocalStack::Testing::TestResource-resourcetypes/localstack-testing-testresource.zip]": 0.0016371540000363893, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_extensions_api.py::TestExtensionsApi::test_extension_not_complete": 0.0016545779999432852, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_extensions_api.py::TestExtensionsApi::test_extension_type_configuration": 0.0017574489997969067, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_extensions_api.py::TestExtensionsApi::test_extension_versioning": 0.0017937960001290776, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_extensions_hooks.py::TestExtensionsHooks::test_hook_deployment[FAIL]": 0.0017696930003694433, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_extensions_hooks.py::TestExtensionsHooks::test_hook_deployment[WARN]": 0.0017494029998488259, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_extensions_modules.py::TestExtensionsModules::test_module_usage": 0.0016796239997347584, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_extensions_resourcetypes.py::TestExtensionsResourceTypes::test_deploy_resource_type": 0.001684413000020868, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_nested_stacks.py::test_deletion_of_failed_nested_stack": 0.0017465179998907843, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_nested_stacks.py::test_lifecycle_nested_stack": 0.0016546570000173233, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_nested_stacks.py::test_nested_output_in_params": 0.0017718059998514946, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_nested_stacks.py::test_nested_stack": 0.0018052189998343238, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_nested_stacks.py::test_nested_stack_output_refs": 0.0017293359996983781, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_nested_stacks.py::test_nested_stacks_conditions": 0.0017429420004191343, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_nested_stacks.py::test_nested_with_nested_stack": 0.0016247410003416007, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_reference_resolving.py::test_nested_getatt_ref[TopicArn]": 0.0016646360004415328, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_reference_resolving.py::test_nested_getatt_ref[TopicName]": 0.0016290489998027624, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_reference_resolving.py::test_reference_unsupported_resource": 0.0016276070000458276, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_reference_resolving.py::test_sub_resolving": 0.0016677620001246396, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stack_policies.py::TestStackPolicy::test_create_stack_with_policy": 0.0016686740000295686, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stack_policies.py::TestStackPolicy::test_different_action_attribute": 0.0017659849995652621, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stack_policies.py::TestStackPolicy::test_different_principal_attribute": 0.0017279339999731747, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stack_policies.py::TestStackPolicy::test_empty_policy": 0.0019371939997654408, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stack_policies.py::TestStackPolicy::test_not_json_policy": 0.0017283150004914205, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stack_policies.py::TestStackPolicy::test_policy_during_update": 0.0017640020000726508, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stack_policies.py::TestStackPolicy::test_policy_lifecycle": 0.0016636840000501252, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stack_policies.py::TestStackPolicy::test_prevent_deletion[resource0]": 0.0017422020000594785, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stack_policies.py::TestStackPolicy::test_prevent_deletion[resource1]": 0.0017512570002509165, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stack_policies.py::TestStackPolicy::test_prevent_modifying_with_policy_specifying_resource_id": 0.0017640820001361135, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stack_policies.py::TestStackPolicy::test_prevent_replacement": 0.0017687600002318504, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stack_policies.py::TestStackPolicy::test_prevent_resource_deletion": 0.0017354779997731384, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stack_policies.py::TestStackPolicy::test_prevent_stack_update": 0.0018170009998357273, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stack_policies.py::TestStackPolicy::test_prevent_update[AWS::S3::Bucket]": 0.0016087609997157415, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stack_policies.py::TestStackPolicy::test_prevent_update[AWS::SNS::Topic]": 0.0017301279995081131, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stack_policies.py::TestStackPolicy::test_set_empty_policy_with_url": 0.0017850609997367428, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stack_policies.py::TestStackPolicy::test_set_invalid_policy_with_url": 0.0016731719997551409, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stack_policies.py::TestStackPolicy::test_set_policy_both_policy_and_url": 0.0016224070000134816, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stack_policies.py::TestStackPolicy::test_set_policy_with_update_operation": 0.0016060070001913118, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stack_policies.py::TestStackPolicy::test_set_policy_with_url": 0.0017561569998179039, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stack_policies.py::TestStackPolicy::test_update_with_empty_policy": 0.0015995650001059403, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stack_policies.py::TestStackPolicy::test_update_with_overlapping_policies[False]": 0.0015853690001677023, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stack_policies.py::TestStackPolicy::test_update_with_overlapping_policies[True]": 0.0017521880004096602, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stack_policies.py::TestStackPolicy::test_update_with_policy": 0.0015900769999461772, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::TestStacksApi::test_create_stack_with_custom_id": 0.001624060000267491, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::TestStacksApi::test_failure_options_for_stack_creation[False-0]": 0.0016327879998243588, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::TestStacksApi::test_failure_options_for_stack_creation[True-1]": 0.0016017489997466328, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::TestStacksApi::test_failure_options_for_stack_update[False-2]": 0.001631543999792484, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::TestStacksApi::test_failure_options_for_stack_update[True-1]": 0.001627395999548753, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::TestStacksApi::test_get_template_using_changesets[json]": 0.0016530839998267766, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::TestStacksApi::test_get_template_using_changesets[yaml]": 0.0016545480002605473, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::TestStacksApi::test_get_template_using_create_stack[json]": 0.00199678600029074, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::TestStacksApi::test_get_template_using_create_stack[yaml]": 0.0017597640003259585, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::TestStacksApi::test_list_events_after_deployment": 0.001648235000175191, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::TestStacksApi::test_list_stack_resources_for_removed_resource": 0.0016603469994151965, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::TestStacksApi::test_stack_description_special_chars": 0.0017242069998246734, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::TestStacksApi::test_stack_lifecycle": 0.001756897999712237, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::TestStacksApi::test_stack_name_creation": 0.0017784789997676853, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::TestStacksApi::test_stack_update_resources": 0.0017301279999628605, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::TestStacksApi::test_update_stack_actual_update": 0.0016286690001834359, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::TestStacksApi::test_update_stack_with_same_template_withoutchange": 0.001662332000250899, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::TestStacksApi::test_update_stack_with_same_template_withoutchange_transformation": 0.0016494670003339706, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::test_blocked_stack_deletion": 0.0016783219998615095, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::test_describe_stack_events_errors": 0.0016208549996008514, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::test_events_resource_types": 0.0016068479999375995, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::test_linting_error_during_creation": 0.0016175690002455667, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::test_list_parameter_type": 0.0016409909999310912, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::test_name_conflicts": 0.0017613670001992432, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::test_no_echo_parameter": 0.0016160549998858187, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::test_notifications": 0.0016484960001434956, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::test_stack_deploy_order[A-B-C]": 0.0016883089997463685, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::test_stack_deploy_order[A-C-B]": 0.0016689740000401798, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::test_stack_deploy_order[B-A-C]": 0.001686827999947127, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::test_stack_deploy_order[B-C-A]": 0.001681748000009975, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::test_stack_deploy_order[C-A-B]": 0.0016266860002360772, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::test_stack_deploy_order[C-B-A]": 0.001633467999909044, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::test_stack_resource_not_found": 0.0016304730002048018, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::test_update_termination_protection": 0.0017768459997569153, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_stacks.py::test_updating_an_updated_stack_sets_status": 0.0016685830005371827, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_templates.py::test_create_stack_from_s3_template_url[http_host]": 0.0016289190002680698, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_templates.py::test_create_stack_from_s3_template_url[http_invalid]": 0.0016554490002818056, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_templates.py::test_create_stack_from_s3_template_url[http_path]": 0.0016753360000620887, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_templates.py::test_create_stack_from_s3_template_url[s3_url]": 0.0016566209997108672, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_templates.py::test_get_template_summary": 0.0018978909997713345, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_templates.py::test_validate_invalid_json_template_should_fail": 0.0016243019999819808, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_templates.py::test_validate_template": 0.0016583639999225852, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_transformers.py::test_duplicate_resources": 0.0016694750001988723, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_transformers.py::test_transformer_individual_resource_level": 0.0016941819999374275, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_transformers.py::test_transformer_property_level": 0.0017674680002528476, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_update_stack.py::test_basic_update": 0.00167597600056979, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_update_stack.py::test_diff_after_update": 0.0016119480001179909, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_update_stack.py::test_no_parameters_update": 0.001651189999847702, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_update_stack.py::test_no_template_error": 0.001718225999866263, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_update_stack.py::test_set_notification_arn_with_update": 0.0016009070000109205, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_update_stack.py::test_update_tags": 0.0016295909999826108, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_update_stack.py::test_update_using_template_url": 0.001724577999993926, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_update_stack.py::test_update_with_capabilities[capability0]": 0.0017580909998287098, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_update_stack.py::test_update_with_capabilities[capability1]": 0.0016339490002792445, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_update_stack.py::test_update_with_invalid_rollback_configuration_errors": 0.0016426849997515092, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_update_stack.py::test_update_with_previous_parameter_value": 0.0016693559996383556, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_update_stack.py::test_update_with_previous_template": 0.0017026280002028216, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_update_stack.py::test_update_with_resource_types": 0.0016581539998696826, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_update_stack.py::test_update_with_role_without_permissions": 0.0016619219995845924, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_update_stack.py::test_update_with_rollback_configuration": 0.0017728779998833488, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_validations.py::test_invalid_output_structure[missing-def]": 0.0017739099998834718, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_validations.py::test_invalid_output_structure[multiple-nones]": 0.0017580600001565472, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_validations.py::test_invalid_output_structure[none-value]": 0.0016242310002780869, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_validations.py::test_missing_resources_block": 0.0018715720002546732, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_validations.py::test_resources_blocks[invalid-key]": 0.0016364230000363023, + "tests/aws/services/cloudformation/v2/ported_from_v1/api/test_validations.py::test_resources_blocks[missing-type]": 0.0015980620000846102, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_attributes.py::TestResourceAttributes::test_dependency_on_attribute_with_dot_notation": 0.0016240200002357597, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_attributes.py::TestResourceAttributes::test_invalid_getatt_fails": 0.0016274969998448796, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_conditions.py::TestCloudFormationConditions::test_condition_on_outputs": 0.0016717389999030274, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_conditions.py::TestCloudFormationConditions::test_conditional_att_to_conditional_resources[create]": 0.0016421639998043247, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_conditions.py::TestCloudFormationConditions::test_conditional_att_to_conditional_resources[no-create]": 0.0019673000001603214, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_conditions.py::TestCloudFormationConditions::test_conditional_in_conditional[dev-us-west-2]": 0.0016471230001116055, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_conditions.py::TestCloudFormationConditions::test_conditional_in_conditional[production-us-east-1]": 0.0016519020000487217, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_conditions.py::TestCloudFormationConditions::test_conditional_with_select": 0.0016791529997135513, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_conditions.py::TestCloudFormationConditions::test_dependency_in_non_evaluated_if_branch[None-FallbackParamValue]": 0.0016691129999344412, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_conditions.py::TestCloudFormationConditions::test_dependency_in_non_evaluated_if_branch[false-DefaultParamValue]": 0.001626235000003362, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_conditions.py::TestCloudFormationConditions::test_dependent_ref": 0.0017997889999605832, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_conditions.py::TestCloudFormationConditions::test_dependent_ref_intrinsic_fn_condition": 0.0017787789997782966, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_conditions.py::TestCloudFormationConditions::test_dependent_ref_with_macro": 0.0016491169999426347, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_conditions.py::TestCloudFormationConditions::test_nested_conditions[prod-bucket-policy]": 0.0018057780002891377, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_conditions.py::TestCloudFormationConditions::test_nested_conditions[prod-nobucket-nopolicy]": 0.0017923739997058874, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_conditions.py::TestCloudFormationConditions::test_nested_conditions[test-bucket-nopolicy]": 0.001670096999987436, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_conditions.py::TestCloudFormationConditions::test_nested_conditions[test-nobucket-nopolicy]": 0.0017514480000500043, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_conditions.py::TestCloudFormationConditions::test_output_reference_to_skipped_resource": 0.0017974840006900195, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_conditions.py::TestCloudFormationConditions::test_simple_condition_evaluation_deploys_resource": 0.0016258339996966242, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_conditions.py::TestCloudFormationConditions::test_simple_condition_evaluation_doesnt_deploy_resource": 0.0015951569998833293, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_conditions.py::TestCloudFormationConditions::test_simple_intrinsic_fn_condition_evaluation[nope]": 0.0016185300000870484, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_conditions.py::TestCloudFormationConditions::test_simple_intrinsic_fn_condition_evaluation[yep]": 0.001638086000639305, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_conditions.py::TestCloudFormationConditions::test_sub_in_conditions": 0.0016341180003109912, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_conditions.py::TestCloudFormationConditions::test_update_conditions": 0.0016525430000911001, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_mappings.py::TestCloudFormationMappings::test_async_mapping_error_first_level": 0.0017788790000849986, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_mappings.py::TestCloudFormationMappings::test_async_mapping_error_second_level": 0.0016696560001037142, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_mappings.py::TestCloudFormationMappings::test_aws_refs_in_mappings": 0.0017633499996918545, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_mappings.py::TestCloudFormationMappings::test_mapping_maximum_nesting_depth": 0.0016652180001983652, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_mappings.py::TestCloudFormationMappings::test_mapping_minimum_nesting_depth": 0.001674385000114853, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_mappings.py::TestCloudFormationMappings::test_mapping_ref_map_key[should-deploy]": 0.0016289700001834717, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_mappings.py::TestCloudFormationMappings::test_mapping_ref_map_key[should-not-deploy]": 0.001620164000087243, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_mappings.py::TestCloudFormationMappings::test_mapping_with_invalid_refs": 0.0016831400002956798, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_mappings.py::TestCloudFormationMappings::test_mapping_with_nonexisting_key": 0.003545655999914743, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_mappings.py::TestCloudFormationMappings::test_simple_mapping_working": 0.0017354679998788924, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_references.py::TestDependsOn::test_depends_on_with_missing_reference": 0.0016682930004208174, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_references.py::TestFnSub::test_fn_sub_cases": 0.0018119209998985752, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_references.py::TestFnSub::test_non_string_parameter_in_sub": 0.0016764389997661056, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_references.py::test_resolve_transitive_placeholders_in_strings": 0.0018164699999942968, + "tests/aws/services/cloudformation/v2/ported_from_v1/engine/test_references.py::test_useful_error_when_invalid_ref": 0.0028951419999430072, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_acm.py::test_cfn_acm_certificate": 0.0017077959996640857, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::TestServerlessApigwLambda::test_serverless_like_deployment_with_update": 0.0018278299999110459, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::test_account": 0.0017173050000565127, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::test_api_gateway_with_policy_as_dict": 0.0018886540001403773, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::test_cfn_apigateway_aws_integration": 0.0016700059995855554, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::test_cfn_apigateway_rest_api": 0.0017587820002518129, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::test_cfn_apigateway_swagger_import": 0.001627647000077559, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::test_cfn_deploy_apigateway_from_s3_swagger": 0.0021194540004216833, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::test_cfn_deploy_apigateway_integration": 0.0016570920001868217, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::test_cfn_deploy_apigateway_models": 0.0016655189997436537, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::test_cfn_with_apigateway_resources": 0.0016802759996608074, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::test_rest_api_serverless_ref_resolving": 0.0018225210001219239, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::test_update_apigateway_stage": 0.0017268930000682303, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::test_update_usage_plan": 0.0017315209997832426, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_apigateway.py::test_url_output": 0.001767900000231748, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_cdk.py::TestCdkInit::test_cdk_bootstrap[10]": 0.0017862319996311271, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_cdk.py::TestCdkInit::test_cdk_bootstrap[11]": 0.0017202590001943463, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_cdk.py::TestCdkInit::test_cdk_bootstrap[12]": 0.0017244279997612466, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_cdk.py::TestCdkInit::test_cdk_bootstrap_redeploy": 0.0017156009998871014, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_cdk.py::TestCdkSampleApp::test_cdk_sample": 0.0019265750001977722, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_cloudformation.py::test_create_macro": 0.0017064639996533515, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_cloudformation.py::test_waitcondition": 0.0017140189997917332, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_cloudwatch.py::test_alarm_creation": 0.0017622780001147476, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_cloudwatch.py::test_alarm_ext_statistic": 0.0017479509997428977, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_cloudwatch.py::test_composite_alarm_creation": 0.001629061000130605, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_dynamodb.py::test_billing_mode_as_conditional[PAY_PER_REQUEST]": 0.0016638339998280571, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_dynamodb.py::test_billing_mode_as_conditional[PROVISIONED]": 0.0016758269998717878, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_dynamodb.py::test_default_name_for_table": 0.0016689650001353584, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_dynamodb.py::test_deploy_stack_with_dynamodb_table": 0.0017121340001722274, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_dynamodb.py::test_global_table": 0.0016793539998616325, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_dynamodb.py::test_global_table_with_ttl_and_sse": 0.0016174590000446187, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_dynamodb.py::test_globalindex_read_write_provisioned_throughput_dynamodb_table": 0.0016123290001814894, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_dynamodb.py::test_table_with_ttl_and_sse": 0.0016396690002693504, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_dynamodb.py::test_ttl_cdk": 0.0016302010003528267, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ec2.py::test_cfn_update_ec2_instance_type": 0.0016275470002256043, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ec2.py::test_cfn_with_multiple_route_table_associations": 0.0017505659998278134, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ec2.py::test_cfn_with_multiple_route_tables": 0.0016215959994951845, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ec2.py::test_dhcp_options": 0.001751388000229781, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ec2.py::test_ec2_security_group_id_with_vpc": 0.0017804520002755453, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ec2.py::test_internet_gateway_ref_and_attr": 0.0016193109995583654, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ec2.py::test_keypair_create_import": 0.0020057930000803026, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ec2.py::test_simple_route_table_creation": 0.001735799000471161, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ec2.py::test_simple_route_table_creation_without_vpc": 0.0017916629999490397, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ec2.py::test_transit_gateway_attachment": 0.0015995339999790303, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ec2.py::test_vpc_creates_default_sg": 0.001612149000266072, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ec2.py::test_vpc_with_route_table": 0.001828812999974616, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_elasticsearch.py::test_cfn_handle_elasticsearch_domain": 0.0016946920000009413, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_events.py::test_cfn_event_api_destination_resource": 0.0016337370002474927, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_events.py::test_cfn_event_bus_resource": 0.001702586000192241, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_events.py::test_event_rule_creation_without_target": 0.0018025539998234308, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_events.py::test_event_rule_to_logs": 0.001757029999680526, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_events.py::test_eventbus_policies": 0.0016267259998130612, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_events.py::test_eventbus_policy_statement": 0.0017364899999847694, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_events.py::test_rule_pattern_transformation": 0.0016314149997924687, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_events.py::test_rule_properties": 0.00176462299987179, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_firehose.py::test_firehose_stack_with_kinesis_as_source": 0.001606167999398167, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_integration.py::test_events_sqs_sns_lambda": 0.001566022000133671, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_kinesis.py::test_cfn_handle_kinesis_firehose_resources": 0.0017862710001281812, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_kinesis.py::test_default_parameters_kinesis": 0.0017126660000030824, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_kinesis.py::test_describe_template": 0.0018704400004025956, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_kinesis.py::test_dynamodb_stream_response_with_cf": 0.0016874680004548281, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_kinesis.py::test_kinesis_stream_consumer_creations": 0.0016350410000995907, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_kinesis.py::test_stream_creation": 0.0019133390001115913, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_kms.py::test_cfn_with_kms_resources": 0.0018566740000096615, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_kms.py::test_deploy_stack_with_kms": 0.001815087999602838, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_kms.py::test_kms_key_disabled": 0.0016707170002518978, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::TestCfnLambdaDestinations::test_generic_destination_routing[sqs-sqs]": 0.0025330809999672965, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::TestCfnLambdaIntegrations::test_cfn_lambda_dynamodb_source": 0.0015493190000483992, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::TestCfnLambdaIntegrations::test_cfn_lambda_kinesis_source": 0.001539922000063143, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::TestCfnLambdaIntegrations::test_cfn_lambda_permissions": 0.0016289580000261594, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::TestCfnLambdaIntegrations::test_cfn_lambda_sqs_source": 0.003112956000052236, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::TestCfnLambdaIntegrations::test_lambda_dynamodb_event_filter": 0.0015304249999985586, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::test_cfn_function_url": 0.01138009500004955, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::test_event_invoke_config": 0.003715923999948245, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::test_lambda_alias": 0.0016713270000536795, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::test_lambda_cfn_dead_letter_config_async_invocation": 0.001723445000038737, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::test_lambda_cfn_run": 0.0016060360000551555, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::test_lambda_cfn_run_with_empty_string_replacement_deny_list": 0.001656991000004382, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::test_lambda_cfn_run_with_non_empty_string_replacement_deny_list": 0.0017497139999704814, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::test_lambda_code_signing_config": 0.0015111169999499907, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::test_lambda_function_tags": 0.0015855780000038067, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::test_lambda_layer_crud": 0.001987971000005473, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::test_lambda_logging_config": 0.0016151720000152636, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::test_lambda_version": 0.0015750979999893389, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::test_lambda_version_provisioned_concurrency": 0.0015330680000147368, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::test_lambda_vpc": 0.003631136000024071, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::test_lambda_w_dynamodb_event_filter": 0.0017889669993564894, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::test_lambda_w_dynamodb_event_filter_update": 0.0016179989997908706, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::test_multiple_lambda_permissions_for_singlefn": 0.001625232000037613, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::test_python_lambda_code_deployed_via_s3": 0.0016671900000346795, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::test_update_lambda_function": 0.0016403310000896454, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::test_update_lambda_function_name": 0.529567550000138, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_lambda.py::test_update_lambda_permissions": 0.0016282659999546922, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_logs.py::test_cfn_handle_log_group_resource": 0.0021754310000119403, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_logs.py::test_logstream": 0.004745299999967756, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_opensearch.py::test_domain": 0.0021074450000355682, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_opensearch.py::test_domain_with_alternative_types": 0.002140004000011686, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_redshift.py::test_redshift_cluster": 0.002166423999995004, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_resource_groups.py::test_group_defaults": 0.002310204000025351, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_route53.py::test_create_health_check": 0.0022860280000145394, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_route53.py::test_create_record_set_via_id": 0.002121520999992299, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_route53.py::test_create_record_set_via_name": 0.0024993890000359897, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_route53.py::test_create_record_set_without_resource_record": 0.002504446999978427, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_s3.py::test_bucket_autoname": 0.002284765000013067, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_s3.py::test_bucket_versioning": 0.0021353869999529707, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_s3.py::test_bucketpolicy": 0.0021014729999819792, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_s3.py::test_cfn_handle_s3_notification_configuration": 0.0027615070000592823, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_s3.py::test_cors_configuration": 0.002125296999963666, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_s3.py::test_object_lock_configuration": 0.002256462999980613, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_s3.py::test_website_configuration": 0.002138741999999638, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sam.py::test_cfn_handle_serverless_api_resource": 0.002171684000074947, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sam.py::test_sam_policies": 0.0023198110000066663, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sam.py::test_sam_sqs_event": 0.002141877999974895, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sam.py::test_sam_template": 0.002115687000014077, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_secretsmanager.py::test_cdk_deployment_generates_secret_value_if_no_value_is_provided": 0.0024656530000015664, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_secretsmanager.py::test_cfn_handle_secretsmanager_secret": 0.0020879880000279627, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_secretsmanager.py::test_cfn_secret_policy[default]": 0.002318048999995881, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_secretsmanager.py::test_cfn_secret_policy[true]": 0.002394752000043354, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_secretsmanager.py::test_cfn_secretsmanager_gen_secret": 0.002242847999980313, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sns.py::test_deploy_stack_with_sns_topic": 0.0021381419999784157, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sns.py::test_sns_subscription": 0.002330551000000014, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sns.py::test_sns_topic_fifo_with_deduplication": 0.0023486050000087744, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sns.py::test_sns_topic_fifo_without_suffix_fails": 0.0023749429999497806, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sns.py::test_sns_topic_with_attributes": 0.002230864000011934, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sns.py::test_update_subscription": 0.002284073999987868, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sqs.py::test_cfn_handle_sqs_resource": 0.002103777000002083, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sqs.py::test_sqs_fifo_queue_generates_valid_name": 0.0020298080000316077, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sqs.py::test_sqs_non_fifo_queue_generates_valid_name": 0.0022614110000063192, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sqs.py::test_sqs_queue_policy": 0.0021520669999404163, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sqs.py::test_update_queue_no_change": 0.0023740120000184106, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_sqs.py::test_update_sqs_queuepolicy": 0.002209774999982983, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ssm.py::test_deploy_patch_baseline": 0.0021358469999768204, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ssm.py::test_maintenance_window": 0.0022475360000271394, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ssm.py::test_parameter_defaults": 0.002671920000011596, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ssm.py::test_update_ssm_parameter_tag": 0.0021047589999625416, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_ssm.py::test_update_ssm_parameters": 0.0022894950000136305, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_stack_sets.py::test_create_stack_set_with_stack_instances": 0.013600381999935962, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_stepfunctions.py::test_apigateway_invoke": 17.98715811900007, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_stepfunctions.py::test_apigateway_invoke_localhost": 9.580212721999999, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_stepfunctions.py::test_apigateway_invoke_localhost_with_path": 15.68548258699991, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_stepfunctions.py::test_apigateway_invoke_with_path": 15.673944400999972, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_stepfunctions.py::test_cfn_statemachine_default_s3_location": 4.875009530999932, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_stepfunctions.py::test_cfn_statemachine_with_dependencies": 2.195825787999979, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_stepfunctions.py::test_nested_statemachine_with_sync2": 0.003904376000036791, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_stepfunctions.py::test_retry_and_catch": 0.002589405000037459, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_stepfunctions.py::test_statemachine_create_with_logging_configuration": 2.6756209350000404, + "tests/aws/services/cloudformation/v2/ported_from_v1/resources/test_stepfunctions.py::test_statemachine_definitionsubstitution": 25.80093697199993, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestImportValues::test_cfn_with_exports": 0.001747738999995363, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestImportValues::test_import_values_across_stacks": 0.0017517780000275707, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestImports::test_stack_imports": 0.001825404999976854, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestIntrinsicFunctions::test_and_or_functions[Fn::And-0-0-False]": 0.0016935469999452835, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestIntrinsicFunctions::test_and_or_functions[Fn::And-0-1-False]": 0.0017379409999875861, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestIntrinsicFunctions::test_and_or_functions[Fn::And-1-0-False]": 0.0018777219999606132, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestIntrinsicFunctions::test_and_or_functions[Fn::And-1-1-True]": 0.0019094319999908294, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestIntrinsicFunctions::test_and_or_functions[Fn::Or-0-0-False]": 0.0018225980000465825, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestIntrinsicFunctions::test_and_or_functions[Fn::Or-0-1-True]": 0.0018449309999937213, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestIntrinsicFunctions::test_and_or_functions[Fn::Or-1-0-True]": 0.0016980959999841616, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestIntrinsicFunctions::test_and_or_functions[Fn::Or-1-1-True]": 0.0020529600000145365, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestIntrinsicFunctions::test_base64_sub_and_getatt_functions": 0.0017432810000741483, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestIntrinsicFunctions::test_cfn_template_with_short_form_fn_sub": 0.0017460350000533253, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestIntrinsicFunctions::test_cidr_function": 0.001730376999944383, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestIntrinsicFunctions::test_find_map_function": 0.0017411879999826851, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestIntrinsicFunctions::test_get_azs_function[ap-northeast-1]": 0.0017477600000006532, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestIntrinsicFunctions::test_get_azs_function[ap-southeast-2]": 0.0017545210000662337, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestIntrinsicFunctions::test_get_azs_function[eu-central-1]": 0.0017292640000050596, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestIntrinsicFunctions::test_get_azs_function[eu-west-1]": 0.0018406919999733873, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestIntrinsicFunctions::test_get_azs_function[us-east-1]": 0.0017496329999744376, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestIntrinsicFunctions::test_get_azs_function[us-east-2]": 0.0017750100000171187, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestIntrinsicFunctions::test_get_azs_function[us-west-1]": 0.0017341019999435048, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestIntrinsicFunctions::test_get_azs_function[us-west-2]": 0.00176067300003524, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestIntrinsicFunctions::test_join_no_value_construct": 0.001855902000045262, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestIntrinsicFunctions::test_split_length_and_join_functions": 0.0017259179999769003, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestIntrinsicFunctions::test_sub_not_ready": 0.001864818000001378, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestIntrinsicFunctions::test_sub_number_type": 0.0017265690000272116, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestIntrinsicFunctions::test_to_json_functions": 0.0017133240000362093, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestMacros::test_attribute_uses_macro": 0.0017536999999947511, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestMacros::test_capabilities_requirements": 0.0017729570000142303, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestMacros::test_error_pass_macro_as_reference": 0.0018402409999680458, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestMacros::test_failed_state[raise_error.py]": 0.0017383509999717717, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestMacros::test_failed_state[return_invalid_template.py]": 0.001761994999981198, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestMacros::test_failed_state[return_unsuccessful_with_message.py]": 0.0017579770000111239, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestMacros::test_failed_state[return_unsuccessful_without_message.py]": 0.0019004440000003342, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestMacros::test_functions_and_references_during_transformation": 0.0017357760000322742, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestMacros::test_global_scope": 0.0018335600000227714, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestMacros::test_macro_deployment": 0.0017561240000532052, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestMacros::test_pyplate_param_type_list": 0.0017364580000389651, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestMacros::test_scope_order_and_parameters": 0.0017298949999826618, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestMacros::test_snipped_scope[transformation_snippet_topic.json]": 0.0017667559999949844, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestMacros::test_snipped_scope[transformation_snippet_topic.yml]": 0.0018593589999795768, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestMacros::test_to_validate_template_limit_for_macro": 0.0018570640000348249, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestMacros::test_validate_lambda_internals": 0.0017534390000264466, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestPreviousValues::test_parameter_usepreviousvalue_behavior": 0.0017534400000158712, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestPseudoParameters::test_stack_id": 0.0017643090000660777, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestSecretsManagerParameters::test_resolve_secretsmanager[resolve_secretsmanager.yaml]": 0.0017258679999940796, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestSecretsManagerParameters::test_resolve_secretsmanager[resolve_secretsmanager_full.yaml]": 0.0018618920000221806, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestSecretsManagerParameters::test_resolve_secretsmanager[resolve_secretsmanager_partial.yaml]": 0.0019373250000285225, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestSsmParameters::test_create_change_set_with_ssm_parameter_list": 0.0017353650000018206, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestSsmParameters::test_create_stack_with_ssm_parameters": 0.001787903999968421, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestSsmParameters::test_resolve_ssm": 0.0018592070000522654, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestSsmParameters::test_resolve_ssm_secure": 0.0018874599999776365, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestSsmParameters::test_resolve_ssm_with_version": 0.0017080949999694894, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestSsmParameters::test_ssm_nested_with_nested_stack": 0.0018454820000215477, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestStackEvents::test_invalid_stack_deploy": 0.0017768330000080823, + "tests/aws/services/cloudformation/v2/ported_from_v1/test_template_engine.py::TestTypes::test_implicit_type_conversion": 0.002130505000025096, + "tests/aws/services/cloudformation/v2/test_change_set_conditions.py::TestChangeSetConditions::test_condition_add_new_negative_condition_to_existent_resource": 0.0017518160000236094, + "tests/aws/services/cloudformation/v2/test_change_set_conditions.py::TestChangeSetConditions::test_condition_add_new_positive_condition_to_existent_resource": 0.0017818119999901683, + "tests/aws/services/cloudformation/v2/test_change_set_conditions.py::TestChangeSetConditions::test_condition_update_adds_resource": 0.0017503430000260778, + "tests/aws/services/cloudformation/v2/test_change_set_conditions.py::TestChangeSetConditions::test_condition_update_removes_resource": 0.0017348450000440607, + "tests/aws/services/cloudformation/v2/test_change_set_depends_on.py::TestChangeSetDependsOn::test_multiple_dependencies_addition": 0.0017581189999873459, + "tests/aws/services/cloudformation/v2/test_change_set_depends_on.py::TestChangeSetDependsOn::test_multiple_dependencies_deletion": 0.0019309709999788538, + "tests/aws/services/cloudformation/v2/test_change_set_depends_on.py::TestChangeSetDependsOn::test_update_depended_resource": 0.0017539689999921393, + "tests/aws/services/cloudformation/v2/test_change_set_depends_on.py::TestChangeSetDependsOn::test_update_depended_resource_list": 0.0017799690000401824, + "tests/aws/services/cloudformation/v2/test_change_set_fn_base64.py::TestChangeSetFnBase64::test_fn_base64_add_to_static_property": 0.0019207219999657354, + "tests/aws/services/cloudformation/v2/test_change_set_fn_base64.py::TestChangeSetFnBase64::test_fn_base64_change_input_string": 0.0017671549999818126, + "tests/aws/services/cloudformation/v2/test_change_set_fn_base64.py::TestChangeSetFnBase64::test_fn_base64_remove_from_static_property": 0.001954013999977633, + "tests/aws/services/cloudformation/v2/test_change_set_fn_get_attr.py::TestChangeSetFnGetAttr::test_direct_attribute_value_change": 0.0017296139999984916, + "tests/aws/services/cloudformation/v2/test_change_set_fn_get_attr.py::TestChangeSetFnGetAttr::test_direct_attribute_value_change_in_get_attr_chain": 0.0017518959999733852, + "tests/aws/services/cloudformation/v2/test_change_set_fn_get_attr.py::TestChangeSetFnGetAttr::test_direct_attribute_value_change_with_dependent_addition": 0.0017672049999646333, + "tests/aws/services/cloudformation/v2/test_change_set_fn_get_attr.py::TestChangeSetFnGetAttr::test_immutable_property_update_causes_resource_replacement": 0.0017357460000084757, + "tests/aws/services/cloudformation/v2/test_change_set_fn_get_attr.py::TestChangeSetFnGetAttr::test_resource_addition": 0.0017150069999729567, + "tests/aws/services/cloudformation/v2/test_change_set_fn_get_attr.py::TestChangeSetFnGetAttr::test_resource_deletion": 0.0017499019999718257, + "tests/aws/services/cloudformation/v2/test_change_set_fn_join.py::TestChangeSetFnJoin::test_indirect_update_refence_argument": 0.0019305600000052436, + "tests/aws/services/cloudformation/v2/test_change_set_fn_join.py::TestChangeSetFnJoin::test_update_refence_argument": 0.0017452540000135741, + "tests/aws/services/cloudformation/v2/test_change_set_fn_join.py::TestChangeSetFnJoin::test_update_string_literal_argument": 0.001749462000020685, + "tests/aws/services/cloudformation/v2/test_change_set_fn_join.py::TestChangeSetFnJoin::test_update_string_literal_arguments_empty": 0.0016918940000323346, + "tests/aws/services/cloudformation/v2/test_change_set_fn_join.py::TestChangeSetFnJoin::test_update_string_literal_delimiter": 0.001756053999940832, + "tests/aws/services/cloudformation/v2/test_change_set_fn_join.py::TestChangeSetFnJoin::test_update_string_literal_delimiter_empty": 0.001707534000047417, + "tests/aws/services/cloudformation/v2/test_change_set_fn_select.py::TestChangeSetFnSelect::test_fn_select_add_to_static_property": 0.0017383800000061456, + "tests/aws/services/cloudformation/v2/test_change_set_fn_select.py::TestChangeSetFnSelect::test_fn_select_change_get_att_reference": 0.0017709819999822685, + "tests/aws/services/cloudformation/v2/test_change_set_fn_select.py::TestChangeSetFnSelect::test_fn_select_change_in_selected_element_type_ref": 0.001773646999936318, + "tests/aws/services/cloudformation/v2/test_change_set_fn_select.py::TestChangeSetFnSelect::test_fn_select_change_in_selection_index_only": 0.0018607099999599086, + "tests/aws/services/cloudformation/v2/test_change_set_fn_select.py::TestChangeSetFnSelect::test_fn_select_change_in_selection_list": 0.001760453000031248, + "tests/aws/services/cloudformation/v2/test_change_set_fn_select.py::TestChangeSetFnSelect::test_fn_select_remove_from_static_property": 0.001751775999991878, + "tests/aws/services/cloudformation/v2/test_change_set_fn_split.py::TestChangeSetFnSplit::test_fn_split_add_to_static_property": 0.002008836999948471, + "tests/aws/services/cloudformation/v2/test_change_set_fn_split.py::TestChangeSetFnSplit::test_fn_split_change_delimiter": 0.001863685000046189, + "tests/aws/services/cloudformation/v2/test_change_set_fn_split.py::TestChangeSetFnSplit::test_fn_split_change_source_string_only": 0.0017426800000066578, + "tests/aws/services/cloudformation/v2/test_change_set_fn_split.py::TestChangeSetFnSplit::test_fn_split_remove_from_static_property": 0.0017424999999775537, + "tests/aws/services/cloudformation/v2/test_change_set_fn_split.py::TestChangeSetFnSplit::test_fn_split_with_get_att": 0.0017369779999398816, + "tests/aws/services/cloudformation/v2/test_change_set_fn_split.py::TestChangeSetFnSplit::test_fn_split_with_ref_as_string_source": 0.0017355160000533942, + "tests/aws/services/cloudformation/v2/test_change_set_fn_sub.py::TestChangeSetFnSub::test_fn_sub_addition_parameter": 0.0017957380000552803, + "tests/aws/services/cloudformation/v2/test_change_set_fn_sub.py::TestChangeSetFnSub::test_fn_sub_addition_parameter_literal": 0.0017542200000093544, + "tests/aws/services/cloudformation/v2/test_change_set_fn_sub.py::TestChangeSetFnSub::test_fn_sub_addition_parameter_ref": 0.001748069999962354, + "tests/aws/services/cloudformation/v2/test_change_set_fn_sub.py::TestChangeSetFnSub::test_fn_sub_addition_string_pseudo": 0.0017076430000315668, + "tests/aws/services/cloudformation/v2/test_change_set_fn_sub.py::TestChangeSetFnSub::test_fn_sub_delete_parameter_literal": 0.001781191000020499, + "tests/aws/services/cloudformation/v2/test_change_set_fn_sub.py::TestChangeSetFnSub::test_fn_sub_delete_string_pseudo": 0.0018761679999670378, + "tests/aws/services/cloudformation/v2/test_change_set_fn_sub.py::TestChangeSetFnSub::test_fn_sub_update_parameter_literal": 0.0017480200000363766, + "tests/aws/services/cloudformation/v2/test_change_set_fn_sub.py::TestChangeSetFnSub::test_fn_sub_update_parameter_type": 0.0017233329999726266, + "tests/aws/services/cloudformation/v2/test_change_set_fn_sub.py::TestChangeSetFnSub::test_fn_sub_update_string_pseudo": 0.001731979999988198, + "tests/aws/services/cloudformation/v2/test_change_set_global_macros.py::TestChangeSetGlobalMacros::test_base_global_macro": 0.001956167999992431, + "tests/aws/services/cloudformation/v2/test_change_set_mappings.py::TestChangeSetMappings::test_mapping_addition_with_resource": 0.0017298949999826618, + "tests/aws/services/cloudformation/v2/test_change_set_mappings.py::TestChangeSetMappings::test_mapping_deletion_with_resource_remap": 0.001763207000010425, + "tests/aws/services/cloudformation/v2/test_change_set_mappings.py::TestChangeSetMappings::test_mapping_key_addition_with_resource": 0.001720217000070079, + "tests/aws/services/cloudformation/v2/test_change_set_mappings.py::TestChangeSetMappings::test_mapping_key_deletion_with_resource_remap": 0.001733892000004289, + "tests/aws/services/cloudformation/v2/test_change_set_mappings.py::TestChangeSetMappings::test_mapping_key_update": 0.0017408239999667785, + "tests/aws/services/cloudformation/v2/test_change_set_mappings.py::TestChangeSetMappings::test_mapping_leaf_update": 0.001770019999980832, + "tests/aws/services/cloudformation/v2/test_change_set_parameters.py::TestChangeSetParameters::test_update_parameter_default_value": 0.0017625460000658677, + "tests/aws/services/cloudformation/v2/test_change_set_parameters.py::TestChangeSetParameters::test_update_parameter_default_value_with_dynamic_overrides": 0.0017895270000281016, + "tests/aws/services/cloudformation/v2/test_change_set_parameters.py::TestChangeSetParameters::test_update_parameter_with_added_default_value": 0.0018852260000699061, + "tests/aws/services/cloudformation/v2/test_change_set_parameters.py::TestChangeSetParameters::test_update_parameter_with_removed_default_value": 0.0017473780000045736, + "tests/aws/services/cloudformation/v2/test_change_set_ref.py::TestChangeSetRef::test_direct_attribute_value_change": 0.001788594000061039, + "tests/aws/services/cloudformation/v2/test_change_set_ref.py::TestChangeSetRef::test_direct_attribute_value_change_in_ref_chain": 0.0018507109999745808, + "tests/aws/services/cloudformation/v2/test_change_set_ref.py::TestChangeSetRef::test_direct_attribute_value_change_with_dependent_addition": 0.0018526750000091852, + "tests/aws/services/cloudformation/v2/test_change_set_ref.py::TestChangeSetRef::test_immutable_property_update_causes_resource_replacement": 0.0020840170000724356, + "tests/aws/services/cloudformation/v2/test_change_set_ref.py::TestChangeSetRef::test_resource_addition": 0.0017609920000154489, + "tests/aws/services/cloudformation/v2/test_change_set_ref.py::TestChangeSetRef::test_supported_pseudo_parameter": 0.001871850000043196, + "tests/aws/services/cloudformation/v2/test_change_set_values.py::TestChangeSetValues::test_property_empy_list": 0.0018670420000148624, + "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_base_dynamic_parameter_scenarios[change_dynamic]": 0.0017550430000028427, + "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_base_dynamic_parameter_scenarios[change_parameter_for_condition_create_resource]": 0.0017420679999418098, + "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_base_dynamic_parameter_scenarios[change_unrelated_property]": 0.001725647000000663, + "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_base_dynamic_parameter_scenarios[change_unrelated_property_not_create_only]": 0.001854356999956508, + "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_base_mapping_scenarios[update_string_referencing_resource]": 0.0020345049999832554, + "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_conditions": 0.0022937900000101763, + "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_direct_update": 0.0018554099999619211, + "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_dynamic_update": 0.0017115410000201337, + "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_execute_with_ref": 0.0018759070000555766, + "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_mappings_with_parameter_lookup": 0.001749893000010161, + "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_mappings_with_static_fields": 0.001741345999960231, + "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_parameter_changes": 0.0017155279999769846, + "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_unrelated_changes_requires_replacement": 0.0017417170000157967, + "tests/aws/services/cloudformation/v2/test_change_sets.py::TestCaptureUpdateProcess::test_unrelated_changes_update_propagation": 0.0018956560000447098, + "tests/aws/services/cloudformation/v2/test_change_sets.py::test_single_resource_static_update": 0.001855000000034579, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_alarm_lambda_target": 16.771269107000023, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_anomaly_detector_lifecycle": 0.0017379579999783346, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_aws_sqs_metrics_created": 2.358792429999994, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_breaching_alarm_actions": 5.996264839999924, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_create_metric_stream": 0.0018482549999703224, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_dashboard_lifecycle": 0.1445118810000281, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_default_ordering": 0.12673318800000288, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_delete_alarm": 0.08853203199998916, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_describe_alarms_converts_date_format_correctly": 0.14378827600000932, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_describe_minimal_metric_alarm": 0.08378711099999236, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_enable_disable_alarm_actions": 10.273937679000028, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data": 2.0685624969999594, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data_different_units_no_unit_in_query[metric_data0]": 0.0017948560000036196, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data_different_units_no_unit_in_query[metric_data1]": 0.0017535890000317522, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data_different_units_no_unit_in_query[metric_data2]": 0.0018715389999783838, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data_for_multiple_metrics": 1.048534166999957, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data_pagination": 2.1898750619999987, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data_stats[Average]": 0.03532425899993541, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data_stats[Maximum]": 0.03601380900005324, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data_stats[Minimum]": 0.03582018699995615, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data_stats[SampleCount]": 0.03451174000002766, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data_stats[Sum]": 0.03370705499997939, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data_with_different_units": 0.026977986000019882, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data_with_dimensions": 0.04379511000001912, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_data_with_zero_and_labels": 0.042926012999998875, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_statistics": 0.18536766200003285, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_with_no_results": 0.046529136000003746, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_get_metric_with_null_dimensions": 0.03175738300001285, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_handle_different_units": 0.030691971999999623, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_insight_rule": 0.0018598170000245773, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_invalid_amount_of_datapoints": 0.5892244340000161, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_invalid_dashboard_name": 0.01673480500005553, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_label_generation[input_pairs0]": 0.03361873000011428, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_label_generation[input_pairs1]": 0.03346734300004073, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_label_generation[input_pairs2]": 0.032934460999967996, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_label_generation[input_pairs3]": 0.032052335999992465, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_label_generation[input_pairs4]": 0.03195510899996634, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_label_generation[input_pairs5]": 0.03270561699997643, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_label_generation[input_pairs6]": 0.04495292700005393, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_list_metrics_pagination": 5.453848747999984, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_list_metrics_uniqueness": 2.060047128000008, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_list_metrics_with_filters": 4.081368558000065, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_metric_widget": 0.0017610130000207391, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_multiple_dimensions": 2.1169133840000427, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_multiple_dimensions_statistics": 0.05381200500005434, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_parallel_put_metric_data_list_metrics": 0.26064043800005265, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_put_composite_alarm_describe_alarms": 0.09496076700003186, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_put_metric_alarm": 10.631772538999996, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_put_metric_alarm_escape_character": 0.07339865900001996, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_put_metric_data_gzip": 0.02400477899999487, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_put_metric_data_validation": 0.04361761999996361, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_put_metric_data_values_list": 0.04178366099995401, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_put_metric_uses_utc": 0.02970611200004214, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_raw_metric_data": 0.020418904999985443, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_set_alarm": 2.819510390000005, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_set_alarm_invalid_input": 0.08893622999994477, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_store_tags": 0.13240751699993325, + "tests/aws/services/cloudwatch/test_cloudwatch.py::TestCloudwatch::test_trigger_composite_alarm": 4.6225327109999625, + "tests/aws/services/cloudwatch/test_cloudwatch_metrics.py::TestCloudWatchLambdaMetrics::test_lambda_invoke_error": 2.5484479039999997, + "tests/aws/services/cloudwatch/test_cloudwatch_metrics.py::TestCloudWatchLambdaMetrics::test_lambda_invoke_successful": 8.543601864999914, + "tests/aws/services/cloudwatch/test_cloudwatch_metrics.py::TestSQSMetrics::test_alarm_number_of_messages_sent": 61.152863412999864, + "tests/aws/services/cloudwatch/test_cloudwatch_metrics.py::TestSqsApproximateMetrics::test_sqs_approximate_metrics": 46.706815783000025, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_batch_write_binary": 0.1144326529998807, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_batch_write_items": 0.13421536800001377, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_batch_write_items_streaming": 1.2276788190000616, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_batch_write_not_existing_table": 0.17457722100004958, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_batch_write_not_matching_schema": 0.11760353500005749, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_binary_data_with_stream": 2.3226145309998856, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_continuous_backup_update": 0.2876983849998851, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_create_duplicate_table": 0.1083803500000613, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_data_encoding_consistency": 0.952914483000086, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_delete_table": 0.11718835699991814, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_batch_execute_statement": 0.1382942819999471, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_create_table_with_class": 0.18322447999992164, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_create_table_with_partial_sse_specification": 0.2502422640001214, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_create_table_with_sse_specification": 0.08412893100000929, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_execute_statement_empy_parameter": 0.10867420500005665, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_execute_transaction": 0.1853452189999416, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_get_batch_items": 0.08827649900001688, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_idempotent_writing": 0.1471009199999571, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_partiql_missing": 0.12816046099999312, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_pay_per_request": 0.05918630300016048, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_stream_records_with_update_item": 0.001959301000056257, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_stream_shard_iterator": 0.945853761000194, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_stream_stream_view_type": 1.3980191350001405, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_streams_describe_with_exclusive_start_shard_id": 0.84459653600004, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_streams_shard_iterator_format": 2.896952916000032, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_update_table_without_sse_specification_change": 0.11632288299995253, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_with_kinesis_stream": 1.5013968220000606, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_empty_and_binary_values": 0.09575078700004269, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_global_tables": 0.10759539900004711, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_global_tables_version_2019": 0.504160380000144, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_gsi_with_billing_mode[PAY_PER_REQUEST]": 0.35231765599996834, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_gsi_with_billing_mode[PROVISIONED]": 0.33458756100003484, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_invalid_query_index": 0.0822543049999922, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_large_data_download": 0.45112054900016574, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_list_tags_of_resource": 0.08335310199993273, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_more_than_20_global_secondary_indexes": 0.2743891950000261, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_multiple_update_expressions": 0.18160540700000638, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_non_ascii_chars": 2.0831957859999193, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_nosql_workbench_localhost_region": 0.08066277500006436, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_query_on_deleted_resource": 0.18176094299997203, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_return_values_in_put_item": 0.1373000990000719, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_return_values_on_conditions_check_failure": 0.22862631800001054, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_stream_destination_records": 13.980052909999927, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_streams_on_global_tables": 1.2697108910001589, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_time_to_live": 0.2619977450000306, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_time_to_live_deletion": 0.5069381519999752, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_transact_get_items": 0.11086896799997703, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_transact_write_items_streaming": 1.3056161560000419, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_transact_write_items_streaming_for_different_tables": 1.8918820659999938, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_transaction_write_binary_data": 0.11319191400002637, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_transaction_write_canceled": 0.11398512099992786, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_transaction_write_items": 0.11193088999993961, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_valid_local_secondary_index": 0.1377746370001205, + "tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_valid_query_index": 0.0916338749998431, + "tests/aws/services/dynamodbstreams/test_dynamodb_streams.py::TestDynamoDBStreams::test_enable_kinesis_streaming_destination": 0.0033147039999903427, + "tests/aws/services/dynamodbstreams/test_dynamodb_streams.py::TestDynamoDBStreams::test_non_existent_stream": 0.022597558000029494, + "tests/aws/services/dynamodbstreams/test_dynamodb_streams.py::TestDynamoDBStreams::test_stream_spec_and_region_replacement": 2.3103481849999525, + "tests/aws/services/dynamodbstreams/test_dynamodb_streams.py::TestDynamoDBStreams::test_table_v2_stream": 1.962224858999889, + "tests/aws/services/ec2/test_ec2.py::TestEc2FlowLogs::test_ec2_flow_logs_s3": 0.5501234830002204, + "tests/aws/services/ec2/test_ec2.py::TestEc2FlowLogs::test_ec2_flow_logs_s3_validation": 0.2123288139998749, + "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_create_route_table_association": 0.801531488999899, + "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_create_security_group_with_custom_id[False-id_manager]": 0.06915941900001599, + "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_create_security_group_with_custom_id[False-tag]": 0.07140004000007139, + "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_create_security_group_with_custom_id[True-id_manager]": 0.05769386099984786, + "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_create_security_group_with_custom_id[True-tag]": 0.31052652300002137, + "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_create_subnet_with_custom_id": 0.06207171100004416, + "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_create_subnet_with_custom_id_and_vpc_id": 0.06103196400010802, + "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_create_subnet_with_tags": 0.12472070599994822, + "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_create_vpc_endpoint": 0.186036108000053, + "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_create_vpc_with_custom_id": 0.11623925299988969, + "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_describe_vpc_endpoints_with_filter": 0.5807274479999478, + "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_describe_vpn_gateways_filter_by_vpc": 0.37622215999999753, + "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_get_security_groups_for_vpc": 0.4053760179999699, + "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_modify_launch_template[id]": 0.07205979299999399, + "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_modify_launch_template[name]": 0.05568993900010355, + "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_reserved_instance_api": 0.03369018400007917, + "tests/aws/services/ec2/test_ec2.py::TestEc2Integrations::test_vcp_peering_difference_regions": 0.9656457380000347, + "tests/aws/services/ec2/test_ec2.py::test_create_specific_vpc_id": 0.0286844369999244, + "tests/aws/services/ec2/test_ec2.py::test_describe_availability_zones_filter_with_zone_ids": 0.3110111590000315, + "tests/aws/services/ec2/test_ec2.py::test_describe_availability_zones_filter_with_zone_names": 1.053244505000066, + "tests/aws/services/ec2/test_ec2.py::test_describe_availability_zones_filters": 0.3231620000000248, + "tests/aws/services/ec2/test_ec2.py::test_pickle_ec2_backend": 1.7661668140000302, + "tests/aws/services/ec2/test_ec2.py::test_raise_create_volume_without_size": 0.0199850950000382, + "tests/aws/services/ec2/test_ec2.py::test_raise_duplicate_launch_template_name": 0.03670621800006302, + "tests/aws/services/ec2/test_ec2.py::test_raise_invalid_launch_template_name": 0.012270898999986457, + "tests/aws/services/ec2/test_ec2.py::test_raise_modify_to_invalid_default_version": 0.035964113999966685, + "tests/aws/services/ec2/test_ec2.py::test_raise_when_launch_template_data_missing": 0.01313037399984296, + "tests/aws/services/es/test_es.py::TestElasticsearchProvider::test_create_domain": 0.0017910379998511416, + "tests/aws/services/es/test_es.py::TestElasticsearchProvider::test_create_existing_domain_causes_exception": 0.0017715409999254916, + "tests/aws/services/es/test_es.py::TestElasticsearchProvider::test_describe_domains": 0.0017959570000130043, + "tests/aws/services/es/test_es.py::TestElasticsearchProvider::test_domain_version": 0.0017576659998894684, + "tests/aws/services/es/test_es.py::TestElasticsearchProvider::test_get_compatible_version_for_domain": 0.0018150730001025295, + "tests/aws/services/es/test_es.py::TestElasticsearchProvider::test_get_compatible_versions": 0.0018090020000727236, + "tests/aws/services/es/test_es.py::TestElasticsearchProvider::test_list_versions": 0.001858423999919978, + "tests/aws/services/es/test_es.py::TestElasticsearchProvider::test_path_endpoint_strategy": 0.0017926019999094933, + "tests/aws/services/es/test_es.py::TestElasticsearchProvider::test_update_domain_config": 0.0016816629999993893, + "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeApiDestinations::test_api_destinations[auth0]": 0.1495218020000948, + "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeApiDestinations::test_api_destinations[auth1]": 0.09709741800008942, + "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeApiDestinations::test_api_destinations[auth2]": 0.09676017799995407, + "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeApiDestinations::test_create_api_destination_invalid_parameters": 0.015970084000059614, + "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeApiDestinations::test_create_api_destination_name_validation": 0.04904253899997002, + "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeConnections::test_connection_secrets[api-key]": 0.05658051699992939, + "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeConnections::test_connection_secrets[basic]": 0.05547985099997277, + "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeConnections::test_connection_secrets[oauth]": 0.05750733200000013, + "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeConnections::test_create_connection": 0.0506619509999382, + "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeConnections::test_create_connection_invalid_parameters": 0.015378792999968027, + "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeConnections::test_create_connection_name_validation": 0.015402469999912682, + "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeConnections::test_create_connection_with_auth[auth_params0]": 0.04839979700011554, + "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeConnections::test_create_connection_with_auth[auth_params1]": 0.05026798200003668, + "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeConnections::test_create_connection_with_auth[auth_params2]": 0.049474756999870806, + "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeConnections::test_delete_connection": 0.09979048599996077, + "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeConnections::test_list_connections": 0.048402290999888464, + "tests/aws/services/events/test_api_destinations_and_connection.py::TestEventBridgeConnections::test_update_connection": 0.09307999200007089, + "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_create_archive_error_duplicate[custom]": 0.0985550879998982, + "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_create_archive_error_duplicate[default]": 0.062196053999855394, + "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_create_archive_error_unknown_event_bus": 0.024476200000208337, + "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_create_list_describe_update_delete_archive[custom]": 0.12071044499987238, + "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_create_list_describe_update_delete_archive[default]": 0.09930715199993756, + "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_delete_archive_error_unknown_archive": 0.01625347399999555, + "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_describe_archive_error_unknown_archive": 0.02116284400017321, + "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_list_archive_error_unknown_source_arn": 0.01729754200005118, + "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_list_archive_state_enabled[custom]": 0.0889519160001555, + "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_list_archive_state_enabled[default]": 0.061124561999918114, + "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_list_archive_with_events[False-custom]": 0.5666142680000803, + "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_list_archive_with_events[False-default]": 0.5444388710000112, + "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_list_archive_with_events[True-custom]": 0.5652279370001452, + "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_list_archive_with_events[True-default]": 0.5557548870000346, + "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_list_archive_with_name_prefix[custom]": 0.107216544000039, + "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_list_archive_with_name_prefix[default]": 0.07605292899995675, + "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_list_archive_with_source_arn[custom]": 0.08836415500002204, + "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_list_archive_with_source_arn[default]": 0.06195007800010899, + "tests/aws/services/events/test_archive_and_replay.py::TestArchive::test_update_archive_error_unknown_archive": 0.0018482039998843902, + "tests/aws/services/events/test_archive_and_replay.py::TestReplay::test_describe_replay_error_unknown_replay": 0.015091938999944432, + "tests/aws/services/events/test_archive_and_replay.py::TestReplay::test_list_replay_with_limit": 0.2548083310000493, + "tests/aws/services/events/test_archive_and_replay.py::TestReplay::test_list_replays_with_event_source_arn": 0.13631367999994382, + "tests/aws/services/events/test_archive_and_replay.py::TestReplay::test_list_replays_with_prefix": 0.1964085020000539, + "tests/aws/services/events/test_archive_and_replay.py::TestReplay::test_start_list_describe_canceled_replay[custom]": 0.0017902270000149656, + "tests/aws/services/events/test_archive_and_replay.py::TestReplay::test_start_list_describe_canceled_replay[default]": 0.0018457390000321539, + "tests/aws/services/events/test_archive_and_replay.py::TestReplay::test_start_replay_error_duplicate_different_archive": 0.12837823399991066, + "tests/aws/services/events/test_archive_and_replay.py::TestReplay::test_start_replay_error_duplicate_name_same_archive": 0.07383736999986468, + "tests/aws/services/events/test_archive_and_replay.py::TestReplay::test_start_replay_error_invalid_end_time[0]": 0.06893903699995008, + "tests/aws/services/events/test_archive_and_replay.py::TestReplay::test_start_replay_error_invalid_end_time[10]": 0.06953031500006546, + "tests/aws/services/events/test_archive_and_replay.py::TestReplay::test_start_replay_error_unknown_archive": 0.014872010000090086, + "tests/aws/services/events/test_archive_and_replay.py::TestReplay::test_start_replay_error_unknown_event_bus": 0.09909897200009254, + "tests/aws/services/events/test_archive_and_replay.py::TestReplay::tests_concurrency_error_too_many_active_replays": 0.0018930480000562966, + "tests/aws/services/events/test_events.py::TestEventBus::test_create_list_describe_delete_custom_event_buses[False-regions0]": 0.04813209300004928, + "tests/aws/services/events/test_events.py::TestEventBus::test_create_list_describe_delete_custom_event_buses[False-regions1]": 0.11881404199993995, + "tests/aws/services/events/test_events.py::TestEventBus::test_create_list_describe_delete_custom_event_buses[True-regions0]": 0.047181891999912295, + "tests/aws/services/events/test_events.py::TestEventBus::test_create_list_describe_delete_custom_event_buses[True-regions1]": 0.1364995330001193, + "tests/aws/services/events/test_events.py::TestEventBus::test_create_multiple_event_buses_same_name": 0.04489421899995705, + "tests/aws/services/events/test_events.py::TestEventBus::test_delete_default_event_bus": 0.013296359999912966, + "tests/aws/services/events/test_events.py::TestEventBus::test_describe_delete_not_existing_event_bus": 0.021839913000007982, + "tests/aws/services/events/test_events.py::TestEventBus::test_list_event_buses_with_limit": 0.23581460700006573, + "tests/aws/services/events/test_events.py::TestEventBus::test_list_event_buses_with_prefix": 0.07861853099984728, + "tests/aws/services/events/test_events.py::TestEventBus::test_put_events_bus_to_bus[domain]": 0.2906787480000048, + "tests/aws/services/events/test_events.py::TestEventBus::test_put_events_bus_to_bus[path]": 0.29267391900009443, + "tests/aws/services/events/test_events.py::TestEventBus::test_put_events_bus_to_bus[standard]": 0.29537224800003514, + "tests/aws/services/events/test_events.py::TestEventBus::test_put_events_nonexistent_event_bus": 0.16369054400001914, + "tests/aws/services/events/test_events.py::TestEventBus::test_put_events_to_default_eventbus_for_custom_eventbus": 1.0640165759999718, + "tests/aws/services/events/test_events.py::TestEventBus::test_put_permission[custom]": 0.28650523399994654, + "tests/aws/services/events/test_events.py::TestEventBus::test_put_permission[default]": 0.09341603200005011, + "tests/aws/services/events/test_events.py::TestEventBus::test_put_permission_non_existing_event_bus": 0.015289257999938854, + "tests/aws/services/events/test_events.py::TestEventBus::test_remove_permission[custom]": 0.08742398000003959, + "tests/aws/services/events/test_events.py::TestEventBus::test_remove_permission[default]": 0.06766632999995181, + "tests/aws/services/events/test_events.py::TestEventBus::test_remove_permission_non_existing_sid[False-custom]": 0.04689926400010336, + "tests/aws/services/events/test_events.py::TestEventBus::test_remove_permission_non_existing_sid[False-default]": 0.022656699000094704, + "tests/aws/services/events/test_events.py::TestEventBus::test_remove_permission_non_existing_sid[True-custom]": 0.04998473900013778, + "tests/aws/services/events/test_events.py::TestEventBus::test_remove_permission_non_existing_sid[True-default]": 0.02934453900002154, + "tests/aws/services/events/test_events.py::TestEventPattern::test_put_events_pattern_nested": 10.238428924999994, + "tests/aws/services/events/test_events.py::TestEventPattern::test_put_events_pattern_with_values_in_array": 5.302827846000014, + "tests/aws/services/events/test_events.py::TestEventRule::test_delete_rule_with_targets": 0.07406426700003976, + "tests/aws/services/events/test_events.py::TestEventRule::test_describe_nonexistent_rule": 0.015774701000054847, + "tests/aws/services/events/test_events.py::TestEventRule::test_disable_re_enable_rule[custom]": 0.08974604600007297, + "tests/aws/services/events/test_events.py::TestEventRule::test_disable_re_enable_rule[default]": 0.06364046400005918, + "tests/aws/services/events/test_events.py::TestEventRule::test_list_rule_names_by_target[custom]": 0.2224088909999864, + "tests/aws/services/events/test_events.py::TestEventRule::test_list_rule_names_by_target[default]": 0.16551383000000897, + "tests/aws/services/events/test_events.py::TestEventRule::test_list_rule_names_by_target_no_matches[custom]": 0.12228702200002317, + "tests/aws/services/events/test_events.py::TestEventRule::test_list_rule_names_by_target_no_matches[default]": 0.09763855600010629, + "tests/aws/services/events/test_events.py::TestEventRule::test_list_rule_names_by_target_with_limit[custom]": 0.29120344800014664, + "tests/aws/services/events/test_events.py::TestEventRule::test_list_rule_names_by_target_with_limit[default]": 0.2600148829999398, + "tests/aws/services/events/test_events.py::TestEventRule::test_list_rule_with_limit": 0.2313037600000598, + "tests/aws/services/events/test_events.py::TestEventRule::test_process_pattern_to_single_matching_rules_single_target": 7.372113158000161, + "tests/aws/services/events/test_events.py::TestEventRule::test_process_to_multiple_matching_rules_different_targets": 0.5421924209999816, + "tests/aws/services/events/test_events.py::TestEventRule::test_process_to_multiple_matching_rules_single_target": 18.371954404999997, + "tests/aws/services/events/test_events.py::TestEventRule::test_process_to_single_matching_rules_single_target": 10.44798205199993, + "tests/aws/services/events/test_events.py::TestEventRule::test_put_list_with_prefix_describe_delete_rule[custom]": 0.08859788200004459, + "tests/aws/services/events/test_events.py::TestEventRule::test_put_list_with_prefix_describe_delete_rule[default]": 0.05573834799997712, + "tests/aws/services/events/test_events.py::TestEventRule::test_put_multiple_rules_with_same_name": 0.08270481799991103, + "tests/aws/services/events/test_events.py::TestEventRule::test_update_rule_with_targets": 0.09638481399997545, + "tests/aws/services/events/test_events.py::TestEventTarget::test_add_exceed_fife_targets_per_rule": 0.09593314900007499, + "tests/aws/services/events/test_events.py::TestEventTarget::test_list_target_by_rule_limit": 0.15494540500003495, + "tests/aws/services/events/test_events.py::TestEventTarget::test_put_list_remove_target[custom]": 0.10925693199999387, + "tests/aws/services/events/test_events.py::TestEventTarget::test_put_list_remove_target[default]": 0.08133978099999695, + "tests/aws/services/events/test_events.py::TestEventTarget::test_put_multiple_targets_with_same_arn_across_different_rules": 0.11573222300000907, + "tests/aws/services/events/test_events.py::TestEventTarget::test_put_multiple_targets_with_same_arn_single_rule": 0.08311901399986255, + "tests/aws/services/events/test_events.py::TestEventTarget::test_put_multiple_targets_with_same_id_across_different_rules": 0.11648701399997208, + "tests/aws/services/events/test_events.py::TestEventTarget::test_put_multiple_targets_with_same_id_single_rule": 0.08259973999997783, + "tests/aws/services/events/test_events.py::TestEventTarget::test_put_target_id_validation": 0.09729406400003882, + "tests/aws/services/events/test_events.py::TestEvents::test_create_connection_validations": 0.013588863000109086, + "tests/aws/services/events/test_events.py::TestEvents::test_events_written_to_disk_are_timestamp_prefixed_for_chronological_ordering": 0.0018104140000332336, + "tests/aws/services/events/test_events.py::TestEvents::test_put_event_malformed_detail[ARRAY]": 0.014820640999914758, + "tests/aws/services/events/test_events.py::TestEvents::test_put_event_malformed_detail[MALFORMED_JSON]": 0.014900991999979851, + "tests/aws/services/events/test_events.py::TestEvents::test_put_event_malformed_detail[SERIALIZED_STRING]": 0.014459616999943137, + "tests/aws/services/events/test_events.py::TestEvents::test_put_event_malformed_detail[STRING]": 0.015501816000096369, + "tests/aws/services/events/test_events.py::TestEvents::test_put_event_with_too_big_detail": 0.019872606000035375, + "tests/aws/services/events/test_events.py::TestEvents::test_put_event_without_detail": 0.014666301000147541, + "tests/aws/services/events/test_events.py::TestEvents::test_put_event_without_detail_type": 0.014684119999856193, + "tests/aws/services/events/test_events.py::TestEvents::test_put_events_exceed_limit_ten_entries[custom]": 0.045469609999940985, + "tests/aws/services/events/test_events.py::TestEvents::test_put_events_exceed_limit_ten_entries[default]": 0.016728548000060073, + "tests/aws/services/events/test_events.py::TestEvents::test_put_events_response_entries_order": 0.3018490929999871, + "tests/aws/services/events/test_events.py::TestEvents::test_put_events_time": 0.31660834799993154, + "tests/aws/services/events/test_events.py::TestEvents::test_put_events_with_target_delivery_failure": 1.1603782700000238, + "tests/aws/services/events/test_events.py::TestEvents::test_put_events_with_time_field": 0.1944284560000824, + "tests/aws/services/events/test_events.py::TestEvents::test_put_events_without_source": 0.014772553000057087, + "tests/aws/services/events/test_events_cross_account_region.py::TestEventsCrossAccountRegion::test_put_events[custom-account]": 0.1549637509999684, + "tests/aws/services/events/test_events_cross_account_region.py::test_event_bus_to_event_bus_cross_account_region[custom-account]": 0.4462265429999661, + "tests/aws/services/events/test_events_cross_account_region.py::test_event_bus_to_event_bus_cross_account_region[custom-region]": 0.44801401300003363, + "tests/aws/services/events/test_events_cross_account_region.py::test_event_bus_to_event_bus_cross_account_region[custom-region_account]": 0.44135201100004906, + "tests/aws/services/events/test_events_cross_account_region.py::test_event_bus_to_event_bus_cross_account_region[default-account]": 0.5847817860000077, + "tests/aws/services/events/test_events_cross_account_region.py::test_event_bus_to_event_bus_cross_account_region[default-region]": 0.48892080900009205, + "tests/aws/services/events/test_events_cross_account_region.py::test_event_bus_to_event_bus_cross_account_region[default-region_account]": 0.5066312309999148, + "tests/aws/services/events/test_events_inputs.py::TestInputPath::test_put_events_with_input_path": 0.1895113200000651, + "tests/aws/services/events/test_events_inputs.py::TestInputPath::test_put_events_with_input_path_max_level_depth": 0.18983674299988706, + "tests/aws/services/events/test_events_inputs.py::TestInputPath::test_put_events_with_input_path_multiple_targets": 0.30395586800000274, + "tests/aws/services/events/test_events_inputs.py::TestInputPath::test_put_events_with_input_path_nested[event_detail0]": 0.19032786600007512, + "tests/aws/services/events/test_events_inputs.py::TestInputPath::test_put_events_with_input_path_nested[event_detail1]": 0.19287989899999047, + "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement[\" multiple list items\"]": 0.23324683300018023, + "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement[\" single list item multiple list items system account id payload user id\"]": 0.23981891899984475, + "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement[\" single list item\"]": 0.2375884740000629, + "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement[\"Payload of with path users-service/users/ and \"]": 0.23198207299981277, + "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement[{\"id\" : \"\"}]": 0.23792319800008954, + "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement[{\"id\" : }]": 0.23384552000004533, + "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement[{\"method\": \"PUT\", \"nested\": {\"level1\": {\"level2\": {\"level3\": \"users-service/users/\"} } }, \"bod\": \"\"}]": 0.24054489399986778, + "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement[{\"method\": \"PUT\", \"path\": \"users-service/users/\", \"bod\": }]": 0.2319100189999972, + "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement[{\"method\": \"PUT\", \"path\": \"users-service/users/\", \"bod\": [, \"hardcoded\"]}]": 0.24008042100001603, + "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement[{\"method\": \"PUT\", \"path\": \"users-service/users/\", \"id\": , \"body\": }]": 0.2387815759999512, + "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement[{\"multi_replacement\": \"users//second/\"}]": 0.24897850400009247, + "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement[{\"singlelistitem\": }]": 0.24056044099995688, + "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement_not_valid[{\"not_valid\": \"users-service/users/\", \"bod\": }]": 5.162613029999989, + "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement_not_valid[{\"payload\": \"\"}]": 5.155755127000134, + "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_nested_keys_replacement_not_valid[{\"singlelistitem\": \"\"}]": 5.155686554999988, + "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_predefined_variables[\"Message containing all pre defined variables \"]": 0.22296367499995995, + "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_input_transformer_predefined_variables[{\"originalEvent\": , \"originalEventJson\": }]": 0.22869897999987643, + "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_put_events_with_input_transformer_input_template_json": 0.41334605200006536, + "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_put_events_with_input_transformer_input_template_string[\"Event of type, at time , info extracted from detail \"]": 0.4135113580000507, + "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_put_events_with_input_transformer_input_template_string[\"{[/Check with special starting characters for event of type\"]": 0.41395944199996393, + "tests/aws/services/events/test_events_inputs.py::TestInputTransformer::test_put_events_with_input_transformer_missing_keys": 0.10897416699992846, + "tests/aws/services/events/test_events_inputs.py::test_put_event_input_path_and_input_transformer": 0.10043030199994973, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_array_event_payload": 0.015089895999949476, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[arrays]": 0.01418535499999507, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[arrays_NEG]": 0.014144407999992836, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[arrays_empty_EXC]": 0.09182017199998427, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[arrays_empty_null_NEG]": 0.017206534000024476, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[boolean]": 0.015645334999931038, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[boolean_NEG]": 0.014563796000061302, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[complex_many_rules]": 0.017817701000012676, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[complex_multi_match]": 0.014593867999906251, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[complex_multi_match_NEG]": 0.01641504300005181, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[complex_or]": 0.014850938999870777, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[complex_or_NEG]": 0.014709566999954404, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_ignorecase]": 0.01532048699993993, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_ignorecase_EXC]": 0.09153017900007399, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_ignorecase_NEG]": 0.01476977800007262, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_ignorecase_list]": 0.014560243000005357, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_ignorecase_list_EXC]": 0.09049450999998498, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_ignorecase_list_NEG]": 0.015604026999994858, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_number]": 0.014140662000045268, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_number_NEG]": 0.014422248999949261, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_number_list]": 0.014220992999980808, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_number_list_NEG]": 0.015528509999967355, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_number_zero]": 0.015174545000036233, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_string]": 0.01441718800003855, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_string_NEG]": 0.014363277999905222, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_string_list]": 0.01453377400014233, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_string_list_NEG]": 0.015208778999976857, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_but_string_null]": 0.01474453799994535, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_prefix]": 0.01522744299995793, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_prefix_NEG]": 0.015610992999995688, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_prefix_empty_EXC]": 0.09121620099995198, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_prefix_ignorecase_EXC]": 0.09072872900003404, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_prefix_int_EXC]": 0.08985628900006759, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_prefix_list]": 0.015811503999998422, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_prefix_list_NEG]": 0.01473751900005027, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_prefix_list_type_EXC]": 0.09129977899988262, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_suffix]": 0.014589840999974513, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_suffix_NEG]": 0.015250748999960706, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_suffix_empty_EXC]": 0.09122861499997725, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_suffix_ignorecase_EXC]": 0.09017989100004797, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_suffix_int_EXC]": 0.0887327960000448, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_suffix_list]": 0.014473303999920972, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_suffix_list_NEG]": 0.015210043000024598, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_suffix_list_type_EXC]": 0.09251169800018033, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_wildcard]": 0.0157278880000149, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_wildcard_NEG]": 0.014598114999785139, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_wildcard_empty]": 0.015358415000036985, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_wildcard_list]": 0.014261095000051682, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_wildcard_list_NEG]": 0.015515510999989601, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_wildcard_list_type_EXC]": 0.09008967199997642, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_anything_wildcard_type_EXC]": 0.08996259700006703, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_exists]": 0.015313957999978811, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_exists_NEG]": 0.014107993000038732, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_exists_false]": 0.01573216899998897, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_exists_false_NEG]": 0.014873647999934292, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ignorecase]": 0.014974262999999155, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ignorecase_EXC]": 0.09132593700007874, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ignorecase_NEG]": 0.015747687000043697, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ignorecase_empty]": 0.014977175999888459, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ignorecase_empty_NEG]": 0.016065219999973124, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ignorecase_list_EXC]": 0.09090099200000168, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ip_address]": 0.014164948999905391, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ip_address_EXC]": 0.08917009200001758, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ip_address_NEG]": 0.015547792000006666, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ip_address_bad_ip_EXC]": 0.09150634400009494, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ip_address_bad_mask_EXC]": 0.09206571999993685, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ip_address_type_EXC]": 0.09055132700007107, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ip_address_v6]": 0.016313724000042384, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ip_address_v6_NEG]": 0.01554782100004104, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_ip_address_v6_bad_ip_EXC]": 0.09156877100008387, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_numeric_EXC]": 0.09084519900011401, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_numeric_and]": 0.01562505699985195, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_numeric_and_NEG]": 0.015039258999991034, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_numeric_number_EXC]": 0.09030554599974039, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_numeric_operatorcasing_EXC]": 0.09118067500003235, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_numeric_syntax_EXC]": 0.09240190800005621, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_prefix]": 0.014220999000031043, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_prefix_NEG]": 0.014740264000010939, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_prefix_empty]": 0.014874562999921181, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_prefix_ignorecase]": 0.015234927000051357, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_prefix_int_EXC]": 0.0917836140001782, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_prefix_list_EXC]": 0.09110454399990431, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_suffix]": 0.015687125999988893, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_suffix_NEG]": 0.014998786000091968, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_suffix_empty]": 0.015154145000110475, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_suffix_ignorecase]": 0.01417378300004657, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_suffix_ignorecase_NEG]": 0.014604705000010654, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_suffix_int_EXC]": 0.09190607099992576, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_suffix_list_EXC]": 0.09040943500008325, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_wildcard_complex_EXC]": 0.08987138500003766, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_wildcard_empty_NEG]": 0.015600060999986454, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_wildcard_int_EXC]": 0.9123096589999022, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_wildcard_list_EXC]": 0.08944618900011392, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_wildcard_nonrepeating]": 0.014520854999886978, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_wildcard_nonrepeating_NEG]": 0.014433108000048378, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_wildcard_repeating]": 0.016214581999975053, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_wildcard_repeating_NEG]": 0.01682463900010589, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_wildcard_repeating_star_EXC]": 0.09179703899997094, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[content_wildcard_simplified]": 0.015478953999945588, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[dot_joining_event]": 0.01523484599999847, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[dot_joining_event_NEG]": 0.014998505000107798, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[dot_joining_pattern]": 0.014738156000021263, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[dot_joining_pattern_NEG]": 0.014155665000089357, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[dynamodb]": 0.01449032800007899, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[exists_dynamodb]": 0.014387754000154018, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[exists_dynamodb_NEG]": 0.014635456999940288, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[exists_list_empty_NEG]": 0.015506976999972721, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[int_nolist_EXC]": 0.09070872899997084, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[key_case_sensitive_NEG]": 0.014791405000096347, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[list_within_dict]": 0.016012680999892837, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[minimal]": 0.015955044000065755, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[nested_json_NEG]": 0.014316569000015988, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[null_value]": 0.014982261999989532, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[null_value_NEG]": 0.014322974000037902, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[number_comparison_float]": 0.014623455999867474, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[numeric-int-float]": 0.015891342999907465, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[numeric-null_NEG]": 0.015749578999930236, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[numeric-string_NEG]": 0.014521122999894942, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[operator_case_sensitive_EXC]": 0.08919345899994369, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[operator_multiple_list]": 0.016181627999912962, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[or-anything-but]": 0.01562978499998735, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[or-exists-parent]": 0.014541871000005813, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[or-exists]": 0.014782729999978983, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[or-numeric-anything-but]": 0.015191496000170446, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[or-numeric-anything-but_NEG]": 0.014498236999997971, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[prefix]": 0.015468404999978702, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[sample1]": 0.01622725300012462, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[string]": 0.014327950999927452, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[string_empty]": 0.015379978000055416, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern[string_nolist_EXC]": 0.08971890199995869, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern_source": 0.02303195199988295, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern_with_escape_characters": 0.012298794999992424, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_pattern_with_multi_key": 0.012314836999962608, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_event_with_large_and_complex_payload": 0.027046988999927635, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_invalid_event_payload": 0.014846158999944237, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_invalid_json_event_pattern[[\"not\", \"a\", \"dict\", \"but valid json\"]]": 0.09297835499990015, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_invalid_json_event_pattern[this is valid json but not a dict]": 0.08778244300003735, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_invalid_json_event_pattern[{\"not\": closed mark\"]": 0.0905720470000233, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_invalid_json_event_pattern[{'bad': 'quotation'}]": 0.09015783100005592, + "tests/aws/services/events/test_events_patterns.py::TestEventPattern::test_plain_string_payload": 0.016089845000010428, + "tests/aws/services/events/test_events_patterns.py::TestRuleWithPattern::test_put_event_with_content_base_rule_in_pattern": 0.1939950990000625, + "tests/aws/services/events/test_events_patterns.py::TestRuleWithPattern::test_put_events_with_rule_pattern_anything_but": 5.326595639000061, + "tests/aws/services/events/test_events_patterns.py::TestRuleWithPattern::test_put_events_with_rule_pattern_exists_false": 5.2485219160000725, + "tests/aws/services/events/test_events_patterns.py::TestRuleWithPattern::test_put_events_with_rule_pattern_exists_true": 5.248775984000076, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::test_schedule_cron_target_sqs": 0.0017258120000178678, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_invalid_schedule_cron[cron(0 1 * * * *)]": 0.015114826999933939, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_invalid_schedule_cron[cron(0 dummy ? * MON-FRI *)]": 0.014104866999900878, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_invalid_schedule_cron[cron(7 20 * * NOT *)]": 0.014690514999983861, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_invalid_schedule_cron[cron(71 8 1 * ? *)]": 0.013825587000042106, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_invalid_schedule_cron[cron(INVALID)]": 0.01412205899998753, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(* * ? * SAT#3 *)]": 0.041378493999900456, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0 10 * * ? *)]": 0.0398063559999855, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0 12 * * ? *)]": 0.03806683100003738, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0 18 ? * MON-FRI *)]": 0.03782728099986343, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0 2 ? * SAT *)]": 0.03826655399984702, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0 2 ? * SAT#3 *)]": 0.03888867000000573, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0 8 1 * ? *)]": 0.04005611900004169, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0/10 * ? * MON-FRI *)]": 0.03777904999992643, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0/15 * * * ? *)]": 0.0384758550000015, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0/30 0-2 ? * MON-FRI *)]": 0.03768058499997551, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0/30 20-23 ? * MON-FRI *)]": 0.038001606999955584, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0/5 5 ? JAN 1-5 2022)]": 0.04016902899991237, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0/5 8-17 ? * MON-FRI *)]": 0.03741782999998122, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(15 10 ? * 6L 2002-2005)]": 0.03839310400007889, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(15 12 * * ? *)]": 0.0374515710001333, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(5,35 14 * * ? *)]": 0.03924130600000808, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_scheduled_rule_does_not_trigger_on_put_events": 3.092397351000045, + "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[ rate(10 minutes)]": 0.012008788999992248, + "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate( 10 minutes )]": 0.011796517999982825, + "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate()]": 0.0114087599999948, + "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(-10 minutes)]": 0.012517465999962951, + "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(0 minutes)]": 0.012451521999878423, + "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(1 days)]": 0.012097862000132409, + "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(1 hours)]": 0.011138340000002245, + "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(1 minutes)]": 0.01169688100003441, + "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(10 MINUTES)]": 0.012402859000076205, + "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(10 day)]": 0.01123187300004247, + "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(10 hour)]": 0.011572537999995802, + "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(10 minute)]": 0.011185177000015756, + "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(10 minutess)]": 0.011515009000049758, + "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(10 seconds)]": 0.012467900000046939, + "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(10 years)]": 0.01153372400005992, + "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(10)]": 0.011467699000149878, + "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[rate(foo minutes)]": 0.011603031000163355, + "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_schedule_rate": 0.03880118699999002, + "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_scheduled_rule_logs": 0.0018379020000338642, + "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::tests_put_rule_with_schedule_custom_event_bus": 0.04150531699997373, + "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::tests_schedule_rate_custom_input_target_sqs": 60.11465573700002, + "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::tests_schedule_rate_target_sqs": 0.0017640910000409349, + "tests/aws/services/events/test_events_tags.py::TestEventBusTags::test_create_event_bus_with_tags": 0.046034366000071714, + "tests/aws/services/events/test_events_tags.py::TestEventBusTags::test_list_tags_for_deleted_event_bus": 0.03734257799999341, + "tests/aws/services/events/test_events_tags.py::TestRuleTags::test_list_tags_for_deleted_rule": 0.06473452800003088, + "tests/aws/services/events/test_events_tags.py::TestRuleTags::test_put_rule_with_tags": 0.06739670499996464, + "tests/aws/services/events/test_events_tags.py::test_recreate_tagged_resource_without_tags[event_bus-event_bus_custom]": 0.06861411399984263, + "tests/aws/services/events/test_events_tags.py::test_recreate_tagged_resource_without_tags[event_bus-event_bus_default]": 0.020628957999861086, + "tests/aws/services/events/test_events_tags.py::test_recreate_tagged_resource_without_tags[rule-event_bus_custom]": 0.09204406999992898, + "tests/aws/services/events/test_events_tags.py::test_recreate_tagged_resource_without_tags[rule-event_bus_default]": 0.061975814000106766, + "tests/aws/services/events/test_events_tags.py::tests_tag_list_untag_not_existing_resource[not_existing_event_bus]": 0.02931512599980124, + "tests/aws/services/events/test_events_tags.py::tests_tag_list_untag_not_existing_resource[not_existing_rule]": 0.030349347999845122, + "tests/aws/services/events/test_events_tags.py::tests_tag_untag_resource[event_bus-event_bus_custom]": 0.07399403200008692, + "tests/aws/services/events/test_events_tags.py::tests_tag_untag_resource[event_bus-event_bus_default]": 0.04879704299992227, + "tests/aws/services/events/test_events_tags.py::tests_tag_untag_resource[rule-event_bus_custom]": 0.09256321900011244, + "tests/aws/services/events/test_events_tags.py::tests_tag_untag_resource[rule-event_bus_default]": 0.06437317199993231, + "tests/aws/services/events/test_events_targets.py::TestEventsTargetApiDestination::test_put_events_to_target_api_destinations[auth0]": 0.12012385400009862, + "tests/aws/services/events/test_events_targets.py::TestEventsTargetApiDestination::test_put_events_to_target_api_destinations[auth1]": 0.11613503800003855, + "tests/aws/services/events/test_events_targets.py::TestEventsTargetApiDestination::test_put_events_to_target_api_destinations[auth2]": 0.11928503000001456, + "tests/aws/services/events/test_events_targets.py::TestEventsTargetApiGateway::test_put_events_with_target_api_gateway": 7.488872645000015, + "tests/aws/services/events/test_events_targets.py::TestEventsTargetCloudWatchLogs::test_put_events_with_target_cloudwatch_logs": 0.20707499000002372, + "tests/aws/services/events/test_events_targets.py::TestEventsTargetEvents::test_put_events_with_target_events[bus_combination0]": 0.2964454079999541, + "tests/aws/services/events/test_events_targets.py::TestEventsTargetEvents::test_put_events_with_target_events[bus_combination1]": 0.32528938500001914, + "tests/aws/services/events/test_events_targets.py::TestEventsTargetEvents::test_put_events_with_target_events[bus_combination2]": 0.3065873020000254, + "tests/aws/services/events/test_events_targets.py::TestEventsTargetFirehose::test_put_events_with_target_firehose": 1.066505063999898, + "tests/aws/services/events/test_events_targets.py::TestEventsTargetKinesis::test_put_events_with_target_kinesis": 0.9321572720000404, + "tests/aws/services/events/test_events_targets.py::TestEventsTargetLambda::test_put_events_with_target_lambda": 4.245475666999937, + "tests/aws/services/events/test_events_targets.py::TestEventsTargetLambda::test_put_events_with_target_lambda_list_entries_partial_match": 4.267418806000023, + "tests/aws/services/events/test_events_targets.py::TestEventsTargetLambda::test_put_events_with_target_lambda_list_entry": 4.274031562000005, + "tests/aws/services/events/test_events_targets.py::TestEventsTargetSns::test_put_events_with_target_sns[domain]": 0.22740507999992587, + "tests/aws/services/events/test_events_targets.py::TestEventsTargetSns::test_put_events_with_target_sns[path]": 0.22809114699987276, + "tests/aws/services/events/test_events_targets.py::TestEventsTargetSns::test_put_events_with_target_sns[standard]": 0.2559268610000345, + "tests/aws/services/events/test_events_targets.py::TestEventsTargetSqs::test_put_events_with_target_sqs": 0.18866875799994887, + "tests/aws/services/events/test_events_targets.py::TestEventsTargetSqs::test_put_events_with_target_sqs_event_detail_match": 5.217495432999954, + "tests/aws/services/events/test_events_targets.py::TestEventsTargetStepFunctions::test_put_events_with_target_statefunction_machine": 2.0166453579998915, + "tests/aws/services/events/test_x_ray_trace_propagation.py::test_xray_trace_propagation_events_api_gateway": 5.697795491999955, + "tests/aws/services/events/test_x_ray_trace_propagation.py::test_xray_trace_propagation_events_events[bus_combination0]": 4.416916714999843, + "tests/aws/services/events/test_x_ray_trace_propagation.py::test_xray_trace_propagation_events_events[bus_combination1]": 4.428701708999938, + "tests/aws/services/events/test_x_ray_trace_propagation.py::test_xray_trace_propagation_events_events[bus_combination2]": 4.379087588999937, + "tests/aws/services/events/test_x_ray_trace_propagation.py::test_xray_trace_propagation_events_lambda": 4.239382899000134, + "tests/aws/services/firehose/test_firehose.py::TestFirehoseIntegration::test_kinesis_firehose_elasticsearch_s3_backup": 0.0017732209998939652, + "tests/aws/services/firehose/test_firehose.py::TestFirehoseIntegration::test_kinesis_firehose_kinesis_as_source": 26.20371856700001, + "tests/aws/services/firehose/test_firehose.py::TestFirehoseIntegration::test_kinesis_firehose_kinesis_as_source_multiple_delivery_streams": 53.65874896000014, + "tests/aws/services/firehose/test_firehose.py::TestFirehoseIntegration::test_kinesis_firehose_opensearch_s3_backup[domain]": 0.001809318999903553, + "tests/aws/services/firehose/test_firehose.py::TestFirehoseIntegration::test_kinesis_firehose_opensearch_s3_backup[path]": 0.0017011869998668772, + "tests/aws/services/firehose/test_firehose.py::TestFirehoseIntegration::test_kinesis_firehose_opensearch_s3_backup[port]": 0.001707098999986556, + "tests/aws/services/firehose/test_firehose.py::TestFirehoseIntegration::test_kinesis_firehose_s3_as_destination_with_file_extension": 1.189739161000034, + "tests/aws/services/firehose/test_firehose.py::test_kinesis_firehose_http[False]": 0.0896975029999112, + "tests/aws/services/firehose/test_firehose.py::test_kinesis_firehose_http[True]": 1.6846019429999615, + "tests/aws/services/iam/test_iam.py::TestIAMExtensions::test_create_role_with_malformed_assume_role_policy_document": 0.020849109000096178, + "tests/aws/services/iam/test_iam.py::TestIAMExtensions::test_create_user_add_permission_boundary_afterwards": 0.11193146199991588, + "tests/aws/services/iam/test_iam.py::TestIAMExtensions::test_create_user_with_permission_boundary": 0.09909946699997363, + "tests/aws/services/iam/test_iam.py::TestIAMExtensions::test_get_user_without_username_as_role": 0.12064189899990652, + "tests/aws/services/iam/test_iam.py::TestIAMExtensions::test_get_user_without_username_as_root": 0.042734262999942985, + "tests/aws/services/iam/test_iam.py::TestIAMExtensions::test_get_user_without_username_as_user": 0.15994781899996724, + "tests/aws/services/iam/test_iam.py::TestIAMExtensions::test_role_with_path_lifecycle": 0.11954385299998194, + "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_attach_detach_role_policy": 0.08393375299988293, + "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_attach_iam_role_to_new_iam_user": 0.09845846700000038, + "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_create_describe_role": 0.15048440700002175, + "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_create_role_with_assume_role_policy": 0.13316081499988286, + "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_create_user_with_tags": 0.032481371000017134, + "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_delete_non_existent_policy_returns_no_such_entity": 0.01595528700011073, + "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_instance_profile_tags": 0.15116745800014542, + "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_list_roles_with_permission_boundary": 0.18620887299994138, + "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_recreate_iam_role": 0.06260548400007337, + "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_role_attach_policy": 0.44875583700002153, + "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_service_linked_role_name_should_match_aws[ecs.amazonaws.com-AWSServiceRoleForECS]": 0.00183798199998364, + "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_service_linked_role_name_should_match_aws[eks.amazonaws.com-AWSServiceRoleForAmazonEKS]": 0.0017149730000483032, + "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_simulate_principle_policy[group]": 0.19528432199990675, + "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_simulate_principle_policy[role]": 0.22017065499994715, + "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_simulate_principle_policy[user]": 0.22764551899990693, + "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_update_assume_role_policy": 0.11544718499987994, + "tests/aws/services/iam/test_iam.py::TestIAMIntegrations::test_user_attach_policy": 0.43069707699976334, + "tests/aws/services/iam/test_iam.py::TestIAMPolicyEncoding::test_put_group_policy_encoding": 0.05670772499991017, + "tests/aws/services/iam/test_iam.py::TestIAMPolicyEncoding::test_put_role_policy_encoding": 0.17793259400002626, + "tests/aws/services/iam/test_iam.py::TestIAMPolicyEncoding::test_put_user_policy_encoding": 0.08280973800003721, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_already_exists": 0.03426108300004671, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_deletion": 6.892259381000031, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[accountdiscovery.ssm.amazonaws.com]": 0.2832900040000368, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[acm.amazonaws.com]": 0.27904887699992287, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[appmesh.amazonaws.com]": 0.27974927200000366, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[autoscaling-plans.amazonaws.com]": 0.2812043099999073, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[autoscaling.amazonaws.com]": 0.2827079499999172, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[backup.amazonaws.com]": 0.2779769460000807, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[batch.amazonaws.com]": 0.2825990839999122, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[cassandra.application-autoscaling.amazonaws.com]": 0.2861093289999417, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[cks.kms.amazonaws.com]": 0.2841395860000375, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[cloudtrail.amazonaws.com]": 0.27977315700013605, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[codestar-notifications.amazonaws.com]": 1.1863946409999926, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[config.amazonaws.com]": 0.2784729589999415, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[connect.amazonaws.com]": 0.2832514759999185, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[dms-fleet-advisor.amazonaws.com]": 0.27889526299998124, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[dms.amazonaws.com]": 0.28121233699994264, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[docdb-elastic.amazonaws.com]": 0.2815274039999167, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[ec2-instance-connect.amazonaws.com]": 0.28315467299989905, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[ec2.application-autoscaling.amazonaws.com]": 0.279080252999961, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[ecr.amazonaws.com]": 0.2776523069999257, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[ecs.amazonaws.com]": 0.28143454200005635, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[eks-connector.amazonaws.com]": 0.2811527900000783, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[eks-fargate.amazonaws.com]": 0.2793887939999422, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[eks-nodegroup.amazonaws.com]": 0.284746729999938, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[eks.amazonaws.com]": 0.2804128679999849, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[elasticache.amazonaws.com]": 0.27808883199998036, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[elasticbeanstalk.amazonaws.com]": 0.28448125300008087, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[elasticfilesystem.amazonaws.com]": 0.2891660720000573, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[elasticloadbalancing.amazonaws.com]": 0.3301724430000377, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[email.cognito-idp.amazonaws.com]": 0.28472655400014446, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[emr-containers.amazonaws.com]": 0.28402039899992815, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[emrwal.amazonaws.com]": 0.2810581740000089, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[fis.amazonaws.com]": 0.28210853199993835, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[grafana.amazonaws.com]": 0.2797036649999427, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[imagebuilder.amazonaws.com]": 0.28332136699975763, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[iotmanagedintegrations.amazonaws.com]": 0.3572825940000257, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[kafka.amazonaws.com]": 0.28209844000002704, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[kafkaconnect.amazonaws.com]": 0.28129157199998645, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[lakeformation.amazonaws.com]": 0.2826866500000733, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[lex.amazonaws.com]": 0.3654876169999852, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[lexv2.amazonaws.com]": 0.2817668989999902, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[lightsail.amazonaws.com]": 0.2855655079999906, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[m2.amazonaws.com]": 0.2849959059999492, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[memorydb.amazonaws.com]": 0.278990616000101, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[mq.amazonaws.com]": 0.28044962399985707, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[mrk.kms.amazonaws.com]": 0.277603245000023, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[notifications.amazonaws.com]": 0.2794281320001346, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[observability.aoss.amazonaws.com]": 0.2839700500001072, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[opensearchservice.amazonaws.com]": 0.2818658979999782, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[ops.apigateway.amazonaws.com]": 0.2818739509999659, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[ops.emr-serverless.amazonaws.com]": 0.2798543359999712, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[opsdatasync.ssm.amazonaws.com]": 0.2779373809999015, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[opsinsights.ssm.amazonaws.com]": 0.27962281999998595, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[pullthroughcache.ecr.amazonaws.com]": 0.28515111100011836, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[ram.amazonaws.com]": 0.2827785109999468, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[rds.amazonaws.com]": 0.28100266100000226, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[redshift.amazonaws.com]": 0.2825241450000249, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[replication.cassandra.amazonaws.com]": 0.2808781570000747, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[replication.ecr.amazonaws.com]": 0.2801635489998944, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[repository.sync.codeconnections.amazonaws.com]": 0.28122661800011883, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[resource-explorer-2.amazonaws.com]": 0.2787340710000308, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[rolesanywhere.amazonaws.com]": 0.28215570199995454, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[s3-outposts.amazonaws.com]": 0.27959938899994086, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[ses.amazonaws.com]": 0.2844310730000643, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[shield.amazonaws.com]": 0.3135478079998393, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[ssm-incidents.amazonaws.com]": 0.3053420979997554, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[ssm-quicksetup.amazonaws.com]": 0.28149120600005517, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[ssm.amazonaws.com]": 0.2788073389999681, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[sso.amazonaws.com]": 0.2790734880001082, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[vpcorigin.cloudfront.amazonaws.com]": 0.2798159650000116, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[waf.amazonaws.com]": 0.2799423180000531, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle[wafv2.amazonaws.com]": 0.28110568500005684, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix[autoscaling.amazonaws.com]": 0.13202905400009968, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix[connect.amazonaws.com]": 1.1300846869999077, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix[lexv2.amazonaws.com]": 0.13416802699998698, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[accountdiscovery.ssm.amazonaws.com]": 0.01664574899996296, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[acm.amazonaws.com]": 0.015982211000050484, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[appmesh.amazonaws.com]": 0.017087318999983836, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[autoscaling-plans.amazonaws.com]": 0.016042050999999447, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[backup.amazonaws.com]": 0.015850388999865572, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[batch.amazonaws.com]": 0.01563526799986903, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[cassandra.application-autoscaling.amazonaws.com]": 0.01625418199989781, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[cks.kms.amazonaws.com]": 0.016224755000052937, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[cloudtrail.amazonaws.com]": 0.016083212000125968, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[codestar-notifications.amazonaws.com]": 0.015845253000065895, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[config.amazonaws.com]": 0.016998461000071075, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[dms-fleet-advisor.amazonaws.com]": 0.015900164999948174, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[dms.amazonaws.com]": 0.016230357000040385, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[docdb-elastic.amazonaws.com]": 0.015660484000022734, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[ec2-instance-connect.amazonaws.com]": 0.016210277999903155, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[ec2.application-autoscaling.amazonaws.com]": 0.016511353000169038, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[ecr.amazonaws.com]": 0.015854477999937444, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[ecs.amazonaws.com]": 0.01566706999994949, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[eks-connector.amazonaws.com]": 0.015404543999920861, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[eks-fargate.amazonaws.com]": 0.015480323999781831, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[eks-nodegroup.amazonaws.com]": 0.015722832000051312, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[eks.amazonaws.com]": 0.01586206100000709, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[elasticache.amazonaws.com]": 0.015737194000053023, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[elasticbeanstalk.amazonaws.com]": 0.015354111999954512, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[elasticfilesystem.amazonaws.com]": 0.01636002100008227, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[elasticloadbalancing.amazonaws.com]": 0.016242408999914915, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[email.cognito-idp.amazonaws.com]": 0.016008049999982177, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[emr-containers.amazonaws.com]": 0.01612020200002462, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[emrwal.amazonaws.com]": 0.016407458000003317, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[fis.amazonaws.com]": 0.016162548999886894, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[grafana.amazonaws.com]": 0.015556341000092289, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[imagebuilder.amazonaws.com]": 0.01580270199997358, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[iotmanagedintegrations.amazonaws.com]": 0.01591240800007654, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[kafka.amazonaws.com]": 0.015527908999956708, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[kafkaconnect.amazonaws.com]": 0.016066859000034128, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[lakeformation.amazonaws.com]": 0.015809273999934703, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[lex.amazonaws.com]": 0.01566344000002573, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[lightsail.amazonaws.com]": 0.01618794900014109, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[m2.amazonaws.com]": 0.015620468999941295, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[memorydb.amazonaws.com]": 0.017583407999950396, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[mq.amazonaws.com]": 0.01649410299989995, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[mrk.kms.amazonaws.com]": 0.016374675999941246, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[notifications.amazonaws.com]": 0.016197473000033824, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[observability.aoss.amazonaws.com]": 0.015647759999978916, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[opensearchservice.amazonaws.com]": 0.016095539999923858, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[ops.apigateway.amazonaws.com]": 0.015471688000047834, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[ops.emr-serverless.amazonaws.com]": 0.016303804000131095, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[opsdatasync.ssm.amazonaws.com]": 0.01602301700006592, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[opsinsights.ssm.amazonaws.com]": 0.01576953999995112, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[pullthroughcache.ecr.amazonaws.com]": 0.015990848999990703, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[ram.amazonaws.com]": 0.016222913000092376, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[rds.amazonaws.com]": 0.01579756399996768, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[redshift.amazonaws.com]": 0.015299667000022055, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[replication.cassandra.amazonaws.com]": 0.016768288999969627, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[replication.ecr.amazonaws.com]": 0.01579972500007898, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[repository.sync.codeconnections.amazonaws.com]": 0.016001929000026394, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[resource-explorer-2.amazonaws.com]": 0.015531946000010066, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[rolesanywhere.amazonaws.com]": 0.01583530600009908, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[s3-outposts.amazonaws.com]": 0.01569798300010916, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[ses.amazonaws.com]": 0.015711651000174243, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[shield.amazonaws.com]": 0.016582710000079715, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[ssm-incidents.amazonaws.com]": 0.015969115000075362, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[ssm-quicksetup.amazonaws.com]": 0.016642540999896482, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[ssm.amazonaws.com]": 0.016167257999882167, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[sso.amazonaws.com]": 0.01606850299992857, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[vpcorigin.cloudfront.amazonaws.com]": 0.01623712000002797, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[waf.amazonaws.com]": 0.01683709799999633, + "tests/aws/services/iam/test_iam.py::TestIAMServiceRoles::test_service_role_lifecycle_custom_suffix_not_allowed[wafv2.amazonaws.com]": 0.01610619600000973, + "tests/aws/services/iam/test_iam.py::TestIAMServiceSpecificCredentials::test_create_service_specific_credential_invalid_service": 0.07773906199997782, + "tests/aws/services/iam/test_iam.py::TestIAMServiceSpecificCredentials::test_create_service_specific_credential_invalid_user": 0.024899978999997074, + "tests/aws/services/iam/test_iam.py::TestIAMServiceSpecificCredentials::test_delete_user_after_service_credential_created": 0.08013889799997287, + "tests/aws/services/iam/test_iam.py::TestIAMServiceSpecificCredentials::test_id_match_user_mismatch": 0.09668986700012283, + "tests/aws/services/iam/test_iam.py::TestIAMServiceSpecificCredentials::test_invalid_update_parameters": 0.079241495000133, + "tests/aws/services/iam/test_iam.py::TestIAMServiceSpecificCredentials::test_list_service_specific_credential_different_service": 0.0795672099999365, + "tests/aws/services/iam/test_iam.py::TestIAMServiceSpecificCredentials::test_service_specific_credential_lifecycle[cassandra.amazonaws.com]": 0.10727879299986398, + "tests/aws/services/iam/test_iam.py::TestIAMServiceSpecificCredentials::test_service_specific_credential_lifecycle[codecommit.amazonaws.com]": 0.11226713199994265, + "tests/aws/services/iam/test_iam.py::TestIAMServiceSpecificCredentials::test_user_match_id_mismatch[satisfiesregexbutstillinvalid]": 0.09909165799979291, + "tests/aws/services/iam/test_iam.py::TestIAMServiceSpecificCredentials::test_user_match_id_mismatch[totally-wrong-credential-id-with-hyphens]": 0.09678122999991956, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_add_tags_to_stream": 0.676205733000188, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_cbor_blob_handling": 0.6666986949999227, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_create_stream_without_shard_count": 0.6761734400001842, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_create_stream_without_stream_name_raises": 0.041891859000088516, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_get_records": 0.7409520800001701, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_get_records_empty_stream": 0.6696620039999743, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_get_records_next_shard_iterator": 0.7075039110000034, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_get_records_shard_iterator_with_surrounding_quotes": 0.6854481230000147, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_record_lifecycle_data_integrity": 0.8761748049998914, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_stream_consumers": 1.3413246319996688, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_subscribe_to_shard": 4.544009079000034, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_subscribe_to_shard_cbor_at_timestamp": 4.3899140109999735, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_subscribe_to_shard_timeout": 6.327568649999876, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_subscribe_to_shard_with_at_timestamp": 4.569665387000214, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_subscribe_to_shard_with_at_timestamp_cbor": 0.6526614429999427, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesis::test_subscribe_to_shard_with_sequence_number_as_iterator": 4.572614492999946, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesisJavaSDK::test_subscribe_to_shard_with_java_sdk_v2_lambda": 5.599409863000119, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_add_tags_to_stream": 0.6644522180001786, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_cbor_blob_handling": 0.6699971870000354, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_create_stream_without_shard_count": 0.6621844819999296, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_create_stream_without_stream_name_raises": 0.04263047299969003, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_get_records": 0.7370063990001654, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_get_records_empty_stream": 0.665732578999723, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_get_records_next_shard_iterator": 0.6691950830002042, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_get_records_shard_iterator_with_surrounding_quotes": 0.6739317449998907, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_record_lifecycle_data_integrity": 0.8685041820001516, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_stream_consumers": 1.3107097690003684, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_subscribe_to_shard": 4.519610539000041, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_subscribe_to_shard_cbor_at_timestamp": 1.3535660909999478, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_subscribe_to_shard_timeout": 6.320716842000138, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_subscribe_to_shard_with_at_timestamp": 4.525006557000097, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_subscribe_to_shard_with_at_timestamp_cbor": 0.6468921050002336, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesisMockScala::test_subscribe_to_shard_with_sequence_number_as_iterator": 4.530134683999904, + "tests/aws/services/kinesis/test_kinesis.py::TestKinesisPythonClient::test_run_kcl": 22.157271877999847, + "tests/aws/services/kms/test_kms.py::TestKMS::test_all_types_of_key_id_can_be_used_for_encryption": 0.0686311330002809, + "tests/aws/services/kms/test_kms.py::TestKMS::test_cant_delete_deleted_key": 0.04985205000025417, + "tests/aws/services/kms/test_kms.py::TestKMS::test_cant_use_disabled_or_deleted_keys": 0.06774898000026042, + "tests/aws/services/kms/test_kms.py::TestKMS::test_create_alias": 0.1136383850000584, + "tests/aws/services/kms/test_kms.py::TestKMS::test_create_custom_key_asymmetric": 0.03922003299999233, + "tests/aws/services/kms/test_kms.py::TestKMS::test_create_grant_with_invalid_key": 0.02607708300001832, + "tests/aws/services/kms/test_kms.py::TestKMS::test_create_grant_with_same_name_two_keys": 0.061705905999815513, + "tests/aws/services/kms/test_kms.py::TestKMS::test_create_grant_with_valid_key": 0.04558373599979859, + "tests/aws/services/kms/test_kms.py::TestKMS::test_create_key": 0.11936288300034903, + "tests/aws/services/kms/test_kms.py::TestKMS::test_create_key_custom_id": 0.028511826999874756, + "tests/aws/services/kms/test_kms.py::TestKMS::test_create_key_custom_key_material_hmac": 0.036858736999874964, + "tests/aws/services/kms/test_kms.py::TestKMS::test_create_key_custom_key_material_symmetric_decrypt": 0.030648311000049944, + "tests/aws/services/kms/test_kms.py::TestKMS::test_create_key_with_invalid_tag_key[lowercase_prefix]": 0.09089444799997182, + "tests/aws/services/kms/test_kms.py::TestKMS::test_create_key_with_invalid_tag_key[too_long_key]": 0.0902723460001198, + "tests/aws/services/kms/test_kms.py::TestKMS::test_create_key_with_invalid_tag_key[uppercase_prefix]": 0.0911043769999651, + "tests/aws/services/kms/test_kms.py::TestKMS::test_create_key_with_tag_and_untag": 0.11910630800002764, + "tests/aws/services/kms/test_kms.py::TestKMS::test_create_key_with_too_many_tags_raises_error": 0.09269915400000173, + "tests/aws/services/kms/test_kms.py::TestKMS::test_create_list_delete_alias": 0.06562563600027715, + "tests/aws/services/kms/test_kms.py::TestKMS::test_create_multi_region_key": 0.17469190899987552, + "tests/aws/services/kms/test_kms.py::TestKMS::test_derive_shared_secret": 0.21443693299988809, + "tests/aws/services/kms/test_kms.py::TestKMS::test_describe_and_list_sign_key": 0.03618682199999057, + "tests/aws/services/kms/test_kms.py::TestKMS::test_disable_and_enable_key": 0.05718195300005391, + "tests/aws/services/kms/test_kms.py::TestKMS::test_encrypt_decrypt[RSA_2048-RSAES_OAEP_SHA_256]": 0.05729236799993487, + "tests/aws/services/kms/test_kms.py::TestKMS::test_encrypt_decrypt[SYMMETRIC_DEFAULT-SYMMETRIC_DEFAULT]": 0.03815684700020938, + "tests/aws/services/kms/test_kms.py::TestKMS::test_encrypt_decrypt_encryption_context": 0.19804450799983897, + "tests/aws/services/kms/test_kms.py::TestKMS::test_encrypt_validate_plaintext_size_per_key_type[RSA_2048-RSAES_OAEP_SHA_1]": 0.14728825799988954, + "tests/aws/services/kms/test_kms.py::TestKMS::test_encrypt_validate_plaintext_size_per_key_type[RSA_2048-RSAES_OAEP_SHA_256]": 0.15815466999993077, + "tests/aws/services/kms/test_kms.py::TestKMS::test_encrypt_validate_plaintext_size_per_key_type[RSA_3072-RSAES_OAEP_SHA_1]": 0.16825195199999143, + "tests/aws/services/kms/test_kms.py::TestKMS::test_encrypt_validate_plaintext_size_per_key_type[RSA_3072-RSAES_OAEP_SHA_256]": 0.23025954400031878, + "tests/aws/services/kms/test_kms.py::TestKMS::test_encrypt_validate_plaintext_size_per_key_type[RSA_4096-RSAES_OAEP_SHA_1]": 0.16828958099995361, + "tests/aws/services/kms/test_kms.py::TestKMS::test_encrypt_validate_plaintext_size_per_key_type[RSA_4096-RSAES_OAEP_SHA_256]": 0.43493772900001204, + "tests/aws/services/kms/test_kms.py::TestKMS::test_error_messaging_for_invalid_keys": 0.20020245799992153, + "tests/aws/services/kms/test_kms.py::TestKMS::test_generate_and_verify_mac[HMAC_224-HMAC_SHA_224]": 0.13680423200003133, + "tests/aws/services/kms/test_kms.py::TestKMS::test_generate_and_verify_mac[HMAC_256-HMAC_SHA_256]": 0.1286308999999619, + "tests/aws/services/kms/test_kms.py::TestKMS::test_generate_and_verify_mac[HMAC_384-HMAC_SHA_384]": 0.12962415299989516, + "tests/aws/services/kms/test_kms.py::TestKMS::test_generate_and_verify_mac[HMAC_512-HMAC_SHA_512]": 0.1293386609997924, + "tests/aws/services/kms/test_kms.py::TestKMS::test_generate_random[1024]": 0.08855314500010536, + "tests/aws/services/kms/test_kms.py::TestKMS::test_generate_random[12]": 0.0887624169999981, + "tests/aws/services/kms/test_kms.py::TestKMS::test_generate_random[1]": 0.08794772199985346, + "tests/aws/services/kms/test_kms.py::TestKMS::test_generate_random[44]": 0.08816837400013355, + "tests/aws/services/kms/test_kms.py::TestKMS::test_generate_random[91]": 0.08903899999995701, + "tests/aws/services/kms/test_kms.py::TestKMS::test_generate_random_invalid_number_of_bytes[0]": 0.08934160600028918, + "tests/aws/services/kms/test_kms.py::TestKMS::test_generate_random_invalid_number_of_bytes[1025]": 0.08965792700018937, + "tests/aws/services/kms/test_kms.py::TestKMS::test_generate_random_invalid_number_of_bytes[None]": 0.09862551200012604, + "tests/aws/services/kms/test_kms.py::TestKMS::test_get_key_does_not_exist": 0.12039443499998015, + "tests/aws/services/kms/test_kms.py::TestKMS::test_get_key_in_different_region": 0.13881704599998557, + "tests/aws/services/kms/test_kms.py::TestKMS::test_get_key_invalid_uuid": 0.10608274499986692, + "tests/aws/services/kms/test_kms.py::TestKMS::test_get_parameters_for_import": 0.46606482399988636, + "tests/aws/services/kms/test_kms.py::TestKMS::test_get_public_key": 0.05553079799983607, + "tests/aws/services/kms/test_kms.py::TestKMS::test_get_put_list_key_policies": 0.05512542100018436, + "tests/aws/services/kms/test_kms.py::TestKMS::test_hmac_create_key": 0.13062684700003047, + "tests/aws/services/kms/test_kms.py::TestKMS::test_hmac_create_key_invalid_operations": 0.1236328389998107, + "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_asymmetric": 0.2855073670002639, + "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_symmetric": 0.3447394439999698, + "tests/aws/services/kms/test_kms.py::TestKMS::test_invalid_generate_mac[HMAC_224-HMAC_SHA_256]": 0.1052327970000988, + "tests/aws/services/kms/test_kms.py::TestKMS::test_invalid_generate_mac[HMAC_256-INVALID]": 0.10565060599992648, + "tests/aws/services/kms/test_kms.py::TestKMS::test_invalid_key_usage": 1.5304006050002954, + "tests/aws/services/kms/test_kms.py::TestKMS::test_invalid_verify_mac[HMAC_256-HMAC_SHA_256-some different important message]": 0.18890124399968045, + "tests/aws/services/kms/test_kms.py::TestKMS::test_invalid_verify_mac[HMAC_256-HMAC_SHA_512-some important message]": 0.18798328299999412, + "tests/aws/services/kms/test_kms.py::TestKMS::test_invalid_verify_mac[HMAC_256-INVALID-some important message]": 0.18590619699989475, + "tests/aws/services/kms/test_kms.py::TestKMS::test_key_enable_rotation_status[180]": 0.11370270100019297, + "tests/aws/services/kms/test_kms.py::TestKMS::test_key_enable_rotation_status[90]": 0.1160972780000975, + "tests/aws/services/kms/test_kms.py::TestKMS::test_key_rotation_status": 0.05666552900015631, + "tests/aws/services/kms/test_kms.py::TestKMS::test_key_rotations_encryption_decryption": 0.13246015499998975, + "tests/aws/services/kms/test_kms.py::TestKMS::test_key_rotations_limits": 0.2277753760001815, + "tests/aws/services/kms/test_kms.py::TestKMS::test_key_with_long_tag_value_raises_error": 0.08978323200039995, + "tests/aws/services/kms/test_kms.py::TestKMS::test_list_aliases_of_key": 0.06770447400003832, + "tests/aws/services/kms/test_kms.py::TestKMS::test_list_grants_with_invalid_key": 0.014177378000113094, + "tests/aws/services/kms/test_kms.py::TestKMS::test_list_keys": 0.02903236099973583, + "tests/aws/services/kms/test_kms.py::TestKMS::test_list_retirable_grants": 0.07021631699967656, + "tests/aws/services/kms/test_kms.py::TestKMS::test_non_multi_region_keys_should_not_have_multi_region_properties": 0.17665338499978134, + "tests/aws/services/kms/test_kms.py::TestKMS::test_plaintext_size_for_encrypt": 0.10579461099996479, + "tests/aws/services/kms/test_kms.py::TestKMS::test_re_encrypt[RSA_2048-RSAES_OAEP_SHA_256]": 0.21262188599985166, + "tests/aws/services/kms/test_kms.py::TestKMS::test_re_encrypt[SYMMETRIC_DEFAULT-SYMMETRIC_DEFAULT]": 0.1422479789996487, + "tests/aws/services/kms/test_kms.py::TestKMS::test_re_encrypt_incorrect_source_key": 0.13156985700015866, + "tests/aws/services/kms/test_kms.py::TestKMS::test_re_encrypt_invalid_destination_key": 0.05421838899997056, + "tests/aws/services/kms/test_kms.py::TestKMS::test_replicate_key": 0.5328271420000874, + "tests/aws/services/kms/test_kms.py::TestKMS::test_retire_grant_with_grant_id_and_key_id": 0.05861383700016631, + "tests/aws/services/kms/test_kms.py::TestKMS::test_retire_grant_with_grant_token": 0.05847788900018713, + "tests/aws/services/kms/test_kms.py::TestKMS::test_revoke_grant": 0.05984837799996967, + "tests/aws/services/kms/test_kms.py::TestKMS::test_rotate_key_on_demand_modifies_key_material": 0.118755358000044, + "tests/aws/services/kms/test_kms.py::TestKMS::test_rotate_key_on_demand_raises_error_given_key_is_disabled": 0.5464327340000636, + "tests/aws/services/kms/test_kms.py::TestKMS::test_rotate_key_on_demand_raises_error_given_key_that_does_not_exist": 0.08981469099990136, + "tests/aws/services/kms/test_kms.py::TestKMS::test_rotate_key_on_demand_raises_error_given_key_with_imported_key_material": 0.10712140500004352, + "tests/aws/services/kms/test_kms.py::TestKMS::test_rotate_key_on_demand_raises_error_given_non_symmetric_key": 0.5030209799999739, + "tests/aws/services/kms/test_kms.py::TestKMS::test_rotate_key_on_demand_with_symmetric_key_and_automatic_rotation_disabled": 0.12121129599995584, + "tests/aws/services/kms/test_kms.py::TestKMS::test_rotate_key_on_demand_with_symmetric_key_and_automatic_rotation_enabled": 0.14088107600014155, + "tests/aws/services/kms/test_kms.py::TestKMS::test_schedule_and_cancel_key_deletion": 0.04794804799985286, + "tests/aws/services/kms/test_kms.py::TestKMS::test_sign_verify[ECC_NIST_P256-ECDSA_SHA_256]": 0.30840894599987223, + "tests/aws/services/kms/test_kms.py::TestKMS::test_sign_verify[ECC_NIST_P384-ECDSA_SHA_384]": 0.31608677700000953, + "tests/aws/services/kms/test_kms.py::TestKMS::test_sign_verify[ECC_SECG_P256K1-ECDSA_SHA_256]": 0.3222830080001131, + "tests/aws/services/kms/test_kms.py::TestKMS::test_sign_verify[RSA_2048-RSASSA_PSS_SHA_256]": 0.755702220999865, + "tests/aws/services/kms/test_kms.py::TestKMS::test_sign_verify[RSA_2048-RSASSA_PSS_SHA_384]": 0.7854651709999416, + "tests/aws/services/kms/test_kms.py::TestKMS::test_sign_verify[RSA_2048-RSASSA_PSS_SHA_512]": 0.7129487149995839, + "tests/aws/services/kms/test_kms.py::TestKMS::test_sign_verify[RSA_4096-RSASSA_PKCS1_V1_5_SHA_256]": 3.315103457999612, + "tests/aws/services/kms/test_kms.py::TestKMS::test_sign_verify[RSA_4096-RSASSA_PKCS1_V1_5_SHA_512]": 3.269015678999949, + "tests/aws/services/kms/test_kms.py::TestKMS::test_symmetric_encrypt_offline_decrypt_online[RSA_2048-RSAES_OAEP_SHA_1]": 0.11190859199973602, + "tests/aws/services/kms/test_kms.py::TestKMS::test_symmetric_encrypt_offline_decrypt_online[RSA_2048-RSAES_OAEP_SHA_256]": 0.10059005299990531, + "tests/aws/services/kms/test_kms.py::TestKMS::test_symmetric_encrypt_offline_decrypt_online[RSA_3072-RSAES_OAEP_SHA_1]": 0.20841363299996374, + "tests/aws/services/kms/test_kms.py::TestKMS::test_symmetric_encrypt_offline_decrypt_online[RSA_3072-RSAES_OAEP_SHA_256]": 0.30233536900004765, + "tests/aws/services/kms/test_kms.py::TestKMS::test_symmetric_encrypt_offline_decrypt_online[RSA_4096-RSAES_OAEP_SHA_1]": 0.6028183949999857, + "tests/aws/services/kms/test_kms.py::TestKMS::test_symmetric_encrypt_offline_decrypt_online[RSA_4096-RSAES_OAEP_SHA_256]": 0.5699651499999163, + "tests/aws/services/kms/test_kms.py::TestKMS::test_tag_existing_key_and_untag": 0.12722007100001065, + "tests/aws/services/kms/test_kms.py::TestKMS::test_tag_existing_key_with_invalid_tag_key": 0.10559854799998902, + "tests/aws/services/kms/test_kms.py::TestKMS::test_tag_key_with_duplicate_tag_keys_raises_error": 0.10647233600025174, + "tests/aws/services/kms/test_kms.py::TestKMS::test_untag_key_partially": 0.11968027899979461, + "tests/aws/services/kms/test_kms.py::TestKMS::test_update_alias": 0.08491713200032791, + "tests/aws/services/kms/test_kms.py::TestKMS::test_update_and_add_tags_on_tagged_key": 0.12199880900016069, + "tests/aws/services/kms/test_kms.py::TestKMS::test_update_key_description": 0.04555385300022863, + "tests/aws/services/kms/test_kms.py::TestKMS::test_verify_salt_length[ECC_NIST_P256-ECDSA_SHA_256]": 0.04506675500010715, + "tests/aws/services/kms/test_kms.py::TestKMS::test_verify_salt_length[ECC_NIST_P384-ECDSA_SHA_384]": 0.04570306100004018, + "tests/aws/services/kms/test_kms.py::TestKMS::test_verify_salt_length[ECC_SECG_P256K1-ECDSA_SHA_256]": 0.0453011519998654, + "tests/aws/services/kms/test_kms.py::TestKMS::test_verify_salt_length[RSA_2048-RSASSA_PSS_SHA_256]": 0.18669400000021596, + "tests/aws/services/kms/test_kms.py::TestKMS::test_verify_salt_length[RSA_2048-RSASSA_PSS_SHA_384]": 0.17848564199994144, + "tests/aws/services/kms/test_kms.py::TestKMS::test_verify_salt_length[RSA_2048-RSASSA_PSS_SHA_512]": 0.1905357760001607, + "tests/aws/services/kms/test_kms.py::TestKMS::test_verify_salt_length[RSA_4096-RSASSA_PKCS1_V1_5_SHA_256]": 0.9618172819998563, + "tests/aws/services/kms/test_kms.py::TestKMS::test_verify_salt_length[RSA_4096-RSASSA_PKCS1_V1_5_SHA_512]": 1.1111577010001383, + "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_encryption_context_generate_data_key": 0.18617593200019655, + "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_encryption_context_generate_data_key_pair": 0.17906635199983612, + "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_encryption_context_generate_data_key_pair_without_plaintext": 0.18518287100005182, + "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_encryption_context_generate_data_key_without_plaintext": 0.1900614589997076, + "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_generate_data_key": 0.03690253600007054, + "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_generate_data_key_pair": 0.06480290999979843, + "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_generate_data_key_pair_dry_run": 0.03204358999983015, + "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_generate_data_key_pair_without_plaintext": 0.11516633400015053, + "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_generate_data_key_pair_without_plaintext_dry_run": 0.0917153230002441, + "tests/aws/services/kms/test_kms.py::TestKMSGenerateKeys::test_generate_data_key_without_plaintext": 0.031834329000048456, + "tests/aws/services/kms/test_kms.py::TestKMSMultiAccounts::test_cross_accounts_access": 1.7380291100000704, + "tests/aws/services/lambda_/event_source_mapping/test_cfn_resource.py::test_adding_tags": 12.541035652000119, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_deletion_event_source_mapping_with_dynamodb": 6.191236356999752, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_disabled_dynamodb_event_source_mapping": 12.348712562000173, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_duplicate_event_source_mappings": 5.618697788999725, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_event_filter[content_filter_type]": 12.853484186000287, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_event_filter[content_multiple_filters]": 0.009238353999990068, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_event_filter[content_or_filter]": 12.879296250000152, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_event_filter[date_time_conversion]": 12.839321594000012, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_event_filter[exists_false_filter]": 12.895846191999908, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_event_filter[exists_filter_type]": 12.863102254000296, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_event_filter[insert_same_entry_twice]": 12.821136056000114, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_event_filter[numeric_filter]": 13.879912709999871, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_event_filter[prefix_filter]": 12.825698371000044, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_event_source_mapping": 14.846101667000084, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_event_source_mapping_with_on_failure_destination_config": 11.368972008000128, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_event_source_mapping_with_s3_on_failure_destination": 11.506200328999967, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_event_source_mapping_with_sns_on_failure_destination_config": 11.366024104999951, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_invalid_event_filter[[{\"eventName\": [\"INSERT\"=123}]]": 4.574729243999855, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_invalid_event_filter[single-string]": 4.573033073999795, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_report_batch_item_failure_scenarios[empty_string_item_identifier_failure]": 14.941665695999973, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_report_batch_item_failure_scenarios[invalid_key_foo_failure]": 14.847551489000125, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_report_batch_item_failure_scenarios[invalid_key_foo_null_value_failure]": 14.833675801000254, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_report_batch_item_failure_scenarios[item_identifier_not_present_failure]": 14.864348080000127, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_report_batch_item_failure_scenarios[null_item_identifier_failure]": 14.843765351999991, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_report_batch_item_failure_scenarios[unhandled_exception_in_function]": 14.872119080000175, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_report_batch_item_failures": 15.218066020999913, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_report_batch_item_success_scenarios[empty_batch_item_failure_success]": 9.774847147999935, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_report_batch_item_success_scenarios[empty_dict_success]": 10.917830376999973, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_report_batch_item_success_scenarios[empty_list_success]": 9.806257493999965, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_report_batch_item_success_scenarios[null_batch_item_failure_success]": 9.757749391999823, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_dynamodb_report_batch_item_success_scenarios[null_success]": 9.80292863800014, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py::TestDynamoDBEventSourceMapping::test_esm_with_not_existing_dynamodb_stream": 1.8334410830002525, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisEventFiltering::test_kinesis_event_filtering_json_pattern": 9.26651315700019, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_create_kinesis_event_source_mapping": 12.144538246000138, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_create_kinesis_event_source_mapping_multiple_lambdas_single_kinesis_event_stream": 19.435743597999817, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_disable_kinesis_event_source_mapping": 29.288944936000235, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_duplicate_event_source_mappings": 3.44413858300004, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_esm_with_not_existing_kinesis_stream": 1.4172446769998714, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_empty_provided": 9.260815192999644, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_event_source_mapping_with_async_invocation": 20.211810517999993, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_event_source_mapping_with_on_failure_destination_config": 9.21996214700016, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_event_source_mapping_with_s3_on_failure_destination": 9.305286427000283, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_event_source_mapping_with_sns_on_failure_destination_config": 9.25112994799997, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_event_source_trim_horizon": 26.330681339999956, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_maximum_record_age_exceeded[expire-before-ingestion]": 14.3887581460001, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_maximum_record_age_exceeded[expire-while-retrying]": 9.372164484999985, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_maximum_record_age_exceeded_discard_records": 19.41394500100023, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_report_batch_item_failure_scenarios[empty_string_item_identifier_failure]": 12.200151101000074, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_report_batch_item_failure_scenarios[invalid_key_foo_failure]": 12.228816929000232, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_report_batch_item_failure_scenarios[invalid_key_foo_null_value_failure]": 12.209553417000052, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_report_batch_item_failure_scenarios[item_identifier_not_present_failure]": 12.191459682999948, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_report_batch_item_failure_scenarios[null_item_identifier_failure]": 12.206344607999654, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_report_batch_item_failure_scenarios[unhandled_exception_in_function]": 12.214424557999791, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_report_batch_item_failures": 12.32019953899976, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_report_batch_item_success_scenarios[empty_batch_item_failure_success]": 7.149461509000048, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_report_batch_item_success_scenarios[empty_dict_success]": 7.1245380639998075, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_report_batch_item_success_scenarios[empty_list_success]": 8.264709756000002, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_report_batch_item_success_scenarios[empty_string_success]": 7.124745953999991, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_report_batch_item_success_scenarios[null_batch_item_failure_success]": 7.165237989999923, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_kinesis.py::TestKinesisSource::test_kinesis_report_batch_item_success_scenarios[null_success]": 7.146712688000207, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_duplicate_event_source_mappings": 2.6031207519995405, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_event_source_mapping_default_batch_size": 3.474526174999937, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_filter[and]": 6.4656855090001955, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_filter[exists]": 7.560251762999542, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_filter[numeric-bigger]": 6.441665234000084, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_filter[numeric-range]": 6.453458142999807, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_filter[numeric-smaller]": 6.430260901999645, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_filter[or]": 6.448308250000309, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_filter[plain-string-filter]": 0.0026974259994858585, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_filter[plain-string-matching]": 0.0037125919998288737, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_filter[prefix]": 6.47439854500044, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_filter[single]": 6.486439485999881, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_filter[valid-json-filter]": 6.47593314400001, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_source_mapping": 6.390761866000048, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_source_mapping_batch_size[10000]": 9.584619455000166, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_source_mapping_batch_size[1000]": 9.563200401999893, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_source_mapping_batch_size[100]": 9.575378006999927, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_source_mapping_batch_size[15]": 9.556642638000085, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_source_mapping_batch_size_override[10000]": 0.012206848000005266, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_source_mapping_batch_size_override[1000]": 9.045478461999664, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_source_mapping_batch_size_override[100]": 6.65445819200022, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_source_mapping_batch_size_override[20]": 6.4574279679995925, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_source_mapping_batching_reserved_concurrency": 8.675899381999898, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_source_mapping_batching_window_size_override": 26.798073158000534, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_event_source_mapping_update": 12.736332385999958, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_invalid_event_filter[None]": 1.262810097000056, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_invalid_event_filter[invalid_filter2]": 1.254674943000282, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_invalid_event_filter[invalid_filter3]": 1.2454660699995657, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::TestSQSEventSourceMapping::test_sqs_invalid_event_filter[simple string]": 1.239644080999824, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::test_esm_with_not_existing_sqs_queue": 1.1944951429998127, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::test_failing_lambda_retries_after_visibility_timeout": 15.41487974499978, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::test_fifo_message_group_parallelism": 63.49388072700003, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::test_message_body_and_attributes_passed_correctly": 4.559201275000078, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::test_redrive_policy_with_failing_lambda": 20.51138577399979, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::test_report_batch_item_failures": 0.003093636999892624, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::test_report_batch_item_failures_empty_json_batch_succeeds": 10.737864171999945, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::test_report_batch_item_failures_invalid_result_json_batch_fails": 16.717805552000073, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::test_report_batch_item_failures_on_lambda_error": 11.431813969999894, + "tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_sqs.py::test_sqs_queue_as_lambda_dead_letter_queue": 6.2821365960001, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaAliases::test_alias_routingconfig": 3.1396465300001637, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaAliases::test_lambda_alias_moving": 3.3983593669997845, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaBaseFeatures::test_assume_role[1]": 1.718888715999583, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaBaseFeatures::test_assume_role[2]": 1.7417046209993714, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaBaseFeatures::test_function_state": 1.24880711600008, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaBaseFeatures::test_lambda_different_iam_keys_environment": 3.8126528779998807, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaBaseFeatures::test_lambda_large_response": 1.6710339660003228, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaBaseFeatures::test_lambda_too_large_response": 1.8949807469998632, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaBaseFeatures::test_lambda_too_large_response_but_with_custom_limit": 1.6207892439992975, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaBaseFeatures::test_large_payloads": 1.8456755889997112, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaBehavior::test_ignore_architecture": 1.5564543660002528, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaBehavior::test_lambda_cache_local[nodejs]": 7.715819646, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaBehavior::test_lambda_cache_local[python]": 1.6800935039996148, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaBehavior::test_lambda_host_prefix_api_operation": 8.44895280899982, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaBehavior::test_lambda_init_environment": 3.726794152999446, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaBehavior::test_lambda_invoke_no_timeout": 3.6525966789999984, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaBehavior::test_lambda_invoke_timed_out_environment_reuse": 0.002838518999851658, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaBehavior::test_lambda_invoke_with_timeout": 4.669718122000177, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaBehavior::test_mixed_architecture": 0.002687376999801927, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaBehavior::test_runtime_introspection_arm": 0.0025128709999080456, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaBehavior::test_runtime_introspection_x86": 1.8437497909999365, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaBehavior::test_runtime_ulimits": 1.637679021999702, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaCleanup::test_delete_lambda_during_sync_invoke": 0.0016889170001377352, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaCleanup::test_recreate_function": 3.3817461610001374, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaConcurrency::test_lambda_concurrency_block": 17.811197213000014, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaConcurrency::test_lambda_concurrency_crud": 1.2272187649998614, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaConcurrency::test_lambda_concurrency_update": 1.3725548410002375, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaConcurrency::test_lambda_provisioned_concurrency_moves_with_alias": 0.002999570999918433, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaConcurrency::test_lambda_provisioned_concurrency_scheduling": 8.495376017000353, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaConcurrency::test_provisioned_concurrency": 3.454744810000193, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaConcurrency::test_provisioned_concurrency_on_alias": 2.9431417190000957, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaConcurrency::test_reserved_concurrency": 12.980825810999931, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaConcurrency::test_reserved_concurrency_async_queue": 3.9451444569999694, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaConcurrency::test_reserved_provisioned_overlap": 10.183843883999998, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaErrors::test_lambda_handler_error": 1.5954365820000476, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaErrors::test_lambda_handler_exit": 0.0025065859999813256, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaErrors::test_lambda_invoke_payload_encoding_error[body-n\\x87r\\x9e\\xe9\\xb5\\xd7I\\xee\\x9bmt]": 1.359920203999991, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaErrors::test_lambda_invoke_payload_encoding_error[message-\\x99\\xeb,j\\x07\\xa1zYh]": 1.3480156959999476, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaErrors::test_lambda_runtime_error": 7.710184544999947, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaErrors::test_lambda_runtime_exit": 0.0017526510000607232, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaErrors::test_lambda_runtime_exit_segfault": 0.0016441459999896324, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaErrors::test_lambda_runtime_startup_error": 1.2713050639997618, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaErrors::test_lambda_runtime_startup_timeout": 41.26370745500026, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaErrors::test_lambda_runtime_wrapper_not_found": 0.0019378679999135784, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_type_dry_run[nodejs16.x]": 0.0020571799998378992, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_type_dry_run[python3.10]": 0.002308165999920675, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_type_event[nodejs16.x]": 2.276463521999972, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_type_event[python3.10]": 2.2810139520000803, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_type_event_error": 0.0021280909998040443, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_type_no_return_payload[nodejs-Event]": 2.2702219800000876, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_type_no_return_payload[nodejs-RequestResponse]": 8.705126933999964, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_type_no_return_payload[python-Event]": 2.261685570000054, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_type_no_return_payload[python-RequestResponse]": 2.5946942509999644, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_type_request_response[nodejs16.x]": 1.6648900060000642, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_type_request_response[python3.10]": 1.6213526060000731, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_with_logs[nodejs16.x]": 15.767191518000004, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_with_logs[python3.10]": 15.725643177999928, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invocation_with_qualifier": 1.8691145529999176, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_invoke_exceptions": 0.1118994199999861, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_lambda_with_context": 0.005753272999982073, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaFeatures::test_upload_lambda_from_s3": 2.1427060169994547, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaMultiAccounts::test_delete_function": 1.1626013319998947, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaMultiAccounts::test_function_alias": 1.1456884199999422, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaMultiAccounts::test_function_concurrency": 1.1547177170000396, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaMultiAccounts::test_function_invocation": 1.5172741890000907, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaMultiAccounts::test_function_tags": 1.1476046299997051, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaMultiAccounts::test_get_function": 1.131605942999613, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaMultiAccounts::test_get_function_configuration": 1.1317489079999632, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaMultiAccounts::test_get_lambda_layer": 0.2600195969998822, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaMultiAccounts::test_list_versions_by_function": 1.1388133770001332, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaMultiAccounts::test_publish_version": 1.2211362540001574, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaPermissions::test_lambda_permission_url_invocation": 0.00238622500000929, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_update_function_url_config": 1.6874640070000169, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_echo_http_fixture_default": 2.538194532000034, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_echo_http_fixture_trim_x_headers": 2.3243644140000015, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_echo_invoke[BUFFERED]": 19.38640573800012, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_echo_invoke[None]": 2.2616022089996477, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_echo_invoke[RESPONSE_STREAM]": 0.015349896000088847, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_form_payload": 2.7144261849999793, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_headers_and_status": 16.026446216999943, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_invalid_invoke_mode": 1.7373517850001008, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_invocation[boolean]": 1.8371176770001512, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_invocation[dict]": 1.85167371200032, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_invocation[float]": 1.8332385409999006, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_invocation[http-response-json]": 1.8612709859999086, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_invocation[http-response]": 1.8523304969999117, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_invocation[integer]": 1.857232804999967, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_invocation[list-mixed]": 1.8477032130003863, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_invocation[string]": 1.8420263039997735, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_invocation_custom_id": 1.5456908199998907, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_invocation_custom_id_aliased": 1.5729064050005945, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_invocation_exception": 2.289011624000068, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_non_existing_url": 0.02390143499997066, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaURL::test_lambda_url_persists_after_alias_delete": 4.544209409000018, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaVersions::test_async_invoke_queue_upon_function_update": 93.75985504099981, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaVersions::test_function_update_during_invoke": 0.0023605260000749695, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaVersions::test_lambda_handler_update": 3.1787452839998878, + "tests/aws/services/lambda_/test_lambda.py::TestLambdaVersions::test_lambda_versions_with_code_changes": 5.556343773999515, + "tests/aws/services/lambda_/test_lambda.py::TestRequestIdHandling::test_request_id_async_invoke_with_retry": 11.274985036999851, + "tests/aws/services/lambda_/test_lambda.py::TestRequestIdHandling::test_request_id_format": 0.02573745700010477, + "tests/aws/services/lambda_/test_lambda.py::TestRequestIdHandling::test_request_id_invoke": 3.6771636099999796, + "tests/aws/services/lambda_/test_lambda.py::TestRequestIdHandling::test_request_id_invoke_url": 3.618407047000119, + "tests/aws/services/lambda_/test_lambda_api.py::TestCodeSigningConfig::test_code_signing_not_found_excs": 1.3190174850001313, + "tests/aws/services/lambda_/test_lambda_api.py::TestCodeSigningConfig::test_function_code_signing_config": 1.2903955219999261, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaAccountSettings::test_account_settings": 0.09284891699985565, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaAccountSettings::test_account_settings_total_code_size": 1.4299462680003217, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaAccountSettings::test_account_settings_total_code_size_config_update": 1.3065426759999355, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaAlias::test_alias_lifecycle": 1.5076486899999963, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaAlias::test_alias_naming": 1.6331631420000576, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaAlias::test_non_existent_alias_deletion": 1.200358635000157, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaAlias::test_non_existent_alias_update": 1.1983476230000178, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaAlias::test_notfound_and_invalid_routingconfigs": 1.4170006960000592, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaEventInvokeConfig::test_lambda_eventinvokeconfig_exceptions": 2.7773233940001774, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaEventInvokeConfig::test_lambda_eventinvokeconfig_lifecycle": 1.3617054379999445, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaEventSourceMappings::test_create_event_filter_criteria_validation": 3.522545082999841, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaEventSourceMappings::test_create_event_source_self_managed": 0.0018367359998592292, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaEventSourceMappings::test_create_event_source_validation": 3.42653706100009, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaEventSourceMappings::test_create_event_source_validation_kinesis": 1.9183465759999763, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaEventSourceMappings::test_event_source_mapping_exceptions": 0.15261563099988962, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaEventSourceMappings::test_event_source_mapping_lifecycle": 7.371975707000047, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaEventSourceMappings::test_event_source_mapping_lifecycle_delete_function": 6.052579371000093, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaEventSourceMappings::test_function_name_variations": 16.0585537259999, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_create_lambda_exceptions": 0.15909726600034446, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_delete_on_nonexisting_version": 1.221831433999796, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_arns": 2.5627251860000797, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_lifecycle": 9.556605144000287, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[full_arn_and_qualifier_too_long_and_invalid_region-create_function]": 0.7547872469999675, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[full_arn_and_qualifier_too_long_and_invalid_region-delete_function]": 0.0884218119997513, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[full_arn_and_qualifier_too_long_and_invalid_region-get_function]": 0.08801976500012643, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[full_arn_and_qualifier_too_long_and_invalid_region-invoke]": 0.08870598799990148, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[full_arn_with_multiple_qualifiers-create_function]": 0.1008665319998272, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[full_arn_with_multiple_qualifiers-delete_function]": 0.08735444900003131, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[full_arn_with_multiple_qualifiers-get_function]": 0.08876660900000388, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[full_arn_with_multiple_qualifiers-invoke]": 0.08745538300013322, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[function_name_is_single_invalid-create_function]": 0.10162813899978573, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[function_name_is_single_invalid-delete_function]": 0.08838500199999544, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[function_name_is_single_invalid-get_function]": 0.08920549700019365, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[function_name_is_single_invalid-invoke]": 0.08802409099985198, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[function_name_too_long-create_function]": 0.10155649399985123, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[function_name_too_long-delete_function]": 0.08925183199971798, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[function_name_too_long-get_function]": 0.0877293030000601, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[function_name_too_long-invoke]": 0.007930472000225564, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[function_name_too_long_and_invalid_region-create_function]": 0.10205394699983117, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[function_name_too_long_and_invalid_region-delete_function]": 0.08742217099984373, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[function_name_too_long_and_invalid_region-get_function]": 0.08883972499984338, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[function_name_too_long_and_invalid_region-invoke]": 0.08789310100019065, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[incomplete_arn-create_function]": 0.007891658999824358, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[incomplete_arn-delete_function]": 0.08835341100007099, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[incomplete_arn-get_function]": 0.08820857299997442, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[incomplete_arn-invoke]": 0.007897109999703389, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_account_id_in_partial_arn-create_function]": 0.1001018390002173, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_account_id_in_partial_arn-delete_function]": 0.08802224600003683, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_account_id_in_partial_arn-get_function]": 0.0893069439998726, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_account_id_in_partial_arn-invoke]": 0.08838213600006384, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_characters_in_function_name-create_function]": 0.10282009800016567, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_characters_in_function_name-delete_function]": 0.08902813800000331, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_characters_in_function_name-get_function]": 0.09277842699998473, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_characters_in_function_name-invoke]": 0.08935021600018445, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_characters_in_qualifier-create_function]": 0.1018771359999846, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_characters_in_qualifier-delete_function]": 0.08724685099991802, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_characters_in_qualifier-get_function]": 0.08820810199972584, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_characters_in_qualifier-invoke]": 0.08796918299958634, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_region_in_arn-create_function]": 0.10067769099987345, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_region_in_arn-delete_function]": 0.08715925200021957, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_region_in_arn-get_function]": 0.08792544699986138, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[invalid_region_in_arn-invoke]": 0.08798738200016487, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[latest_version_with_additional_qualifier-create_function]": 0.10204160400007822, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[latest_version_with_additional_qualifier-delete_function]": 0.0875028730001759, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[latest_version_with_additional_qualifier-get_function]": 0.08891635600002701, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[latest_version_with_additional_qualifier-invoke]": 0.08799356400004399, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[lowercase_latest_qualifier-create_function]": 0.10183134600015364, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[lowercase_latest_qualifier-delete_function]": 0.00817999500031874, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[lowercase_latest_qualifier-get_function]": 0.08778703700022561, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[lowercase_latest_qualifier-invoke]": 0.08811705299967798, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[missing_account_id_in_arn-create_function]": 0.10461156700011998, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[missing_account_id_in_arn-delete_function]": 0.09823772700019617, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[missing_account_id_in_arn-get_function]": 0.09170790899997883, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[missing_account_id_in_arn-invoke]": 0.09806081499982611, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[missing_region_in_arn-create_function]": 0.11028611000006094, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[missing_region_in_arn-delete_function]": 0.0889594309999211, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[missing_region_in_arn-get_function]": 0.08736499600013303, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[missing_region_in_arn-invoke]": 0.09527316300022903, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[misspelled_latest_in_arn-create_function]": 0.10174479399984193, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[misspelled_latest_in_arn-delete_function]": 0.0877127080000264, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[misspelled_latest_in_arn-get_function]": 0.08916226599990296, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[misspelled_latest_in_arn-invoke]": 0.08888665599988599, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[non_lambda_arn-create_function]": 0.1023087549997399, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[non_lambda_arn-delete_function]": 0.0873213229999692, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[non_lambda_arn-get_function]": 0.0880439469999601, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[non_lambda_arn-invoke]": 0.08990755199988598, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[partial_arn_with_extra_qualifier-create_function]": 0.10148255800004335, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[partial_arn_with_extra_qualifier-delete_function]": 0.08745746699969459, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[partial_arn_with_extra_qualifier-get_function]": 0.08782042500001808, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[partial_arn_with_extra_qualifier-invoke]": 0.08804142400003911, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[qualifier_too_long-create_function]": 0.10108476100003827, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[qualifier_too_long-delete_function]": 0.08704301900002065, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[qualifier_too_long-get_function]": 0.0871047149998958, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_function_name_and_qualifier_validation[qualifier_too_long-invoke]": 0.08833030699997835, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_get_function_wrong_region[delete_function]": 1.2030194100000244, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_get_function_wrong_region[get_function]": 1.2158654329996352, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_get_function_wrong_region[get_function_code_signing_config]": 1.188823376000073, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_get_function_wrong_region[get_function_concurrency]": 1.1842262650000066, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_get_function_wrong_region[get_function_configuration]": 1.206499026000074, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_get_function_wrong_region[get_function_event_invoke_config]": 1.2002878719997625, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_get_function_wrong_region[get_function_url_config]": 1.2054965899999388, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_get_function_wrong_region[invoke]": 1.2041038099998786, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_invalid_invoke": 0.08910819500010803, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_invalid_vpc_config_security_group": 0.0016141090000019176, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_invalid_vpc_config_subnet": 0.4834410570001637, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_lambda_code_location_s3": 1.4612896470002852, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_lambda_code_location_zipfile": 1.4601643160001458, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_lambda_concurrent_code_updates": 2.2908133429998543, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_lambda_concurrent_config_updates": 2.2521450879999065, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_list_functions": 2.4869067390000055, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_ops_on_nonexisting_fn[delete_function]": 0.09116318999963369, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_ops_on_nonexisting_fn[get_function]": 0.09005214599983447, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_ops_on_nonexisting_fn[get_function_code_signing_config]": 0.0907247859997824, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_ops_on_nonexisting_fn[get_function_concurrency]": 0.08939689900012127, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_ops_on_nonexisting_fn[get_function_configuration]": 0.09124519299984968, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_ops_on_nonexisting_fn[get_function_event_invoke_config]": 0.08954257799973675, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_ops_on_nonexisting_fn[get_function_url_config]": 0.08871163699973295, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_ops_on_nonexisting_version[get_function]": 1.1986779700000625, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_ops_on_nonexisting_version[get_function_configuration]": 1.2034181379997335, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_ops_on_nonexisting_version[get_function_event_invoke_config]": 1.2054227500000252, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_ops_with_arn_qualifier_mismatch[delete_function]": 0.0997374400001263, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_ops_with_arn_qualifier_mismatch[get_function]": 0.0970064249997904, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_ops_with_arn_qualifier_mismatch[get_function_configuration]": 0.0980635999999322, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_redundant_updates": 1.295875659000103, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_update_lambda_exceptions": 1.2065533820000383, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaFunction::test_vpc_config": 2.140163329999723, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaImages::test_lambda_image_and_image_config_crud": 1.5409253840000474, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaImages::test_lambda_image_crud": 4.260486441000012, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaImages::test_lambda_image_versions": 1.6018417469999804, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaImages::test_lambda_zip_file_to_image": 1.4454686430001402, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaLayer::test_layer_compatibilities[runtimes0]": 0.1297597410000435, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaLayer::test_layer_compatibilities[runtimes1]": 0.13174750800021684, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaLayer::test_layer_deterministic_version": 0.06440910300034375, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaLayer::test_layer_exceptions": 0.29845610500001385, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaLayer::test_layer_function_exceptions": 17.476814110000078, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaLayer::test_layer_function_quota_exception": 16.3761926159998, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaLayer::test_layer_lifecycle": 1.492815968999821, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaLayer::test_layer_policy_exceptions": 0.24508717900016563, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaLayer::test_layer_policy_lifecycle": 0.1856204389996492, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaLayer::test_layer_s3_content": 0.21755182900028558, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaPermissions::test_add_lambda_permission_aws": 1.211669997999934, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaPermissions::test_add_lambda_permission_fields": 1.280301254000051, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaPermissions::test_create_multiple_lambda_permissions": 1.231731530000161, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaPermissions::test_lambda_permission_fn_versioning": 1.359412058999851, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaPermissions::test_permission_exceptions": 1.3333234979997997, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaPermissions::test_remove_multi_permissions": 1.2737341730000935, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaProvisionedConcurrency::test_lambda_provisioned_lifecycle": 2.447428605000141, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaProvisionedConcurrency::test_provisioned_concurrency_exceptions": 1.3652053969997269, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaProvisionedConcurrency::test_provisioned_concurrency_limits": 1.2527217809997637, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaRecursion::test_put_function_recursion_config_allow": 1.2121039579999433, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaRecursion::test_put_function_recursion_config_default_terminate": 1.195062088999748, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaRecursion::test_put_function_recursion_config_invalid_value": 1.1969943240003431, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaReservedConcurrency::test_function_concurrency": 1.2291467399998055, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaReservedConcurrency::test_function_concurrency_exceptions": 1.2274422900002264, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaReservedConcurrency::test_function_concurrency_limits": 1.2195561539999744, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaRevisions::test_function_revisions_basic": 13.67796139699999, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaRevisions::test_function_revisions_permissions": 1.2712238950002757, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaRevisions::test_function_revisions_version_and_alias": 1.3477899020001587, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSizeLimits::test_lambda_envvars_near_limit_succeeds": 1.291283126000053, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSizeLimits::test_large_environment_fails_multiple_keys": 16.211631318999935, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSizeLimits::test_large_environment_variables_fails": 16.21707043100014, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSizeLimits::test_large_lambda": 12.367211152000209, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSizeLimits::test_oversized_request_create_lambda": 2.080838936999953, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSizeLimits::test_oversized_unzipped_lambda": 4.7266379349998715, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSizeLimits::test_oversized_zipped_create_lambda": 1.5718942529999822, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSnapStart::test_snapstart_exceptions": 0.10752271799992741, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSnapStart::test_snapstart_lifecycle[dotnet8]": 4.324149942000076, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSnapStart::test_snapstart_lifecycle[java11]": 3.2920675710001888, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSnapStart::test_snapstart_lifecycle[java17]": 3.2124793269997554, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSnapStart::test_snapstart_lifecycle[java21]": 3.326676116000044, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSnapStart::test_snapstart_lifecycle[python3.12]": 1.2574053340001683, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSnapStart::test_snapstart_lifecycle[python3.13]": 1.2840751720002572, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSnapStart::test_snapstart_update_function_configuration[dotnet8]": 1.239703972999905, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSnapStart::test_snapstart_update_function_configuration[java11]": 1.2547960140000214, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSnapStart::test_snapstart_update_function_configuration[java17]": 1.2829569300001822, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSnapStart::test_snapstart_update_function_configuration[java21]": 1.2473053930000333, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSnapStart::test_snapstart_update_function_configuration[python3.12]": 1.2396175940000376, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaSnapStart::test_snapstart_update_function_configuration[python3.13]": 1.2565196370003378, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaTag::test_create_tag_on_esm_create": 1.3291881699997248, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaTag::test_create_tag_on_fn_create": 1.2290101379999214, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaTag::test_tag_exceptions[event_source_mapping]": 0.11885980700026266, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaTag::test_tag_exceptions[lambda_function]": 0.12100729200005844, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaTag::test_tag_lifecycle[event_source_mapping]": 1.4161304479998762, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaTag::test_tag_lifecycle[lambda_function]": 1.3132946109999466, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaTag::test_tag_nonexisting_resource": 1.250340045999792, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaTags::test_tag_exceptions": 1.3081583000002865, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaTags::test_tag_lifecycle": 1.3616764679998141, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaTags::test_tag_limits": 1.3797031629997036, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaTags::test_tag_versions": 1.2545899999995527, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaUrl::test_create_url_config_custom_id_tag": 1.1332117560002644, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaUrl::test_create_url_config_custom_id_tag_alias": 3.3786815860000843, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaUrl::test_create_url_config_custom_id_tag_invalid_id": 1.1118680839999797, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaUrl::test_url_config_deletion_without_qualifier": 1.3449068919999263, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaUrl::test_url_config_exceptions": 1.5595724370000426, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaUrl::test_url_config_lifecycle": 1.322540368000091, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaUrl::test_url_config_list_paging": 1.380340176000118, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaVersions::test_publish_version_on_create": 1.2691354539999793, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaVersions::test_publish_with_update": 1.3934498280000298, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaVersions::test_publish_with_wrong_sha256": 1.2726388610001322, + "tests/aws/services/lambda_/test_lambda_api.py::TestLambdaVersions::test_version_lifecycle": 3.14893777400016, + "tests/aws/services/lambda_/test_lambda_api.py::TestLoggingConfig::test_advanced_logging_configuration_format_switch": 1.3306916430001365, + "tests/aws/services/lambda_/test_lambda_api.py::TestLoggingConfig::test_function_advanced_logging_configuration": 2.2871210149999115, + "tests/aws/services/lambda_/test_lambda_api.py::TestLoggingConfig::test_function_partial_advanced_logging_configuration_update[partial_config0]": 2.2720323659998485, + "tests/aws/services/lambda_/test_lambda_api.py::TestLoggingConfig::test_function_partial_advanced_logging_configuration_update[partial_config1]": 2.288856936000002, + "tests/aws/services/lambda_/test_lambda_api.py::TestLoggingConfig::test_function_partial_advanced_logging_configuration_update[partial_config2]": 2.2793463190000693, + "tests/aws/services/lambda_/test_lambda_api.py::TestLoggingConfig::test_function_partial_advanced_logging_configuration_update[partial_config3]": 1.8941441770000438, + "tests/aws/services/lambda_/test_lambda_api.py::TestPartialARNMatching::test_cross_region_arn_function_access": 1.14901983499999, + "tests/aws/services/lambda_/test_lambda_api.py::TestPartialARNMatching::test_update_function_configuration_full_arn": 2.233243441999548, + "tests/aws/services/lambda_/test_lambda_api.py::TestRuntimeValidation::test_create_deprecated_function_runtime_with_validation_disabled": 15.19022232799989, + "tests/aws/services/lambda_/test_lambda_api.py::TestRuntimeValidation::test_create_deprecated_function_runtime_with_validation_enabled[dotnetcore3.1]": 0.10243707399968116, + "tests/aws/services/lambda_/test_lambda_api.py::TestRuntimeValidation::test_create_deprecated_function_runtime_with_validation_enabled[go1.x]": 0.10247198799970647, + "tests/aws/services/lambda_/test_lambda_api.py::TestRuntimeValidation::test_create_deprecated_function_runtime_with_validation_enabled[java8]": 0.10498801199992158, + "tests/aws/services/lambda_/test_lambda_api.py::TestRuntimeValidation::test_create_deprecated_function_runtime_with_validation_enabled[nodejs12.x]": 0.1028064170000107, + "tests/aws/services/lambda_/test_lambda_api.py::TestRuntimeValidation::test_create_deprecated_function_runtime_with_validation_enabled[nodejs14.x]": 0.10196799999994255, + "tests/aws/services/lambda_/test_lambda_api.py::TestRuntimeValidation::test_create_deprecated_function_runtime_with_validation_enabled[provided]": 0.10273329299980105, + "tests/aws/services/lambda_/test_lambda_api.py::TestRuntimeValidation::test_create_deprecated_function_runtime_with_validation_enabled[python3.7]": 0.10247558099968046, + "tests/aws/services/lambda_/test_lambda_api.py::TestRuntimeValidation::test_create_deprecated_function_runtime_with_validation_enabled[ruby2.7]": 0.10122983800010843, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[dotnet6]": 1.8806105950000074, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[dotnet8]": 1.87721002100011, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[java11]": 4.943897252999932, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[java17]": 4.090401636000024, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[java21]": 4.450018294999836, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[java8.al2]": 5.955204133000052, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[nodejs16.x]": 1.8167310589999488, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[nodejs18.x]": 1.6836734569997134, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[nodejs20.x]": 1.7756777469999179, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[nodejs22.x]": 1.6427306789996692, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[python3.10]": 1.7275466390001384, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[python3.11]": 1.7080384940002205, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[python3.12]": 1.7259053729999323, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[python3.13]": 1.7831524909997825, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[python3.8]": 1.707024139999703, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[python3.9]": 1.741869263000126, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[ruby3.2]": 2.3402717449998818, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[ruby3.3]": 2.2832336810001834, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaCallingLocalstack::test_manual_endpoint_injection[ruby3.4]": 2.0400697519999085, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[dotnet6]": 3.494246553999801, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[dotnet8]": 2.5528855230002137, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[java11]": 2.503796317999786, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[java17]": 2.424640843999896, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[java21]": 2.4775368060002165, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[java8.al2]": 3.4833431019999352, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[nodejs16.x]": 2.489676282000346, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[nodejs18.x]": 2.498678992000123, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[nodejs20.x]": 2.430283233000182, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[nodejs22.x]": 7.449667802000022, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[provided.al2023]": 3.265368650000255, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[provided.al2]": 4.106061272000034, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[python3.10]": 2.545203942999933, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[python3.11]": 2.5635546939997766, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[python3.12]": 2.5698073660000773, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[python3.13]": 2.6039759250002135, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[python3.8]": 2.7607778900000994, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[python3.9]": 6.606961557999739, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[ruby3.2]": 8.570009588999937, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[ruby3.3]": 11.613489641000115, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_echo_invoke[ruby3.4]": 8.578147272000251, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[dotnet6]": 4.720862491999924, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[dotnet8]": 3.7295547329999863, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[java11]": 3.829747591999876, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[java17]": 3.716582550000112, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[java21]": 4.756357782999885, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[java8.al2]": 4.033336429999736, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[nodejs16.x]": 4.569167765000202, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[nodejs18.x]": 3.6213532790000045, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[nodejs20.x]": 3.7190860200003044, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[nodejs22.x]": 3.5876863999999387, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[provided.al2023]": 3.6637628629998744, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[provided.al2]": 3.628393891999849, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[python3.10]": 3.5976172129999213, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[python3.11]": 3.561076157000116, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[python3.12]": 3.6379527819999566, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[python3.13]": 3.5711602239998683, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[python3.8]": 3.6060452630003965, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[python3.9]": 3.600364374000037, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[ruby3.2]": 3.6335525530000723, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[ruby3.3]": 3.6512160669999503, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_introspection_invoke[ruby3.4]": 3.707666783999912, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[dotnet6]": 1.8238886880001246, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[dotnet8]": 1.8048676549999527, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[java11]": 1.91178578500012, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[java17]": 1.8269835790001707, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[java21]": 1.8315822669999307, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[java8.al2]": 2.0793070659997284, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[nodejs16.x]": 1.7236356439998417, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[nodejs18.x]": 1.7195560410000326, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[nodejs20.x]": 1.7274133870000696, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[nodejs22.x]": 1.662720489000094, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[python3.10]": 1.6854611510000268, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[python3.11]": 1.7016114840002956, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[python3.12]": 1.6438638980002906, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[python3.13]": 1.6671108499997445, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[python3.8]": 1.6968491029999768, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[python3.9]": 1.701859671000193, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[ruby3.2]": 1.766660242999933, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[ruby3.3]": 1.7504008419998627, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_runtime_wrapper_invoke[ruby3.4]": 1.7558742040000652, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[dotnet6]": 1.8329583839999941, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[dotnet8]": 1.8146536940002989, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[java11]": 1.9125299730001188, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[java17]": 1.8461240649999127, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[java21]": 1.8439806409999164, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[java8.al2]": 2.0929024819999995, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[nodejs16.x]": 1.742548319000207, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[nodejs18.x]": 1.7781525450000117, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[nodejs20.x]": 1.7050472169996738, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[nodejs22.x]": 1.7115891379999084, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[provided.al2023]": 1.7291143590002775, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[provided.al2]": 2.768886246999955, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[python3.10]": 1.692717546999802, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[python3.11]": 1.6954424909999943, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[python3.12]": 1.6976075089999085, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[python3.13]": 1.70986305800011, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[python3.8]": 1.7020377950002512, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[python3.9]": 1.699152932000061, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[ruby3.2]": 1.7561629970000467, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[ruby3.3]": 1.7650119130000803, + "tests/aws/services/lambda_/test_lambda_common.py::TestLambdaRuntimesCommon::test_uncaught_exception_invoke[ruby3.4]": 1.8048661720001746, + "tests/aws/services/lambda_/test_lambda_destinations.py::TestLambdaDLQ::test_dead_letter_queue": 20.218355874000054, + "tests/aws/services/lambda_/test_lambda_destinations.py::TestLambdaDestinationEventbridge::test_invoke_lambda_eventbridge": 16.71344005300034, + "tests/aws/services/lambda_/test_lambda_destinations.py::TestLambdaDestinationSqs::test_assess_lambda_destination_invocation[payload0]": 1.901975364000009, + "tests/aws/services/lambda_/test_lambda_destinations.py::TestLambdaDestinationSqs::test_assess_lambda_destination_invocation[payload1]": 1.872234552000009, + "tests/aws/services/lambda_/test_lambda_destinations.py::TestLambdaDestinationSqs::test_lambda_destination_default_retries": 21.399107448999985, + "tests/aws/services/lambda_/test_lambda_destinations.py::TestLambdaDestinationSqs::test_maxeventage": 63.14399650700011, + "tests/aws/services/lambda_/test_lambda_destinations.py::TestLambdaDestinationSqs::test_retries": 22.497012583999776, + "tests/aws/services/lambda_/test_lambda_developer_tools.py::TestDockerFlags::test_additional_docker_flags": 1.5493834450003305, + "tests/aws/services/lambda_/test_lambda_developer_tools.py::TestDockerFlags::test_lambda_docker_networks": 5.693154898999637, + "tests/aws/services/lambda_/test_lambda_developer_tools.py::TestHotReloading::test_hot_reloading[nodejs20.x]": 3.3840609330004554, + "tests/aws/services/lambda_/test_lambda_developer_tools.py::TestHotReloading::test_hot_reloading[python3.12]": 3.3593808299997363, + "tests/aws/services/lambda_/test_lambda_developer_tools.py::TestHotReloading::test_hot_reloading_environment_placeholder": 0.4279780440006107, + "tests/aws/services/lambda_/test_lambda_developer_tools.py::TestHotReloading::test_hot_reloading_error_path_not_absolute": 0.023301980999804073, + "tests/aws/services/lambda_/test_lambda_developer_tools.py::TestHotReloading::test_hot_reloading_publish_version": 0.11566127599962783, + "tests/aws/services/lambda_/test_lambda_developer_tools.py::TestLambdaDNS::test_lambda_localhost_localstack_cloud_connectivity": 1.5421575820000726, + "tests/aws/services/lambda_/test_lambda_integration_xray.py::test_traceid_outside_handler[Active]": 2.5870600190000914, + "tests/aws/services/lambda_/test_lambda_integration_xray.py::test_traceid_outside_handler[PassThrough]": 2.574565793000147, + "tests/aws/services/lambda_/test_lambda_integration_xray.py::test_xray_trace_propagation": 1.5237544030001118, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestCloudwatchLogs::test_multi_line_prints": 3.6222867250007766, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestGoProvidedRuntimes::test_manual_endpoint_injection[provided.al2023]": 1.8368333329999587, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestGoProvidedRuntimes::test_manual_endpoint_injection[provided.al2]": 1.8570417269993413, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestGoProvidedRuntimes::test_uncaught_exception_invoke[provided.al2023]": 2.993950304000009, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestGoProvidedRuntimes::test_uncaught_exception_invoke[provided.al2]": 1.984604443000535, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestJavaRuntimes::test_java_custom_handler_method_specification[cloud.localstack.sample.LambdaHandlerWithInterfaceAndCustom-INTERFACE]": 3.0223312319999422, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestJavaRuntimes::test_java_custom_handler_method_specification[cloud.localstack.sample.LambdaHandlerWithInterfaceAndCustom::handleRequest-INTERFACE]": 3.0125732700003027, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestJavaRuntimes::test_java_custom_handler_method_specification[cloud.localstack.sample.LambdaHandlerWithInterfaceAndCustom::handleRequestCustom-CUSTOM]": 2.997319391000474, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestJavaRuntimes::test_java_lambda_subscribe_sns_topic": 8.835442270000385, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestJavaRuntimes::test_java_runtime_with_lib": 5.6274372779998885, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestJavaRuntimes::test_serializable_input_object[java11]": 2.6430705389998366, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestJavaRuntimes::test_serializable_input_object[java17]": 2.5585273509996114, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestJavaRuntimes::test_serializable_input_object[java21]": 2.7137315549998675, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestJavaRuntimes::test_serializable_input_object[java8.al2]": 2.8404074089994538, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestJavaRuntimes::test_stream_handler[java11]": 1.8174038500001188, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestJavaRuntimes::test_stream_handler[java17]": 1.7079150340000524, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestJavaRuntimes::test_stream_handler[java21]": 1.7857296049996876, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestJavaRuntimes::test_stream_handler[java8.al2]": 1.7106071520001933, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestNodeJSRuntimes::test_invoke_nodejs_es6_lambda[nodejs16.x]": 4.679755252000177, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestNodeJSRuntimes::test_invoke_nodejs_es6_lambda[nodejs18.x]": 4.696529878000547, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestNodeJSRuntimes::test_invoke_nodejs_es6_lambda[nodejs20.x]": 4.6817106300004525, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestNodeJSRuntimes::test_invoke_nodejs_es6_lambda[nodejs22.x]": 4.671121191999646, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestPythonRuntimes::test_handler_in_submodule[python3.10]": 1.6521215279994976, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestPythonRuntimes::test_handler_in_submodule[python3.11]": 1.6595463140001812, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestPythonRuntimes::test_handler_in_submodule[python3.12]": 1.6405968630001553, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestPythonRuntimes::test_handler_in_submodule[python3.13]": 1.6520123309996961, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestPythonRuntimes::test_handler_in_submodule[python3.8]": 1.6376930439996613, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestPythonRuntimes::test_handler_in_submodule[python3.9]": 1.6406329459996414, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestPythonRuntimes::test_python_runtime_correct_versions[python3.10]": 1.5263622229999783, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestPythonRuntimes::test_python_runtime_correct_versions[python3.11]": 1.5250049299997954, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestPythonRuntimes::test_python_runtime_correct_versions[python3.12]": 1.519323983999584, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestPythonRuntimes::test_python_runtime_correct_versions[python3.13]": 1.5479120960003456, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestPythonRuntimes::test_python_runtime_correct_versions[python3.8]": 1.570466267000029, + "tests/aws/services/lambda_/test_lambda_runtimes.py::TestPythonRuntimes::test_python_runtime_correct_versions[python3.9]": 1.5400226989995645, + "tests/aws/services/logs/test_logs.py::TestCloudWatchLogs::test_create_and_delete_log_group": 0.2143328840002141, + "tests/aws/services/logs/test_logs.py::TestCloudWatchLogs::test_create_and_delete_log_stream": 0.5177181779999955, + "tests/aws/services/logs/test_logs.py::TestCloudWatchLogs::test_delivery_logs_for_sns": 1.086059003000173, + "tests/aws/services/logs/test_logs.py::TestCloudWatchLogs::test_filter_log_events_response_header": 0.070151001999875, + "tests/aws/services/logs/test_logs.py::TestCloudWatchLogs::test_list_tags_log_group": 0.2260008299999754, + "tests/aws/services/logs/test_logs.py::TestCloudWatchLogs::test_metric_filters": 0.0017348529995615536, + "tests/aws/services/logs/test_logs.py::TestCloudWatchLogs::test_put_events_multi_bytes_msg": 0.07250434100023995, + "tests/aws/services/logs/test_logs.py::TestCloudWatchLogs::test_put_subscription_filter_firehose": 0.48638784900003884, + "tests/aws/services/logs/test_logs.py::TestCloudWatchLogs::test_put_subscription_filter_kinesis": 2.365477252999881, + "tests/aws/services/logs/test_logs.py::TestCloudWatchLogs::test_put_subscription_filter_lambda": 1.9475835309999638, + "tests/aws/services/logs/test_logs.py::TestCloudWatchLogs::test_resource_does_not_exist": 0.040096138999615505, + "tests/aws/services/opensearch/test_opensearch.py::TestCustomBackendManager::test_custom_backend": 0.14606878299991877, + "tests/aws/services/opensearch/test_opensearch.py::TestCustomBackendManager::test_custom_backend_with_custom_endpoint": 0.1699449189995903, + "tests/aws/services/opensearch/test_opensearch.py::TestEdgeProxiedOpensearchCluster::test_custom_endpoint": 9.930969946999994, + "tests/aws/services/opensearch/test_opensearch.py::TestEdgeProxiedOpensearchCluster::test_custom_endpoint_disabled": 9.914726486999825, + "tests/aws/services/opensearch/test_opensearch.py::TestEdgeProxiedOpensearchCluster::test_route_through_edge": 9.72144251499958, + "tests/aws/services/opensearch/test_opensearch.py::TestMultiClusterManager::test_multi_cluster": 16.660946764999608, + "tests/aws/services/opensearch/test_opensearch.py::TestMultiplexingClusterManager::test_multiplexing_cluster": 10.275542594999479, + "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_cloudformation_deployment": 12.245546750999893, + "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_create_domain": 10.552142506999644, + "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_create_domain_with_invalid_custom_endpoint": 0.019064825999976165, + "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_create_domain_with_invalid_name": 0.03160309799932293, + "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_create_existing_domain_causes_exception": 10.388525632999972, + "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_create_indices": 11.669789034999667, + "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_describe_domains": 10.481071857999723, + "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_domain_version": 10.471427080000467, + "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_endpoint_strategy_path": 9.881986864000282, + "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_endpoint_strategy_port": 9.857843570000114, + "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_exception_header_field": 0.01125751500012484, + "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_get_compatible_version_for_domain": 9.435145142999772, + "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_get_compatible_versions": 0.02224516099977336, + "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_get_document": 10.513471018000473, + "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_gzip_responses": 10.567655205000392, + "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_list_versions": 0.09833614499984833, + "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_search": 10.90698451399976, + "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_security_plugin": 16.132425498999964, + "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_sql_plugin": 15.194244419999904, + "tests/aws/services/opensearch/test_opensearch.py::TestOpensearchProvider::test_update_domain_config": 10.031371039000078, + "tests/aws/services/opensearch/test_opensearch.py::TestSingletonClusterManager::test_endpoint_strategy_port_singleton_cluster": 9.74074976599968, + "tests/aws/services/redshift/test_redshift.py::TestRedshift::test_cluster_security_groups": 0.03606374299988602, + "tests/aws/services/redshift/test_redshift.py::TestRedshift::test_create_clusters": 0.170891882999058, + "tests/aws/services/resource_groups/test_resource_groups.py::TestResourceGroups::test_cloudformation_query": 0.0017252770003324258, + "tests/aws/services/resource_groups/test_resource_groups.py::TestResourceGroups::test_create_group": 0.4318274749994089, + "tests/aws/services/resource_groups/test_resource_groups.py::TestResourceGroups::test_resource_groups_different_region": 0.00171794299967587, + "tests/aws/services/resource_groups/test_resource_groups.py::TestResourceGroups::test_resource_groups_tag_query": 0.0017144569997071812, + "tests/aws/services/resource_groups/test_resource_groups.py::TestResourceGroups::test_resource_type_filters": 0.0016211240003940475, + "tests/aws/services/resource_groups/test_resource_groups.py::TestResourceGroups::test_search_resources": 0.0017195159998664167, + "tests/aws/services/resourcegroupstaggingapi/test_rgsa.py::TestRGSAIntegrations::test_get_resources": 0.5160235670000475, + "tests/aws/services/route53/test_route53.py::TestRoute53::test_associate_vpc_with_hosted_zone": 0.535587053999734, + "tests/aws/services/route53/test_route53.py::TestRoute53::test_create_hosted_zone": 0.6278063849999853, + "tests/aws/services/route53/test_route53.py::TestRoute53::test_create_hosted_zone_in_non_existent_vpc": 0.21164331699992545, + "tests/aws/services/route53/test_route53.py::TestRoute53::test_create_private_hosted_zone": 1.9677505279996694, + "tests/aws/services/route53/test_route53.py::TestRoute53::test_crud_health_check": 0.20379017499953989, + "tests/aws/services/route53/test_route53.py::TestRoute53::test_reusable_delegation_sets": 0.1874946159996398, + "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_associate_and_disassociate_resolver_rule": 0.5123129399999016, + "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_create_resolver_endpoint[INBOUND-5]": 0.36079468200023257, + "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_create_resolver_endpoint[OUTBOUND-10]": 0.3041840159999083, + "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_create_resolver_query_log_config": 0.32700275900015185, + "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_create_resolver_rule": 0.41018462700048985, + "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_create_resolver_rule_with_invalid_direction": 0.3201359240001693, + "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_delete_non_existent_resolver_endpoint": 0.09312730700048633, + "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_delete_non_existent_resolver_query_log_config": 0.16701360700017176, + "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_delete_non_existent_resolver_rule": 0.09380673900022884, + "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_delete_resolver_endpoint": 0.30861568099999204, + "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_disassociate_non_existent_association": 0.09339519600007407, + "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_list_firewall_domain_lists": 0.19615350799995213, + "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_list_firewall_rules": 0.3343570920001184, + "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_list_firewall_rules_for_empty_rule_group": 0.11017034599990438, + "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_list_firewall_rules_for_missing_rule_group": 0.16653840300023148, + "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_multipe_create_resolver_rule": 0.4502968060000967, + "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_multiple_create_resolver_endpoint_with_same_req_id": 0.3209407580006882, + "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_route53resolver_bad_create_endpoint_security_groups": 0.2103866639995431, + "tests/aws/services/route53resolver/test_route53resolver.py::TestRoute53Resolver::test_update_resolver_endpoint": 0.3266579619994445, + "tests/aws/services/s3/test_s3.py::TestS3::test_access_bucket_different_region": 0.0017377610001858557, + "tests/aws/services/s3/test_s3.py::TestS3::test_bucket_availability": 0.032754569000189804, + "tests/aws/services/s3/test_s3.py::TestS3::test_bucket_does_not_exist": 0.455000729000858, + "tests/aws/services/s3/test_s3.py::TestS3::test_bucket_exists": 0.2440340729995114, + "tests/aws/services/s3/test_s3.py::TestS3::test_bucket_name_with_dots": 0.6000019759999304, + "tests/aws/services/s3/test_s3.py::TestS3::test_bucket_operation_between_regions": 0.4774934110000686, + "tests/aws/services/s3/test_s3.py::TestS3::test_complete_multipart_parts_order": 0.47737245799999073, + "tests/aws/services/s3/test_s3.py::TestS3::test_copy_in_place_with_bucket_encryption": 0.14140114900010303, + "tests/aws/services/s3/test_s3.py::TestS3::test_copy_object_kms": 0.6714924670004621, + "tests/aws/services/s3/test_s3.py::TestS3::test_copy_object_special_character": 0.6758725960003176, + "tests/aws/services/s3/test_s3.py::TestS3::test_copy_object_special_character_plus_for_space": 0.10151528500000495, + "tests/aws/services/s3/test_s3.py::TestS3::test_create_bucket_head_bucket": 0.6632904399998552, + "tests/aws/services/s3/test_s3.py::TestS3::test_create_bucket_via_host_name": 0.040520028000173625, + "tests/aws/services/s3/test_s3.py::TestS3::test_create_bucket_with_existing_name": 0.44556275499962794, + "tests/aws/services/s3/test_s3.py::TestS3::test_delete_bucket_no_such_bucket": 0.02093478899996626, + "tests/aws/services/s3/test_s3.py::TestS3::test_delete_bucket_policy": 0.10210770599996977, + "tests/aws/services/s3/test_s3.py::TestS3::test_delete_bucket_policy_expected_bucket_owner": 1.3575167819999479, + "tests/aws/services/s3/test_s3.py::TestS3::test_delete_bucket_with_content": 0.7545708149996244, + "tests/aws/services/s3/test_s3.py::TestS3::test_delete_keys_in_versioned_bucket": 0.5403501730002063, + "tests/aws/services/s3/test_s3.py::TestS3::test_delete_non_existing_keys": 0.07680011099955664, + "tests/aws/services/s3/test_s3.py::TestS3::test_delete_non_existing_keys_in_non_existing_bucket": 0.023685128999659355, + "tests/aws/services/s3/test_s3.py::TestS3::test_delete_non_existing_keys_quiet": 0.07760197799962043, + "tests/aws/services/s3/test_s3.py::TestS3::test_delete_object_tagging": 0.10655310999982248, + "tests/aws/services/s3/test_s3.py::TestS3::test_delete_objects_encoding": 0.1155748650003261, + "tests/aws/services/s3/test_s3.py::TestS3::test_different_location_constraint": 1.842643083999974, + "tests/aws/services/s3/test_s3.py::TestS3::test_download_fileobj_multiple_range_requests": 1.1207599629997276, + "tests/aws/services/s3/test_s3.py::TestS3::test_empty_bucket_fixture": 0.1421354940002857, + "tests/aws/services/s3/test_s3.py::TestS3::test_etag_on_get_object_call": 1.5601908169996932, + "tests/aws/services/s3/test_s3.py::TestS3::test_get_bucket_notification_configuration_no_such_bucket": 0.021697106000374333, + "tests/aws/services/s3/test_s3.py::TestS3::test_get_bucket_policy": 0.1230710109998654, + "tests/aws/services/s3/test_s3.py::TestS3::test_get_bucket_policy_invalid_account_id[0000000000020]": 0.06918193900037295, + "tests/aws/services/s3/test_s3.py::TestS3::test_get_bucket_policy_invalid_account_id[0000]": 0.07024318000003404, + "tests/aws/services/s3/test_s3.py::TestS3::test_get_bucket_policy_invalid_account_id[aa000000000$]": 0.06881261500029723, + "tests/aws/services/s3/test_s3.py::TestS3::test_get_bucket_policy_invalid_account_id[abcd]": 0.06687695700065888, + "tests/aws/services/s3/test_s3.py::TestS3::test_get_bucket_versioning_order": 0.5278214929994647, + "tests/aws/services/s3/test_s3.py::TestS3::test_get_object_after_deleted_in_versioned_bucket": 0.11773890700033007, + "tests/aws/services/s3/test_s3.py::TestS3::test_get_object_attributes": 0.3234831330000816, + "tests/aws/services/s3/test_s3.py::TestS3::test_get_object_attributes_versioned": 0.5156001080003989, + "tests/aws/services/s3/test_s3.py::TestS3::test_get_object_attributes_with_space": 0.09616222500017102, + "tests/aws/services/s3/test_s3.py::TestS3::test_get_object_content_length_with_virtual_host[False]": 0.09011745799989512, + "tests/aws/services/s3/test_s3.py::TestS3::test_get_object_content_length_with_virtual_host[True]": 0.09084958999937953, + "tests/aws/services/s3/test_s3.py::TestS3::test_get_object_no_such_bucket": 0.02292139099972701, + "tests/aws/services/s3/test_s3.py::TestS3::test_get_object_part": 0.22887023999965095, + "tests/aws/services/s3/test_s3.py::TestS3::test_get_object_with_anon_credentials": 0.5007160610002757, + "tests/aws/services/s3/test_s3.py::TestS3::test_get_range_object_headers": 0.08663164099971254, + "tests/aws/services/s3/test_s3.py::TestS3::test_head_object_fields": 0.09927549800022462, + "tests/aws/services/s3/test_s3.py::TestS3::test_invalid_range_error": 0.09071486099946924, + "tests/aws/services/s3/test_s3.py::TestS3::test_metadata_header_character_decoding": 0.4562747169998147, + "tests/aws/services/s3/test_s3.py::TestS3::test_multipart_and_list_parts": 0.18474399300021105, + "tests/aws/services/s3/test_s3.py::TestS3::test_multipart_complete_multipart_too_small": 0.11367406299996219, + "tests/aws/services/s3/test_s3.py::TestS3::test_multipart_complete_multipart_wrong_part": 0.10060384799999156, + "tests/aws/services/s3/test_s3.py::TestS3::test_multipart_copy_object_etag": 0.13736746399990807, + "tests/aws/services/s3/test_s3.py::TestS3::test_multipart_no_such_upload": 0.08978362400011974, + "tests/aws/services/s3/test_s3.py::TestS3::test_multipart_overwrite_key": 0.12366085899975587, + "tests/aws/services/s3/test_s3.py::TestS3::test_object_with_slashes_in_key[False]": 0.18862366000030306, + "tests/aws/services/s3/test_s3.py::TestS3::test_object_with_slashes_in_key[True]": 0.18862249499943573, + "tests/aws/services/s3/test_s3.py::TestS3::test_precondition_failed_error": 0.1252563680000094, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_and_get_object_with_content_language_disposition": 0.9514182179996169, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_and_get_object_with_hash_prefix": 0.47055087799981266, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_and_get_object_with_utf8_key": 0.4665584470003523, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_bucket_inventory_config_order": 0.15517080500058, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_bucket_policy": 0.0934643909999977, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_bucket_policy_expected_bucket_owner": 0.09244217100012975, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_bucket_policy_invalid_account_id[0000000000020]": 0.06832255100016482, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_bucket_policy_invalid_account_id[0000]": 0.0686302149997573, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_bucket_policy_invalid_account_id[aa000000000$]": 0.07128155199961839, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_bucket_policy_invalid_account_id[abcd]": 0.070095302000027, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_get_object_single_character_trailing_slash": 0.15414225800032, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_get_object_special_character[a/%F0%9F%98%80/]": 0.4752704520001316, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_get_object_special_character[file%2Fname]": 0.5033893869995154, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_get_object_special_character[test key//]": 0.4901872339996771, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_get_object_special_character[test key/]": 0.4732642740004849, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_get_object_special_character[test%123/]": 0.4770653069999753, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_get_object_special_character[test%123]": 0.4673835000003237, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_get_object_special_character[test%percent]": 0.47399162700003217, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_get_object_special_character[test@key/]": 0.4918745539998781, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_acl_on_delete_marker": 0.5394600979998359, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_chunked_checksum": 0.10426203799988798, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_chunked_content_encoding": 0.1021797309995236, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_chunked_newlines": 0.07917727200037916, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_chunked_newlines_no_sig": 0.08820546899960391, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_chunked_newlines_no_sig_empty_body": 0.08416931700048735, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_chunked_newlines_with_trailing_checksum": 0.1030434869999226, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_storage_class[DEEP_ARCHIVE-False]": 0.09774747100027525, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_storage_class[GLACIER-False]": 0.09708789100068316, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_storage_class[GLACIER_IR-True]": 0.09683602399945812, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_storage_class[INTELLIGENT_TIERING-True]": 0.09707980000030147, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_storage_class[ONEZONE_IA-True]": 0.09809807099964019, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_storage_class[REDUCED_REDUNDANCY-True]": 0.09861441500015644, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_storage_class[STANDARD-True]": 0.09877875800020774, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_storage_class[STANDARD_IA-True]": 0.09984361499982697, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_storage_class_outposts": 0.08034603500027515, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_tagging_empty_list": 0.12645945599979314, + "tests/aws/services/s3/test_s3.py::TestS3::test_put_object_with_md5_and_chunk_signature": 0.0796832760001962, + "tests/aws/services/s3/test_s3.py::TestS3::test_putobject_with_multiple_keys": 0.45953943299991806, + "tests/aws/services/s3/test_s3.py::TestS3::test_range_header_body_length": 0.10451611000053163, + "tests/aws/services/s3/test_s3.py::TestS3::test_range_key_not_exists": 0.07134434199997486, + "tests/aws/services/s3/test_s3.py::TestS3::test_region_header_exists_outside_us_east_1": 0.5719105399998625, + "tests/aws/services/s3/test_s3.py::TestS3::test_response_structure": 0.16396043399936389, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_analytics_configurations": 0.21165318899966223, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_batch_delete_objects": 0.4923105820003002, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_batch_delete_objects_using_requests_with_acl": 0.0018232980000902899, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_batch_delete_public_objects_using_requests": 0.48657782900045277, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_bucket_acl": 0.14846836600008828, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_bucket_acl_exceptions": 0.18871481899986975, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_content_type_and_metadata": 0.5242202100002942, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_metadata_directive_copy": 0.5156041179998283, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_metadata_replace": 0.4872820209998281, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_in_place": 0.5520005220000712, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_in_place_metadata_directive": 0.580313507000028, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_in_place_storage_class": 0.5072362340006293, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_in_place_suspended_only": 0.5895788479997464, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_in_place_versioned": 0.64779644500004, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_in_place_website_redirect_location": 0.497922213000038, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_in_place_with_encryption": 0.8070412600004602, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_preconditions": 3.544426726999518, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_storage_class": 0.4998210920002748, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_with_checksum[CRC32C]": 0.5056475820001651, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_with_checksum[CRC32]": 0.4927220270001271, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_with_checksum[CRC64NVME]": 0.5078794109995215, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_with_checksum[SHA1]": 0.529413828000088, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_with_checksum[SHA256]": 0.5513068230006866, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_with_default_checksum[CRC32C]": 0.5150854789999357, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_with_default_checksum[CRC32]": 0.5153786550004043, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_with_default_checksum[CRC64NVME]": 0.5190937540000959, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_with_default_checksum[SHA1]": 0.508819456999845, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_with_default_checksum[SHA256]": 0.5226092950001657, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_wrong_format": 0.44900781999967876, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_tagging_directive[COPY]": 0.5121984660004273, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_tagging_directive[None]": 0.5119780410000203, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_tagging_directive[REPLACE]": 0.508136194999679, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_tagging_directive_versioned[COPY]": 0.6036629779996474, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_tagging_directive_versioned[None]": 0.6094781239999065, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_tagging_directive_versioned[REPLACE]": 0.6109056770001189, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_delete_object_with_version_id": 0.5465767340001548, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_delete_objects_trailing_slash": 0.07076338099977875, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_download_object_with_lambda": 4.256924979999894, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_get_object_header_overrides": 0.09033322699951896, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_get_object_headers": 0.15364679399954184, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_get_object_preconditions[get_object]": 3.581649379999817, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_get_object_preconditions[head_object]": 3.5454579229995034, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_hostname_with_subdomain": 0.021439698999529355, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_intelligent_tier_config": 0.15785213000026488, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_invalid_content_md5": 11.238553538999895, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_inventory_report_crud": 0.1637208789993565, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_lambda_integration": 11.568549113999325, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_multipart_upload_acls": 0.20431246800035296, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_multipart_upload_sse": 0.20036700199989355, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_object_acl": 0.1630551079997531, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_object_acl_exceptions": 0.22892836799974248, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_object_expiry": 3.566067505999854, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_put_inventory_report_exceptions": 0.1577265949995308, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_put_more_than_1000_items": 12.969149960999857, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_put_object_versioned": 0.6515515859996412, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_raw_request_routing": 0.140311827000005, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_request_payer": 0.08309193399963988, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_request_payer_exceptions": 0.07944373400005134, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_sse_bucket_key_default": 0.2264348449998579, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_sse_default_kms_key": 0.0017639390002841537, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_sse_validate_kms_key": 0.2649421089995485, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_sse_validate_kms_key_state": 0.29447866800001066, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_timestamp_precision": 0.104442989000745, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_upload_download_gzip": 0.0965745810003682, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_uppercase_bucket_name": 0.3883459139997285, + "tests/aws/services/s3/test_s3.py::TestS3::test_s3_uppercase_key_names": 0.09396393000042735, + "tests/aws/services/s3/test_s3.py::TestS3::test_set_external_hostname": 0.1395769000000655, + "tests/aws/services/s3/test_s3.py::TestS3::test_upload_big_file": 0.6131274070007748, + "tests/aws/services/s3/test_s3.py::TestS3::test_upload_file_multipart": 0.4894929280003453, + "tests/aws/services/s3/test_s3.py::TestS3::test_upload_file_with_xml_preamble": 0.46451395200028855, + "tests/aws/services/s3/test_s3.py::TestS3::test_upload_part_chunked_cancelled_valid_etag": 0.11871217400039313, + "tests/aws/services/s3/test_s3.py::TestS3::test_upload_part_chunked_newlines_valid_etag": 0.10164770699975634, + "tests/aws/services/s3/test_s3.py::TestS3::test_url_encoded_key[False]": 0.1445281099991007, + "tests/aws/services/s3/test_s3.py::TestS3::test_url_encoded_key[True]": 0.1501400880001711, + "tests/aws/services/s3/test_s3.py::TestS3::test_virtual_host_proxy_does_not_decode_gzip": 0.08814250199975504, + "tests/aws/services/s3/test_s3.py::TestS3::test_virtual_host_proxying_headers": 0.08977678500014008, + "tests/aws/services/s3/test_s3.py::TestS3BucketLifecycle::test_bucket_lifecycle_configuration_date": 0.07496489400045903, + "tests/aws/services/s3/test_s3.py::TestS3BucketLifecycle::test_bucket_lifecycle_configuration_object_expiry": 0.11242237999977078, + "tests/aws/services/s3/test_s3.py::TestS3BucketLifecycle::test_bucket_lifecycle_configuration_object_expiry_versioned": 0.15672700300001452, + "tests/aws/services/s3/test_s3.py::TestS3BucketLifecycle::test_bucket_lifecycle_multiple_rules": 0.11869607999960863, + "tests/aws/services/s3/test_s3.py::TestS3BucketLifecycle::test_bucket_lifecycle_object_size_rules": 0.11816291000013734, + "tests/aws/services/s3/test_s3.py::TestS3BucketLifecycle::test_bucket_lifecycle_tag_rules": 0.1777785049994236, + "tests/aws/services/s3/test_s3.py::TestS3BucketLifecycle::test_delete_bucket_lifecycle_configuration": 0.11011944900019444, + "tests/aws/services/s3/test_s3.py::TestS3BucketLifecycle::test_delete_lifecycle_configuration_on_bucket_deletion": 0.11088589700011653, + "tests/aws/services/s3/test_s3.py::TestS3BucketLifecycle::test_lifecycle_expired_object_delete_marker": 0.10231754699998419, + "tests/aws/services/s3/test_s3.py::TestS3BucketLifecycle::test_object_expiry_after_bucket_lifecycle_configuration": 0.12222347000033551, + "tests/aws/services/s3/test_s3.py::TestS3BucketLifecycle::test_put_bucket_lifecycle_conf_exc": 0.13763947400002507, + "tests/aws/services/s3/test_s3.py::TestS3BucketLifecycle::test_s3_transition_default_minimum_object_size": 0.11668738000025769, + "tests/aws/services/s3/test_s3.py::TestS3BucketLogging::test_put_bucket_logging": 0.14544916700015165, + "tests/aws/services/s3/test_s3.py::TestS3BucketLogging::test_put_bucket_logging_accept_wrong_grants": 0.126612034000118, + "tests/aws/services/s3/test_s3.py::TestS3BucketLogging::test_put_bucket_logging_cross_locations": 0.1614668600004734, + "tests/aws/services/s3/test_s3.py::TestS3BucketLogging::test_put_bucket_logging_wrong_target": 0.12252710600068895, + "tests/aws/services/s3/test_s3.py::TestS3BucketReplication::test_replication_config": 1.7992485479999232, + "tests/aws/services/s3/test_s3.py::TestS3BucketReplication::test_replication_config_without_filter": 0.6282677499998499, + "tests/aws/services/s3/test_s3.py::TestS3DeepArchive::test_s3_get_deep_archive_object_restore": 0.5457322640008897, + "tests/aws/services/s3/test_s3.py::TestS3DeepArchive::test_storage_class_deep_archive": 0.1610681460001615, + "tests/aws/services/s3/test_s3.py::TestS3MultiAccounts::test_cross_account_access": 0.13261018000048352, + "tests/aws/services/s3/test_s3.py::TestS3MultiAccounts::test_cross_account_copy_object": 0.09426405500016699, + "tests/aws/services/s3/test_s3.py::TestS3MultiAccounts::test_shared_bucket_namespace": 0.0665997400001288, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_composite[CRC32C]": 0.4639651140000751, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_composite[CRC32]": 0.4812059120008598, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_composite[SHA1]": 0.48757263100014825, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_composite[SHA256]": 0.48248738599977514, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_default": 0.20889673200008474, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_full_object[CRC32C]": 0.5873168240000268, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_full_object[CRC32]": 0.5598075520001657, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_full_object[CRC64NVME]": 0.5958196050000879, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_complete_multipart_parts_checksum_full_object_default": 0.13216373200020826, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[COMPOSITE-CRC32C]": 0.06874650400004612, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[COMPOSITE-CRC32]": 0.06930489500018666, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[COMPOSITE-CRC64NVME]": 0.06913759200006098, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[COMPOSITE-SHA1]": 0.07003761399982977, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[COMPOSITE-SHA256]": 0.06969941500028654, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[FULL_OBJECT-CRC32C]": 0.06739061899997978, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[FULL_OBJECT-CRC32]": 0.07017321500006801, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[FULL_OBJECT-CRC64NVME]": 0.06814229000019623, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[FULL_OBJECT-SHA1]": 0.06825507800022024, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_compatibility[FULL_OBJECT-SHA256]": 0.06997887700026695, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_default_for_checksum[CRC32C]": 0.06931798599998729, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_default_for_checksum[CRC32]": 0.06758309299993925, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_default_for_checksum[CRC64NVME]": 0.06776337900009821, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_default_for_checksum[SHA1]": 0.06820239499984382, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_checksum_type_default_for_checksum[SHA256]": 0.0683457919999455, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_parts_checksum_exceptions_composite": 5.074903023999923, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_parts_checksum_exceptions_full_object": 38.05990962400074, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_size_validation": 0.11876405900011378, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_checksum_exception[CRC32C]": 11.98745130799989, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_checksum_exception[CRC32]": 10.101586202999897, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_checksum_exception[CRC64NVME]": 10.366791807999562, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_checksum_exception[SHA1]": 8.469462776999535, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_checksum_exception[SHA256]": 7.276466451000033, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_copy_checksum[COMPOSITE]": 0.16080871700023636, + "tests/aws/services/s3/test_s3.py::TestS3MultipartUploadChecksum::test_multipart_upload_part_copy_checksum[FULL_OBJECT]": 0.15157674200008842, + "tests/aws/services/s3/test_s3.py::TestS3ObjectLockLegalHold::test_delete_locked_object": 0.11965547999989212, + "tests/aws/services/s3/test_s3.py::TestS3ObjectLockLegalHold::test_put_get_object_legal_hold": 0.13469800399980159, + "tests/aws/services/s3/test_s3.py::TestS3ObjectLockLegalHold::test_put_object_legal_hold_exc": 0.16523954400008734, + "tests/aws/services/s3/test_s3.py::TestS3ObjectLockLegalHold::test_put_object_with_legal_hold": 0.10574997200001235, + "tests/aws/services/s3/test_s3.py::TestS3ObjectLockLegalHold::test_s3_copy_object_legal_hold": 0.5070335130003514, + "tests/aws/services/s3/test_s3.py::TestS3ObjectLockLegalHold::test_s3_legal_hold_lock_versioned": 0.5459156079996319, + "tests/aws/services/s3/test_s3.py::TestS3ObjectLockRetention::test_bucket_config_default_retention": 0.1393712509998295, + "tests/aws/services/s3/test_s3.py::TestS3ObjectLockRetention::test_object_lock_delete_markers": 0.12012572399999044, + "tests/aws/services/s3/test_s3.py::TestS3ObjectLockRetention::test_object_lock_extend_duration": 0.12564304600027754, + "tests/aws/services/s3/test_s3.py::TestS3ObjectLockRetention::test_s3_copy_object_retention_lock": 0.49055865599984827, + "tests/aws/services/s3/test_s3.py::TestS3ObjectLockRetention::test_s3_object_lock_mode_validation": 0.10098833999973067, + "tests/aws/services/s3/test_s3.py::TestS3ObjectLockRetention::test_s3_object_retention": 6.166208540999833, + "tests/aws/services/s3/test_s3.py::TestS3ObjectLockRetention::test_s3_object_retention_compliance_mode": 6.143054728000152, + "tests/aws/services/s3/test_s3.py::TestS3ObjectLockRetention::test_s3_object_retention_exc": 0.24291139300021314, + "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_default_checksum": 0.09186653400047362, + "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_policy_casing[s3]": 0.09354642399966906, + "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_policy_casing[s3v4]": 0.09785780199990768, + "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_policy_conditions_validation_eq": 0.32806321699990804, + "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_policy_conditions_validation_starts_with": 0.28869105600051626, + "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_policy_validation_size": 0.23010378100025264, + "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_with_file_as_string": 0.3362911690001056, + "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_with_files": 0.1294434619999265, + "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_with_metadata": 0.0924956949997977, + "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_with_storage_class": 0.3215117499998996, + "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_with_tags[invalid]": 0.16323631500017655, + "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_with_tags[list]": 0.16437781400054519, + "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_with_tags[notxml]": 0.1520418699997208, + "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_with_tags[single]": 0.1703842980000445, + "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_object_with_wrong_content_type": 0.14097107099951245, + "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_request_expires": 3.147410301000491, + "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_request_malformed_policy[s3]": 0.15455719000055979, + "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_request_malformed_policy[s3v4]": 0.15580979499964087, + "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_request_missing_fields[s3]": 0.1731264810000539, + "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_request_missing_fields[s3v4]": 0.19541484199999104, + "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_request_missing_signature[s3]": 0.15328779900028167, + "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_post_request_missing_signature[s3v4]": 0.15274820300010106, + "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_presigned_post_with_different_user_credentials": 0.1890405579997605, + "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_s3_presigned_post_success_action_redirect": 0.11284307400001126, + "tests/aws/services/s3/test_s3.py::TestS3PresignedPost::test_s3_presigned_post_success_action_status_201_response": 0.08363163199965129, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_delete_has_empty_content_length_header": 0.09378294800035292, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_get_object_ignores_request_body": 0.08662354299985964, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_get_request_expires_ignored_if_validation_disabled": 3.112235419999706, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_head_has_correct_content_length_header": 0.0837748039998587, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_pre_signed_url_forward_slash_bucket": 0.09793999400017128, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_pre_signed_url_if_match": 0.09712903999979972, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_pre_signed_url_if_none_match": 0.09408060599980672, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presign_check_signature_validation_for_port_permutation": 0.10242237900001783, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presign_with_additional_query_params": 0.11011971100060691, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_double_encoded_credentials": 0.173130071000287, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_signature_authentication[s3-False]": 0.21807055000044784, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_signature_authentication[s3-True]": 0.21965711400025612, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_signature_authentication[s3v4-False]": 0.22889908800061676, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_signature_authentication[s3v4-True]": 0.2280263319998994, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_signature_authentication_expired[s3-False]": 2.173837683000329, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_signature_authentication_expired[s3-True]": 2.174651814999379, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_signature_authentication_expired[s3v4-False]": 2.174826619999749, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_signature_authentication_expired[s3v4-True]": 2.1717230730000665, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_signature_authentication_multi_part[s3-False]": 0.11474644399959288, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_signature_authentication_multi_part[s3-True]": 0.11607119500013141, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_signature_authentication_multi_part[s3v4-False]": 0.11697311300031288, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_signature_authentication_multi_part[s3v4-True]": 0.11993345600012617, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_v4_signed_headers_in_qs": 2.1653735219997543, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_v4_x_amz_in_qs": 8.413620758999514, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_with_different_user_credentials": 0.18236617500042485, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_presigned_url_with_session_token": 0.11487100899967118, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_put_object": 0.46142456799952924, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_put_object_with_md5_and_chunk_signature_bad_headers[s3-False]": 0.08851997500005382, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_put_object_with_md5_and_chunk_signature_bad_headers[s3-True]": 0.16339013000060731, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_put_object_with_md5_and_chunk_signature_bad_headers[s3v4-False]": 0.08897431900004449, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_put_object_with_md5_and_chunk_signature_bad_headers[s3v4-True]": 0.1644958760002737, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_put_url_metadata_with_sig_s3[False]": 0.54799379699989, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_put_url_metadata_with_sig_s3[True]": 0.5580918669998027, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_put_url_metadata_with_sig_s3v4[False]": 0.5732215320003888, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_put_url_metadata_with_sig_s3v4[True]": 0.5680722179999975, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_copy_md5": 0.10927026599938472, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_get_response_case_sensitive_headers": 0.08486306399981913, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_get_response_content_type_same_as_upload_and_range": 0.09585092899942538, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_get_response_default_content_type": 0.08387662399991314, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_get_response_header_overrides[s3]": 0.09873026000013851, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_get_response_header_overrides[s3v4]": 0.10096148200000243, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_ignored_special_headers": 0.12264371499986737, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_presign_url_encoding[s3]": 0.09308279499919081, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_presign_url_encoding[s3v4]": 0.09608300200079611, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_presigned_url_expired[s3]": 3.193924362999951, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_presigned_url_expired[s3v4]": 3.1988627700006873, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_put_presigned_url_missing_sig_param[s3]": 0.17278313299993897, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_put_presigned_url_missing_sig_param[s3v4]": 0.1700350190003519, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_put_presigned_url_same_header_and_qs_parameter": 0.18275859000004857, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_put_presigned_url_with_different_headers[s3]": 1.3139008100001774, + "tests/aws/services/s3/test_s3.py::TestS3PresignedUrl::test_s3_put_presigned_url_with_different_headers[s3v4]": 0.214943661000234, + "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_put_object_checksum[CRC32C]": 9.025636942000347, + "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_put_object_checksum[CRC32]": 5.711442942999383, + "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_put_object_checksum[CRC64NVME]": 4.938957258999835, + "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_put_object_checksum[SHA1]": 5.975829427000008, + "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_put_object_checksum[SHA256]": 4.843360059999668, + "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_s3_checksum_no_algorithm": 0.11130721300014557, + "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_s3_checksum_no_automatic_sdk_calculation": 0.248393770000348, + "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_s3_checksum_with_content_encoding": 0.1070730139999796, + "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_s3_get_object_checksum[CRC32C]": 0.11763677800036021, + "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_s3_get_object_checksum[CRC32]": 0.11805519199970149, + "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_s3_get_object_checksum[CRC64NVME]": 0.11600462300020808, + "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_s3_get_object_checksum[None]": 0.11553541000012046, + "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_s3_get_object_checksum[SHA1]": 0.11637014500001897, + "tests/aws/services/s3/test_s3.py::TestS3PutObjectChecksum::test_s3_get_object_checksum[SHA256]": 0.11636639800008197, + "tests/aws/services/s3/test_s3.py::TestS3Routing::test_access_favicon_via_aws_endpoints[s3.amazonaws.com-False]": 0.0903928409998116, + "tests/aws/services/s3/test_s3.py::TestS3Routing::test_access_favicon_via_aws_endpoints[s3.amazonaws.com-True]": 0.0902906129999792, + "tests/aws/services/s3/test_s3.py::TestS3Routing::test_access_favicon_via_aws_endpoints[s3.us-west-2.amazonaws.com-False]": 0.09054037000032622, + "tests/aws/services/s3/test_s3.py::TestS3Routing::test_access_favicon_via_aws_endpoints[s3.us-west-2.amazonaws.com-True]": 0.09048810599961143, + "tests/aws/services/s3/test_s3.py::TestS3SSECEncryption::test_copy_object_with_sse_c": 0.22205149399997026, + "tests/aws/services/s3/test_s3.py::TestS3SSECEncryption::test_multipart_upload_sse_c": 0.4661431869999433, + "tests/aws/services/s3/test_s3.py::TestS3SSECEncryption::test_multipart_upload_sse_c_validation": 0.19104238100044313, + "tests/aws/services/s3/test_s3.py::TestS3SSECEncryption::test_object_retrieval_sse_c": 0.24533578899945496, + "tests/aws/services/s3/test_s3.py::TestS3SSECEncryption::test_put_object_default_checksum_with_sse_c": 0.18251436700029444, + "tests/aws/services/s3/test_s3.py::TestS3SSECEncryption::test_put_object_lifecycle_with_sse_c": 0.17934357900003306, + "tests/aws/services/s3/test_s3.py::TestS3SSECEncryption::test_put_object_validation_sse_c": 0.20361132099969836, + "tests/aws/services/s3/test_s3.py::TestS3SSECEncryption::test_sse_c_with_versioning": 0.22546165499989002, + "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_crud_website_configuration": 0.10290628999973706, + "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_object_website_redirect_location": 0.2578346720006266, + "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_routing_rules_conditions": 0.5297959870003979, + "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_routing_rules_empty_replace_prefix": 0.4164051030002156, + "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_routing_rules_order": 0.23960981300024287, + "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_routing_rules_redirects": 0.1528676960001576, + "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_s3_static_website_hosting": 0.5298386740005299, + "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_s3_static_website_index": 0.13926996800046254, + "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_validate_website_configuration": 0.20617380600015167, + "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_website_hosting_404": 0.213473002000228, + "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_website_hosting_http_methods": 0.13618763600015882, + "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_website_hosting_index_lookup": 0.26415075800014165, + "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_website_hosting_no_such_website": 0.1303935839996484, + "tests/aws/services/s3/test_s3.py::TestS3StaticWebsiteHosting::test_website_hosting_redirect_all": 0.2987584739998965, + "tests/aws/services/s3/test_s3.py::TestS3TerraformRawRequests::test_terraform_request_sequence": 0.05705920699983835, + "tests/aws/services/s3/test_s3_api.py::TestS3BucketAccelerateConfiguration::test_bucket_acceleration_configuration_crud": 0.09824534699964715, + "tests/aws/services/s3/test_s3_api.py::TestS3BucketAccelerateConfiguration::test_bucket_acceleration_configuration_exc": 0.1275247810003748, + "tests/aws/services/s3/test_s3_api.py::TestS3BucketCRUD::test_delete_bucket_with_objects": 0.43320531000063056, + "tests/aws/services/s3/test_s3_api.py::TestS3BucketCRUD::test_delete_versioned_bucket_with_objects": 0.4761938340002416, + "tests/aws/services/s3/test_s3_api.py::TestS3BucketEncryption::test_s3_bucket_encryption_sse_kms": 0.2277451119998659, + "tests/aws/services/s3/test_s3_api.py::TestS3BucketEncryption::test_s3_bucket_encryption_sse_kms_aws_managed_key": 0.27945827099983944, + "tests/aws/services/s3/test_s3_api.py::TestS3BucketEncryption::test_s3_bucket_encryption_sse_s3": 0.10384561199998643, + "tests/aws/services/s3/test_s3_api.py::TestS3BucketEncryption::test_s3_default_bucket_encryption": 0.08767096400015362, + "tests/aws/services/s3/test_s3_api.py::TestS3BucketEncryption::test_s3_default_bucket_encryption_exc": 0.4815031330003876, + "tests/aws/services/s3/test_s3_api.py::TestS3BucketObjectTagging::test_bucket_tagging_crud": 0.13846078400001716, + "tests/aws/services/s3/test_s3_api.py::TestS3BucketObjectTagging::test_bucket_tagging_exc": 0.08329444999981206, + "tests/aws/services/s3/test_s3_api.py::TestS3BucketObjectTagging::test_object_tagging_crud": 0.1735137779996876, + "tests/aws/services/s3/test_s3_api.py::TestS3BucketObjectTagging::test_object_tagging_exc": 0.20664752300035616, + "tests/aws/services/s3/test_s3_api.py::TestS3BucketObjectTagging::test_object_tagging_versioned": 0.20295681699963097, + "tests/aws/services/s3/test_s3_api.py::TestS3BucketObjectTagging::test_object_tags_delete_or_overwrite_object": 0.13394287300025098, + "tests/aws/services/s3/test_s3_api.py::TestS3BucketObjectTagging::test_put_object_with_tags": 0.19473258500056545, + "tests/aws/services/s3/test_s3_api.py::TestS3BucketObjectTagging::test_tagging_validation": 0.17719945399994685, + "tests/aws/services/s3/test_s3_api.py::TestS3BucketOwnershipControls::test_bucket_ownership_controls_exc": 0.107174608999685, + "tests/aws/services/s3/test_s3_api.py::TestS3BucketOwnershipControls::test_crud_bucket_ownership_controls": 0.15799062699989008, + "tests/aws/services/s3/test_s3_api.py::TestS3BucketPolicy::test_bucket_policy_crud": 0.11781792000010682, + "tests/aws/services/s3/test_s3_api.py::TestS3BucketPolicy::test_bucket_policy_exc": 0.09609018800028934, + "tests/aws/services/s3/test_s3_api.py::TestS3BucketVersioning::test_bucket_versioning_crud": 0.15033838800036392, + "tests/aws/services/s3/test_s3_api.py::TestS3BucketVersioning::test_object_version_id_format": 0.09742670200057546, + "tests/aws/services/s3/test_s3_api.py::TestS3DeletePrecondition::test_delete_object_if_match_all_non_express": 0.09145774700027687, + "tests/aws/services/s3/test_s3_api.py::TestS3DeletePrecondition::test_delete_object_if_match_modified_non_express": 0.09627583600013168, + "tests/aws/services/s3/test_s3_api.py::TestS3DeletePrecondition::test_delete_object_if_match_non_express": 0.096994034999625, + "tests/aws/services/s3/test_s3_api.py::TestS3DeletePrecondition::test_delete_object_if_match_size_non_express": 0.0970460980001917, + "tests/aws/services/s3/test_s3_api.py::TestS3MetricsConfiguration::test_delete_metrics_configuration": 0.07886743400013074, + "tests/aws/services/s3/test_s3_api.py::TestS3MetricsConfiguration::test_delete_metrics_configuration_twice": 0.08259682100015198, + "tests/aws/services/s3/test_s3_api.py::TestS3MetricsConfiguration::test_get_bucket_metrics_configuration": 0.07103728700030842, + "tests/aws/services/s3/test_s3_api.py::TestS3MetricsConfiguration::test_get_bucket_metrics_configuration_not_exist": 0.06403213499970661, + "tests/aws/services/s3/test_s3_api.py::TestS3MetricsConfiguration::test_list_bucket_metrics_configurations": 0.07911696200017104, + "tests/aws/services/s3/test_s3_api.py::TestS3MetricsConfiguration::test_list_bucket_metrics_configurations_paginated": 0.8015899529996204, + "tests/aws/services/s3/test_s3_api.py::TestS3MetricsConfiguration::test_overwrite_bucket_metrics_configuration": 0.15217927000003328, + "tests/aws/services/s3/test_s3_api.py::TestS3MetricsConfiguration::test_put_bucket_metrics_configuration": 0.14899170400030926, + "tests/aws/services/s3/test_s3_api.py::TestS3Multipart::test_upload_part_copy_no_copy_source_range": 0.1849292400002014, + "tests/aws/services/s3/test_s3_api.py::TestS3Multipart::test_upload_part_copy_range": 0.326927077000164, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectCRUD::test_delete_object": 0.09171115700019072, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectCRUD::test_delete_object_on_suspended_bucket": 0.5809484550004527, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectCRUD::test_delete_object_versioned": 0.5691140130002168, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectCRUD::test_delete_objects": 0.08320467200019266, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectCRUD::test_delete_objects_versioned": 0.510280660000717, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectCRUD::test_get_object_range": 0.28285670299965204, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectCRUD::test_get_object_with_version_unversioned_bucket": 0.48658666100027403, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectCRUD::test_list_object_versions_order_unversioned": 0.5058404819997122, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectCRUD::test_put_object_on_suspended_bucket": 0.6210557670001435, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectLock::test_delete_object_with_no_locking": 0.09970045199952438, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectLock::test_disable_versioning_on_locked_bucket": 0.0693686920003529, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectLock::test_get_object_lock_configuration_exc": 0.07260569600020972, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectLock::test_get_put_object_lock_configuration": 0.09216875899983279, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectLock::test_put_object_lock_configuration_exc": 0.11435444000017014, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectLock::test_put_object_lock_configuration_on_existing_bucket": 0.11213175700004285, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_multipart_if_match_etag": 0.1454504199996336, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_multipart_if_match_with_delete": 0.1310921820004296, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_multipart_if_match_with_put": 0.15037759299957543, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_multipart_if_match_with_put_identical": 0.1413157119995958, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_multipart_if_none_match_with_delete": 0.15071189100035554, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_multipart_if_none_match_with_put": 0.1040178640000704, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_put_object_if_match": 0.12299135000012029, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_put_object_if_match_and_if_none_match_validation": 0.06604170600030557, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_put_object_if_match_validation": 0.08501553699989017, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_put_object_if_match_versioned_bucket": 0.1614405419995819, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_put_object_if_none_match": 0.10446344799993312, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_put_object_if_none_match_validation": 0.08416226300005292, + "tests/aws/services/s3/test_s3_api.py::TestS3ObjectWritePrecondition::test_put_object_if_none_match_versioned_bucket": 0.13820283099994413, + "tests/aws/services/s3/test_s3_api.py::TestS3PublicAccessBlock::test_crud_public_access_block": 0.10814045899996927, + "tests/aws/services/s3/test_s3_concurrency.py::TestParallelBucketCreation::test_parallel_bucket_creation": 0.4598064050001085, + "tests/aws/services/s3/test_s3_concurrency.py::TestParallelBucketCreation::test_parallel_object_creation_and_listing": 0.32165103800025463, + "tests/aws/services/s3/test_s3_concurrency.py::TestParallelBucketCreation::test_parallel_object_creation_and_read": 1.5384911649998685, + "tests/aws/services/s3/test_s3_concurrency.py::TestParallelBucketCreation::test_parallel_object_read_range": 2.6351351410007737, + "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_cors_expose_headers": 0.26255039200032115, + "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_cors_http_get_no_config": 0.11147572500021852, + "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_cors_http_options_no_config": 0.19901048099973195, + "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_cors_http_options_non_existent_bucket": 0.16172906999963743, + "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_cors_http_options_non_existent_bucket_ls_allowed": 0.07635704300037105, + "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_cors_list_buckets": 0.07972187700033828, + "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_cors_match_headers": 0.7955974349997632, + "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_cors_match_methods": 0.7490092420002838, + "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_cors_match_origins": 0.6562944610000159, + "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_cors_no_config_localstack_allowed": 0.10500783799989222, + "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_cors_options_fails_partial_origin": 0.45038796600010755, + "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_cors_options_match_partial_origin": 0.16345534799984307, + "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_delete_cors": 0.18758299899945996, + "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_get_cors": 0.1726525980002407, + "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_put_cors": 0.1627790369993818, + "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_put_cors_default_values": 0.48796134799977153, + "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_put_cors_empty_origin": 0.15997531499988327, + "tests/aws/services/s3/test_s3_cors.py::TestS3Cors::test_put_cors_invalid_rules": 0.16239919300005567, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListBuckets::test_list_buckets_by_bucket_region": 0.5756147210004201, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListBuckets::test_list_buckets_by_prefix_with_case_sensitivity": 0.5347243229998639, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListBuckets::test_list_buckets_when_continuation_token_is_empty": 0.479854714999874, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListBuckets::test_list_buckets_with_continuation_token": 0.5484644779999144, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListBuckets::test_list_buckets_with_max_buckets": 0.4848089579995758, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListMultipartUploads::test_list_multipart_uploads_marker_common_prefixes": 0.4933325930005594, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListMultipartUploads::test_list_multiparts_next_marker": 0.6250763480002206, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListMultipartUploads::test_list_multiparts_with_prefix_and_delimiter": 0.49754371100016215, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListMultipartUploads::test_s3_list_multiparts_timestamp_precision": 0.07346102200017413, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjectVersions::test_list_object_versions_pagination_common_prefixes": 0.5780135730001348, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjectVersions::test_list_objects_versions_markers": 0.675115841999741, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjectVersions::test_list_objects_versions_with_prefix": 0.5917734500003462, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjectVersions::test_list_objects_versions_with_prefix_only_and_pagination": 0.6126810580003621, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjectVersions::test_list_objects_versions_with_prefix_only_and_pagination_many_versions": 1.1160612139997284, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjectVersions::test_s3_list_object_versions_timestamp_precision": 0.10281224499976815, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjects::test_list_objects_marker_common_prefixes": 0.5460077980001188, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjects::test_list_objects_next_marker": 0.5227870899998379, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjects::test_list_objects_with_prefix[%2F]": 0.4659225229997901, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjects::test_list_objects_with_prefix[/]": 0.45269561700024497, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjects::test_list_objects_with_prefix[]": 0.45054683800026396, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjects::test_s3_list_objects_empty_marker": 0.4313675200000944, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjects::test_s3_list_objects_timestamp_precision[ListObjectsV2]": 0.08260895300054472, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjects::test_s3_list_objects_timestamp_precision[ListObjects]": 0.08437555799991969, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjectsV2::test_list_objects_v2_continuation_common_prefixes": 0.5268341190003412, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjectsV2::test_list_objects_v2_continuation_start_after": 0.6548823759999323, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjectsV2::test_list_objects_v2_with_prefix": 0.5285376099996029, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListObjectsV2::test_list_objects_v2_with_prefix_and_delimiter": 0.5103265060001831, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListParts::test_list_parts_empty_part_number_marker": 0.10087214199984373, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListParts::test_list_parts_pagination": 0.13605091799990987, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListParts::test_list_parts_via_object_attrs_pagination": 0.2428747400008433, + "tests/aws/services/s3/test_s3_list_operations.py::TestS3ListParts::test_s3_list_parts_timestamp_precision": 0.08098554499974853, + "tests/aws/services/s3/test_s3_notifications_eventbridge.py::TestS3NotificationsToEventBridge::test_object_created_put": 1.8433345409998765, + "tests/aws/services/s3/test_s3_notifications_eventbridge.py::TestS3NotificationsToEventBridge::test_object_created_put_in_different_region": 1.86470816200017, + "tests/aws/services/s3/test_s3_notifications_eventbridge.py::TestS3NotificationsToEventBridge::test_object_created_put_versioned": 6.509635985000386, + "tests/aws/services/s3/test_s3_notifications_eventbridge.py::TestS3NotificationsToEventBridge::test_object_put_acl": 1.2758390719995987, + "tests/aws/services/s3/test_s3_notifications_eventbridge.py::TestS3NotificationsToEventBridge::test_restore_object": 1.1440576820000388, + "tests/aws/services/s3/test_s3_notifications_lambda.py::TestS3NotificationsToLambda::test_create_object_by_presigned_request_via_dynamodb": 6.123400103000222, + "tests/aws/services/s3/test_s3_notifications_lambda.py::TestS3NotificationsToLambda::test_create_object_put_via_dynamodb": 2.900247516000036, + "tests/aws/services/s3/test_s3_notifications_lambda.py::TestS3NotificationsToLambda::test_invalid_lambda_arn": 0.4603442160000668, + "tests/aws/services/s3/test_s3_notifications_sns.py::TestS3NotificationsToSns::test_bucket_not_exist": 0.38114347999999154, + "tests/aws/services/s3/test_s3_notifications_sns.py::TestS3NotificationsToSns::test_bucket_notifications_with_filter": 1.6500466209995466, + "tests/aws/services/s3/test_s3_notifications_sns.py::TestS3NotificationsToSns::test_invalid_topic_arn": 0.2586807070001669, + "tests/aws/services/s3/test_s3_notifications_sns.py::TestS3NotificationsToSns::test_object_created_put": 1.7531417489994965, + "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_bucket_notification_with_invalid_filter_rules": 0.2687275150001369, + "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_delete_objects": 0.8486476420002873, + "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_filter_rules_case_insensitive": 0.09590828699992926, + "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_invalid_sqs_arn": 0.4063650820003204, + "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_key_encoding": 0.6227796719999787, + "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_multiple_invalid_sqs_arns": 0.6202301160005845, + "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_notifications_with_filter": 0.7277803260003566, + "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_object_created_and_object_removed": 0.857263100000182, + "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_object_created_complete_multipart_upload": 0.6685202470002878, + "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_object_created_copy": 0.683386698999584, + "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_object_created_put": 0.7084122100004606, + "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_object_created_put_versioned": 1.0829657750000479, + "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_object_created_put_with_presigned_url_upload": 0.9076797990001069, + "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_object_put_acl": 0.8152143250003974, + "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_object_tagging_delete_event": 0.6720708839993677, + "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_object_tagging_put_event": 0.6703523559999667, + "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_restore_object": 0.7971347439997771, + "tests/aws/services/s3/test_s3_notifications_sqs.py::TestS3NotificationsToSQS::test_xray_header": 1.6149032999996962, + "tests/aws/services/s3control/test_s3control.py::TestLegacyS3Control::test_lifecycle_public_access_block": 0.2870573879999938, + "tests/aws/services/s3control/test_s3control.py::TestLegacyS3Control::test_public_access_block_validations": 0.030416025000249647, + "tests/aws/services/s3control/test_s3control.py::TestS3ControlAccessPoint::test_access_point_already_exists": 0.0016548059998058307, + "tests/aws/services/s3control/test_s3control.py::TestS3ControlAccessPoint::test_access_point_bucket_not_exists": 0.00161970100043618, + "tests/aws/services/s3control/test_s3control.py::TestS3ControlAccessPoint::test_access_point_lifecycle": 0.0016159540000444395, + "tests/aws/services/s3control/test_s3control.py::TestS3ControlAccessPoint::test_access_point_name_validation": 0.0016247409998868534, + "tests/aws/services/s3control/test_s3control.py::TestS3ControlAccessPoint::test_access_point_pagination": 0.0016104440005619836, + "tests/aws/services/s3control/test_s3control.py::TestS3ControlAccessPoint::test_access_point_public_access_block_configuration": 0.0017036170002029394, + "tests/aws/services/s3control/test_s3control.py::TestS3ControlPublicAccessBlock::test_crud_public_access_block": 0.0016478640000059386, + "tests/aws/services/s3control/test_s3control.py::TestS3ControlPublicAccessBlock::test_empty_public_access_block": 0.0015945340005600883, + "tests/aws/services/scheduler/test_scheduler.py::test_list_schedules": 0.06491508200042517, + "tests/aws/services/scheduler/test_scheduler.py::test_tag_resource": 0.03457746100048098, + "tests/aws/services/scheduler/test_scheduler.py::test_untag_resource": 0.031048218000250927, + "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[ rate(10 minutes)]": 0.014670525999918027, + "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[at(2021-12-31)]": 0.014527179999731743, + "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[at(2021-12-31T23:59:59Z)]": 0.014557700999375811, + "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[cron()]": 0.01537453299988556, + "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[cron(0 1 * * * *)]": 0.017297516999860818, + "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[cron(0 dummy ? * MON-FRI *)]": 0.014910867999788024, + "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[cron(7 20 * * NOT *)]": 0.014462636000644125, + "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[cron(71 8 1 * ? *)]": 0.014121110999894881, + "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[cron(INVALID)]": 0.014885482999488886, + "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[rate( 10 minutes )]": 0.014256545000080223, + "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[rate()]": 0.014560407999852032, + "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[rate(-10 minutes)]": 0.01497082199966826, + "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[rate(10 minutess)]": 0.014484697000170854, + "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[rate(10 seconds)]": 0.014596536000226479, + "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[rate(10 years)]": 0.014461935999861453, + "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[rate(10)]": 0.014357531000314339, + "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_invalid_schedule_expression[rate(foo minutes)]": 0.014635128999998415, + "tests/aws/services/scheduler/test_scheduler.py::tests_create_schedule_with_valid_schedule_expression": 0.11560566500020286, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_call_lists_secrets_multiple_times": 0.053598926000177016, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_call_lists_secrets_multiple_times_snapshots": 0.0016658469994581537, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_can_recreate_delete_secret": 0.05240996600014114, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_create_and_update_secret[Valid/_+=.@-Name-a1b2]": 0.08564795199981745, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_create_and_update_secret[Valid/_+=.@-Name-a1b2c3-]": 0.08497401100021307, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_create_and_update_secret[Valid/_+=.@-Name]": 0.08700897500011706, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_create_and_update_secret[s-c64bdc03]": 0.11185663000014756, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_create_multi_secrets": 0.1025900949998686, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_create_multi_secrets_snapshot": 0.0016780699997980264, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_create_secret_version_from_empty_secret": 0.039372243999878265, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_create_secret_with_custom_id": 0.021446753999953216, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_delete_non_existent_secret_returns_as_if_secret_exists": 0.019815953000488662, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_deprecated_secret_version": 0.8665190439996877, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_deprecated_secret_version_stage": 0.191514303999611, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_exp_raised_on_creation_of_secret_scheduled_for_deletion": 0.038944376000017655, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_first_rotate_secret_with_missing_lambda_arn": 0.03430245500021556, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_force_delete_deleted_secret": 0.0534416370001054, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_get_random_exclude_characters_and_symbols": 0.01506039800005965, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_get_secret_value": 0.07460137200041572, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_get_secret_value_errors": 0.03793347700002414, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_http_put_secret_value_custom_client_request_token_new_version_stages": 0.05343149899954369, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_http_put_secret_value_duplicate_req": 0.04763476099969921, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_http_put_secret_value_null_client_request_token_new_version_stages": 0.05414937799969266, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_http_put_secret_value_with_duplicate_client_request_token": 0.048670129000129236, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_http_put_secret_value_with_non_provided_client_request_token": 0.049033853000310046, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_invalid_secret_name[ Inv *?!]Name\\\\-]": 0.10733010700050727, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_invalid_secret_name[ Inv Name]": 0.08741831900033503, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_invalid_secret_name[ Inv*Name? ]": 0.08746908500006612, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_invalid_secret_name[Inv Name]": 0.0929332050004632, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_last_accessed_date": 0.06806153300021833, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_last_updated_date": 0.09478835700019772, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_list_secrets_filtering": 0.18954647700047644, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_no_client_request_token[CreateSecret]": 0.02259410599981493, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_no_client_request_token[PutSecretValue]": 0.022540780999861454, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_no_client_request_token[RotateSecret]": 0.022150613000576413, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_no_client_request_token[UpdateSecret]": 0.022855591000279674, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_non_versioning_version_stages_no_replacement": 0.21457649200010565, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_non_versioning_version_stages_replacement": 0.21495466599935753, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_put_secret_value_with_new_custom_client_request_token": 0.0477912340002149, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_put_secret_value_with_version_stages": 0.0967174080001314, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_resource_policy": 0.04906840499961618, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_rotate_secret_invalid_lambda_arn": 0.22123540000029607, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_rotate_secret_multiple_times_with_lambda_success": 2.8084498419998454, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_rotate_secret_with_lambda_success[None]": 2.3127128139999513, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_rotate_secret_with_lambda_success[True]": 2.3174316299996462, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_secret_exists": 0.0454417480000302, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_secret_exists_snapshots": 0.04754435700033355, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_secret_not_found": 0.026254778999827977, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_secret_restore": 0.04651641499958714, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_secret_tags": 0.11846780600035345, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_secret_version_not_found": 0.043251796999356884, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_update_secret_description": 0.11362572599955456, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_update_secret_version_stages_current_pending": 0.23653131299988672, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_update_secret_version_stages_current_pending_cycle": 0.27748866699994323, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_update_secret_version_stages_current_pending_cycle_custom_stages_1": 0.2865304599999945, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_update_secret_version_stages_current_pending_cycle_custom_stages_2": 0.29910723400007555, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_update_secret_version_stages_current_pending_cycle_custom_stages_3": 1.5018751020002128, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_update_secret_version_stages_current_previous": 0.22894645400037916, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_update_secret_version_stages_return_type": 0.05574267800056987, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManager::test_update_secret_with_non_provided_client_request_token": 0.04543267800045214, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManagerMultiAccounts::test_cross_account_access": 0.13828251800032376, + "tests/aws/services/secretsmanager/test_secretsmanager.py::TestSecretsManagerMultiAccounts::test_cross_account_access_non_default_key": 0.10640958800058797, + "tests/aws/services/ses/test_ses.py::TestSES::test_cannot_create_event_for_no_topic": 0.041011978999904386, + "tests/aws/services/ses/test_ses.py::TestSES::test_clone_receipt_rule_set": 0.7337345520004419, + "tests/aws/services/ses/test_ses.py::TestSES::test_creating_event_destination_without_configuration_set": 0.06175793299917132, + "tests/aws/services/ses/test_ses.py::TestSES::test_delete_template": 0.055849796000075, + "tests/aws/services/ses/test_ses.py::TestSES::test_deleting_non_existent_configuration_set": 0.014495577999696252, + "tests/aws/services/ses/test_ses.py::TestSES::test_deleting_non_existent_configuration_set_event_destination": 0.029565247999926214, + "tests/aws/services/ses/test_ses.py::TestSES::test_get_identity_verification_attributes_for_domain": 0.011340866999489663, + "tests/aws/services/ses/test_ses.py::TestSES::test_get_identity_verification_attributes_for_email": 0.02450390299964056, + "tests/aws/services/ses/test_ses.py::TestSES::test_invalid_tags_send_email[-]": 0.014573505000498699, + "tests/aws/services/ses/test_ses.py::TestSES::test_invalid_tags_send_email[-test]": 0.014541684999585414, + "tests/aws/services/ses/test_ses.py::TestSES::test_invalid_tags_send_email[test-]": 0.014465304000168544, + "tests/aws/services/ses/test_ses.py::TestSES::test_invalid_tags_send_email[test-test_invalid_value:123]": 0.01505315700023857, + "tests/aws/services/ses/test_ses.py::TestSES::test_invalid_tags_send_email[test_invalid_name:123-test]": 0.015610261999881914, + "tests/aws/services/ses/test_ses.py::TestSES::test_invalid_tags_send_email[test_invalid_name:123-test_invalid_value:123]": 0.014519416000439378, + "tests/aws/services/ses/test_ses.py::TestSES::test_invalid_tags_send_email[test_invalid_name_len]": 0.014843466999991506, + "tests/aws/services/ses/test_ses.py::TestSES::test_invalid_tags_send_email[test_invalid_value_len]": 0.014587510000183102, + "tests/aws/services/ses/test_ses.py::TestSES::test_invalid_tags_send_email[test_priority_name_value]": 0.01465206099965144, + "tests/aws/services/ses/test_ses.py::TestSES::test_list_templates": 0.15927046599972527, + "tests/aws/services/ses/test_ses.py::TestSES::test_sending_to_deleted_topic": 0.4510891379995883, + "tests/aws/services/ses/test_ses.py::TestSES::test_sent_message_counter": 0.12428153700011535, + "tests/aws/services/ses/test_ses.py::TestSES::test_ses_sns_topic_integration_send_email": 1.5402664079997521, + "tests/aws/services/ses/test_ses.py::TestSES::test_ses_sns_topic_integration_send_raw_email": 1.5209185150006306, + "tests/aws/services/ses/test_ses.py::TestSES::test_ses_sns_topic_integration_send_templated_email": 1.5317867309995563, + "tests/aws/services/ses/test_ses.py::TestSES::test_special_tags_send_email[ses:feedback-id-a-this-marketing-campaign]": 0.015825561999918136, + "tests/aws/services/ses/test_ses.py::TestSES::test_special_tags_send_email[ses:feedback-id-b-that-campaign]": 0.016214715999467444, + "tests/aws/services/ses/test_ses.py::TestSES::test_trying_to_delete_event_destination_from_non_existent_configuration_set": 0.09009279000019887, + "tests/aws/services/ses/test_ses.py::TestSESRetrospection::test_send_email_can_retrospect": 1.5318527639997228, + "tests/aws/services/ses/test_ses.py::TestSESRetrospection::test_send_templated_email_can_retrospect": 0.07059792399968501, + "tests/aws/services/sns/test_sns.py::TestSNSCertEndpoint::test_cert_endpoint_host[]": 0.18162520099986068, + "tests/aws/services/sns/test_sns.py::TestSNSCertEndpoint::test_cert_endpoint_host[sns.us-east-1.amazonaws.com]": 0.1334205230000407, + "tests/aws/services/sns/test_sns.py::TestSNSMultiAccounts::test_cross_account_access": 0.1258500050003022, + "tests/aws/services/sns/test_sns.py::TestSNSMultiAccounts::test_cross_account_publish_to_sqs": 0.5090560509997886, + "tests/aws/services/sns/test_sns.py::TestSNSMultiRegions::test_cross_region_access": 0.07973988699995971, + "tests/aws/services/sns/test_sns.py::TestSNSMultiRegions::test_cross_region_delivery_sqs": 0.14972677900004783, + "tests/aws/services/sns/test_sns.py::TestSNSPlatformEndpoint::test_create_platform_endpoint_check_idempotency": 0.0018214659999102878, + "tests/aws/services/sns/test_sns.py::TestSNSPlatformEndpoint::test_publish_disabled_endpoint": 0.12142043099993316, + "tests/aws/services/sns/test_sns.py::TestSNSPlatformEndpoint::test_publish_to_gcm": 0.001800015999833704, + "tests/aws/services/sns/test_sns.py::TestSNSPlatformEndpoint::test_publish_to_platform_endpoint_is_dispatched": 0.13921688800019183, + "tests/aws/services/sns/test_sns.py::TestSNSPlatformEndpoint::test_subscribe_platform_endpoint": 0.17415846599942597, + "tests/aws/services/sns/test_sns.py::TestSNSPublishCrud::test_empty_sns_message": 0.0886730510005691, + "tests/aws/services/sns/test_sns.py::TestSNSPublishCrud::test_message_structure_json_exc": 0.055418145999738044, + "tests/aws/services/sns/test_sns.py::TestSNSPublishCrud::test_publish_batch_too_long_message": 0.0730227570002171, + "tests/aws/services/sns/test_sns.py::TestSNSPublishCrud::test_publish_by_path_parameters": 0.1359510140000566, + "tests/aws/services/sns/test_sns.py::TestSNSPublishCrud::test_publish_message_before_subscribe_topic": 0.14073098099970593, + "tests/aws/services/sns/test_sns.py::TestSNSPublishCrud::test_publish_message_by_target_arn": 0.19691519300022264, + "tests/aws/services/sns/test_sns.py::TestSNSPublishCrud::test_publish_non_existent_target": 0.03250794799987489, + "tests/aws/services/sns/test_sns.py::TestSNSPublishCrud::test_publish_too_long_message": 0.07354350400009935, + "tests/aws/services/sns/test_sns.py::TestSNSPublishCrud::test_publish_with_empty_subject": 0.04070268000032229, + "tests/aws/services/sns/test_sns.py::TestSNSPublishCrud::test_publish_wrong_arn_format": 0.03271540099967751, + "tests/aws/services/sns/test_sns.py::TestSNSPublishCrud::test_topic_publish_another_region": 0.05754724400003397, + "tests/aws/services/sns/test_sns.py::TestSNSPublishCrud::test_unknown_topic_publish": 0.04070768400015368, + "tests/aws/services/sns/test_sns.py::TestSNSPublishDelivery::test_delivery_lambda": 2.0746540400000413, + "tests/aws/services/sns/test_sns.py::TestSNSRetrospectionEndpoints::test_publish_sms_can_retrospect": 0.2531518689997938, + "tests/aws/services/sns/test_sns.py::TestSNSRetrospectionEndpoints::test_publish_to_platform_endpoint_can_retrospect": 0.20521074899943414, + "tests/aws/services/sns/test_sns.py::TestSNSRetrospectionEndpoints::test_subscription_tokens_can_retrospect": 2.412056286999814, + "tests/aws/services/sns/test_sns.py::TestSNSSMS::test_publish_sms": 0.015131248999296076, + "tests/aws/services/sns/test_sns.py::TestSNSSMS::test_publish_sms_endpoint": 0.15543567900022026, + "tests/aws/services/sns/test_sns.py::TestSNSSMS::test_publish_wrong_phone_format": 0.04958740499932901, + "tests/aws/services/sns/test_sns.py::TestSNSSMS::test_subscribe_sms_endpoint": 0.04673392699942269, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionCrud::test_create_subscriptions_with_attributes": 0.08385199999975157, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionCrud::test_list_subscriptions": 0.3363484410001547, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionCrud::test_list_subscriptions_by_topic_pagination": 1.5031704299999546, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionCrud::test_not_found_error_on_set_subscription_attributes": 0.30026444199984326, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionCrud::test_sns_confirm_subscription_wrong_token": 0.12264556299987817, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionCrud::test_subscribe_idempotency": 0.11191757999995389, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionCrud::test_subscribe_with_invalid_protocol": 0.0322593699997924, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionCrud::test_subscribe_with_invalid_topic": 0.048284674999649724, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionCrud::test_unsubscribe_from_non_existing_subscription": 0.08806163300050684, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionCrud::test_unsubscribe_idempotency": 0.08963717200049359, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionCrud::test_unsubscribe_wrong_arn_format": 0.03199189099950672, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionCrud::test_validate_set_sub_attributes": 0.2678716450000138, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionFirehose::test_publish_to_firehose_with_s3": 1.2944442100001652, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionHttp::test_dlq_external_http_endpoint[False]": 2.6770939090001775, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionHttp::test_dlq_external_http_endpoint[True]": 2.6683900769999127, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionHttp::test_http_subscription_response": 0.07359495500031699, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionHttp::test_multiple_subscriptions_http_endpoint": 1.7171804459999294, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionHttp::test_redrive_policy_http_subscription": 0.6425859030005086, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionHttp::test_subscribe_external_http_endpoint[False]": 1.6249605030002385, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionHttp::test_subscribe_external_http_endpoint[True]": 1.6301829009998983, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionHttp::test_subscribe_external_http_endpoint_content_type[False]": 1.6058741650003867, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionHttp::test_subscribe_external_http_endpoint_content_type[True]": 1.6085446639995098, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionHttp::test_subscribe_external_http_endpoint_lambda_url_sig_validation": 2.095204957000533, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionLambda::test_publish_lambda_verify_signature[1]": 4.215745101999801, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionLambda::test_publish_lambda_verify_signature[2]": 4.242130937000184, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionLambda::test_python_lambda_subscribe_sns_topic": 4.197573376000037, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionLambda::test_redrive_policy_lambda_subscription": 1.3112038459994437, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionLambda::test_sns_topic_as_lambda_dead_letter_queue": 2.358016221000071, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSES::test_email_sender": 2.1029696549994696, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSES::test_topic_email_subscription_confirmation": 0.06228611500000625, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_attribute_raw_subscribe": 0.14234896999960256, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_empty_or_wrong_message_attributes": 0.29261558799998966, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_message_attributes_not_missing": 0.22544612600040637, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_message_attributes_prefixes": 0.17211738200012405, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_message_structure_json_to_sqs": 0.200248174999615, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_publish_batch_exceptions": 0.06838407300028848, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_publish_batch_messages_from_sns_to_sqs": 0.6673131469997315, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_publish_batch_messages_without_topic": 0.03474431300037395, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_publish_sqs_from_sns": 0.22994953299985355, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_publish_sqs_from_sns_with_xray_propagation": 0.13420569399977467, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_publish_sqs_verify_signature[1]": 0.14349877599988758, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_publish_sqs_verify_signature[2]": 0.1423751090001133, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_publish_unicode_chars": 0.13328402900015135, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_redrive_policy_sqs_queue_subscription[False]": 0.19310960500069996, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_redrive_policy_sqs_queue_subscription[True]": 0.20134648600060245, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_sqs_topic_subscription_confirmation": 0.07335083199950532, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_subscribe_sqs_queue": 0.1730452389997481, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_subscribe_to_sqs_with_queue_url": 0.04762818800008972, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQS::test_subscription_after_failure_to_deliver": 1.509153435999906, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_fifo_topic_to_regular_sqs[False]": 0.2694609459995263, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_fifo_topic_to_regular_sqs[True]": 0.2692964299999403, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_message_to_fifo_sqs[False]": 1.1670739920000415, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_message_to_fifo_sqs[True]": 1.173240798000279, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_message_to_fifo_sqs_ordering": 2.586876251999911, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_publish_batch_messages_from_fifo_topic_to_fifo_queue[False]": 3.6435898190002263, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_publish_batch_messages_from_fifo_topic_to_fifo_queue[True]": 3.6427861230004055, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_publish_fifo_messages_to_dlq[False]": 1.5592932029999247, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_publish_fifo_messages_to_dlq[True]": 1.5665144300000975, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_publish_to_fifo_topic_deduplication_on_topic_level": 1.6655979899996964, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_publish_to_fifo_topic_to_sqs_queue_no_content_dedup[False]": 0.26698093199911455, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_publish_to_fifo_topic_to_sqs_queue_no_content_dedup[True]": 0.27157499300028576, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_publish_to_fifo_with_target_arn": 0.03300230200011356, + "tests/aws/services/sns/test_sns.py::TestSNSSubscriptionSQSFifo::test_validations_for_fifo": 0.23112610699945435, + "tests/aws/services/sns/test_sns.py::TestSNSTopicCrud::test_create_duplicate_topic_check_idempotency": 0.08665219199974672, + "tests/aws/services/sns/test_sns.py::TestSNSTopicCrud::test_create_duplicate_topic_with_more_tags": 0.032933589999629476, + "tests/aws/services/sns/test_sns.py::TestSNSTopicCrud::test_create_topic_after_delete_with_new_tags": 0.05351727299921549, + "tests/aws/services/sns/test_sns.py::TestSNSTopicCrud::test_create_topic_test_arn": 0.3053685600002609, + "tests/aws/services/sns/test_sns.py::TestSNSTopicCrud::test_create_topic_with_attributes": 0.2761789059995863, + "tests/aws/services/sns/test_sns.py::TestSNSTopicCrud::test_delete_topic_idempotency": 0.05172369499996421, + "tests/aws/services/sns/test_sns.py::TestSNSTopicCrud::test_tags": 0.08310183300045537, + "tests/aws/services/sns/test_sns.py::TestSNSTopicCrud::test_topic_delivery_policy_crud": 0.0016716589998395648, + "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyAttributes::test_exists_filter_policy": 0.30604541499951665, + "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyAttributes::test_exists_filter_policy_attributes_array": 4.273497275999944, + "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyAttributes::test_filter_policy": 5.323017856999741, + "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyBody::test_filter_policy_empty_array_payload": 0.1698930279999331, + "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyBody::test_filter_policy_for_batch": 3.3822688209997978, + "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyBody::test_filter_policy_ip_address_condition": 0.3429991430002701, + "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyBody::test_filter_policy_large_complex_payload": 0.18824107999989792, + "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyBody::test_filter_policy_on_message_body[False]": 5.328899086999172, + "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyBody::test_filter_policy_on_message_body[True]": 5.328909401000146, + "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyBody::test_filter_policy_on_message_body_array_attributes": 0.6285723420000977, + "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyBody::test_filter_policy_on_message_body_array_of_object_attributes": 0.3430771879993699, + "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyBody::test_filter_policy_on_message_body_dot_attribute": 5.574634939999669, + "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyBody::test_filter_policy_on_message_body_or_attribute": 0.8192823989998033, + "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyConditions::test_policy_complexity": 0.053249705999405705, + "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyConditions::test_policy_complexity_with_or": 0.05693690599991896, + "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyConditions::test_validate_policy": 0.12268843100036975, + "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyConditions::test_validate_policy_exists_operator": 0.11609053499978472, + "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyConditions::test_validate_policy_nested_anything_but_operator": 0.16242894699962562, + "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyConditions::test_validate_policy_numeric_operator": 0.2175010369996926, + "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyConditions::test_validate_policy_string_operators": 0.21940426699984528, + "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyCrud::test_set_subscription_filter_policy_scope": 0.12499729000001025, + "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyCrud::test_sub_filter_policy_nested_property": 0.10803628599978765, + "tests/aws/services/sns/test_sns_filter_policy.py::TestSNSFilterPolicyCrud::test_sub_filter_policy_nested_property_constraints": 0.177852563000215, + "tests/aws/services/sqs/test_sqs.py::TestSQSMultiAccounts::test_cross_account_access[domain]": 0.09700663399999598, + "tests/aws/services/sqs/test_sqs.py::TestSQSMultiAccounts::test_cross_account_access[path]": 0.09297219099994436, + "tests/aws/services/sqs/test_sqs.py::TestSQSMultiAccounts::test_cross_account_access[standard]": 1.1259620570000095, + "tests/aws/services/sqs/test_sqs.py::TestSQSMultiAccounts::test_cross_account_get_queue_url[domain]": 0.029453788000040504, + "tests/aws/services/sqs/test_sqs.py::TestSQSMultiAccounts::test_cross_account_get_queue_url[path]": 0.03106258700000808, + "tests/aws/services/sqs/test_sqs.py::TestSQSMultiAccounts::test_cross_account_get_queue_url[standard]": 0.030582523000020956, + "tests/aws/services/sqs/test_sqs.py::TestSQSMultiAccounts::test_delete_queue_multi_account[sqs]": 0.2250524000000098, + "tests/aws/services/sqs/test_sqs.py::TestSQSMultiAccounts::test_delete_queue_multi_account[sqs_query]": 0.10446263100001829, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_approximate_number_of_messages_delayed[sqs]": 3.132674118000068, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_approximate_number_of_messages_delayed[sqs_query]": 3.1375497190001624, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_batch_send_with_invalid_char_should_succeed[sqs]": 0.11866529399958381, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_batch_send_with_invalid_char_should_succeed[sqs_query]": 0.11642969000058656, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_change_message_visibility_after_visibility_timeout_expiration[sqs]": 2.1010728149999522, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_change_message_visibility_after_visibility_timeout_expiration[sqs_query]": 2.1017634670001826, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_change_message_visibility_batch_with_too_large_batch[sqs]": 0.883112873000016, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_change_message_visibility_batch_with_too_large_batch[sqs_query]": 0.7176341109999953, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_change_message_visibility_not_permanent[sqs]": 0.15747184800000014, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_change_message_visibility_not_permanent[sqs_query]": 0.19496589399997788, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_change_visibility_on_deleted_message_raises_invalid_parameter_value[sqs]": 0.10161979700001211, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_change_visibility_on_deleted_message_raises_invalid_parameter_value[sqs_query]": 0.1030107319999729, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_and_send_to_fifo_queue[sqs]": 0.11450390300001345, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_and_send_to_fifo_queue[sqs_query]": 0.11820256800004358, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_and_update_queue_attributes[sqs]": 0.08219186600035755, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_and_update_queue_attributes[sqs_query]": 0.08384735000026922, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_fifo_queue_with_different_attributes_raises_error[sqs]": 0.14158620500029429, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_fifo_queue_with_different_attributes_raises_error[sqs_query]": 0.14153152599965324, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_fifo_queue_with_same_attributes_is_idempotent": 0.036367301999689516, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_after_internal_attributes_changes_works[sqs]": 0.08304295899961289, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_after_internal_attributes_changes_works[sqs_query]": 0.08383224200042605, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_after_modified_attributes[sqs]": 0.0017113509998125664, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_after_modified_attributes[sqs_query]": 0.0016025589998207579, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_after_send[sqs]": 0.11243977700041796, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_after_send[sqs_query]": 0.11357402999965416, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_and_get_attributes[sqs]": 0.02990025599956425, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_and_get_attributes[sqs_query]": 0.03177236000010453, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_recently_deleted[sqs]": 0.0350043389998973, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_recently_deleted[sqs_query]": 0.037067986000693054, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_recently_deleted_cache[sqs]": 1.5509754680001606, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_recently_deleted_cache[sqs_query]": 1.5510937829994873, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_recently_deleted_can_be_disabled[sqs]": 0.043554386999403505, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_recently_deleted_can_be_disabled[sqs_query]": 0.04272159299989653, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_with_default_arguments_works_with_modified_attributes[sqs]": 0.0017773550002857519, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_with_default_arguments_works_with_modified_attributes[sqs_query]": 0.0017249369998353359, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_with_default_attributes_is_idempotent": 0.03935656099974949, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_with_different_attributes_raises_exception[sqs]": 0.19617200499942555, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_with_different_attributes_raises_exception[sqs_query]": 0.1971635959998821, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_with_same_attributes_is_idempotent": 0.03495283099982771, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_with_tags[sqs]": 0.02759762999949089, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_with_tags[sqs_query]": 0.027797288999863667, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_queue_without_attributes_is_idempotent": 0.034279114000128175, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_standard_queue_with_fifo_attribute_raises_error[sqs]": 0.07778701199913485, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_create_standard_queue_with_fifo_attribute_raises_error[sqs_query]": 0.07713379300002998, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_dead_letter_queue_chain[sqs]": 0.002394660999982534, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_dead_letter_queue_chain[sqs_query]": 0.002221063999996886, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_dead_letter_queue_config": 0.06671148600003107, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_dead_letter_queue_execution_lambda_mapping_preserves_id[sqs]": 0.0030832269999905293, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_dead_letter_queue_execution_lambda_mapping_preserves_id[sqs_query]": 0.002449733999981163, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_dead_letter_queue_list_sources[sqs]": 0.08438539300001935, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_dead_letter_queue_list_sources[sqs_query]": 0.08349773700001606, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_dead_letter_queue_max_receive_count[sqs]": 0.1580767680000008, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_dead_letter_queue_max_receive_count[sqs_query]": 0.17078098999999725, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_dead_letter_queue_message_attributes": 0.816229858999975, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_dead_letter_queue_with_fifo_and_content_based_deduplication[sqs]": 0.2149176820000207, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_dead_letter_queue_with_fifo_and_content_based_deduplication[sqs_query]": 0.219592361999986, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_deduplication_interval[sqs]": 0.00214187299999935, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_deduplication_interval[sqs_query]": 0.0019641979999960313, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_after_visibility_timeout[sqs]": 1.1277474910002638, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_after_visibility_timeout[sqs_query]": 1.137950510000337, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_batch_from_lambda[sqs]": 0.0018468339999344607, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_batch_from_lambda[sqs_query]": 0.0017697999996926228, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_batch_invalid_msg_id[sqs-]": 0.12363772800000561, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_batch_invalid_msg_id[sqs-invalid:id]": 0.13712971399999674, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_batch_invalid_msg_id[sqs-testLongIdtestLongIdtestLongIdtestLongIdtestLongIdtestLongIdtestLongIdtestLongIdtestLongIdtestLongId]": 0.13123869600002536, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_batch_invalid_msg_id[sqs_query-]": 0.11477346599997418, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_batch_invalid_msg_id[sqs_query-invalid:id]": 0.171683943000005, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_batch_invalid_msg_id[sqs_query-testLongIdtestLongIdtestLongIdtestLongIdtestLongIdtestLongIdtestLongIdtestLongIdtestLongIdtestLongId]": 0.11776025899999354, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_batch_with_too_large_batch[sqs]": 0.8884240430000148, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_batch_with_too_large_batch[sqs_query]": 1.15753644199998, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_deletes_with_change_visibility_timeout[sqs]": 0.12769488000049023, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_deletes_with_change_visibility_timeout[sqs_query]": 0.13136690900000758, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_with_deleted_receipt_handle[sqs]": 0.08075464900002771, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_with_deleted_receipt_handle[sqs_query]": 0.06405155999999579, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_with_illegal_receipt_handle[sqs]": 0.035484843000006094, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_delete_message_with_illegal_receipt_handle[sqs_query]": 0.0436317329999838, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_disallow_queue_name_with_slashes": 0.0031166310000401154, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_extend_message_visibility_timeout_set_in_queue[sqs]": 6.162805739000305, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_extend_message_visibility_timeout_set_in_queue[sqs_query]": 6.997480597000049, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_external_endpoint[sqs]": 0.10857651399919632, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_external_endpoint[sqs_query]": 0.16679374499972255, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_external_host_via_header_complete_message_lifecycle": 0.08778107800026191, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_external_hostname_via_host_header": 0.06489391000013711, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_approx_number_of_messages[sqs]": 0.2429420590005975, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_approx_number_of_messages[sqs_query]": 0.2510279799998898, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_change_to_high_throughput_after_creation[sqs]": 0.3433468319999804, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_change_to_high_throughput_after_creation[sqs_query]": 0.37961048500002903, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_change_to_regular_throughput_after_creation[sqs]": 0.29429433499998936, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_change_to_regular_throughput_after_creation[sqs_query]": 0.2855547879999847, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_content_based_message_deduplication_arrives_once[sqs]": 1.1209046230000013, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_content_based_message_deduplication_arrives_once[sqs_query]": 1.0922226049999892, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_deduplication_arrives_once_after_delete[sqs-False]": 1.217189053999988, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_deduplication_arrives_once_after_delete[sqs-True]": 1.1383746660000043, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_deduplication_arrives_once_after_delete[sqs_query-False]": 1.1770048919999851, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_deduplication_arrives_once_after_delete[sqs_query-True]": 1.1949159870000017, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_deduplication_not_on_message_group_id[sqs-False]": 1.1577926740000066, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_deduplication_not_on_message_group_id[sqs-True]": 1.1592088230000002, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_deduplication_not_on_message_group_id[sqs_query-False]": 1.2621608839999965, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_deduplication_not_on_message_group_id[sqs_query-True]": 1.1565383489999874, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_delete_after_visibility_timeout[sqs]": 1.1852583909994792, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_delete_after_visibility_timeout[sqs_query]": 1.185417439000048, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_delete_message_with_expired_receipt_handle[sqs]": 0.0017371789995195286, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_delete_message_with_expired_receipt_handle[sqs_query]": 0.0016602659998170566, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_empty_message_groups_added_back_to_queue[sqs]": 0.1726493519995529, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_empty_message_groups_added_back_to_queue[sqs_query]": 0.17320950500015897, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_high_throughput_ordering[sqs]": 0.17005798000002414, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_high_throughput_ordering[sqs_query]": 0.17470402400002172, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_message_attributes[sqs]": 0.1581135850001374, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_message_attributes[sqs_query]": 0.16021523000017623, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_message_group_visibility": 2.120088570000007, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_message_group_visibility_after_change_message_visibility[sqs]": 2.1183042740003657, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_message_group_visibility_after_change_message_visibility[sqs_query]": 2.1244160940000256, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_message_group_visibility_after_delete[sqs]": 0.23575836899954083, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_message_group_visibility_after_delete[sqs_query]": 0.2799893070005055, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_message_group_visibility_after_partial_delete[sqs]": 0.30157227300060185, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_message_group_visibility_after_partial_delete[sqs_query]": 0.2544022540005244, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_message_group_visibility_after_terminate_visibility_timeout[sqs]": 0.1348698729998432, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_message_group_visibility_after_terminate_visibility_timeout[sqs_query]": 0.13807516600036251, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_messages_in_order_after_timeout[sqs]": 2.1353628759993626, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_messages_in_order_after_timeout[sqs_query]": 2.1091233959996316, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_queue_requires_suffix": 0.03386665499996866, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_queue_send_message_with_delay_on_queue_works[sqs]": 4.108970381999825, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_queue_send_message_with_delay_on_queue_works[sqs_query]": 4.110584672000186, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_queue_send_message_with_delay_seconds_fails[sqs]": 0.17040344500037463, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_queue_send_message_with_delay_seconds_fails[sqs_query]": 0.159065482999722, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_queue_send_multiple_messages_multiple_single_receives[sqs]": 0.2847527449999916, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_queue_send_multiple_messages_multiple_single_receives[sqs_query]": 0.2855318029999978, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_receive_message_group_id_ordering[sqs]": 0.13658184999940204, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_receive_message_group_id_ordering[sqs_query]": 0.13611421300038273, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_receive_message_visibility_timeout_shared_in_group[sqs]": 2.1817693149996558, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_receive_message_visibility_timeout_shared_in_group[sqs_query]": 2.1937072609998722, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_receive_message_with_zero_visibility_timeout[sqs]": 0.1755401850000453, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_receive_message_with_zero_visibility_timeout[sqs_query]": 0.1802540260000569, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_sequence_number_increases[sqs]": 0.14676063900000713, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_sequence_number_increases[sqs_query]": 0.1606716370000072, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_set_content_based_deduplication_strategy[sqs]": 0.08662035600036688, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_fifo_set_content_based_deduplication_strategy[sqs_query]": 0.08511430699991251, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_get_list_queues_with_query_auth": 0.04696853100000453, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_get_queue_url_contains_localstack_host[sqs]": 0.029329222999876947, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_get_queue_url_contains_localstack_host[sqs_query]": 0.03777957000011156, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_get_queue_url_multi_region[domain]": 0.04997466900002223, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_get_queue_url_multi_region[path]": 0.05001401200001965, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_get_queue_url_multi_region[standard]": 0.05403107100002558, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_get_specific_queue_attribute_response[sqs]": 0.08033138500002224, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_get_specific_queue_attribute_response[sqs_query]": 0.07153429099997766, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_inflight_message_requeue": 4.616462746999986, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_invalid_batch_id[sqs]": 1.6293685139999923, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_invalid_batch_id[sqs_query]": 0.2631312960000116, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_invalid_dead_letter_arn_rejected_before_lookup": 0.0031613850000269395, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_invalid_receipt_handle_should_return_error_message[sqs]": 0.030110090000562195, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_invalid_receipt_handle_should_return_error_message[sqs_query]": 0.0295339099998273, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_invalid_string_attributes_cause_invalid_parameter_value_error[sqs]": 0.056603089000020645, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_invalid_string_attributes_cause_invalid_parameter_value_error[sqs_query]": 0.05401362799997855, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_list_queue_tags[sqs]": 0.03420747600011964, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_list_queue_tags[sqs_query]": 0.03530155999942508, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_list_queues": 0.09611651600016557, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_list_queues_multi_region_with_endpoint_strategy_domain": 0.0652703039999949, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_list_queues_multi_region_with_endpoint_strategy_standard": 0.06524505199996611, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_list_queues_multi_region_without_endpoint_strategy": 0.07821504300002857, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_list_queues_pagination": 0.2712403560003622, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_marker_serialization_json_protocol[\"{\\\\\"foo\\\\\": \\\\\"ba\\\\rr\\\\\"}\"]": 0.07746783199991114, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_marker_serialization_json_protocol[{\"foo\": \"ba\\rr\", \"foo2\": \"ba"r"\"}]": 0.0795767380000143, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_message_deduplication_id_too_long": 0.16338312299967583, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_message_group_id_too_long": 0.16298225400032607, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_message_retention": 3.0693264170004113, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_message_retention_fifo": 3.078094061000229, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_message_retention_with_inflight": 5.61030814500009, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_message_system_attribute_names_with_attribute_names[sqs]": 0.129527693999961, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_message_system_attribute_names_with_attribute_names[sqs_query]": 0.1387777939999637, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_message_with_attributes_should_be_enqueued[sqs]": 0.061261567999736144, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_message_with_attributes_should_be_enqueued[sqs_query]": 0.06280686699983562, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_message_with_carriage_return[sqs]": 0.12200776800000313, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_message_with_carriage_return[sqs_query]": 0.10591326000002255, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_non_existent_queue": 0.27154993099998137, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_posting_to_fifo_requires_deduplicationid_group_id[sqs]": 0.4684033470000202, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_posting_to_fifo_requires_deduplicationid_group_id[sqs_query]": 0.45655784199999516, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_posting_to_queue_via_queue_name[sqs]": 0.07753673799999206, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_posting_to_queue_via_queue_name[sqs_query]": 0.11289443600000482, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_publish_get_delete_message[sqs]": 0.09236037799973928, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_publish_get_delete_message[sqs_query]": 0.0915415560002657, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_publish_get_delete_message_batch[sqs]": 0.11335122399998454, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_publish_get_delete_message_batch[sqs_query]": 0.1267404929999998, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_purge_queue[sqs]": 1.3751787420000028, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_purge_queue[sqs_query]": 1.2687468730000262, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_purge_queue_clears_fifo_deduplication_cache[sqs]": 0.10284594700002003, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_purge_queue_clears_fifo_deduplication_cache[sqs_query]": 0.10141912900002126, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_purge_queue_deletes_delayed_messages[sqs]": 3.1812709509999877, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_purge_queue_deletes_delayed_messages[sqs_query]": 3.1701205699999946, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_purge_queue_deletes_inflight_messages[sqs]": 4.257675323000001, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_purge_queue_deletes_inflight_messages[sqs_query]": 4.279287834999991, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_queue_list_nonexistent_tags[sqs]": 0.02814552600011666, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_queue_list_nonexistent_tags[sqs_query]": 0.029168067000227893, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_after_visibility_timeout[sqs]": 1.7281771300004038, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_after_visibility_timeout[sqs_query]": 1.994484743999692, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_empty_queue[sqs]": 1.090049466000437, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_empty_queue[sqs_query]": 1.0897252750000916, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_message_attribute_names_filters[sqs]": 0.24689023100000895, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_message_attribute_names_filters[sqs_query]": 0.2563755310000033, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_message_attributes_timestamp_types[sqs]": 0.07419738600037817, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_message_attributes_timestamp_types[sqs_query]": 0.08757626399983565, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_message_message_attribute_names_filters[sqs]": 0.27445260400000393, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_message_message_attribute_names_filters[sqs_query]": 0.27544773099995723, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_message_message_system_attribute_names_filters[sqs]": 0.17068033800001103, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_message_message_system_attribute_names_filters[sqs_query]": 0.16807901100000322, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_message_wait_time_seconds_and_max_number_of_messages_does_not_block[sqs]": 0.09281016499971884, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_message_wait_time_seconds_and_max_number_of_messages_does_not_block[sqs_query]": 0.09316606199990929, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_message_with_visibility_timeout_updates_timeout[sqs]": 0.09131525100019644, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_message_with_visibility_timeout_updates_timeout[sqs_query]": 0.094855144999201, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_terminate_visibility_timeout[sqs]": 0.09471885600032692, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_terminate_visibility_timeout[sqs_query]": 0.09398187099986899, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_redrive_policy_attribute_validity[sqs]": 0.00344659200001729, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_redrive_policy_attribute_validity[sqs_query]": 0.003830734999979768, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_remove_message_with_old_receipt_handle[sqs]": 2.093728841999962, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_remove_message_with_old_receipt_handle[sqs_query]": 2.095365488999988, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_batch_message_size": 1.1266579710000144, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_batch_missing_deduplication_id_for_fifo_queue[sqs]": 0.20666274999999246, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_batch_missing_deduplication_id_for_fifo_queue[sqs_query]": 0.17753718900002013, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_batch_missing_message_group_id_for_fifo_queue[sqs]": 0.19463262700000428, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_batch_missing_message_group_id_for_fifo_queue[sqs_query]": 0.2037766470000406, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_batch_receive_multiple[sqs]": 0.1045333879997088, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_batch_receive_multiple[sqs_query]": 0.1074978130004638, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_delay_and_wait_time[sqs]": 1.69203183000036, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_delay_and_wait_time[sqs_query]": 1.997564338000302, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_empty_message[sqs]": 0.13996525800030213, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_empty_message[sqs_query]": 0.14158619599947997, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_batch[sqs]": 0.1134980709998672, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_batch[sqs_query]": 0.11289953500045158, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_batch_with_empty_list[sqs]": 0.028564422999806993, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_batch_with_empty_list[sqs_query]": 0.029754578999927617, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_batch_with_oversized_contents[sqs]": 0.14676036600030784, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_batch_with_oversized_contents[sqs_query]": 0.14878145399961795, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_batch_with_oversized_contents_with_updated_maximum_message_size[sqs]": 0.11081724800078518, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_batch_with_oversized_contents_with_updated_maximum_message_size[sqs_query]": 0.11132254099948113, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_to_standard_queue_with_empty_message_group_id": 0.08396440699971208, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_attributes[sqs]": 0.0979601969999635, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_attributes[sqs_query]": 0.10587088100001552, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_binary_attributes[sqs]": 0.15734075799997527, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_binary_attributes[sqs_query]": 0.14530453100005047, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_delay_0_works_for_fifo[sqs]": 0.06190736000007746, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_delay_0_works_for_fifo[sqs_query]": 0.06160130999978719, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_empty_string_attribute[sqs]": 0.18212361599998417, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_empty_string_attribute[sqs_query]": 0.18059135600003628, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_invalid_fifo_parameters[sqs]": 0.0029071649999821148, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_invalid_fifo_parameters[sqs_query]": 0.0030893189999972037, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_invalid_payload_characters[sqs]": 0.048268769999992855, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_invalid_payload_characters[sqs_query]": 0.044094717999968225, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_invalid_string_attributes[sqs]": 0.17651722200000108, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_invalid_string_attributes[sqs_query]": 0.18473405000000298, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_updated_maximum_message_size[sqs]": 0.1725253389995487, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_message_with_updated_maximum_message_size[sqs_query]": 0.17307643000003736, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_oversized_message[sqs]": 0.14661599100054445, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_oversized_message[sqs_query]": 0.150029196000105, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_receive_max_number_of_messages[sqs]": 0.16371004199982053, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_receive_max_number_of_messages[sqs_query]": 0.16516077300047982, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_receive_message[sqs]": 0.06314650400008759, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_receive_message[sqs_query]": 0.06560633399976723, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_receive_message_encoded_content[sqs]": 0.06133054800056925, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_receive_message_encoded_content[sqs_query]": 0.06226437999976042, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_receive_message_multiple_queues": 0.10535586000014519, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_receive_wait_time_seconds[sqs]": 0.23328640799991263, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_receive_wait_time_seconds[sqs_query]": 0.26601174300049024, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sent_message_retains_attributes_after_receive[sqs]": 0.10883110599999668, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sent_message_retains_attributes_after_receive[sqs_query]": 0.11041672099997868, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sequence_number[sqs]": 0.09938303199999154, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sequence_number[sqs_query]": 0.1252940989999729, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_set_empty_queue_policy[sqs]": 0.1086971169999913, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_set_empty_queue_policy[sqs_query]": 0.1067873860000077, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_set_empty_redrive_policy[sqs]": 0.11304070799999977, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_set_empty_redrive_policy[sqs_query]": 0.11593708900002753, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_set_queue_policy[sqs]": 0.0679240830000083, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_set_queue_policy[sqs_query]": 0.07966290699999945, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_set_unsupported_attribute_fifo[sqs]": 0.278661091999993, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_set_unsupported_attribute_fifo[sqs_query]": 0.2979286370000125, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_set_unsupported_attribute_standard[sqs]": 0.2607583829999669, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_set_unsupported_attribute_standard[sqs_query]": 0.2515141369999867, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sqs_fifo_message_group_scope_no_throughput_setting[sqs]": 0.16677484499999196, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sqs_fifo_message_group_scope_no_throughput_setting[sqs_query]": 0.1704986250000502, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sqs_fifo_same_dedup_id_different_message_groups[sqs]": 0.1667663260000154, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sqs_fifo_same_dedup_id_different_message_groups[sqs_query]": 0.16663728199998218, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sqs_permission_lifecycle[sqs]": 0.383878076000002, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sqs_permission_lifecycle[sqs_query]": 0.2871844339999825, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sse_kms_and_sqs_are_mutually_exclusive[sqs]": 0.001931208000002016, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sse_kms_and_sqs_are_mutually_exclusive[sqs_query]": 0.0017596749999881922, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sse_queue_attributes[sqs]": 0.11099304900000106, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_sse_queue_attributes[sqs_query]": 0.11423053100003244, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_standard_queue_cannot_have_fifo_suffix": 0.02812432300001433, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_successive_purge_calls_fail[sqs]": 0.15865656999997668, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_successive_purge_calls_fail[sqs_query]": 0.1620032120000019, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_system_attributes_have_no_effect_on_attr_md5[sqs]": 0.1276836239999568, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_system_attributes_have_no_effect_on_attr_md5[sqs_query]": 0.1303231010000161, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_tag_queue_overwrites_existing_tag[sqs]": 0.04036844500024017, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_tag_queue_overwrites_existing_tag[sqs_query]": 0.04116884099994422, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_tag_untag_queue[sqs]": 0.10428988800003935, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_tag_untag_queue[sqs_query]": 0.10366048600008071, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_tags_case_sensitive[sqs]": 0.035268821999579814, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_tags_case_sensitive[sqs_query]": 0.0348542169999746, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_terminate_visibility_timeout_after_receive[sqs]": 0.09899920500038206, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_terminate_visibility_timeout_after_receive[sqs_query]": 0.0987952509999559, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_too_many_entries_in_batch_request[sqs]": 0.1416589890004616, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_too_many_entries_in_batch_request[sqs_query]": 0.7484206919998542, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_untag_queue_ignores_non_existing_tag[sqs]": 0.04024388299967541, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_untag_queue_ignores_non_existing_tag[sqs_query]": 0.04085113699966314, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_wait_time_seconds_queue_attribute_waits_correctly[sqs]": 1.0617544669999006, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_wait_time_seconds_queue_attribute_waits_correctly[sqs_query]": 1.0573050570001215, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_wait_time_seconds_waits_correctly[sqs]": 1.0588185040001008, + "tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_wait_time_seconds_waits_correctly[sqs_query]": 1.0627414730001874, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_endpoint_strategy_with_multi_region[domain]": 0.12655722800002422, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_endpoint_strategy_with_multi_region[off]": 0.129038195000021, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_endpoint_strategy_with_multi_region[path]": 0.12671940099997414, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_endpoint_strategy_with_multi_region[standard]": 0.18392066700002374, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_create_queue_fails": 0.03498967999999536, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_delete_queue[domain]": 0.04921194299998888, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_delete_queue[path]": 0.05140457600001014, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_delete_queue[standard]": 0.050330190000011044, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_list_queues_fails": 0.03298735599994984, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_list_queues_fails_json_format": 0.0019037160000152653, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_on_deleted_queue_fails[sqs]": 0.05643106900001271, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_on_deleted_queue_fails[sqs_query]": 0.06217880599999148, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_attributes_all": 0.13759825500002876, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_attributes_json_format": 0.0016764469999941412, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_attributes_of_fifo_queue": 0.04431331399996452, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_attributes_with_invalid_arg_returns_error": 0.045034474999994245, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_attributes_with_query_args": 0.040929758999965316, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_attributes_works_without_authparams[domain]": 0.04570956900002443, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_attributes_works_without_authparams[path]": 0.044648286000011694, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_attributes_works_without_authparams[standard]": 0.04621186999997917, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_url_work_for_different_queue[domain]": 0.05813413600000672, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_url_work_for_different_queue[path]": 0.057842270000008966, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_url_work_for_different_queue[standard]": 0.057866814000021805, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_url_works_for_same_queue[domain]": 0.04350230800002919, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_url_works_for_same_queue[path]": 0.04460174100000813, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_queue_url_works_for_same_queue[standard]": 0.044142505999985815, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_send_and_receive_messages": 0.12822937700002512, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_without_query_json_format_returns_returns_xml": 0.03138155899998196, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_get_without_query_returns_unknown_operation": 0.0343083219999869, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_invalid_action_raises_exception": 0.03460571400000845, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_overwrite_queue_url_in_params": 0.05917204200000015, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_queue_url_format_path_strategy": 0.025908199999975068, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_send_message_via_queue_url_with_json_protocol": 1.103997407000037, + "tests/aws/services/sqs/test_sqs.py::TestSqsQueryApi::test_valid_action_with_missing_parameter_raises_exception": 0.033604830000001584, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_fifo_list_messages_as_botocore_endpoint_url[json-domain]": 0.10951670999997987, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_fifo_list_messages_as_botocore_endpoint_url[json-path]": 0.1272353860000237, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_fifo_list_messages_as_botocore_endpoint_url[json-standard]": 0.10613832899997533, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_fifo_list_messages_as_botocore_endpoint_url[query-domain]": 0.1110439910000025, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_fifo_list_messages_as_botocore_endpoint_url[query-path]": 0.11137532899999769, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_fifo_list_messages_as_botocore_endpoint_url[query-standard]": 0.10868421999995803, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_as_botocore_endpoint_url[json-domain]": 0.0837565980000079, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_as_botocore_endpoint_url[json-path]": 0.08225657599999181, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_as_botocore_endpoint_url[json-standard]": 0.08808901199998331, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_as_botocore_endpoint_url[query-domain]": 0.08300406899999757, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_as_botocore_endpoint_url[query-path]": 0.08408114399998112, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_as_botocore_endpoint_url[query-standard]": 0.08645717699999977, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_as_json[domain]": 0.09809804000002487, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_as_json[path]": 0.08087274100000741, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_as_json[standard]": 0.11673480700000027, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_has_no_side_effects[domain]": 0.09980106300000102, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_has_no_side_effects[path]": 0.10594946299997332, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_has_no_side_effects[standard]": 0.10798799099995904, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_delayed_messages[domain]": 0.11273929100002533, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_delayed_messages[path]": 0.11914108000001988, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_delayed_messages[standard]": 0.11293101199999, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_invalid_action_raises_error[json-domain]": 0.044115172999994456, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_invalid_action_raises_error[json-path]": 0.04875780800000484, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_invalid_action_raises_error[json-standard]": 0.04478672900000902, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_invalid_action_raises_error[query-domain]": 0.04285599000004936, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_invalid_action_raises_error[query-path]": 0.04687190500001748, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_invalid_action_raises_error[query-standard]": 0.03823812400000293, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_invalid_queue_url[domain]": 0.020571628999988434, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_invalid_queue_url[path]": 0.0191971089999754, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_invalid_queue_url[standard]": 0.020793883000010283, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_invisible_messages[domain]": 0.1286744029999909, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_invisible_messages[path]": 0.12819378200001097, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_invisible_messages[standard]": 0.13152964500002895, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_non_existent_queue[domain]": 0.027752413999991177, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_non_existent_queue[path]": 0.026064044000037256, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_non_existent_queue[standard]": 0.02626305799998363, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_queue_url_in_path[domain]": 0.09051669600000878, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_queue_url_in_path[path]": 0.0893963829999791, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_with_queue_url_in_path[standard]": 0.08916278000003786, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_without_queue_url[domain]": 0.018991228999993837, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_without_queue_url[path]": 0.018389859999984992, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsDeveloperEndpoints::test_list_messages_without_queue_url[standard]": 0.019647375999994665, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsOverrideHeaders::test_receive_message_override_max_number_of_messages": 0.5629613920000054, + "tests/aws/services/sqs/test_sqs_backdoor.py::TestSqsOverrideHeaders::test_receive_message_override_message_wait_time_seconds": 25.258542186, + "tests/aws/services/sqs/test_sqs_move_task.py::test_basic_move_task_workflow": 1.8510754360000021, + "tests/aws/services/sqs/test_sqs_move_task.py::test_cancel_with_invalid_source_arn_in_task_handle": 0.05548406500000169, + "tests/aws/services/sqs/test_sqs_move_task.py::test_cancel_with_invalid_task_handle": 0.060641323000027114, + "tests/aws/services/sqs/test_sqs_move_task.py::test_cancel_with_invalid_task_id_in_task_handle": 0.08042634899999257, + "tests/aws/services/sqs/test_sqs_move_task.py::test_destination_needs_to_exist": 0.11274476899998831, + "tests/aws/services/sqs/test_sqs_move_task.py::test_move_task_cancel": 1.9159331529999974, + "tests/aws/services/sqs/test_sqs_move_task.py::test_move_task_delete_destination_queue_while_running": 1.968043736999988, + "tests/aws/services/sqs/test_sqs_move_task.py::test_move_task_with_throughput_limit": 3.4216306109999834, + "tests/aws/services/sqs/test_sqs_move_task.py::test_move_task_workflow_with_default_destination": 1.8407915749999972, + "tests/aws/services/sqs/test_sqs_move_task.py::test_move_task_workflow_with_multiple_sources_as_default_destination": 2.6096332850000294, + "tests/aws/services/sqs/test_sqs_move_task.py::test_source_needs_redrive_policy": 0.09884030700001745, + "tests/aws/services/sqs/test_sqs_move_task.py::test_start_multiple_move_tasks": 0.811016344000052, + "tests/aws/services/ssm/test_ssm.py::TestSSM::test_describe_parameters": 0.2452299149999817, + "tests/aws/services/ssm/test_ssm.py::TestSSM::test_get_inexistent_maintenance_window": 0.015695828999980677, + "tests/aws/services/ssm/test_ssm.py::TestSSM::test_get_inexistent_secret": 0.035305024999985335, + "tests/aws/services/ssm/test_ssm.py::TestSSM::test_get_parameter_by_arn": 0.06209988699998803, + "tests/aws/services/ssm/test_ssm.py::TestSSM::test_get_parameters_and_secrets": 0.13479947400003311, + "tests/aws/services/ssm/test_ssm.py::TestSSM::test_get_parameters_by_path_and_filter_by_labels": 0.06477308000000903, + "tests/aws/services/ssm/test_ssm.py::TestSSM::test_get_secret_parameter": 0.09132140999997773, + "tests/aws/services/ssm/test_ssm.py::TestSSM::test_hierarchical_parameter[///b//c]": 0.08439586899999085, + "tests/aws/services/ssm/test_ssm.py::TestSSM::test_hierarchical_parameter[/b/c]": 0.06267177099999799, + "tests/aws/services/ssm/test_ssm.py::TestSSM::test_parameters_with_path": 0.1649521209999989, + "tests/aws/services/ssm/test_ssm.py::TestSSM::test_put_parameters": 0.2664128090000304, + "tests/aws/services/ssm/test_ssm.py::TestSSM::test_trigger_event_on_systems_manager_change[domain]": 0.12247955999998794, + "tests/aws/services/ssm/test_ssm.py::TestSSM::test_trigger_event_on_systems_manager_change[path]": 0.12152377099999967, + "tests/aws/services/ssm/test_ssm.py::TestSSM::test_trigger_event_on_systems_manager_change[standard]": 0.1587779149999733, + "tests/aws/services/stepfunctions/v2/activities/test_activities.py::TestActivities::test_activity_task": 2.6468680769999366, + "tests/aws/services/stepfunctions/v2/activities/test_activities.py::TestActivities::test_activity_task_failure": 2.0722022299999026, + "tests/aws/services/stepfunctions/v2/activities/test_activities.py::TestActivities::test_activity_task_no_worker_name": 2.04629380800003, + "tests/aws/services/stepfunctions/v2/activities/test_activities.py::TestActivities::test_activity_task_on_deleted": 0.46814628300001004, + "tests/aws/services/stepfunctions/v2/activities/test_activities.py::TestActivities::test_activity_task_start_timeout": 5.835423596999931, + "tests/aws/services/stepfunctions/v2/activities/test_activities.py::TestActivities::test_activity_task_with_heartbeat": 6.218183746999955, + "tests/aws/services/stepfunctions/v2/arguments/test_arguments.py::TestArgumentsBase::test_base_cases[BASE_LAMBDA_EMPTY]": 17.18564925200002, + "tests/aws/services/stepfunctions/v2/arguments/test_arguments.py::TestArgumentsBase::test_base_cases[BASE_LAMBDA_EMPTY_GLOBAL_QL_JSONATA]": 2.6141508000000613, + "tests/aws/services/stepfunctions/v2/arguments/test_arguments.py::TestArgumentsBase::test_base_cases[BASE_LAMBDA_EXPRESSION]": 7.966713929999969, + "tests/aws/services/stepfunctions/v2/arguments/test_arguments.py::TestArgumentsBase::test_base_cases[BASE_LAMBDA_LITERALS]": 2.456878341999925, + "tests/aws/services/stepfunctions/v2/assign/test_assign_base.py::TestAssignBase::test_assign_in_choice[CONDITION_FALSE]": 0.953702754999938, + "tests/aws/services/stepfunctions/v2/assign/test_assign_base.py::TestAssignBase::test_assign_in_choice[CONDITION_TRUE]": 1.002448725000022, + "tests/aws/services/stepfunctions/v2/assign/test_assign_base.py::TestAssignBase::test_base_cases[BASE_CONSTANT_LITERALS]": 1.2157912279999437, + "tests/aws/services/stepfunctions/v2/assign/test_assign_base.py::TestAssignBase::test_base_cases[BASE_EMPTY]": 0.7348588980000272, + "tests/aws/services/stepfunctions/v2/assign/test_assign_base.py::TestAssignBase::test_base_cases[BASE_PATHS]": 1.0805708579999873, + "tests/aws/services/stepfunctions/v2/assign/test_assign_base.py::TestAssignBase::test_base_cases[BASE_SCOPE_MAP]": 1.1049659430000247, + "tests/aws/services/stepfunctions/v2/assign/test_assign_base.py::TestAssignBase::test_base_cases[BASE_VAR]": 1.366381577000027, + "tests/aws/services/stepfunctions/v2/assign/test_assign_base.py::TestAssignBase::test_base_parallel_cases[BASE_SCOPE_PARALLEL]": 1.157553341000039, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_assign_from_value[BASE_ASSIGN_FROM_INTRINSIC_FUNCTION]": 1.9939067390000105, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_assign_from_value[BASE_ASSIGN_FROM_PARAMETERS]": 1.033818229000019, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_assign_from_value[BASE_ASSIGN_FROM_RESULT]": 0.9953386999999339, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_assign_in_catch_state": 2.4387074709999865, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_assign_in_choice_state[CORRECT]": 1.0376448730000902, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_assign_in_choice_state[INCORRECT]": 1.0350296889999981, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_assign_in_wait_state": 0.7139574119999565, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_assign[BASE_REFERENCE_IN_CHOICE]": 1.0663373450000222, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_assign[BASE_REFERENCE_IN_FAIL]": 0.9738616710000656, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_assign[BASE_REFERENCE_IN_INPUTPATH]": 0.9926959709999892, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_assign[BASE_REFERENCE_IN_INTRINSIC_FUNCTION]": 1.2697863589999656, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_assign[BASE_REFERENCE_IN_ITERATOR_OUTER_SCOPE]": 2.0867837130000453, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_assign[BASE_REFERENCE_IN_OUTPUTPATH]": 1.0024980250000226, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_assign[BASE_REFERENCE_IN_PARAMETERS]": 0.9809750169999916, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_assign[BASE_REFERENCE_IN_WAIT]": 1.004300561999969, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_in_map_state[MAP_STATE_REFERENCE_IN_INTRINSIC_FUNCTION]": 1.3208210030000487, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_in_map_state[MAP_STATE_REFERENCE_IN_ITEMS_PATH]": 1.531188287999953, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_in_map_state[MAP_STATE_REFERENCE_IN_ITEM_SELECTOR]": 1.1116830860000846, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_in_map_state[MAP_STATE_REFERENCE_IN_MAX_CONCURRENCY_PATH]": 1.0145393009999566, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_in_map_state[MAP_STATE_REFERENCE_IN_TOLERATED_FAILURE_PATH]": 2.3072060880000436, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_in_map_state_max_items_path[MAP_STATE_REFERENCE_IN_MAX_ITEMS_PATH]": 1.2149167840000246, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_reference_in_map_state_max_items_path[MAP_STATE_REFERENCE_IN_MAX_PER_BATCH_PATH]": 0.002302186999997957, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_state_assign_evaluation_order[BASE_EVALUATION_ORDER_PASS_STATE]": 0.002016128999969169, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_undefined_reference[BASE_UNDEFINED_ARGUMENTS]": 0.0026173409999614705, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_undefined_reference[BASE_UNDEFINED_ARGUMENTS_FIELD]": 0.0019974129999695833, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_undefined_reference[BASE_UNDEFINED_ASSIGN]": 1.3040889349999247, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_undefined_reference[BASE_UNDEFINED_OUTPUT]": 2.52030210800001, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_undefined_reference[BASE_UNDEFINED_OUTPUT_FIELD]": 1.2516008320000083, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_undefined_reference[BASE_UNDEFINED_OUTPUT_MULTIPLE_STATES]": 1.3128543590000277, + "tests/aws/services/stepfunctions/v2/assign/test_assign_reference_variables.py::TestAssignReferenceVariables::test_variables_in_lambda_task[BASE_ASSIGN_FROM_LAMBDA_TASK_RESULT]": 2.7624432160000083, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_decl_version_1_0": 0.5087481909999951, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_event_bridge_events_base": 2.630798898999956, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_event_bridge_events_failure": 0.0021281700000486126, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_execution_dateformat": 0.4428444049999598, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_access[$.items[0]]": 0.7271945620000224, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_access[$.items[10]]": 0.7439916730000391, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_wildcard_or_slice_with_no_input[$.item.items[*]]": 0.7164900889999899, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_wildcard_or_slice_with_no_input[$.item.items[1:5].itemValue]": 0.7427737239999601, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_wildcard_or_slice_with_no_input[$.item.items[1:5]]": 0.7479130970000369, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_wildcard_or_slice_with_no_input[$.item.items[1:]]": 0.7282706629999893, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_wildcard_or_slice_with_no_input[$.item.items[:1]]": 0.7259133239999755, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_wildcard_or_slice_with_no_input[$.items[*].itemValue]": 0.7389544140000339, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_wildcard_or_slice_with_no_input[$.items[*]]": 0.7040124970000079, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_wildcard_or_slice_with_no_input[$.items[1:].itemValue]": 0.7391831789999515, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_wildcard_or_slice_with_no_input[$.items[1:]]": 0.6916590299999257, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_wildcard_or_slice_with_no_input[$.items[:1].itemValue]": 1.9595333940000614, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_wildcard_or_slice_with_no_input[$.items[:1]]": 0.700021027000048, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_json_path_array_wildcard_or_slice_with_no_input[$[*]]": 0.715331691000074, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_query_context_object_values": 1.6580525210000019, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_state_fail": 0.6504615760000547, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_state_fail_empty": 0.6423733729999981, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_state_fail_intrinsic": 0.7423112840000385, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_state_fail_path": 0.7168345160000058, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_state_pass_regex_json_path": 0.002117578000024878, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_state_pass_regex_json_path_base": 0.7916825510000649, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_state_pass_result": 0.6892495700000154, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_state_pass_result_jsonpaths": 0.4842035199999941, + "tests/aws/services/stepfunctions/v2/base/test_base.py::TestSnfBase::test_state_pass_result_null_input_output_paths": 0.7649750819999781, + "tests/aws/services/stepfunctions/v2/base/test_wait.py::TestSfnWait::test_base_wait_seconds_path[-1.5]": 0.7160375360000444, + "tests/aws/services/stepfunctions/v2/base/test_wait.py::TestSfnWait::test_base_wait_seconds_path[-1]": 0.739571647000048, + "tests/aws/services/stepfunctions/v2/base/test_wait.py::TestSfnWait::test_base_wait_seconds_path[0]": 0.6953606970000124, + "tests/aws/services/stepfunctions/v2/base/test_wait.py::TestSfnWait::test_base_wait_seconds_path[1.5]": 0.7086296769999763, + "tests/aws/services/stepfunctions/v2/base/test_wait.py::TestSfnWait::test_base_wait_seconds_path[1]": 1.5366633839999508, + "tests/aws/services/stepfunctions/v2/base/test_wait.py::TestSfnWait::test_timestamp_too_far_in_future_boundary[24855]": 0.002780888999950548, + "tests/aws/services/stepfunctions/v2/base/test_wait.py::TestSfnWait::test_timestamp_too_far_in_future_boundary[24856]": 0.0021455530000480394, + "tests/aws/services/stepfunctions/v2/base/test_wait.py::TestSfnWait::test_wait_timestamppath[.000000Z]": 0.7323164420000694, + "tests/aws/services/stepfunctions/v2/base/test_wait.py::TestSfnWait::test_wait_timestamppath[.000000]": 0.686886258999948, + "tests/aws/services/stepfunctions/v2/base/test_wait.py::TestSfnWait::test_wait_timestamppath[.00Z]": 0.7282812130000593, + "tests/aws/services/stepfunctions/v2/base/test_wait.py::TestSfnWait::test_wait_timestamppath[Z]": 0.7169662439999911, + "tests/aws/services/stepfunctions/v2/base/test_wait.py::TestSfnWait::test_wait_timestamppath[]": 0.7098722299999736, + "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_multiple_executions_and_heartbeat_notifications": 0.002727466999999706, + "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_multiple_heartbeat_notifications": 0.0039657310000507096, + "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_sns_publish_wait_for_task_token": 1.5483456860000047, + "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_sqs_failure_in_wait_for_task_tok_no_error_field[SQS_PARALLEL_WAIT_FOR_TASK_TOKEN]": 0.010894508999967911, + "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_sqs_failure_in_wait_for_task_tok_no_error_field[SQS_WAIT_FOR_TASK_TOKEN_CATCH]": 1.7842332189999865, + "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_sqs_failure_in_wait_for_task_token": 2.536810727000102, + "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_sqs_wait_for_task_tok_with_heartbeat": 7.72896494500003, + "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_sqs_wait_for_task_token": 2.6513739389999955, + "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_sqs_wait_for_task_token_call_chain": 4.472971474000019, + "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_sqs_wait_for_task_token_no_token_parameter": 5.883572742000013, + "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_sqs_wait_for_task_token_timeout": 5.9160674149999295, + "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_start_execution_sync": 2.6588442900000473, + "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_start_execution_sync2": 1.3417085840000027, + "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_start_execution_sync_delegate_failure": 1.1402177399999687, + "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_start_execution_sync_delegate_timeout": 7.6643816239999865, + "tests/aws/services/stepfunctions/v2/callback/test_callback.py::TestCallback::test_sync_with_task_token": 3.0907435430000305, + "tests/aws/services/stepfunctions/v2/choice_operators/test_boolean_equals.py::TestBooleanEquals::test_boolean_equals": 15.846918172000073, + "tests/aws/services/stepfunctions/v2/choice_operators/test_boolean_equals.py::TestBooleanEquals::test_boolean_equals_path": 14.974674809000021, + "tests/aws/services/stepfunctions/v2/choice_operators/test_is_operators.py::TestIsOperators::test_is_boolean": 16.095281735000015, + "tests/aws/services/stepfunctions/v2/choice_operators/test_is_operators.py::TestIsOperators::test_is_null": 15.038386489999994, + "tests/aws/services/stepfunctions/v2/choice_operators/test_is_operators.py::TestIsOperators::test_is_numeric": 15.04133874200005, + "tests/aws/services/stepfunctions/v2/choice_operators/test_is_operators.py::TestIsOperators::test_is_present": 16.239720643000055, + "tests/aws/services/stepfunctions/v2/choice_operators/test_is_operators.py::TestIsOperators::test_is_string": 14.803534107000132, + "tests/aws/services/stepfunctions/v2/choice_operators/test_is_operators.py::TestIsOperators::test_is_timestamp": 0.005447792000040863, + "tests/aws/services/stepfunctions/v2/choice_operators/test_numeric.py::TestNumerics::test_numeric_equals": 22.184041339999908, + "tests/aws/services/stepfunctions/v2/choice_operators/test_numeric.py::TestNumerics::test_numeric_equals_path": 24.017214479999893, + "tests/aws/services/stepfunctions/v2/choice_operators/test_numeric.py::TestNumerics::test_numeric_greater_than": 2.7421404699998675, + "tests/aws/services/stepfunctions/v2/choice_operators/test_numeric.py::TestNumerics::test_numeric_greater_than_equals": 2.7886374400000022, + "tests/aws/services/stepfunctions/v2/choice_operators/test_numeric.py::TestNumerics::test_numeric_greater_than_equals_path": 4.032605022999974, + "tests/aws/services/stepfunctions/v2/choice_operators/test_numeric.py::TestNumerics::test_numeric_greater_than_path": 2.7581377210000255, + "tests/aws/services/stepfunctions/v2/choice_operators/test_numeric.py::TestNumerics::test_numeric_less_than": 2.6841509719999976, + "tests/aws/services/stepfunctions/v2/choice_operators/test_numeric.py::TestNumerics::test_numeric_less_than_equals": 2.799307504000012, + "tests/aws/services/stepfunctions/v2/choice_operators/test_numeric.py::TestNumerics::test_numeric_less_than_equals_path": 2.743925904999969, + "tests/aws/services/stepfunctions/v2/choice_operators/test_numeric.py::TestNumerics::test_numeric_less_than_path": 2.702059590999852, + "tests/aws/services/stepfunctions/v2/choice_operators/test_string_operators.py::TestStrings::test_string_equals": 6.677434035000033, + "tests/aws/services/stepfunctions/v2/choice_operators/test_string_operators.py::TestStrings::test_string_equals_path": 1.6079736180000737, + "tests/aws/services/stepfunctions/v2/choice_operators/test_string_operators.py::TestStrings::test_string_greater_than": 1.9189063479999504, + "tests/aws/services/stepfunctions/v2/choice_operators/test_string_operators.py::TestStrings::test_string_greater_than_equals": 1.542404134000094, + "tests/aws/services/stepfunctions/v2/choice_operators/test_string_operators.py::TestStrings::test_string_greater_than_equals_path": 1.5583886400000893, + "tests/aws/services/stepfunctions/v2/choice_operators/test_string_operators.py::TestStrings::test_string_greater_than_path": 1.898680160999902, + "tests/aws/services/stepfunctions/v2/choice_operators/test_string_operators.py::TestStrings::test_string_less_than": 1.5548422869999285, + "tests/aws/services/stepfunctions/v2/choice_operators/test_string_operators.py::TestStrings::test_string_less_than_equals": 1.605492229000106, + "tests/aws/services/stepfunctions/v2/choice_operators/test_string_operators.py::TestStrings::test_string_less_than_equals_path": 2.9371328470000435, + "tests/aws/services/stepfunctions/v2/choice_operators/test_string_operators.py::TestStrings::test_string_less_than_path": 1.6098080020000225, + "tests/aws/services/stepfunctions/v2/choice_operators/test_timestamp_operators.py::TestTimestamps::test_timestamp_equals": 7.018717414999969, + "tests/aws/services/stepfunctions/v2/choice_operators/test_timestamp_operators.py::TestTimestamps::test_timestamp_equals_path": 1.5072069190001685, + "tests/aws/services/stepfunctions/v2/choice_operators/test_timestamp_operators.py::TestTimestamps::test_timestamp_greater_than": 1.5039958290000186, + "tests/aws/services/stepfunctions/v2/choice_operators/test_timestamp_operators.py::TestTimestamps::test_timestamp_greater_than_equals": 1.6013476319999427, + "tests/aws/services/stepfunctions/v2/choice_operators/test_timestamp_operators.py::TestTimestamps::test_timestamp_greater_than_equals_path": 0.7708720099999482, + "tests/aws/services/stepfunctions/v2/choice_operators/test_timestamp_operators.py::TestTimestamps::test_timestamp_greater_than_path": 0.748695057999953, + "tests/aws/services/stepfunctions/v2/choice_operators/test_timestamp_operators.py::TestTimestamps::test_timestamp_less_than": 1.5125615270000026, + "tests/aws/services/stepfunctions/v2/choice_operators/test_timestamp_operators.py::TestTimestamps::test_timestamp_less_than_equals": 1.5489640480001299, + "tests/aws/services/stepfunctions/v2/choice_operators/test_timestamp_operators.py::TestTimestamps::test_timestamp_less_than_equals_path": 0.7481980809999413, + "tests/aws/services/stepfunctions/v2/choice_operators/test_timestamp_operators.py::TestTimestamps::test_timestamp_less_than_path": 0.7355139430001145, + "tests/aws/services/stepfunctions/v2/comments/test_comments.py::TestComments::test_comment_in_parameters": 0.7256410700000515, + "tests/aws/services/stepfunctions/v2/comments/test_comments.py::TestComments::test_comments_as_per_docs": 7.748485761999859, + "tests/aws/services/stepfunctions/v2/context_object/test_context_object.py::TestSnfBase::test_error_cause_path": 2.2562792110001055, + "tests/aws/services/stepfunctions/v2/context_object/test_context_object.py::TestSnfBase::test_input_path[$$.Execution.Input]": 1.0313531969999303, + "tests/aws/services/stepfunctions/v2/context_object/test_context_object.py::TestSnfBase::test_input_path[$$]": 0.8614934690000382, + "tests/aws/services/stepfunctions/v2/context_object/test_context_object.py::TestSnfBase::test_output_path[$$.Execution.Input]": 1.0622476749999805, + "tests/aws/services/stepfunctions/v2/context_object/test_context_object.py::TestSnfBase::test_output_path[$$]": 1.0705827399999635, + "tests/aws/services/stepfunctions/v2/context_object/test_context_object.py::TestSnfBase::test_result_selector": 2.790298899999925, + "tests/aws/services/stepfunctions/v2/context_object/test_context_object.py::TestSnfBase::test_variable": 1.1197022950000246, + "tests/aws/services/stepfunctions/v2/credentials/test_credentials_base.py::TestCredentialsBase::test_cross_account_lambda_task": 2.7576050479999594, + "tests/aws/services/stepfunctions/v2/credentials/test_credentials_base.py::TestCredentialsBase::test_cross_account_service_lambda_invoke": 2.627567286000044, + "tests/aws/services/stepfunctions/v2/credentials/test_credentials_base.py::TestCredentialsBase::test_cross_account_service_lambda_invoke_retry": 6.044840451999903, + "tests/aws/services/stepfunctions/v2/credentials/test_credentials_base.py::TestCredentialsBase::test_cross_account_states_start_sync_execution[SFN_START_EXECUTION_SYNC_ROLE_ARN_INTRINSIC]": 1.6842371480000793, + "tests/aws/services/stepfunctions/v2/credentials/test_credentials_base.py::TestCredentialsBase::test_cross_account_states_start_sync_execution[SFN_START_EXECUTION_SYNC_ROLE_ARN_JSONATA]": 1.4359353370000463, + "tests/aws/services/stepfunctions/v2/credentials/test_credentials_base.py::TestCredentialsBase::test_cross_account_states_start_sync_execution[SFN_START_EXECUTION_SYNC_ROLE_ARN_PATH]": 1.6417182230001117, + "tests/aws/services/stepfunctions/v2/credentials/test_credentials_base.py::TestCredentialsBase::test_cross_account_states_start_sync_execution[SFN_START_EXECUTION_SYNC_ROLE_ARN_PATH_CONTEXT]": 1.703145993000021, + "tests/aws/services/stepfunctions/v2/credentials/test_credentials_base.py::TestCredentialsBase::test_cross_account_states_start_sync_execution[SFN_START_EXECUTION_SYNC_ROLE_ARN_VARIABLE]": 1.6505515750001223, + "tests/aws/services/stepfunctions/v2/credentials/test_credentials_base.py::TestCredentialsBase::test_invalid_credentials_field[EMPTY_CREDENTIALS]": 0.9801361610000185, + "tests/aws/services/stepfunctions/v2/credentials/test_credentials_base.py::TestCredentialsBase::test_invalid_credentials_field[INVALID_CREDENTIALS_FIELD]": 0.9638266140000269, + "tests/aws/services/stepfunctions/v2/error_handling/test_aws_sdk.py::TestAwsSdk::test_dynamodb_invalid_param": 0.002222705000008318, + "tests/aws/services/stepfunctions/v2/error_handling/test_aws_sdk.py::TestAwsSdk::test_dynamodb_put_item_no_such_table": 4.715305069999886, + "tests/aws/services/stepfunctions/v2/error_handling/test_aws_sdk.py::TestAwsSdk::test_invalid_secret_name": 0.8631910609999522, + "tests/aws/services/stepfunctions/v2/error_handling/test_aws_sdk.py::TestAwsSdk::test_no_such_bucket": 0.7910341309999467, + "tests/aws/services/stepfunctions/v2/error_handling/test_aws_sdk.py::TestAwsSdk::test_s3_no_such_key": 0.840325281000105, + "tests/aws/services/stepfunctions/v2/error_handling/test_states_errors.py::TestStatesErrors::test_service_task_lambada_catch_state_all_data_limit_exceeded_on_large_utf8_response": 2.3912948729999925, + "tests/aws/services/stepfunctions/v2/error_handling/test_states_errors.py::TestStatesErrors::test_service_task_lambada_data_limit_exceeded_on_large_utf8_response": 2.4105566929999895, + "tests/aws/services/stepfunctions/v2/error_handling/test_states_errors.py::TestStatesErrors::test_start_large_input": 5.157440620000102, + "tests/aws/services/stepfunctions/v2/error_handling/test_states_errors.py::TestStatesErrors::test_task_lambda_catch_state_all_data_limit_exceeded_on_large_utf8_response": 2.3559214810001095, + "tests/aws/services/stepfunctions/v2/error_handling/test_states_errors.py::TestStatesErrors::test_task_lambda_data_limit_exceeded_on_large_utf8_response": 2.386207044000116, + "tests/aws/services/stepfunctions/v2/error_handling/test_task_lambda.py::TestTaskLambda::test_no_such_function": 2.468006292000041, + "tests/aws/services/stepfunctions/v2/error_handling/test_task_lambda.py::TestTaskLambda::test_no_such_function_catch": 2.4980727700000216, + "tests/aws/services/stepfunctions/v2/error_handling/test_task_lambda.py::TestTaskLambda::test_raise_custom_exception": 2.3178665099999307, + "tests/aws/services/stepfunctions/v2/error_handling/test_task_lambda.py::TestTaskLambda::test_raise_exception": 2.584179094000092, + "tests/aws/services/stepfunctions/v2/error_handling/test_task_lambda.py::TestTaskLambda::test_raise_exception_catch": 2.5817392300000392, + "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_dynamodb.py::TestTaskServiceDynamoDB::test_invalid_param": 0.8109449570000606, + "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_dynamodb.py::TestTaskServiceDynamoDB::test_put_item_invalid_table_name": 0.892199628999947, + "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_dynamodb.py::TestTaskServiceDynamoDB::test_put_item_no_such_table": 0.829600490999951, + "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_lambda.py::TestTaskServiceLambda::test_invoke_timeout": 6.968898233999994, + "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_lambda.py::TestTaskServiceLambda::test_no_such_function": 1.920788107999897, + "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_lambda.py::TestTaskServiceLambda::test_no_such_function_catch": 1.9480873659999816, + "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_lambda.py::TestTaskServiceLambda::test_raise_custom_exception": 2.4553305389999878, + "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_lambda.py::TestTaskServiceLambda::test_raise_exception": 2.437849024000002, + "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_lambda.py::TestTaskServiceLambda::test_raise_exception_catch": 2.543665979000025, + "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_lambda.py::TestTaskServiceLambda::test_raise_exception_catch_output_path[$.Payload]": 3.784682021000094, + "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_lambda.py::TestTaskServiceLambda::test_raise_exception_catch_output_path[$.no.such.path]": 2.420316664999973, + "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_lambda.py::TestTaskServiceLambda::test_raise_exception_catch_output_path[None]": 2.39413597500004, + "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_sfn.py::TestTaskServiceSfn::test_start_execution_no_such_arn": 1.197575395000058, + "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_sqs.py::TestTaskServiceSqs::test_send_message_empty_body": 0.002068366000116839, + "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_sqs.py::TestTaskServiceSqs::test_send_message_no_such_queue": 1.209459260000017, + "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_sqs.py::TestTaskServiceSqs::test_send_message_no_such_queue_no_catch": 1.0874312669999426, + "tests/aws/services/stepfunctions/v2/error_handling/test_task_service_sqs.py::TestTaskServiceSqs::test_sqs_failure_in_wait_for_task_tok": 2.8091973280000957, + "tests/aws/services/stepfunctions/v2/evaluate_jsonata/test_base_evaluate_expressions.py::TestBaseEvaluateJsonata::test_base_map[ITEMS]": 1.225468884999941, + "tests/aws/services/stepfunctions/v2/evaluate_jsonata/test_base_evaluate_expressions.py::TestBaseEvaluateJsonata::test_base_map[ITEMS_DOUBLE_QUOTES]": 1.4778626549999672, + "tests/aws/services/stepfunctions/v2/evaluate_jsonata/test_base_evaluate_expressions.py::TestBaseEvaluateJsonata::test_base_map[MAX_CONCURRENCY]": 1.1910937510000394, + "tests/aws/services/stepfunctions/v2/evaluate_jsonata/test_base_evaluate_expressions.py::TestBaseEvaluateJsonata::test_base_map[TOLERATED_FAILURE_COUNT]": 1.144240726999783, + "tests/aws/services/stepfunctions/v2/evaluate_jsonata/test_base_evaluate_expressions.py::TestBaseEvaluateJsonata::test_base_map[TOLERATED_FAILURE_PERCENTAGE]": 1.1564732109998204, + "tests/aws/services/stepfunctions/v2/evaluate_jsonata/test_base_evaluate_expressions.py::TestBaseEvaluateJsonata::test_base_map_from_input[ITEMS]": 2.4088412050000443, + "tests/aws/services/stepfunctions/v2/evaluate_jsonata/test_base_evaluate_expressions.py::TestBaseEvaluateJsonata::test_base_map_from_input[MAX_CONCURRENCY]": 3.7634989750000614, + "tests/aws/services/stepfunctions/v2/evaluate_jsonata/test_base_evaluate_expressions.py::TestBaseEvaluateJsonata::test_base_map_from_input[TOLERATED_FAILURE_COUNT]": 2.2937591659999725, + "tests/aws/services/stepfunctions/v2/evaluate_jsonata/test_base_evaluate_expressions.py::TestBaseEvaluateJsonata::test_base_map_from_input[TOLERATED_FAILURE_PERCENTAGE]": 2.312570740999945, + "tests/aws/services/stepfunctions/v2/evaluate_jsonata/test_base_evaluate_expressions.py::TestBaseEvaluateJsonata::test_base_task[HEARTBEAT_SECONDS]": 2.6375069479998956, + "tests/aws/services/stepfunctions/v2/evaluate_jsonata/test_base_evaluate_expressions.py::TestBaseEvaluateJsonata::test_base_task[TIMEOUT_SECONDS]": 0.002733708000050683, + "tests/aws/services/stepfunctions/v2/evaluate_jsonata/test_base_evaluate_expressions.py::TestBaseEvaluateJsonata::test_base_task_from_input[HEARTBEAT_SECONDS]": 2.63042142300003, + "tests/aws/services/stepfunctions/v2/evaluate_jsonata/test_base_evaluate_expressions.py::TestBaseEvaluateJsonata::test_base_task_from_input[TIMEOUT_SECONDS]": 0.0021967669998730344, + "tests/aws/services/stepfunctions/v2/express/test_express_async.py::TestExpressAsync::test_base[BASE_PASS_RESULT]": 1.334662577000131, + "tests/aws/services/stepfunctions/v2/express/test_express_async.py::TestExpressAsync::test_base[BASE_RAISE_FAILURE]": 1.3241981579999447, + "tests/aws/services/stepfunctions/v2/express/test_express_async.py::TestExpressAsync::test_catch": 3.036316450000072, + "tests/aws/services/stepfunctions/v2/express/test_express_async.py::TestExpressAsync::test_query_runtime_memory": 2.2806618039999194, + "tests/aws/services/stepfunctions/v2/express/test_express_async.py::TestExpressAsync::test_retry": 10.417790123999907, + "tests/aws/services/stepfunctions/v2/express/test_express_sync.py::TestExpressSync::test_base[BASE_PASS_RESULT]": 0.6737322349999886, + "tests/aws/services/stepfunctions/v2/express/test_express_sync.py::TestExpressSync::test_base[BASE_RAISE_FAILURE]": 0.638991962000091, + "tests/aws/services/stepfunctions/v2/express/test_express_sync.py::TestExpressSync::test_catch": 2.5220389229999682, + "tests/aws/services/stepfunctions/v2/express/test_express_sync.py::TestExpressSync::test_query_runtime_memory": 1.6320290020000812, + "tests/aws/services/stepfunctions/v2/express/test_express_sync.py::TestExpressSync::test_retry": 9.805808871999943, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_array.py::TestArray::test_array_0": 0.5079719430000296, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_array.py::TestArray::test_array_2": 3.159307252000076, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_array.py::TestArray::test_array_contains": 3.300473279000016, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_array.py::TestArray::test_array_get_item": 0.7493113799999946, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_array.py::TestArray::test_array_length": 0.7461314199999833, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_array.py::TestArray::test_array_partition": 10.501872002000141, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_array.py::TestArray::test_array_range": 1.7604212750001125, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_array.py::TestArray::test_array_unique": 0.7617449509999688, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_array_jsonata.py::TestArrayJSONata::test_array_partition": 6.739056477999952, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_array_jsonata.py::TestArrayJSONata::test_array_range": 1.3395756060000394, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_encode_decode.py::TestEncodeDecode::test_base_64_decode": 0.9868791799999599, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_encode_decode.py::TestEncodeDecode::test_base_64_encode": 1.0386258129999533, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_generic.py::TestGeneric::test_context_json_path": 0.7202553570000418, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_generic.py::TestGeneric::test_escape_sequence": 0.4782145619999483, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_generic.py::TestGeneric::test_format_1": 2.5753994650000323, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_generic.py::TestGeneric::test_format_2": 2.8983637240000917, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_generic.py::TestGeneric::test_nested_calls_1": 0.7193440190000047, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_generic.py::TestGeneric::test_nested_calls_2": 0.7375795820000803, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_hash_calculations.py::TestHashCalculations::test_hash": 1.984172871000169, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_json_manipulation.py::TestJsonManipulation::test_json_merge": 0.7244290870000896, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_json_manipulation.py::TestJsonManipulation::test_json_merge_escaped_argument": 0.7826377229998798, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_json_manipulation.py::TestJsonManipulation::test_json_to_string": 2.9310856470000317, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_json_manipulation.py::TestJsonManipulation::test_string_to_json": 3.6611377259999927, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_json_manipulation_jsonata.py::TestJsonManipulationJSONata::test_parse": 2.4842477889999373, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_math_operations.py::TestMathOperations::test_math_add": 7.240648730000089, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_math_operations.py::TestMathOperations::test_math_random": 1.4219515620000038, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_math_operations.py::TestMathOperations::test_math_random_seeded": 0.8116612999999688, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_math_operations_jsonata.py::TestMathOperationsJSONata::test_math_random_seeded": 0.00286491599990768, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_string_operations.py::TestStringOperations::test_string_split": 2.7313754380001, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_string_operations.py::TestStringOperations::test_string_split_context_object": 0.6855210139999599, + "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_unique_id_generation.py::TestUniqueIdGeneration::test_uuid": 0.5181886340000119, + "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_base[pass_result.json5_ALL_False]": 1.1127914020000844, + "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_base[pass_result.json5_ALL_True]": 2.8951463399999966, + "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_base[raise_failure.json5_ALL_False]": 1.0663462299999082, + "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_base[raise_failure.json5_ALL_True]": 1.0814265649999015, + "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_base[wait_seconds_path.json5_ALL_False]": 1.07937698000012, + "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_base[wait_seconds_path.json5_ALL_True]": 1.0757000709999147, + "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_deleted_log_group": 1.0739739250000184, + "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_log_group_with_multiple_runs": 1.685184078000134, + "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[pass_result.json5_ERROR_False]": 0.7853045089999569, + "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[pass_result.json5_ERROR_True]": 0.7967605300000287, + "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[pass_result.json5_FATAL_False]": 0.8041271720001077, + "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[pass_result.json5_FATAL_True]": 1.0607689150000397, + "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[pass_result.json5_OFF_False]": 0.767912344000024, + "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[pass_result.json5_OFF_True]": 0.98543438899992, + "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[raise_failure.json5_ERROR_False]": 1.0844556729999795, + "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[raise_failure.json5_ERROR_True]": 1.0792185480000853, + "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[raise_failure.json5_FATAL_False]": 0.8650860349998766, + "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[raise_failure.json5_FATAL_True]": 0.8611919570000737, + "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[raise_failure.json5_OFF_False]": 0.766594519000023, + "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[raise_failure.json5_OFF_True]": 0.7594096909999735, + "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[wait_seconds_path.json5_ERROR_False]": 1.0698227960000395, + "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[wait_seconds_path.json5_ERROR_True]": 1.1096793740000521, + "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[wait_seconds_path.json5_FATAL_False]": 1.0847033229999852, + "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[wait_seconds_path.json5_FATAL_True]": 1.088042797000071, + "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[wait_seconds_path.json5_OFF_False]": 0.9888181590000613, + "tests/aws/services/stepfunctions/v2/logs/test_logs.py::TestLogs::test_partial_log_levels[wait_seconds_path.json5_OFF_True]": 1.0058326360001502, + "tests/aws/services/stepfunctions/v2/mocking/test_aws_scenarios.py::TestBaseScenarios::test_lambda_sqs_integration_happy_path": 0.43864115200005926, + "tests/aws/services/stepfunctions/v2/mocking/test_aws_scenarios.py::TestBaseScenarios::test_lambda_sqs_integration_hybrid_path": 0.3900331440000855, + "tests/aws/services/stepfunctions/v2/mocking/test_aws_scenarios.py::TestBaseScenarios::test_lambda_sqs_integration_retry_path": 8.983300909000036, + "tests/aws/services/stepfunctions/v2/mocking/test_base_callbacks.py::TestBaseScenarios::test_sfn_start_execution_sync[SFN_SYNC2]": 1.768031856999869, + "tests/aws/services/stepfunctions/v2/mocking/test_base_callbacks.py::TestBaseScenarios::test_sfn_start_execution_sync[SFN_SYNC]": 1.7676508260000219, + "tests/aws/services/stepfunctions/v2/mocking/test_base_callbacks.py::TestBaseScenarios::test_sqs_wait_for_task_token": 1.756386865999957, + "tests/aws/services/stepfunctions/v2/mocking/test_base_callbacks.py::TestBaseScenarios::test_sqs_wait_for_task_token_task_failure": 1.8050069549999535, + "tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py::TestBaseScenarios::test_dynamodb_put_get_item": 1.0780657450000035, + "tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py::TestBaseScenarios::test_events_put_events": 1.0094046819999676, + "tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py::TestBaseScenarios::test_lambda_invoke": 0.9787905610000962, + "tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py::TestBaseScenarios::test_lambda_invoke_retries": 3.4438581089999616, + "tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py::TestBaseScenarios::test_lambda_service_invoke": 0.9992437020001717, + "tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py::TestBaseScenarios::test_lambda_service_invoke_sync_execution": 0.8712686990000975, + "tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py::TestBaseScenarios::test_map_state_lambda": 1.5814792550000902, + "tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py::TestBaseScenarios::test_parallel_state_lambda": 1.5330481620001137, + "tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py::TestBaseScenarios::test_sns_publish_base": 1.0615017850000186, + "tests/aws/services/stepfunctions/v2/mocking/test_base_scenarios.py::TestBaseScenarios::test_sqs_send_message": 1.0381429110001363, + "tests/aws/services/stepfunctions/v2/mocking/test_mock_config_file.py::TestMockConfigFile::test_is_mock_config_flag_detected_set": 0.005158965000077842, + "tests/aws/services/stepfunctions/v2/mocking/test_mock_config_file.py::TestMockConfigFile::test_is_mock_config_flag_detected_unset": 0.007447744999922179, + "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_cases[BASE_DIRECT_EXPR]": 2.9274657249999336, + "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_cases[BASE_EMPTY]": 0.9674048870000433, + "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_cases[BASE_EXPR]": 1.044669913000007, + "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_cases[BASE_LITERALS]": 0.9156685289999587, + "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_lambda[BASE_LAMBDA]": 2.7352749789998825, + "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_output_any_non_dict[BOOL]": 0.7438920170000074, + "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_output_any_non_dict[FLOAT]": 0.7350674469998921, + "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_output_any_non_dict[INT]": 0.9491684289999966, + "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_output_any_non_dict[JSONATA_EXPR]": 0.7484403209999755, + "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_output_any_non_dict[LIST_EMPY]": 0.990145439999992, + "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_output_any_non_dict[LIST_RICH]": 0.9634200700000974, + "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_output_any_non_dict[NULL]": 0.7523092759998917, + "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_output_any_non_dict[STR_LIT]": 0.7417627539999785, + "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_base_task_lambda[BASE_TASK_LAMBDA]": 2.6299390899999935, + "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_output_in_choice[CONDITION_FALSE]": 2.281637122999996, + "tests/aws/services/stepfunctions/v2/outputdecl/test_output.py::TestArgumentsBase::test_output_in_choice[CONDITION_TRUE]": 0.9891717080000717, + "tests/aws/services/stepfunctions/v2/query_language/test_base_query_language.py::TestBaseQueryLanguage::test_base_query_language_field[JSONATA]": 0.4788989290000245, + "tests/aws/services/stepfunctions/v2/query_language/test_base_query_language.py::TestBaseQueryLanguage::test_base_query_language_field[JSON_PATH]": 0.48799675600014325, + "tests/aws/services/stepfunctions/v2/query_language/test_base_query_language.py::TestBaseQueryLanguage::test_jsonata_query_language_field_downgrade_exception": 0.0024407570000448686, + "tests/aws/services/stepfunctions/v2/query_language/test_base_query_language.py::TestBaseQueryLanguage::test_query_language_field_override[JSONATA_OVERRIDE]": 0.4875527099999317, + "tests/aws/services/stepfunctions/v2/query_language/test_base_query_language.py::TestBaseQueryLanguage::test_query_language_field_override[JSONATA_OVERRIDE_DEFAULT]": 0.4810308730000088, + "tests/aws/services/stepfunctions/v2/query_language/test_mixed_query_language.py::TestMixedQueryLanguageFlow::test_lambda_task_resource_data_flow[TASK_LAMBDA_LEGACY_RESOURCE_JSONATA_TO_JSONPATH]": 2.342050244999996, + "tests/aws/services/stepfunctions/v2/query_language/test_mixed_query_language.py::TestMixedQueryLanguageFlow::test_lambda_task_resource_data_flow[TASK_LAMBDA_LEGACY_RESOURCE_JSONPATH_TO_JSONATA]": 2.3193802639999603, + "tests/aws/services/stepfunctions/v2/query_language/test_mixed_query_language.py::TestMixedQueryLanguageFlow::test_lambda_task_resource_data_flow[TASK_LAMBDA_SDK_RESOURCE_JSONATA_TO_JSONPATH]": 2.5443997429999854, + "tests/aws/services/stepfunctions/v2/query_language/test_mixed_query_language.py::TestMixedQueryLanguageFlow::test_lambda_task_resource_data_flow[TASK_LAMBDA_SDK_RESOURCE_JSONPATH_TO_JSONATA]": 2.390960853000024, + "tests/aws/services/stepfunctions/v2/query_language/test_mixed_query_language.py::TestMixedQueryLanguageFlow::test_output_to_state[JSONATA_OUTPUT_TO_JSONPATH]": 0.9026971389999972, + "tests/aws/services/stepfunctions/v2/query_language/test_mixed_query_language.py::TestMixedQueryLanguageFlow::test_output_to_state[JSONPATH_OUTPUT_TO_JSONATA]": 0.9204034310001816, + "tests/aws/services/stepfunctions/v2/query_language/test_mixed_query_language.py::TestMixedQueryLanguageFlow::test_task_dataflow_to_state": 2.6460452239999768, + "tests/aws/services/stepfunctions/v2/query_language/test_mixed_query_language.py::TestMixedQueryLanguageFlow::test_variable_sampling[JSONATA_ASSIGN_JSONPATH_REF]": 0.8965460029999122, + "tests/aws/services/stepfunctions/v2/query_language/test_mixed_query_language.py::TestMixedQueryLanguageFlow::test_variable_sampling[JSONPATH_ASSIGN_JSONATA_REF]": 0.9012987419999945, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_catch_empty": 2.1775360010000213, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_catch_states_runtime": 2.5006335199998375, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_choice_aws_docs_scenario[CHOICE_STATE_AWS_SCENARIO]": 0.8004946060002567, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_choice_aws_docs_scenario[CHOICE_STATE_AWS_SCENARIO_JSONATA]": 0.7518846990001293, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_choice_condition_constant_jsonata": 0.5233457400001953, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_choice_singleton_composite[CHOICE_STATE_SINGLETON_COMPOSITE]": 0.8162471210000604, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_choice_singleton_composite[CHOICE_STATE_SINGLETON_COMPOSITE_JSONATA]": 0.7329932979996556, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_choice_singleton_composite[CHOICE_STATE_SINGLETON_COMPOSITE_LITERAL_JSONATA]": 0.756081815999778, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_choice_unsorted_parameters_negative[CHOICE_STATE_UNSORTED_CHOICE_PARAMETERS]": 0.7785752160000357, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_choice_unsorted_parameters_negative[CHOICE_STATE_UNSORTED_CHOICE_PARAMETERS_JSONATA]": 0.7157639669999298, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_choice_unsorted_parameters_positive[CHOICE_STATE_UNSORTED_CHOICE_PARAMETERS]": 0.9662161740000101, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_choice_unsorted_parameters_positive[CHOICE_STATE_UNSORTED_CHOICE_PARAMETERS_JSONATA]": 0.8362843029999567, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_escape_sequence_parsing[ESCAPE_SEQUENCES_JSONATA_COMPARISON_ASSIGN]": 0.7801319440000043, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_escape_sequence_parsing[ESCAPE_SEQUENCES_JSONATA_COMPARISON_OUTPUT]": 0.7641355060000024, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_escape_sequence_parsing[ESCAPE_SEQUENCES_JSONPATH]": 0.7826076439998815, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_escape_sequence_parsing[ESCAPE_SEQUENCES_STRING_LITERALS]": 0.8588197739998122, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_fail_cause_jsonata": 0.7306465480003226, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_fail_error_jsonata": 0.7178299110000808, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_illegal_escapes[ESCAPE_SEQUENCES_ILLEGAL_INTRINSIC_FUNCTION]": 0.0021616209999137936, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_illegal_escapes[ESCAPE_SEQUENCES_ILLEGAL_INTRINSIC_FUNCTION_2]": 0.0020942840001225704, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_invalid_jsonpath[INVALID_JSONPATH_IN_ERRORPATH]": 0.7465587130000131, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_invalid_jsonpath[INVALID_JSONPATH_IN_STRING_EXPR_CONTEXTPATH]": 0.8120026429999143, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_invalid_jsonpath[INVALID_JSONPATH_IN_STRING_EXPR_JSONPATH]": 0.7551344689998132, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_invalid_jsonpath[ST.INVALID_JSONPATH_IN_CAUSEPATH]": 0.7266698589999123, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_invalid_jsonpath[ST.INVALID_JSONPATH_IN_HEARTBEATSECONDSPATH]": 0.0021896949999700155, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_invalid_jsonpath[ST.INVALID_JSONPATH_IN_INPUTPATH]": 0.7040271690000282, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_invalid_jsonpath[ST.INVALID_JSONPATH_IN_OUTPUTPATH]": 0.7539091480000479, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_invalid_jsonpath[ST.INVALID_JSONPATH_IN_TIMEOUTSECONDSPATH]": 0.002242454999986876, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_lambda_empty_retry": 2.1782130730000517, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_lambda_invoke_with_retry_base": 9.652626562999785, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_lambda_invoke_with_retry_extended_input": 9.849057039999934, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_lambda_service_invoke_with_retry_extended_input": 10.217782993000128, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_batching_base_json_max_per_batch_jsonata": 0.0022114339999461663, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_base_csv_headers_decl": 1.0671934300000885, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_base_csv_headers_first_line": 0.8628306489999886, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_base_json": 0.8515386200001558, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_base_json_max_items": 0.8543217820001701, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_base_json_max_items_jsonata": 0.9591915699995752, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_base_json_with_items_path[INVALID_ITEMS_PATH]": 0.9891026030002195, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_base_json_with_items_path[VALID_ITEMS_PATH_FROM_ITEM_READER]": 1.1886151210001117, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_base_json_with_items_path[VALID_ITEMS_PATH_FROM_PREVIOUS]": 1.1851382219999778, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_base_list_objects_v2": 0.8672432500000014, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_csv_first_row_extra_fields": 0.8152638670001124, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_csv_headers_decl_duplicate_headers": 1.9677284259998942, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_csv_headers_decl_extra_fields": 0.8404513059999772, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_csv_headers_first_row_typed_headers": 0.8298477370001365, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_csv_max_items[0]": 0.8346996180000588, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_csv_max_items[100000000]": 0.8271257040003093, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_csv_max_items[2]": 0.7942197710001437, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_csv_max_items_paths[-1]": 0.8328968329999498, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_csv_max_items_paths[0]": 0.848359524999978, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_csv_max_items_paths[1.5]": 0.02554877800025679, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_csv_max_items_paths[100000000]": 0.8375675219999721, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_csv_max_items_paths[100000001]": 0.8815883230001873, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_csv_max_items_paths[2]": 0.820450443000027, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_item_reader_json_no_json_list_object": 0.8330129369999213, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state": 1.967243761000077, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_break_condition": 0.9250865950000389, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_break_condition_legacy": 0.9253196150000349, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_catch": 0.8339824470003805, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_catch_empty_fail": 0.8971340200000668, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_catch_legacy": 0.8603428150001946, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_config_distributed_item_selector": 0.8359386149999182, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_config_distributed_item_selector_parameters": 1.1150575349998917, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_config_distributed_items_path_from_previous": 0.856776844000251, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_config_distributed_parameters": 0.8745964790000471, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_config_distributed_reentrant": 1.6789305919999151, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_config_distributed_reentrant_lambda": 2.940705495999964, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_config_inline_item_selector": 0.8400831990001052, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_config_inline_parameters": 0.8563495680000415, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_item_selector[MAP_STATE_ITEM_SELECTOR]": 1.9665942679998807, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_item_selector[MAP_STATE_ITEM_SELECTOR_JSONATA]": 0.8259039270001267, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_item_selector_parameters": 1.1056293580002148, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_item_selector_singleton": 1.4163698989998466, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata[empty]": 0.6862260630000492, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata[mixed]": 0.7254202350000014, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata[singleton]": 0.7158991889999697, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata_fail[boolean]": 0.7755247400000371, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata_fail[function]": 0.0018910420001247985, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata_fail[null]": 1.8769653510000808, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata_fail[number]": 0.7914913619999879, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata_fail[object]": 0.770965101999991, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata_fail[string]": 0.7769711320000852, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata_variable_sampling_fail[boolean]": 0.8354351680000036, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata_variable_sampling_fail[null]": 0.7901132380000035, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata_variable_sampling_fail[number]": 0.8244634480000741, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata_variable_sampling_fail[object]": 0.7853993169999285, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_eval_jsonata_variable_sampling_fail[string]": 1.741533163999975, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_input_array[empty]": 0.7444559059999847, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_input_array[mixed]": 0.8060503850001624, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_input_array[singleton]": 0.7973446939997757, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_input_types[boolean]": 0.9943730320001123, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_input_types[null]": 1.028521845999876, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_input_types[number]": 0.9695020209999257, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_input_types[object]": 1.000118939999993, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_input_types[string]": 0.9653845950001596, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_variable_sampling[boolean]": 0.8350921730000209, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_variable_sampling[null]": 0.8354967919999581, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_variable_sampling[number]": 0.8497095340001124, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_variable_sampling[object]": 0.8353982419998829, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_items_variable_sampling[string]": 0.9367125979997581, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_label": 0.7864737830000195, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_legacy": 0.8270519609999383, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_legacy_config_distributed": 0.800845428000116, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_legacy_config_distributed_item_selector": 0.8491450330000134, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_legacy_config_distributed_parameters": 0.8333413049998626, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_legacy_config_inline": 0.8264363610001055, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_legacy_config_inline_item_selector": 0.8664469059999647, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_legacy_config_inline_parameters": 0.8961734809998916, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_legacy_reentrant": 1.7506280139999717, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_nested": 0.9370756239999309, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_nested_config_distributed": 0.9299468730000626, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_nested_config_distributed_no_max_max_concurrency": 12.574948748999986, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_no_processor_config": 0.7589867810002033, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_parameters_legacy": 1.984776643999794, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_parameters_singleton_legacy": 1.3796839579999869, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_result_writer": 1.1239940970001498, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_retry": 3.8068488649996652, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_retry_legacy": 3.8065901400000257, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_retry_multiple_retriers": 9.505994492000127, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_count_path[-1]": 0.7718913850001172, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_count_path[0]": 0.7895325299998603, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_count_path[1]": 0.735611758999994, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_count_path[NoNumber]": 0.7671988949998649, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_count_path[tolerated_failure_count_value0]": 0.7515701980000813, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_percentage_path[-1.1]": 0.7780102190001799, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_percentage_path[-1]": 0.7838071339999715, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_percentage_path[0]": 0.7380475090001255, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_percentage_path[1.1]": 0.7940360999998575, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_percentage_path[100.1]": 0.7866291260002072, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_percentage_path[100]": 0.7912745880000784, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_percentage_path[1]": 0.7797710649999772, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_percentage_path[NoNumber]": 0.7371642729999621, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_percentage_path[tolerated_failure_percentage_value0]": 0.8037049870001738, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_values[count_literal]": 0.7822893129998647, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_map_state_tolerated_failure_values[percentage_literal]": 0.8112578860000212, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_max_concurrency_path[0]": 0.7444176570000991, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_max_concurrency_path[1]": 0.7501786779999975, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_max_concurrency_path[NoNumber]": 0.7685452570001416, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_max_concurrency_path[max_concurrency_value0]": 0.7993476870001359, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_max_concurrency_path_negative": 0.8477982920001068, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_parallel_state[PARALLEL_STATE]": 0.8653242609999552, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_parallel_state[PARALLEL_STATE_PARAMETERS]": 0.7811182950000557, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_parallel_state_catch": 0.7476929249999102, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_parallel_state_fail": 0.5215535940000109, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_parallel_state_nested": 1.045486518999951, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_parallel_state_order": 0.9078255680000211, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_parallel_state_retry": 3.669604233999962, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_retry_interval_features": 6.579835702999844, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_retry_interval_features_jitter_none": 4.550232334999919, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_retry_interval_features_max_attempts_zero": 2.4057645850000426, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_seconds_jsonata": 0.5115332420000414, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp[NANOSECONDS]": 0.49010691600005885, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp[SECONDS]": 0.5174356859999989, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_invalid[INVALID_DATE]": 0.44022484200013423, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_invalid[INVALID_ISO]": 0.43611648999967656, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_invalid[INVALID_TIME]": 0.43901811900013854, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_invalid[JSONATA]": 2.164539786000205, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_invalid[NO_T]": 0.45659764499964695, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_invalid[NO_Z]": 0.4435498949999328, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_jsonata[INVALID_DATE]": 0.0020528160000594653, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_jsonata[INVALID_ISO]": 0.0019133339999370946, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_jsonata[INVALID_TIME]": 0.0019110689997887675, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_jsonata[NANOSECONDS]": 0.5071575010001652, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_jsonata[NO_T]": 0.0022707259997787332, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_jsonata[NO_Z]": 0.002067262999844388, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_jsonata[SECONDS]": 0.5272763900002246, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_path[INVALID_DATE]": 0.7524599710000075, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_path[INVALID_ISO]": 0.7473167510001986, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_path[INVALID_TIME]": 0.7587612060001447, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_path[NANOSECONDS]": 0.6937360989998069, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_path[NO_T]": 0.7454825150002762, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_path[NO_Z]": 0.7602407940003104, + "tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py::TestBaseScenarios::test_wait_timestamp_path[SECONDS]": 0.7463288309998006, + "tests/aws/services/stepfunctions/v2/scenarios/test_sfn_scenarios.py::TestFundamental::test_path_based_on_data": 6.522477252000044, + "tests/aws/services/stepfunctions/v2/scenarios/test_sfn_scenarios.py::TestFundamental::test_step_functions_calling_api_gateway": 13.677974790999997, + "tests/aws/services/stepfunctions/v2/scenarios/test_sfn_scenarios.py::TestFundamental::test_wait_for_callback": 19.81755325799986, + "tests/aws/services/stepfunctions/v2/services/test_apigetway_task_service.py::TestTaskApiGateway::test_invoke_base": 3.135412831999929, + "tests/aws/services/stepfunctions/v2/services/test_apigetway_task_service.py::TestTaskApiGateway::test_invoke_error": 3.131585981999706, + "tests/aws/services/stepfunctions/v2/services/test_apigetway_task_service.py::TestTaskApiGateway::test_invoke_with_body_post[HelloWorld]": 3.1729907509998156, + "tests/aws/services/stepfunctions/v2/services/test_apigetway_task_service.py::TestTaskApiGateway::test_invoke_with_body_post[None]": 3.2090083390000927, + "tests/aws/services/stepfunctions/v2/services/test_apigetway_task_service.py::TestTaskApiGateway::test_invoke_with_body_post[]": 3.2583439130000897, + "tests/aws/services/stepfunctions/v2/services/test_apigetway_task_service.py::TestTaskApiGateway::test_invoke_with_body_post[request_body3]": 3.1858432990002257, + "tests/aws/services/stepfunctions/v2/services/test_apigetway_task_service.py::TestTaskApiGateway::test_invoke_with_headers[custom_header1]": 3.5020667060000505, + "tests/aws/services/stepfunctions/v2/services/test_apigetway_task_service.py::TestTaskApiGateway::test_invoke_with_headers[custom_header2]": 3.2403230200002326, + "tests/aws/services/stepfunctions/v2/services/test_apigetway_task_service.py::TestTaskApiGateway::test_invoke_with_headers[singleStringHeader]": 0.003194588000042131, + "tests/aws/services/stepfunctions/v2/services/test_apigetway_task_service.py::TestTaskApiGateway::test_invoke_with_query_parameters": 3.4025571479999144, + "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_dynamodb_put_delete_item": 1.0380567229997268, + "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_dynamodb_put_get_item": 1.2208141940000132, + "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_dynamodb_put_update_get_item": 1.358226261000027, + "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_list_secrets": 2.8457703849999234, + "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_s3_get_object[binary]": 1.2181919410002138, + "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_s3_get_object[bytearray]": 1.169680605000167, + "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_s3_get_object[empty_binary]": 1.2251223749999554, + "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_s3_get_object[empty_str]": 1.2696212930000002, + "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_s3_get_object[str]": 1.201052091000065, + "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_s3_put_object[bool]": 1.294494744000076, + "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_s3_put_object[dict]": 1.2780674060002184, + "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_s3_put_object[list]": 1.3057092059998467, + "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_s3_put_object[num]": 1.2545225110000047, + "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_s3_put_object[str]": 1.2863569300000108, + "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_sfn_send_task_outcome_with_no_such_token[state_machine_template0]": 1.0050623490003545, + "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_sfn_send_task_outcome_with_no_such_token[state_machine_template1]": 0.9822376960000838, + "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_sfn_start_execution": 1.0836820220001755, + "tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py::TestTaskServiceAwsSdk::test_sfn_start_execution_implicit_json_serialisation": 1.0954700209999828, + "tests/aws/services/stepfunctions/v2/services/test_dynamodb_task_service.py::TestTaskServiceDynamoDB::test_base_integrations[DYNAMODB_PUT_DELETE_ITEM]": 1.3345800730000974, + "tests/aws/services/stepfunctions/v2/services/test_dynamodb_task_service.py::TestTaskServiceDynamoDB::test_base_integrations[DYNAMODB_PUT_GET_ITEM]": 1.2939891139997144, + "tests/aws/services/stepfunctions/v2/services/test_dynamodb_task_service.py::TestTaskServiceDynamoDB::test_base_integrations[DYNAMODB_PUT_QUERY]": 3.319225448999987, + "tests/aws/services/stepfunctions/v2/services/test_dynamodb_task_service.py::TestTaskServiceDynamoDB::test_base_integrations[DYNAMODB_PUT_UPDATE_GET_ITEM]": 1.6816415350001535, + "tests/aws/services/stepfunctions/v2/services/test_dynamodb_task_service.py::TestTaskServiceDynamoDB::test_invalid_integration": 0.6242711490001511, + "tests/aws/services/stepfunctions/v2/services/test_ecs_task_service.py::TestTaskServiceECS::test_run_task": 0.002159166999945228, + "tests/aws/services/stepfunctions/v2/services/test_ecs_task_service.py::TestTaskServiceECS::test_run_task_raise_failure": 0.00186914899995827, + "tests/aws/services/stepfunctions/v2/services/test_ecs_task_service.py::TestTaskServiceECS::test_run_task_sync": 0.0019926630000099976, + "tests/aws/services/stepfunctions/v2/services/test_ecs_task_service.py::TestTaskServiceECS::test_run_task_sync_raise_failure": 0.0019007189998774265, + "tests/aws/services/stepfunctions/v2/services/test_events_task_service.py::TestTaskServiceEvents::test_put_events_base": 2.0850956959998257, + "tests/aws/services/stepfunctions/v2/services/test_events_task_service.py::TestTaskServiceEvents::test_put_events_malformed_detail": 0.9748696410001685, + "tests/aws/services/stepfunctions/v2/services/test_events_task_service.py::TestTaskServiceEvents::test_put_events_mixed_malformed_detail": 1.0329435700002705, + "tests/aws/services/stepfunctions/v2/services/test_events_task_service.py::TestTaskServiceEvents::test_put_events_no_source": 31.23749798200015, + "tests/aws/services/stepfunctions/v2/services/test_lambda_task.py::TestTaskLambda::test_invoke_bytes_payload": 2.1568894260001343, + "tests/aws/services/stepfunctions/v2/services/test_lambda_task.py::TestTaskLambda::test_invoke_json_values[0.0]": 2.1245320909997645, + "tests/aws/services/stepfunctions/v2/services/test_lambda_task.py::TestTaskLambda::test_invoke_json_values[0_0]": 2.160594858000195, + "tests/aws/services/stepfunctions/v2/services/test_lambda_task.py::TestTaskLambda::test_invoke_json_values[0_1]": 2.12646980500017, + "tests/aws/services/stepfunctions/v2/services/test_lambda_task.py::TestTaskLambda::test_invoke_json_values[HelloWorld]": 2.2179067580000265, + "tests/aws/services/stepfunctions/v2/services/test_lambda_task.py::TestTaskLambda::test_invoke_json_values[True]": 2.160545815999967, + "tests/aws/services/stepfunctions/v2/services/test_lambda_task.py::TestTaskLambda::test_invoke_json_values[json_value5]": 2.1939007200001015, + "tests/aws/services/stepfunctions/v2/services/test_lambda_task.py::TestTaskLambda::test_invoke_json_values[json_value6]": 2.1341302819998873, + "tests/aws/services/stepfunctions/v2/services/test_lambda_task.py::TestTaskLambda::test_invoke_pipe": 3.7826031229999444, + "tests/aws/services/stepfunctions/v2/services/test_lambda_task.py::TestTaskLambda::test_invoke_string_payload": 2.1450705439999638, + "tests/aws/services/stepfunctions/v2/services/test_lambda_task.py::TestTaskLambda::test_lambda_task_filter_parameters_input": 2.4182260740003585, + "tests/aws/services/stepfunctions/v2/services/test_lambda_task_service.py::TestTaskServiceLambda::test_invoke": 2.612286210000093, + "tests/aws/services/stepfunctions/v2/services/test_lambda_task_service.py::TestTaskServiceLambda::test_invoke_bytes_payload": 2.6089770449996195, + "tests/aws/services/stepfunctions/v2/services/test_lambda_task_service.py::TestTaskServiceLambda::test_invoke_json_values[0.0]": 2.596786560000055, + "tests/aws/services/stepfunctions/v2/services/test_lambda_task_service.py::TestTaskServiceLambda::test_invoke_json_values[0_0]": 2.5489297880003505, + "tests/aws/services/stepfunctions/v2/services/test_lambda_task_service.py::TestTaskServiceLambda::test_invoke_json_values[0_1]": 2.594664807000072, + "tests/aws/services/stepfunctions/v2/services/test_lambda_task_service.py::TestTaskServiceLambda::test_invoke_json_values[HelloWorld]": 2.6907809450001423, + "tests/aws/services/stepfunctions/v2/services/test_lambda_task_service.py::TestTaskServiceLambda::test_invoke_json_values[True]": 4.610479865000116, + "tests/aws/services/stepfunctions/v2/services/test_lambda_task_service.py::TestTaskServiceLambda::test_invoke_json_values[json_value5]": 2.571324858000253, + "tests/aws/services/stepfunctions/v2/services/test_lambda_task_service.py::TestTaskServiceLambda::test_invoke_json_values[json_value6]": 2.6115823739999087, + "tests/aws/services/stepfunctions/v2/services/test_lambda_task_service.py::TestTaskServiceLambda::test_invoke_unsupported_param": 2.6747511969997504, + "tests/aws/services/stepfunctions/v2/services/test_lambda_task_service.py::TestTaskServiceLambda::test_list_functions": 0.002510007000182668, + "tests/aws/services/stepfunctions/v2/services/test_sfn_task_service.py::TestTaskServiceSfn::test_start_execution": 1.0711348710001403, + "tests/aws/services/stepfunctions/v2/services/test_sfn_task_service.py::TestTaskServiceSfn::test_start_execution_input_json": 1.0767740280000453, + "tests/aws/services/stepfunctions/v2/services/test_sns_task_service.py::TestTaskServiceSns::test_fifo_message_attribute[input_params0-True]": 1.0121071320002102, + "tests/aws/services/stepfunctions/v2/services/test_sns_task_service.py::TestTaskServiceSns::test_fifo_message_attribute[input_params1-False]": 1.0292122250000375, + "tests/aws/services/stepfunctions/v2/services/test_sns_task_service.py::TestTaskServiceSns::test_publish_base[1]": 1.0256674309998743, + "tests/aws/services/stepfunctions/v2/services/test_sns_task_service.py::TestTaskServiceSns::test_publish_base[HelloWorld]": 1.0015638750001017, + "tests/aws/services/stepfunctions/v2/services/test_sns_task_service.py::TestTaskServiceSns::test_publish_base[None]": 1.0135911930001384, + "tests/aws/services/stepfunctions/v2/services/test_sns_task_service.py::TestTaskServiceSns::test_publish_base[True]": 1.0245170730001973, + "tests/aws/services/stepfunctions/v2/services/test_sns_task_service.py::TestTaskServiceSns::test_publish_base[]": 0.9595056259997818, + "tests/aws/services/stepfunctions/v2/services/test_sns_task_service.py::TestTaskServiceSns::test_publish_base[message1]": 1.001482347000092, + "tests/aws/services/stepfunctions/v2/services/test_sns_task_service.py::TestTaskServiceSns::test_publish_base_error_topic_arn": 1.1234421150002163, + "tests/aws/services/stepfunctions/v2/services/test_sns_task_service.py::TestTaskServiceSns::test_publish_message_attributes[\"HelloWorld\"]": 1.153285660000165, + "tests/aws/services/stepfunctions/v2/services/test_sns_task_service.py::TestTaskServiceSns::test_publish_message_attributes[HelloWorld]": 1.2914371599999868, + "tests/aws/services/stepfunctions/v2/services/test_sns_task_service.py::TestTaskServiceSns::test_publish_message_attributes[message_value3]": 1.4233576969998012, + "tests/aws/services/stepfunctions/v2/services/test_sns_task_service.py::TestTaskServiceSns::test_publish_message_attributes[{}]": 1.1933432830001038, + "tests/aws/services/stepfunctions/v2/services/test_sqs_task_service.py::TestTaskServiceSqs::test_send_message": 1.3266455549999137, + "tests/aws/services/stepfunctions/v2/services/test_sqs_task_service.py::TestTaskServiceSqs::test_send_message_attributes": 1.5505020430000513, + "tests/aws/services/stepfunctions/v2/services/test_sqs_task_service.py::TestTaskServiceSqs::test_send_message_unsupported_parameters": 1.2670010699998784, + "tests/aws/services/stepfunctions/v2/states_variables/test_error_output.py::TestStateVariablesTemplate::test_catch_error_variable_sampling[TASK_CATCH_ERROR_VARIABLE_SAMPLING]": 5.366742402, + "tests/aws/services/stepfunctions/v2/states_variables/test_error_output.py::TestStateVariablesTemplate::test_catch_error_variable_sampling[TASK_CATCH_ERROR_VARIABLE_SAMPLING_TO_JSONPATH]": 2.965703774999838, + "tests/aws/services/stepfunctions/v2/states_variables/test_error_output.py::TestStateVariablesTemplate::test_map_catch_error[MAP_CATCH_ERROR_OUTPUT]": 0.0030611249997036794, + "tests/aws/services/stepfunctions/v2/states_variables/test_error_output.py::TestStateVariablesTemplate::test_map_catch_error[MAP_CATCH_ERROR_OUTPUT_WITH_RETRY]": 0.002666662000137876, + "tests/aws/services/stepfunctions/v2/states_variables/test_error_output.py::TestStateVariablesTemplate::test_map_catch_error[MAP_CATCH_ERROR_VARIABLE_SAMPLING]": 0.0026953570002206106, + "tests/aws/services/stepfunctions/v2/states_variables/test_error_output.py::TestStateVariablesTemplate::test_parallel_catch_error[PARALLEL_CATCH_ERROR_OUTPUT]": 0.0024292960001730535, + "tests/aws/services/stepfunctions/v2/states_variables/test_error_output.py::TestStateVariablesTemplate::test_parallel_catch_error[PARALLEL_CATCH_ERROR_OUTPUT_WITH_RETRY]": 0.0024634989999867685, + "tests/aws/services/stepfunctions/v2/states_variables/test_error_output.py::TestStateVariablesTemplate::test_parallel_catch_error[PARALLEL_CATCH_ERROR_VARIABLE_SAMPLING]": 0.0022991299999830517, + "tests/aws/services/stepfunctions/v2/states_variables/test_error_output.py::TestStateVariablesTemplate::test_task_catch_error_output[TASK_CATCH_ERROR_OUTPUT]": 2.480925332999959, + "tests/aws/services/stepfunctions/v2/states_variables/test_error_output.py::TestStateVariablesTemplate::test_task_catch_error_output[TASK_CATCH_ERROR_OUTPUT_TO_JSONPATH]": 2.5144735250003123, + "tests/aws/services/stepfunctions/v2/states_variables/test_error_output.py::TestStateVariablesTemplate::test_task_catch_error_with_retry[TASK_CATCH_ERROR_OUTPUT_WITH_RETRY]": 3.888734533000161, + "tests/aws/services/stepfunctions/v2/states_variables/test_error_output.py::TestStateVariablesTemplate::test_task_catch_error_with_retry[TASK_CATCH_ERROR_OUTPUT_WITH_RETRY_TO_JSONPATH]": 3.7617458589998023, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_cloudformation_definition_create_describe[dump]": 1.532795873999703, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_cloudformation_definition_create_describe[dumps]": 1.5342553680000037, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_cloudformation_definition_string_create_describe[dump]": 1.585214828000062, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_cloudformation_definition_string_create_describe[dumps]": 1.5351234419999855, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_create_delete_invalid_sm": 0.6208908369999335, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_create_delete_valid_sm": 1.6555771619998723, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_create_duplicate_definition_format_sm": 0.5254582039999605, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_create_duplicate_sm_name": 0.5487753360002898, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_create_exact_duplicate_sm": 0.5872602340000412, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_create_update_state_machine_base_definition": 0.5668841039998824, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_create_update_state_machine_base_definition_and_role": 0.6591545190001398, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_create_update_state_machine_base_role_arn": 0.6490276620002078, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_create_update_state_machine_base_update_none": 0.5094728960000339, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_create_update_state_machine_same_parameters": 0.5919838339998478, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_delete_nonexistent_sm": 0.46418140700006916, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_describe_execution": 1.011169301999871, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_describe_execution_arn_containing_punctuation": 3.0390132410000206, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_describe_execution_invalid_arn": 0.4462269179998657, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_describe_execution_no_such_state_machine": 0.5439191139998911, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_describe_invalid_arn_sm": 0.446329434000063, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_describe_nonexistent_sm": 0.47885094000002937, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_describe_sm_arn_containing_punctuation": 0.49411251200012885, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_describe_state_machine_for_execution": 0.7603402099998675, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_get_execution_history_invalid_arn": 0.434685355000056, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_get_execution_history_no_such_execution": 0.5251859010002136, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_get_execution_history_reversed": 0.5687826450000557, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_invalid_start_execution_arn": 0.4838492430003498, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_invalid_start_execution_input": 0.8765661850000015, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_list_execution_invalid_arn": 0.45369208699980845, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_list_execution_no_such_state_machine": 0.4674700249997841, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_list_executions_pagination": 1.934780743000374, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_list_executions_versions_pagination": 2.214126073000216, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_list_sms": 0.5762743440000122, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_list_sms_pagination": 0.9364028479999433, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_start_execution": 0.6423734689997218, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_start_execution_idempotent": 1.1931279509999513, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_start_sync_execution": 0.5029603970001517, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_state_machine_status_filter": 0.654939880000029, + "tests/aws/services/stepfunctions/v2/test_sfn_api.py::TestSnfApi::test_stop_execution": 0.551295416999892, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[\\x00activity]": 0.37103961699995125, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity name]": 0.36674011000013707, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity\"name]": 0.36117429700016146, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity#name]": 0.3660621099998025, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity$name]": 0.36157672499984983, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity%name]": 0.3740681759998097, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity&name]": 0.367472146999944, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity*name]": 0.35889039799985767, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity,name]": 0.37026506700021855, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity/name]": 0.3697699110000485, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity:name]": 0.36609816899976977, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity;name]": 0.36515024399977847, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activityname]": 0.3712750910001432, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity?name]": 0.36114143499980855, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity[name]": 0.3852866530000938, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity\\\\name]": 0.35755384900016907, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity\\x1f]": 0.3770267080001304, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity\\x7f]": 0.38044045500009815, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity]name]": 0.3594567130000996, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity^name]": 0.3613063850000344, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity`name]": 0.3758948369998052, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity{name]": 0.370490401999632, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity|name]": 0.3631932089997463, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity}name]": 0.3765893180002422, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_activity_invalid_name[activity~name]": 0.37067843099998754, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_describe_delete_activity[ACTIVITY_NAME_ABC]": 0.43746887600036644, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_describe_delete_activity[Activity1]": 0.4572332230000029, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_describe_delete_activity[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]": 0.44328665500006537, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_describe_delete_activity[activity-name.1]": 0.4756556239999554, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_describe_delete_activity[activity-name_123]": 0.44103537099977075, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_describe_delete_activity[activity.name.v2]": 0.4383458399997835, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_describe_delete_activity[activity.name]": 0.4380702900000415, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_describe_delete_activity[activityName.with.dots]": 0.440205700000206, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_create_describe_delete_activity[activity_123.name]": 0.46482811300029425, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_describe_activity_invalid_arn": 0.4528477799999564, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_describe_deleted_activity": 0.410929657999759, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_get_activity_task_deleted": 0.3885910329995568, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_get_activity_task_invalid_arn": 0.4494258560000617, + "tests/aws/services/stepfunctions/v2/test_sfn_api_activities.py::TestSnfApiActivities::test_list_activities": 0.40256727199971465, + "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_base_create_alias_single_router_config": 0.7395654110000578, + "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_base_lifecycle_create_delete_list": 0.9585661730000083, + "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_base_lifecycle_create_invoke_describe_list": 1.1920507510001244, + "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_base_lifecycle_create_update_describe": 0.8215854529998978, + "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_delete_no_such_alias_arn": 0.8053839709996282, + "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_delete_revision_with_alias": 0.7378445900001225, + "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_delete_version_with_alias": 0.7921729369998047, + "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_error_create_alias_invalid_name": 0.7470031479999761, + "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_error_create_alias_invalid_router_configs": 0.7792483980001634, + "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_error_create_alias_not_idempotent": 0.7619567719998486, + "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_error_create_alias_with_state_machine_arn": 0.7266459539998777, + "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_idempotent_create_alias": 2.849745381000048, + "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_list_state_machine_aliases_pagination_invalid_next_token": 0.7705190629999379, + "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_list_state_machine_aliases_pagination_max_results[0]": 0.8864059589998305, + "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_list_state_machine_aliases_pagination_max_results[1]": 0.8824810590001562, + "tests/aws/services/stepfunctions/v2/test_sfn_api_aliasing.py::TestSfnApiAliasing::test_update_no_such_alias_arn": 0.7971445750004023, + "tests/aws/services/stepfunctions/v2/test_sfn_api_express.py::TestSfnApiExpress::test_create_describe_delete": 0.8295719879997705, + "tests/aws/services/stepfunctions/v2/test_sfn_api_express.py::TestSfnApiExpress::test_illegal_activity_task": 0.9748832939997101, + "tests/aws/services/stepfunctions/v2/test_sfn_api_express.py::TestSfnApiExpress::test_illegal_callbacks[SYNC]": 0.953952722999702, + "tests/aws/services/stepfunctions/v2/test_sfn_api_express.py::TestSfnApiExpress::test_illegal_callbacks[WAIT_FOR_TASK_TOKEN]": 1.0142173900001126, + "tests/aws/services/stepfunctions/v2/test_sfn_api_express.py::TestSfnApiExpress::test_start_async_describe_history_execution": 1.505450036999946, + "tests/aws/services/stepfunctions/v2/test_sfn_api_express.py::TestSfnApiExpress::test_start_sync_execution": 0.8602293500000542, + "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_deleted_log_group": 0.5676215150001553, + "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_incomplete_logging_configuration[logging_configuration0]": 0.47706987299989123, + "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_incomplete_logging_configuration[logging_configuration1]": 0.48329171600016707, + "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_invalid_logging_configuration[logging_configuration0]": 0.42843262399992454, + "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_invalid_logging_configuration[logging_configuration1]": 0.44373708100010845, + "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_invalid_logging_configuration[logging_configuration2]": 0.4310890560002463, + "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_logging_configuration[ALL-False]": 0.511781671000108, + "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_logging_configuration[ALL-True]": 0.5354666749999524, + "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_logging_configuration[ERROR-False]": 0.52764924600001, + "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_logging_configuration[ERROR-True]": 0.5241281230000823, + "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_logging_configuration[FATAL-False]": 0.5384218539998074, + "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_logging_configuration[FATAL-True]": 0.5341142199999922, + "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_logging_configuration[OFF-False]": 0.5158044449999579, + "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_logging_configuration[OFF-True]": 0.511416341000313, + "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_multiple_destinations": 0.5168464009998388, + "tests/aws/services/stepfunctions/v2/test_sfn_api_logs.py::TestSnfApiLogs::test_update_logging_configuration": 0.7225768490002338, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_list_map_runs_and_describe_map_run": 0.9177400569999463, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_empty_fail": 0.37411854999982097, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[ ]": 0.37567437299981066, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\"]": 0.37922809299993787, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[#]": 0.4259452250000777, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[$]": 0.4038882410000042, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[%]": 0.4269688250001309, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[&]": 0.42327714900011415, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[*]": 0.3870429360001708, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[,]": 0.5315504090001468, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[:]": 0.4164574020001055, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[;]": 0.4231517989999247, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[<]": 0.3620827059999101, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[>]": 0.3580043890001434, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[?]": 2.413245479999887, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[[]": 0.4267193610000959, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\\\]": 0.39927507299989884, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\n]": 0.3565193699998872, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\r]": 0.3942078259999562, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\t]": 0.3810566540000764, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x00]": 0.361241433999794, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x01]": 0.4104043659999661, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x02]": 0.4036763950000477, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x03]": 0.4240986940003495, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x04]": 0.37647016499977326, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x05]": 0.37761419100024796, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x06]": 0.38025407300028746, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x07]": 0.3731345109999893, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x08]": 0.3757773909997013, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x0b]": 0.3751338859999578, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x0c]": 0.4083357669999259, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x0e]": 0.3771181719998822, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x0f]": 0.3701000119999662, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x10]": 0.3973605849998876, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x11]": 0.4044681010000204, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x12]": 0.3805835579998984, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x13]": 0.3928046839998842, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x14]": 0.3739891400000488, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x15]": 0.3600940880003236, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x16]": 0.4028629209999508, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x17]": 0.4187823479999224, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x18]": 0.43286664600009317, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x19]": 0.3963860520000253, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x1a]": 0.4060903040001449, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x1b]": 0.4110584459997426, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x1c]": 0.40679014400006963, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x1d]": 0.39582909200021277, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x1e]": 0.3800778860002083, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x1f]": 0.3928412330001265, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x7f]": 0.37116463799975463, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x80]": 0.3665359399999488, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x81]": 0.37032406399976026, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x82]": 0.4008515919999809, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x83]": 0.401836694999929, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x84]": 0.4686016469997867, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x85]": 0.3922241400002804, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x86]": 0.4114848740000525, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x87]": 0.39126453199992284, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x88]": 0.3934783720001178, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x89]": 0.39019314400024996, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x8a]": 0.3686967099999947, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x8b]": 0.3681496189999507, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x8c]": 0.38801578600009634, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x8d]": 0.3750435419999576, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x8e]": 2.587271193000106, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x8f]": 0.40629622200003723, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x90]": 0.3917859729999691, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x91]": 0.3566098259998398, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x92]": 0.3880952439997145, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x93]": 0.38557013800004825, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x94]": 0.37011341700008416, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x95]": 0.3720128320001095, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x96]": 0.36455649000004087, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x97]": 0.38718525200010845, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x98]": 0.3947549249999156, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x99]": 0.3900551730000643, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x9a]": 0.4016689469999619, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x9b]": 0.40325699100003476, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x9c]": 0.3893235469997762, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x9d]": 0.39447939699994095, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x9e]": 0.3716111669998554, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[\\x9f]": 0.36753898899974047, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[]]": 0.4161381519998031, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[^]": 0.40231832800009215, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[`]": 0.39391110099995785, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[{]": 0.3735565030001453, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[|]": 0.4379468810002436, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[}]": 0.4359331709997605, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_invalid_char_fail[~]": 0.4257806549999259, + "tests/aws/services/stepfunctions/v2/test_sfn_api_map_run.py::TestSnfApiMapRun::test_map_state_label_too_long_fail": 0.39522448100001384, + "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_create_state_machine": 0.42589713699999265, + "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_tag_invalid_state_machine[None]": 0.4171023050000713, + "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_tag_invalid_state_machine[tag_list1]": 0.42825875499988797, + "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_tag_invalid_state_machine[tag_list2]": 0.41189972200004377, + "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_tag_invalid_state_machine[tag_list3]": 0.396725614999923, + "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_tag_state_machine[tag_list0]": 0.45997725199981687, + "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_tag_state_machine[tag_list1]": 0.5045484949998809, + "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_tag_state_machine[tag_list2]": 0.4487642369997502, + "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_tag_state_machine[tag_list3]": 0.41265856299992265, + "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_tag_state_machine[tag_list4]": 0.4276146390000122, + "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_tag_state_machine_version": 0.4535700649998944, + "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_untag_state_machine[tag_keys0]": 0.44893085800003973, + "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_untag_state_machine[tag_keys1]": 0.4362238480000542, + "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_untag_state_machine[tag_keys2]": 0.44093167899995933, + "tests/aws/services/stepfunctions/v2/test_sfn_api_tagging.py::TestSnfApiTagging::test_untag_state_machine[tag_keys3]": 0.45425796400036234, + "tests/aws/services/stepfunctions/v2/test_sfn_api_validation.py::TestSfnApiValidation::test_validate_state_machine_definition_not_a_definition[EMPTY_DICT]": 0.3969524740000452, + "tests/aws/services/stepfunctions/v2/test_sfn_api_validation.py::TestSfnApiValidation::test_validate_state_machine_definition_not_a_definition[EMPTY_STRING]": 0.4130530960001124, + "tests/aws/services/stepfunctions/v2/test_sfn_api_validation.py::TestSfnApiValidation::test_validate_state_machine_definition_not_a_definition[NOT_A_DEF]": 0.41718552799989084, + "tests/aws/services/stepfunctions/v2/test_sfn_api_validation.py::TestSfnApiValidation::test_validate_state_machine_definition_type_express[ILLEGAL_WFTT]": 0.39964284500024405, + "tests/aws/services/stepfunctions/v2/test_sfn_api_validation.py::TestSfnApiValidation::test_validate_state_machine_definition_type_express[INVALID_BASE_NO_STARTAT]": 0.4075980109998909, + "tests/aws/services/stepfunctions/v2/test_sfn_api_validation.py::TestSfnApiValidation::test_validate_state_machine_definition_type_express[VALID_BASE_PASS]": 0.3725473710003371, + "tests/aws/services/stepfunctions/v2/test_sfn_api_validation.py::TestSfnApiValidation::test_validate_state_machine_definition_type_standard[INVALID_BASE_NO_STARTAT]": 0.39493821900009607, + "tests/aws/services/stepfunctions/v2/test_sfn_api_validation.py::TestSfnApiValidation::test_validate_state_machine_definition_type_standard[VALID_BASE_PASS]": 0.40232140599982813, + "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[BASE_ASSIGN_FROM_INTRINSIC_FUNCTION]": 4.315271190000203, + "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[BASE_ASSIGN_FROM_PARAMETERS]": 1.0093066020001515, + "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[BASE_ASSIGN_FROM_RESULT]": 1.0082469910003056, + "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[BASE_EVALUATION_ORDER_PASS_STATE]": 1.033812246000025, + "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[BASE_REFERENCE_IN_CHOICE]": 1.0719961269999203, + "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[BASE_REFERENCE_IN_FAIL]": 0.9690866599999026, + "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[BASE_REFERENCE_IN_INPUTPATH]": 1.0203463449997798, + "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[BASE_REFERENCE_IN_INTRINSIC_FUNCTION]": 1.2510383970002295, + "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[BASE_REFERENCE_IN_ITERATOR_OUTER_SCOPE]": 1.9903604329997506, + "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[BASE_REFERENCE_IN_OUTPUTPATH]": 0.98193230100037, + "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[BASE_REFERENCE_IN_PARAMETERS]": 0.9956693179999547, + "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[BASE_REFERENCE_IN_WAIT]": 0.9916474219999145, + "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[MAP_STATE_REFERENCE_IN_INTRINSIC_FUNCTION]": 1.3351836839999578, + "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[MAP_STATE_REFERENCE_IN_ITEMS_PATH]": 3.298518965000085, + "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[MAP_STATE_REFERENCE_IN_ITEM_SELECTOR]": 1.2473628759998974, + "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[MAP_STATE_REFERENCE_IN_MAX_CONCURRENCY_PATH]": 0.9710715520002395, + "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[MAP_STATE_REFERENCE_IN_MAX_ITEMS_PATH]": 1.0797531800001252, + "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_assign_templates[MAP_STATE_REFERENCE_IN_TOLERATED_FAILURE_PATH]": 1.0080621860001884, + "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_jsonata_template[CHOICE_CONDITION_CONSTANT_JSONATA]": 0.5766096949998882, + "tests/aws/services/stepfunctions/v2/test_sfn_api_variable_references.py::TestSfnApiVariableReferences::test_base_variable_references_in_jsonata_template[CHOICE_STATE_UNSORTED_CHOICE_PARAMETERS_JSONATA]": 0.6200984969998444, + "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_create_express_with_publish": 0.4670878919998813, + "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_create_publish_describe_no_version_description": 0.4944730410002194, + "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_create_publish_describe_with_version_description": 0.49440472999981466, + "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_create_with_publish": 0.4845824939998238, + "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_create_with_version_description_no_publish": 0.42660526200006643, + "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_describe_state_machine_for_execution_of_version": 0.573416655000301, + "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_describe_state_machine_for_execution_of_version_with_revision": 0.8123175790001369, + "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_empty_revision_with_publish_and_no_publish_on_creation": 0.5243920239997806, + "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_empty_revision_with_publish_and_publish_on_creation": 0.5368959410000116, + "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_idempotent_publish": 0.5131725049998295, + "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_list_delete_version": 0.5741292260001956, + "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_list_state_machine_versions_pagination": 0.952574082999945, + "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_publish_state_machine_version": 0.7059655349999048, + "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_publish_state_machine_version_invalid_arn": 0.45958849100020416, + "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_publish_state_machine_version_no_such_machine": 0.49115759700021044, + "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_start_version_execution": 0.6905082509997555, + "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_update_state_machine": 0.58075421500007, + "tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py::TestSnfApiVersioning::test_version_ids_between_deletions": 0.5283831069996268, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_debug[BASE_CHOICE_STATE]": 3.389210280000043, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_debug[BASE_FAIL_STATE]": 0.9272321539999666, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_debug[BASE_PASS_STATE]": 0.8930914570000823, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_debug[BASE_RESULT_PASS_STATE]": 0.9033143399999517, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_debug[BASE_SUCCEED_STATE]": 0.8912401840000257, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_debug[IO_PASS_STATE]": 1.0309594359998755, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_debug[IO_RESULT_PASS_STATE]": 1.012774399999671, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_info[BASE_CHOICE_STATE]": 0.7642947239999103, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_info[BASE_FAIL_STATE]": 0.5420207579998078, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_info[BASE_PASS_STATE]": 0.5522862980001264, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_info[BASE_RESULT_PASS_STATE]": 0.5619175450001421, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_info[BASE_SUCCEED_STATE]": 0.5415973890001169, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_info[IO_PASS_STATE]": 0.6692073589999836, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_info[IO_RESULT_PASS_STATE]": 0.671932704000028, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_trace[BASE_CHOICE_STATE]": 1.103891207000288, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_trace[BASE_FAIL_STATE]": 0.8832339570001295, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_trace[BASE_PASS_STATE]": 0.896254726000052, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_trace[BASE_RESULT_PASS_STATE]": 0.9209346669997558, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_trace[BASE_SUCCEED_STATE]": 0.8794885690001593, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_trace[IO_PASS_STATE]": 1.0355958700001793, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_inspection_level_trace[IO_RESULT_PASS_STATE]": 0.996998848999965, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_lambda_service_task_state[DEBUG]": 2.6137596870000834, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_lambda_service_task_state[INFO]": 2.641255145000059, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_lambda_service_task_state[TRACE]": 2.6222967430001063, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_lambda_task_state[DEBUG]": 2.6263873709999643, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_lambda_task_state[INFO]": 2.593241111999987, + "tests/aws/services/stepfunctions/v2/test_state/test_test_state_scenarios.py::TestStateCaseScenarios::test_base_lambda_task_state[TRACE]": 2.550220839000076, + "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::TestStateMachine::test_create_choice_state_machine": 2.9075917589998426, + "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::TestStateMachine::test_create_run_map_state_machine": 1.2362435590000587, + "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::TestStateMachine::test_create_run_state_machine": 1.6590625199999067, + "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::TestStateMachine::test_create_state_machines_in_parallel": 2.023295843999904, + "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::TestStateMachine::test_events_state_machine": 0.0023350070000560663, + "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::TestStateMachine::test_intrinsic_functions": 1.3170026739996956, + "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::TestStateMachine::test_try_catch_state_machine": 10.21245763900015, + "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::test_aws_sdk_task": 1.2825834629998099, + "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::test_default_logging_configuration": 0.08433106699976634, + "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::test_multiregion_nested[statemachine_definition0-eu-central-1]": 0.002151411999875563, + "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::test_multiregion_nested[statemachine_definition0-eu-west-1]": 0.002082382000025973, + "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::test_multiregion_nested[statemachine_definition0-us-east-1]": 0.0031113479999476112, + "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::test_multiregion_nested[statemachine_definition0-us-east-2]": 0.0021482960000867024, + "tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py::test_run_aws_sdk_secrets_manager": 3.4229431139999633, + "tests/aws/services/stepfunctions/v2/timeouts/test_heartbeats.py::TestHeartbeats::test_heartbeat_no_timeout": 6.229720967000048, + "tests/aws/services/stepfunctions/v2/timeouts/test_heartbeats.py::TestHeartbeats::test_heartbeat_path_timeout": 6.313291388000152, + "tests/aws/services/stepfunctions/v2/timeouts/test_heartbeats.py::TestHeartbeats::test_heartbeat_timeout": 6.355362087999993, + "tests/aws/services/stepfunctions/v2/timeouts/test_timeouts.py::TestTimeouts::test_fixed_timeout_lambda": 7.3281544730000405, + "tests/aws/services/stepfunctions/v2/timeouts/test_timeouts.py::TestTimeouts::test_fixed_timeout_service_lambda": 9.294602548000057, + "tests/aws/services/stepfunctions/v2/timeouts/test_timeouts.py::TestTimeouts::test_fixed_timeout_service_lambda_with_path": 7.249261395000076, + "tests/aws/services/stepfunctions/v2/timeouts/test_timeouts.py::TestTimeouts::test_global_timeout": 5.874466621000238, + "tests/aws/services/stepfunctions/v2/timeouts/test_timeouts.py::TestTimeouts::test_service_lambda_map_timeout": 0.003191320000041742, + "tests/aws/services/sts/test_sts.py::TestSTSAssumeRoleTagging::test_assume_role_tag_validation": 0.2040062560001843, + "tests/aws/services/sts/test_sts.py::TestSTSAssumeRoleTagging::test_iam_role_chaining_override_transitive_tags": 0.2591821000000891, + "tests/aws/services/sts/test_sts.py::TestSTSIntegrations::test_assume_non_existent_role": 0.02057948599986048, + "tests/aws/services/sts/test_sts.py::TestSTSIntegrations::test_assume_role": 0.2896937930001968, + "tests/aws/services/sts/test_sts.py::TestSTSIntegrations::test_assume_role_with_saml": 0.07632272699993337, + "tests/aws/services/sts/test_sts.py::TestSTSIntegrations::test_assume_role_with_web_identity": 0.06098835700026939, + "tests/aws/services/sts/test_sts.py::TestSTSIntegrations::test_expiration_date_format": 0.021412017999864474, + "tests/aws/services/sts/test_sts.py::TestSTSIntegrations::test_get_caller_identity_role_access_key[False]": 0.10997705900012988, + "tests/aws/services/sts/test_sts.py::TestSTSIntegrations::test_get_caller_identity_role_access_key[True]": 0.10678508500018324, + "tests/aws/services/sts/test_sts.py::TestSTSIntegrations::test_get_caller_identity_root": 0.017536847000201305, + "tests/aws/services/sts/test_sts.py::TestSTSIntegrations::test_get_caller_identity_user_access_key[False]": 0.08144548299969756, + "tests/aws/services/sts/test_sts.py::TestSTSIntegrations::test_get_caller_identity_user_access_key[True]": 0.24889859199993225, + "tests/aws/services/sts/test_sts.py::TestSTSIntegrations::test_get_federation_token": 0.1591389929997149, + "tests/aws/services/support/test_support.py::TestConfigService::test_support_case_lifecycle": 0.08875551200003429, + "tests/aws/services/swf/test_swf.py::TestSwf::test_run_workflow": 0.22711444100013978, + "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_failing_deletion": 0.31272837299979983, + "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_failing_start_transcription_job": 0.49207644699981756, + "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_get_transcription_job": 0.6402712829999473, + "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_list_transcription_jobs": 4.061396845000218, + "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_error_invalid_length": 32.9388712089999, + "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_error_speaker_labels": 0.0018466490000719205, + "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_happy_path": 4.544716678999976, + "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_speaker_diarization": 0.0021503089999441727, + "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_start_job[None-None]": 3.6959623059997284, + "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_start_job[test-output-bucket-2-None]": 6.839008607000096, + "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_start_job[test-output-bucket-3-test-output]": 6.0269128199997795, + "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_start_job[test-output-bucket-4-test-output.json]": 6.311103962999823, + "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_start_job[test-output-bucket-5-test-files/test-output.json]": 6.351689628000031, + "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_start_job[test-output-bucket-6-test-files/test-output]": 2.557397569000159, + "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_start_job_same_name": 5.725525425000114, + "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_supported_media_formats[../../files/en-gb.amr-hello my name is]": 2.188583607000055, + "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_supported_media_formats[../../files/en-gb.flac-hello my name is]": 2.185481928000172, + "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_supported_media_formats[../../files/en-gb.mp3-hello my name is]": 5.742409927000153, + "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_supported_media_formats[../../files/en-gb.mp4-hello my name is]": 2.247200858000042, + "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_supported_media_formats[../../files/en-gb.ogg-hello my name is]": 2.2186730150001495, + "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_supported_media_formats[../../files/en-gb.webm-hello my name is]": 2.2576190669999505, + "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_supported_media_formats[../../files/en-us_video.mkv-one of the most vital]": 2.2769664390000344, + "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_supported_media_formats[../../files/en-us_video.mp4-one of the most vital]": 2.204825165999864, + "tests/aws/services/transcribe/test_transcribe.py::TestTranscribe::test_transcribe_unsupported_media_format_failure": 3.27021918000014, + "tests/aws/test_error_injection.py::TestErrorInjection::test_dynamodb_error_injection": 25.795660405000035, + "tests/aws/test_error_injection.py::TestErrorInjection::test_dynamodb_read_error_injection": 25.77061480999987, + "tests/aws/test_error_injection.py::TestErrorInjection::test_dynamodb_write_error_injection": 51.45584413000006, + "tests/aws/test_error_injection.py::TestErrorInjection::test_kinesis_error_injection": 2.1977103599997463, + "tests/aws/test_integration.py::TestIntegration::test_firehose_extended_s3": 0.2564107010002772, + "tests/aws/test_integration.py::TestIntegration::test_firehose_kinesis_to_s3": 40.627013786000134, + "tests/aws/test_integration.py::TestIntegration::test_firehose_s3": 0.4596591360000275, + "tests/aws/test_integration.py::TestIntegration::test_lambda_streams_batch_and_transactions": 42.230651337999916, + "tests/aws/test_integration.py::TestIntegration::test_scheduled_lambda": 61.51520805200039, + "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_put_item_to_dynamodb[python3.10]": 2.0131830569994236, + "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_put_item_to_dynamodb[python3.11]": 2.0934489660003237, + "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_put_item_to_dynamodb[python3.12]": 2.000033226000596, + "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_put_item_to_dynamodb[python3.13]": 2.003803005000009, + "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_put_item_to_dynamodb[python3.8]": 2.0841916409999612, + "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_put_item_to_dynamodb[python3.9]": 1.9838037849999637, + "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_send_message_to_sqs[python3.10]": 7.9523335939998105, + "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_send_message_to_sqs[python3.11]": 7.9481763150001825, + "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_send_message_to_sqs[python3.12]": 1.9465450530001362, + "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_send_message_to_sqs[python3.13]": 7.913847543000429, + "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_send_message_to_sqs[python3.8]": 15.936157621999882, + "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_send_message_to_sqs[python3.9]": 1.9005593579995548, + "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_start_stepfunctions_execution[python3.10]": 4.017458616000113, + "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_start_stepfunctions_execution[python3.11]": 3.9996685099999922, + "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_start_stepfunctions_execution[python3.12]": 4.113968739000029, + "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_start_stepfunctions_execution[python3.13]": 4.114239764000104, + "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_start_stepfunctions_execution[python3.8]": 4.025582046000181, + "tests/aws/test_integration.py::TestLambdaOutgoingSdkCalls::test_lambda_start_stepfunctions_execution[python3.9]": 4.019813317999706, + "tests/aws/test_integration.py::test_kinesis_lambda_forward_chain": 0.0025505039998279244, + "tests/aws/test_moto.py::test_call_include_response_metadata": 0.00851766200048587, + "tests/aws/test_moto.py::test_call_multi_region_backends": 0.02063037300013093, + "tests/aws/test_moto.py::test_call_non_implemented_operation": 0.05813689099977637, + "tests/aws/test_moto.py::test_call_s3_with_streaming_trait[IO[bytes]]": 0.03175662900048337, + "tests/aws/test_moto.py::test_call_s3_with_streaming_trait[bytes]": 0.0274127069997121, + "tests/aws/test_moto.py::test_call_s3_with_streaming_trait[str]": 0.06946530600043843, + "tests/aws/test_moto.py::test_call_sqs_invalid_call_raises_http_exception": 0.009314643000379874, + "tests/aws/test_moto.py::test_call_with_es_creates_state_correctly": 0.07979999900044277, + "tests/aws/test_moto.py::test_call_with_modified_request": 0.011432380000314879, + "tests/aws/test_moto.py::test_call_with_sns_with_full_uri": 0.006175982000058866, + "tests/aws/test_moto.py::test_call_with_sqs_creates_state_correctly": 4.938354699000229, + "tests/aws/test_moto.py::test_call_with_sqs_invalid_call_raises_exception": 0.008722547999695962, + "tests/aws/test_moto.py::test_call_with_sqs_modifies_state_in_moto_backend": 0.012107703000310721, + "tests/aws/test_moto.py::test_call_with_sqs_returns_service_response": 0.007767378999687935, + "tests/aws/test_moto.py::test_moto_fallback_dispatcher": 0.01683729000023959, + "tests/aws/test_moto.py::test_moto_fallback_dispatcher_error_handling": 0.043336435000128404, + "tests/aws/test_moto.py::test_request_with_response_header_location_fields": 0.12816525899961562, + "tests/aws/test_multi_accounts.py::TestMultiAccounts::test_account_id_namespacing_for_localstack_backends": 0.19999723899991295, + "tests/aws/test_multi_accounts.py::TestMultiAccounts::test_account_id_namespacing_for_moto_backends": 2.0691060829999515, + "tests/aws/test_multi_accounts.py::TestMultiAccounts::test_multi_accounts_dynamodb": 0.33878484399974695, + "tests/aws/test_multi_accounts.py::TestMultiAccounts::test_multi_accounts_kinesis": 1.497637919999761, + "tests/aws/test_multiregion.py::TestMultiRegion::test_multi_region_api_gateway": 0.4939112459996977, + "tests/aws/test_multiregion.py::TestMultiRegion::test_multi_region_sns": 0.09238733200027127, + "tests/aws/test_network_configuration.py::TestLambda::test_function_url": 1.1857527879997178, + "tests/aws/test_network_configuration.py::TestLambda::test_http_api_for_function_url": 0.002411542000118061, + "tests/aws/test_network_configuration.py::TestOpenSearch::test_default_strategy": 11.444635271000152, + "tests/aws/test_network_configuration.py::TestOpenSearch::test_path_strategy": 11.142784281000331, + "tests/aws/test_network_configuration.py::TestOpenSearch::test_port_strategy": 11.118154679000327, + "tests/aws/test_network_configuration.py::TestS3::test_201_response": 0.09323997399997097, + "tests/aws/test_network_configuration.py::TestS3::test_multipart_upload": 0.11771037900007286, + "tests/aws/test_network_configuration.py::TestS3::test_non_us_east_1_location": 0.07480809700018654, + "tests/aws/test_network_configuration.py::TestSQS::test_domain_based_strategies[domain]": 0.027447381999991194, + "tests/aws/test_network_configuration.py::TestSQS::test_domain_based_strategies[standard]": 0.022022494999873743, + "tests/aws/test_network_configuration.py::TestSQS::test_off_strategy_with_external_port": 0.023533451999810495, + "tests/aws/test_network_configuration.py::TestSQS::test_off_strategy_without_external_port": 0.027290325999729248, + "tests/aws/test_network_configuration.py::TestSQS::test_path_strategy": 0.022388364999642363, + "tests/aws/test_notifications.py::TestNotifications::test_sns_to_sqs": 0.1727763160001814, + "tests/aws/test_notifications.py::TestNotifications::test_sqs_queue_names": 0.027045736000218312, + "tests/aws/test_serverless.py::TestServerless::test_apigateway_deployed": 0.06938873800027068, + "tests/aws/test_serverless.py::TestServerless::test_dynamodb_stream_handler_deployed": 0.05352500099979807, + "tests/aws/test_serverless.py::TestServerless::test_event_rules_deployed": 102.76428099400027, + "tests/aws/test_serverless.py::TestServerless::test_kinesis_stream_handler_deployed": 0.0020297000005484733, + "tests/aws/test_serverless.py::TestServerless::test_lambda_with_configs_deployed": 0.025924660000328004, + "tests/aws/test_serverless.py::TestServerless::test_queue_handler_deployed": 0.048895632000494516, + "tests/aws/test_serverless.py::TestServerless::test_s3_bucket_deployed": 22.854606267000236, + "tests/aws/test_terraform.py::TestTerraform::test_acm": 0.0019188520000170683, + "tests/aws/test_terraform.py::TestTerraform::test_apigateway": 0.0019112769996354473, + "tests/aws/test_terraform.py::TestTerraform::test_apigateway_escaped_policy": 0.0019292609995318344, + "tests/aws/test_terraform.py::TestTerraform::test_bucket_exists": 0.005778517000180727, + "tests/aws/test_terraform.py::TestTerraform::test_dynamodb": 0.0020267350000722217, + "tests/aws/test_terraform.py::TestTerraform::test_event_source_mapping": 0.0017712340004436555, + "tests/aws/test_terraform.py::TestTerraform::test_lambda": 0.00197891499965408, + "tests/aws/test_terraform.py::TestTerraform::test_route53": 0.001846816000124818, + "tests/aws/test_terraform.py::TestTerraform::test_security_groups": 0.0019925910000893055, + "tests/aws/test_terraform.py::TestTerraform::test_sqs": 0.001986921000025177, + "tests/aws/test_validate.py::TestMissingParameter::test_elasticache": 0.001888324000447028, + "tests/aws/test_validate.py::TestMissingParameter::test_opensearch": 0.0018842760000552516, + "tests/aws/test_validate.py::TestMissingParameter::test_sns": 0.001820837000195752, + "tests/aws/test_validate.py::TestMissingParameter::test_sqs_create_queue": 0.0018610540005283838, + "tests/aws/test_validate.py::TestMissingParameter::test_sqs_send_message": 0.0019662719996631495, + "tests/cli/test_cli.py::TestCliContainerLifecycle::test_container_starts_non_root": 0.0019476359998407133, + "tests/cli/test_cli.py::TestCliContainerLifecycle::test_custom_docker_flags": 0.0020047130001330515, + "tests/cli/test_cli.py::TestCliContainerLifecycle::test_logs": 0.0019412540000303125, + "tests/cli/test_cli.py::TestCliContainerLifecycle::test_pulling_image_message": 0.0019682450001710095, + "tests/cli/test_cli.py::TestCliContainerLifecycle::test_restart": 0.0019438090002950048, + "tests/cli/test_cli.py::TestCliContainerLifecycle::test_start_already_running": 0.0018122899996342312, + "tests/cli/test_cli.py::TestCliContainerLifecycle::test_start_cli_within_container": 0.0018897069994636695, + "tests/cli/test_cli.py::TestCliContainerLifecycle::test_start_wait_stop": 0.0019450810004855157, + "tests/cli/test_cli.py::TestCliContainerLifecycle::test_status_services": 0.0020746160003000114, + "tests/cli/test_cli.py::TestCliContainerLifecycle::test_volume_dir_mounted_correctly": 0.001945212000009633, + "tests/cli/test_cli.py::TestCliContainerLifecycle::test_wait_timeout_raises_exception": 0.0018940759996439738, + "tests/cli/test_cli.py::TestDNSServer::test_dns_port_not_published_by_default": 0.0018575270000837918, + "tests/cli/test_cli.py::TestDNSServer::test_dns_port_published_with_flag": 0.001951172999724804, + "tests/cli/test_cli.py::TestHooks::test_prepare_host_hook_called_with_correct_dirs": 0.5776223900002151, + "tests/cli/test_cli.py::TestImports::test_import_venv": 0.007494947999930446, + "tests/integration/aws/test_app.py::TestExceptionHandlers::test_404_unfortunately_detected_as_s3_request": 0.04150502900029096, + "tests/integration/aws/test_app.py::TestExceptionHandlers::test_internal_failure_handler_http_errors": 0.024781626999811124, + "tests/integration/aws/test_app.py::TestExceptionHandlers::test_router_handler_get_http_errors": 0.002144297000086226, + "tests/integration/aws/test_app.py::TestExceptionHandlers::test_router_handler_get_unexpected_errors": 0.0020628130005206913, + "tests/integration/aws/test_app.py::TestExceptionHandlers::test_router_handler_patch_http_errors": 0.12544674400032818, + "tests/integration/aws/test_app.py::TestHTTP2Support::test_http2_http": 0.11721108099982303, + "tests/integration/aws/test_app.py::TestHTTP2Support::test_http2_https": 0.12351408300037292, + "tests/integration/aws/test_app.py::TestHTTP2Support::test_http2_https_localhost": 0.066230311000254, + "tests/integration/aws/test_app.py::TestHttps::test_default_cert_works": 0.07541962799996327, + "tests/integration/aws/test_app.py::TestWebSocketIntegration::test_return_response": 0.00198096899976008, + "tests/integration/aws/test_app.py::TestWebSocketIntegration::test_ssl_websockets": 0.002143855999747757, + "tests/integration/aws/test_app.py::TestWebSocketIntegration::test_websocket_reject_through_edge_router": 0.002141681000466633, + "tests/integration/aws/test_app.py::TestWebSocketIntegration::test_websockets_served_through_edge_router": 0.0022197279995452845, + "tests/integration/aws/test_app.py::TestWerkzeugIntegration::test_chunked_request_streaming": 0.12190717599969503, + "tests/integration/aws/test_app.py::TestWerkzeugIntegration::test_chunked_response_streaming": 0.1407514809998247, + "tests/integration/aws/test_app.py::TestWerkzeugIntegration::test_raw_header_handling": 0.13231259900021541, + "tests/integration/aws/test_app.py::TestWerkzeugIntegration::test_response_close_handlers_called_with_router": 0.10865986099997826, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_build_image[CmdDockerClient-False-False]": 0.0021742129997619486, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_build_image[CmdDockerClient-False-True]": 0.002233483000054548, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_build_image[CmdDockerClient-True-False]": 0.0022045999999136257, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_build_image[CmdDockerClient-True-True]": 0.0021147409997865907, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_build_image[SdkDockerClient-False-False]": 2.987745396000264, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_build_image[SdkDockerClient-False-True]": 3.006608507999772, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_build_image[SdkDockerClient-True-False]": 2.9955340089995843, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_build_image[SdkDockerClient-True-True]": 2.724292030000015, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_container_lifecycle_commands[CmdDockerClient]": 0.0019860180000250693, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_container_lifecycle_commands[SdkDockerClient]": 21.03611520600043, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_directory_content_into_container[CmdDockerClient]": 0.0020858660000158125, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_directory_content_into_container[SdkDockerClient]": 0.2988429830002133, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_directory_into_container[CmdDockerClient]": 0.001974317000076553, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_directory_into_container[SdkDockerClient]": 0.23329376000037882, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_directory_structure_into_container[CmdDockerClient]": 0.005608187000234466, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_directory_structure_into_container[SdkDockerClient]": 0.26489212700062126, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_from_container[CmdDockerClient]": 0.0020115670004088315, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_from_container[SdkDockerClient]": 0.25259946500000297, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_from_container_into_directory[CmdDockerClient]": 0.0020048940004926408, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_from_container_into_directory[SdkDockerClient]": 0.26565576099983446, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_from_container_to_different_file[CmdDockerClient]": 0.0020266650003577524, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_from_container_to_different_file[SdkDockerClient]": 0.25459548899971196, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_from_non_existent_container[CmdDockerClient]": 0.0019204059999538003, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_from_non_existent_container[SdkDockerClient]": 0.010422433999792702, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_into_container[CmdDockerClient]": 0.0044269830000303045, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_into_container[SdkDockerClient]": 0.2315645849998873, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_into_container_with_existing_target[CmdDockerClient]": 0.0020039429996359104, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_into_container_with_existing_target[SdkDockerClient]": 0.3534016660000816, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_into_container_without_target_filename[CmdDockerClient]": 0.0019703779998963, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_into_container_without_target_filename[SdkDockerClient]": 0.22823089399980745, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_into_non_existent_container[CmdDockerClient]": 0.0019743069997275597, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_copy_into_non_existent_container[SdkDockerClient]": 0.009799647999898298, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_container_non_existing_image[CmdDockerClient]": 0.0020139809994361713, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_container_non_existing_image[SdkDockerClient]": 0.0771440190001158, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_container_remove_removes_container[CmdDockerClient]": 0.0020172069998807274, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_container_remove_removes_container[SdkDockerClient]": 1.1971179379993373, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_container_with_init[CmdDockerClient]": 0.0021503880002455844, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_container_with_init[SdkDockerClient]": 0.02966227400020216, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_container_with_max_env_vars[CmdDockerClient]": 0.0019564520002859354, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_container_with_max_env_vars[SdkDockerClient]": 0.24906973500037566, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_file_in_container[CmdDockerClient]": 0.0019042949998038239, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_file_in_container[SdkDockerClient]": 0.20178695499953392, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_start_container_with_stdin_to_file[CmdDockerClient-False]": 0.001978634999886708, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_start_container_with_stdin_to_file[CmdDockerClient-True]": 0.0019305150003674498, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_start_container_with_stdin_to_file[SdkDockerClient-False]": 0.23755164700014575, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_start_container_with_stdin_to_file[SdkDockerClient-True]": 0.22942345200044656, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_start_container_with_stdin_to_stdout[CmdDockerClient-False]": 0.00196893700012879, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_start_container_with_stdin_to_stdout[CmdDockerClient-True]": 0.0019893339999725868, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_start_container_with_stdin_to_stdout[SdkDockerClient-False]": 0.21441249999998035, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_start_container_with_stdin_to_stdout[SdkDockerClient-True]": 0.2021442330001264, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_with_exposed_ports[CmdDockerClient]": 0.0019774520001192286, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_with_exposed_ports[SdkDockerClient]": 0.005977562999760266, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_with_host_network[CmdDockerClient]": 0.001933640000061132, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_with_host_network[SdkDockerClient]": 0.031781079999746, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_with_port_mapping[CmdDockerClient]": 0.002028447999691707, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_with_port_mapping[SdkDockerClient]": 0.029414658000405325, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_with_volume[CmdDockerClient]": 0.0020568810000440862, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_create_with_volume[SdkDockerClient]": 0.0019099450000794604, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_docker_image_names[CmdDockerClient]": 0.002061249999769643, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_docker_image_names[SdkDockerClient]": 0.682877703000031, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_docker_not_available[CmdDockerClient]": 0.008115415999782272, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_docker_not_available[SdkDockerClient]": 0.0063621279996368685, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_error_in_container[CmdDockerClient]": 0.0019432869999036484, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_error_in_container[SdkDockerClient]": 0.26232140299953244, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container[CmdDockerClient]": 0.0020318850001785904, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container[SdkDockerClient]": 0.2647730569997293, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container_not_running_raises_exception[CmdDockerClient]": 0.001989434999813966, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container_not_running_raises_exception[SdkDockerClient]": 0.03197939600022437, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container_with_env[CmdDockerClient]": 0.0019410640002206492, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container_with_env[SdkDockerClient]": 0.24466521299973465, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container_with_env_deletion[CmdDockerClient]": 0.0020113850000598177, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container_with_env_deletion[SdkDockerClient]": 0.30638482900030795, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container_with_stdin[CmdDockerClient]": 0.002076358000522305, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container_with_stdin[SdkDockerClient]": 0.2720680259994879, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container_with_stdin_stdout_stderr[CmdDockerClient]": 0.0019836449996546435, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container_with_stdin_stdout_stderr[SdkDockerClient]": 0.24858734799954618, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container_with_workdir[CmdDockerClient]": 0.0019338000001880573, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_exec_in_container_with_workdir[SdkDockerClient]": 0.24724962399932338, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_command[CmdDockerClient]": 0.001883455000097456, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_command[SdkDockerClient]": 0.006720673000017996, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_command_non_existing_image[CmdDockerClient]": 0.0020430060003491235, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_command_non_existing_image[SdkDockerClient]": 0.07826454399992144, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_command_not_pulled_image[CmdDockerClient]": 0.0019641270000647637, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_command_not_pulled_image[SdkDockerClient]": 0.4372740019994126, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_entrypoint[CmdDockerClient]": 0.002024702000198886, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_entrypoint[SdkDockerClient]": 0.010586408999643027, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_entrypoint_non_existing_image[CmdDockerClient]": 0.0018401740003355371, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_entrypoint_non_existing_image[SdkDockerClient]": 0.08512466899992432, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_entrypoint_not_pulled_image[CmdDockerClient]": 0.0018812019993674767, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_entrypoint_not_pulled_image[SdkDockerClient]": 0.4306315139997423, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_id[CmdDockerClient]": 0.0020818590000999393, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_id[SdkDockerClient]": 0.2117440759998317, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_id_not_existing[CmdDockerClient]": 0.0020848849999310914, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_id_not_existing[SdkDockerClient]": 0.009128685999712616, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_ip[CmdDockerClient]": 0.001969276000181708, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_ip[SdkDockerClient]": 0.21698503100014932, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_ip_for_host_network[CmdDockerClient]": 0.0021808449996569834, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_ip_for_host_network[SdkDockerClient]": 0.0439226399994368, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_ip_for_network[CmdDockerClient]": 0.002211062999776914, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_ip_for_network[SdkDockerClient]": 0.46928623100029654, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_ip_for_network_non_existent_network[CmdDockerClient]": 0.0020847139999204956, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_ip_for_network_non_existent_network[SdkDockerClient]": 0.2089021980000325, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_ip_for_network_wrong_network[CmdDockerClient]": 0.0021463409998432326, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_ip_for_network_wrong_network[SdkDockerClient]": 0.37929143299970747, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_ip_non_existing_container[CmdDockerClient]": 0.0019315449999339762, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_ip_non_existing_container[SdkDockerClient]": 0.007194666000032157, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_name[CmdDockerClient]": 0.002041642999756732, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_name[SdkDockerClient]": 0.21556963800048834, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_name_not_existing[CmdDockerClient]": 0.001986009000120248, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_container_name_not_existing[SdkDockerClient]": 0.009509341000011773, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_logs[CmdDockerClient]": 0.0021719179999308835, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_logs[SdkDockerClient]": 0.20122225999966759, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_logs_non_existent_container[CmdDockerClient]": 0.0021066150002297945, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_logs_non_existent_container[SdkDockerClient]": 0.00852498900030696, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_network[CmdDockerClient]": 0.0020590069998434046, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_network[SdkDockerClient]": 0.02732670599971243, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_network_multiple_networks[CmdDockerClient]": 0.002051412999662716, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_network_multiple_networks[SdkDockerClient]": 0.4312691140003153, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_network_non_existing_container[CmdDockerClient]": 0.0020825800002057804, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_network_non_existing_container[SdkDockerClient]": 0.008047258999795304, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_system_id[CmdDockerClient]": 0.0019617330003711686, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_system_id[SdkDockerClient]": 0.029429615000026388, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_system_info[CmdDockerClient]": 0.004160180999861041, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_get_system_info[SdkDockerClient]": 0.038108755999019195, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_inspect_container[CmdDockerClient]": 0.0021684119997189555, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_inspect_container[SdkDockerClient]": 0.20471055899997737, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_inspect_container_volumes[CmdDockerClient]": 0.0018556729996817012, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_inspect_container_volumes[SdkDockerClient]": 0.002003512000101182, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_inspect_container_volumes_with_no_volumes[CmdDockerClient]": 0.0019185710002602718, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_inspect_container_volumes_with_no_volumes[SdkDockerClient]": 0.2158825399997113, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_inspect_image[CmdDockerClient]": 0.0021215839997239527, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_inspect_image[SdkDockerClient]": 0.03882104099966455, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_inspect_network[CmdDockerClient]": 0.002155416999812587, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_inspect_network[SdkDockerClient]": 0.15950247499995385, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_inspect_network_non_existent_network[CmdDockerClient]": 0.0022225539996725274, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_inspect_network_non_existent_network[SdkDockerClient]": 0.010294172000612889, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_is_container_running[CmdDockerClient]": 0.002205211000273266, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_is_container_running[SdkDockerClient]": 20.517752243000814, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_list_containers[CmdDockerClient]": 0.0020131000001128996, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_list_containers[SdkDockerClient]": 0.08856012399974134, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_list_containers_filter[CmdDockerClient]": 0.0020307429999775195, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_list_containers_filter[SdkDockerClient]": 0.08017961999939871, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_list_containers_filter_illegal_filter[CmdDockerClient]": 0.0019034130000363803, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_list_containers_filter_illegal_filter[SdkDockerClient]": 0.007755959999940387, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_list_containers_filter_non_existing[CmdDockerClient]": 0.0019158059999426769, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_list_containers_filter_non_existing[SdkDockerClient]": 0.008862195000347128, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_list_containers_with_podman_image_ref_format[CmdDockerClient]": 0.0020492469998316665, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_list_containers_with_podman_image_ref_format[SdkDockerClient]": 0.2525531430001138, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_pause_non_existing_container[CmdDockerClient]": 0.001999594000153593, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_pause_non_existing_container[SdkDockerClient]": 0.006145097999706195, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_pull_docker_image[CmdDockerClient]": 0.00211296699990271, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_pull_docker_image[SdkDockerClient]": 0.4488909179995062, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_pull_docker_image_with_hash[CmdDockerClient]": 0.002143505000276491, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_pull_docker_image_with_hash[SdkDockerClient]": 0.3439823339999748, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_pull_docker_image_with_tag[CmdDockerClient]": 0.0021081280001453706, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_pull_docker_image_with_tag[SdkDockerClient]": 0.4324289379997026, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_pull_non_existent_docker_image[CmdDockerClient]": 0.002118629000506189, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_pull_non_existent_docker_image[SdkDockerClient]": 0.06837712800006557, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_push_access_denied[CmdDockerClient]": 0.0020590659996742033, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_push_access_denied[SdkDockerClient]": 0.4220290550001664, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_push_invalid_registry[CmdDockerClient]": 0.002065096999558591, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_push_invalid_registry[SdkDockerClient]": 0.022701955999764323, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_push_non_existent_docker_image[CmdDockerClient]": 0.002520583999739756, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_push_non_existent_docker_image[SdkDockerClient]": 0.00704300199959107, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_remove_non_existing_container[CmdDockerClient]": 0.0019594489999690268, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_remove_non_existing_container[SdkDockerClient]": 0.006093070000588341, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_restart_non_existing_container[CmdDockerClient]": 0.0019982009998784633, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_restart_non_existing_container[SdkDockerClient]": 0.006166820000089501, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_container[CmdDockerClient]": 0.0019983520001005672, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_container[SdkDockerClient]": 0.18854597399968043, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_container_automatic_pull[CmdDockerClient]": 0.0022507970002152433, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_container_automatic_pull[SdkDockerClient]": 0.673041239000213, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_container_error[CmdDockerClient]": 0.0020157449998805532, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_container_error[SdkDockerClient]": 0.12924806299997726, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_container_non_existent_image[CmdDockerClient]": 0.002463868999711849, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_container_non_existent_image[SdkDockerClient]": 0.1013009660005082, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_container_with_init[CmdDockerClient]": 0.004238168000028963, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_container_with_init[SdkDockerClient]": 0.20150086099965847, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_container_with_stdin[CmdDockerClient]": 0.002009592999911547, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_container_with_stdin[SdkDockerClient]": 0.20015795600011188, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_detached_with_logs[CmdDockerClient]": 0.0019669829998747446, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_run_detached_with_logs[SdkDockerClient]": 0.2096487759995398, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_running_container_names[CmdDockerClient]": 0.0021156230000087817, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_running_container_names[SdkDockerClient]": 10.709374915999888, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_set_container_entrypoint[CmdDockerClient-echo]": 0.0020460209998418577, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_set_container_entrypoint[CmdDockerClient-entrypoint1]": 0.00202808800031562, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_set_container_entrypoint[SdkDockerClient-echo]": 0.20505091799986985, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_set_container_entrypoint[SdkDockerClient-entrypoint1]": 0.19657022100000177, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_start_non_existing_container[CmdDockerClient]": 0.0021365929997045896, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_start_non_existing_container[SdkDockerClient]": 0.006085186000291287, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_stop_non_existing_container[CmdDockerClient]": 0.002061800999854313, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_stop_non_existing_container[SdkDockerClient]": 0.007365015999766911, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_stream_logs[CmdDockerClient]": 0.0019685150000441354, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_stream_logs[SdkDockerClient]": 0.18855870900097216, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_stream_logs_non_existent_container[CmdDockerClient]": 0.002259103000142204, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_stream_logs_non_existent_container[SdkDockerClient]": 0.006439974000386428, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_tag_image[CmdDockerClient]": 0.0020554189995891647, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_tag_image[SdkDockerClient]": 0.18093338100061374, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_tag_non_existing_image[CmdDockerClient]": 0.002032997000242176, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_tag_non_existing_image[SdkDockerClient]": 0.006922284000211221, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_unpause_non_existing_container[CmdDockerClient]": 0.002325988999928086, + "tests/integration/docker_utils/test_docker.py::TestDockerClient::test_unpause_non_existing_container[SdkDockerClient]": 0.0061809359999642766, + "tests/integration/docker_utils/test_docker.py::TestDockerImages::test_commit_creates_image_from_running_container[CmdDockerClient]": 0.004262325000127021, + "tests/integration/docker_utils/test_docker.py::TestDockerImages::test_commit_creates_image_from_running_container[SdkDockerClient]": 0.8075754829992547, + "tests/integration/docker_utils/test_docker.py::TestDockerImages::test_commit_image_raises_for_nonexistent_container[CmdDockerClient]": 0.0025424069999644416, + "tests/integration/docker_utils/test_docker.py::TestDockerImages::test_commit_image_raises_for_nonexistent_container[SdkDockerClient]": 0.007106669999757287, + "tests/integration/docker_utils/test_docker.py::TestDockerImages::test_remove_image_raises_for_nonexistent_image[CmdDockerClient]": 0.002530634000322607, + "tests/integration/docker_utils/test_docker.py::TestDockerImages::test_remove_image_raises_for_nonexistent_image[SdkDockerClient]": 0.00676469600011842, + "tests/integration/docker_utils/test_docker.py::TestDockerLabels::test_create_container_with_labels[CmdDockerClient]": 0.004102704999695561, + "tests/integration/docker_utils/test_docker.py::TestDockerLabels::test_create_container_with_labels[SdkDockerClient]": 0.04916868100053762, + "tests/integration/docker_utils/test_docker.py::TestDockerLabels::test_get_container_stats[CmdDockerClient]": 0.0021238400004222058, + "tests/integration/docker_utils/test_docker.py::TestDockerLabels::test_get_container_stats[SdkDockerClient]": 1.2495884569998452, + "tests/integration/docker_utils/test_docker.py::TestDockerLabels::test_list_containers_with_labels[CmdDockerClient]": 0.0021063669996692624, + "tests/integration/docker_utils/test_docker.py::TestDockerLabels::test_list_containers_with_labels[SdkDockerClient]": 0.2228096439998808, + "tests/integration/docker_utils/test_docker.py::TestDockerLabels::test_run_container_with_labels[CmdDockerClient]": 0.0021591750000879983, + "tests/integration/docker_utils/test_docker.py::TestDockerLabels::test_run_container_with_labels[SdkDockerClient]": 0.19981819099984932, + "tests/integration/docker_utils/test_docker.py::TestDockerLogging::test_docker_logging_fluentbit[CmdDockerClient]": 0.0035743590005949955, + "tests/integration/docker_utils/test_docker.py::TestDockerLogging::test_docker_logging_fluentbit[SdkDockerClient]": 3.1070925779999925, + "tests/integration/docker_utils/test_docker.py::TestDockerLogging::test_docker_logging_none_disables_logs[CmdDockerClient]": 0.007059620999825711, + "tests/integration/docker_utils/test_docker.py::TestDockerLogging::test_docker_logging_none_disables_logs[SdkDockerClient]": 0.23436751700046443, + "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_connect_container_to_network[CmdDockerClient]": 0.0075569180003185465, + "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_connect_container_to_network[SdkDockerClient]": 0.44557842899939715, + "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_connect_container_to_network_with_alias_and_disconnect[CmdDockerClient]": 0.004173216000253888, + "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_connect_container_to_network_with_alias_and_disconnect[SdkDockerClient]": 0.8661076929997762, + "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_connect_container_to_network_with_link_local_address[CmdDockerClient]": 0.0020424250001269684, + "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_connect_container_to_network_with_link_local_address[SdkDockerClient]": 0.18895921499915858, + "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_connect_container_to_nonexistent_network[CmdDockerClient]": 0.002027345999977115, + "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_connect_container_to_nonexistent_network[SdkDockerClient]": 0.200472837000234, + "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_connect_nonexistent_container_to_network[CmdDockerClient]": 0.002066130000002886, + "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_connect_nonexistent_container_to_network[SdkDockerClient]": 0.14693845400006467, + "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_disconnect_container_from_nonexistent_network[CmdDockerClient]": 0.002021375999902375, + "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_disconnect_container_from_nonexistent_network[SdkDockerClient]": 0.20208038900045722, + "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_disconnect_nonexistent_container_from_network[CmdDockerClient]": 0.0020775109996975516, + "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_disconnect_nonexistent_container_from_network[SdkDockerClient]": 0.15538073800007624, + "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_docker_sdk_no_retries": 0.02843729300002451, + "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_docker_sdk_retries_after_init": 1.1295256840003276, + "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_docker_sdk_retries_on_init": 1.054931353000029, + "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_docker_sdk_timeout_seconds": 0.022548158999597945, + "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_get_container_ip_with_network[CmdDockerClient]": 0.002214628999809065, + "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_get_container_ip_with_network[SdkDockerClient]": 0.38788707499998054, + "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_network_lifecycle[CmdDockerClient]": 0.0036067999999431777, + "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_network_lifecycle[SdkDockerClient]": 0.16487809999989622, + "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_set_container_workdir[CmdDockerClient]": 0.002195463999214553, + "tests/integration/docker_utils/test_docker.py::TestDockerNetworking::test_set_container_workdir[SdkDockerClient]": 0.2317638970007465, + "tests/integration/docker_utils/test_docker.py::TestDockerPermissions::test_container_with_cap_add[CmdDockerClient]": 0.0041865499997584266, + "tests/integration/docker_utils/test_docker.py::TestDockerPermissions::test_container_with_cap_add[SdkDockerClient]": 0.4311435279992111, + "tests/integration/docker_utils/test_docker.py::TestDockerPermissions::test_container_with_cap_drop[CmdDockerClient]": 0.0023205000002235465, + "tests/integration/docker_utils/test_docker.py::TestDockerPermissions::test_container_with_cap_drop[SdkDockerClient]": 0.3717644060002385, + "tests/integration/docker_utils/test_docker.py::TestDockerPermissions::test_container_with_sec_opt[CmdDockerClient]": 0.002121473999977752, + "tests/integration/docker_utils/test_docker.py::TestDockerPermissions::test_container_with_sec_opt[SdkDockerClient]": 0.028574189999289956, + "tests/integration/docker_utils/test_docker.py::TestDockerPorts::test_container_port_can_be_bound[CmdDockerClient-None]": 0.0019871919998877274, + "tests/integration/docker_utils/test_docker.py::TestDockerPorts::test_container_port_can_be_bound[CmdDockerClient-tcp]": 0.002020073000494449, + "tests/integration/docker_utils/test_docker.py::TestDockerPorts::test_container_port_can_be_bound[CmdDockerClient-udp]": 0.002187629000218294, + "tests/integration/docker_utils/test_docker.py::TestDockerPorts::test_container_port_can_be_bound[SdkDockerClient-None]": 1.5191904920002344, + "tests/integration/docker_utils/test_docker.py::TestDockerPorts::test_container_port_can_be_bound[SdkDockerClient-tcp]": 1.5375408579998293, + "tests/integration/docker_utils/test_docker.py::TestDockerPorts::test_container_port_can_be_bound[SdkDockerClient-udp]": 1.5351471829999355, + "tests/integration/docker_utils/test_docker.py::TestDockerPorts::test_reserve_container_port[CmdDockerClient-None]": 0.00370103899967944, + "tests/integration/docker_utils/test_docker.py::TestDockerPorts::test_reserve_container_port[CmdDockerClient-tcp]": 0.0020293419997869933, + "tests/integration/docker_utils/test_docker.py::TestDockerPorts::test_reserve_container_port[CmdDockerClient-udp]": 0.002146861999790417, + "tests/integration/docker_utils/test_docker.py::TestDockerPorts::test_reserve_container_port[SdkDockerClient-None]": 2.7168887719994927, + "tests/integration/docker_utils/test_docker.py::TestDockerPorts::test_reserve_container_port[SdkDockerClient-tcp]": 2.7473444379998, + "tests/integration/docker_utils/test_docker.py::TestDockerPorts::test_reserve_container_port[SdkDockerClient-udp]": 2.9031447020001906, + "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_additional_arguments[CmdDockerClient]": 0.00474069599977156, + "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_additional_arguments[SdkDockerClient]": 0.42618688999982623, + "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_additional_arguments_add_dns[CmdDockerClient-False]": 0.0024292040002364956, + "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_additional_arguments_add_dns[CmdDockerClient-True]": 0.0026626840003700636, + "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_additional_arguments_add_dns[SdkDockerClient-False]": 0.12470965300008174, + "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_additional_arguments_add_dns[SdkDockerClient-True]": 0.12371353699973042, + "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_additional_arguments_add_host[CmdDockerClient]": 0.002673152999705053, + "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_additional_arguments_add_host[SdkDockerClient]": 0.1931397069997729, + "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_additional_arguments_env_files[CmdDockerClient]": 0.002387545000146929, + "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_additional_arguments_env_files[SdkDockerClient]": 0.7819009720005852, + "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_additional_arguments_random_port[CmdDockerClient]": 0.0023395849998451013, + "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_additional_arguments_random_port[SdkDockerClient]": 0.43408959499993216, + "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_ulimit[CmdDockerClient]": 0.010533972999837715, + "tests/integration/docker_utils/test_docker.py::TestRunWithAdditionalArgs::test_run_with_ulimit[SdkDockerClient]": 0.20870612499993513, + "tests/integration/services/test_internal.py::TestHealthResource::test_get": 0.021462121000240586, + "tests/integration/services/test_internal.py::TestHealthResource::test_head": 0.01698914100006732, + "tests/integration/services/test_internal.py::TestInfoEndpoint::test_get": 0.053014601000541006, + "tests/integration/services/test_internal.py::TestInitScriptsResource::test_query_individual_stage_completed[boot-True]": 0.02475049099939497, + "tests/integration/services/test_internal.py::TestInitScriptsResource::test_query_individual_stage_completed[ready-True]": 0.026020423999852937, + "tests/integration/services/test_internal.py::TestInitScriptsResource::test_query_individual_stage_completed[shutdown-False]": 0.02113915400013866, + "tests/integration/services/test_internal.py::TestInitScriptsResource::test_query_individual_stage_completed[start-True]": 0.036748376000105054, + "tests/integration/services/test_internal.py::TestInitScriptsResource::test_query_nonexisting_stage": 0.024770581000211678, + "tests/integration/services/test_internal.py::TestInitScriptsResource::test_stages_have_completed": 1.6176944450003248, + "tests/integration/test_config_endpoint.py::test_config_endpoint": 0.044313297999906354, + "tests/integration/test_config_service.py::TestConfigService::test_put_configuration_recorder": 0.2226027039996552, + "tests/integration/test_config_service.py::TestConfigService::test_put_delivery_channel": 0.2078004609998061, + "tests/integration/test_forwarder.py::test_forwarding_fallback_dispatcher": 0.00885731800008216, + "tests/integration/test_forwarder.py::test_forwarding_fallback_dispatcher_avoid_fallback": 0.005770044000200869, + "tests/integration/test_security.py::TestCSRF::test_CSRF": 0.1288371869995899, + "tests/integration/test_security.py::TestCSRF::test_additional_allowed_origins": 0.019218036000438588, + "tests/integration/test_security.py::TestCSRF::test_cors_apigw_not_applied": 0.05873192800027027, + "tests/integration/test_security.py::TestCSRF::test_cors_s3_override": 0.1105007889996159, + "tests/integration/test_security.py::TestCSRF::test_default_cors_headers": 0.015081617000305414, + "tests/integration/test_security.py::TestCSRF::test_disable_cors_checks": 0.02084868500014636, + "tests/integration/test_security.py::TestCSRF::test_disable_cors_headers": 0.022774078000566078, + "tests/integration/test_security.py::TestCSRF::test_internal_route_cors_headers[/_localstack/health]": 0.01495811600034358, + "tests/integration/test_security.py::TestCSRF::test_no_cors_without_origin_header": 0.012300651000259677, + "tests/integration/test_stores.py::test_nonstandard_regions": 0.1849991590006539, + "tests/integration/utils/test_diagnose.py::test_diagnose_resource": 0.38743312299993704 } From a6ec49870a896714958b030ae44f771c37621f68 Mon Sep 17 00:00:00 2001 From: LocalStack Bot <88328844+localstack-bot@users.noreply.github.com> Date: Mon, 30 Jun 2025 08:51:11 +0200 Subject: [PATCH 66/74] Update ASF APIs (#12817) Co-authored-by: LocalStack Bot --- .../localstack/aws/api/ec2/__init__.py | 10 ++++++++++ .../aws/api/route53resolver/__init__.py | 7 +++++++ localstack-core/localstack/aws/api/s3/__init__.py | 3 +++ .../localstack/aws/api/s3control/__init__.py | 15 +++++++++++++-- .../localstack/aws/api/transcribe/__init__.py | 1 + pyproject.toml | 4 ++-- requirements-base-runtime.txt | 4 ++-- requirements-dev.txt | 6 +++--- requirements-runtime.txt | 6 +++--- requirements-test.txt | 6 +++--- requirements-typehint.txt | 6 +++--- 11 files changed, 50 insertions(+), 18 deletions(-) diff --git a/localstack-core/localstack/aws/api/ec2/__init__.py b/localstack-core/localstack/aws/api/ec2/__init__.py index 6940b26e626b5..148985a2a48e5 100644 --- a/localstack-core/localstack/aws/api/ec2/__init__.py +++ b/localstack-core/localstack/aws/api/ec2/__init__.py @@ -270,6 +270,7 @@ NeuronDeviceName = str NextToken = str NitroTpmSupportedVersionType = str +OdbNetworkArn = str OfferingId = str OutpostArn = str OutpostLagId = str @@ -5692,8 +5693,10 @@ class EbsBlockDevice(TypedDict, total=False): KmsKeyId: Optional[String] Throughput: Optional[Integer] OutpostArn: Optional[String] + AvailabilityZone: Optional[String] Encrypted: Optional[Boolean] VolumeInitializationRate: Optional[Integer] + AvailabilityZoneId: Optional[String] class BlockDeviceMapping(TypedDict, total=False): @@ -7341,6 +7344,7 @@ class CreateFpgaImageResult(TypedDict, total=False): class CreateImageRequest(ServiceRequest): TagSpecifications: Optional[TagSpecificationList] + SnapshotLocation: Optional[SnapshotLocationEnum] DryRun: Optional[Boolean] InstanceId: InstanceId Name: String @@ -8886,6 +8890,7 @@ class CreateRouteRequest(ServiceRequest): LocalGatewayId: Optional[LocalGatewayId] CarrierGatewayId: Optional[CarrierGatewayId] CoreNetworkArn: Optional[CoreNetworkArn] + OdbNetworkArn: Optional[OdbNetworkArn] DryRun: Optional[Boolean] RouteTableId: RouteTableId DestinationCidrBlock: Optional[String] @@ -9022,6 +9027,7 @@ class Route(TypedDict, total=False): State: Optional[RouteState] VpcPeeringConnectionId: Optional[String] CoreNetworkArn: Optional[CoreNetworkArn] + OdbNetworkArn: Optional[OdbNetworkArn] RouteList = List[Route] @@ -19955,6 +19961,7 @@ class ReplaceRouteRequest(ServiceRequest): LocalGatewayId: Optional[LocalGatewayId] CarrierGatewayId: Optional[CarrierGatewayId] CoreNetworkArn: Optional[CoreNetworkArn] + OdbNetworkArn: Optional[OdbNetworkArn] DryRun: Optional[Boolean] RouteTableId: RouteTableId DestinationCidrBlock: Optional[String] @@ -21608,6 +21615,7 @@ def create_image( instance_id: InstanceId, name: String, tag_specifications: TagSpecificationList | None = None, + snapshot_location: SnapshotLocationEnum | None = None, dry_run: Boolean | None = None, description: String | None = None, no_reboot: Boolean | None = None, @@ -22097,6 +22105,7 @@ def create_route( local_gateway_id: LocalGatewayId | None = None, carrier_gateway_id: CarrierGatewayId | None = None, core_network_arn: CoreNetworkArn | None = None, + odb_network_arn: OdbNetworkArn | None = None, dry_run: Boolean | None = None, destination_cidr_block: String | None = None, gateway_id: RouteGatewayId | None = None, @@ -28503,6 +28512,7 @@ def replace_route( local_gateway_id: LocalGatewayId | None = None, carrier_gateway_id: CarrierGatewayId | None = None, core_network_arn: CoreNetworkArn | None = None, + odb_network_arn: OdbNetworkArn | None = None, dry_run: Boolean | None = None, destination_cidr_block: String | None = None, gateway_id: RouteGatewayId | None = None, diff --git a/localstack-core/localstack/aws/api/route53resolver/__init__.py b/localstack-core/localstack/aws/api/route53resolver/__init__.py index 29bb80aa29a4b..35e718630ef4b 100644 --- a/localstack-core/localstack/aws/api/route53resolver/__init__.py +++ b/localstack-core/localstack/aws/api/route53resolver/__init__.py @@ -10,6 +10,7 @@ Boolean = bool Count = int CreatorRequestId = str +DelegationRecord = str DestinationArn = str DomainListFileUrl = str DomainName = str @@ -139,6 +140,7 @@ class IpAddressStatus(StrEnum): DELETE_FAILED_FAS_EXPIRED = "DELETE_FAILED_FAS_EXPIRED" UPDATING = "UPDATING" UPDATE_FAILED = "UPDATE_FAILED" + ISOLATED = "ISOLATED" class MutationProtectionStatus(StrEnum): @@ -183,6 +185,7 @@ class ResolverDNSSECValidationStatus(StrEnum): class ResolverEndpointDirection(StrEnum): INBOUND = "INBOUND" OUTBOUND = "OUTBOUND" + INBOUND_DELEGATION = "INBOUND_DELEGATION" class ResolverEndpointStatus(StrEnum): @@ -241,6 +244,7 @@ class RuleTypeOption(StrEnum): FORWARD = "FORWARD" SYSTEM = "SYSTEM" RECURSIVE = "RECURSIVE" + DELEGATE = "DELEGATE" class ShareStatus(StrEnum): @@ -667,6 +671,7 @@ class CreateResolverRuleRequest(ServiceRequest): TargetIps: Optional[TargetList] ResolverEndpointId: Optional[ResourceId] Tags: Optional[TagList] + DelegationRecord: Optional[DelegationRecord] class ResolverRule(TypedDict, total=False): @@ -684,6 +689,7 @@ class ResolverRule(TypedDict, total=False): ShareStatus: Optional[ShareStatus] CreationTime: Optional[Rfc3339TimeString] ModificationTime: Optional[Rfc3339TimeString] + DelegationRecord: Optional[DelegationRecord] class CreateResolverRuleResponse(TypedDict, total=False): @@ -1520,6 +1526,7 @@ def create_resolver_rule( target_ips: TargetList | None = None, resolver_endpoint_id: ResourceId | None = None, tags: TagList | None = None, + delegation_record: DelegationRecord | None = None, **kwargs, ) -> CreateResolverRuleResponse: raise NotImplementedError diff --git a/localstack-core/localstack/aws/api/s3/__init__.py b/localstack-core/localstack/aws/api/s3/__init__.py index 07f26771311af..29ff70b4c8088 100644 --- a/localstack-core/localstack/aws/api/s3/__init__.py +++ b/localstack-core/localstack/aws/api/s3/__init__.py @@ -495,6 +495,7 @@ class ObjectStorageClass(StrEnum): GLACIER_IR = "GLACIER_IR" SNOW = "SNOW" EXPRESS_ONEZONE = "EXPRESS_ONEZONE" + FSX_OPENZFS = "FSX_OPENZFS" class ObjectVersionStorageClass(StrEnum): @@ -574,6 +575,7 @@ class RestoreRequestType(StrEnum): class ServerSideEncryption(StrEnum): AES256 = "AES256" + aws_fsx = "aws:fsx" aws_kms = "aws:kms" aws_kms_dsse = "aws:kms:dsse" @@ -600,6 +602,7 @@ class StorageClass(StrEnum): GLACIER_IR = "GLACIER_IR" SNOW = "SNOW" EXPRESS_ONEZONE = "EXPRESS_ONEZONE" + FSX_OPENZFS = "FSX_OPENZFS" class StorageClassAnalysisSchemaVersion(StrEnum): diff --git a/localstack-core/localstack/aws/api/s3control/__init__.py b/localstack-core/localstack/aws/api/s3control/__init__.py index 2f8768c4892c1..429e3219630d2 100644 --- a/localstack-core/localstack/aws/api/s3control/__init__.py +++ b/localstack-core/localstack/aws/api/s3control/__init__.py @@ -11,6 +11,7 @@ AccessGrantsLocationArn = str AccessGrantsLocationId = str AccessKeyId = str +AccessPointBucketName = str AccessPointName = str AccountId = str Alias = str @@ -25,6 +26,8 @@ ConfirmRemoveSelfBucketAccess = bool ConfirmationRequired = bool ContinuationToken = str +DataSourceId = str +DataSourceType = str Days = int DaysAfterInitiation = int DurationSeconds = int @@ -567,10 +570,12 @@ class AccessPoint(TypedDict, total=False): Name: AccessPointName NetworkOrigin: NetworkOrigin VpcConfiguration: Optional[VpcConfiguration] - Bucket: BucketName + Bucket: AccessPointBucketName AccessPointArn: Optional[S3AccessPointArn] Alias: Optional[Alias] BucketAccountId: Optional[AccountId] + DataSourceId: Optional[DataSourceId] + DataSourceType: Optional[DataSourceType] AccessPointList = List[AccessPoint] @@ -1576,7 +1581,7 @@ class GetAccessPointRequest(ServiceRequest): class GetAccessPointResult(TypedDict, total=False): Name: Optional[AccessPointName] - Bucket: Optional[BucketName] + Bucket: Optional[AccessPointBucketName] NetworkOrigin: Optional[NetworkOrigin] VpcConfiguration: Optional[VpcConfiguration] PublicAccessBlockConfiguration: Optional[PublicAccessBlockConfiguration] @@ -1585,6 +1590,8 @@ class GetAccessPointResult(TypedDict, total=False): AccessPointArn: Optional[S3AccessPointArn] Endpoints: Optional[Endpoints] BucketAccountId: Optional[AccountId] + DataSourceId: Optional[DataSourceId] + DataSourceType: Optional[DataSourceType] class GetAccessPointScopeRequest(ServiceRequest): @@ -2037,6 +2044,8 @@ class ListAccessPointsRequest(ServiceRequest): Bucket: Optional[BucketName] NextToken: Optional[NonEmptyMaxLength1024String] MaxResults: Optional[MaxResults] + DataSourceId: Optional[DataSourceId] + DataSourceType: Optional[DataSourceType] class ListAccessPointsResult(TypedDict, total=False): @@ -2920,6 +2929,8 @@ def list_access_points( bucket: BucketName | None = None, next_token: NonEmptyMaxLength1024String | None = None, max_results: MaxResults | None = None, + data_source_id: DataSourceId | None = None, + data_source_type: DataSourceType | None = None, **kwargs, ) -> ListAccessPointsResult: raise NotImplementedError diff --git a/localstack-core/localstack/aws/api/transcribe/__init__.py b/localstack-core/localstack/aws/api/transcribe/__init__.py index ac5b8cf19b94e..112611949bdcc 100644 --- a/localstack-core/localstack/aws/api/transcribe/__init__.py +++ b/localstack-core/localstack/aws/api/transcribe/__init__.py @@ -128,6 +128,7 @@ class LanguageCode(StrEnum): cs_CZ = "cs-CZ" cy_WL = "cy-WL" el_GR = "el-GR" + et_EE = "et-EE" et_ET = "et-ET" eu_ES = "eu-ES" fi_FI = "fi-FI" diff --git a/pyproject.toml b/pyproject.toml index 53ba567b75633..f623c5661b7f4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,9 +53,9 @@ Issues = "https://github.com/localstack/localstack/issues" # minimal required to actually run localstack on the host for services natively implemented in python base-runtime = [ # pinned / updated by ASF update action - "boto3==1.38.41", + "boto3==1.38.46", # pinned / updated by ASF update action - "botocore==1.38.41", + "botocore==1.38.46", "awscrt>=0.13.14,!=0.27.1", "cbor2>=5.5.0", "dnspython>=1.16.0", diff --git a/requirements-base-runtime.txt b/requirements-base-runtime.txt index 3602f2b83edf5..f5c6035f85b21 100644 --- a/requirements-base-runtime.txt +++ b/requirements-base-runtime.txt @@ -11,9 +11,9 @@ attrs==25.3.0 # referencing awscrt==0.27.4 # via localstack-core (pyproject.toml) -boto3==1.38.41 +boto3==1.38.46 # via localstack-core (pyproject.toml) -botocore==1.38.41 +botocore==1.38.46 # via # boto3 # localstack-core (pyproject.toml) diff --git a/requirements-dev.txt b/requirements-dev.txt index 461d13f1edb31..6365509657aed 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -39,17 +39,17 @@ aws-sam-translator==1.99.0 # localstack-core aws-xray-sdk==2.14.0 # via moto-ext -awscli==1.40.40 +awscli==1.40.45 # via localstack-core awscrt==0.27.4 # via localstack-core -boto3==1.38.41 +boto3==1.38.46 # via # aws-sam-translator # kclpy-ext # localstack-core # moto-ext -botocore==1.38.41 +botocore==1.38.46 # via # aws-xray-sdk # awscli diff --git a/requirements-runtime.txt b/requirements-runtime.txt index c39cf45709156..47df1e25956ff 100644 --- a/requirements-runtime.txt +++ b/requirements-runtime.txt @@ -27,17 +27,17 @@ aws-sam-translator==1.99.0 # localstack-core (pyproject.toml) aws-xray-sdk==2.14.0 # via moto-ext -awscli==1.40.40 +awscli==1.40.45 # via localstack-core (pyproject.toml) awscrt==0.27.4 # via localstack-core -boto3==1.38.41 +boto3==1.38.46 # via # aws-sam-translator # kclpy-ext # localstack-core # moto-ext -botocore==1.38.41 +botocore==1.38.46 # via # aws-xray-sdk # awscli diff --git a/requirements-test.txt b/requirements-test.txt index 34aafd8ae2eae..df543ae15c040 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -39,17 +39,17 @@ aws-sam-translator==1.99.0 # localstack-core aws-xray-sdk==2.14.0 # via moto-ext -awscli==1.40.40 +awscli==1.40.45 # via localstack-core awscrt==0.27.4 # via localstack-core -boto3==1.38.41 +boto3==1.38.46 # via # aws-sam-translator # kclpy-ext # localstack-core # moto-ext -botocore==1.38.41 +botocore==1.38.46 # via # aws-xray-sdk # awscli diff --git a/requirements-typehint.txt b/requirements-typehint.txt index 784140de5f81f..48af601b8b0ff 100644 --- a/requirements-typehint.txt +++ b/requirements-typehint.txt @@ -39,11 +39,11 @@ aws-sam-translator==1.99.0 # localstack-core aws-xray-sdk==2.14.0 # via moto-ext -awscli==1.40.40 +awscli==1.40.45 # via localstack-core awscrt==0.27.4 # via localstack-core -boto3==1.38.41 +boto3==1.38.46 # via # aws-sam-translator # kclpy-ext @@ -51,7 +51,7 @@ boto3==1.38.41 # moto-ext boto3-stubs==1.38.42 # via localstack-core (pyproject.toml) -botocore==1.38.41 +botocore==1.38.46 # via # aws-xray-sdk # awscli From e854dd1950d4740f7c4dc96f98178cc701377900 Mon Sep 17 00:00:00 2001 From: Anastasia Dusak <61540676+k-a-il@users.noreply.github.com> Date: Mon, 30 Jun 2025 18:08:20 +0200 Subject: [PATCH 67/74] CI: updated owners of .test_durations file (#12820) --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index d234e770c5024..6c8bd385cf82f 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -18,7 +18,7 @@ # Git, Pipelines, GitHub config /.github @alexrashed @dfangl @dominikschubert @silv-io @k-a-il -/.test_durations @alexrashed +/.test_durations @alexrashed @silv-io @k-a-il /.git-blame-ignore-revs @alexrashed @thrau /bin/release-dev.sh @thrau @alexrashed /bin/release-helper.sh @thrau @alexrashed From 0f5ebcc9c8328c7a7791697dc193e5a34977c7cb Mon Sep 17 00:00:00 2001 From: LocalStack Bot <88328844+localstack-bot@users.noreply.github.com> Date: Tue, 1 Jul 2025 08:36:01 +0200 Subject: [PATCH 68/74] Upgrade pinned Python dependencies (#12822) Co-authored-by: LocalStack Bot --- .pre-commit-config.yaml | 2 +- requirements-dev.txt | 4 +- requirements-test.txt | 2 +- requirements-typehint.txt | 216 +++++++++++++++++++------------------- 4 files changed, 112 insertions(+), 112 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3d5de8acf3314..a64fa8cb1cadf 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,7 +3,7 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.12.0 + rev: v0.12.1 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] diff --git a/requirements-dev.txt b/requirements-dev.txt index 6365509657aed..4c524726d52a6 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -29,7 +29,7 @@ aws-cdk-asset-awscli-v1==2.2.240 # via aws-cdk-lib aws-cdk-asset-node-proxy-agent-v6==2.1.0 # via aws-cdk-lib -aws-cdk-cloud-assembly-schema==44.7.0 +aws-cdk-cloud-assembly-schema==44.8.0 # via aws-cdk-lib aws-cdk-lib==2.202.0 # via localstack-core @@ -433,7 +433,7 @@ rsa==4.7.2 # via awscli rstr==3.2.2 # via localstack-core (pyproject.toml) -ruff==0.12.0 +ruff==0.12.1 # via localstack-core (pyproject.toml) s3transfer==0.13.0 # via diff --git a/requirements-test.txt b/requirements-test.txt index df543ae15c040..1ae4d16fab64a 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -29,7 +29,7 @@ aws-cdk-asset-awscli-v1==2.2.240 # via aws-cdk-lib aws-cdk-asset-node-proxy-agent-v6==2.1.0 # via aws-cdk-lib -aws-cdk-cloud-assembly-schema==44.7.0 +aws-cdk-cloud-assembly-schema==44.8.0 # via aws-cdk-lib aws-cdk-lib==2.202.0 # via localstack-core (pyproject.toml) diff --git a/requirements-typehint.txt b/requirements-typehint.txt index 48af601b8b0ff..60d50be0621b4 100644 --- a/requirements-typehint.txt +++ b/requirements-typehint.txt @@ -29,7 +29,7 @@ aws-cdk-asset-awscli-v1==2.2.240 # via aws-cdk-lib aws-cdk-asset-node-proxy-agent-v6==2.1.0 # via aws-cdk-lib -aws-cdk-cloud-assembly-schema==44.7.0 +aws-cdk-cloud-assembly-schema==44.8.0 # via aws-cdk-lib aws-cdk-lib==2.202.0 # via localstack-core @@ -49,7 +49,7 @@ boto3==1.38.46 # kclpy-ext # localstack-core # moto-ext -boto3-stubs==1.38.42 +boto3-stubs==1.39.0 # via localstack-core (pyproject.toml) botocore==1.38.46 # via @@ -59,7 +59,7 @@ botocore==1.38.46 # localstack-core # moto-ext # s3transfer -botocore-stubs==1.38.30 +botocore-stubs==1.38.46 # via boto3-stubs build==1.2.2.post1 # via @@ -262,211 +262,211 @@ multipart==1.2.1 # via moto-ext mypy==1.16.1 # via localstack-core -mypy-boto3-acm==1.38.38 +mypy-boto3-acm==1.39.0 # via boto3-stubs -mypy-boto3-acm-pca==1.38.0 +mypy-boto3-acm-pca==1.39.0 # via boto3-stubs -mypy-boto3-amplify==1.38.30 +mypy-boto3-amplify==1.39.0 # via boto3-stubs -mypy-boto3-apigateway==1.38.36 +mypy-boto3-apigateway==1.39.0 # via boto3-stubs -mypy-boto3-apigatewayv2==1.38.36 +mypy-boto3-apigatewayv2==1.39.0 # via boto3-stubs -mypy-boto3-appconfig==1.38.7 +mypy-boto3-appconfig==1.39.0 # via boto3-stubs -mypy-boto3-appconfigdata==1.38.0 +mypy-boto3-appconfigdata==1.39.0 # via boto3-stubs -mypy-boto3-application-autoscaling==1.38.21 +mypy-boto3-application-autoscaling==1.39.0 # via boto3-stubs -mypy-boto3-appsync==1.38.33 +mypy-boto3-appsync==1.39.0 # via boto3-stubs -mypy-boto3-athena==1.38.28 +mypy-boto3-athena==1.39.0 # via boto3-stubs -mypy-boto3-autoscaling==1.38.39 +mypy-boto3-autoscaling==1.39.0 # via boto3-stubs -mypy-boto3-backup==1.38.38 +mypy-boto3-backup==1.39.0 # via boto3-stubs -mypy-boto3-batch==1.38.0 +mypy-boto3-batch==1.39.0 # via boto3-stubs -mypy-boto3-ce==1.38.33 +mypy-boto3-ce==1.39.0 # via boto3-stubs -mypy-boto3-cloudcontrol==1.38.0 +mypy-boto3-cloudcontrol==1.39.0 # via boto3-stubs -mypy-boto3-cloudformation==1.38.31 +mypy-boto3-cloudformation==1.39.0 # via boto3-stubs -mypy-boto3-cloudfront==1.38.12 +mypy-boto3-cloudfront==1.39.0 # via boto3-stubs -mypy-boto3-cloudtrail==1.38.26 +mypy-boto3-cloudtrail==1.39.0 # via boto3-stubs -mypy-boto3-cloudwatch==1.38.21 +mypy-boto3-cloudwatch==1.39.0 # via boto3-stubs -mypy-boto3-codebuild==1.38.17 +mypy-boto3-codebuild==1.39.0 # via boto3-stubs -mypy-boto3-codecommit==1.38.0 +mypy-boto3-codecommit==1.39.0 # via boto3-stubs -mypy-boto3-codeconnections==1.38.0 +mypy-boto3-codeconnections==1.39.0 # via boto3-stubs -mypy-boto3-codedeploy==1.38.0 +mypy-boto3-codedeploy==1.39.0 # via boto3-stubs -mypy-boto3-codepipeline==1.38.18 +mypy-boto3-codepipeline==1.39.0 # via boto3-stubs -mypy-boto3-codestar-connections==1.38.0 +mypy-boto3-codestar-connections==1.39.0 # via boto3-stubs -mypy-boto3-cognito-identity==1.38.0 +mypy-boto3-cognito-identity==1.39.0 # via boto3-stubs -mypy-boto3-cognito-idp==1.38.16 +mypy-boto3-cognito-idp==1.39.0 # via boto3-stubs -mypy-boto3-dms==1.38.38 +mypy-boto3-dms==1.39.0 # via boto3-stubs -mypy-boto3-docdb==1.38.0 +mypy-boto3-docdb==1.39.0 # via boto3-stubs -mypy-boto3-dynamodb==1.38.4 +mypy-boto3-dynamodb==1.39.0 # via boto3-stubs -mypy-boto3-dynamodbstreams==1.38.0 +mypy-boto3-dynamodbstreams==1.39.0 # via boto3-stubs -mypy-boto3-ec2==1.38.33 +mypy-boto3-ec2==1.39.0 # via boto3-stubs -mypy-boto3-ecr==1.38.37 +mypy-boto3-ecr==1.39.0 # via boto3-stubs -mypy-boto3-ecs==1.38.41 +mypy-boto3-ecs==1.39.0 # via boto3-stubs -mypy-boto3-efs==1.38.33 +mypy-boto3-efs==1.39.0 # via boto3-stubs -mypy-boto3-eks==1.38.35 +mypy-boto3-eks==1.39.0 # via boto3-stubs -mypy-boto3-elasticache==1.38.0 +mypy-boto3-elasticache==1.39.0 # via boto3-stubs -mypy-boto3-elasticbeanstalk==1.38.0 +mypy-boto3-elasticbeanstalk==1.39.0 # via boto3-stubs -mypy-boto3-elbv2==1.38.0 +mypy-boto3-elbv2==1.39.0 # via boto3-stubs -mypy-boto3-emr==1.38.18 +mypy-boto3-emr==1.39.0 # via boto3-stubs -mypy-boto3-emr-serverless==1.38.40 +mypy-boto3-emr-serverless==1.39.0 # via boto3-stubs -mypy-boto3-es==1.38.0 +mypy-boto3-es==1.39.0 # via boto3-stubs -mypy-boto3-events==1.38.25 +mypy-boto3-events==1.39.0 # via boto3-stubs -mypy-boto3-firehose==1.38.16 +mypy-boto3-firehose==1.39.0 # via boto3-stubs -mypy-boto3-fis==1.38.0 +mypy-boto3-fis==1.39.0 # via boto3-stubs -mypy-boto3-glacier==1.38.0 +mypy-boto3-glacier==1.39.0 # via boto3-stubs -mypy-boto3-glue==1.38.42 +mypy-boto3-glue==1.39.0 # via boto3-stubs -mypy-boto3-iam==1.38.14 +mypy-boto3-iam==1.39.0 # via boto3-stubs -mypy-boto3-identitystore==1.38.0 +mypy-boto3-identitystore==1.39.0 # via boto3-stubs -mypy-boto3-iot==1.38.0 +mypy-boto3-iot==1.39.0 # via boto3-stubs -mypy-boto3-iot-data==1.38.0 +mypy-boto3-iot-data==1.39.0 # via boto3-stubs -mypy-boto3-iotanalytics==1.38.0 +mypy-boto3-iotanalytics==1.39.0 # via boto3-stubs -mypy-boto3-iotwireless==1.38.0 +mypy-boto3-iotwireless==1.39.0 # via boto3-stubs -mypy-boto3-kafka==1.38.0 +mypy-boto3-kafka==1.39.0 # via boto3-stubs -mypy-boto3-kinesis==1.38.8 +mypy-boto3-kinesis==1.39.0 # via boto3-stubs -mypy-boto3-kinesisanalytics==1.38.0 +mypy-boto3-kinesisanalytics==1.39.0 # via boto3-stubs -mypy-boto3-kinesisanalyticsv2==1.38.0 +mypy-boto3-kinesisanalyticsv2==1.39.0 # via boto3-stubs -mypy-boto3-kms==1.38.36 +mypy-boto3-kms==1.39.0 # via boto3-stubs -mypy-boto3-lakeformation==1.38.0 +mypy-boto3-lakeformation==1.39.0 # via boto3-stubs -mypy-boto3-lambda==1.38.40 +mypy-boto3-lambda==1.39.0 # via boto3-stubs -mypy-boto3-logs==1.38.39 +mypy-boto3-logs==1.39.0 # via boto3-stubs -mypy-boto3-managedblockchain==1.38.0 +mypy-boto3-managedblockchain==1.39.0 # via boto3-stubs -mypy-boto3-mediaconvert==1.38.41 +mypy-boto3-mediaconvert==1.39.0 # via boto3-stubs -mypy-boto3-mediastore==1.38.0 +mypy-boto3-mediastore==1.39.0 # via boto3-stubs -mypy-boto3-mq==1.38.0 +mypy-boto3-mq==1.39.0 # via boto3-stubs -mypy-boto3-mwaa==1.38.26 +mypy-boto3-mwaa==1.39.0 # via boto3-stubs -mypy-boto3-neptune==1.38.18 +mypy-boto3-neptune==1.39.0 # via boto3-stubs -mypy-boto3-opensearch==1.38.0 +mypy-boto3-opensearch==1.39.0 # via boto3-stubs -mypy-boto3-organizations==1.38.38 +mypy-boto3-organizations==1.39.0 # via boto3-stubs -mypy-boto3-pi==1.38.0 +mypy-boto3-pi==1.39.0 # via boto3-stubs -mypy-boto3-pinpoint==1.38.0 +mypy-boto3-pinpoint==1.39.0 # via boto3-stubs -mypy-boto3-pipes==1.38.0 +mypy-boto3-pipes==1.39.0 # via boto3-stubs -mypy-boto3-qldb==1.38.0 +mypy-boto3-qldb==1.39.0 # via boto3-stubs -mypy-boto3-qldb-session==1.38.0 +mypy-boto3-qldb-session==1.39.0 # via boto3-stubs -mypy-boto3-rds==1.38.35 +mypy-boto3-rds==1.39.0 # via boto3-stubs -mypy-boto3-rds-data==1.38.0 +mypy-boto3-rds-data==1.39.0 # via boto3-stubs -mypy-boto3-redshift==1.38.0 +mypy-boto3-redshift==1.39.0 # via boto3-stubs -mypy-boto3-redshift-data==1.38.0 +mypy-boto3-redshift-data==1.39.0 # via boto3-stubs -mypy-boto3-resource-groups==1.38.0 +mypy-boto3-resource-groups==1.39.0 # via boto3-stubs -mypy-boto3-resourcegroupstaggingapi==1.38.0 +mypy-boto3-resourcegroupstaggingapi==1.39.0 # via boto3-stubs -mypy-boto3-route53==1.38.32 +mypy-boto3-route53==1.39.0 # via boto3-stubs -mypy-boto3-route53resolver==1.38.0 +mypy-boto3-route53resolver==1.39.0 # via boto3-stubs -mypy-boto3-s3==1.38.39 +mypy-boto3-s3==1.39.0 # via boto3-stubs -mypy-boto3-s3control==1.38.14 +mypy-boto3-s3control==1.39.0 # via boto3-stubs -mypy-boto3-sagemaker==1.38.40 +mypy-boto3-sagemaker==1.39.0 # via boto3-stubs -mypy-boto3-sagemaker-runtime==1.38.0 +mypy-boto3-sagemaker-runtime==1.39.0 # via boto3-stubs -mypy-boto3-secretsmanager==1.38.0 +mypy-boto3-secretsmanager==1.39.0 # via boto3-stubs -mypy-boto3-serverlessrepo==1.38.0 +mypy-boto3-serverlessrepo==1.39.0 # via boto3-stubs -mypy-boto3-servicediscovery==1.38.0 +mypy-boto3-servicediscovery==1.39.0 # via boto3-stubs -mypy-boto3-ses==1.38.0 +mypy-boto3-ses==1.39.0 # via boto3-stubs -mypy-boto3-sesv2==1.38.0 +mypy-boto3-sesv2==1.39.0 # via boto3-stubs -mypy-boto3-sns==1.38.0 +mypy-boto3-sns==1.39.0 # via boto3-stubs -mypy-boto3-sqs==1.38.0 +mypy-boto3-sqs==1.39.0 # via boto3-stubs -mypy-boto3-ssm==1.38.5 +mypy-boto3-ssm==1.39.0 # via boto3-stubs -mypy-boto3-sso-admin==1.38.12 +mypy-boto3-sso-admin==1.39.0 # via boto3-stubs -mypy-boto3-stepfunctions==1.38.0 +mypy-boto3-stepfunctions==1.39.0 # via boto3-stubs -mypy-boto3-sts==1.38.38 +mypy-boto3-sts==1.39.0 # via boto3-stubs -mypy-boto3-timestream-query==1.38.10 +mypy-boto3-timestream-query==1.39.0 # via boto3-stubs -mypy-boto3-timestream-write==1.38.10 +mypy-boto3-timestream-write==1.39.0 # via boto3-stubs -mypy-boto3-transcribe==1.38.30 +mypy-boto3-transcribe==1.39.0 # via boto3-stubs -mypy-boto3-verifiedpermissions==1.38.7 +mypy-boto3-verifiedpermissions==1.39.0 # via boto3-stubs -mypy-boto3-wafv2==1.38.38 +mypy-boto3-wafv2==1.39.0 # via boto3-stubs -mypy-boto3-xray==1.38.0 +mypy-boto3-xray==1.39.0 # via boto3-stubs mypy-extensions==1.1.0 # via mypy @@ -643,7 +643,7 @@ rsa==4.7.2 # via awscli rstr==3.2.2 # via localstack-core -ruff==0.12.0 +ruff==0.12.1 # via localstack-core s3transfer==0.13.0 # via @@ -675,7 +675,7 @@ typeguard==2.13.3 # aws-cdk-lib # constructs # jsii -types-awscrt==0.27.2 +types-awscrt==0.27.4 # via botocore-stubs types-s3transfer==0.13.0 # via boto3-stubs From 6a0e8ee2078f43a38b97679f1ce587a3ea49434b Mon Sep 17 00:00:00 2001 From: Simon Walker Date: Tue, 1 Jul 2025 15:36:38 +0100 Subject: [PATCH 69/74] CFn telemetry: capture actions on resources (#12798) --- .../services/cloudformation/analytics.py | 62 ++++++++++++++++++- .../engine/template_deployer.py | 32 ++++++++-- .../engine/v2/change_set_model_executor.py | 11 ++++ .../cloudformation/resource_provider.py | 18 +----- 4 files changed, 102 insertions(+), 21 deletions(-) diff --git a/localstack-core/localstack/services/cloudformation/analytics.py b/localstack-core/localstack/services/cloudformation/analytics.py index f5530e262f92e..80ec4d1960005 100644 --- a/localstack-core/localstack/services/cloudformation/analytics.py +++ b/localstack-core/localstack/services/cloudformation/analytics.py @@ -1,7 +1,67 @@ +import enum +from typing import Self + +from localstack.aws.api.cloudformation import ChangeAction from localstack.utils.analytics.metrics import LabeledCounter COUNTER_NAMESPACE = "cloudformation" +COUNTER_VERSION = 2 + + +class ActionOptions(enum.StrEnum): + """ + Available actions that can be performed on a resource. + + Must support both CFn and CloudControl. + """ + + CREATE = "create" + DELETE = "delete" + UPDATE = "update" + # for cloudcontrol + READ = "read" + LIST = "list" + + @classmethod + def from_action(cls, action: Self | str | ChangeAction) -> Self: + if isinstance(action, cls): + return action + + # only used in CFn + if isinstance(action, ChangeAction): + action = action.value + + match action: + case "Add": + return cls.CREATE + case "Modify" | "Dynamic": + return cls.UPDATE + case "Remove": + return cls.DELETE + case "Read": + return cls.READ + case "List": + return cls.LIST + case _: + available_values = [every.value for every in cls] + raise ValueError( + f"Invalid action option '{action}', should be one of {available_values}" + ) + resources = LabeledCounter( - namespace=COUNTER_NAMESPACE, name="resources", labels=["resource_type", "missing"] + namespace=COUNTER_NAMESPACE, + name="resources", + labels=["resource_type", "missing", "action"], + schema_version=COUNTER_VERSION, ) + + +def track_resource_operation( + action: ActionOptions | str, expected_resource_type: str, *, missing: bool +): + resources.labels( + resource_type=expected_resource_type, + missing=missing, + action=ActionOptions.from_action(action), + ).increment() diff --git a/localstack-core/localstack/services/cloudformation/engine/template_deployer.py b/localstack-core/localstack/services/cloudformation/engine/template_deployer.py index a0ae9c286d61c..e3a0802c54bed 100644 --- a/localstack-core/localstack/services/cloudformation/engine/template_deployer.py +++ b/localstack-core/localstack/services/cloudformation/engine/template_deployer.py @@ -11,9 +11,11 @@ from localstack import config from localstack.aws.connect import connect_to from localstack.constants import INTERNAL_AWS_SECRET_ACCESS_KEY +from localstack.services.cloudformation.analytics import track_resource_operation from localstack.services.cloudformation.deployment_utils import ( PLACEHOLDER_AWS_NO_VALUE, get_action_name_for_resource_change, + log_not_available_message, remove_none_values, ) from localstack.services.cloudformation.engine.changes import ChangeConfig, ResourceChange @@ -31,6 +33,7 @@ ) from localstack.services.cloudformation.resource_provider import ( Credentials, + NoResourceProvider, OperationStatus, ProgressEvent, ResourceProviderExecutor, @@ -1295,7 +1298,9 @@ def apply_change(self, change: ChangeConfig, stack: Stack) -> None: action, logical_resource_id=resource_id ) - resource_provider = executor.try_load_resource_provider(get_resource_type(resource)) + resource_type = get_resource_type(resource) + resource_provider = executor.try_load_resource_provider(resource_type) + track_resource_operation(action, resource_type, missing=resource_provider is None) if resource_provider is not None: # add in-progress event resource_status = f"{get_action_name_for_resource_change(action)}_IN_PROGRESS" @@ -1321,6 +1326,15 @@ def apply_change(self, change: ChangeConfig, stack: Stack) -> None: resource_provider, resource, resource_provider_payload ) else: + # track that we don't handle the resource, and possibly raise an exception + log_not_available_message( + resource_type, + f'No resource provider found for "{resource_type}"', + ) + + if not config.CFN_IGNORE_UNSUPPORTED_RESOURCE_TYPES: + raise NoResourceProvider + resource["PhysicalResourceId"] = MOCK_REFERENCE progress_event = ProgressEvent(OperationStatus.SUCCESS, resource_model={}) @@ -1419,6 +1433,7 @@ def delete_stack(self): ) for i, resource_id in enumerate(ordered_resource_ids): resource = resources[resource_id] + resource_type = get_resource_type(resource) try: # TODO: cache condition value in resource details on deployment and use cached value here if not evaluate_resource_condition( @@ -1427,23 +1442,32 @@ def delete_stack(self): ): continue + action = "Remove" executor = self.create_resource_provider_executor() resource_provider_payload = self.create_resource_provider_payload( - "Remove", logical_resource_id=resource_id + action, logical_resource_id=resource_id ) LOG.debug( 'Handling "Remove" for resource "%s" (%s/%s) type "%s"', resource_id, i + 1, len(resources), - resource["ResourceType"], + resource_type, ) - resource_provider = executor.try_load_resource_provider(get_resource_type(resource)) + resource_provider = executor.try_load_resource_provider(resource_type) + track_resource_operation(action, resource_type, missing=resource_provider is None) if resource_provider is not None: event = executor.deploy_loop( resource_provider, resource, resource_provider_payload ) else: + log_not_available_message( + resource_type, + f'No resource provider found for "{resource_type}"', + ) + + if not config.CFN_IGNORE_UNSUPPORTED_RESOURCE_TYPES: + raise NoResourceProvider event = ProgressEvent(OperationStatus.SUCCESS, resource_model={}) match event.status: case OperationStatus.SUCCESS: diff --git a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py index 99603edf027a0..9de7b296d4eb9 100644 --- a/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py +++ b/localstack-core/localstack/services/cloudformation/engine/v2/change_set_model_executor.py @@ -4,12 +4,15 @@ from dataclasses import dataclass from typing import Final, Optional +from localstack import config from localstack.aws.api.cloudformation import ( ChangeAction, ResourceStatus, StackStatus, ) from localstack.constants import INTERNAL_AWS_SECRET_ACCESS_KEY +from localstack.services.cloudformation.analytics import track_resource_operation +from localstack.services.cloudformation.deployment_utils import log_not_available_message from localstack.services.cloudformation.engine.parameters import resolve_ssm_parameter from localstack.services.cloudformation.engine.v2.change_set_model import ( NodeDependsOn, @@ -27,6 +30,7 @@ ) from localstack.services.cloudformation.resource_provider import ( Credentials, + NoResourceProvider, OperationStatus, ProgressEvent, ResourceProviderExecutor, @@ -350,6 +354,13 @@ def _execute_resource_action( after_properties=after_properties, ) resource_provider = resource_provider_executor.try_load_resource_provider(resource_type) + track_resource_operation(action, resource_type, missing=resource_provider is not None) + log_not_available_message( + resource_type, + f'No resource provider found for "{resource_type}"', + ) + if resource_provider is None and not config.CFN_IGNORE_UNSUPPORTED_RESOURCE_TYPES: + raise NoResourceProvider extra_resource_properties = {} event = ProgressEvent(OperationStatus.SUCCESS, resource_model={}) diff --git a/localstack-core/localstack/services/cloudformation/resource_provider.py b/localstack-core/localstack/services/cloudformation/resource_provider.py index 31ac0938712bb..421ad8ecd2b30 100644 --- a/localstack-core/localstack/services/cloudformation/resource_provider.py +++ b/localstack-core/localstack/services/cloudformation/resource_provider.py @@ -19,13 +19,11 @@ from localstack import config from localstack.aws.connect import InternalClientFactory, ServiceLevelClientFactory -from localstack.services.cloudformation import analytics from localstack.services.cloudformation.deployment_utils import ( check_not_found_exception, convert_data_types, fix_account_id_in_arns, fix_boto_parameters_based_on_report, - log_not_available_message, remove_none_values, ) from localstack.services.cloudformation.engine.quirks import PHYSICAL_RESOURCE_ID_SPECIAL_CASES @@ -581,7 +579,6 @@ def try_load_resource_provider(resource_type: str) -> ResourceProvider | None: # 2. try to load community resource provider try: plugin = plugin_manager.load(resource_type) - analytics.resources.labels(resource_type=resource_type, missing=False).increment() return plugin.factory() except ValueError: # could not find a plugin for that name @@ -594,19 +591,8 @@ def try_load_resource_provider(resource_type: str) -> ResourceProvider | None: exc_info=LOG.isEnabledFor(logging.DEBUG), ) - # 3. we could not find the resource provider so log the missing resource provider - log_not_available_message( - resource_type, - f'No resource provider found for "{resource_type}"', - ) - - analytics.resources.labels(resource_type=resource_type, missing=True).increment() - - if config.CFN_IGNORE_UNSUPPORTED_RESOURCE_TYPES: - # TODO: figure out a better way to handle non-implemented here? - return None - else: - raise NoResourceProvider + # we could not find the resource provider + return None def extract_physical_resource_id_from_model_with_schema( self, resource_model: Properties, resource_type: str, resource_type_schema: dict From 7fd523cb2534262f5c89bb14ab6159333eaa8b86 Mon Sep 17 00:00:00 2001 From: Daniel Fangl Date: Tue, 1 Jul 2025 17:09:41 +0200 Subject: [PATCH 70/74] Update STS session storage model to be more flexible (#12793) --- .../localstack/services/sts/models.py | 6 ++++-- .../localstack/services/sts/provider.py | 19 ++++++++++--------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/localstack-core/localstack/services/sts/models.py b/localstack-core/localstack/services/sts/models.py index 67a8665dbb76f..de28b1e723647 100644 --- a/localstack-core/localstack/services/sts/models.py +++ b/localstack-core/localstack/services/sts/models.py @@ -4,16 +4,18 @@ from localstack.services.stores import AccountRegionBundle, BaseStore, CrossRegionAttribute -class SessionTaggingConfig(TypedDict): +class SessionConfig(TypedDict): # => {"Key": , "Value": } tags: dict[str, Tag] # list of lowercase transitive tag keys transitive_tags: list[str] + # other stored context variables + iam_context: dict[str, str | list[str]] class STSStore(BaseStore): # maps access key ids to tagging config for the session they belong to - session_tags: dict[str, SessionTaggingConfig] = CrossRegionAttribute(default=dict) + sessions: dict[str, SessionConfig] = CrossRegionAttribute(default=dict) sts_stores = AccountRegionBundle("sts", STSStore) diff --git a/localstack-core/localstack/services/sts/provider.py b/localstack-core/localstack/services/sts/provider.py index 14807869ea9cb..b53e7b0a1684e 100644 --- a/localstack-core/localstack/services/sts/provider.py +++ b/localstack-core/localstack/services/sts/provider.py @@ -21,7 +21,7 @@ from localstack.services.iam.iam_patches import apply_iam_patches from localstack.services.moto import call_moto from localstack.services.plugins import ServiceLifecycleHook -from localstack.services.sts.models import SessionTaggingConfig, sts_stores +from localstack.services.sts.models import SessionConfig, sts_stores from localstack.utils.aws.arns import extract_account_id_from_arn from localstack.utils.aws.request_context import extract_access_key_id_from_auth_header @@ -64,7 +64,7 @@ def assume_role( target_account_id = extract_account_id_from_arn(role_arn) access_key_id = extract_access_key_id_from_auth_header(context.request.headers) store = sts_stores[target_account_id]["us-east-1"] - existing_tagging_config = store.session_tags.get(access_key_id, {}) + existing_session_config = store.sessions.get(access_key_id, {}) if tags: tag_keys = {tag["Key"].lower() for tag in tags} @@ -75,8 +75,8 @@ def assume_role( ) # prevent transitive tags from being overridden - if existing_tagging_config: - if set(existing_tagging_config["transitive_tags"]).intersection(tag_keys): + if existing_session_config: + if set(existing_session_config["transitive_tags"]).intersection(tag_keys): raise InvalidParameterValueError( "One of the specified transitive tag keys can't be set because it conflicts with a transitive tag key from the calling session." ) @@ -93,15 +93,16 @@ def assume_role( tags = tags or [] transformed_tags = {tag["Key"].lower(): tag for tag in tags} # propagate transitive tags - if existing_tagging_config: - for tag in existing_tagging_config["transitive_tags"]: - transformed_tags[tag] = existing_tagging_config["tags"][tag] - transitive_tag_keys += existing_tagging_config["transitive_tags"] + if existing_session_config: + for tag in existing_session_config["transitive_tags"]: + transformed_tags[tag] = existing_session_config["tags"][tag] + transitive_tag_keys += existing_session_config["transitive_tags"] if transformed_tags: # store session tagging config access_key_id = response["Credentials"]["AccessKeyId"] - store.session_tags[access_key_id] = SessionTaggingConfig( + store.sessions[access_key_id] = SessionConfig( tags=transformed_tags, transitive_tags=[key.lower() for key in transitive_tag_keys], + iam_context={}, ) return response From 518c2fe7f237819509c002b5db53c2ba1d63da26 Mon Sep 17 00:00:00 2001 From: Arthur Akhadov <48313237+ArthurAkh@users.noreply.github.com> Date: Tue, 1 Jul 2025 21:42:23 +0200 Subject: [PATCH 71/74] APIGW: implement UpdateMethodResponse and tests for MethodResponse (#12821) --- .../services/apigateway/legacy/provider.py | 98 ++- .../apigateway/test_apigateway_api.py | 596 ++++++++++++++++++ .../test_apigateway_api.snapshot.json | 312 +++++++++ .../test_apigateway_api.validation.json | 54 ++ 4 files changed, 1053 insertions(+), 7 deletions(-) diff --git a/localstack-core/localstack/services/apigateway/legacy/provider.py b/localstack-core/localstack/services/apigateway/legacy/provider.py index f8e1c3b3d141c..e2a8774b02923 100644 --- a/localstack-core/localstack/services/apigateway/legacy/provider.py +++ b/localstack-core/localstack/services/apigateway/legacy/provider.py @@ -93,7 +93,7 @@ VpcLinks, ) from localstack.aws.connect import connect_to -from localstack.aws.forwarder import NotImplementedAvoidFallbackError, create_aws_request_context +from localstack.aws.forwarder import create_aws_request_context from localstack.constants import APPLICATION_JSON from localstack.services.apigateway.exporter import OpenApiExporter from localstack.services.apigateway.helpers import ( @@ -985,13 +985,98 @@ def get_method_response( method_response = moto_method_response.to_json() return method_response - @handler("UpdateMethodResponse", expand=False) + @handler("UpdateMethodResponse") def update_method_response( - self, context: RequestContext, request: TestInvokeMethodRequest + self, + context: RequestContext, + rest_api_id: String, + resource_id: String, + http_method: String, + status_code: StatusCode, + patch_operations: ListOfPatchOperation | None = None, + **kwargs, ) -> MethodResponse: - # this operation is not implemented by moto, but raises a 500 error (instead of a 501). - # avoid a fallback to moto and return the 501 to the client directly instead. - raise NotImplementedAvoidFallbackError + error_messages = [] + for index, operation in enumerate(patch_operations): + op = operation.get("op") + if op not in VALID_PATCH_OPERATIONS: + error_messages.append( + f"Value '{op}' at 'updateMethodResponseInput.patchOperations.{index + 1}.member.op' " + f"failed to satisfy constraint: Member must satisfy enum value set: [{', '.join(VALID_PATCH_OPERATIONS)}]" + ) + + if not re.fullmatch(r"[1-5]\d\d", status_code): + error_messages.append( + f"Value '{status_code}' at 'statusCode' failed to satisfy constraint: " + "Member must satisfy regular expression pattern: [1-5]\\d\\d" + ) + + if error_messages: + prefix = f"{len(error_messages)} validation error{'s' if len(error_messages) > 1 else ''} detected: " + raise CommonServiceException( + code="ValidationException", + message=prefix + "; ".join(error_messages), + ) + + moto_rest_api = get_moto_rest_api(context, rest_api_id) + moto_resource = moto_rest_api.resources.get(resource_id) + if not moto_resource: + raise NotFoundException("Invalid Resource identifier specified") + + moto_method = moto_resource.resource_methods.get(http_method) + if not moto_method: + raise NotFoundException("Invalid Method identifier specified") + + method_response = moto_method.method_responses.get(status_code) + if not method_response: + raise NotFoundException("Invalid Response status code specified") + + if method_response.response_models is None: + method_response.response_models = {} + if method_response.response_parameters is None: + method_response.response_parameters = {} + + for patch_operation in patch_operations: + op = patch_operation["op"] + path = patch_operation["path"] + value = patch_operation.get("value") + + if path.startswith("/responseParameters/"): + param_name = path.removeprefix("/responseParameters/") + if param_name not in method_response.response_parameters and op in ( + "replace", + "remove", + ): + raise NotFoundException("Invalid parameter name specified") + if op in ("add", "replace"): + method_response.response_parameters[param_name] = value == "true" + elif op == "remove": + method_response.response_parameters.pop(param_name) + + elif path.startswith("/responseModels/"): + param_name = path.removeprefix("/responseModels/") + param_name = param_name.replace("~1", "/") + if param_name not in method_response.response_models and op in ( + "replace", + "remove", + ): + raise NotFoundException("Content-Type specified was not found") + if op in ("add", "replace"): + method_response.response_models[param_name] = value + elif op == "remove": + method_response.response_models.pop(param_name) + else: + raise BadRequestException(f"Invalid patch path {path}") + + response: MethodResponse = method_response.to_json() + + # AWS doesn't send back empty responseParameters or responseModels + if not method_response.response_parameters: + response.pop("responseParameters") + if not method_response.response_models: + response.pop("responseModels") + + return response # stages @@ -2089,7 +2174,6 @@ def get_integration_response( # TODO: fix upstream if ( "selectionPattern" not in response - and integration_response and integration_response.selection_pattern is not None ): response["selectionPattern"] = integration_response.selection_pattern diff --git a/tests/aws/services/apigateway/test_apigateway_api.py b/tests/aws/services/apigateway/test_apigateway_api.py index ca64cf8169b03..70d17804488b1 100644 --- a/tests/aws/services/apigateway/test_apigateway_api.py +++ b/tests/aws/services/apigateway/test_apigateway_api.py @@ -2921,3 +2921,599 @@ def test_lifecycle_integration_response(self, aws_client, apigw_create_rest_api, statusCode="200", ) snapshot.match("delete-integration-response", delete_response) + + @markers.aws.validated + def test_update_method_wrong_param_names(self, aws_client, apigw_create_rest_api, snapshot): + snapshot.add_transformer(snapshot.transform.key_value("cacheNamespace")) + apigw_client = aws_client.apigateway + response = apigw_create_rest_api(name=f"test-api-{short_uid()}") + api_id = response["id"] + root_resource_id = response["rootResourceId"] + + apigw_client.put_method( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + authorizationType="NONE", + ) + apigw_client.put_integration( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + type="MOCK", + requestTemplates={"application/json": '{"statusCode": 200}'}, + ) + + apigw_client.put_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + responseParameters={"method.response.header.my-header": False}, + responseModels={"application/json": "Empty"}, + ) + + with pytest.raises(ClientError) as e: + apigw_client.update_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + patchOperations=[ + { + "op": "replace", + "path": "/responseParameters/wrong", + "value": "true", + }, + ], + ) + snapshot.match("update-method-response-operation-with-wrong-param-name-1", e.value.response) + + with pytest.raises(ClientError) as e: + apigw_client.update_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + patchOperations=[ + { + "op": "remove", + "path": "/responseParameters/wrong", + "value": "true", + }, + ], + ) + snapshot.match("update-method-response-operation-with-wrong-param-name-2", e.value.response) + + with pytest.raises(ClientError) as e: + apigw_client.update_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + patchOperations=[ + { + "op": "replace", + "path": "/responseModels/wrong", + "value": "Empty", + }, + ], + ) + snapshot.match("update-method-response-operation-with-wrong-param-name-3", e.value.response) + + with pytest.raises(ClientError) as e: + apigw_client.update_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + patchOperations=[ + { + "op": "remove", + "path": "/responseModels/wrong", + "value": "Empty", + }, + ], + ) + snapshot.match("update-method-response-operation-with-wrong-param-name-4", e.value.response) + + @markers.aws.validated + def test_update_method_lack_response_parameters_and_models( + self, aws_client, apigw_create_rest_api, snapshot + ): + snapshot.add_transformer(snapshot.transform.key_value("cacheNamespace")) + apigw_client = aws_client.apigateway + response = apigw_create_rest_api(name=f"test-api-{short_uid()}") + api_id = response["id"] + root_resource_id = response["rootResourceId"] + + apigw_client.put_method( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + authorizationType="NONE", + ) + apigw_client.put_integration( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + type="MOCK", + requestTemplates={"application/json": '{"statusCode": 200}'}, + ) + + apigw_client.put_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + ) + + with pytest.raises(ClientError) as e: + apigw_client.update_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + patchOperations=[ + { + "op": "remove", + "path": "/responseParameters/method.response.header.my-header", + "value": "true", + }, + ], + ) + snapshot.match( + "update-method-response-operation-without-response-parameters", e.value.response + ) + + with pytest.raises(ClientError) as e: + apigw_client.update_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + patchOperations=[ + { + "op": "remove", + "path": "/responseModels/application~1json", + "value": "Empty", + }, + ], + ) + snapshot.match("update-method-response-operation-without-response-models", e.value.response) + + with pytest.raises(ClientError) as e: + apigw_client.update_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + patchOperations=[ + { + "op": "remove", + "path": "/wrong/method.response.header.my-header", + "value": "true", + }, + ], + ) + snapshot.match("update-method-response-operation-with-wrong-path", e.value.response) + + @markers.aws.validated + def test_update_method_response_negative_tests( + self, aws_client, apigw_create_rest_api, snapshot + ): + snapshot.add_transformer(snapshot.transform.key_value("cacheNamespace")) + apigw_client = aws_client.apigateway + response = apigw_create_rest_api(name=f"test-api-{short_uid()}") + api_id = response["id"] + root_resource_id = response["rootResourceId"] + + apigw_client.put_method( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + authorizationType="NONE", + ) + apigw_client.put_integration( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + type="MOCK", + requestTemplates={"application/json": '{"statusCode": 200}'}, + ) + + apigw_client.put_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + responseParameters={"method.response.header.my-header": False}, + responseModels={"application/json": "Empty"}, + ) + + with pytest.raises(ClientError) as e: + apigw_client.update_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="201", + patchOperations=[ + { + "op": "replace", + "path": "/responseParameters/method.response.header.my-header", + "value": "true", + }, + ], + ) + snapshot.match("update-method-response-wrong-statuscode", e.value.response) + + with pytest.raises(ClientError) as e: + apigw_client.update_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="wrong", + patchOperations=[ + { + "op": "replace", + "path": "/responseParameters/method.response.header.my-header", + "value": "true", + }, + ], + ) + snapshot.match("update-method-response-invalid-statuscode", e.value.response) + + with pytest.raises(ClientError) as e: + apigw_client.update_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="wrong", + patchOperations=[ + { + "op": "wrong_op", + "path": "/responseParameters/method.response.header.my-header", + "value": "true", + }, + ], + ) + snapshot.match("update-method-response-invalid-statuscode-and-wrong-op", e.value.response) + + with pytest.raises(ClientError) as e: + apigw_client.update_method_response( + restApiId=api_id, + resourceId="wrong", + httpMethod="GET", + statusCode="200", + patchOperations=[ + { + "op": "replace", + "path": "/responseParameters/method.response.header.my-header", + "value": "true", + }, + ], + ) + snapshot.match("update-method-response-wrong-resource", e.value.response) + + with pytest.raises(ClientError) as e: + apigw_client.update_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="POST", + statusCode="200", + patchOperations=[ + { + "op": "replace", + "path": "/responseParameters/method.response.header.my-header", + "value": "true", + }, + ], + ) + snapshot.match("update-method-response-wrong-method", e.value.response) + + @markers.aws.validated + def test_update_method_response_wrong_operations( + self, aws_client, apigw_create_rest_api, snapshot + ): + snapshot.add_transformer(snapshot.transform.key_value("cacheNamespace")) + apigw_client = aws_client.apigateway + response = apigw_create_rest_api(name=f"test-api-{short_uid()}") + api_id = response["id"] + root_resource_id = response["rootResourceId"] + + apigw_client.put_method( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + authorizationType="NONE", + ) + apigw_client.put_integration( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + type="MOCK", + requestTemplates={"application/json": '{"statusCode": 200}'}, + ) + apigw_client.put_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + responseParameters={"method.response.header.my-header": False}, + responseModels={"application/json": "Empty"}, + ) + + with pytest.raises(ClientError) as e: + apigw_client.update_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + patchOperations=[ + { + "op": "wrong_op", + "path": "/responseParameters/method.response.header.my-header", + "value": "true", + }, + ], + ) + snapshot.match("update-method-response-wrong-operation-1", e.value.response) + + with pytest.raises(ClientError) as e: + apigw_client.update_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + patchOperations=[ + { + "op": "wrong_op", + "path": "/responseModels/application~1json", + "value": "Empty", + }, + ], + ) + snapshot.match("update-method-response-wrong-operation-2", e.value.response) + + with pytest.raises(ClientError) as e: + apigw_client.update_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + patchOperations=[ + { + "op": "wrong_op", + "path": "/responseParameters/method.response.header.my-header", + "value": "true", + }, + { + "op": "wrong_op", + "path": "/responseModels/application~1json", + "value": "Empty", + }, + ], + ) + snapshot.match("update-method-response-wrong-operation-3", e.value.response) + + with pytest.raises(ClientError) as e: + apigw_client.update_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + patchOperations=[ + { + "op": "wrong_op", + "path": "/responseParameters/method.response.header.my-header", + "value": "true", + }, + { + "op": "wrong_op", + "path": "/responseModels/application~1json", + "value": "Empty", + }, + { + "op": "wrong_op", + "path": "/responseParameters/method.response.header.my-header", + "value": "true", + }, + { + "op": "wrong_op", + "path": "/responseModels/application~1json", + "value": "Empty", + }, + ], + ) + snapshot.match("update-method-response-wrong-operation-4", e.value.response) + + with pytest.raises(ClientError) as e: + apigw_client.update_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + patchOperations=[ + { + "op": "wrong_op", + "path": "/responseParameters/method.response.header.my-header", + "value": "true", + }, + { + "op": "remove", + "path": "/responseModels/application~1json", + "value": "Empty", + }, + { + "op": "wrong_op", + "path": "/responseModels/application~1json", + "value": "Empty", + }, + ], + ) + snapshot.match("update-method-response-wrong-operation-5", e.value.response) + + @markers.aws.validated + def test_update_method_response(self, aws_client, apigw_create_rest_api, snapshot): + snapshot.add_transformer(snapshot.transform.key_value("cacheNamespace")) + apigw_client = aws_client.apigateway + response = apigw_create_rest_api(name=f"test-api-{short_uid()}") + api_id = response["id"] + root_resource_id = response["rootResourceId"] + + apigw_client.put_method( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + authorizationType="NONE", + ) + apigw_client.put_integration( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + type="MOCK", + requestTemplates={"application/json": '{"statusCode": 200}'}, + ) + apigw_client.put_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + responseParameters={"method.response.header.my-header": False}, + responseModels={"application/json": "Empty"}, + ) + + remove_update_response = apigw_client.update_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + patchOperations=[ + { + "op": "remove", + "path": "/responseParameters/method.response.header.my-header", + "value": "true", + }, + { + "op": "remove", + "path": "/responseModels/application~1json", + "value": "Empty", + }, + ], + ) + snapshot.match("remove-update-method-response", remove_update_response) + + add_update_response = apigw_client.update_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + patchOperations=[ + { + "op": "add", + "path": "/responseParameters/method.response.header.my-header", + "value": "true", + }, + { + "op": "add", + "path": "/responseModels/application~1json", + "value": "Empty", + }, + ], + ) + snapshot.match("add-update-method-response", add_update_response) + + @markers.aws.validated + def test_lifecycle_method_response(self, aws_client, apigw_create_rest_api, snapshot): + snapshot.add_transformer(snapshot.transform.key_value("cacheNamespace")) + apigw_client = aws_client.apigateway + response = apigw_create_rest_api(name=f"test-api-{short_uid()}") + api_id = response["id"] + root_resource_id = response["rootResourceId"] + + apigw_client.put_method( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + authorizationType="NONE", + ) + apigw_client.put_integration( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + type="MOCK", + requestTemplates={"application/json": '{"statusCode": 200}'}, + ) + + put_method_response = apigw_client.put_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + responseParameters={}, + responseModels={}, + ) + snapshot.match("put-method-response", put_method_response) + + get_response = apigw_client.get_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + ) + snapshot.match("get-integration-response", get_response) + + add_responses = apigw_client.update_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + patchOperations=[ + { + "op": "add", + "path": "/responseParameters/method.response.header.my-header", + "value": "true", + }, + { + "op": "add", + "path": "/responseModels/application~1json", + "value": "Empty", + }, + ], + ) + snapshot.match("add-method-responses", add_responses) + + update_responses = apigw_client.update_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + patchOperations=[ + { + "op": "replace", + "path": "/responseParameters/method.response.header.my-header", + "value": "true", + }, + { + "op": "replace", + "path": "/responseModels/application~1json", + "value": "Empty", + }, + ], + ) + snapshot.match("update-method-responses", update_responses) + + get_method = apigw_client.get_method( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + ) + snapshot.match("get-method", get_method) + + delete_response = apigw_client.delete_method_response( + restApiId=api_id, + resourceId=root_resource_id, + httpMethod="GET", + statusCode="200", + ) + snapshot.match("delete-method-response", delete_response) diff --git a/tests/aws/services/apigateway/test_apigateway_api.snapshot.json b/tests/aws/services/apigateway/test_apigateway_api.snapshot.json index 4b03f9f2baffe..e02f5cc8d6147 100644 --- a/tests/aws/services/apigateway/test_apigateway_api.snapshot.json +++ b/tests/aws/services/apigateway/test_apigateway_api.snapshot.json @@ -3878,5 +3878,317 @@ } } } + }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_lifecycle_method_response": { + "recorded-date": "01-07-2025, 15:48:02", + "recorded-content": { + "put-method-response": { + "responseModels": {}, + "responseParameters": {}, + "statusCode": "200", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 201 + } + }, + "get-integration-response": { + "responseModels": {}, + "responseParameters": {}, + "statusCode": "200", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "add-method-responses": { + "responseModels": { + "application/json": "Empty" + }, + "responseParameters": { + "method.response.header.my-header": true + }, + "statusCode": "200", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 201 + } + }, + "update-method-responses": { + "responseModels": { + "application/json": "Empty" + }, + "responseParameters": { + "method.response.header.my-header": true + }, + "statusCode": "200", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 201 + } + }, + "get-method": { + "apiKeyRequired": false, + "authorizationType": "NONE", + "httpMethod": "GET", + "methodIntegration": { + "cacheKeyParameters": [], + "cacheNamespace": "", + "passthroughBehavior": "WHEN_NO_MATCH", + "requestTemplates": { + "application/json": { + "statusCode": 200 + } + }, + "timeoutInMillis": 29000, + "type": "MOCK" + }, + "methodResponses": { + "200": { + "responseModels": { + "application/json": "Empty" + }, + "responseParameters": { + "method.response.header.my-header": true + }, + "statusCode": "200" + } + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "delete-method-response": { + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 204 + } + } + } + }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_update_method_response": { + "recorded-date": "30-06-2025, 12:42:31", + "recorded-content": { + "remove-update-method-response": { + "statusCode": "200", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 201 + } + }, + "add-update-method-response": { + "responseModels": { + "application/json": "Empty" + }, + "responseParameters": { + "method.response.header.my-header": true + }, + "statusCode": "200", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 201 + } + } + } + }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_update_method_response_wrong_operations": { + "recorded-date": "30-06-2025, 13:54:57", + "recorded-content": { + "update-method-response-wrong-operation-1": { + "Error": { + "Code": "ValidationException", + "Message": "1 validation error detected: Value 'wrong_op' at 'updateMethodResponseInput.patchOperations.1.member.op' failed to satisfy constraint: Member must satisfy enum value set: [add, remove, move, test, replace, copy]" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 400 + } + }, + "update-method-response-wrong-operation-2": { + "Error": { + "Code": "ValidationException", + "Message": "1 validation error detected: Value 'wrong_op' at 'updateMethodResponseInput.patchOperations.1.member.op' failed to satisfy constraint: Member must satisfy enum value set: [add, remove, move, test, replace, copy]" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 400 + } + }, + "update-method-response-wrong-operation-3": { + "Error": { + "Code": "ValidationException", + "Message": "2 validation errors detected: Value 'wrong_op' at 'updateMethodResponseInput.patchOperations.1.member.op' failed to satisfy constraint: Member must satisfy enum value set: [add, remove, move, test, replace, copy]; Value 'wrong_op' at 'updateMethodResponseInput.patchOperations.2.member.op' failed to satisfy constraint: Member must satisfy enum value set: [add, remove, move, test, replace, copy]" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 400 + } + }, + "update-method-response-wrong-operation-4": { + "Error": { + "Code": "ValidationException", + "Message": "4 validation errors detected: Value 'wrong_op' at 'updateMethodResponseInput.patchOperations.1.member.op' failed to satisfy constraint: Member must satisfy enum value set: [add, remove, move, test, replace, copy]; Value 'wrong_op' at 'updateMethodResponseInput.patchOperations.2.member.op' failed to satisfy constraint: Member must satisfy enum value set: [add, remove, move, test, replace, copy]; Value 'wrong_op' at 'updateMethodResponseInput.patchOperations.3.member.op' failed to satisfy constraint: Member must satisfy enum value set: [add, remove, move, test, replace, copy]; Value 'wrong_op' at 'updateMethodResponseInput.patchOperations.4.member.op' failed to satisfy constraint: Member must satisfy enum value set: [add, remove, move, test, replace, copy]" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 400 + } + }, + "update-method-response-wrong-operation-5": { + "Error": { + "Code": "ValidationException", + "Message": "2 validation errors detected: Value 'wrong_op' at 'updateMethodResponseInput.patchOperations.1.member.op' failed to satisfy constraint: Member must satisfy enum value set: [add, remove, move, test, replace, copy]; Value 'wrong_op' at 'updateMethodResponseInput.patchOperations.3.member.op' failed to satisfy constraint: Member must satisfy enum value set: [add, remove, move, test, replace, copy]" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 400 + } + } + } + }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_update_method_response_negative_tests": { + "recorded-date": "30-06-2025, 15:24:43", + "recorded-content": { + "update-method-response-wrong-statuscode": { + "Error": { + "Code": "NotFoundException", + "Message": "Invalid Response status code specified" + }, + "message": "Invalid Response status code specified", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 404 + } + }, + "update-method-response-invalid-statuscode": { + "Error": { + "Code": "ValidationException", + "Message": "1 validation error detected: Value 'wrong' at 'statusCode' failed to satisfy constraint: Member must satisfy regular expression pattern: [1-5]\\d\\d" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 400 + } + }, + "update-method-response-invalid-statuscode-and-wrong-op": { + "Error": { + "Code": "ValidationException", + "Message": "2 validation errors detected: Value 'wrong_op' at 'updateMethodResponseInput.patchOperations.1.member.op' failed to satisfy constraint: Member must satisfy enum value set: [add, remove, move, test, replace, copy]; Value 'wrong' at 'statusCode' failed to satisfy constraint: Member must satisfy regular expression pattern: [1-5]\\d\\d" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 400 + } + }, + "update-method-response-wrong-resource": { + "Error": { + "Code": "NotFoundException", + "Message": "Invalid Resource identifier specified" + }, + "message": "Invalid Resource identifier specified", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 404 + } + }, + "update-method-response-wrong-method": { + "Error": { + "Code": "NotFoundException", + "Message": "Invalid Method identifier specified" + }, + "message": "Invalid Method identifier specified", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 404 + } + } + } + }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_update_method_lack_response_parameters_and_models": { + "recorded-date": "01-07-2025, 15:48:38", + "recorded-content": { + "update-method-response-operation-without-response-parameters": { + "Error": { + "Code": "NotFoundException", + "Message": "Invalid parameter name specified" + }, + "message": "Invalid parameter name specified", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 404 + } + }, + "update-method-response-operation-without-response-models": { + "Error": { + "Code": "NotFoundException", + "Message": "Content-Type specified was not found" + }, + "message": "Content-Type specified was not found", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 404 + } + }, + "update-method-response-operation-with-wrong-path": { + "Error": { + "Code": "BadRequestException", + "Message": "Invalid patch path /wrong/method.response.header.my-header" + }, + "message": "Invalid patch path /wrong/method.response.header.my-header", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 400 + } + } + } + }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_update_method_wrong_param_names": { + "recorded-date": "01-07-2025, 15:49:16", + "recorded-content": { + "update-method-response-operation-with-wrong-param-name-1": { + "Error": { + "Code": "NotFoundException", + "Message": "Invalid parameter name specified" + }, + "message": "Invalid parameter name specified", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 404 + } + }, + "update-method-response-operation-with-wrong-param-name-2": { + "Error": { + "Code": "NotFoundException", + "Message": "Invalid parameter name specified" + }, + "message": "Invalid parameter name specified", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 404 + } + }, + "update-method-response-operation-with-wrong-param-name-3": { + "Error": { + "Code": "NotFoundException", + "Message": "Content-Type specified was not found" + }, + "message": "Content-Type specified was not found", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 404 + } + }, + "update-method-response-operation-with-wrong-param-name-4": { + "Error": { + "Code": "NotFoundException", + "Message": "Content-Type specified was not found" + }, + "message": "Content-Type specified was not found", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 404 + } + } + } } } diff --git a/tests/aws/services/apigateway/test_apigateway_api.validation.json b/tests/aws/services/apigateway/test_apigateway_api.validation.json index 3bb989388a4a6..1b2ac789947a5 100644 --- a/tests/aws/services/apigateway/test_apigateway_api.validation.json +++ b/tests/aws/services/apigateway/test_apigateway_api.validation.json @@ -203,6 +203,15 @@ "total": 4.21 } }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_lifecycle_method_response": { + "last_validated_date": "2025-07-01T15:48:02+00:00", + "durations_in_seconds": { + "setup": 1.38, + "call": 2.76, + "teardown": 0.41, + "total": 4.55 + } + }, "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_put_integration_request_parameter_bool_type": { "last_validated_date": "2024-12-12T10:46:41+00:00" }, @@ -212,6 +221,51 @@ "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_put_integration_wrong_type": { "last_validated_date": "2024-04-15T20:48:47+00:00" }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_update_method_lack_response_parameters_and_models": { + "last_validated_date": "2025-07-01T15:48:38+00:00", + "durations_in_seconds": { + "setup": 1.4, + "call": 1.95, + "teardown": 0.42, + "total": 3.77 + } + }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_update_method_response": { + "last_validated_date": "2025-06-30T12:42:31+00:00", + "durations_in_seconds": { + "setup": 1.26, + "call": 1.63, + "teardown": 0.35, + "total": 3.24 + } + }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_update_method_response_negative_tests": { + "last_validated_date": "2025-06-30T15:24:43+00:00", + "durations_in_seconds": { + "setup": 1.53, + "call": 2.45, + "teardown": 0.43, + "total": 4.41 + } + }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_update_method_response_wrong_operations": { + "last_validated_date": "2025-06-30T13:54:57+00:00", + "durations_in_seconds": { + "setup": 1.36, + "call": 2.35, + "teardown": 0.42, + "total": 4.13 + } + }, + "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayIntegration::test_update_method_wrong_param_names": { + "last_validated_date": "2025-07-01T15:49:16+00:00", + "durations_in_seconds": { + "setup": 1.44, + "call": 2.13, + "teardown": 0.41, + "total": 3.98 + } + }, "tests/aws/services/apigateway/test_apigateway_api.py::TestApigatewayTestInvoke::test_invoke_test_method": { "last_validated_date": "2024-04-15T20:48:35+00:00" } From fdef9934c4dc94bf5f43ec6dabacddc136d3e7bb Mon Sep 17 00:00:00 2001 From: Mathieu Cloutier <79954947+cloutierMat@users.noreply.github.com> Date: Wed, 2 Jul 2025 01:10:46 -0600 Subject: [PATCH 72/74] removed create appsync fixtures (#12572) --- .../localstack/testing/pytest/fixtures.py | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/localstack-core/localstack/testing/pytest/fixtures.py b/localstack-core/localstack/testing/pytest/fixtures.py index 5c282ea8fcbc5..77beed14d280c 100644 --- a/localstack-core/localstack/testing/pytest/fixtures.py +++ b/localstack-core/localstack/testing/pytest/fixtures.py @@ -2191,29 +2191,6 @@ def _create_apigateway_function(**kwargs): apigateway_client.delete_rest_api(restApiId=rest_api_id) -@pytest.fixture -def appsync_create_api(aws_client): - graphql_apis = [] - - def factory(**kwargs): - if "name" not in kwargs: - kwargs["name"] = f"graphql-api-testing-name-{short_uid()}" - if not kwargs.get("authenticationType"): - kwargs["authenticationType"] = "API_KEY" - - result = aws_client.appsync.create_graphql_api(**kwargs)["graphqlApi"] - graphql_apis.append(result["apiId"]) - return result - - yield factory - - for api in graphql_apis: - try: - aws_client.appsync.delete_graphql_api(apiId=api) - except Exception as e: - LOG.debug("Error cleaning up AppSync API: %s, %s", api, e) - - @pytest.fixture def assert_host_customisation(monkeypatch): localstack_host = "foo.bar" From 583b6200ba1dccf44da474ed49549b63e86b0ec3 Mon Sep 17 00:00:00 2001 From: Daniel Fangl Date: Wed, 2 Jul 2025 13:11:50 +0200 Subject: [PATCH 73/74] IAM: Fix listing roles with tags (#12825) --- .../localstack/services/iam/provider.py | 6 +- tests/aws/services/iam/test_iam.py | 36 +++++++ tests/aws/services/iam/test_iam.snapshot.json | 98 +++++++++++++++++++ .../aws/services/iam/test_iam.validation.json | 9 ++ 4 files changed, 146 insertions(+), 3 deletions(-) diff --git a/localstack-core/localstack/services/iam/provider.py b/localstack-core/localstack/services/iam/provider.py index ef640fbc9c051..9ea97b5ec8a63 100644 --- a/localstack-core/localstack/services/iam/provider.py +++ b/localstack-core/localstack/services/iam/provider.py @@ -53,7 +53,6 @@ ServiceSpecificCredentialMetadata, SimulatePolicyResponse, SimulationPolicyListType, - Tag, User, arnType, customSuffixType, @@ -278,7 +277,7 @@ def moto_role_to_role_type(moto_role: MotoRole) -> Role: if moto_role.permissions_boundary: role["PermissionsBoundary"] = moto_role.permissions_boundary if moto_role.tags: - role["Tags"] = [Tag(Key=k, Value=v) for k, v in moto_role.tags.items()] + role["Tags"] = moto_role.tags # role["RoleLastUsed"]: # TODO: add support return role @@ -299,8 +298,9 @@ def list_roles( response_roles = [] for moto_role in moto_roles: response_role = self.moto_role_to_role_type(moto_role) - # Permission boundary should not be a part of the response + # Permission boundary and Tags should not be a part of the response response_role.pop("PermissionsBoundary", None) + response_role.pop("Tags", None) response_roles.append(response_role) if path_prefix: # TODO: this is consistent with the patch it migrates, but should add tests for this. response_role["AssumeRolePolicyDocument"] = quote( diff --git a/tests/aws/services/iam/test_iam.py b/tests/aws/services/iam/test_iam.py index ef10f0165416b..9fe79e743661c 100755 --- a/tests/aws/services/iam/test_iam.py +++ b/tests/aws/services/iam/test_iam.py @@ -1477,3 +1477,39 @@ def test_service_role_already_exists(self, aws_client, snapshot, create_service_ with pytest.raises(ClientError) as e: aws_client.iam.create_service_linked_role(AWSServiceName=service_name) snapshot.match("role-already-exists-error", e.value.response) + + +class TestRoles: + @pytest.fixture(autouse=True) + def snapshot_transformers(self, snapshot): + snapshot.add_transformer(snapshot.transform.iam_api()) + + @markers.aws.validated + def test_role_with_tags(self, aws_client, account_id, create_role, snapshot): + role_name = f"role-{short_uid()}" + path = "/role-with-tags/" + trust_policy = { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": {"Service": "ec2.amazonaws.com"}, + "Action": "sts:AssumeRole", + } + ], + } + tags = [{"Key": "test", "Value": "value"}] + + create_role_response = create_role( + RoleName=role_name, + AssumeRolePolicyDocument=json.dumps(trust_policy), + Tags=tags, + Path=path, + ) + snapshot.match("create-role-response", create_role_response) + + get_role_response = aws_client.iam.get_role(RoleName=role_name) + snapshot.match("get-role-response", get_role_response) + + list_role_response = aws_client.iam.list_roles(PathPrefix=path) + snapshot.match("list-role-response", list_role_response) diff --git a/tests/aws/services/iam/test_iam.snapshot.json b/tests/aws/services/iam/test_iam.snapshot.json index 6e37bcdd431cf..80eba4371a21a 100644 --- a/tests/aws/services/iam/test_iam.snapshot.json +++ b/tests/aws/services/iam/test_iam.snapshot.json @@ -6475,5 +6475,103 @@ } } } + }, + "tests/aws/services/iam/test_iam.py::TestRoles::test_role_with_tags": { + "recorded-date": "02-07-2025, 09:40:33", + "recorded-content": { + "create-role-response": { + "Role": { + "Arn": "arn::iam::111111111111:role/role-with-tags/", + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ec2.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "CreateDate": "", + "Path": "/role-with-tags/", + "RoleId": "", + "RoleName": "", + "Tags": [ + { + "Key": "test", + "Value": "value" + } + ] + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "get-role-response": { + "Role": { + "Arn": "arn::iam::111111111111:role/role-with-tags/", + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ec2.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "CreateDate": "", + "MaxSessionDuration": 3600, + "Path": "/role-with-tags/", + "RoleId": "", + "RoleLastUsed": {}, + "RoleName": "", + "Tags": [ + { + "Key": "test", + "Value": "value" + } + ] + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "list-role-response": { + "IsTruncated": false, + "Roles": [ + { + "Arn": "arn::iam::111111111111:role/role-with-tags/", + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ec2.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "CreateDate": "", + "MaxSessionDuration": 3600, + "Path": "/role-with-tags/", + "RoleId": "", + "RoleName": "" + } + ], + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } } } diff --git a/tests/aws/services/iam/test_iam.validation.json b/tests/aws/services/iam/test_iam.validation.json index 41312b6a29073..e4ba6fcc28cc4 100644 --- a/tests/aws/services/iam/test_iam.validation.json +++ b/tests/aws/services/iam/test_iam.validation.json @@ -556,5 +556,14 @@ }, "tests/aws/services/iam/test_iam.py::TestIAMServiceSpecificCredentials::test_user_match_id_mismatch[totally-wrong-credential-id-with-hyphens]": { "last_validated_date": "2025-03-06T16:58:44+00:00" + }, + "tests/aws/services/iam/test_iam.py::TestRoles::test_role_with_tags": { + "last_validated_date": "2025-07-02T09:40:33+00:00", + "durations_in_seconds": { + "setup": 1.44, + "call": 1.03, + "teardown": 0.59, + "total": 3.06 + } } } From fcdc53cd97582127411f0f45fbee7abdfae7dba2 Mon Sep 17 00:00:00 2001 From: "localstack[bot]" Date: Thu, 3 Jul 2025 06:16:07 +0000 Subject: [PATCH 74/74] release version 4.6.0