diff --git a/.github/workflows/test_outdated_versions.yml b/.github/workflows/test_outdated_versions.yml index f6cf99322..155b275f9 100644 --- a/.github/workflows/test_outdated_versions.yml +++ b/.github/workflows/test_outdated_versions.yml @@ -13,8 +13,9 @@ jobs: strategy: fail-fast: false matrix: + botocore: ["--upgrade boto3 botocore", "boto3==1.11.0 botocore==1.14.0"] python-version: [ "3.11" ] - responses-version: ["0.13.0", "0.15.0", "0.17.0", "0.19.0", "0.20.0" ] + responses-version: ["0.15.0", "0.17.0", "0.19.0", "0.20.0" ] werkzeug-version: ["2.0.1", "2.1.1", "2.2.2"] openapi-spec-validator-version: ["0.5.0"] @@ -38,6 +39,7 @@ jobs: pip install flask==${{ matrix.werkzeug-version }} pip install werkzeug==${{ matrix.werkzeug-version }} pip install openapi-spec-validator==${{ matrix.openapi-spec-validator-version }} + pip install ${{ matrix.botocore }} - name: Run tests run: | @@ -65,6 +67,6 @@ jobs: if: always() uses: actions/upload-artifact@v4 with: - name: test-${{ matrix.responses-version }}-${{ matrix.werkzeug-version }}-${{ matrix.werkzeug-version }}-${{ matrix.openapi-spec-validator-version }} + name: test-${{ matrix.responses-version }}-${{ matrix.werkzeug-version }}-${{ matrix.werkzeug-version }}-${{ matrix.openapi-spec-validator-version }}-${{ matrix.botocore }} path: | serverlogs/* diff --git a/moto/__init__.py b/moto/__init__.py index 4d86b3e0d..5a3682e25 100644 --- a/moto/__init__.py +++ b/moto/__init__.py @@ -2,18 +2,3 @@ from moto.core.decorator import mock_aws # noqa # pylint: disable=unused-impor __title__ = "moto" __version__ = "4.2.15.dev" - - -try: - # Need to monkey-patch botocore requests back to underlying urllib3 classes - from botocore.awsrequest import ( # type: ignore[attr-defined] - HTTPConnection, - HTTPConnectionPool, - HTTPSConnectionPool, - VerifiedHTTPSConnection, - ) -except ImportError: - pass -else: - HTTPSConnectionPool.ConnectionCls = VerifiedHTTPSConnection - HTTPConnectionPool.ConnectionCls = HTTPConnection diff --git a/moto/core/versions.py b/moto/core/versions.py index 07769fed6..cc2a6dba6 100644 --- a/moto/core/versions.py +++ b/moto/core/versions.py @@ -13,5 +13,9 @@ def is_responses_0_17_x() -> bool: return LooseVersion(RESPONSES_VERSION) >= LooseVersion("0.17.0") +def is_werkzeug_2_0_x_or_older() -> bool: + return LooseVersion(WERKZEUG_VERSION) < LooseVersion("2.1.0") + + def is_werkzeug_2_3_x() -> bool: return LooseVersion(WERKZEUG_VERSION) >= LooseVersion("2.3.0") diff --git a/setup.cfg b/setup.cfg index 8d24d68e5..1318959b1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -27,13 +27,13 @@ project_urls = python_requires = >=3.8 install_requires = boto3>=1.9.201 - botocore>=1.13.46 + botocore>=1.14.0 cryptography>=3.3.1 requests>=2.5 xmltodict werkzeug>=0.5,!=2.2.0,!=2.2.1 python-dateutil<3.0.0,>=2.1 - responses>=0.13.0 + responses>=0.15.0 Jinja2>=2.10.1 package_dir = moto = moto diff --git a/tests/test_awslambda/test_lambda.py b/tests/test_awslambda/test_lambda.py index 5476728fd..3bcffa387 100644 --- a/tests/test_awslambda/test_lambda.py +++ b/tests/test_awslambda/test_lambda.py @@ -2,6 +2,7 @@ import base64 import hashlib import json import os +import sys from unittest import SkipTest, mock from uuid import uuid4 @@ -12,6 +13,7 @@ from freezegun import freeze_time from moto import mock_aws, settings from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID +from moto.utilities.distutils_version import LooseVersion from tests.test_ecr.test_ecr_helpers import _create_image_manifest from . import lambda_aws_verified @@ -28,6 +30,8 @@ PYTHON_VERSION = "python3.11" LAMBDA_FUNC_NAME = "test" _lambda_region = "us-west-2" +boto3_version = sys.modules["botocore"].__version__ + @mock.patch.dict("os.environ", {"MOTO_ENABLE_ISO_REGIONS": "true"}) @pytest.mark.parametrize("region", ["us-west-2", "cn-northwest-1", "us-isob-east-1"]) @@ -35,6 +39,8 @@ _lambda_region = "us-west-2" def test_lambda_regions(region): if not settings.TEST_DECORATOR_MODE: raise SkipTest("Can only set EnvironVars in DecoratorMode") + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("ISO-region not available in older versions") client = boto3.client("lambda", region_name=region) resp = client.list_functions() assert resp["ResponseMetadata"]["HTTPStatusCode"] == 200 @@ -43,6 +49,8 @@ def test_lambda_regions(region): @pytest.mark.aws_verified @lambda_aws_verified def test_list_functions(iam_role_arn=None): + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Parameters only available in newer versions") sts = boto3.client("sts", "eu-west-2") account_id = sts.get_caller_identity()["Account"] @@ -70,7 +78,9 @@ def test_list_functions(iam_role_arn=None): func_list = conn.list_functions()["Functions"] our_functions = [f for f in func_list if f["FunctionName"] == function_name] assert len(our_functions) == 1 - assert our_functions[0]["PackageType"] == "Zip" + if LooseVersion(boto3_version) > LooseVersion("1.29.0"): + # PackageType only available in new versions + assert our_functions[0]["PackageType"] == "Zip" # FunctionVersion=ALL means we should get a list of all versions full_list = conn.list_functions(FunctionVersion="ALL")["Functions"] @@ -127,6 +137,8 @@ def test_create_based_on_s3_with_missing_bucket(): @mock_aws @freeze_time("2015-01-01 00:00:00") def test_create_function_from_aws_bucket(): + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Parameters only available in newer versions") bucket_name = str(uuid4()) s3_conn = boto3.client("s3", _lambda_region) s3_conn.create_bucket( @@ -169,6 +181,8 @@ def test_create_function_from_aws_bucket(): @mock_aws @freeze_time("2015-01-01 00:00:00") def test_create_function_from_zipfile(): + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Parameters only available in newer versions") conn = boto3.client("lambda", _lambda_region) zip_content = get_test_zip_file1() function_name = str(uuid4())[0:6] @@ -218,6 +232,8 @@ def test_create_function_from_zipfile(): @mock_aws def test_create_function_from_image(): + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Parameters only available in newer versions") conn = boto3.client("lambda", _lambda_region) function_name = str(uuid4())[0:6] image_uri = f"{ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/testlambdaecr:prod" @@ -237,9 +253,6 @@ def test_create_function_from_image(): Description="test lambda function", ImageConfig=image_config, PackageType="Image", - Timeout=3, - MemorySize=128, - Publish=True, ) result = conn.get_function(FunctionName=function_name) @@ -250,6 +263,8 @@ def test_create_function_from_image(): @mock_aws def test_create_function_from_image_default_working_directory(): + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Parameters only available in newer versions") conn = boto3.client("lambda", _lambda_region) function_name = str(uuid4())[0:6] image_uri = f"{ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/testlambdaecr:prod" @@ -268,9 +283,6 @@ def test_create_function_from_image_default_working_directory(): Description="test lambda function", ImageConfig=image_config, PackageType="Image", - Timeout=3, - MemorySize=128, - Publish=True, ) result = conn.get_function(FunctionName=function_name) @@ -281,6 +293,8 @@ def test_create_function_from_image_default_working_directory(): @mock_aws def test_create_function_error_bad_architecture(): + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Parameters only available in newer versions") conn = boto3.client("lambda", _lambda_region) function_name = str(uuid4())[0:6] image_uri = f"{ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/testlambdaecr:prod" @@ -291,10 +305,6 @@ def test_create_function_error_bad_architecture(): FunctionName=function_name, Role=get_role_name(), Code={"ImageUri": image_uri}, - Description="test lambda function", - Timeout=3, - MemorySize=128, - Publish=True, ) err = exc.value.response @@ -310,6 +320,8 @@ def test_create_function_error_bad_architecture(): @mock_aws def test_create_function_error_ephemeral_too_big(): + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Parameters only available in newer versions") conn = boto3.client("lambda", _lambda_region) function_name = str(uuid4())[0:6] image_uri = f"{ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/testlambdaecr:prod" @@ -405,6 +417,8 @@ def ecr_repo_fixture(): @mock_aws def test_create_function_from_stubbed_ecr(): + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Parameters only available in newer versions") lambda_client = boto3.client("lambda", "us-east-1") fn_name = str(uuid4())[0:6] image_uri = "111122223333.dkr.ecr.us-east-1.amazonaws.com/testlambda:latest" @@ -440,6 +454,8 @@ def test_create_function_from_stubbed_ecr(): def test_create_function_from_mocked_ecr_image_tag( with_ecr_mock, ): # pylint: disable=unused-argument + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Parameters only available in newer versions") if not settings.TEST_DECORATOR_MODE: raise SkipTest( "Envars not easily set in server mode, feature off by default, skipping..." @@ -482,6 +498,8 @@ def test_create_function_from_mocked_ecr_image_tag( def test_create_function_from_mocked_ecr_image_digest( with_ecr_mock, ): # pylint: disable=unused-argument + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Parameters only available in newer versions") if not settings.TEST_DECORATOR_MODE: raise SkipTest( "Envars not easily set in server mode, feature off by default, skipping..." @@ -509,6 +527,8 @@ def test_create_function_from_mocked_ecr_image_digest( def test_create_function_from_mocked_ecr_missing_image( with_ecr_mock, ): # pylint: disable=unused-argument + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Parameters only available in newer versions") if not settings.TEST_DECORATOR_MODE: raise SkipTest( "Envars not easily set in server mode, feature off by default, skipping..." @@ -696,6 +716,8 @@ def test_get_function_configuration(key): @pytest.mark.parametrize("key", ["FunctionName", "FunctionArn"]) @mock_aws def test_get_function_code_signing_config(key): + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Parameters only available in newer versions") bucket_name = str(uuid4()) s3_conn = boto3.client("s3", _lambda_region) s3_conn.create_bucket( @@ -929,6 +951,8 @@ def test_list_create_list_get_delete_list(): test `list -> create -> list -> get -> delete -> list` integration """ + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Parameters only available in newer versions") bucket_name = str(uuid4()) s3_conn = boto3.client("s3", _lambda_region) s3_conn.create_bucket( @@ -1055,9 +1079,6 @@ def test_get_function_created_with_zipfile(): Handler="lambda_function.handler", Code={"ZipFile": zip_content}, Description="test lambda function", - Timeout=3, - MemorySize=128, - Publish=True, ) response = conn.get_function(FunctionName=function_name) @@ -1503,6 +1524,8 @@ def test_update_function_s3(): @mock_aws def test_update_function_ecr(): + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Parameters only available in newer versions") conn = boto3.client("lambda", _lambda_region) function_name = str(uuid4())[0:6] image_uri = f"{ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/testlambdaecr:prod" diff --git a/tests/test_awslambda/test_lambda_function_urls.py b/tests/test_awslambda/test_lambda_function_urls.py index f583332e4..37e875c17 100644 --- a/tests/test_awslambda/test_lambda_function_urls.py +++ b/tests/test_awslambda/test_lambda_function_urls.py @@ -1,3 +1,5 @@ +import sys +from unittest import SkipTest from uuid import uuid4 import boto3 @@ -5,15 +7,20 @@ import pytest from botocore.exceptions import ClientError from moto import mock_aws +from moto.utilities.distutils_version import LooseVersion from .utilities import get_role_name, get_test_zip_file1 PYTHON_VERSION = "python3.11" +boto3_version = sys.modules["botocore"].__version__ + @mock_aws @pytest.mark.parametrize("key", ["FunctionName", "FunctionArn"]) def test_create_function_url_config(key): + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Parameters only available in newer versions") client = boto3.client("lambda", "us-east-2") function_name = str(uuid4())[0:6] fxn = client.create_function( @@ -40,6 +47,8 @@ def test_create_function_url_config(key): @mock_aws def test_create_function_url_config_with_cors(): + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Parameters only available in newer versions") client = boto3.client("lambda", "us-east-2") function_name = str(uuid4())[0:6] fxn = client.create_function( @@ -75,6 +84,8 @@ def test_create_function_url_config_with_cors(): @mock_aws def test_update_function_url_config_with_cors(): + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Parameters only available in newer versions") client = boto3.client("lambda", "us-east-2") function_name = str(uuid4())[0:6] fxn = client.create_function( @@ -108,6 +119,8 @@ def test_update_function_url_config_with_cors(): @mock_aws @pytest.mark.parametrize("key", ["FunctionName", "FunctionArn"]) def test_delete_function_url_config(key): + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Parameters only available in newer versions") client = boto3.client("lambda", "us-east-2") function_name = str(uuid4())[0:6] fxn = client.create_function( diff --git a/tests/test_awslambda/test_lambda_layers.py b/tests/test_awslambda/test_lambda_layers.py index 701adb915..5e751997c 100644 --- a/tests/test_awslambda/test_lambda_layers.py +++ b/tests/test_awslambda/test_lambda_layers.py @@ -1,4 +1,5 @@ import os +import sys from unittest import SkipTest, mock from uuid import uuid4 @@ -9,12 +10,15 @@ from freezegun import freeze_time from moto import mock_aws, settings from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID +from moto.utilities.distutils_version import LooseVersion from .utilities import get_role_name, get_test_zip_file1 PYTHON_VERSION = "python3.11" _lambda_region = "us-west-2" +boto3_version = sys.modules["botocore"].__version__ + @mock_aws def test_publish_lambda_layers__without_content(): @@ -50,6 +54,8 @@ def test_publish_layer_with_unknown_s3_file(): @mock_aws @freeze_time("2015-01-01 00:00:00") def test_get_lambda_layers(): + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Parameters only available in newer versions") bucket_name = str(uuid4()) s3_conn = boto3.client("s3", _lambda_region) s3_conn.create_bucket( @@ -152,6 +158,8 @@ def test_get_lambda_layers(): @mock_aws def test_get_layer_version(): + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Parameters only available in newer versions") bucket_name = str(uuid4()) s3_conn = boto3.client("s3", _lambda_region) s3_conn.create_bucket( diff --git a/tests/test_awslambda/test_lambda_policy.py b/tests/test_awslambda/test_lambda_policy.py index df038282d..524f28254 100644 --- a/tests/test_awslambda/test_lambda_policy.py +++ b/tests/test_awslambda/test_lambda_policy.py @@ -1,4 +1,6 @@ import json +import sys +from unittest import SkipTest from uuid import uuid4 import boto3 @@ -7,12 +9,15 @@ from botocore.exceptions import ClientError from moto import mock_aws from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID +from moto.utilities.distutils_version import LooseVersion from .utilities import get_role_name, get_test_zip_file1, get_test_zip_file2 PYTHON_VERSION = "python3.11" _lambda_region = "us-west-2" +boto3_version = sys.modules["botocore"].__version__ + @pytest.mark.parametrize("key", ["FunctionName", "FunctionArn"]) @mock_aws @@ -51,6 +56,8 @@ def test_add_function_permission(key): @mock_aws def test_add_permission_with_principalorgid(): + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Parameters only available in newer versions") conn = boto3.client("lambda", _lambda_region) zip_content = get_test_zip_file1() function_name = str(uuid4())[0:6] diff --git a/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py b/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py index d6c37aa67..7706a0286 100644 --- a/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py +++ b/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py @@ -1,6 +1,7 @@ import copy import json import os +import sys from collections import OrderedDict from datetime import datetime, timedelta, timezone from unittest import SkipTest @@ -12,11 +13,14 @@ from botocore.exceptions import ClientError from moto import mock_aws, settings from moto.cloudformation import cloudformation_backends from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID +from moto.utilities.distutils_version import LooseVersion from tests import EXAMPLE_AMI_ID TEST_STACK_NAME = "test_stack" REGION_NAME = "us-east-1" +boto3_version = sys.modules["botocore"].__version__ + dummy_template = { "AWSTemplateFormatVersion": "2010-09-09", "Description": "Stack 1", @@ -367,7 +371,9 @@ def test_describe_stack_instances(): for instance in [use1_instance, usw2_instance]: assert instance["Account"] == ACCOUNT_ID assert instance["Status"] == "CURRENT" - assert instance["StackInstanceStatus"] == {"DetailedStatus": "SUCCEEDED"} + if LooseVersion(boto3_version) > LooseVersion("1.29.0"): + # "Parameters only available in newer versions" + assert instance["StackInstanceStatus"] == {"DetailedStatus": "SUCCEEDED"} @mock_aws @@ -1615,6 +1621,8 @@ def test_delete_change_set(): @mock_aws def test_create_change_set_twice__no_changes(): + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Parameters only available in newer versions") cf_client = boto3.client("cloudformation", region_name=REGION_NAME) # Execute once @@ -1646,6 +1654,8 @@ def test_create_change_set_twice__no_changes(): @mock_aws def test_create_change_set_twice__using_s3__no_changes(): + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Parameters only available in newer versions") cf_client = boto3.client("cloudformation", region_name=REGION_NAME) s3 = boto3.client("s3", region_name=REGION_NAME) s3_conn = boto3.resource("s3", region_name=REGION_NAME) diff --git a/tests/test_cloudformation/test_cloudformation_stack_integration.py b/tests/test_cloudformation/test_cloudformation_stack_integration.py index 534ec31f7..3be5d3083 100644 --- a/tests/test_cloudformation/test_cloudformation_stack_integration.py +++ b/tests/test_cloudformation/test_cloudformation_stack_integration.py @@ -1,5 +1,6 @@ import io import json +import sys import zipfile from decimal import Decimal from string import Template @@ -10,10 +11,13 @@ from botocore.exceptions import ClientError from moto import mock_aws from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID +from moto.utilities.distutils_version import LooseVersion from tests import EXAMPLE_AMI_ID, EXAMPLE_AMI_ID2 from tests.markers import requires_docker from tests.test_cloudformation.fixtures import fn_join, single_instance_with_ebs_volume +boto3_version = sys.modules["botocore"].__version__ + @mock_aws def test_create_template_without_required_param_boto3(): @@ -274,18 +278,19 @@ def lambda_handler(event, context): lambda_conn = boto3.client("lambda", region) result = lambda_conn.list_layers() layer_name = result["Layers"][0]["LayerName"] - result = lambda_conn.list_layer_versions(LayerName=layer_name) - result["LayerVersions"][0].pop("CreatedDate") - assert result["LayerVersions"] == [ - { - "Version": 1, - "LayerVersionArn": f"arn:aws:lambda:{region}:{ACCOUNT_ID}:layer:{layer_name}:1", - "CompatibleRuntimes": ["python2.7", "python3.6"], - "Description": "Test Layer", - "LicenseInfo": "MIT", - "CompatibleArchitectures": [], - } - ] + lv = lambda_conn.list_layer_versions(LayerName=layer_name)["LayerVersions"][0] + + assert lv["Version"] == 1 + assert ( + lv["LayerVersionArn"] + == f"arn:aws:lambda:{region}:{ACCOUNT_ID}:layer:{layer_name}:1" + ) + assert lv["CompatibleRuntimes"] == ["python2.7", "python3.6"] + assert lv["Description"] == "Test Layer" + assert lv["LicenseInfo"] == "MIT" + if LooseVersion(boto3_version) > LooseVersion("1.29.0"): + # "Parameters only available in newer versions" + assert lv["CompatibleArchitectures"] == [] @mock_aws diff --git a/tests/test_core/test_auth.py b/tests/test_core/test_auth.py index 4813fb420..9dedf9040 100644 --- a/tests/test_core/test_auth.py +++ b/tests/test_core/test_auth.py @@ -1,5 +1,7 @@ import json +import sys from typing import Any, Dict, Optional +from unittest import SkipTest from uuid import uuid4 import boto3 @@ -9,6 +11,9 @@ from botocore.exceptions import ClientError from moto import mock_aws from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID from moto.core import set_initial_no_auth_action_count +from moto.utilities.distutils_version import LooseVersion + +boto3_version = sys.modules["botocore"].__version__ @mock_aws @@ -191,6 +196,8 @@ def test_invalid_client_token_id() -> None: @set_initial_no_auth_action_count(0) @mock_aws def test_auth_failure() -> None: + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Error handling is different in newer versions") client = boto3.client( "ec2", region_name="us-east-1", @@ -230,6 +237,8 @@ def test_signature_does_not_match() -> None: @set_initial_no_auth_action_count(2) @mock_aws def test_auth_failure_with_valid_access_key_id() -> None: + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Error handling is different in newer versions") access_key = create_user_with_access_key() client = boto3.client( "ec2", @@ -250,6 +259,8 @@ def test_auth_failure_with_valid_access_key_id() -> None: @set_initial_no_auth_action_count(2) @mock_aws def test_access_denied_with_no_policy() -> None: + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Error handling is different in newer versions") user_name = "test-user" access_key = create_user_with_access_key(user_name) client = boto3.client( @@ -271,6 +282,8 @@ def test_access_denied_with_no_policy() -> None: @set_initial_no_auth_action_count(3) @mock_aws def test_access_denied_with_not_allowing_policy() -> None: + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Error handling is different in newer versions") user_name = "test-user" inline_policy_document = { "Version": "2012-10-17", @@ -339,6 +352,8 @@ def test_access_denied_explicitly_on_specific_resource() -> None: @set_initial_no_auth_action_count(3) @mock_aws def test_access_denied_for_run_instances() -> None: + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Error handling is different in newer versions") # https://github.com/getmoto/moto/issues/2774 # The run-instances method was broken between botocore versions 1.15.8 and 1.15.12 # This was due to the inclusion of '"idempotencyToken":true' in the response, somehow altering the signature and breaking the authentication @@ -372,6 +387,8 @@ def test_access_denied_for_run_instances() -> None: @set_initial_no_auth_action_count(3) @mock_aws def test_access_denied_with_denying_policy() -> None: + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Error handling is different in newer versions") user_name = "test-user" inline_policy_document = { "Version": "2012-10-17", @@ -533,6 +550,8 @@ def test_s3_access_denied_with_denying_inline_group_policy() -> None: @set_initial_no_auth_action_count(10) @mock_aws def test_access_denied_with_many_irrelevant_policies() -> None: + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Error handling is different in newer versions") user_name = "test-user" inline_policy_document = { "Version": "2012-10-17", diff --git a/tests/test_core/test_ec2_vpc_endpoint_services.py b/tests/test_core/test_ec2_vpc_endpoint_services.py index b804da1f1..9b0ce6515 100644 --- a/tests/test_core/test_ec2_vpc_endpoint_services.py +++ b/tests/test_core/test_ec2_vpc_endpoint_services.py @@ -3,11 +3,16 @@ # # There are some issues with running these tests in parallel # Running them as part of 'moto/core' avoids that problem +import sys + import boto3 import pytest from botocore.exceptions import ClientError from moto import mock_aws +from moto.utilities.distutils_version import LooseVersion + +boto3_version = sys.modules["botocore"].__version__ @mock_aws @@ -103,9 +108,11 @@ def test_describe_vpc_default_endpoint_services() -> None: assert details["ManagesVpcEndpoints"] is False assert details["Owner"] == "amazon" assert details["PrivateDnsName"] == "config.us-west-1.amazonaws.com" - assert details["PrivateDnsNames"] == [ - {"PrivateDnsName": "config.us-west-1.amazonaws.com"} - ] + if LooseVersion(boto3_version) > LooseVersion("1.29.0"): + # Attribute wasn't available in older botocore versions + assert details["PrivateDnsNames"] == [ + {"PrivateDnsName": "config.us-west-1.amazonaws.com"} + ] assert details["PrivateDnsNameVerificationState"] == "verified" assert details["ServiceName"] == "com.amazonaws.us-west-1.config" assert details["ServiceType"] == [{"ServiceType": "Interface"}] diff --git a/tests/test_core/test_importorder.py b/tests/test_core/test_importorder.py index e235f553a..7c4569c1e 100644 --- a/tests/test_core/test_importorder.py +++ b/tests/test_core/test_importorder.py @@ -1,3 +1,4 @@ +import sys from typing import Any, List from unittest import SkipTest @@ -5,6 +6,9 @@ import boto3 import pytest from moto import mock_aws, settings +from moto.utilities.distutils_version import LooseVersion + +boto3_version = sys.modules["botocore"].__version__ @pytest.fixture(scope="function", name="aws_credentials") @@ -70,6 +74,8 @@ def test_mock_works_with_resource_created_outside( def test_patch_can_be_called_on_a_mocked_client() -> None: + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Error handling is different in newer versions") # start S3 after the mock, ensuring that the client contains our event-handler m = mock_aws() m.start() @@ -118,6 +124,8 @@ class ImportantBusinessLogic: def test_mock_works_when_replacing_client( aws_credentials: Any, # pylint: disable=unused-argument ) -> None: + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Error handling is different in newer versions") logic = ImportantBusinessLogic() m = mock_aws() diff --git a/tests/test_core/test_request_passthrough.py b/tests/test_core/test_request_passthrough.py index 16867d8cc..a563a9856 100644 --- a/tests/test_core/test_request_passthrough.py +++ b/tests/test_core/test_request_passthrough.py @@ -8,11 +8,16 @@ import requests from botocore.exceptions import ClientError from moto import mock_aws, settings +from moto.core.versions import is_werkzeug_2_0_x_or_older def test_passthrough_calls_for_entire_service() -> None: if not settings.TEST_DECORATOR_MODE: raise SkipTest("Can only test config when using decorators") + if is_werkzeug_2_0_x_or_older(): + raise SkipTest( + "Bug in old werkzeug versions where headers with byte-values throw errors" + ) # Still mock the credentials ourselves, we don't want to reach out to AWS for real with patch.dict( os.environ, {"AWS_ACCESS_KEY_ID": "a", "AWS_SECRET_ACCESS_KEY": "b"} @@ -50,6 +55,10 @@ def test_passthrough_calls_for_entire_service() -> None: def test_passthrough_calls_for_specific_url() -> None: if not settings.TEST_DECORATOR_MODE: raise SkipTest("Can only test config when using decorators") + if is_werkzeug_2_0_x_or_older(): + raise SkipTest( + "Bug in old werkzeug versions where headers with byte-values throw errors" + ) # Still mock the credentials ourselves, we don't want to reach out to AWS for real with patch.dict( os.environ, {"AWS_ACCESS_KEY_ID": "a", "AWS_SECRET_ACCESS_KEY": "b"} @@ -135,9 +144,9 @@ def test_passthrough__using_unsupported_service() -> None: } } ): - b2bi = boto3.client("b2bi", "us-east-1") + workdocs = boto3.client("workdocs", "us-east-1") with pytest.raises(ClientError) as exc: - b2bi.list_transformers() + workdocs.describe_users() assert "Not yet implemented" in str(exc.value) diff --git a/tests/test_iotdata/test_iotdata.py b/tests/test_iotdata/test_iotdata.py index 73a5e4d1b..60e58c081 100644 --- a/tests/test_iotdata/test_iotdata.py +++ b/tests/test_iotdata/test_iotdata.py @@ -1,4 +1,6 @@ import json +import sys +from unittest import SkipTest import boto3 import pytest @@ -7,6 +9,9 @@ from botocore.exceptions import ClientError import moto.iotdata.models from moto import mock_aws, settings from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID +from moto.utilities.distutils_version import LooseVersion + +boto3_version = sys.modules["botocore"].__version__ @mock_aws @@ -94,6 +99,8 @@ def test_update(): @mock_aws def test_create_named_shadows(): + if LooseVersion(boto3_version) < LooseVersion("1.29.0"): + raise SkipTest("Parameter only available in newer versions") iot_client = boto3.client("iot", region_name="ap-northeast-1") client = boto3.client("iot-data", region_name="ap-northeast-1") thing_name = "my-thing"