diff --git a/.github/workflows/run-e2e-tests.yml b/.github/workflows/run-e2e-tests.yml index 06196b97f92..7a8fb00ebbe 100644 --- a/.github/workflows/run-e2e-tests.yml +++ b/.github/workflows/run-e2e-tests.yml @@ -26,6 +26,7 @@ jobs: id-token: write # needed to request JWT with GitHub's OIDC Token endpoint. docs: https://bit.ly/3MNgQO9 contents: read strategy: + fail-fast: false # needed so if a version fails, the others will still be able to complete and cleanup matrix: version: ["3.7", "3.8", "3.9"] if: ${{ github.actor != 'dependabot[bot]' }} diff --git a/parallel_run_e2e.py b/parallel_run_e2e.py index be3e1ab0cf8..1146f66931e 100755 --- a/parallel_run_e2e.py +++ b/parallel_run_e2e.py @@ -8,7 +8,7 @@ def main(): features = Path("tests/e2e").rglob("infrastructure.py") workers = len(list(features)) - 1 - command = f"poetry run pytest -n {workers} --dist loadfile -o log_cli=true tests/e2e" + command = f"poetry run pytest -n {workers} -o log_cli=true tests/e2e" result = subprocess.run(command.split(), shell=False) sys.exit(result.returncode) diff --git a/tests/e2e/event_handler/conftest.py b/tests/e2e/event_handler/conftest.py index 43941946ac7..664c870e1de 100644 --- a/tests/e2e/event_handler/conftest.py +++ b/tests/e2e/event_handler/conftest.py @@ -3,7 +3,7 @@ from tests.e2e.event_handler.infrastructure import EventHandlerStack -@pytest.fixture(autouse=True, scope="module") +@pytest.fixture(autouse=True, scope="package") def infrastructure(): """Setup and teardown logic for E2E test infrastructure diff --git a/tests/e2e/event_handler/test_header_serializer.py b/tests/e2e/event_handler/test_header_serializer.py index eedb69ccaad..5026bf6aa4a 100644 --- a/tests/e2e/event_handler/test_header_serializer.py +++ b/tests/e2e/event_handler/test_header_serializer.py @@ -36,6 +36,7 @@ def lambda_function_url_endpoint(infrastructure: dict) -> str: return infrastructure.get("LambdaFunctionUrl", "") +@pytest.mark.xdist_group(name="event_handler") def test_alb_headers_serializer(alb_basic_listener_endpoint): # GIVEN url = f"{alb_basic_listener_endpoint}/todos" @@ -74,6 +75,7 @@ def test_alb_headers_serializer(alb_basic_listener_endpoint): assert response.cookies.get(last_cookie.name) == last_cookie.value +@pytest.mark.xdist_group(name="event_handler") def test_alb_multi_value_headers_serializer(alb_multi_value_header_listener_endpoint): # GIVEN url = f"{alb_multi_value_header_listener_endpoint}/todos" @@ -112,6 +114,7 @@ def test_alb_multi_value_headers_serializer(alb_multi_value_header_listener_endp assert response.cookies.get(cookie.name) == cookie.value +@pytest.mark.xdist_group(name="event_handler") def test_api_gateway_rest_headers_serializer(apigw_rest_endpoint): # GIVEN url = f"{apigw_rest_endpoint}todos" @@ -147,6 +150,7 @@ def test_api_gateway_rest_headers_serializer(apigw_rest_endpoint): assert response.cookies.get(cookie.name) == cookie.value +@pytest.mark.xdist_group(name="event_handler") def test_api_gateway_http_headers_serializer(apigw_http_endpoint): # GIVEN url = f"{apigw_http_endpoint}todos" @@ -182,6 +186,7 @@ def test_api_gateway_http_headers_serializer(apigw_http_endpoint): assert response.cookies.get(cookie.name) == cookie.value +@pytest.mark.xdist_group(name="event_handler") def test_lambda_function_url_headers_serializer(lambda_function_url_endpoint): # GIVEN url = f"{lambda_function_url_endpoint}todos" # the function url endpoint already has the trailing / diff --git a/tests/e2e/event_handler/test_paths_ending_with_slash.py b/tests/e2e/event_handler/test_paths_ending_with_slash.py index 4c1461d6fc5..1944768c2ff 100644 --- a/tests/e2e/event_handler/test_paths_ending_with_slash.py +++ b/tests/e2e/event_handler/test_paths_ending_with_slash.py @@ -33,6 +33,7 @@ def lambda_function_url_endpoint(infrastructure: dict) -> str: return infrastructure.get("LambdaFunctionUrl", "") +@pytest.mark.xdist_group(name="event_handler") def test_api_gateway_rest_trailing_slash(apigw_rest_endpoint): # GIVEN API URL ends in a trailing slash url = f"{apigw_rest_endpoint}todos/" @@ -51,6 +52,7 @@ def test_api_gateway_rest_trailing_slash(apigw_rest_endpoint): assert response.status_code == 200 +@pytest.mark.xdist_group(name="event_handler") def test_api_gateway_http_trailing_slash(apigw_http_endpoint): # GIVEN the URL for the API ends in a trailing slash API gateway should return a 404 url = f"{apigw_http_endpoint}todos/" @@ -67,6 +69,7 @@ def test_api_gateway_http_trailing_slash(apigw_http_endpoint): ) +@pytest.mark.xdist_group(name="event_handler") def test_lambda_function_url_trailing_slash(lambda_function_url_endpoint): # GIVEN the URL for the API ends in a trailing slash it should behave as if there was not one url = f"{lambda_function_url_endpoint}todos/" # the function url endpoint already has the trailing / @@ -83,6 +86,7 @@ def test_lambda_function_url_trailing_slash(lambda_function_url_endpoint): ) +@pytest.mark.xdist_group(name="event_handler") def test_alb_url_trailing_slash(alb_multi_value_header_listener_endpoint): # GIVEN url has a trailing slash - it should behave as if there was not one url = f"{alb_multi_value_header_listener_endpoint}/todos/" diff --git a/tests/e2e/idempotency/conftest.py b/tests/e2e/idempotency/conftest.py index 24a7c71c1f2..61578d904a6 100644 --- a/tests/e2e/idempotency/conftest.py +++ b/tests/e2e/idempotency/conftest.py @@ -3,8 +3,8 @@ from tests.e2e.idempotency.infrastructure import IdempotencyDynamoDBStack -@pytest.fixture(autouse=True, scope="module") -def infrastructure(tmp_path_factory, worker_id): +@pytest.fixture(autouse=True, scope="package") +def infrastructure(): """Setup and teardown logic for E2E test infrastructure Yields diff --git a/tests/e2e/idempotency/test_idempotency_dynamodb.py b/tests/e2e/idempotency/test_idempotency_dynamodb.py index 87b61d285ec..d3452a1a161 100644 --- a/tests/e2e/idempotency/test_idempotency_dynamodb.py +++ b/tests/e2e/idempotency/test_idempotency_dynamodb.py @@ -27,6 +27,7 @@ def idempotency_table_name(infrastructure: dict) -> str: return infrastructure.get("DynamoDBTable", "") +@pytest.mark.xdist_group(name="idempotency") def test_ttl_caching_expiration_idempotency(ttl_cache_expiration_handler_fn_arn: str): # GIVEN payload = json.dumps({"message": "Lambda Powertools - TTL 5s"}) @@ -56,6 +57,7 @@ def test_ttl_caching_expiration_idempotency(ttl_cache_expiration_handler_fn_arn: assert third_execution_response != second_execution_response +@pytest.mark.xdist_group(name="idempotency") def test_ttl_caching_timeout_idempotency(ttl_cache_timeout_handler_fn_arn: str): # GIVEN payload_timeout_execution = json.dumps({"sleep": 5, "message": "Lambda Powertools - TTL 1s"}) @@ -79,6 +81,7 @@ def test_ttl_caching_timeout_idempotency(ttl_cache_timeout_handler_fn_arn: str): assert payload_working_execution == execution_working_response +@pytest.mark.xdist_group(name="idempotency") def test_parallel_execution_idempotency(parallel_execution_handler_fn_arn: str): # GIVEN arguments = json.dumps({"message": "Lambda Powertools - Parallel execution"}) diff --git a/tests/e2e/logger/conftest.py b/tests/e2e/logger/conftest.py index a31be77031b..ad336931a93 100644 --- a/tests/e2e/logger/conftest.py +++ b/tests/e2e/logger/conftest.py @@ -3,8 +3,8 @@ from tests.e2e.logger.infrastructure import LoggerStack -@pytest.fixture(autouse=True, scope="module") -def infrastructure(tmp_path_factory, worker_id): +@pytest.fixture(autouse=True, scope="package") +def infrastructure(): """Setup and teardown logic for E2E test infrastructure Yields diff --git a/tests/e2e/logger/test_logger.py b/tests/e2e/logger/test_logger.py index e5c27dd0a8f..28ee9c0aac0 100644 --- a/tests/e2e/logger/test_logger.py +++ b/tests/e2e/logger/test_logger.py @@ -17,6 +17,7 @@ def basic_handler_fn_arn(infrastructure: dict) -> str: return infrastructure.get("BasicHandlerArn", "") +@pytest.mark.xdist_group(name="logger") def test_basic_lambda_logs_visible(basic_handler_fn, basic_handler_fn_arn): # GIVEN message = "logs should be visible with default settings" diff --git a/tests/e2e/metrics/conftest.py b/tests/e2e/metrics/conftest.py index 2f72e7950be..197aaff847f 100644 --- a/tests/e2e/metrics/conftest.py +++ b/tests/e2e/metrics/conftest.py @@ -3,8 +3,8 @@ from tests.e2e.metrics.infrastructure import MetricsStack -@pytest.fixture(autouse=True, scope="module") -def infrastructure(tmp_path_factory, worker_id): +@pytest.fixture(autouse=True, scope="package") +def infrastructure(): """Setup and teardown logic for E2E test infrastructure Yields diff --git a/tests/e2e/metrics/test_metrics.py b/tests/e2e/metrics/test_metrics.py index 516f93ac1f0..192cbcc25af 100644 --- a/tests/e2e/metrics/test_metrics.py +++ b/tests/e2e/metrics/test_metrics.py @@ -28,6 +28,7 @@ def cold_start_fn_arn(infrastructure: dict) -> str: METRIC_NAMESPACE = "powertools-e2e-metric" +@pytest.mark.xdist_group(name="metrics") def test_basic_lambda_metric_is_visible(basic_handler_fn: str, basic_handler_fn_arn: str): # GIVEN metric_name = data_builder.build_metric_name() @@ -47,6 +48,7 @@ def test_basic_lambda_metric_is_visible(basic_handler_fn: str, basic_handler_fn_ assert metric_values == [3.0] +@pytest.mark.xdist_group(name="metrics") def test_cold_start_metric(cold_start_fn_arn: str, cold_start_fn: str): # GIVEN metric_name = "ColdStart" diff --git a/tests/e2e/parameters/conftest.py b/tests/e2e/parameters/conftest.py index f4c9d7396dd..99146607384 100644 --- a/tests/e2e/parameters/conftest.py +++ b/tests/e2e/parameters/conftest.py @@ -3,8 +3,8 @@ from tests.e2e.parameters.infrastructure import ParametersStack -@pytest.fixture(autouse=True, scope="module") -def infrastructure(tmp_path_factory, worker_id): +@pytest.fixture(autouse=True, scope="package") +def infrastructure(): """Setup and teardown logic for E2E test infrastructure Yields diff --git a/tests/e2e/parameters/infrastructure.py b/tests/e2e/parameters/infrastructure.py index e2cd5101ba7..018fceab2aa 100644 --- a/tests/e2e/parameters/infrastructure.py +++ b/tests/e2e/parameters/infrastructure.py @@ -27,7 +27,7 @@ def create_resources(self): iam.PolicyStatement( effect=iam.Effect.ALLOW, actions=[ - "ssm:GetParameter", + "ssm:GetParameters", ], resources=[f"arn:aws:ssm:{self.region}:{self.account_id}:parameter/powertools/e2e/parameters/*"], ) diff --git a/tests/e2e/parameters/test_appconfig.py b/tests/e2e/parameters/test_appconfig.py index 0129adb1515..7cf6f87067f 100644 --- a/tests/e2e/parameters/test_appconfig.py +++ b/tests/e2e/parameters/test_appconfig.py @@ -35,6 +35,7 @@ def parameter_appconfig_freeform_profile(infrastructure: dict) -> str: return infrastructure.get("AppConfigProfile", "") +@pytest.mark.xdist_group(name="parameters") def test_get_parameter_appconfig_freeform( parameter_appconfig_freeform_handler_fn_arn: str, parameter_appconfig_freeform_value: str, diff --git a/tests/e2e/parameters/test_ssm.py b/tests/e2e/parameters/test_ssm.py index 7e9614f8ea0..239813fab51 100644 --- a/tests/e2e/parameters/test_ssm.py +++ b/tests/e2e/parameters/test_ssm.py @@ -17,7 +17,7 @@ def parameters_list(infrastructure: dict) -> List[str]: return json.loads(param_list) -# +@pytest.mark.xdist_group(name="parameters") def test_get_parameters_by_name( ssm_get_parameters_by_name_fn_arn: str, parameters_list: str, diff --git a/tests/e2e/pytest.ini b/tests/e2e/pytest.ini new file mode 100644 index 00000000000..3fc35fa5847 --- /dev/null +++ b/tests/e2e/pytest.ini @@ -0,0 +1,2 @@ +[pytest] +addopts = -ra -vv --dist loadgroup \ No newline at end of file diff --git a/tests/e2e/streaming/conftest.py b/tests/e2e/streaming/conftest.py index c3a44365d39..94f7f212af0 100644 --- a/tests/e2e/streaming/conftest.py +++ b/tests/e2e/streaming/conftest.py @@ -3,8 +3,8 @@ from tests.e2e.streaming.infrastructure import StreamingStack -@pytest.fixture(autouse=True, scope="module") -def infrastructure(tmp_path_factory, worker_id): +@pytest.fixture(autouse=True, scope="package") +def infrastructure(): """Setup and teardown logic for E2E test infrastructure Yields diff --git a/tests/e2e/streaming/test_s3_object.py b/tests/e2e/streaming/test_s3_object.py index 1e2fe1a0222..fe4fd638b10 100644 --- a/tests/e2e/streaming/test_s3_object.py +++ b/tests/e2e/streaming/test_s3_object.py @@ -21,6 +21,7 @@ def s3_object_handler_fn_arn(infrastructure: dict) -> str: return infrastructure.get("S3ObjectHandler", "") +@pytest.mark.xdist_group(name="streaming") def get_object_version(bucket, key) -> str: s3 = boto3.client("s3") versions = s3.list_object_versions(Bucket=bucket) @@ -43,6 +44,7 @@ def get_lambda_result_payload(s3_object_handler_fn_arn: str, payload: dict) -> d return json.loads(handler_result["Payload"].read()) +@pytest.mark.xdist_group(name="streaming") def test_s3_object_size(s3_object_handler_fn_arn, regular_bucket_name): payload = {"bucket": regular_bucket_name, "key": "plain.txt"} result = get_lambda_result_payload(s3_object_handler_fn_arn, payload) @@ -50,6 +52,7 @@ def test_s3_object_size(s3_object_handler_fn_arn, regular_bucket_name): assert result.get("body") == "hello world" +@pytest.mark.xdist_group(name="streaming") def test_s3_versioned_object_size(s3_object_handler_fn_arn, versioned_bucket_name): key = "plain.txt" payload = { @@ -62,18 +65,21 @@ def test_s3_versioned_object_size(s3_object_handler_fn_arn, versioned_bucket_nam assert result.get("body") == "hello world" +@pytest.mark.xdist_group(name="streaming") def test_s3_object_non_existent(s3_object_handler_fn_arn, regular_bucket_name): payload = {"bucket": regular_bucket_name, "key": "NOTEXISTENT.txt"} result = get_lambda_result_payload(s3_object_handler_fn_arn, payload) assert result.get("error") == "Not found" +@pytest.mark.xdist_group(name="streaming") def test_s3_object_csv_constructor(s3_object_handler_fn_arn, regular_bucket_name): payload = {"bucket": regular_bucket_name, "key": "csv.txt", "is_csv": True} result = get_lambda_result_payload(s3_object_handler_fn_arn, payload) assert result.get("body") == {"name": "hello", "value": "world"} +@pytest.mark.xdist_group(name="streaming") def test_s3_versioned_object_csv_constructor(s3_object_handler_fn_arn, versioned_bucket_name): key = "csv.txt" payload = { @@ -86,24 +92,28 @@ def test_s3_versioned_object_csv_constructor(s3_object_handler_fn_arn, versioned assert result.get("body") == {"name": "hello", "value": "world"} +@pytest.mark.xdist_group(name="streaming") def test_s3_object_csv_transform(s3_object_handler_fn_arn, regular_bucket_name): payload = {"bucket": regular_bucket_name, "key": "csv.txt", "transform_csv": True} result = get_lambda_result_payload(s3_object_handler_fn_arn, payload) assert result.get("body") == {"name": "hello", "value": "world"} +@pytest.mark.xdist_group(name="streaming") def test_s3_object_csv_transform_in_place(s3_object_handler_fn_arn, regular_bucket_name): payload = {"bucket": regular_bucket_name, "key": "csv.txt", "transform_csv": True, "in_place": True} result = get_lambda_result_payload(s3_object_handler_fn_arn, payload) assert result.get("body") == {"name": "hello", "value": "world"} +@pytest.mark.xdist_group(name="streaming") def test_s3_object_csv_gzip_constructor(s3_object_handler_fn_arn, regular_bucket_name): payload = {"bucket": regular_bucket_name, "key": "csv.txt.gz", "is_csv": True, "is_gzip": True} result = get_lambda_result_payload(s3_object_handler_fn_arn, payload) assert result.get("body") == {"name": "hello", "value": "world"} +@pytest.mark.xdist_group(name="streaming") def test_s3_versioned_object_csv_gzip_constructor(s3_object_handler_fn_arn, versioned_bucket_name): key = "csv.txt.gz" payload = { @@ -117,12 +127,14 @@ def test_s3_versioned_object_csv_gzip_constructor(s3_object_handler_fn_arn, vers assert result.get("body") == {"name": "hello", "value": "world"} +@pytest.mark.xdist_group(name="streaming") def test_s3_object_gzip_constructor(s3_object_handler_fn_arn, regular_bucket_name): payload = {"bucket": regular_bucket_name, "key": "plain.txt.gz", "is_gzip": True} result = get_lambda_result_payload(s3_object_handler_fn_arn, payload) assert result.get("body") == "hello world" +@pytest.mark.xdist_group(name="streaming") def test_s3_versioned_object_gzip_constructor(s3_object_handler_fn_arn, versioned_bucket_name): key = "plain.txt.gz" payload = { @@ -135,18 +147,21 @@ def test_s3_versioned_object_gzip_constructor(s3_object_handler_fn_arn, versione assert result.get("body") == "hello world" +@pytest.mark.xdist_group(name="streaming") def test_s3_object_gzip_transform(s3_object_handler_fn_arn, regular_bucket_name): payload = {"bucket": regular_bucket_name, "key": "plain.txt.gz", "transform_gzip": True} result = get_lambda_result_payload(s3_object_handler_fn_arn, payload) assert result.get("body") == "hello world" +@pytest.mark.xdist_group(name="streaming") def test_s3_object_gzip_transform_in_place(s3_object_handler_fn_arn, regular_bucket_name): payload = {"bucket": regular_bucket_name, "key": "plain.txt.gz", "transform_gzip": True, "in_place": True} result = get_lambda_result_payload(s3_object_handler_fn_arn, payload) assert result.get("body") == "hello world" +@pytest.mark.xdist_group(name="streaming") def test_s3_object_zip_transform(s3_object_handler_fn_arn, regular_bucket_name): payload = {"bucket": regular_bucket_name, "key": "fileset.zip", "transform_zip": True} result = get_lambda_result_payload(s3_object_handler_fn_arn, payload) @@ -154,6 +169,7 @@ def test_s3_object_zip_transform(s3_object_handler_fn_arn, regular_bucket_name): assert result.get("body") == "This is file 2" +@pytest.mark.xdist_group(name="streaming") def test_s3_object_zip_transform_in_place(s3_object_handler_fn_arn, regular_bucket_name): payload = {"bucket": regular_bucket_name, "key": "fileset.zip", "transform_zip": True, "in_place": True} result = get_lambda_result_payload(s3_object_handler_fn_arn, payload) @@ -161,6 +177,7 @@ def test_s3_object_zip_transform_in_place(s3_object_handler_fn_arn, regular_buck assert result.get("body") == "This is file 2" +@pytest.mark.xdist_group(name="streaming") def test_s3_object_zip_lzma_transform(s3_object_handler_fn_arn, regular_bucket_name): payload = {"bucket": regular_bucket_name, "key": "fileset.zip.lzma", "transform_zip_lzma": True} result = get_lambda_result_payload(s3_object_handler_fn_arn, payload) @@ -168,6 +185,7 @@ def test_s3_object_zip_lzma_transform(s3_object_handler_fn_arn, regular_bucket_n assert result.get("body") == "This is file 2" +@pytest.mark.xdist_group(name="streaming") def test_s3_object_zip_lzma_transform_in_place(s3_object_handler_fn_arn, regular_bucket_name): payload = {"bucket": regular_bucket_name, "key": "fileset.zip.lzma", "transform_zip_lzma": True, "in_place": True} result = get_lambda_result_payload(s3_object_handler_fn_arn, payload) diff --git a/tests/e2e/tracer/conftest.py b/tests/e2e/tracer/conftest.py index afb34ffee2b..d3728ab91ba 100644 --- a/tests/e2e/tracer/conftest.py +++ b/tests/e2e/tracer/conftest.py @@ -3,7 +3,7 @@ from tests.e2e.tracer.infrastructure import TracerStack -@pytest.fixture(autouse=True, scope="module") +@pytest.fixture(autouse=True, scope="package") def infrastructure(): """Setup and teardown logic for E2E test infrastructure diff --git a/tests/e2e/tracer/test_tracer.py b/tests/e2e/tracer/test_tracer.py index e2abc5af6bc..5dfe68ee08c 100644 --- a/tests/e2e/tracer/test_tracer.py +++ b/tests/e2e/tracer/test_tracer.py @@ -36,6 +36,7 @@ def async_fn(infrastructure: dict) -> str: return infrastructure.get("AsyncCapture", "") +@pytest.mark.xdist_group(name="tracer") def test_lambda_handler_trace_is_visible(basic_handler_fn_arn: str, basic_handler_fn: str): # GIVEN service = data_builder.build_service_name() @@ -64,6 +65,7 @@ def test_lambda_handler_trace_is_visible(basic_handler_fn_arn: str, basic_handle assert len(trace.get_subsegment(name=method_subsegment)) == 2 +@pytest.mark.xdist_group(name="tracer") def test_lambda_handler_trace_multiple_functions_same_name(same_function_name_arn: str, same_function_name_fn: str): # GIVEN service = data_builder.build_service_name() @@ -90,6 +92,7 @@ def test_lambda_handler_trace_multiple_functions_same_name(same_function_name_ar assert len(trace.get_subsegment(name=method_subsegment_comments)) == 1 +@pytest.mark.xdist_group(name="tracer") def test_async_trace_is_visible(async_fn_arn: str, async_fn: str): # GIVEN service = data_builder.build_service_name() diff --git a/tests/e2e/utils/functions.py b/tests/e2e/utils/functions.py index 7b64c439298..db70f4ab6b9 100644 --- a/tests/e2e/utils/functions.py +++ b/tests/e2e/utils/functions.py @@ -1,4 +1,6 @@ -from concurrent.futures import ThreadPoolExecutor +import time +from concurrent.futures import Future, ThreadPoolExecutor +from typing import List from tests.e2e.utils import data_fetcher # noqa F401 @@ -6,9 +8,25 @@ def execute_lambdas_in_parallel(function_name: str, lambdas_arn: list, arguments: str): result_list = [] with ThreadPoolExecutor() as executor: - running_tasks = executor.map(lambda exec: eval(function_name)(*exec), [(arn, arguments) for arn in lambdas_arn]) + running_tasks: List[Future] = [] + for arn in lambdas_arn: + # Sleep 0.5, 1, 1.5, ... seconds between each invocation. This way + # we can guarantee that lambdas are executed in parallel, but they are + # called in the same "order" as they are passed in, thus guaranteeing that + # we can assert on the correct output. + time.sleep(0.5 * len(running_tasks)) + running_tasks.append( + executor.submit( + lambda lname, larn, largs: eval(lname)(larn, largs), + function_name, + arn, + arguments, + ) + ) + executor.shutdown(wait=True) + for running_task in running_tasks: - result_list.append(running_task) + result_list.append(running_task.result()) return result_list diff --git a/tests/e2e/utils/infrastructure.py b/tests/e2e/utils/infrastructure.py index daf1a817c89..29e45b83abf 100644 --- a/tests/e2e/utils/infrastructure.py +++ b/tests/e2e/utils/infrastructure.py @@ -1,7 +1,6 @@ import json import logging import os -import platform import subprocess import sys import textwrap @@ -57,7 +56,7 @@ def __init__(self) -> None: self._feature_infra_module_path = self.feature_path / "infrastructure" self._feature_infra_file = self.feature_path / "infrastructure.py" self._handlers_dir = self.feature_path / "handlers" - self._cdk_out_dir: Path = CDK_OUT_PATH / "-".join(platform.python_version_tuple()) / self.feature_name + self._cdk_out_dir: Path = CDK_OUT_PATH / self.feature_name self._stack_outputs_file = f'{self._cdk_out_dir / "stack_outputs.json"}' if not self._feature_infra_file.exists():