diff --git a/integration/combination/test_api_with_gateway_responses.py b/integration/combination/test_api_with_gateway_responses.py index 39979e016..b3e101bd2 100644 --- a/integration/combination/test_api_with_gateway_responses.py +++ b/integration/combination/test_api_with_gateway_responses.py @@ -1,6 +1,7 @@ import logging from unittest.case import skipIf +import pytest from tenacity import stop_after_attempt, retry_if_exception_type, after_log, wait_exponential, retry, wait_random from integration.helpers.base_test import BaseTest @@ -14,6 +15,7 @@ current_region_does_not_support([GATEWAY_RESPONSES]), "GatewayResponses is not supported in this testing region" ) class TestApiWithGatewayResponses(BaseTest): + @pytest.mark.flaky(reruns=5) def test_gateway_responses(self): self.create_and_verify_stack("combination/api_with_gateway_responses") @@ -45,7 +47,7 @@ def test_gateway_responses(self): reraise=True, ) def _verify_request_response_and_cors(self, url, expected_response): - response = self.verify_get_request_response(url, expected_response) + response = self.verify_get_request_response(url, expected_response, "AWS::ApiGateway::RestApi") access_control_allow_origin = response.headers.get("Access-Control-Allow-Origin", "") self.assertEqual(access_control_allow_origin, "*", "Access-Control-Allow-Origin must be '*'") diff --git a/integration/combination/test_function_with_http_api.py b/integration/combination/test_function_with_http_api.py index 337edc429..faec5ba6f 100644 --- a/integration/combination/test_function_with_http_api.py +++ b/integration/combination/test_function_with_http_api.py @@ -1,17 +1,24 @@ +import logging from unittest.case import skipIf +import pytest + from integration.helpers.base_test import BaseTest from integration.helpers.resource import current_region_does_not_support from integration.config.service_names import HTTP_API +LOG = logging.getLogger(__name__) + @skipIf(current_region_does_not_support([HTTP_API]), "HttpApi is not supported in this testing region") class TestFunctionWithHttpApi(BaseTest): + @pytest.mark.flaky(reruns=5) def test_function_with_http_api(self): self.create_and_verify_stack("combination/function_with_http_api") stack_outputs = self.get_stack_outputs() base_url = stack_outputs["ApiUrl"] - self.verify_get_request_response(base_url + "some/path", 200) - self.verify_get_request_response(base_url + "something", 404) - self.verify_get_request_response(base_url + "another/endpoint", 404) + resource_type = "AWS::ApiGatewayV2::Api" + self.verify_get_request_response(base_url + "some/path", 200, resource_type) + self.verify_get_request_response(base_url + "something", 404, resource_type) + self.verify_get_request_response(base_url + "another/endpoint", 404, resource_type) diff --git a/integration/helpers/deployer/deployer.py b/integration/helpers/deployer/deployer.py index 63d16cacd..ffaf6c12c 100644 --- a/integration/helpers/deployer/deployer.py +++ b/integration/helpers/deployer/deployer.py @@ -26,18 +26,18 @@ # - Moved DeployColor to colors.py # - Removed unnecessary functions from artifact_exporter import sys -import math from collections import OrderedDict import logging import time from datetime import datetime + from integration.helpers.resource import generate_suffix import botocore from integration.helpers.deployer.utils.colors import DeployColor from integration.helpers.deployer.exceptions import exceptions as deploy_exceptions -from integration.helpers.deployer.utils.retry import retry, retry_with_exponential_backoff_and_jitter +from integration.helpers.deployer.utils.retry import retry_with_exponential_backoff_and_jitter from integration.helpers.deployer.utils.table_print import ( pprint_column_names, pprint_columns, @@ -307,75 +307,6 @@ def get_last_event_time(self, stack_name): except KeyError: return time.time() - @pprint_column_names( - format_string=DESCRIBE_STACK_EVENTS_FORMAT_STRING, - format_kwargs=DESCRIBE_STACK_EVENTS_DEFAULT_ARGS, - table_header=DESCRIBE_STACK_EVENTS_TABLE_HEADER_NAME, - ) - def describe_stack_events(self, stack_name, time_stamp_marker, **kwargs): - """ - Calls CloudFormation to get current stack events - :param stack_name: Name or ID of the stack - :param time_stamp_marker: last event time on the stack to start streaming events from. - :return: - """ - - stack_change_in_progress = True - events = set() - retry_attempts = 0 - - while stack_change_in_progress and retry_attempts <= self.max_attempts: - try: - - # Only sleep if there have been no retry_attempts - time.sleep(self.client_sleep if retry_attempts == 0 else 0) - describe_stacks_resp = self._client.describe_stacks(StackName=stack_name) - paginator = self._client.get_paginator("describe_stack_events") - response_iterator = paginator.paginate(StackName=stack_name) - stack_status = describe_stacks_resp["Stacks"][0]["StackStatus"] - latest_time_stamp_marker = time_stamp_marker - for event_items in response_iterator: - for event in event_items["StackEvents"]: - if event["EventId"] not in events and utc_to_timestamp(event["Timestamp"]) > time_stamp_marker: - events.add(event["EventId"]) - latest_time_stamp_marker = max( - latest_time_stamp_marker, utc_to_timestamp(event["Timestamp"]) - ) - row_color = self.deploy_color.get_stack_events_status_color(status=event["ResourceStatus"]) - pprint_columns( - columns=[ - event["ResourceStatus"], - event["ResourceType"], - event["LogicalResourceId"], - event.get("ResourceStatusReason", "-"), - ], - width=kwargs["width"], - margin=kwargs["margin"], - format_string=DESCRIBE_STACK_EVENTS_FORMAT_STRING, - format_args=kwargs["format_args"], - columns_dict=DESCRIBE_STACK_EVENTS_DEFAULT_ARGS.copy(), - color=row_color, - ) - # Skip already shown old event entries - elif utc_to_timestamp(event["Timestamp"]) <= time_stamp_marker: - time_stamp_marker = latest_time_stamp_marker - break - else: # go to next loop if not break from inside loop - time_stamp_marker = latest_time_stamp_marker # update marker if all events are new - continue - break # reached here only if break from inner loop! - - if self._check_stack_complete(stack_status): - stack_change_in_progress = False - break - except botocore.exceptions.ClientError as ex: - retry_attempts = retry_attempts + 1 - if retry_attempts > self.max_attempts: - LOG.error("Describing stack events for %s failed: %s", stack_name, str(ex)) - return - # Sleep in exponential backoff mode - time.sleep(math.pow(self.backoff, retry_attempts)) - def _check_stack_complete(self, status): return "COMPLETE" in status and "CLEANUP" not in status @@ -386,8 +317,6 @@ def wait_for_execute(self, stack_name, changeset_type): ) sys.stdout.flush() - self.describe_stack_events(stack_name, self.get_last_event_time(stack_name)) - # Pick the right waiter if changeset_type == "CREATE": waiter = self._client.get_waiter("stack_create_complete") diff --git a/integration/single/test_basic_function.py b/integration/single/test_basic_function.py index 112e2043f..a80226c0f 100644 --- a/integration/single/test_basic_function.py +++ b/integration/single/test_basic_function.py @@ -1,11 +1,15 @@ +import logging from unittest.case import skipIf -from integration.config.service_names import KMS, XRAY, ARM, CODE_DEPLOY, HTTP_API +import pytest +from integration.config.service_names import KMS, XRAY, ARM, CODE_DEPLOY, HTTP_API from integration.helpers.resource import current_region_does_not_support from parameterized import parameterized from integration.helpers.base_test import BaseTest +LOG = logging.getLogger(__name__) + class TestBasicFunction(BaseTest): """ @@ -36,6 +40,7 @@ def test_basic_function(self, file_name): "single/function_alias_with_http_api_events", ] ) + @pytest.mark.flaky(reruns=5) @skipIf(current_region_does_not_support([HTTP_API]), "HTTP API is not supported in this testing region") def test_function_with_http_api_events(self, file_name): self.create_and_verify_stack(file_name)