Techdebt: Verify minimum boto3-version, up minimum responses version (#7218)

This commit is contained in:
Bert Blommers 2024-01-17 10:02:15 +00:00
parent f834d98314
commit 16ba3de855
15 changed files with 158 additions and 51 deletions

View File

@ -13,8 +13,9 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
botocore: ["--upgrade boto3 botocore", "boto3==1.11.0 botocore==1.14.0"]
python-version: [ "3.11" ] 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"] werkzeug-version: ["2.0.1", "2.1.1", "2.2.2"]
openapi-spec-validator-version: ["0.5.0"] openapi-spec-validator-version: ["0.5.0"]
@ -38,6 +39,7 @@ jobs:
pip install flask==${{ matrix.werkzeug-version }} pip install flask==${{ matrix.werkzeug-version }}
pip install werkzeug==${{ matrix.werkzeug-version }} pip install werkzeug==${{ matrix.werkzeug-version }}
pip install openapi-spec-validator==${{ matrix.openapi-spec-validator-version }} pip install openapi-spec-validator==${{ matrix.openapi-spec-validator-version }}
pip install ${{ matrix.botocore }}
- name: Run tests - name: Run tests
run: | run: |
@ -65,6 +67,6 @@ jobs:
if: always() if: always()
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: 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: | path: |
serverlogs/* serverlogs/*

View File

@ -2,18 +2,3 @@ from moto.core.decorator import mock_aws # noqa # pylint: disable=unused-impor
__title__ = "moto" __title__ = "moto"
__version__ = "4.2.15.dev" __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

View File

@ -13,5 +13,9 @@ def is_responses_0_17_x() -> bool:
return LooseVersion(RESPONSES_VERSION) >= LooseVersion("0.17.0") 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: def is_werkzeug_2_3_x() -> bool:
return LooseVersion(WERKZEUG_VERSION) >= LooseVersion("2.3.0") return LooseVersion(WERKZEUG_VERSION) >= LooseVersion("2.3.0")

View File

@ -27,13 +27,13 @@ project_urls =
python_requires = >=3.8 python_requires = >=3.8
install_requires = install_requires =
boto3>=1.9.201 boto3>=1.9.201
botocore>=1.13.46 botocore>=1.14.0
cryptography>=3.3.1 cryptography>=3.3.1
requests>=2.5 requests>=2.5
xmltodict xmltodict
werkzeug>=0.5,!=2.2.0,!=2.2.1 werkzeug>=0.5,!=2.2.0,!=2.2.1
python-dateutil<3.0.0,>=2.1 python-dateutil<3.0.0,>=2.1
responses>=0.13.0 responses>=0.15.0
Jinja2>=2.10.1 Jinja2>=2.10.1
package_dir = package_dir =
moto = moto moto = moto

View File

@ -2,6 +2,7 @@ import base64
import hashlib import hashlib
import json import json
import os import os
import sys
from unittest import SkipTest, mock from unittest import SkipTest, mock
from uuid import uuid4 from uuid import uuid4
@ -12,6 +13,7 @@ from freezegun import freeze_time
from moto import mock_aws, settings from moto import mock_aws, settings
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID 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 tests.test_ecr.test_ecr_helpers import _create_image_manifest
from . import lambda_aws_verified from . import lambda_aws_verified
@ -28,6 +30,8 @@ PYTHON_VERSION = "python3.11"
LAMBDA_FUNC_NAME = "test" LAMBDA_FUNC_NAME = "test"
_lambda_region = "us-west-2" _lambda_region = "us-west-2"
boto3_version = sys.modules["botocore"].__version__
@mock.patch.dict("os.environ", {"MOTO_ENABLE_ISO_REGIONS": "true"}) @mock.patch.dict("os.environ", {"MOTO_ENABLE_ISO_REGIONS": "true"})
@pytest.mark.parametrize("region", ["us-west-2", "cn-northwest-1", "us-isob-east-1"]) @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): def test_lambda_regions(region):
if not settings.TEST_DECORATOR_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Can only set EnvironVars in DecoratorMode") 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) client = boto3.client("lambda", region_name=region)
resp = client.list_functions() resp = client.list_functions()
assert resp["ResponseMetadata"]["HTTPStatusCode"] == 200 assert resp["ResponseMetadata"]["HTTPStatusCode"] == 200
@ -43,6 +49,8 @@ def test_lambda_regions(region):
@pytest.mark.aws_verified @pytest.mark.aws_verified
@lambda_aws_verified @lambda_aws_verified
def test_list_functions(iam_role_arn=None): 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") sts = boto3.client("sts", "eu-west-2")
account_id = sts.get_caller_identity()["Account"] 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"] func_list = conn.list_functions()["Functions"]
our_functions = [f for f in func_list if f["FunctionName"] == function_name] our_functions = [f for f in func_list if f["FunctionName"] == function_name]
assert len(our_functions) == 1 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 # FunctionVersion=ALL means we should get a list of all versions
full_list = conn.list_functions(FunctionVersion="ALL")["Functions"] full_list = conn.list_functions(FunctionVersion="ALL")["Functions"]
@ -127,6 +137,8 @@ def test_create_based_on_s3_with_missing_bucket():
@mock_aws @mock_aws
@freeze_time("2015-01-01 00:00:00") @freeze_time("2015-01-01 00:00:00")
def test_create_function_from_aws_bucket(): 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()) bucket_name = str(uuid4())
s3_conn = boto3.client("s3", _lambda_region) s3_conn = boto3.client("s3", _lambda_region)
s3_conn.create_bucket( s3_conn.create_bucket(
@ -169,6 +181,8 @@ def test_create_function_from_aws_bucket():
@mock_aws @mock_aws
@freeze_time("2015-01-01 00:00:00") @freeze_time("2015-01-01 00:00:00")
def test_create_function_from_zipfile(): 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) conn = boto3.client("lambda", _lambda_region)
zip_content = get_test_zip_file1() zip_content = get_test_zip_file1()
function_name = str(uuid4())[0:6] function_name = str(uuid4())[0:6]
@ -218,6 +232,8 @@ def test_create_function_from_zipfile():
@mock_aws @mock_aws
def test_create_function_from_image(): 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) conn = boto3.client("lambda", _lambda_region)
function_name = str(uuid4())[0:6] function_name = str(uuid4())[0:6]
image_uri = f"{ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/testlambdaecr:prod" 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", Description="test lambda function",
ImageConfig=image_config, ImageConfig=image_config,
PackageType="Image", PackageType="Image",
Timeout=3,
MemorySize=128,
Publish=True,
) )
result = conn.get_function(FunctionName=function_name) result = conn.get_function(FunctionName=function_name)
@ -250,6 +263,8 @@ def test_create_function_from_image():
@mock_aws @mock_aws
def test_create_function_from_image_default_working_directory(): 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) conn = boto3.client("lambda", _lambda_region)
function_name = str(uuid4())[0:6] function_name = str(uuid4())[0:6]
image_uri = f"{ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/testlambdaecr:prod" 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", Description="test lambda function",
ImageConfig=image_config, ImageConfig=image_config,
PackageType="Image", PackageType="Image",
Timeout=3,
MemorySize=128,
Publish=True,
) )
result = conn.get_function(FunctionName=function_name) result = conn.get_function(FunctionName=function_name)
@ -281,6 +293,8 @@ def test_create_function_from_image_default_working_directory():
@mock_aws @mock_aws
def test_create_function_error_bad_architecture(): 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) conn = boto3.client("lambda", _lambda_region)
function_name = str(uuid4())[0:6] function_name = str(uuid4())[0:6]
image_uri = f"{ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/testlambdaecr:prod" 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, FunctionName=function_name,
Role=get_role_name(), Role=get_role_name(),
Code={"ImageUri": image_uri}, Code={"ImageUri": image_uri},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
) )
err = exc.value.response err = exc.value.response
@ -310,6 +320,8 @@ def test_create_function_error_bad_architecture():
@mock_aws @mock_aws
def test_create_function_error_ephemeral_too_big(): 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) conn = boto3.client("lambda", _lambda_region)
function_name = str(uuid4())[0:6] function_name = str(uuid4())[0:6]
image_uri = f"{ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/testlambdaecr:prod" image_uri = f"{ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/testlambdaecr:prod"
@ -405,6 +417,8 @@ def ecr_repo_fixture():
@mock_aws @mock_aws
def test_create_function_from_stubbed_ecr(): 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") lambda_client = boto3.client("lambda", "us-east-1")
fn_name = str(uuid4())[0:6] fn_name = str(uuid4())[0:6]
image_uri = "111122223333.dkr.ecr.us-east-1.amazonaws.com/testlambda:latest" 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( def test_create_function_from_mocked_ecr_image_tag(
with_ecr_mock, with_ecr_mock,
): # pylint: disable=unused-argument ): # 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: if not settings.TEST_DECORATOR_MODE:
raise SkipTest( raise SkipTest(
"Envars not easily set in server mode, feature off by default, skipping..." "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( def test_create_function_from_mocked_ecr_image_digest(
with_ecr_mock, with_ecr_mock,
): # pylint: disable=unused-argument ): # 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: if not settings.TEST_DECORATOR_MODE:
raise SkipTest( raise SkipTest(
"Envars not easily set in server mode, feature off by default, skipping..." "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( def test_create_function_from_mocked_ecr_missing_image(
with_ecr_mock, with_ecr_mock,
): # pylint: disable=unused-argument ): # 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: if not settings.TEST_DECORATOR_MODE:
raise SkipTest( raise SkipTest(
"Envars not easily set in server mode, feature off by default, skipping..." "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"]) @pytest.mark.parametrize("key", ["FunctionName", "FunctionArn"])
@mock_aws @mock_aws
def test_get_function_code_signing_config(key): 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()) bucket_name = str(uuid4())
s3_conn = boto3.client("s3", _lambda_region) s3_conn = boto3.client("s3", _lambda_region)
s3_conn.create_bucket( s3_conn.create_bucket(
@ -929,6 +951,8 @@ def test_list_create_list_get_delete_list():
test `list -> create -> list -> get -> delete -> list` integration 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()) bucket_name = str(uuid4())
s3_conn = boto3.client("s3", _lambda_region) s3_conn = boto3.client("s3", _lambda_region)
s3_conn.create_bucket( s3_conn.create_bucket(
@ -1055,9 +1079,6 @@ def test_get_function_created_with_zipfile():
Handler="lambda_function.handler", Handler="lambda_function.handler",
Code={"ZipFile": zip_content}, Code={"ZipFile": zip_content},
Description="test lambda function", Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
) )
response = conn.get_function(FunctionName=function_name) response = conn.get_function(FunctionName=function_name)
@ -1503,6 +1524,8 @@ def test_update_function_s3():
@mock_aws @mock_aws
def test_update_function_ecr(): 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) conn = boto3.client("lambda", _lambda_region)
function_name = str(uuid4())[0:6] function_name = str(uuid4())[0:6]
image_uri = f"{ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/testlambdaecr:prod" image_uri = f"{ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/testlambdaecr:prod"

View File

@ -1,3 +1,5 @@
import sys
from unittest import SkipTest
from uuid import uuid4 from uuid import uuid4
import boto3 import boto3
@ -5,15 +7,20 @@ import pytest
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
from moto import mock_aws from moto import mock_aws
from moto.utilities.distutils_version import LooseVersion
from .utilities import get_role_name, get_test_zip_file1 from .utilities import get_role_name, get_test_zip_file1
PYTHON_VERSION = "python3.11" PYTHON_VERSION = "python3.11"
boto3_version = sys.modules["botocore"].__version__
@mock_aws @mock_aws
@pytest.mark.parametrize("key", ["FunctionName", "FunctionArn"]) @pytest.mark.parametrize("key", ["FunctionName", "FunctionArn"])
def test_create_function_url_config(key): 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") client = boto3.client("lambda", "us-east-2")
function_name = str(uuid4())[0:6] function_name = str(uuid4())[0:6]
fxn = client.create_function( fxn = client.create_function(
@ -40,6 +47,8 @@ def test_create_function_url_config(key):
@mock_aws @mock_aws
def test_create_function_url_config_with_cors(): 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") client = boto3.client("lambda", "us-east-2")
function_name = str(uuid4())[0:6] function_name = str(uuid4())[0:6]
fxn = client.create_function( fxn = client.create_function(
@ -75,6 +84,8 @@ def test_create_function_url_config_with_cors():
@mock_aws @mock_aws
def test_update_function_url_config_with_cors(): 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") client = boto3.client("lambda", "us-east-2")
function_name = str(uuid4())[0:6] function_name = str(uuid4())[0:6]
fxn = client.create_function( fxn = client.create_function(
@ -108,6 +119,8 @@ def test_update_function_url_config_with_cors():
@mock_aws @mock_aws
@pytest.mark.parametrize("key", ["FunctionName", "FunctionArn"]) @pytest.mark.parametrize("key", ["FunctionName", "FunctionArn"])
def test_delete_function_url_config(key): 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") client = boto3.client("lambda", "us-east-2")
function_name = str(uuid4())[0:6] function_name = str(uuid4())[0:6]
fxn = client.create_function( fxn = client.create_function(

View File

@ -1,4 +1,5 @@
import os import os
import sys
from unittest import SkipTest, mock from unittest import SkipTest, mock
from uuid import uuid4 from uuid import uuid4
@ -9,12 +10,15 @@ from freezegun import freeze_time
from moto import mock_aws, settings from moto import mock_aws, settings
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID 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 from .utilities import get_role_name, get_test_zip_file1
PYTHON_VERSION = "python3.11" PYTHON_VERSION = "python3.11"
_lambda_region = "us-west-2" _lambda_region = "us-west-2"
boto3_version = sys.modules["botocore"].__version__
@mock_aws @mock_aws
def test_publish_lambda_layers__without_content(): def test_publish_lambda_layers__without_content():
@ -50,6 +54,8 @@ def test_publish_layer_with_unknown_s3_file():
@mock_aws @mock_aws
@freeze_time("2015-01-01 00:00:00") @freeze_time("2015-01-01 00:00:00")
def test_get_lambda_layers(): 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()) bucket_name = str(uuid4())
s3_conn = boto3.client("s3", _lambda_region) s3_conn = boto3.client("s3", _lambda_region)
s3_conn.create_bucket( s3_conn.create_bucket(
@ -152,6 +158,8 @@ def test_get_lambda_layers():
@mock_aws @mock_aws
def test_get_layer_version(): 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()) bucket_name = str(uuid4())
s3_conn = boto3.client("s3", _lambda_region) s3_conn = boto3.client("s3", _lambda_region)
s3_conn.create_bucket( s3_conn.create_bucket(

View File

@ -1,4 +1,6 @@
import json import json
import sys
from unittest import SkipTest
from uuid import uuid4 from uuid import uuid4
import boto3 import boto3
@ -7,12 +9,15 @@ from botocore.exceptions import ClientError
from moto import mock_aws from moto import mock_aws
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID 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 from .utilities import get_role_name, get_test_zip_file1, get_test_zip_file2
PYTHON_VERSION = "python3.11" PYTHON_VERSION = "python3.11"
_lambda_region = "us-west-2" _lambda_region = "us-west-2"
boto3_version = sys.modules["botocore"].__version__
@pytest.mark.parametrize("key", ["FunctionName", "FunctionArn"]) @pytest.mark.parametrize("key", ["FunctionName", "FunctionArn"])
@mock_aws @mock_aws
@ -51,6 +56,8 @@ def test_add_function_permission(key):
@mock_aws @mock_aws
def test_add_permission_with_principalorgid(): 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) conn = boto3.client("lambda", _lambda_region)
zip_content = get_test_zip_file1() zip_content = get_test_zip_file1()
function_name = str(uuid4())[0:6] function_name = str(uuid4())[0:6]

View File

@ -1,6 +1,7 @@
import copy import copy
import json import json
import os import os
import sys
from collections import OrderedDict from collections import OrderedDict
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
from unittest import SkipTest from unittest import SkipTest
@ -12,11 +13,14 @@ from botocore.exceptions import ClientError
from moto import mock_aws, settings from moto import mock_aws, settings
from moto.cloudformation import cloudformation_backends from moto.cloudformation import cloudformation_backends
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
from moto.utilities.distutils_version import LooseVersion
from tests import EXAMPLE_AMI_ID from tests import EXAMPLE_AMI_ID
TEST_STACK_NAME = "test_stack" TEST_STACK_NAME = "test_stack"
REGION_NAME = "us-east-1" REGION_NAME = "us-east-1"
boto3_version = sys.modules["botocore"].__version__
dummy_template = { dummy_template = {
"AWSTemplateFormatVersion": "2010-09-09", "AWSTemplateFormatVersion": "2010-09-09",
"Description": "Stack 1", "Description": "Stack 1",
@ -367,7 +371,9 @@ def test_describe_stack_instances():
for instance in [use1_instance, usw2_instance]: for instance in [use1_instance, usw2_instance]:
assert instance["Account"] == ACCOUNT_ID assert instance["Account"] == ACCOUNT_ID
assert instance["Status"] == "CURRENT" 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 @mock_aws
@ -1615,6 +1621,8 @@ def test_delete_change_set():
@mock_aws @mock_aws
def test_create_change_set_twice__no_changes(): 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) cf_client = boto3.client("cloudformation", region_name=REGION_NAME)
# Execute once # Execute once
@ -1646,6 +1654,8 @@ def test_create_change_set_twice__no_changes():
@mock_aws @mock_aws
def test_create_change_set_twice__using_s3__no_changes(): 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) cf_client = boto3.client("cloudformation", region_name=REGION_NAME)
s3 = boto3.client("s3", region_name=REGION_NAME) s3 = boto3.client("s3", region_name=REGION_NAME)
s3_conn = boto3.resource("s3", region_name=REGION_NAME) s3_conn = boto3.resource("s3", region_name=REGION_NAME)

View File

@ -1,5 +1,6 @@
import io import io
import json import json
import sys
import zipfile import zipfile
from decimal import Decimal from decimal import Decimal
from string import Template from string import Template
@ -10,10 +11,13 @@ from botocore.exceptions import ClientError
from moto import mock_aws from moto import mock_aws
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID 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 import EXAMPLE_AMI_ID, EXAMPLE_AMI_ID2
from tests.markers import requires_docker from tests.markers import requires_docker
from tests.test_cloudformation.fixtures import fn_join, single_instance_with_ebs_volume from tests.test_cloudformation.fixtures import fn_join, single_instance_with_ebs_volume
boto3_version = sys.modules["botocore"].__version__
@mock_aws @mock_aws
def test_create_template_without_required_param_boto3(): def test_create_template_without_required_param_boto3():
@ -274,18 +278,19 @@ def lambda_handler(event, context):
lambda_conn = boto3.client("lambda", region) lambda_conn = boto3.client("lambda", region)
result = lambda_conn.list_layers() result = lambda_conn.list_layers()
layer_name = result["Layers"][0]["LayerName"] layer_name = result["Layers"][0]["LayerName"]
result = lambda_conn.list_layer_versions(LayerName=layer_name) lv = lambda_conn.list_layer_versions(LayerName=layer_name)["LayerVersions"][0]
result["LayerVersions"][0].pop("CreatedDate")
assert result["LayerVersions"] == [ assert lv["Version"] == 1
{ assert (
"Version": 1, lv["LayerVersionArn"]
"LayerVersionArn": f"arn:aws:lambda:{region}:{ACCOUNT_ID}:layer:{layer_name}:1", == f"arn:aws:lambda:{region}:{ACCOUNT_ID}:layer:{layer_name}:1"
"CompatibleRuntimes": ["python2.7", "python3.6"], )
"Description": "Test Layer", assert lv["CompatibleRuntimes"] == ["python2.7", "python3.6"]
"LicenseInfo": "MIT", assert lv["Description"] == "Test Layer"
"CompatibleArchitectures": [], assert lv["LicenseInfo"] == "MIT"
} if LooseVersion(boto3_version) > LooseVersion("1.29.0"):
] # "Parameters only available in newer versions"
assert lv["CompatibleArchitectures"] == []
@mock_aws @mock_aws

View File

@ -1,5 +1,7 @@
import json import json
import sys
from typing import Any, Dict, Optional from typing import Any, Dict, Optional
from unittest import SkipTest
from uuid import uuid4 from uuid import uuid4
import boto3 import boto3
@ -9,6 +11,9 @@ from botocore.exceptions import ClientError
from moto import mock_aws from moto import mock_aws
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
from moto.core import set_initial_no_auth_action_count 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 @mock_aws
@ -191,6 +196,8 @@ def test_invalid_client_token_id() -> None:
@set_initial_no_auth_action_count(0) @set_initial_no_auth_action_count(0)
@mock_aws @mock_aws
def test_auth_failure() -> None: 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( client = boto3.client(
"ec2", "ec2",
region_name="us-east-1", region_name="us-east-1",
@ -230,6 +237,8 @@ def test_signature_does_not_match() -> None:
@set_initial_no_auth_action_count(2) @set_initial_no_auth_action_count(2)
@mock_aws @mock_aws
def test_auth_failure_with_valid_access_key_id() -> None: 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() access_key = create_user_with_access_key()
client = boto3.client( client = boto3.client(
"ec2", "ec2",
@ -250,6 +259,8 @@ def test_auth_failure_with_valid_access_key_id() -> None:
@set_initial_no_auth_action_count(2) @set_initial_no_auth_action_count(2)
@mock_aws @mock_aws
def test_access_denied_with_no_policy() -> None: 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" user_name = "test-user"
access_key = create_user_with_access_key(user_name) access_key = create_user_with_access_key(user_name)
client = boto3.client( client = boto3.client(
@ -271,6 +282,8 @@ def test_access_denied_with_no_policy() -> None:
@set_initial_no_auth_action_count(3) @set_initial_no_auth_action_count(3)
@mock_aws @mock_aws
def test_access_denied_with_not_allowing_policy() -> None: 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" user_name = "test-user"
inline_policy_document = { inline_policy_document = {
"Version": "2012-10-17", "Version": "2012-10-17",
@ -339,6 +352,8 @@ def test_access_denied_explicitly_on_specific_resource() -> None:
@set_initial_no_auth_action_count(3) @set_initial_no_auth_action_count(3)
@mock_aws @mock_aws
def test_access_denied_for_run_instances() -> None: 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 # https://github.com/getmoto/moto/issues/2774
# The run-instances method was broken between botocore versions 1.15.8 and 1.15.12 # 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 # 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) @set_initial_no_auth_action_count(3)
@mock_aws @mock_aws
def test_access_denied_with_denying_policy() -> None: 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" user_name = "test-user"
inline_policy_document = { inline_policy_document = {
"Version": "2012-10-17", "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) @set_initial_no_auth_action_count(10)
@mock_aws @mock_aws
def test_access_denied_with_many_irrelevant_policies() -> None: 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" user_name = "test-user"
inline_policy_document = { inline_policy_document = {
"Version": "2012-10-17", "Version": "2012-10-17",

View File

@ -3,11 +3,16 @@
# #
# There are some issues with running these tests in parallel # There are some issues with running these tests in parallel
# Running them as part of 'moto/core' avoids that problem # Running them as part of 'moto/core' avoids that problem
import sys
import boto3 import boto3
import pytest import pytest
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
from moto import mock_aws from moto import mock_aws
from moto.utilities.distutils_version import LooseVersion
boto3_version = sys.modules["botocore"].__version__
@mock_aws @mock_aws
@ -103,9 +108,11 @@ def test_describe_vpc_default_endpoint_services() -> None:
assert details["ManagesVpcEndpoints"] is False assert details["ManagesVpcEndpoints"] is False
assert details["Owner"] == "amazon" assert details["Owner"] == "amazon"
assert details["PrivateDnsName"] == "config.us-west-1.amazonaws.com" assert details["PrivateDnsName"] == "config.us-west-1.amazonaws.com"
assert details["PrivateDnsNames"] == [ if LooseVersion(boto3_version) > LooseVersion("1.29.0"):
{"PrivateDnsName": "config.us-west-1.amazonaws.com"} # Attribute wasn't available in older botocore versions
] assert details["PrivateDnsNames"] == [
{"PrivateDnsName": "config.us-west-1.amazonaws.com"}
]
assert details["PrivateDnsNameVerificationState"] == "verified" assert details["PrivateDnsNameVerificationState"] == "verified"
assert details["ServiceName"] == "com.amazonaws.us-west-1.config" assert details["ServiceName"] == "com.amazonaws.us-west-1.config"
assert details["ServiceType"] == [{"ServiceType": "Interface"}] assert details["ServiceType"] == [{"ServiceType": "Interface"}]

View File

@ -1,3 +1,4 @@
import sys
from typing import Any, List from typing import Any, List
from unittest import SkipTest from unittest import SkipTest
@ -5,6 +6,9 @@ import boto3
import pytest import pytest
from moto import mock_aws, settings 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") @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: 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 # start S3 after the mock, ensuring that the client contains our event-handler
m = mock_aws() m = mock_aws()
m.start() m.start()
@ -118,6 +124,8 @@ class ImportantBusinessLogic:
def test_mock_works_when_replacing_client( def test_mock_works_when_replacing_client(
aws_credentials: Any, # pylint: disable=unused-argument aws_credentials: Any, # pylint: disable=unused-argument
) -> None: ) -> None:
if LooseVersion(boto3_version) < LooseVersion("1.29.0"):
raise SkipTest("Error handling is different in newer versions")
logic = ImportantBusinessLogic() logic = ImportantBusinessLogic()
m = mock_aws() m = mock_aws()

View File

@ -8,11 +8,16 @@ import requests
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
from moto import mock_aws, settings 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: def test_passthrough_calls_for_entire_service() -> None:
if not settings.TEST_DECORATOR_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Can only test config when using decorators") 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 # Still mock the credentials ourselves, we don't want to reach out to AWS for real
with patch.dict( with patch.dict(
os.environ, {"AWS_ACCESS_KEY_ID": "a", "AWS_SECRET_ACCESS_KEY": "b"} 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: def test_passthrough_calls_for_specific_url() -> None:
if not settings.TEST_DECORATOR_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Can only test config when using decorators") 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 # Still mock the credentials ourselves, we don't want to reach out to AWS for real
with patch.dict( with patch.dict(
os.environ, {"AWS_ACCESS_KEY_ID": "a", "AWS_SECRET_ACCESS_KEY": "b"} 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: with pytest.raises(ClientError) as exc:
b2bi.list_transformers() workdocs.describe_users()
assert "Not yet implemented" in str(exc.value) assert "Not yet implemented" in str(exc.value)

View File

@ -1,4 +1,6 @@
import json import json
import sys
from unittest import SkipTest
import boto3 import boto3
import pytest import pytest
@ -7,6 +9,9 @@ from botocore.exceptions import ClientError
import moto.iotdata.models import moto.iotdata.models
from moto import mock_aws, settings from moto import mock_aws, settings
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID 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 @mock_aws
@ -94,6 +99,8 @@ def test_update():
@mock_aws @mock_aws
def test_create_named_shadows(): 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") iot_client = boto3.client("iot", region_name="ap-northeast-1")
client = boto3.client("iot-data", region_name="ap-northeast-1") client = boto3.client("iot-data", region_name="ap-northeast-1")
thing_name = "my-thing" thing_name = "my-thing"