Remove deprecated decorators + boto dependency (#4378)

This commit is contained in:
Bert Blommers 2022-01-18 14:18:57 -01:00 committed by GitHub
parent 3adb5ea84f
commit aa70ee254d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
139 changed files with 560 additions and 23697 deletions

View File

@ -1,38 +0,0 @@
.. _boto:
=============
Boto vs Boto3
=============
Boto3 is the latest Python SDK, and as such the SDK targeted by Moto. All our `@mock_`-decorators should be usable against any boto3-version.
Still stuck on boto, the former SDK? Moto does have some support, in the form of our deprecated services:
.. sourcecode:: python
from moto import mock_ec2_deprecated
import boto
@mock_ec2_deprecated
def test_something_with_ec2():
ec2_conn = boto.ec2.connect_to_region('us-east-1')
ec2_conn.get_only_instances(instance_ids='i-123456')
When using both boto2 and boto3, one can do this to avoid confusion:
.. sourcecode:: python
from moto import mock_ec2_deprecated as mock_ec2_b2
from moto import mock_ec2
If you want to use Server Mode, the easiest way is to create a boto config file (`~/.boto`) with the following values:
.. code-block:: bash
[Boto]
is_secure = False
https_validate_certificates = False
proxy_port = 5000
proxy = 127.0.0.1

View File

@ -33,7 +33,6 @@ Additional Resources
docs/getting_started docs/getting_started
docs/server_mode docs/server_mode
docs/faq docs/faq
docs/boto
docs/iam docs/iam
docs/aws_config docs/aws_config

View File

@ -26,68 +26,47 @@ def lazy_load(
mock_acm = lazy_load(".acm", "mock_acm") mock_acm = lazy_load(".acm", "mock_acm")
mock_apigateway = lazy_load(".apigateway", "mock_apigateway") mock_apigateway = lazy_load(".apigateway", "mock_apigateway")
mock_apigateway_deprecated = lazy_load(".apigateway", "mock_apigateway_deprecated")
mock_appsync = lazy_load(".appsync", "mock_appsync", boto3_name="appsync") mock_appsync = lazy_load(".appsync", "mock_appsync", boto3_name="appsync")
mock_athena = lazy_load(".athena", "mock_athena") mock_athena = lazy_load(".athena", "mock_athena")
mock_applicationautoscaling = lazy_load( mock_applicationautoscaling = lazy_load(
".applicationautoscaling", "mock_applicationautoscaling" ".applicationautoscaling", "mock_applicationautoscaling"
) )
mock_autoscaling = lazy_load(".autoscaling", "mock_autoscaling") mock_autoscaling = lazy_load(".autoscaling", "mock_autoscaling")
mock_autoscaling_deprecated = lazy_load(".autoscaling", "mock_autoscaling_deprecated")
mock_lambda = lazy_load( mock_lambda = lazy_load(
".awslambda", "mock_lambda", boto3_name="lambda", backend="lambda_backends" ".awslambda", "mock_lambda", boto3_name="lambda", backend="lambda_backends"
) )
mock_lambda_deprecated = lazy_load(".awslambda", "mock_lambda_deprecated")
mock_batch = lazy_load(".batch", "mock_batch") mock_batch = lazy_load(".batch", "mock_batch")
mock_budgets = lazy_load(".budgets", "mock_budgets") mock_budgets = lazy_load(".budgets", "mock_budgets")
mock_cloudformation = lazy_load(".cloudformation", "mock_cloudformation") mock_cloudformation = lazy_load(".cloudformation", "mock_cloudformation")
mock_cloudformation_deprecated = lazy_load(
".cloudformation", "mock_cloudformation_deprecated"
)
mock_cloudfront = lazy_load(".cloudfront", "mock_cloudfront") mock_cloudfront = lazy_load(".cloudfront", "mock_cloudfront")
mock_cloudtrail = lazy_load(".cloudtrail", "mock_cloudtrail", boto3_name="cloudtrail") mock_cloudtrail = lazy_load(".cloudtrail", "mock_cloudtrail", boto3_name="cloudtrail")
mock_cloudwatch = lazy_load(".cloudwatch", "mock_cloudwatch") mock_cloudwatch = lazy_load(".cloudwatch", "mock_cloudwatch")
mock_cloudwatch_deprecated = lazy_load(".cloudwatch", "mock_cloudwatch_deprecated")
mock_codecommit = lazy_load(".codecommit", "mock_codecommit") mock_codecommit = lazy_load(".codecommit", "mock_codecommit")
mock_codepipeline = lazy_load(".codepipeline", "mock_codepipeline") mock_codepipeline = lazy_load(".codepipeline", "mock_codepipeline")
mock_cognitoidentity = lazy_load( mock_cognitoidentity = lazy_load(
".cognitoidentity", "mock_cognitoidentity", boto3_name="cognito-identity" ".cognitoidentity", "mock_cognitoidentity", boto3_name="cognito-identity"
) )
mock_cognitoidentity_deprecated = lazy_load(
".cognitoidentity", "mock_cognitoidentity_deprecated"
)
mock_cognitoidp = lazy_load(".cognitoidp", "mock_cognitoidp", boto3_name="cognito-idp") mock_cognitoidp = lazy_load(".cognitoidp", "mock_cognitoidp", boto3_name="cognito-idp")
mock_cognitoidp_deprecated = lazy_load(".cognitoidp", "mock_cognitoidp_deprecated")
mock_config = lazy_load(".config", "mock_config") mock_config = lazy_load(".config", "mock_config")
mock_datapipeline = lazy_load(".datapipeline", "mock_datapipeline") mock_datapipeline = lazy_load(".datapipeline", "mock_datapipeline")
mock_datapipeline_deprecated = lazy_load(
".datapipeline", "mock_datapipeline_deprecated"
)
mock_datasync = lazy_load(".datasync", "mock_datasync") mock_datasync = lazy_load(".datasync", "mock_datasync")
mock_dax = lazy_load(".dax", "mock_dax") mock_dax = lazy_load(".dax", "mock_dax")
mock_dms = lazy_load(".dms", "mock_dms") mock_dms = lazy_load(".dms", "mock_dms")
mock_ds = lazy_load(".ds", "mock_ds", boto3_name="ds") mock_ds = lazy_load(".ds", "mock_ds", boto3_name="ds")
mock_dynamodb = lazy_load(".dynamodb", "mock_dynamodb", warn_repurpose=True) mock_dynamodb = lazy_load(".dynamodb", "mock_dynamodb", warn_repurpose=True)
mock_dynamodb_deprecated = lazy_load(".dynamodb", "mock_dynamodb_deprecated")
mock_dynamodb2 = lazy_load(".dynamodb2", "mock_dynamodb2", backend="dynamodb_backends2") mock_dynamodb2 = lazy_load(".dynamodb2", "mock_dynamodb2", backend="dynamodb_backends2")
mock_dynamodb2_deprecated = lazy_load(".dynamodb2", "mock_dynamodb2_deprecated")
mock_dynamodbstreams = lazy_load(".dynamodbstreams", "mock_dynamodbstreams") mock_dynamodbstreams = lazy_load(".dynamodbstreams", "mock_dynamodbstreams")
mock_elasticbeanstalk = lazy_load( mock_elasticbeanstalk = lazy_load(
".elasticbeanstalk", "mock_elasticbeanstalk", backend="eb_backends" ".elasticbeanstalk", "mock_elasticbeanstalk", backend="eb_backends"
) )
mock_ec2 = lazy_load(".ec2", "mock_ec2") mock_ec2 = lazy_load(".ec2", "mock_ec2")
mock_ec2_deprecated = lazy_load(".ec2", "mock_ec2_deprecated")
mock_ec2instanceconnect = lazy_load(".ec2instanceconnect", "mock_ec2instanceconnect") mock_ec2instanceconnect = lazy_load(".ec2instanceconnect", "mock_ec2instanceconnect")
mock_ecr = lazy_load(".ecr", "mock_ecr") mock_ecr = lazy_load(".ecr", "mock_ecr")
mock_ecr_deprecated = lazy_load(".ecr", "mock_ecr_deprecated")
mock_ecs = lazy_load(".ecs", "mock_ecs") mock_ecs = lazy_load(".ecs", "mock_ecs")
mock_ecs_deprecated = lazy_load(".ecs", "mock_ecs_deprecated")
mock_elastictranscoder = lazy_load(".elastictranscoder", "mock_elastictranscoder") mock_elastictranscoder = lazy_load(".elastictranscoder", "mock_elastictranscoder")
mock_elb = lazy_load(".elb", "mock_elb") mock_elb = lazy_load(".elb", "mock_elb")
mock_elb_deprecated = lazy_load(".elb", "mock_elb_deprecated")
mock_elbv2 = lazy_load(".elbv2", "mock_elbv2") mock_elbv2 = lazy_load(".elbv2", "mock_elbv2")
mock_emr = lazy_load(".emr", "mock_emr") mock_emr = lazy_load(".emr", "mock_emr")
mock_emr_deprecated = lazy_load(".emr", "mock_emr_deprecated")
mock_emrcontainers = lazy_load( mock_emrcontainers = lazy_load(
".emrcontainers", "mock_emrcontainers", boto3_name="emr-containers" ".emrcontainers", "mock_emrcontainers", boto3_name="emr-containers"
) )
@ -96,31 +75,22 @@ mock_events = lazy_load(".events", "mock_events")
mock_firehose = lazy_load(".firehose", "mock_firehose") mock_firehose = lazy_load(".firehose", "mock_firehose")
mock_forecast = lazy_load(".forecast", "mock_forecast") mock_forecast = lazy_load(".forecast", "mock_forecast")
mock_glacier = lazy_load(".glacier", "mock_glacier") mock_glacier = lazy_load(".glacier", "mock_glacier")
mock_glacier_deprecated = lazy_load(".glacier", "mock_glacier_deprecated")
mock_glue = lazy_load(".glue", "mock_glue") mock_glue = lazy_load(".glue", "mock_glue")
mock_guardduty = lazy_load(".guardduty", "mock_guardduty") mock_guardduty = lazy_load(".guardduty", "mock_guardduty")
mock_iam = lazy_load(".iam", "mock_iam") mock_iam = lazy_load(".iam", "mock_iam")
mock_iam_deprecated = lazy_load(".iam", "mock_iam_deprecated")
mock_iot = lazy_load(".iot", "mock_iot") mock_iot = lazy_load(".iot", "mock_iot")
mock_iotdata = lazy_load(".iotdata", "mock_iotdata", boto3_name="iot-data") mock_iotdata = lazy_load(".iotdata", "mock_iotdata", boto3_name="iot-data")
mock_kinesis = lazy_load(".kinesis", "mock_kinesis") mock_kinesis = lazy_load(".kinesis", "mock_kinesis")
mock_kinesis_deprecated = lazy_load(".kinesis", "mock_kinesis_deprecated")
mock_kms = lazy_load(".kms", "mock_kms") mock_kms = lazy_load(".kms", "mock_kms")
mock_kms_deprecated = lazy_load(".kms", "mock_kms_deprecated")
mock_logs = lazy_load(".logs", "mock_logs") mock_logs = lazy_load(".logs", "mock_logs")
mock_logs_deprecated = lazy_load(".logs", "mock_logs_deprecated")
mock_managedblockchain = lazy_load(".managedblockchain", "mock_managedblockchain") mock_managedblockchain = lazy_load(".managedblockchain", "mock_managedblockchain")
mock_opsworks = lazy_load(".opsworks", "mock_opsworks") mock_opsworks = lazy_load(".opsworks", "mock_opsworks")
mock_opsworks_deprecated = lazy_load(".opsworks", "mock_opsworks_deprecated")
mock_organizations = lazy_load(".organizations", "mock_organizations") mock_organizations = lazy_load(".organizations", "mock_organizations")
mock_polly = lazy_load(".polly", "mock_polly") mock_polly = lazy_load(".polly", "mock_polly")
mock_ram = lazy_load(".ram", "mock_ram") mock_ram = lazy_load(".ram", "mock_ram")
mock_rds = lazy_load(".rds", "mock_rds", warn_repurpose=True) mock_rds = lazy_load(".rds", "mock_rds", warn_repurpose=True)
mock_rds_deprecated = lazy_load(".rds", "mock_rds_deprecated")
mock_rds2 = lazy_load(".rds2", "mock_rds2", boto3_name="rds") mock_rds2 = lazy_load(".rds2", "mock_rds2", boto3_name="rds")
mock_rds2_deprecated = lazy_load(".rds2", "mock_rds2_deprecated")
mock_redshift = lazy_load(".redshift", "mock_redshift") mock_redshift = lazy_load(".redshift", "mock_redshift")
mock_redshift_deprecated = lazy_load(".redshift", "mock_redshift_deprecated")
mock_resourcegroups = lazy_load( mock_resourcegroups = lazy_load(
".resourcegroups", "mock_resourcegroups", boto3_name="resource-groups" ".resourcegroups", "mock_resourcegroups", boto3_name="resource-groups"
) )
@ -128,29 +98,22 @@ mock_resourcegroupstaggingapi = lazy_load(
".resourcegroupstaggingapi", "mock_resourcegroupstaggingapi" ".resourcegroupstaggingapi", "mock_resourcegroupstaggingapi"
) )
mock_route53 = lazy_load(".route53", "mock_route53") mock_route53 = lazy_load(".route53", "mock_route53")
mock_route53_deprecated = lazy_load(".route53", "mock_route53_deprecated")
mock_route53resolver = lazy_load( mock_route53resolver = lazy_load(
".route53resolver", "mock_route53resolver", boto3_name="route53resolver" ".route53resolver", "mock_route53resolver", boto3_name="route53resolver"
) )
mock_s3 = lazy_load(".s3", "mock_s3") mock_s3 = lazy_load(".s3", "mock_s3")
mock_s3_deprecated = lazy_load(".s3", "mock_s3_deprecated")
mock_sagemaker = lazy_load(".sagemaker", "mock_sagemaker") mock_sagemaker = lazy_load(".sagemaker", "mock_sagemaker")
mock_secretsmanager = lazy_load(".secretsmanager", "mock_secretsmanager") mock_secretsmanager = lazy_load(".secretsmanager", "mock_secretsmanager")
mock_ses = lazy_load(".ses", "mock_ses") mock_ses = lazy_load(".ses", "mock_ses")
mock_ses_deprecated = lazy_load(".ses", "mock_ses_deprecated")
mock_sns = lazy_load(".sns", "mock_sns") mock_sns = lazy_load(".sns", "mock_sns")
mock_sns_deprecated = lazy_load(".sns", "mock_sns_deprecated")
mock_sqs = lazy_load(".sqs", "mock_sqs") mock_sqs = lazy_load(".sqs", "mock_sqs")
mock_sqs_deprecated = lazy_load(".sqs", "mock_sqs_deprecated")
mock_ssm = lazy_load(".ssm", "mock_ssm") mock_ssm = lazy_load(".ssm", "mock_ssm")
mock_ssoadmin = lazy_load(".ssoadmin", "mock_ssoadmin", boto3_name="sso-admin") mock_ssoadmin = lazy_load(".ssoadmin", "mock_ssoadmin", boto3_name="sso-admin")
mock_stepfunctions = lazy_load( mock_stepfunctions = lazy_load(
".stepfunctions", "mock_stepfunctions", backend="stepfunction_backends" ".stepfunctions", "mock_stepfunctions", backend="stepfunction_backends"
) )
mock_sts = lazy_load(".sts", "mock_sts") mock_sts = lazy_load(".sts", "mock_sts")
mock_sts_deprecated = lazy_load(".sts", "mock_sts_deprecated")
mock_swf = lazy_load(".swf", "mock_swf") mock_swf = lazy_load(".swf", "mock_swf")
mock_swf_deprecated = lazy_load(".swf", "mock_swf_deprecated")
mock_timestreamwrite = lazy_load( mock_timestreamwrite = lazy_load(
".timestreamwrite", "mock_timestreamwrite", boto3_name="timestream-write" ".timestreamwrite", "mock_timestreamwrite", boto3_name="timestream-write"
) )

View File

@ -1,6 +1,5 @@
from .models import apigateway_backends from .models import apigateway_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
apigateway_backend = apigateway_backends["us-east-1"] apigateway_backend = apigateway_backends["us-east-1"]
mock_apigateway = base_decorator(apigateway_backends) mock_apigateway = base_decorator(apigateway_backends)
mock_apigateway_deprecated = deprecated_base_decorator(apigateway_backends)

View File

@ -1,6 +1,5 @@
from .models import athena_backends from .models import athena_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
athena_backend = athena_backends["us-east-1"] athena_backend = athena_backends["us-east-1"]
mock_athena = base_decorator(athena_backends) mock_athena = base_decorator(athena_backends)
mock_athena_deprecated = deprecated_base_decorator(athena_backends)

View File

@ -1,6 +1,5 @@
from .models import autoscaling_backends from .models import autoscaling_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
autoscaling_backend = autoscaling_backends["us-east-1"] autoscaling_backend = autoscaling_backends["us-east-1"]
mock_autoscaling = base_decorator(autoscaling_backends) mock_autoscaling = base_decorator(autoscaling_backends)
mock_autoscaling_deprecated = deprecated_base_decorator(autoscaling_backends)

View File

@ -1,6 +1,5 @@
from .models import lambda_backends from .models import lambda_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
lambda_backend = lambda_backends["us-east-1"] lambda_backend = lambda_backends["us-east-1"]
mock_lambda = base_decorator(lambda_backends) mock_lambda = base_decorator(lambda_backends)
mock_lambda_deprecated = deprecated_base_decorator(lambda_backends)

View File

@ -1,6 +1,5 @@
from .models import cloudformation_backends from .models import cloudformation_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
cloudformation_backend = cloudformation_backends["us-east-1"] cloudformation_backend = cloudformation_backends["us-east-1"]
mock_cloudformation = base_decorator(cloudformation_backends) mock_cloudformation = base_decorator(cloudformation_backends)
mock_cloudformation_deprecated = deprecated_base_decorator(cloudformation_backends)

View File

@ -57,7 +57,6 @@ from .exceptions import (
ValidationError, ValidationError,
UnsupportedAttribute, UnsupportedAttribute,
) )
from moto.packages.boto.cloudformation.stack import Output
# List of supported CloudFormation models # List of supported CloudFormation models
MODEL_LIST = CloudFormationModel.__subclasses__() MODEL_LIST = CloudFormationModel.__subclasses__()
@ -78,6 +77,17 @@ DEFAULT_REGION = "us-east-1"
logger = logging.getLogger("moto") logger = logging.getLogger("moto")
class Output(object):
def __init__(self, connection=None):
self.connection = connection
self.description = None
self.key = None
self.value = None
def __repr__(self):
return 'Output:"%s"="%s"' % (self.key, self.value)
class LazyDict(dict): class LazyDict(dict):
def __getitem__(self, key): def __getitem__(self, key):
val = dict.__getitem__(self, key) val = dict.__getitem__(self, key)

View File

@ -1,5 +1,4 @@
from .models import cloudwatch_backends from .models import cloudwatch_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
mock_cloudwatch = base_decorator(cloudwatch_backends) mock_cloudwatch = base_decorator(cloudwatch_backends)
mock_cloudwatch_deprecated = deprecated_base_decorator(cloudwatch_backends)

View File

@ -1,5 +1,4 @@
from .models import cognitoidentity_backends from .models import cognitoidentity_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
mock_cognitoidentity = base_decorator(cognitoidentity_backends) mock_cognitoidentity = base_decorator(cognitoidentity_backends)
mock_cognitoidentity_deprecated = deprecated_base_decorator(cognitoidentity_backends)

View File

@ -1,5 +1,4 @@
from .models import cognitoidp_backends from .models import cognitoidp_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
mock_cognitoidp = base_decorator(cognitoidp_backends) mock_cognitoidp = base_decorator(cognitoidp_backends)
mock_cognitoidp_deprecated = deprecated_base_decorator(cognitoidp_backends)

View File

@ -16,7 +16,6 @@ from botocore.awsrequest import AWSResponse
from moto import settings from moto import settings
import responses import responses
from moto.packages.httpretty import HTTPretty
from unittest.mock import patch from unittest.mock import patch
from .custom_responses_mock import ( from .custom_responses_mock import (
get_response_mock, get_response_mock,
@ -25,7 +24,6 @@ from .custom_responses_mock import (
reset_responses_mock, reset_responses_mock,
) )
from .utils import ( from .utils import (
convert_httpretty_response,
convert_regex_to_flask_path, convert_regex_to_flask_path,
convert_flask_to_responses_response, convert_flask_to_responses_response,
) )
@ -177,28 +175,6 @@ class BaseMockAWS:
del os.environ[k] del os.environ[k]
class HttprettyMockAWS(BaseMockAWS):
def reset(self):
HTTPretty.reset()
def enable_patching(self):
if not HTTPretty.is_enabled():
HTTPretty.enable()
for method in HTTPretty.METHODS:
for backend in self.backends_for_urls.values():
for key, value in backend.urls.items():
HTTPretty.register_uri(
method=method,
uri=re.compile(key),
body=convert_httpretty_response(value),
)
def disable_patching(self):
HTTPretty.disable()
HTTPretty.reset()
RESPONSES_METHODS = [ RESPONSES_METHODS = [
responses.GET, responses.GET,
responses.DELETE, responses.DELETE,
@ -681,12 +657,6 @@ class BaseBackend:
else: else:
return mocked_backend return mocked_backend
def deprecated_decorator(self, func=None):
if func:
return HttprettyMockAWS({"global": self})(func)
else:
return HttprettyMockAWS({"global": self})
# def list_config_service_resources(self, resource_ids, resource_name, limit, next_token): # def list_config_service_resources(self, resource_ids, resource_name, limit, next_token):
# """For AWS Config. This will list all of the resources of the given type and optional resource name and region""" # """For AWS Config. This will list all of the resources of the given type and optional resource name and region"""
# raise NotImplementedError() # raise NotImplementedError()
@ -792,7 +762,7 @@ class base_decorator:
self.backends = backends self.backends = backends
def __call__(self, func=None): def __call__(self, func=None):
if self.mock_backend != HttprettyMockAWS and settings.TEST_SERVER_MODE: if settings.TEST_SERVER_MODE:
mocked_backend = ServerModeMockAWS(self.backends) mocked_backend = ServerModeMockAWS(self.backends)
else: else:
mocked_backend = self.mock_backend(self.backends) mocked_backend = self.mock_backend(self.backends)
@ -803,10 +773,6 @@ class base_decorator:
return mocked_backend return mocked_backend
class deprecated_base_decorator(base_decorator):
mock_backend = HttprettyMockAWS
class MotoAPIBackend(BaseBackend): class MotoAPIBackend(BaseBackend):
def reset(self): def reset(self):
import moto.backends as backends import moto.backends as backends

View File

@ -106,29 +106,7 @@ def convert_regex_to_flask_path(url_path):
return url_path return url_path
class convert_httpretty_response(object): class convert_to_flask_response(object):
def __init__(self, callback):
self.callback = callback
@property
def __name__(self):
# For instance methods, use class and method names. Otherwise
# use module and method name
if inspect.ismethod(self.callback):
outer = self.callback.__self__.__class__.__name__
else:
outer = self.callback.__module__
return "{0}.{1}".format(outer, self.callback.__name__)
def __call__(self, request, url, headers, **kwargs):
result = self.callback(request, url, headers)
status, headers, response = result
if "server" not in headers:
headers["server"] = "amazon.com"
return status, headers, response
class convert_flask_to_httpretty_response(object):
def __init__(self, callback): def __init__(self, callback):
self.callback = callback self.callback = callback

View File

@ -1,5 +1,4 @@
from .models import datapipeline_backends from .models import datapipeline_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
mock_datapipeline = base_decorator(datapipeline_backends) mock_datapipeline = base_decorator(datapipeline_backends)
mock_datapipeline_deprecated = deprecated_base_decorator(datapipeline_backends)

View File

@ -1,6 +1,5 @@
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
from .models import datasync_backends from .models import datasync_backends
datasync_backend = datasync_backends["us-east-1"] datasync_backend = datasync_backends["us-east-1"]
mock_datasync = base_decorator(datasync_backends) mock_datasync = base_decorator(datasync_backends)
mock_datasync_deprecated = deprecated_base_decorator(datasync_backends)

View File

@ -2,4 +2,3 @@ from .models import dynamodb_backend
dynamodb_backends = {"global": dynamodb_backend} dynamodb_backends = {"global": dynamodb_backend}
mock_dynamodb = dynamodb_backend.decorator mock_dynamodb = dynamodb_backend.decorator
mock_dynamodb_deprecated = dynamodb_backend.deprecated_decorator

View File

@ -1,6 +1,5 @@
from moto.dynamodb2.models import dynamodb_backends as dynamodb_backends2 from moto.dynamodb2.models import dynamodb_backends as dynamodb_backends2
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
dynamodb_backend2 = dynamodb_backends2["us-east-1"] dynamodb_backend2 = dynamodb_backends2["us-east-1"]
mock_dynamodb2 = base_decorator(dynamodb_backends2) mock_dynamodb2 = base_decorator(dynamodb_backends2)
mock_dynamodb2_deprecated = deprecated_base_decorator(dynamodb_backends2)

View File

@ -1,5 +1,4 @@
import re import re
import sys
from moto.dynamodb2.exceptions import ( from moto.dynamodb2.exceptions import (
InvalidTokenException, InvalidTokenException,
@ -148,15 +147,8 @@ class ExpressionTokenizer(object):
self.token_list = [] self.token_list = []
self.staged_characters = "" self.staged_characters = ""
@classmethod
def is_py2(cls):
return sys.version_info[0] == 2
@classmethod @classmethod
def make_list(cls, input_expression_str): def make_list(cls, input_expression_str):
if cls.is_py2():
pass
else:
assert isinstance(input_expression_str, str) assert isinstance(input_expression_str, str)
return ExpressionTokenizer(input_expression_str)._make_list() return ExpressionTokenizer(input_expression_str)._make_list()

View File

@ -1,6 +1,5 @@
from .models import ec2_backends from .models import ec2_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
ec2_backend = ec2_backends["us-east-1"] ec2_backend = ec2_backends["us-east-1"]
mock_ec2 = base_decorator(ec2_backends) mock_ec2 = base_decorator(ec2_backends)
mock_ec2_deprecated = deprecated_base_decorator(ec2_backends)

View File

@ -1,6 +1,5 @@
from .models import ecr_backends from .models import ecr_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
ecr_backend = ecr_backends["us-east-1"] ecr_backend = ecr_backends["us-east-1"]
mock_ecr = base_decorator(ecr_backends) mock_ecr = base_decorator(ecr_backends)
mock_ecr_deprecated = deprecated_base_decorator(ecr_backends)

View File

@ -1,6 +1,5 @@
from .models import ecs_backends from .models import ecs_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
ecs_backend = ecs_backends["us-east-1"] ecs_backend = ecs_backends["us-east-1"]
mock_ecs = base_decorator(ecs_backends) mock_ecs = base_decorator(ecs_backends)
mock_ecs_deprecated = deprecated_base_decorator(ecs_backends)

View File

@ -1,6 +1,5 @@
from .models import elb_backends from .models import elb_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
elb_backend = elb_backends["us-east-1"] elb_backend = elb_backends["us-east-1"]
mock_elb = base_decorator(elb_backends) mock_elb = base_decorator(elb_backends)
mock_elb_deprecated = deprecated_base_decorator(elb_backends)

View File

@ -2,13 +2,6 @@ import datetime
import pytz import pytz
from moto.packages.boto.ec2.elb.attributes import (
LbAttributes,
ConnectionSettingAttribute,
ConnectionDrainingAttribute,
AccessLogAttribute,
CrossZoneLoadBalancingAttribute,
)
from moto.packages.boto.ec2.elb.policies import Policies, OtherPolicy from moto.packages.boto.ec2.elb.policies import Policies, OtherPolicy
from collections import OrderedDict from collections import OrderedDict
from moto.core import BaseBackend, BaseModel, CloudFormationModel from moto.core import BaseBackend, BaseModel, CloudFormationModel
@ -248,23 +241,11 @@ class FakeLoadBalancer(CloudFormationModel):
@classmethod @classmethod
def get_default_attributes(cls): def get_default_attributes(cls):
attributes = LbAttributes() attributes = dict()
attributes["cross_zone_load_balancing"] = {"enabled": False}
cross_zone_load_balancing = CrossZoneLoadBalancingAttribute() attributes["connection_draining"] = {"enabled": False}
cross_zone_load_balancing.enabled = False attributes["access_log"] = {"enabled": False}
attributes.cross_zone_load_balancing = cross_zone_load_balancing attributes["connection_settings"] = {"idle_timeout": 60}
connection_draining = ConnectionDrainingAttribute()
connection_draining.enabled = False
attributes.connection_draining = connection_draining
access_log = AccessLogAttribute()
access_log.enabled = False
attributes.access_log = access_log
connection_settings = ConnectionSettingAttribute()
connection_settings.idle_timeout = 60
attributes.connecting_settings = connection_settings
return attributes return attributes
@ -468,25 +449,27 @@ class ELBBackend(BaseBackend):
return load_balancer return load_balancer
def set_cross_zone_load_balancing_attribute(self, load_balancer_name, attribute): def modify_load_balancer_attributes(
self,
load_balancer_name,
cross_zone=None,
connection_settings=None,
connection_draining=None,
access_log=None,
):
load_balancer = self.get_load_balancer(load_balancer_name) load_balancer = self.get_load_balancer(load_balancer_name)
load_balancer.attributes.cross_zone_load_balancing = attribute if cross_zone:
return load_balancer load_balancer.attributes["cross_zone_load_balancing"] = cross_zone
if connection_settings:
def set_access_log_attribute(self, load_balancer_name, attribute): load_balancer.attributes["connection_settings"] = connection_settings
load_balancer = self.get_load_balancer(load_balancer_name) if connection_draining:
load_balancer.attributes.access_log = attribute load_balancer.attributes["connection_draining"] = connection_draining
return load_balancer if "timeout" not in connection_draining:
load_balancer.attributes["connection_draining"][
def set_connection_draining_attribute(self, load_balancer_name, attribute): "timeout"
load_balancer = self.get_load_balancer(load_balancer_name) ] = 300 # default
load_balancer.attributes.connection_draining = attribute if access_log:
return load_balancer load_balancer.attributes["access_log"] = access_log
def set_connection_settings_attribute(self, load_balancer_name, attribute):
load_balancer = self.get_load_balancer(load_balancer_name)
load_balancer.attributes.connecting_settings = attribute
return load_balancer
def create_lb_other_policy(self, load_balancer_name, other_policy): def create_lb_other_policy(self, load_balancer_name, other_policy):
load_balancer = self.get_load_balancer(load_balancer_name) load_balancer = self.get_load_balancer(load_balancer_name)

View File

@ -1,9 +1,3 @@
from moto.packages.boto.ec2.elb.attributes import (
ConnectionSettingAttribute,
ConnectionDrainingAttribute,
AccessLogAttribute,
CrossZoneLoadBalancingAttribute,
)
from moto.packages.boto.ec2.elb.policies import AppCookieStickinessPolicy, OtherPolicy from moto.packages.boto.ec2.elb.policies import AppCookieStickinessPolicy, OtherPolicy
from moto.core.responses import BaseResponse from moto.core.responses import BaseResponse
@ -153,40 +147,30 @@ class ELBResponse(BaseResponse):
"LoadBalancerAttributes.CrossZoneLoadBalancing." "LoadBalancerAttributes.CrossZoneLoadBalancing."
) )
if cross_zone: if cross_zone:
attribute = CrossZoneLoadBalancingAttribute() self.elb_backend.modify_load_balancer_attributes(
attribute.enabled = cross_zone["enabled"] == "true" load_balancer_name, cross_zone=cross_zone
self.elb_backend.set_cross_zone_load_balancing_attribute(
load_balancer_name, attribute
) )
access_log = self._get_dict_param("LoadBalancerAttributes.AccessLog.") access_log = self._get_dict_param("LoadBalancerAttributes.AccessLog.")
if access_log: if access_log:
attribute = AccessLogAttribute() self.elb_backend.modify_load_balancer_attributes(
attribute.enabled = access_log["enabled"] == "true" load_balancer_name, access_log=access_log
attribute.s3_bucket_name = access_log["s3_bucket_name"] )
attribute.s3_bucket_prefix = access_log["s3_bucket_prefix"]
attribute.emit_interval = access_log["emit_interval"]
self.elb_backend.set_access_log_attribute(load_balancer_name, attribute)
connection_draining = self._get_dict_param( connection_draining = self._get_dict_param(
"LoadBalancerAttributes.ConnectionDraining." "LoadBalancerAttributes.ConnectionDraining."
) )
if connection_draining: if connection_draining:
attribute = ConnectionDrainingAttribute() self.elb_backend.modify_load_balancer_attributes(
attribute.enabled = connection_draining["enabled"] == "true" load_balancer_name, connection_draining=connection_draining
attribute.timeout = connection_draining.get("timeout", 300)
self.elb_backend.set_connection_draining_attribute(
load_balancer_name, attribute
) )
connection_settings = self._get_dict_param( connection_settings = self._get_dict_param(
"LoadBalancerAttributes.ConnectionSettings." "LoadBalancerAttributes.ConnectionSettings."
) )
if connection_settings: if connection_settings:
attribute = ConnectionSettingAttribute() self.elb_backend.modify_load_balancer_attributes(
attribute.idle_timeout = connection_settings["idle_timeout"] load_balancer_name, connection_settings=connection_settings
self.elb_backend.set_connection_settings_attribute(
load_balancer_name, attribute
) )
template = self.response_template(MODIFY_ATTRIBUTES_TEMPLATE) template = self.response_template(MODIFY_ATTRIBUTES_TEMPLATE)
@ -628,23 +612,23 @@ DESCRIBE_ATTRIBUTES_TEMPLATE = """<DescribeLoadBalancerAttributesResponse xmlns
<DescribeLoadBalancerAttributesResult> <DescribeLoadBalancerAttributesResult>
<LoadBalancerAttributes> <LoadBalancerAttributes>
<AccessLog> <AccessLog>
<Enabled>{{ attributes.access_log.enabled }}</Enabled> <Enabled>{{ attributes["access_log"]["enabled"] }}</Enabled>
{% if attributes.access_log.enabled %} {% if attributes["access_log"]["enabled"] == 'true' %}
<S3BucketName>{{ attributes.access_log.s3_bucket_name }}</S3BucketName> <S3BucketName>{{ attributes["access_log"]["s3_bucket_name"] }}</S3BucketName>
<S3BucketPrefix>{{ attributes.access_log.s3_bucket_prefix }}</S3BucketPrefix> <S3BucketPrefix>{{ attributes["access_log"]["s3_bucket_prefix"] }}</S3BucketPrefix>
<EmitInterval>{{ attributes.access_log.emit_interval }}</EmitInterval> <EmitInterval>{{ attributes["access_log"]["emit_interval"] }}</EmitInterval>
{% endif %} {% endif %}
</AccessLog> </AccessLog>
<ConnectionSettings> <ConnectionSettings>
<IdleTimeout>{{ attributes.connecting_settings.idle_timeout }}</IdleTimeout> <IdleTimeout>{{ attributes["connection_settings"]["idle_timeout"] }}</IdleTimeout>
</ConnectionSettings> </ConnectionSettings>
<CrossZoneLoadBalancing> <CrossZoneLoadBalancing>
<Enabled>{{ attributes.cross_zone_load_balancing.enabled }}</Enabled> <Enabled>{{ attributes.cross_zone_load_balancing.enabled }}</Enabled>
</CrossZoneLoadBalancing> </CrossZoneLoadBalancing>
<ConnectionDraining> <ConnectionDraining>
{% if attributes.connection_draining.enabled %} {% if attributes["connection_draining"]["enabled"] == 'true' %}
<Enabled>true</Enabled> <Enabled>true</Enabled>
<Timeout>{{ attributes.connection_draining.timeout }}</Timeout> <Timeout>{{ attributes["connection_draining"]["timeout"] }}</Timeout>
{% else %} {% else %}
<Enabled>false</Enabled> <Enabled>false</Enabled>
{% endif %} {% endif %}
@ -662,23 +646,23 @@ MODIFY_ATTRIBUTES_TEMPLATE = """<ModifyLoadBalancerAttributesResponse xmlns="htt
<LoadBalancerName>{{ load_balancer.name }}</LoadBalancerName> <LoadBalancerName>{{ load_balancer.name }}</LoadBalancerName>
<LoadBalancerAttributes> <LoadBalancerAttributes>
<AccessLog> <AccessLog>
<Enabled>{{ attributes.access_log.enabled }}</Enabled> <Enabled>{{ attributes["access_log"]["enabled"] == 'true' }}</Enabled>
{% if attributes.access_log.enabled %} {% if attributes["access_log"]["enabled"] == 'true' %}
<S3BucketName>{{ attributes.access_log.s3_bucket_name }}</S3BucketName> <S3BucketName>{{ attributes["access_log"]["s3_bucket_name"] }}</S3BucketName>
<S3BucketPrefix>{{ attributes.access_log.s3_bucket_prefix }}</S3BucketPrefix> <S3BucketPrefix>{{ attributes["access_log"]["s3_bucket_prefix"] }}</S3BucketPrefix>
<EmitInterval>{{ attributes.access_log.emit_interval }}</EmitInterval> <EmitInterval>{{ attributes["access_log"]["emit_interval"] }}</EmitInterval>
{% endif %} {% endif %}
</AccessLog> </AccessLog>
<ConnectionSettings> <ConnectionSettings>
<IdleTimeout>{{ attributes.connecting_settings.idle_timeout }}</IdleTimeout> <IdleTimeout>{{ attributes["connection_settings"]["idle_timeout"] }}</IdleTimeout>
</ConnectionSettings> </ConnectionSettings>
<CrossZoneLoadBalancing> <CrossZoneLoadBalancing>
<Enabled>{{ attributes.cross_zone_load_balancing.enabled }}</Enabled> <Enabled>{{ attributes.cross_zone_load_balancing.enabled }}</Enabled>
</CrossZoneLoadBalancing> </CrossZoneLoadBalancing>
<ConnectionDraining> <ConnectionDraining>
{% if attributes.connection_draining.enabled %} {% if attributes["connection_draining"]["enabled"] == 'true' %}
<Enabled>true</Enabled> <Enabled>true</Enabled>
<Timeout>{{ attributes.connection_draining.timeout }}</Timeout> <Timeout>{{ attributes["connection_draining"]["timeout"] }}</Timeout>
{% else %} {% else %}
<Enabled>false</Enabled> <Enabled>false</Enabled>
{% endif %} {% endif %}

View File

@ -1,6 +1,5 @@
from .models import emr_backends from .models import emr_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
emr_backend = emr_backends["us-east-1"] emr_backend = emr_backends["us-east-1"]
mock_emr = base_decorator(emr_backends) mock_emr = base_decorator(emr_backends)
mock_emr_deprecated = deprecated_base_decorator(emr_backends)

View File

@ -1,6 +1,5 @@
from .models import glacier_backends from .models import glacier_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
glacier_backend = glacier_backends["us-east-1"] glacier_backend = glacier_backends["us-east-1"]
mock_glacier = base_decorator(glacier_backends) mock_glacier = base_decorator(glacier_backends)
mock_glacier_deprecated = deprecated_base_decorator(glacier_backends)

View File

@ -2,4 +2,3 @@ from .models import iam_backend
iam_backends = {"global": iam_backend} iam_backends = {"global": iam_backend}
mock_iam = iam_backend.decorator mock_iam = iam_backend.decorator
mock_iam_deprecated = iam_backend.deprecated_decorator

View File

@ -1,6 +1,5 @@
from .models import kinesis_backends from .models import kinesis_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
kinesis_backend = kinesis_backends["us-east-1"] kinesis_backend = kinesis_backends["us-east-1"]
mock_kinesis = base_decorator(kinesis_backends) mock_kinesis = base_decorator(kinesis_backends)
mock_kinesis_deprecated = deprecated_base_decorator(kinesis_backends)

View File

@ -1,6 +1,5 @@
from .models import kms_backends from .models import kms_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
kms_backend = kms_backends["us-east-1"] kms_backend = kms_backends["us-east-1"]
mock_kms = base_decorator(kms_backends) mock_kms = base_decorator(kms_backends)
mock_kms_deprecated = deprecated_base_decorator(kms_backends)

View File

@ -1,5 +1,4 @@
from .models import logs_backends from .models import logs_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
mock_logs = base_decorator(logs_backends) mock_logs = base_decorator(logs_backends)
mock_logs_deprecated = deprecated_base_decorator(logs_backends)

View File

@ -1,8 +1,5 @@
from .models import managedblockchain_backends from .models import managedblockchain_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
managedblockchain_backend = managedblockchain_backends["us-east-1"] managedblockchain_backend = managedblockchain_backends["us-east-1"]
mock_managedblockchain = base_decorator(managedblockchain_backends) mock_managedblockchain = base_decorator(managedblockchain_backends)
mock_managedblockchain_deprecated = deprecated_base_decorator(
managedblockchain_backends
)

View File

@ -1,6 +1,5 @@
from .models import opsworks_backends from .models import opsworks_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
opsworks_backend = opsworks_backends["us-east-1"] opsworks_backend = opsworks_backends["us-east-1"]
mock_opsworks = base_decorator(opsworks_backends) mock_opsworks = base_decorator(opsworks_backends)
mock_opsworks_deprecated = deprecated_base_decorator(opsworks_backends)

View File

@ -1,9 +0,0 @@
class Output(object):
def __init__(self, connection=None):
self.connection = connection
self.description = None
self.key = None
self.value = None
def __repr__(self):
return 'Output:"%s"="%s"' % (self.key, self.value)

View File

@ -1,100 +0,0 @@
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish, dis-
# tribute, sublicense, and/or sell copies of the Software, and to permit
# persons to whom the Software is furnished to do so, subject to the fol-
# lowing conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
# Created by Chris Huegle for TellApart, Inc.
class ConnectionSettingAttribute(object):
"""
Represents the ConnectionSetting segment of ELB Attributes.
"""
def __init__(self, connection=None):
self.idle_timeout = None
def __repr__(self):
return "ConnectionSettingAttribute(%s)" % (self.idle_timeout)
class CrossZoneLoadBalancingAttribute(object):
"""
Represents the CrossZoneLoadBalancing segement of ELB Attributes.
"""
def __init__(self, connection=None):
self.enabled = None
def __repr__(self):
return "CrossZoneLoadBalancingAttribute(%s)" % (self.enabled)
class AccessLogAttribute(object):
"""
Represents the AccessLog segment of ELB attributes.
"""
def __init__(self, connection=None):
self.enabled = None
self.s3_bucket_name = None
self.s3_bucket_prefix = None
self.emit_interval = None
def __repr__(self):
return "AccessLog(%s, %s, %s, %s)" % (
self.enabled,
self.s3_bucket_name,
self.s3_bucket_prefix,
self.emit_interval,
)
class ConnectionDrainingAttribute(object):
"""
Represents the ConnectionDraining segment of ELB attributes.
"""
def __init__(self, connection=None):
self.enabled = None
self.timeout = None
def __repr__(self):
return "ConnectionDraining(%s, %s)" % (self.enabled, self.timeout)
class LbAttributes(object):
"""
Represents the Attributes of an Elastic Load Balancer.
"""
def __init__(self, connection=None):
self.connection = connection
self.cross_zone_load_balancing = CrossZoneLoadBalancingAttribute(
self.connection
)
self.access_log = AccessLogAttribute(self.connection)
self.connection_draining = ConnectionDrainingAttribute(self.connection)
self.connecting_settings = ConnectionSettingAttribute(self.connection)
def __repr__(self):
return "LbAttributes(%s, %s, %s, %s)" % (
repr(self.cross_zone_load_balancing),
repr(self.access_log),
repr(self.connection_draining),
repr(self.connecting_settings),
)

View File

@ -1,61 +0,0 @@
# #!/usr/bin/env python
# -*- coding: utf-8 -*-
# <HTTPretty - HTTP client mock for Python>
# Copyright (C) <2011-2013> Gabriel Falcão <gabriel@nacaolivre.org>
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following
# conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
from __future__ import unicode_literals
__version__ = version = "0.8.10"
from .core import httpretty, httprettified, EmptyRequestHeaders
from .errors import HTTPrettyError, UnmockedError
from .core import URIInfo
HTTPretty = httpretty
activate = httprettified
enable = httpretty.enable
register_uri = httpretty.register_uri
disable = httpretty.disable
is_enabled = httpretty.is_enabled
reset = httpretty.reset
Response = httpretty.Response
GET = httpretty.GET
PUT = httpretty.PUT
POST = httpretty.POST
DELETE = httpretty.DELETE
HEAD = httpretty.HEAD
PATCH = httpretty.PATCH
OPTIONS = httpretty.OPTIONS
CONNECT = httpretty.CONNECT
def last_request():
"""returns the last request"""
return httpretty.last_request
def has_request():
"""returns a boolean indicating whether any request has been made"""
return not isinstance(httpretty.last_request.headers, EmptyRequestHeaders)

View File

@ -1,106 +0,0 @@
# #!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# <HTTPretty - HTTP client mock for Python>
# Copyright (C) <2011-2013> Gabriel Falcão <gabriel@nacaolivre.org>
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following
# conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
from __future__ import unicode_literals
import sys
import types
PY3 = sys.version_info[0] == 3
if PY3: # pragma: no cover
text_type = str
byte_type = bytes
import io
StringIO = io.BytesIO
basestring = (str, bytes)
class BaseClass(object):
def __repr__(self):
return self.__str__()
else: # pragma: no cover
text_type = unicode
byte_type = str
import StringIO
StringIO = StringIO.StringIO
basestring = basestring
class BaseClass(object):
def __repr__(self):
ret = self.__str__()
if PY3: # pragma: no cover
return ret
else:
return ret.encode("utf-8")
try: # pragma: no cover
from urllib.parse import urlsplit, urlunsplit, parse_qs, quote, quote_plus, unquote
unquote_utf8 = unquote
except ImportError: # pragma: no cover
from urlparse import urlsplit, urlunsplit, parse_qs, unquote
from urllib import quote, quote_plus
def unquote_utf8(qs):
if isinstance(qs, text_type):
qs = qs.encode("utf-8")
s = unquote(qs)
if isinstance(s, byte_type):
return s.decode("utf-8")
else:
return s
try: # pragma: no cover
from http.server import BaseHTTPRequestHandler
except ImportError: # pragma: no cover
from BaseHTTPServer import BaseHTTPRequestHandler
ClassTypes = (type,)
if not PY3: # pragma: no cover
ClassTypes = (type, types.ClassType)
__all__ = [
"PY3",
"StringIO",
"text_type",
"byte_type",
"BaseClass",
"BaseHTTPRequestHandler",
"quote",
"quote_plus",
"urlunsplit",
"urlsplit",
"parse_qs",
"ClassTypes",
]

File diff suppressed because it is too large Load Diff

View File

@ -1,39 +0,0 @@
# #!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# <HTTPretty - HTTP client mock for Python>
# Copyright (C) <2011-2013> Gabriel Falcão <gabriel@nacaolivre.org>
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following
# conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
from __future__ import unicode_literals
class HTTPrettyError(Exception):
pass
class UnmockedError(HTTPrettyError):
def __init__(self):
super(UnmockedError, self).__init__(
"No mocking was registered, and real connections are "
"not allowed (httpretty.allow_net_connect = False)."
)

View File

@ -1,154 +0,0 @@
# #!/usr/bin/env python
# -*- coding: utf-8 -*-
# <HTTPretty - HTTP client mock for Python>
# Copyright (C) <2011-2013> Gabriel Falcão <gabriel@nacaolivre.org>
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following
# conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
from __future__ import unicode_literals
import re
from .compat import BaseClass
from .utils import decode_utf8
STATUSES = {
100: "Continue",
101: "Switching Protocols",
102: "Processing",
200: "OK",
201: "Created",
202: "Accepted",
203: "Non-Authoritative Information",
204: "No Content",
205: "Reset Content",
206: "Partial Content",
207: "Multi-Status",
208: "Already Reported",
226: "IM Used",
300: "Multiple Choices",
301: "Moved Permanently",
302: "Found",
303: "See Other",
304: "Not Modified",
305: "Use Proxy",
306: "Switch Proxy",
307: "Temporary Redirect",
308: "Permanent Redirect",
400: "Bad Request",
401: "Unauthorized",
402: "Payment Required",
403: "Forbidden",
404: "Not Found",
405: "Method Not Allowed",
406: "Not Acceptable",
407: "Proxy Authentication Required",
408: "Request a Timeout",
409: "Conflict",
410: "Gone",
411: "Length Required",
412: "Precondition Failed",
413: "Request Entity Too Large",
414: "Request-URI Too Long",
415: "Unsupported Media Type",
416: "Requested Range Not Satisfiable",
417: "Expectation Failed",
418: "I'm a teapot",
420: "Enhance Your Calm",
422: "Unprocessable Entity",
423: "Locked",
424: "Failed Dependency",
424: "Method Failure",
425: "Unordered Collection",
426: "Upgrade Required",
428: "Precondition Required",
429: "Too Many Requests",
431: "Request Header Fields Too Large",
444: "No Response",
449: "Retry With",
450: "Blocked by Windows Parental Controls",
451: "Unavailable For Legal Reasons",
451: "Redirect",
494: "Request Header Too Large",
495: "Cert Error",
496: "No Cert",
497: "HTTP to HTTPS",
499: "Client Closed Request",
500: "Internal Server Error",
501: "Not Implemented",
502: "Bad Gateway",
503: "Service Unavailable",
504: "Gateway Timeout",
505: "HTTP Version Not Supported",
506: "Variant Also Negotiates",
507: "Insufficient Storage",
508: "Loop Detected",
509: "Bandwidth Limit Exceeded",
510: "Not Extended",
511: "Network Authentication Required",
598: "Network read timeout error",
599: "Network connect timeout error",
}
class HttpBaseClass(BaseClass):
GET = "GET"
PUT = "PUT"
POST = "POST"
DELETE = "DELETE"
HEAD = "HEAD"
PATCH = "PATCH"
OPTIONS = "OPTIONS"
CONNECT = "CONNECT"
METHODS = (GET, PUT, POST, DELETE, HEAD, PATCH, OPTIONS, CONNECT)
def parse_requestline(s):
"""
http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5
>>> parse_requestline('GET / HTTP/1.0')
('GET', '/', '1.0')
>>> parse_requestline('post /testurl htTP/1.1')
('POST', '/testurl', '1.1')
>>> parse_requestline('Im not a RequestLine')
Traceback (most recent call last):
...
ValueError: Not a Request-Line
"""
methods = "|".join(HttpBaseClass.METHODS)
m = re.match(r"({})\s+(.*)\s+HTTP/(1.[0|1])".format(methods), s, re.I)
if m:
return m.group(1).upper(), m.group(2), m.group(3)
else:
raise ValueError("Not a Request-Line")
def last_requestline(sent_data):
"""
Find the last line in sent_data that can be parsed with parse_requestline
"""
for line in reversed(sent_data):
try:
parse_requestline(decode_utf8(line))
except ValueError:
pass
else:
return line

View File

@ -1,46 +0,0 @@
# #!/usr/bin/env python
# -*- coding: utf-8 -*-
# <HTTPretty - HTTP client mock for Python>
# Copyright (C) <2011-2013> Gabriel Falcão <gabriel@nacaolivre.org>
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following
# conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
from __future__ import unicode_literals
from .compat import byte_type, text_type
def utf8(s):
if isinstance(s, text_type):
s = s.encode("utf-8")
elif s is None:
return byte_type()
return byte_type(s)
def decode_utf8(s):
if isinstance(s, byte_type):
s = s.decode("utf-8")
elif s is None:
return text_type()
return text_type(s)

View File

@ -1,5 +1,4 @@
from .models import rds_backends from .models import rds_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
mock_rds = base_decorator(rds_backends) mock_rds = base_decorator(rds_backends)
mock_rds_deprecated = deprecated_base_decorator(rds_backends)

View File

@ -1,6 +1,5 @@
from .models import rds2_backends from .models import rds2_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
rds2_backend = rds2_backends["us-west-1"] rds2_backend = rds2_backends["us-west-1"]
mock_rds2 = base_decorator(rds2_backends) mock_rds2 = base_decorator(rds2_backends)
mock_rds2_deprecated = deprecated_base_decorator(rds2_backends)

View File

@ -1,5 +1,4 @@
from .models import redshift_backends from .models import redshift_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
mock_redshift = base_decorator(redshift_backends) mock_redshift = base_decorator(redshift_backends)
mock_redshift_deprecated = deprecated_base_decorator(redshift_backends)

View File

@ -2,4 +2,3 @@ from .models import route53_backend
route53_backends = {"global": route53_backend} route53_backends = {"global": route53_backend}
mock_route53 = route53_backend.decorator mock_route53 = route53_backend.decorator
mock_route53_deprecated = route53_backend.deprecated_decorator

View File

@ -2,4 +2,3 @@ from .models import s3_backend
s3_backends = {"global": s3_backend} s3_backends = {"global": s3_backend}
mock_s3 = s3_backend.decorator mock_s3 = s3_backend.decorator
mock_s3_deprecated = s3_backend.deprecated_decorator

View File

@ -196,18 +196,6 @@ class FakeKey(BaseModel):
def set_acl(self, acl): def set_acl(self, acl):
self.acl = acl self.acl = acl
def append_to_value(self, value):
self.contentsize += len(value)
self._value_buffer.seek(0, os.SEEK_END)
self._value_buffer.write(value)
self.last_modified = datetime.datetime.utcnow()
self._etag = None # must recalculate etag
if self._is_versioned:
self._version_id = str(uuid.uuid4())
else:
self._version_id = None
def restore(self, days): def restore(self, days):
self._expiry = datetime.datetime.utcnow() + datetime.timedelta(days) self._expiry = datetime.datetime.utcnow() + datetime.timedelta(days)
@ -1674,11 +1662,6 @@ class S3Backend(BaseBackend, CloudWatchMetricProvider):
key.lock_mode = retention[0] key.lock_mode = retention[0]
key.lock_until = retention[1] key.lock_until = retention[1]
def append_to_key(self, bucket_name, key_name, value):
key = self.get_object(bucket_name, key_name)
key.append_to_value(value)
return key
def get_object(self, bucket_name, key_name, version_id=None, part_number=None): def get_object(self, bucket_name, key_name, version_id=None, part_number=None):
key_name = clean_key_name(key_name) key_name = clean_key_name(key_name)
bucket = self.get_bucket(bucket_name) bucket = self.get_bucket(bucket_name)

View File

@ -5,10 +5,10 @@ from typing import List, Union
from botocore.awsrequest import AWSPreparedRequest from botocore.awsrequest import AWSPreparedRequest
from moto import settings
from moto.core.utils import amzn_request_id, str_to_rfc_1123_datetime from moto.core.utils import amzn_request_id, str_to_rfc_1123_datetime
from urllib.parse import ( from urllib.parse import (
parse_qs, parse_qs,
parse_qsl,
urlparse, urlparse,
unquote, unquote,
urlencode, urlencode,
@ -17,8 +17,6 @@ from urllib.parse import (
import xmltodict import xmltodict
from moto import settings
from moto.packages.httpretty.core import HTTPrettyRequest
from moto.core.responses import _TemplateEnvironmentMixin, ActionAuthenticatorMixin from moto.core.responses import _TemplateEnvironmentMixin, ActionAuthenticatorMixin
from moto.core.utils import path_url from moto.core.utils import path_url
from moto.core import ACCOUNT_ID from moto.core import ACCOUNT_ID
@ -972,13 +970,7 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin):
self._authenticate_and_authorize_s3_action() self._authenticate_and_authorize_s3_action()
# POST to bucket-url should create file from form # POST to bucket-url should create file from form
if hasattr(request, "form"):
# Not HTTPretty
form = request.form form = request.form
else:
# HTTPretty, build new form object
body = body.decode()
form = dict(parse_qsl(body))
key = form["key"] key = form["key"]
if "file" in form: if "file" in form:
@ -1028,15 +1020,11 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin):
@staticmethod @staticmethod
def _get_path(request): def _get_path(request):
if isinstance(request, HTTPrettyRequest): return (
path = request.path
else:
path = (
request.full_path request.full_path
if hasattr(request, "full_path") if hasattr(request, "full_path")
else path_url(request.url) else path_url(request.url)
) )
return path
def _bucket_response_delete_keys(self, request, body, bucket_name): def _bucket_response_delete_keys(self, request, body, bucket_name):
template = self.response_template(S3_DELETE_KEYS_RESPONSE) template = self.response_template(S3_DELETE_KEYS_RESPONSE)
@ -1587,15 +1575,6 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin):
template = self.response_template(S3_OBJECT_COPY_RESPONSE) template = self.response_template(S3_OBJECT_COPY_RESPONSE)
response_headers.update(new_key.response_dict) response_headers.update(new_key.response_dict)
return 200, response_headers, template.render(key=new_key) return 200, response_headers, template.render(key=new_key)
streaming_request = hasattr(request, "streaming") and request.streaming
closing_connection = headers.get("connection") == "close"
if closing_connection and streaming_request:
# Closing the connection of a streaming request. No more data
new_key = self.backend.get_object(bucket_name, key_name)
elif streaming_request:
# Streaming request, more data
new_key = self.backend.append_to_key(bucket_name, key_name, body)
else:
# Initial data # Initial data
new_key = self.backend.put_object( new_key = self.backend.put_object(
@ -1611,7 +1590,6 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin):
lock_until=lock_until, lock_until=lock_until,
) )
request.streaming = True
metadata = metadata_from_headers(request.headers) metadata = metadata_from_headers(request.headers)
metadata.update(metadata_from_headers(query)) metadata.update(metadata_from_headers(query))
new_key.set_metadata(metadata) new_key.set_metadata(metadata)

View File

@ -17,7 +17,7 @@ from werkzeug.serving import run_simple
import moto.backends as backends import moto.backends as backends
import moto.backend_index as backend_index import moto.backend_index as backend_index
from moto.core.utils import convert_flask_to_httpretty_response from moto.core.utils import convert_to_flask_response
HTTP_METHODS = ["GET", "POST", "PUT", "DELETE", "HEAD", "PATCH", "OPTIONS"] HTTP_METHODS = ["GET", "POST", "PUT", "DELETE", "HEAD", "PATCH", "OPTIONS"]
@ -291,7 +291,7 @@ def create_backend_app(service):
backend = backend_dict["global"] backend = backend_dict["global"]
for url_path, handler in backend.flask_paths.items(): for url_path, handler in backend.flask_paths.items():
view_func = convert_flask_to_httpretty_response(handler) view_func = convert_to_flask_response(handler)
if handler.__name__ == "dispatch": if handler.__name__ == "dispatch":
endpoint = "{0}.dispatch".format(handler.__self__.__name__) endpoint = "{0}.dispatch".format(handler.__self__.__name__)
else: else:

View File

@ -2,4 +2,3 @@ from .models import ses_backend
ses_backends = {"global": ses_backend} ses_backends = {"global": ses_backend}
mock_ses = ses_backend.decorator mock_ses = ses_backend.decorator
mock_ses_deprecated = ses_backend.deprecated_decorator

View File

@ -1,6 +1,5 @@
from .models import sns_backends from .models import sns_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
sns_backend = sns_backends["us-east-1"] sns_backend = sns_backends["us-east-1"]
mock_sns = base_decorator(sns_backends) mock_sns = base_decorator(sns_backends)
mock_sns_deprecated = deprecated_base_decorator(sns_backends)

View File

@ -1,6 +1,5 @@
from .models import sqs_backends from .models import sqs_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
sqs_backend = sqs_backends["us-east-1"] sqs_backend = sqs_backends["us-east-1"]
mock_sqs = base_decorator(sqs_backends) mock_sqs = base_decorator(sqs_backends)
mock_sqs_deprecated = deprecated_base_decorator(sqs_backends)

View File

@ -2,4 +2,3 @@ from .models import sts_backend
sts_backends = {"global": sts_backend} sts_backends = {"global": sts_backend}
mock_sts = sts_backend.decorator mock_sts = sts_backend.decorator
mock_sts_deprecated = sts_backend.deprecated_decorator

View File

@ -1,6 +1,5 @@
from .models import swf_backends from .models import swf_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator
swf_backend = swf_backends["us-east-1"] swf_backend = swf_backends["us-east-1"]
mock_swf = base_decorator(swf_backends) mock_swf = base_decorator(swf_backends)
mock_swf_deprecated = deprecated_base_decorator(swf_backends)

View File

@ -4,7 +4,6 @@
black==19.10b0 black==19.10b0
regex==2019.11.1 regex==2019.11.1
flake8==3.7.8 flake8==3.7.8
boto>=2.45.0
click click
inflection==0.3.1 inflection==0.3.1
lxml lxml

View File

@ -3,7 +3,6 @@ from io import open
import os import os
import re import re
from setuptools import setup, find_packages from setuptools import setup, find_packages
import sys
import moto.__init__ as service_list import moto.__init__ as service_list
# Borrowed from pip at https://github.com/pypa/pip/blob/62c27dee45625e1b63d1e023b0656310f276e050/setup.py#L11-L15 # Borrowed from pip at https://github.com/pypa/pip/blob/62c27dee45625e1b63d1e023b0656310f276e050/setup.py#L11-L15

View File

@ -1,33 +1,7 @@
import boto
from unittest import SkipTest
from collections.abc import Iterable, Mapping from collections.abc import Iterable, Mapping
from sure import assertion from sure import assertion
def version_tuple(v):
return tuple(map(int, (v.split("."))))
# Note: See https://github.com/spulec/moto/issues/201 for why this is a
# separate method.
def skip_test():
raise SkipTest
class requires_boto_gte(object):
"""Decorator for requiring boto version greater than or equal to 'version'"""
def __init__(self, version):
self.version = version
def __call__(self, test):
boto_version = version_tuple(boto.__version__)
required = version_tuple(self.version)
if boto_version >= required:
return test
return skip_test
@assertion @assertion
def containing_item_with_attributes(context, **kwargs): def containing_item_with_attributes(context, **kwargs):
contains = False contains = False

View File

@ -1,123 +1,22 @@
import boto
import boto3 import boto3
import boto.ec2.autoscale
from boto.ec2.autoscale.launchconfig import LaunchConfiguration
from boto.ec2.autoscale.group import AutoScalingGroup
from boto.ec2.autoscale import Tag
import boto.ec2.elb
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
import pytest import pytest
from moto import ( from moto import (
mock_autoscaling, mock_autoscaling,
mock_ec2_deprecated,
mock_elb_deprecated,
mock_elb, mock_elb,
mock_autoscaling_deprecated,
mock_ec2, mock_ec2,
) )
from moto.core import ACCOUNT_ID from moto.core import ACCOUNT_ID
from tests.helpers import requires_boto_gte
from .utils import ( from .utils import (
setup_networking, setup_networking,
setup_networking_deprecated,
setup_instance_with_networking, setup_instance_with_networking,
) )
from tests import EXAMPLE_AMI_ID from tests import EXAMPLE_AMI_ID
# Has boto3 equivalent
@mock_autoscaling_deprecated
@mock_elb_deprecated
@mock_ec2_deprecated
def test_create_autoscaling_group():
mocked_networking = setup_networking_deprecated()
elb_conn = boto.ec2.elb.connect_to_region("us-east-1")
elb_conn.create_load_balancer("test_lb", zones=[], listeners=[(80, 8080, "http")])
# we attach a couple of machines to the load balancer
# that are not managed by the auto scaling group
INSTANCE_COUNT_START = 3
INSTANCE_COUNT_GROUP = 2
ec2 = boto3.resource("ec2", region_name="us-east-1")
instances = ec2.create_instances(
ImageId=EXAMPLE_AMI_ID,
InstanceType="t1.micro",
MaxCount=INSTANCE_COUNT_START,
MinCount=INSTANCE_COUNT_START,
SubnetId=mocked_networking["subnet1"],
)
instances_ids = [_.id for _ in instances]
elb_conn.register_instances(
"test_lb", instances_ids,
)
conn = boto.ec2.autoscale.connect_to_region("us-east-1")
config = LaunchConfiguration(
name="tester", image_id=EXAMPLE_AMI_ID, instance_type="t2.medium"
)
conn.create_launch_configuration(config)
group = AutoScalingGroup(
name="tester_group",
availability_zones=["us-east-1a", "us-east-1b"],
default_cooldown=60,
desired_capacity=INSTANCE_COUNT_GROUP,
health_check_period=100,
health_check_type="EC2",
max_size=INSTANCE_COUNT_GROUP,
min_size=INSTANCE_COUNT_GROUP,
launch_config=config,
load_balancers=["test_lb"],
placement_group="test_placement",
vpc_zone_identifier="{subnet1},{subnet2}".format(
subnet1=mocked_networking["subnet1"], subnet2=mocked_networking["subnet2"]
),
termination_policies=["OldestInstance", "NewestInstance"],
tags=[
Tag(
resource_id="tester_group",
key="test_key",
value="test_value",
propagate_at_launch=True,
)
],
)
conn.create_auto_scaling_group(group)
group = conn.get_all_groups()[0]
group.name.should.equal("tester_group")
set(group.availability_zones).should.equal(set(["us-east-1a", "us-east-1b"]))
group.desired_capacity.should.equal(2)
group.max_size.should.equal(INSTANCE_COUNT_GROUP)
group.min_size.should.equal(INSTANCE_COUNT_GROUP)
group.instances.should.have.length_of(INSTANCE_COUNT_GROUP)
group.vpc_zone_identifier.should.equal(
"{subnet1},{subnet2}".format(
subnet1=mocked_networking["subnet1"], subnet2=mocked_networking["subnet2"]
)
)
group.launch_config_name.should.equal("tester")
group.default_cooldown.should.equal(60)
group.health_check_period.should.equal(100)
group.health_check_type.should.equal("EC2")
list(group.load_balancers).should.equal(["test_lb"])
group.placement_group.should.equal("test_placement")
list(group.termination_policies).should.equal(["OldestInstance", "NewestInstance"])
len(list(group.tags)).should.equal(1)
tag = list(group.tags)[0]
tag.resource_id.should.equal("tester_group")
tag.key.should.equal("test_key")
tag.value.should.equal("test_value")
tag.propagate_at_launch.should.equal(True)
instances_attached = elb_conn.describe_instance_health("test_lb")
len(instances_attached).should.equal(INSTANCE_COUNT_START + INSTANCE_COUNT_GROUP)
@mock_autoscaling @mock_autoscaling
@mock_ec2 @mock_ec2
@mock_elb @mock_elb
@ -222,47 +121,6 @@ def test_create_autoscaling_group_boto3_within_elb():
attached_ids.should.contain(ec2_instance_id) attached_ids.should.contain(ec2_instance_id)
# Has boto3 equivalent
@mock_autoscaling_deprecated
def test_create_autoscaling_groups_defaults():
"""Test with the minimum inputs and check that all of the proper defaults
are assigned for the other attributes"""
mocked_networking = setup_networking_deprecated()
conn = boto.connect_autoscale()
config = LaunchConfiguration(
name="tester", image_id=EXAMPLE_AMI_ID, instance_type="t2.medium"
)
conn.create_launch_configuration(config)
group = AutoScalingGroup(
name="tester_group",
max_size=2,
min_size=2,
launch_config=config,
vpc_zone_identifier=mocked_networking["subnet1"],
)
conn.create_auto_scaling_group(group)
group = conn.get_all_groups()[0]
group.name.should.equal("tester_group")
group.max_size.should.equal(2)
group.min_size.should.equal(2)
group.launch_config_name.should.equal("tester")
# Defaults
list(group.availability_zones).should.equal(["us-east-1a"]) # subnet1
group.desired_capacity.should.equal(2)
group.vpc_zone_identifier.should.equal(mocked_networking["subnet1"])
group.default_cooldown.should.equal(300)
group.health_check_period.should.equal(300)
group.health_check_type.should.equal("EC2")
list(group.load_balancers).should.equal([])
group.placement_group.should.equal(None)
list(group.termination_policies).should.equal([])
list(group.tags).should.equal([])
@mock_autoscaling @mock_autoscaling
def test_create_autoscaling_groups_defaults_boto3(): def test_create_autoscaling_groups_defaults_boto3():
"""Test with the minimum inputs and check that all of the proper defaults """Test with the minimum inputs and check that all of the proper defaults
@ -371,142 +229,6 @@ def test_propogate_tags():
tags.should.contain({"Value": "TestGroup1", "Key": "aws:autoscaling:groupName"}) tags.should.contain({"Value": "TestGroup1", "Key": "aws:autoscaling:groupName"})
# Has boto3 equivalent
@mock_autoscaling_deprecated
def test_autoscaling_group_describe_filter():
mocked_networking = setup_networking_deprecated()
conn = boto.connect_autoscale()
config = LaunchConfiguration(
name="tester", image_id=EXAMPLE_AMI_ID, instance_type="t2.medium"
)
conn.create_launch_configuration(config)
group = AutoScalingGroup(
name="tester_group",
max_size=2,
min_size=2,
launch_config=config,
vpc_zone_identifier=mocked_networking["subnet1"],
)
conn.create_auto_scaling_group(group)
group.name = "tester_group2"
conn.create_auto_scaling_group(group)
group.name = "tester_group3"
conn.create_auto_scaling_group(group)
conn.get_all_groups(names=["tester_group", "tester_group2"]).should.have.length_of(
2
)
conn.get_all_groups().should.have.length_of(3)
# Has boto3 equivalent
@mock_autoscaling_deprecated
def test_autoscaling_update():
mocked_networking = setup_networking_deprecated()
conn = boto.connect_autoscale()
config = LaunchConfiguration(
name="tester", image_id=EXAMPLE_AMI_ID, instance_type="t2.medium"
)
conn.create_launch_configuration(config)
group = AutoScalingGroup(
name="tester_group",
desired_capacity=2,
max_size=2,
min_size=2,
launch_config=config,
vpc_zone_identifier=mocked_networking["subnet1"],
)
conn.create_auto_scaling_group(group)
group = conn.get_all_groups()[0]
group.availability_zones.should.equal(["us-east-1a"])
group.vpc_zone_identifier.should.equal(mocked_networking["subnet1"])
group.availability_zones = ["us-east-1b"]
group.vpc_zone_identifier = mocked_networking["subnet2"]
group.update()
group = conn.get_all_groups()[0]
group.availability_zones.should.equal(["us-east-1b"])
group.vpc_zone_identifier.should.equal(mocked_networking["subnet2"])
# Has boto3 equivalent
@mock_autoscaling_deprecated
def test_autoscaling_tags_update():
mocked_networking = setup_networking_deprecated()
conn = boto.connect_autoscale()
config = LaunchConfiguration(
name="tester", image_id=EXAMPLE_AMI_ID, instance_type="t2.medium"
)
conn.create_launch_configuration(config)
group = AutoScalingGroup(
name="tester_group",
availability_zones=["us-east-1a"],
desired_capacity=2,
max_size=2,
min_size=2,
launch_config=config,
tags=[
Tag(
resource_id="tester_group",
key="test_key",
value="test_value",
propagate_at_launch=True,
)
],
vpc_zone_identifier=mocked_networking["subnet1"],
)
conn.create_auto_scaling_group(group)
conn.create_or_update_tags(
tags=[
Tag(
resource_id="tester_group",
key="test_key",
value="new_test_value",
propagate_at_launch=True,
),
Tag(
resource_id="tester_group",
key="test_key2",
value="test_value2",
propagate_at_launch=True,
),
]
)
group = conn.get_all_groups()[0]
group.tags.should.have.length_of(2)
# Has boto3 equivalent
@mock_autoscaling_deprecated
def test_autoscaling_group_delete():
mocked_networking = setup_networking_deprecated()
conn = boto.connect_autoscale()
config = LaunchConfiguration(
name="tester", image_id=EXAMPLE_AMI_ID, instance_type="t2.medium"
)
conn.create_launch_configuration(config)
group = AutoScalingGroup(
name="tester_group",
max_size=2,
min_size=2,
launch_config=config,
vpc_zone_identifier=mocked_networking["subnet1"],
)
conn.create_auto_scaling_group(group)
conn.get_all_groups().should.have.length_of(1)
conn.delete_auto_scaling_group("tester_group")
conn.get_all_groups().should.have.length_of(0)
@mock_autoscaling @mock_autoscaling
def test_autoscaling_group_delete_boto3(): def test_autoscaling_group_delete_boto3():
mocked_networking = setup_networking() mocked_networking = setup_networking()
@ -535,197 +257,6 @@ def test_autoscaling_group_delete_boto3():
) )
# Has boto3 equivalent
@mock_ec2_deprecated
@mock_autoscaling_deprecated
def test_autoscaling_group_describe_instances():
mocked_networking = setup_networking_deprecated()
conn = boto.ec2.autoscale.connect_to_region("us-east-1")
config = LaunchConfiguration(
name="tester", image_id=EXAMPLE_AMI_ID, instance_type="t2.medium"
)
conn.create_launch_configuration(config)
group = AutoScalingGroup(
name="tester_group",
max_size=2,
min_size=2,
launch_config=config,
vpc_zone_identifier=mocked_networking["subnet1"],
)
conn.create_auto_scaling_group(group)
instances = list(conn.get_all_autoscaling_instances())
instances.should.have.length_of(2)
instances[0].launch_config_name.should.equal("tester")
instances[0].health_status.should.equal("Healthy")
autoscale_instance_ids = [instance.instance_id for instance in instances]
ec2_conn = boto.ec2.connect_to_region("us-east-1")
reservations = ec2_conn.get_all_reservations()
instances = reservations[0].instances
instances.should.have.length_of(2)
instance_ids = [instance.id for instance in instances]
set(autoscale_instance_ids).should.equal(set(instance_ids))
instances[0].instance_type.should.equal("t2.medium")
# Has boto3 equivalent
@requires_boto_gte("2.8")
@mock_autoscaling_deprecated
def test_set_desired_capacity_up():
mocked_networking = setup_networking_deprecated()
conn = boto.connect_autoscale()
config = LaunchConfiguration(
name="tester", image_id=EXAMPLE_AMI_ID, instance_type="t2.medium"
)
conn.create_launch_configuration(config)
group = AutoScalingGroup(
name="tester_group",
availability_zones=["us-east-1a"],
desired_capacity=2,
max_size=2,
min_size=2,
launch_config=config,
vpc_zone_identifier=mocked_networking["subnet1"],
)
conn.create_auto_scaling_group(group)
group = conn.get_all_groups()[0]
group.desired_capacity.should.equal(2)
instances = list(conn.get_all_autoscaling_instances())
instances.should.have.length_of(2)
conn.set_desired_capacity("tester_group", 3)
group = conn.get_all_groups()[0]
group.desired_capacity.should.equal(3)
instances = list(conn.get_all_autoscaling_instances())
instances.should.have.length_of(3)
# Has boto3 equivalent
@requires_boto_gte("2.8")
@mock_autoscaling_deprecated
def test_set_desired_capacity_down():
mocked_networking = setup_networking_deprecated()
conn = boto.connect_autoscale()
config = LaunchConfiguration(
name="tester", image_id=EXAMPLE_AMI_ID, instance_type="t2.medium"
)
conn.create_launch_configuration(config)
group = AutoScalingGroup(
name="tester_group",
availability_zones=["us-east-1a"],
desired_capacity=2,
max_size=2,
min_size=2,
launch_config=config,
vpc_zone_identifier=mocked_networking["subnet1"],
)
conn.create_auto_scaling_group(group)
group = conn.get_all_groups()[0]
group.desired_capacity.should.equal(2)
instances = list(conn.get_all_autoscaling_instances())
instances.should.have.length_of(2)
conn.set_desired_capacity("tester_group", 1)
group = conn.get_all_groups()[0]
group.desired_capacity.should.equal(1)
instances = list(conn.get_all_autoscaling_instances())
instances.should.have.length_of(1)
# Has boto3 equivalent
@requires_boto_gte("2.8")
@mock_autoscaling_deprecated
def test_set_desired_capacity_the_same():
mocked_networking = setup_networking_deprecated()
conn = boto.connect_autoscale()
config = LaunchConfiguration(
name="tester", image_id=EXAMPLE_AMI_ID, instance_type="t2.medium"
)
conn.create_launch_configuration(config)
group = AutoScalingGroup(
name="tester_group",
availability_zones=["us-east-1a"],
desired_capacity=2,
max_size=2,
min_size=2,
launch_config=config,
vpc_zone_identifier=mocked_networking["subnet1"],
)
conn.create_auto_scaling_group(group)
group = conn.get_all_groups()[0]
group.desired_capacity.should.equal(2)
instances = list(conn.get_all_autoscaling_instances())
instances.should.have.length_of(2)
conn.set_desired_capacity("tester_group", 2)
group = conn.get_all_groups()[0]
group.desired_capacity.should.equal(2)
instances = list(conn.get_all_autoscaling_instances())
instances.should.have.length_of(2)
# Has boto3 equivalent
@mock_autoscaling_deprecated
@mock_elb_deprecated
def test_autoscaling_group_with_elb():
mocked_networking = setup_networking_deprecated()
elb_conn = boto.connect_elb()
zones = ["us-east-1a", "us-east-1b"]
ports = [(80, 8080, "http"), (443, 8443, "tcp")]
elb_conn.create_load_balancer("my-lb", zones, ports)
instances_health = elb_conn.describe_instance_health("my-lb")
instances_health.should.be.empty
conn = boto.connect_autoscale()
config = LaunchConfiguration(
name="tester", image_id=EXAMPLE_AMI_ID, instance_type="t2.medium"
)
conn.create_launch_configuration(config)
group = AutoScalingGroup(
name="tester_group",
max_size=2,
min_size=2,
launch_config=config,
load_balancers=["my-lb"],
vpc_zone_identifier=mocked_networking["subnet1"],
)
conn.create_auto_scaling_group(group)
group = conn.get_all_groups()[0]
elb = elb_conn.get_all_load_balancers()[0]
group.desired_capacity.should.equal(2)
elb.instances.should.have.length_of(2)
autoscale_instance_ids = set(instance.instance_id for instance in group.instances)
elb_instace_ids = set(instance.id for instance in elb.instances)
autoscale_instance_ids.should.equal(elb_instace_ids)
conn.set_desired_capacity("tester_group", 3)
group = conn.get_all_groups()[0]
elb = elb_conn.get_all_load_balancers()[0]
group.desired_capacity.should.equal(3)
elb.instances.should.have.length_of(3)
autoscale_instance_ids = set(instance.instance_id for instance in group.instances)
elb_instace_ids = set(instance.id for instance in elb.instances)
autoscale_instance_ids.should.equal(elb_instace_ids)
conn.delete_auto_scaling_group("tester_group")
conn.get_all_groups().should.have.length_of(0)
elb = elb_conn.get_all_load_balancers()[0]
elb.instances.should.have.length_of(0)
@mock_autoscaling @mock_autoscaling
@mock_elb @mock_elb
def test_describe_load_balancers(): def test_describe_load_balancers():

View File

@ -1,54 +1,15 @@
import base64 import base64
import boto
import boto3 import boto3
from boto.ec2.autoscale.launchconfig import LaunchConfiguration
from boto.ec2.blockdevicemapping import BlockDeviceType, BlockDeviceMapping
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
import pytest import pytest
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
from moto import mock_autoscaling_deprecated
from moto import mock_autoscaling from moto import mock_autoscaling
from moto.core import ACCOUNT_ID from moto.core import ACCOUNT_ID
from tests.helpers import requires_boto_gte
from tests import EXAMPLE_AMI_ID from tests import EXAMPLE_AMI_ID
# Has boto3 equivalent
@mock_autoscaling_deprecated
def test_create_launch_configuration():
conn = boto.connect_autoscale()
config = LaunchConfiguration(
name="tester",
image_id="ami-abcd1234",
instance_type="t1.micro",
key_name="the_keys",
security_groups=["default", "default2"],
user_data=b"This is some user_data",
instance_monitoring=True,
instance_profile_name="arn:aws:iam::{}:instance-profile/testing".format(
ACCOUNT_ID
),
spot_price=0.1,
)
conn.create_launch_configuration(config)
launch_config = conn.get_all_launch_configurations()[0]
launch_config.name.should.equal("tester")
launch_config.image_id.should.equal("ami-abcd1234")
launch_config.instance_type.should.equal("t1.micro")
launch_config.key_name.should.equal("the_keys")
set(launch_config.security_groups).should.equal(set(["default", "default2"]))
launch_config.user_data.should.equal(b"This is some user_data")
launch_config.instance_monitoring.enabled.should.equal("true")
launch_config.instance_profile_name.should.equal(
"arn:aws:iam::{}:instance-profile/testing".format(ACCOUNT_ID)
)
launch_config.spot_price.should.equal(0.1)
@mock_autoscaling @mock_autoscaling
def test_create_launch_configuration_boto3(): def test_create_launch_configuration_boto3():
client = boto3.client("autoscaling", region_name="us-east-1") client = boto3.client("autoscaling", region_name="us-east-1")
@ -84,76 +45,6 @@ def test_create_launch_configuration_boto3():
launch_config["BlockDeviceMappings"].should.equal([]) launch_config["BlockDeviceMappings"].should.equal([])
# Has boto3 equivalent
@requires_boto_gte("2.27.0")
@mock_autoscaling_deprecated
def test_create_launch_configuration_with_block_device_mappings():
block_device_mapping = BlockDeviceMapping()
ephemeral_drive = BlockDeviceType()
ephemeral_drive.ephemeral_name = "ephemeral0"
block_device_mapping["/dev/xvdb"] = ephemeral_drive
snapshot_drive = BlockDeviceType()
snapshot_drive.snapshot_id = "snap-1234abcd"
snapshot_drive.volume_type = "standard"
block_device_mapping["/dev/xvdp"] = snapshot_drive
ebs_drive = BlockDeviceType()
ebs_drive.volume_type = "io1"
ebs_drive.size = 100
ebs_drive.iops = 1000
ebs_drive.delete_on_termination = False
block_device_mapping["/dev/xvdh"] = ebs_drive
conn = boto.connect_autoscale(use_block_device_types=True)
config = LaunchConfiguration(
name="tester",
image_id="ami-abcd1234",
instance_type="m1.small",
key_name="the_keys",
security_groups=["default", "default2"],
user_data=b"This is some user_data",
instance_monitoring=True,
instance_profile_name="arn:aws:iam::{}:instance-profile/testing".format(
ACCOUNT_ID
),
spot_price=0.1,
block_device_mappings=[block_device_mapping],
)
conn.create_launch_configuration(config)
launch_config = conn.get_all_launch_configurations()[0]
launch_config.name.should.equal("tester")
launch_config.image_id.should.equal("ami-abcd1234")
launch_config.instance_type.should.equal("m1.small")
launch_config.key_name.should.equal("the_keys")
set(launch_config.security_groups).should.equal(set(["default", "default2"]))
launch_config.user_data.should.equal(b"This is some user_data")
launch_config.instance_monitoring.enabled.should.equal("true")
launch_config.instance_profile_name.should.equal(
"arn:aws:iam::{}:instance-profile/testing".format(ACCOUNT_ID)
)
launch_config.spot_price.should.equal(0.1)
len(launch_config.block_device_mappings).should.equal(3)
returned_mapping = launch_config.block_device_mappings
set(returned_mapping.keys()).should.equal(
set(["/dev/xvdb", "/dev/xvdp", "/dev/xvdh"])
)
returned_mapping["/dev/xvdh"].iops.should.equal(1000)
returned_mapping["/dev/xvdh"].size.should.equal(100)
returned_mapping["/dev/xvdh"].volume_type.should.equal("io1")
returned_mapping["/dev/xvdh"].delete_on_termination.should.be.false
returned_mapping["/dev/xvdp"].snapshot_id.should.equal("snap-1234abcd")
returned_mapping["/dev/xvdp"].volume_type.should.equal("standard")
returned_mapping["/dev/xvdb"].ephemeral_name.should.equal("ephemeral0")
@mock_autoscaling @mock_autoscaling
def test_create_launch_configuration_with_block_device_mappings_boto3(): def test_create_launch_configuration_with_block_device_mappings_boto3():
client = boto3.client("autoscaling", region_name="us-east-1") client = boto3.client("autoscaling", region_name="us-east-1")
@ -214,34 +105,6 @@ def test_create_launch_configuration_with_block_device_mappings_boto3():
xvdb.shouldnt.have.key("Ebs") xvdb.shouldnt.have.key("Ebs")
# Has boto3 equivalent
@requires_boto_gte("2.12")
@mock_autoscaling_deprecated
def test_create_launch_configuration_for_2_12():
conn = boto.connect_autoscale()
config = LaunchConfiguration(
name="tester", image_id="ami-abcd1234", ebs_optimized=True
)
conn.create_launch_configuration(config)
launch_config = conn.get_all_launch_configurations()[0]
launch_config.ebs_optimized.should.equal(True)
# Has boto3 equivalent
@requires_boto_gte("2.25.0")
@mock_autoscaling_deprecated
def test_create_launch_configuration_using_ip_association():
conn = boto.connect_autoscale()
config = LaunchConfiguration(
name="tester", image_id="ami-abcd1234", associate_public_ip_address=True
)
conn.create_launch_configuration(config)
launch_config = conn.get_all_launch_configurations()[0]
launch_config.associate_public_ip_address.should.equal(True)
@mock_autoscaling @mock_autoscaling
def test_create_launch_configuration_additional_parameters(): def test_create_launch_configuration_additional_parameters():
client = boto3.client("autoscaling", region_name="us-east-1") client = boto3.client("autoscaling", region_name="us-east-1")
@ -258,18 +121,6 @@ def test_create_launch_configuration_additional_parameters():
launch_config["AssociatePublicIpAddress"].should.equal(True) launch_config["AssociatePublicIpAddress"].should.equal(True)
# Has boto3 equivalent
@requires_boto_gte("2.25.0")
@mock_autoscaling_deprecated
def test_create_launch_configuration_using_ip_association_should_default_to_false():
conn = boto.connect_autoscale()
config = LaunchConfiguration(name="tester", image_id="ami-abcd1234")
conn.create_launch_configuration(config)
launch_config = conn.get_all_launch_configurations()[0]
launch_config.associate_public_ip_address.should.equal(False)
@mock_autoscaling @mock_autoscaling
def test_create_launch_configuration_additional_params_default_to_false(): def test_create_launch_configuration_additional_params_default_to_false():
client = boto3.client("autoscaling", region_name="us-east-1") client = boto3.client("autoscaling", region_name="us-east-1")
@ -284,31 +135,6 @@ def test_create_launch_configuration_additional_params_default_to_false():
launch_config["AssociatePublicIpAddress"].should.equal(False) launch_config["AssociatePublicIpAddress"].should.equal(False)
# Has boto3 equivalent
@mock_autoscaling_deprecated
def test_create_launch_configuration_defaults():
"""Test with the minimum inputs and check that all of the proper defaults
are assigned for the other attributes"""
conn = boto.connect_autoscale()
config = LaunchConfiguration(
name="tester", image_id="ami-abcd1234", instance_type="m1.small"
)
conn.create_launch_configuration(config)
launch_config = conn.get_all_launch_configurations()[0]
launch_config.name.should.equal("tester")
launch_config.image_id.should.equal("ami-abcd1234")
launch_config.instance_type.should.equal("m1.small")
# Defaults
launch_config.key_name.should.equal("")
list(launch_config.security_groups).should.equal([])
launch_config.user_data.should.equal(b"")
launch_config.instance_monitoring.enabled.should.equal("false")
launch_config.instance_profile_name.should.equal(None)
launch_config.spot_price.should.equal(None)
@mock_autoscaling @mock_autoscaling
def test_create_launch_configuration_defaults_boto3(): def test_create_launch_configuration_defaults_boto3():
"""Test with the minimum inputs and check that all of the proper defaults """Test with the minimum inputs and check that all of the proper defaults
@ -331,37 +157,6 @@ def test_create_launch_configuration_defaults_boto3():
launch_config.shouldnt.have.key("SpotPrice") launch_config.shouldnt.have.key("SpotPrice")
# Has boto3 equivalent
@requires_boto_gte("2.12")
@mock_autoscaling_deprecated
def test_create_launch_configuration_defaults_for_2_12():
conn = boto.connect_autoscale()
config = LaunchConfiguration(name="tester", image_id="ami-abcd1234")
conn.create_launch_configuration(config)
launch_config = conn.get_all_launch_configurations()[0]
launch_config.ebs_optimized.should.equal(False)
# Has boto3 equivalent
@mock_autoscaling_deprecated
def test_launch_configuration_describe_filter():
conn = boto.connect_autoscale()
config = LaunchConfiguration(
name="tester", image_id="ami-abcd1234", instance_type="m1.small"
)
conn.create_launch_configuration(config)
config.name = "tester2"
conn.create_launch_configuration(config)
config.name = "tester3"
conn.create_launch_configuration(config)
conn.get_all_launch_configurations(
names=["tester", "tester2"]
).should.have.length_of(2)
conn.get_all_launch_configurations().should.have.length_of(3)
@mock_autoscaling @mock_autoscaling
def test_launch_configuration_describe_filter_boto3(): def test_launch_configuration_describe_filter_boto3():
client = boto3.client("autoscaling", region_name="us-east-1") client = boto3.client("autoscaling", region_name="us-east-1")
@ -404,21 +199,6 @@ def test_launch_configuration_describe_paginated():
assert "NextToken" not in response2.keys() assert "NextToken" not in response2.keys()
# Has boto3 equivalent
@mock_autoscaling_deprecated
def test_launch_configuration_delete():
conn = boto.connect_autoscale()
config = LaunchConfiguration(
name="tester", image_id="ami-abcd1234", instance_type="m1.small"
)
conn.create_launch_configuration(config)
conn.get_all_launch_configurations().should.have.length_of(1)
conn.delete_launch_configuration("tester")
conn.get_all_launch_configurations().should.have.length_of(0)
@mock_autoscaling @mock_autoscaling
def test_launch_configuration_delete_boto3(): def test_launch_configuration_delete_boto3():
client = boto3.client("autoscaling", region_name="us-east-1") client = boto3.client("autoscaling", region_name="us-east-1")

View File

@ -1,36 +1,13 @@
import boto
import boto3 import boto3
from boto.ec2.autoscale.launchconfig import LaunchConfiguration
from boto.ec2.autoscale.group import AutoScalingGroup
from boto.ec2.autoscale.policy import ScalingPolicy
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
import pytest import pytest
from moto import mock_autoscaling_deprecated, mock_autoscaling from moto import mock_autoscaling
from .utils import setup_networking_deprecated, setup_networking from .utils import setup_networking
from tests import EXAMPLE_AMI_ID from tests import EXAMPLE_AMI_ID
def setup_autoscale_group():
mocked_networking = setup_networking_deprecated()
conn = boto.connect_autoscale()
config = LaunchConfiguration(
name="tester", image_id=EXAMPLE_AMI_ID, instance_type="m1.small"
)
conn.create_launch_configuration(config)
group = AutoScalingGroup(
name="tester_group",
max_size=2,
min_size=2,
launch_config=config,
vpc_zone_identifier=mocked_networking["subnet1"],
)
conn.create_auto_scaling_group(group)
return group
def setup_autoscale_group_boto3(): def setup_autoscale_group_boto3():
mocked_networking = setup_networking() mocked_networking = setup_networking()
client = boto3.client("autoscaling", region_name="us-east-1") client = boto3.client("autoscaling", region_name="us-east-1")
@ -49,28 +26,6 @@ def setup_autoscale_group_boto3():
) )
# Has boto3 equivalent
@mock_autoscaling_deprecated
def test_create_policy():
setup_autoscale_group()
conn = boto.connect_autoscale()
policy = ScalingPolicy(
name="ScaleUp",
adjustment_type="ExactCapacity",
as_name="tester_group",
scaling_adjustment=3,
cooldown=60,
)
conn.create_scaling_policy(policy)
policy = conn.get_all_policies()[0]
policy.name.should.equal("ScaleUp")
policy.adjustment_type.should.equal("ExactCapacity")
policy.as_name.should.equal("tester_group")
policy.scaling_adjustment.should.equal(3)
policy.cooldown.should.equal(60)
@mock_autoscaling @mock_autoscaling
def test_create_policy_boto3(): def test_create_policy_boto3():
setup_autoscale_group_boto3() setup_autoscale_group_boto3()
@ -91,26 +46,6 @@ def test_create_policy_boto3():
policy["Cooldown"].should.equal(60) policy["Cooldown"].should.equal(60)
# Has boto3 equivalent
@mock_autoscaling_deprecated
def test_create_policy_default_values():
setup_autoscale_group()
conn = boto.connect_autoscale()
policy = ScalingPolicy(
name="ScaleUp",
adjustment_type="ExactCapacity",
as_name="tester_group",
scaling_adjustment=3,
)
conn.create_scaling_policy(policy)
policy = conn.get_all_policies()[0]
policy.name.should.equal("ScaleUp")
# Defaults
policy.cooldown.should.equal(300)
@mock_autoscaling @mock_autoscaling
def test_create_policy_default_values_boto3(): def test_create_policy_default_values_boto3():
setup_autoscale_group_boto3() setup_autoscale_group_boto3()
@ -129,34 +64,6 @@ def test_create_policy_default_values_boto3():
policy["Cooldown"].should.equal(300) policy["Cooldown"].should.equal(300)
# Has boto3 equivalent
@mock_autoscaling_deprecated
def test_update_policy():
setup_autoscale_group()
conn = boto.connect_autoscale()
policy = ScalingPolicy(
name="ScaleUp",
adjustment_type="ExactCapacity",
as_name="tester_group",
scaling_adjustment=3,
)
conn.create_scaling_policy(policy)
policy = conn.get_all_policies()[0]
policy.scaling_adjustment.should.equal(3)
# Now update it by creating another with the same name
policy = ScalingPolicy(
name="ScaleUp",
adjustment_type="ExactCapacity",
as_name="tester_group",
scaling_adjustment=2,
)
conn.create_scaling_policy(policy)
policy = conn.get_all_policies()[0]
policy.scaling_adjustment.should.equal(2)
@mock_autoscaling @mock_autoscaling
def test_update_policy_boto3(): def test_update_policy_boto3():
setup_autoscale_group_boto3() setup_autoscale_group_boto3()
@ -184,25 +91,6 @@ def test_update_policy_boto3():
policy["ScalingAdjustment"].should.equal(2) policy["ScalingAdjustment"].should.equal(2)
# Has boto3 equivalent
@mock_autoscaling_deprecated
def test_delete_policy():
setup_autoscale_group()
conn = boto.connect_autoscale()
policy = ScalingPolicy(
name="ScaleUp",
adjustment_type="ExactCapacity",
as_name="tester_group",
scaling_adjustment=3,
)
conn.create_scaling_policy(policy)
conn.get_all_policies().should.have.length_of(1)
conn.delete_policy("ScaleUp")
conn.get_all_policies().should.have.length_of(0)
@mock_autoscaling @mock_autoscaling
def test_delete_policy_boto3(): def test_delete_policy_boto3():
setup_autoscale_group_boto3() setup_autoscale_group_boto3()
@ -220,25 +108,6 @@ def test_delete_policy_boto3():
client.describe_policies()["ScalingPolicies"].should.have.length_of(0) client.describe_policies()["ScalingPolicies"].should.have.length_of(0)
# Has boto3 equivalent
@mock_autoscaling_deprecated
def test_execute_policy_exact_capacity():
setup_autoscale_group()
conn = boto.connect_autoscale()
policy = ScalingPolicy(
name="ScaleUp",
adjustment_type="ExactCapacity",
as_name="tester_group",
scaling_adjustment=3,
)
conn.create_scaling_policy(policy)
conn.execute_policy("ScaleUp")
instances = list(conn.get_all_autoscaling_instances())
instances.should.have.length_of(3)
@mock_autoscaling @mock_autoscaling
def test_execute_policy_exact_capacity_boto3(): def test_execute_policy_exact_capacity_boto3():
setup_autoscale_group_boto3() setup_autoscale_group_boto3()
@ -256,25 +125,6 @@ def test_execute_policy_exact_capacity_boto3():
instances["AutoScalingInstances"].should.have.length_of(3) instances["AutoScalingInstances"].should.have.length_of(3)
# Has boto3 equivalent
@mock_autoscaling_deprecated
def test_execute_policy_positive_change_in_capacity():
setup_autoscale_group()
conn = boto.connect_autoscale()
policy = ScalingPolicy(
name="ScaleUp",
adjustment_type="ChangeInCapacity",
as_name="tester_group",
scaling_adjustment=3,
)
conn.create_scaling_policy(policy)
conn.execute_policy("ScaleUp")
instances = list(conn.get_all_autoscaling_instances())
instances.should.have.length_of(5)
@mock_autoscaling @mock_autoscaling
def test_execute_policy_positive_change_in_capacity_boto3(): def test_execute_policy_positive_change_in_capacity_boto3():
setup_autoscale_group_boto3() setup_autoscale_group_boto3()
@ -292,25 +142,6 @@ def test_execute_policy_positive_change_in_capacity_boto3():
instances["AutoScalingInstances"].should.have.length_of(5) instances["AutoScalingInstances"].should.have.length_of(5)
# Has boto3 equivalent
@mock_autoscaling_deprecated
def test_execute_policy_percent_change_in_capacity():
setup_autoscale_group()
conn = boto.connect_autoscale()
policy = ScalingPolicy(
name="ScaleUp",
adjustment_type="PercentChangeInCapacity",
as_name="tester_group",
scaling_adjustment=50,
)
conn.create_scaling_policy(policy)
conn.execute_policy("ScaleUp")
instances = list(conn.get_all_autoscaling_instances())
instances.should.have.length_of(3)
@pytest.mark.parametrize( @pytest.mark.parametrize(
"adjustment,nr_of_instances", [(1, 3), (50, 3), (100, 4), (250, 7)], "adjustment,nr_of_instances", [(1, 3), (50, 3), (100, 4), (250, 7)],
) )
@ -332,25 +163,3 @@ def test_execute_policy_percent_change_in_capacity_boto3(adjustment, nr_of_insta
instances = client.describe_auto_scaling_instances() instances = client.describe_auto_scaling_instances()
instances["AutoScalingInstances"].should.have.length_of(nr_of_instances) instances["AutoScalingInstances"].should.have.length_of(nr_of_instances)
# Has boto3 equivalent
@mock_autoscaling_deprecated
def test_execute_policy_small_percent_change_in_capacity():
"""http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/as-scale-based-on-demand.html
If PercentChangeInCapacity returns a value between 0 and 1,
Auto Scaling will round it off to 1."""
setup_autoscale_group()
conn = boto.connect_autoscale()
policy = ScalingPolicy(
name="ScaleUp",
adjustment_type="PercentChangeInCapacity",
as_name="tester_group",
scaling_adjustment=1,
)
conn.create_scaling_policy(policy)
conn.execute_policy("ScaleUp")
instances = list(conn.get_all_autoscaling_instances())
instances.should.have.length_of(3)

View File

@ -1,6 +1,5 @@
import boto3 import boto3
from boto import vpc as boto_vpc from moto import mock_ec2
from moto import mock_ec2, mock_ec2_deprecated
@mock_ec2 @mock_ec2
@ -16,15 +15,6 @@ def setup_networking(region_name="us-east-1"):
return {"vpc": vpc.id, "subnet1": subnet1.id, "subnet2": subnet2.id} return {"vpc": vpc.id, "subnet1": subnet1.id, "subnet2": subnet2.id}
@mock_ec2_deprecated
def setup_networking_deprecated():
conn = boto_vpc.connect_to_region("us-east-1")
vpc = conn.create_vpc("10.11.0.0/16")
subnet1 = conn.create_subnet(vpc.id, "10.11.1.0/24", availability_zone="us-east-1a")
subnet2 = conn.create_subnet(vpc.id, "10.11.2.0/24", availability_zone="us-east-1b")
return {"vpc": vpc.id, "subnet1": subnet1.id, "subnet2": subnet2.id}
@mock_ec2 @mock_ec2
def setup_instance_with_networking(image_id, instance_type): def setup_instance_with_networking(image_id, instance_type):
mock_data = setup_networking() mock_data = setup_networking()

View File

@ -1,772 +0,0 @@
import os
import json
import boto
import boto.dynamodb2
import boto.iam
import boto.s3
import boto.s3.key
import boto.cloudformation
from boto.exception import BotoServerError
import sure # noqa # pylint: disable=unused-import
from freezegun import freeze_time
import pytest
from moto import (
mock_cloudformation_deprecated,
mock_s3_deprecated,
mock_sns_deprecated,
mock_sqs_deprecated,
mock_route53_deprecated,
mock_iam_deprecated,
mock_dynamodb2_deprecated,
)
from moto.cloudformation import cloudformation_backends
dummy_template = {
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Stack 1",
"Resources": {},
}
dummy_template2 = {
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Stack 2",
"Resources": {},
}
# template with resource which has no delete attribute defined
dummy_template3 = {
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Stack 3",
"Resources": {
"VPC": {"Properties": {"CidrBlock": "192.168.0.0/16"}, "Type": "AWS::EC2::VPC"}
},
}
dummy_template4 = {
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"myDynamoDBTable": {
"Type": "AWS::DynamoDB::Table",
"Properties": {
"AttributeDefinitions": [
{"AttributeName": "Name", "AttributeType": "S"},
{"AttributeName": "Age", "AttributeType": "S"},
],
"KeySchema": [
{"AttributeName": "Name", "KeyType": "HASH"},
{"AttributeName": "Age", "KeyType": "RANGE"},
],
"ProvisionedThroughput": {
"ReadCapacityUnits": 5,
"WriteCapacityUnits": 5,
},
"TableName": "Person",
},
}
},
}
dummy_template_json = json.dumps(dummy_template)
dummy_template_json2 = json.dumps(dummy_template2)
dummy_template_json3 = json.dumps(dummy_template3)
dummy_template_json4 = json.dumps(dummy_template4)
# Has boto3 equivalent
@mock_cloudformation_deprecated
def test_create_stack():
conn = boto.connect_cloudformation()
conn.create_stack("test_stack", template_body=dummy_template_json)
stack = conn.describe_stacks()[0]
stack.stack_id.should.contain(
"arn:aws:cloudformation:us-east-1:123456789:stack/test_stack/"
)
stack.stack_name.should.equal("test_stack")
stack.get_template().should.equal(
{
"GetTemplateResponse": {
"GetTemplateResult": {
"TemplateBody": dummy_template_json,
"ResponseMetadata": {
"RequestId": "2d06e36c-ac1d-11e0-a958-f9382b6eb86bEXAMPLE"
},
}
}
}
)
@mock_cloudformation_deprecated
def test_create_stack_with_other_region():
conn = boto.cloudformation.connect_to_region("us-west-2")
conn.create_stack("test_stack", template_body=dummy_template_json)
stack = conn.describe_stacks()[0]
stack.stack_id.should.contain(
"arn:aws:cloudformation:us-west-2:123456789:stack/test_stack/"
)
stack.stack_name.should.equal("test_stack")
stack.get_template().should.equal(
{
"GetTemplateResponse": {
"GetTemplateResult": {
"TemplateBody": dummy_template_json,
"ResponseMetadata": {
"RequestId": "2d06e36c-ac1d-11e0-a958-f9382b6eb86bEXAMPLE"
},
}
}
}
)
# Has boto3 equivalent
@mock_cloudformation_deprecated
@mock_route53_deprecated
def test_create_stack_hosted_zone_by_id():
conn = boto.connect_cloudformation()
dummy_template = {
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Stack 1",
"Parameters": {},
"Resources": {
"Bar": {
"Type": "AWS::Route53::HostedZone",
"Properties": {"Name": "foo.bar.baz"},
}
},
}
dummy_template2 = {
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Stack 2",
"Parameters": {"ZoneId": {"Type": "String"}},
"Resources": {
"Foo": {
"Properties": {"HostedZoneId": {"Ref": "ZoneId"}, "RecordSets": []},
"Type": "AWS::Route53::RecordSetGroup",
}
},
}
conn.create_stack(
"test_stack1", template_body=json.dumps(dummy_template), parameters={}.items()
)
r53_conn = boto.connect_route53()
zone_id = r53_conn.get_zones()[0].id
conn.create_stack(
"test_stack2",
template_body=json.dumps(dummy_template2),
parameters={"ZoneId": zone_id}.items(),
)
stack = conn.describe_stacks()[0]
assert stack.list_resources()
# Has boto3 equivalent
@mock_cloudformation_deprecated
def test_creating_stacks_across_regions():
west1_conn = boto.cloudformation.connect_to_region("us-west-1")
west1_conn.create_stack("test_stack", template_body=dummy_template_json)
west2_conn = boto.cloudformation.connect_to_region("us-west-2")
west2_conn.create_stack("test_stack", template_body=dummy_template_json)
list(west1_conn.describe_stacks()).should.have.length_of(1)
list(west2_conn.describe_stacks()).should.have.length_of(1)
# Has boto3 equivalent
@mock_cloudformation_deprecated
@mock_sns_deprecated
@mock_sqs_deprecated
def test_create_stack_with_notification_arn():
sqs_conn = boto.connect_sqs()
queue = sqs_conn.create_queue("fake-queue", visibility_timeout=3)
queue_arn = queue.get_attributes()["QueueArn"]
sns_conn = boto.connect_sns()
topic = sns_conn.create_topic("fake-topic")
topic_arn = topic["CreateTopicResponse"]["CreateTopicResult"]["TopicArn"]
sns_conn.subscribe(topic_arn, "sqs", queue_arn)
conn = boto.connect_cloudformation()
with freeze_time("2015-01-01 12:00:00"):
conn.create_stack(
"test_stack_with_notifications",
template_body=dummy_template_json,
notification_arns=topic_arn,
)
stack = conn.describe_stacks()[0]
[n.value for n in stack.notification_arns].should.contain(topic_arn)
with freeze_time("2015-01-01 12:00:01"):
message = queue.read(1)
msg = json.loads(message.get_body())
msg["Subject"].should.equal("AWS CloudFormation Notification")
msg["Message"].should.contain("StackId='{}'\n".format(stack.stack_id))
msg["Message"].should.contain("Timestamp='2015-01-01T12:00:00.000Z'\n")
msg["Message"].should.contain("LogicalResourceId='test_stack_with_notifications'\n")
msg["Message"].should.contain("ResourceStatus='CREATE_IN_PROGRESS'\n")
msg["Message"].should.contain("ResourceStatusReason='User Initiated'\n")
msg["Message"].should.contain("ResourceType='AWS::CloudFormation::Stack'\n")
msg["Message"].should.contain("StackName='test_stack_with_notifications'\n")
msg.should.have.key("MessageId")
msg.should.have.key("Signature")
msg.should.have.key("SignatureVersion")
msg.should.have.key("Subject")
msg["Timestamp"].should.equal("2015-01-01T12:00:00.000Z")
msg["TopicArn"].should.equal(topic_arn)
msg.should.have.key("Type")
msg.should.have.key("UnsubscribeURL")
with freeze_time("2015-01-01 12:00:02"):
message = queue.read(1)
msg = json.loads(message.get_body())
msg["Message"].should.contain("StackId='{}'\n".format(stack.stack_id))
msg["Message"].should.contain("Timestamp='2015-01-01T12:00:00.000Z'\n")
msg["Message"].should.contain("LogicalResourceId='test_stack_with_notifications'\n")
msg["Message"].should.contain("ResourceStatus='CREATE_COMPLETE'\n")
msg["Message"].should.contain("ResourceStatusReason='None'\n")
msg["Message"].should.contain("ResourceType='AWS::CloudFormation::Stack'\n")
msg["Message"].should.contain("StackName='test_stack_with_notifications'\n")
msg.should.have.key("MessageId")
msg.should.have.key("Signature")
msg.should.have.key("SignatureVersion")
msg.should.have.key("Subject")
msg["Timestamp"].should.equal("2015-01-01T12:00:00.000Z")
msg["TopicArn"].should.equal(topic_arn)
msg.should.have.key("Type")
msg.should.have.key("UnsubscribeURL")
# Has boto3 equivalent
@mock_cloudformation_deprecated
@mock_s3_deprecated
def test_create_stack_from_s3_url():
s3_conn = boto.s3.connect_to_region("us-west-1")
bucket = s3_conn.create_bucket("foobar", location="us-west-1")
key = boto.s3.key.Key(bucket)
key.key = "template-key"
key.set_contents_from_string(dummy_template_json)
key_url = key.generate_url(expires_in=0, query_auth=False)
conn = boto.cloudformation.connect_to_region("us-west-1")
conn.create_stack("new-stack", template_url=key_url)
stack = conn.describe_stacks()[0]
stack.stack_name.should.equal("new-stack")
stack.get_template().should.equal(
{
"GetTemplateResponse": {
"GetTemplateResult": {
"TemplateBody": dummy_template_json,
"ResponseMetadata": {
"RequestId": "2d06e36c-ac1d-11e0-a958-f9382b6eb86bEXAMPLE"
},
}
}
}
)
# Has boto3 equivalent
@mock_cloudformation_deprecated
def test_describe_stack_by_name():
conn = boto.connect_cloudformation()
conn.create_stack("test_stack", template_body=dummy_template_json)
stack = conn.describe_stacks("test_stack")[0]
stack.stack_name.should.equal("test_stack")
# Has boto3 equivalent
@mock_cloudformation_deprecated
def test_describe_stack_by_stack_id():
conn = boto.connect_cloudformation()
conn.create_stack("test_stack", template_body=dummy_template_json)
stack = conn.describe_stacks("test_stack")[0]
stack_by_id = conn.describe_stacks(stack.stack_id)[0]
stack_by_id.stack_id.should.equal(stack.stack_id)
stack_by_id.stack_name.should.equal("test_stack")
@mock_dynamodb2_deprecated
# Has boto3 equivalent
@mock_cloudformation_deprecated
def test_delete_stack_dynamo_template():
conn = boto.connect_cloudformation()
db_conn = boto.dynamodb2.connect_to_region("us-east-1")
#
conn.create_stack("test_stack", template_body=dummy_template_json4)
db_conn.list_tables()["TableNames"].should.have.length_of(1)
#
conn.delete_stack("test_stack")
db_conn.list_tables()["TableNames"].should.have.length_of(0)
# Has boto3 equivalent
@mock_cloudformation_deprecated
def test_describe_deleted_stack():
conn = boto.connect_cloudformation()
conn.create_stack("test_stack", template_body=dummy_template_json)
stack = conn.describe_stacks("test_stack")[0]
stack_id = stack.stack_id
conn.delete_stack(stack.stack_id)
stack_by_id = conn.describe_stacks(stack_id)[0]
stack_by_id.stack_id.should.equal(stack.stack_id)
stack_by_id.stack_name.should.equal("test_stack")
stack_by_id.stack_status.should.equal("DELETE_COMPLETE")
# Has boto3 equivalent
@mock_cloudformation_deprecated
def test_get_template_by_name():
conn = boto.connect_cloudformation()
conn.create_stack("test_stack", template_body=dummy_template_json)
template = conn.get_template("test_stack")
template.should.equal(
{
"GetTemplateResponse": {
"GetTemplateResult": {
"TemplateBody": dummy_template_json,
"ResponseMetadata": {
"RequestId": "2d06e36c-ac1d-11e0-a958-f9382b6eb86bEXAMPLE"
},
}
}
}
)
# Has boto3 equivalent
@mock_cloudformation_deprecated
def test_list_stacks():
conn = boto.connect_cloudformation()
conn.create_stack("test_stack", template_body=dummy_template_json)
conn.create_stack("test_stack2", template_body=dummy_template_json)
stacks = conn.list_stacks()
stacks.should.have.length_of(2)
stacks[0].template_description.should.equal("Stack 1")
# Has boto3 equivalent
@mock_cloudformation_deprecated
def test_list_stacks_with_filter():
conn = boto.connect_cloudformation()
conn.create_stack("test_stack", template_body=dummy_template_json)
conn.create_stack("test_stack2", template_body=dummy_template_json)
conn.update_stack("test_stack", template_body=dummy_template_json2)
stacks = conn.list_stacks("CREATE_COMPLETE")
stacks.should.have.length_of(1)
stacks[0].template_description.should.equal("Stack 1")
stacks = conn.list_stacks("UPDATE_COMPLETE")
stacks.should.have.length_of(1)
# Has boto3 equivalent
@mock_cloudformation_deprecated
def test_delete_stack_by_name():
conn = boto.connect_cloudformation()
conn.create_stack("test_stack", template_body=dummy_template_json)
conn.describe_stacks().should.have.length_of(1)
conn.delete_stack("test_stack")
conn.describe_stacks().should.have.length_of(0)
# Has boto3 equivalent
@mock_cloudformation_deprecated
def test_delete_stack_by_id():
conn = boto.connect_cloudformation()
stack_id = conn.create_stack("test_stack", template_body=dummy_template_json)
conn.describe_stacks().should.have.length_of(1)
conn.delete_stack(stack_id)
conn.describe_stacks().should.have.length_of(0)
with pytest.raises(BotoServerError):
conn.describe_stacks("test_stack")
conn.describe_stacks(stack_id).should.have.length_of(1)
# Has boto3 equivalent
@mock_cloudformation_deprecated
def test_delete_stack_with_resource_missing_delete_attr():
conn = boto.connect_cloudformation()
conn.create_stack("test_stack", template_body=dummy_template_json3)
conn.describe_stacks().should.have.length_of(1)
conn.delete_stack("test_stack")
conn.describe_stacks().should.have.length_of(0)
# Has boto3 equivalent
@mock_cloudformation_deprecated
def test_bad_describe_stack():
conn = boto.connect_cloudformation()
with pytest.raises(BotoServerError):
conn.describe_stacks("bad_stack")
# Has boto3 equivalent
@mock_cloudformation_deprecated()
def test_cloudformation_params():
dummy_template = {
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Stack 1",
"Resources": {},
"Parameters": {
"APPNAME": {
"Default": "app-name",
"Description": "The name of the app",
"Type": "String",
}
},
}
dummy_template_json = json.dumps(dummy_template)
cfn = boto.connect_cloudformation()
cfn.create_stack(
"test_stack1",
template_body=dummy_template_json,
parameters=[("APPNAME", "testing123")],
)
stack = cfn.describe_stacks("test_stack1")[0]
stack.parameters.should.have.length_of(1)
param = stack.parameters[0]
param.key.should.equal("APPNAME")
param.value.should.equal("testing123")
# Has boto3 equivalent
@mock_cloudformation_deprecated
def test_cloudformation_params_conditions_and_resources_are_distinct():
dummy_template = {
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Stack 1",
"Conditions": {
"FooEnabled": {"Fn::Equals": [{"Ref": "FooEnabled"}, "true"]},
"FooDisabled": {
"Fn::Not": [{"Fn::Equals": [{"Ref": "FooEnabled"}, "true"]}]
},
},
"Parameters": {
"FooEnabled": {"Type": "String", "AllowedValues": ["true", "false"]}
},
"Resources": {
"Bar": {
"Properties": {"CidrBlock": "192.168.0.0/16"},
"Condition": "FooDisabled",
"Type": "AWS::EC2::VPC",
}
},
}
dummy_template_json = json.dumps(dummy_template)
cfn = boto.connect_cloudformation()
cfn.create_stack(
"test_stack1",
template_body=dummy_template_json,
parameters=[("FooEnabled", "true")],
)
stack = cfn.describe_stacks("test_stack1")[0]
resources = stack.list_resources()
assert not [
resource for resource in resources if resource.logical_resource_id == "Bar"
]
# Has boto3 equivalent
@mock_cloudformation_deprecated
def test_stack_tags():
conn = boto.connect_cloudformation()
conn.create_stack(
"test_stack",
template_body=dummy_template_json,
tags={"foo": "bar", "baz": "bleh"},
)
stack = conn.describe_stacks()[0]
dict(stack.tags).should.equal({"foo": "bar", "baz": "bleh"})
# Has boto3 equivalent
@mock_cloudformation_deprecated
def test_update_stack():
conn = boto.connect_cloudformation()
conn.create_stack("test_stack", template_body=dummy_template_json)
conn.update_stack("test_stack", dummy_template_json2)
stack = conn.describe_stacks()[0]
stack.stack_status.should.equal("UPDATE_COMPLETE")
stack.get_template().should.equal(
{
"GetTemplateResponse": {
"GetTemplateResult": {
"TemplateBody": dummy_template_json2,
"ResponseMetadata": {
"RequestId": "2d06e36c-ac1d-11e0-a958-f9382b6eb86bEXAMPLE"
},
}
}
}
)
# Has boto3 equivalent
@mock_cloudformation_deprecated
def test_update_stack_with_previous_template():
conn = boto.connect_cloudformation()
conn.create_stack("test_stack", template_body=dummy_template_json)
conn.update_stack("test_stack", use_previous_template=True)
stack = conn.describe_stacks()[0]
stack.stack_status.should.equal("UPDATE_COMPLETE")
stack.get_template().should.equal(
{
"GetTemplateResponse": {
"GetTemplateResult": {
"TemplateBody": dummy_template_json,
"ResponseMetadata": {
"RequestId": "2d06e36c-ac1d-11e0-a958-f9382b6eb86bEXAMPLE"
},
}
}
}
)
# Has boto3 equivalent
@mock_cloudformation_deprecated
def test_update_stack_with_parameters():
dummy_template = {
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Stack",
"Resources": {
"VPC": {
"Properties": {"CidrBlock": {"Ref": "Bar"}},
"Type": "AWS::EC2::VPC",
}
},
"Parameters": {"Bar": {"Type": "String"}},
}
dummy_template_json = json.dumps(dummy_template)
conn = boto.connect_cloudformation()
conn.create_stack(
"test_stack",
template_body=dummy_template_json,
parameters=[("Bar", "192.168.0.0/16")],
)
conn.update_stack(
"test_stack",
template_body=dummy_template_json,
parameters=[("Bar", "192.168.0.1/16")],
)
stack = conn.describe_stacks()[0]
assert stack.parameters[0].value == "192.168.0.1/16"
# Has boto3 equivalent
@mock_cloudformation_deprecated
def test_update_stack_replace_tags():
conn = boto.connect_cloudformation()
conn.create_stack(
"test_stack", template_body=dummy_template_json, tags={"foo": "bar"}
)
conn.update_stack(
"test_stack", template_body=dummy_template_json, tags={"foo": "baz"}
)
stack = conn.describe_stacks()[0]
stack.stack_status.should.equal("UPDATE_COMPLETE")
# since there is one tag it doesn't come out as a list
dict(stack.tags).should.equal({"foo": "baz"})
# Has boto3 equivalent
@mock_cloudformation_deprecated
def test_update_stack_when_rolled_back():
conn = boto.connect_cloudformation()
stack_id = conn.create_stack("test_stack", template_body=dummy_template_json)
cloudformation_backends[conn.region.name].stacks[
stack_id
].status = "ROLLBACK_COMPLETE"
with pytest.raises(BotoServerError) as err:
conn.update_stack("test_stack", dummy_template_json)
ex = err.value
ex.body.should.match(r"is in ROLLBACK_COMPLETE state and can not be updated")
ex.error_code.should.equal("ValidationError")
ex.reason.should.equal("Bad Request")
ex.status.should.equal(400)
# Has boto3 equivalent
@mock_cloudformation_deprecated
def test_describe_stack_events_shows_create_update_and_delete():
conn = boto.connect_cloudformation()
stack_id = conn.create_stack("test_stack", template_body=dummy_template_json)
conn.update_stack(stack_id, template_body=dummy_template_json2)
conn.delete_stack(stack_id)
# assert begins and ends with stack events
events = conn.describe_stack_events(stack_id)
events[0].resource_type.should.equal("AWS::CloudFormation::Stack")
events[-1].resource_type.should.equal("AWS::CloudFormation::Stack")
# testing ordering of stack events without assuming resource events will not exist
# the AWS API returns events in reverse chronological order
stack_events_to_look_for = iter(
[
("DELETE_COMPLETE", None),
("DELETE_IN_PROGRESS", "User Initiated"),
("UPDATE_COMPLETE", None),
("UPDATE_IN_PROGRESS", "User Initiated"),
("CREATE_COMPLETE", None),
("CREATE_IN_PROGRESS", "User Initiated"),
]
)
try:
for event in events:
event.stack_id.should.equal(stack_id)
event.stack_name.should.equal("test_stack")
event.event_id.should.match(r"[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}")
if event.resource_type == "AWS::CloudFormation::Stack":
event.logical_resource_id.should.equal("test_stack")
event.physical_resource_id.should.equal(stack_id)
status_to_look_for, reason_to_look_for = next(stack_events_to_look_for)
event.resource_status.should.equal(status_to_look_for)
if reason_to_look_for is not None:
event.resource_status_reason.should.equal(reason_to_look_for)
except StopIteration:
assert False, "Too many stack events"
list(stack_events_to_look_for).should.be.empty
with pytest.raises(BotoServerError) as exp:
conn.describe_stack_events("non_existing_stack")
err = exp.value
err.message.should.equal("Stack with id non_existing_stack does not exist")
err.body.should.match(r"Stack with id non_existing_stack does not exist")
err.error_code.should.equal("ValidationError")
err.reason.should.equal("Bad Request")
err.status.should.equal(400)
# Has boto3 equivalent
@mock_cloudformation_deprecated
def test_create_stack_lambda_and_dynamodb():
conn = boto.connect_cloudformation()
dummy_template = {
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Stack Lambda Test 1",
"Parameters": {},
"Resources": {
"func1": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {"S3Bucket": "bucket_123", "S3Key": "key_123"},
"FunctionName": "func1",
"Handler": "handler.handler",
"Role": get_role_name(),
"Runtime": "python2.7",
"Description": "descr",
"MemorySize": 12345,
},
},
"func1version": {
"Type": "AWS::Lambda::Version",
"Properties": {"FunctionName": {"Ref": "func1"}},
},
"tab1": {
"Type": "AWS::DynamoDB::Table",
"Properties": {
"TableName": "tab1",
"KeySchema": [{"AttributeName": "attr1", "KeyType": "HASH"}],
"AttributeDefinitions": [
{"AttributeName": "attr1", "AttributeType": "string"}
],
"ProvisionedThroughput": {
"ReadCapacityUnits": 10,
"WriteCapacityUnits": 10,
},
"StreamSpecification": {"StreamViewType": "KEYS_ONLY"},
},
},
"func1mapping": {
"Type": "AWS::Lambda::EventSourceMapping",
"Properties": {
"FunctionName": {"Ref": "func1"},
"EventSourceArn": {"Fn::GetAtt": ["tab1", "StreamArn"]},
"StartingPosition": "0",
"BatchSize": 100,
"Enabled": True,
},
},
},
}
validate_s3_before = os.environ.get("VALIDATE_LAMBDA_S3", "")
try:
os.environ["VALIDATE_LAMBDA_S3"] = "false"
conn.create_stack(
"test_stack_lambda_1",
template_body=json.dumps(dummy_template),
parameters={}.items(),
)
finally:
os.environ["VALIDATE_LAMBDA_S3"] = validate_s3_before
stack = conn.describe_stacks()[0]
resources = stack.list_resources()
assert len(resources) == 4
# Has boto3 equivalent
@mock_cloudformation_deprecated
def test_create_stack_kinesis():
conn = boto.connect_cloudformation()
dummy_template = {
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Stack Kinesis Test 1",
"Parameters": {},
"Resources": {
"stream1": {
"Type": "AWS::Kinesis::Stream",
"Properties": {"Name": "stream1", "ShardCount": 2},
}
},
}
conn.create_stack(
"test_stack_kinesis_1",
template_body=json.dumps(dummy_template),
parameters={}.items(),
)
stack = conn.describe_stacks()[0]
resources = stack.list_resources()
assert len(resources) == 1
def get_role_name():
with mock_iam_deprecated():
iam = boto.connect_iam()
role = iam.create_role("my-role")["create_role_response"]["create_role_result"][
"role"
]["arn"]
return role

View File

@ -25,7 +25,6 @@ from moto import (
from moto import settings from moto import settings
from moto.core import ACCOUNT_ID from moto.core import ACCOUNT_ID
from moto.cloudformation import cloudformation_backends from moto.cloudformation import cloudformation_backends
from .test_cloudformation_stack_crud import dummy_template_json2, dummy_template_json4
from tests import EXAMPLE_AMI_ID from tests import EXAMPLE_AMI_ID
@ -48,6 +47,12 @@ dummy_template = {
}, },
} }
dummy_template2 = {
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Stack 2",
"Resources": {},
}
dummy_template3 = { dummy_template3 = {
"AWSTemplateFormatVersion": "2010-09-09", "AWSTemplateFormatVersion": "2010-09-09",
"Description": "Stack 3", "Description": "Stack 3",
@ -56,6 +61,29 @@ dummy_template3 = {
}, },
} }
dummy_template4 = {
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"myDynamoDBTable": {
"Type": "AWS::DynamoDB::Table",
"Properties": {
"AttributeDefinitions": [
{"AttributeName": "Name", "AttributeType": "S"},
{"AttributeName": "Age", "AttributeType": "S"},
],
"KeySchema": [
{"AttributeName": "Name", "KeyType": "HASH"},
{"AttributeName": "Age", "KeyType": "RANGE"},
],
"ProvisionedThroughput": {
"ReadCapacityUnits": 5,
"WriteCapacityUnits": 5,
},
"TableName": "Person",
},
}
},
}
dummy_template_with_parameters = { dummy_template_with_parameters = {
"AWSTemplateFormatVersion": "2010-09-09", "AWSTemplateFormatVersion": "2010-09-09",
@ -278,6 +306,8 @@ dummy_update_template_json = json.dumps(dummy_update_template)
dummy_output_template_json = json.dumps(dummy_output_template) dummy_output_template_json = json.dumps(dummy_output_template)
dummy_import_template_json = json.dumps(dummy_import_template) dummy_import_template_json = json.dumps(dummy_import_template)
dummy_redrive_template_json = json.dumps(dummy_redrive_template) dummy_redrive_template_json = json.dumps(dummy_redrive_template)
dummy_template_json2 = json.dumps(dummy_template2)
dummy_template_json4 = json.dumps(dummy_template4)
dummy_unknown_template_json = json.dumps(dummy_unknown_template) dummy_unknown_template_json = json.dumps(dummy_unknown_template)

View File

@ -1,4 +1,4 @@
from __future__ import absolute_import, division, print_function from __future__ import absolute_import, division
# Standard library modules # Standard library modules
import unittest import unittest

View File

@ -12,12 +12,12 @@ from moto.cloudformation.models import FakeStack
from moto.cloudformation.parsing import ( from moto.cloudformation.parsing import (
resource_class_from_type, resource_class_from_type,
parse_condition, parse_condition,
Output,
) )
from moto import mock_cloudformation, mock_sqs, mock_ssm, settings from moto import mock_cloudformation, mock_sqs, mock_ssm, settings
from moto.sqs.models import Queue from moto.sqs.models import Queue
from moto.s3.models import FakeBucket from moto.s3.models import FakeBucket
from moto.cloudformation.utils import yaml_tag_constructor from moto.cloudformation.utils import yaml_tag_constructor
from moto.packages.boto.cloudformation.stack import Output
dummy_template = { dummy_template = {

View File

@ -1,225 +0,0 @@
import boto
from boto.ec2.cloudwatch.alarm import MetricAlarm
from boto.s3.key import Key
from datetime import datetime
import sure # noqa # pylint: disable=unused-import
from moto import mock_cloudwatch_deprecated, mock_s3_deprecated
def alarm_fixture(name="tester", action=None):
action = action or ["arn:alarm"]
return MetricAlarm(
name=name,
namespace="{0}_namespace".format(name),
metric="{0}_metric".format(name),
comparison=">=",
threshold=2.0,
period=60,
evaluation_periods=5,
statistic="Average",
description="A test",
dimensions={"InstanceId": ["i-0123456,i-0123457"]},
alarm_actions=action,
ok_actions=["arn:ok"],
insufficient_data_actions=["arn:insufficient"],
unit="Seconds",
)
# Has boto3 equivalent
@mock_cloudwatch_deprecated
def test_create_alarm():
conn = boto.connect_cloudwatch()
alarm = alarm_fixture()
conn.create_alarm(alarm)
alarms = conn.describe_alarms()
alarms.should.have.length_of(1)
alarm = alarms[0]
alarm.name.should.equal("tester")
alarm.namespace.should.equal("tester_namespace")
alarm.metric.should.equal("tester_metric")
alarm.comparison.should.equal(">=")
alarm.threshold.should.equal(2.0)
alarm.period.should.equal(60)
alarm.evaluation_periods.should.equal(5)
alarm.statistic.should.equal("Average")
alarm.description.should.equal("A test")
dict(alarm.dimensions).should.equal({"InstanceId": ["i-0123456,i-0123457"]})
list(alarm.alarm_actions).should.equal(["arn:alarm"])
list(alarm.ok_actions).should.equal(["arn:ok"])
list(alarm.insufficient_data_actions).should.equal(["arn:insufficient"])
alarm.unit.should.equal("Seconds")
assert "tester" in alarm.alarm_arn
# Has boto3 equivalent
@mock_cloudwatch_deprecated
def test_delete_alarm():
conn = boto.connect_cloudwatch()
alarms = conn.describe_alarms()
alarms.should.have.length_of(0)
alarm = alarm_fixture()
conn.create_alarm(alarm)
alarms = conn.describe_alarms()
alarms.should.have.length_of(1)
alarms[0].delete()
alarms = conn.describe_alarms()
alarms.should.have.length_of(0)
# Has boto3 equivalent
@mock_cloudwatch_deprecated
def test_put_metric_data():
conn = boto.connect_cloudwatch()
conn.put_metric_data(
namespace="tester",
name="metric",
value=1.5,
dimensions={"InstanceId": ["i-0123456,i-0123457"]},
)
metrics = conn.list_metrics()
metric_names = [m for m in metrics if m.name == "metric"]
metric_names.should.have(1)
metric = metrics[0]
metric.namespace.should.equal("tester")
metric.name.should.equal("metric")
dict(metric.dimensions).should.equal({"InstanceId": ["i-0123456,i-0123457"]})
# Has boto3 equivalent
@mock_cloudwatch_deprecated
def test_describe_alarms():
conn = boto.connect_cloudwatch()
alarms = conn.describe_alarms()
alarms.should.have.length_of(0)
conn.create_alarm(alarm_fixture(name="nfoobar", action="afoobar"))
conn.create_alarm(alarm_fixture(name="nfoobaz", action="afoobaz"))
conn.create_alarm(alarm_fixture(name="nbarfoo", action="abarfoo"))
conn.create_alarm(alarm_fixture(name="nbazfoo", action="abazfoo"))
enabled = alarm_fixture(name="enabled1", action=["abarfoo"])
enabled.add_alarm_action("arn:alarm")
conn.create_alarm(enabled)
alarms = conn.describe_alarms()
alarms.should.have.length_of(5)
alarms = conn.describe_alarms(alarm_name_prefix="nfoo")
alarms.should.have.length_of(2)
alarms = conn.describe_alarms(alarm_names=["nfoobar", "nbarfoo", "nbazfoo"])
alarms.should.have.length_of(3)
alarms = conn.describe_alarms(action_prefix="afoo")
alarms.should.have.length_of(2)
alarms = conn.describe_alarms(alarm_name_prefix="enabled")
alarms.should.have.length_of(1)
alarms[0].actions_enabled.should.equal("true")
for alarm in conn.describe_alarms():
alarm.delete()
alarms = conn.describe_alarms()
alarms.should.have.length_of(0)
# Has boto3 equivalent
@mock_cloudwatch_deprecated
def test_describe_alarms_for_metric():
conn = boto.connect_cloudwatch()
conn.create_alarm(alarm_fixture(name="nfoobar", action="afoobar"))
conn.create_alarm(alarm_fixture(name="nfoobaz", action="afoobaz"))
conn.create_alarm(alarm_fixture(name="nbarfoo", action="abarfoo"))
conn.create_alarm(alarm_fixture(name="nbazfoo", action="abazfoo"))
alarms = conn.describe_alarms_for_metric("nbarfoo_metric", "nbarfoo_namespace")
alarms.should.have.length_of(1)
alarms = conn.describe_alarms_for_metric("nbazfoo_metric", "nbazfoo_namespace")
alarms.should.have.length_of(1)
# Has boto3 equivalent
@mock_cloudwatch_deprecated
def test_get_metric_statistics():
conn = boto.connect_cloudwatch()
metric_timestamp = datetime(2018, 4, 9, 13, 0, 0, 0)
conn.put_metric_data(
namespace="tester",
name="metric",
value=1.5,
dimensions={"InstanceId": ["i-0123456,i-0123457"]},
timestamp=metric_timestamp,
unit="Count",
)
metric_kwargs = dict(
namespace="tester",
metric_name="metric",
start_time=metric_timestamp,
end_time=datetime.now(),
period=3600,
statistics=["Minimum"],
unit="Count",
)
datapoints = conn.get_metric_statistics(**metric_kwargs)
datapoints.should.have.length_of(1)
datapoint = datapoints[0]
datapoint.should.have.key("Minimum").which.should.equal(1.5)
datapoint.should.have.key("Timestamp").which.should.equal(metric_timestamp)
metric_kwargs = dict(
namespace="tester",
metric_name="metric",
start_time=metric_timestamp,
end_time=datetime.now(),
period=3600,
statistics=["Minimum"],
unit="Percent",
)
datapoints = conn.get_metric_statistics(**metric_kwargs)
datapoints.should.have.length_of(0)
@mock_s3_deprecated
@mock_cloudwatch_deprecated
def test_cloudwatch_return_s3_metrics():
region = "us-east-1"
cw = boto.ec2.cloudwatch.connect_to_region(region)
s3 = boto.s3.connect_to_region(region)
bucket_name_1 = "test-bucket-1"
bucket_name_2 = "test-bucket-2"
bucket1 = s3.create_bucket(bucket_name=bucket_name_1)
key = Key(bucket1)
key.key = "the-key"
key.set_contents_from_string("foobar" * 4)
s3.create_bucket(bucket_name=bucket_name_2)
metrics_s3_bucket_1 = cw.list_metrics(dimensions={"BucketName": bucket_name_1})
# Verify that the OOTB S3 metrics are available for the created buckets
len(metrics_s3_bucket_1).should.be(2)
metric_names = [m.name for m in metrics_s3_bucket_1]
sorted(metric_names).should.equal(["BucketSizeBytes", "NumberOfObjects"])
# Delete everything, to make sure it's not picked up in later tests
bucket1.delete_key("the-key")
s3.delete_bucket("test-bucket-1")
s3.delete_bucket("test-bucket-2")

View File

@ -24,10 +24,9 @@ def test_put_metric_data_no_dimensions():
) )
metrics = conn.list_metrics()["Metrics"] metrics = conn.list_metrics()["Metrics"]
metrics.should.have.length_of(1) metrics.should.contain(
metric = metrics[0] {"Namespace": "tester", "MetricName": "metric", "Dimensions": []}
metric["Namespace"].should.equal("tester") )
metric["MetricName"].should.equal("metric")
@mock_cloudwatch @mock_cloudwatch
@ -75,10 +74,9 @@ def test_put_metric_data_with_statistics():
) )
metrics = conn.list_metrics()["Metrics"] metrics = conn.list_metrics()["Metrics"]
metrics.should.have.length_of(1) metrics.should.contain(
metric = metrics[0] {"Namespace": "tester", "MetricName": "statmetric", "Dimensions": []}
metric["Namespace"].should.equal("tester") )
metric["MetricName"].should.equal("statmetric")
# TODO: test statistics - https://github.com/spulec/moto/issues/1615 # TODO: test statistics - https://github.com/spulec/moto/issues/1615
@ -170,7 +168,6 @@ def test_get_metric_statistics_dimensions():
Statistics=["Average", "Sum"], Statistics=["Average", "Sum"],
**params[0], **params[0],
) )
print(stats)
stats["Datapoints"].should.have.length_of(1) stats["Datapoints"].should.have.length_of(1)
datapoint = stats["Datapoints"][0] datapoint = stats["Datapoints"][0]
datapoint["Sum"].should.equal(params[1]) datapoint["Sum"].should.equal(params[1])
@ -319,14 +316,14 @@ def test_list_metrics():
create_metrics(cloudwatch, namespace="list_test_2/", metrics=4, data_points=2) create_metrics(cloudwatch, namespace="list_test_2/", metrics=4, data_points=2)
# Verify we can retrieve everything # Verify we can retrieve everything
res = cloudwatch.list_metrics()["Metrics"] res = cloudwatch.list_metrics()["Metrics"]
len(res).should.equal(16) # 2 namespaces * 4 metrics * 2 data points assert len(res) >= 16 # 2 namespaces * 4 metrics * 2 data points
# Verify we can filter by namespace/metric name # Verify we can filter by namespace/metric name
res = cloudwatch.list_metrics(Namespace="list_test_1/")["Metrics"] res = cloudwatch.list_metrics(Namespace="list_test_1/")["Metrics"]
len(res).should.equal(8) # 1 namespace * 4 metrics * 2 data points res.should.have.length_of(8) # 1 namespace * 4 metrics * 2 data points
res = cloudwatch.list_metrics(Namespace="list_test_1/", MetricName="metric1")[ res = cloudwatch.list_metrics(Namespace="list_test_1/", MetricName="metric1")[
"Metrics" "Metrics"
] ]
len(res).should.equal(2) # 1 namespace * 1 metrics * 2 data points res.should.have.length_of(2) # 1 namespace * 1 metrics * 2 data points
# Verify format # Verify format
res.should.equal( res.should.equal(
[ [
@ -353,29 +350,34 @@ def test_list_metrics_paginated():
# Add a boatload of metrics # Add a boatload of metrics
create_metrics(cloudwatch, namespace="test", metrics=100, data_points=1) create_metrics(cloudwatch, namespace="test", metrics=100, data_points=1)
# Verify that a single page is returned until we've reached 500 # Verify that a single page is returned until we've reached 500
first_page = cloudwatch.list_metrics() first_page = cloudwatch.list_metrics(Namespace="test")
first_page["Metrics"].shouldnt.be.empty first_page["Metrics"].shouldnt.be.empty
len(first_page["Metrics"]).should.equal(100) len(first_page["Metrics"]).should.equal(100)
create_metrics(cloudwatch, namespace="test", metrics=200, data_points=2) create_metrics(cloudwatch, namespace="test", metrics=200, data_points=2)
first_page = cloudwatch.list_metrics() first_page = cloudwatch.list_metrics(Namespace="test")
len(first_page["Metrics"]).should.equal(500) len(first_page["Metrics"]).should.equal(500)
first_page.shouldnt.contain("NextToken") first_page.shouldnt.contain("NextToken")
# Verify that adding more data points results in pagination # Verify that adding more data points results in pagination
create_metrics(cloudwatch, namespace="test", metrics=60, data_points=10) create_metrics(cloudwatch, namespace="test", metrics=60, data_points=10)
first_page = cloudwatch.list_metrics() first_page = cloudwatch.list_metrics(Namespace="test")
len(first_page["Metrics"]).should.equal(500) len(first_page["Metrics"]).should.equal(500)
first_page["NextToken"].shouldnt.be.empty first_page["NextToken"].shouldnt.be.empty
# Retrieve second page - and verify there's more where that came from # Retrieve second page - and verify there's more where that came from
second_page = cloudwatch.list_metrics(NextToken=first_page["NextToken"]) second_page = cloudwatch.list_metrics(
Namespace="test", NextToken=first_page["NextToken"]
)
len(second_page["Metrics"]).should.equal(500) len(second_page["Metrics"]).should.equal(500)
second_page.should.contain("NextToken") second_page.should.contain("NextToken")
# Last page should only have the last 100 results, and no NextToken (indicating that pagination is finished) # Last page should only have the last 100 results, and no NextToken (indicating that pagination is finished)
third_page = cloudwatch.list_metrics(NextToken=second_page["NextToken"]) third_page = cloudwatch.list_metrics(
Namespace="test", NextToken=second_page["NextToken"]
)
len(third_page["Metrics"]).should.equal(100) len(third_page["Metrics"]).should.equal(100)
third_page.shouldnt.contain("NextToken") third_page.shouldnt.contain("NextToken")
# Verify that we can't reuse an existing token # Verify that we can't reuse an existing token
with pytest.raises(ClientError) as e: with pytest.raises(ClientError) as e:
cloudwatch.list_metrics(NextToken=first_page["NextToken"]) cloudwatch.list_metrics(Namespace="test", NextToken=first_page["NextToken"])
e.value.response["Error"]["Message"].should.equal( e.value.response["Error"]["Message"].should.equal(
"Request parameter NextToken is invalid" "Request parameter NextToken is invalid"
) )
@ -427,7 +429,7 @@ def test_list_metrics_with_same_dimensions_different_metric_name():
], ],
) )
results = cloudwatch.list_metrics()["Metrics"] results = cloudwatch.list_metrics(Namespace="unique/")["Metrics"]
results.should.have.length_of(2) results.should.have.length_of(2)
# duplicating existing metric # duplicating existing metric
@ -443,7 +445,7 @@ def test_list_metrics_with_same_dimensions_different_metric_name():
) )
# asserting only unique values are returned # asserting only unique values are returned
results = cloudwatch.list_metrics()["Metrics"] results = cloudwatch.list_metrics(Namespace="unique/")["Metrics"]
results.should.have.length_of(2) results.should.have.length_of(2)

View File

@ -1,60 +1,70 @@
import boto import boto3
from boto.exception import EC2ResponseError
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
import os
import unittest import unittest
import pytest import pytest
from moto import mock_ec2_deprecated, mock_s3_deprecated from botocore.exceptions import ClientError
from moto import mock_ec2, mock_s3, settings
from unittest import SkipTest
""" """
Test the different ways that the decorator can be used Test the different ways that the decorator can be used
""" """
@mock_ec2_deprecated @mock_ec2
def test_basic_connect():
boto.connect_ec2()
@mock_ec2_deprecated
def test_basic_decorator(): def test_basic_decorator():
conn = boto.connect_ec2("the_key", "the_secret") client = boto3.client("ec2", region_name="us-west-1")
list(conn.get_all_reservations()).should.equal([]) client.describe_addresses()["Addresses"].should.equal([])
@pytest.fixture
def aws_credentials():
"""Mocked AWS Credentials for moto."""
os.environ["AWS_ACCESS_KEY_ID"] = "testing"
os.environ["AWS_SECRET_ACCESS_KEY"] = "testing"
os.environ["AWS_SECURITY_TOKEN"] = "testing"
os.environ["AWS_SESSION_TOKEN"] = "testing"
@pytest.mark.network @pytest.mark.network
def test_context_manager(): def test_context_manager(aws_credentials):
conn = boto.connect_ec2("the_key", "the_secret") client = boto3.client("ec2", region_name="us-west-1")
with pytest.raises(EC2ResponseError): with pytest.raises(ClientError) as exc:
conn.get_all_reservations() client.describe_addresses()
err = exc.value.response["Error"]
err["Code"].should.equal("AuthFailure")
err["Message"].should.equal(
"AWS was not able to validate the provided access credentials"
)
with mock_ec2_deprecated(): with mock_ec2():
conn = boto.connect_ec2("the_key", "the_secret") client = boto3.client("ec2", region_name="us-west-1")
list(conn.get_all_reservations()).should.equal([]) client.describe_addresses()["Addresses"].should.equal([])
with pytest.raises(EC2ResponseError):
conn = boto.connect_ec2("the_key", "the_secret")
conn.get_all_reservations()
@pytest.mark.network @pytest.mark.network
def test_decorator_start_and_stop(): def test_decorator_start_and_stop():
conn = boto.connect_ec2("the_key", "the_secret") if settings.TEST_SERVER_MODE:
with pytest.raises(EC2ResponseError): raise SkipTest("Authentication always works in ServerMode")
conn.get_all_reservations() mock = mock_ec2()
mock = mock_ec2_deprecated()
mock.start() mock.start()
conn = boto.connect_ec2("the_key", "the_secret") client = boto3.client("ec2", region_name="us-west-1")
list(conn.get_all_reservations()).should.equal([]) client.describe_addresses()["Addresses"].should.equal([])
mock.stop() mock.stop()
with pytest.raises(EC2ResponseError): with pytest.raises(ClientError) as exc:
conn.get_all_reservations() client.describe_addresses()
err = exc.value.response["Error"]
err["Code"].should.equal("AuthFailure")
err["Message"].should.equal(
"AWS was not able to validate the provided access credentials"
)
@mock_ec2_deprecated @mock_ec2
def test_decorater_wrapped_gets_set(): def test_decorater_wrapped_gets_set():
""" """
Moto decorator's __wrapped__ should get set to the tests function Moto decorator's __wrapped__ should get set to the tests function
@ -64,29 +74,32 @@ def test_decorater_wrapped_gets_set():
) )
@mock_ec2_deprecated @mock_ec2
class Tester(object): class Tester(object):
def test_the_class(self): def test_the_class(self):
conn = boto.connect_ec2() client = boto3.client("ec2", region_name="us-west-1")
list(conn.get_all_reservations()).should.have.length_of(0) client.describe_addresses()["Addresses"].should.equal([])
def test_still_the_same(self): def test_still_the_same(self):
conn = boto.connect_ec2() client = boto3.client("ec2", region_name="us-west-1")
list(conn.get_all_reservations()).should.have.length_of(0) client.describe_addresses()["Addresses"].should.equal([])
@mock_s3_deprecated @mock_s3
class TesterWithSetup(unittest.TestCase): class TesterWithSetup(unittest.TestCase):
def setUp(self): def setUp(self):
self.conn = boto.connect_s3() self.client = boto3.client("s3")
self.conn.create_bucket("mybucket") self.client.create_bucket(Bucket="mybucket")
def test_still_the_same(self): def test_still_the_same(self):
bucket = self.conn.get_bucket("mybucket") buckets = self.client.list_buckets()["Buckets"]
bucket.name.should.equal("mybucket") bucket_names = [b["Name"] for b in buckets]
# There is a potential bug in the class-decorator, where the reset API is not called on start.
# This leads to a situation where 'bucket_names' may contain buckets created by earlier tests
bucket_names.should.contain("mybucket")
@mock_s3_deprecated @mock_s3
class TesterWithStaticmethod(object): class TesterWithStaticmethod(object):
@staticmethod @staticmethod
def static(*args): def static(*args):

View File

@ -1,38 +1,12 @@
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
import unittest import unittest
from boto.sqs.connection import SQSConnection
from boto.sqs.message import Message
from boto.ec2 import EC2Connection
import boto3 import boto3
from moto import mock_sqs_deprecated, mock_ec2_deprecated
from moto import mock_sqs, mock_ec2 from moto import mock_sqs, mock_ec2
from tests import EXAMPLE_AMI_ID from tests import EXAMPLE_AMI_ID
class TestNestedDecorators(unittest.TestCase):
# Has boto3 equivalent
@mock_sqs_deprecated
def setup_sqs_queue(self):
conn = SQSConnection()
q = conn.create_queue("some-queue")
m = Message()
m.set_body("This is my first message.")
q.write(m)
self.assertEqual(q.count(), 1)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_nested(self):
self.setup_sqs_queue()
conn = EC2Connection()
conn.run_instances(EXAMPLE_AMI_ID)
class TestNestedDecoratorsBoto3(unittest.TestCase): class TestNestedDecoratorsBoto3(unittest.TestCase):
@mock_sqs @mock_sqs
def setup_sqs_queue(self): def setup_sqs_queue(self):

View File

@ -1,37 +1,9 @@
import unittest import unittest
from moto import mock_dynamodb2_deprecated, mock_dynamodb2 from moto import mock_dynamodb2
import socket import socket
class TestSocketPair(unittest.TestCase): class TestSocketPair(unittest.TestCase):
@mock_dynamodb2_deprecated
def test_asyncio_deprecated(self):
self.assertIn(
"httpretty.core.fakesock.socket",
str(socket.socket),
"Our mock should be present",
)
import asyncio
self.assertIsNotNone(asyncio.get_event_loop())
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_socket_pair_deprecated(self):
self.assertIn(
"httpretty.core.fakesock.socket",
str(socket.socket),
"Our mock should be present",
)
a, b = socket.socketpair()
self.assertIsNotNone(a)
self.assertIsNotNone(b)
if a:
a.close()
if b:
b.close()
@mock_dynamodb2 @mock_dynamodb2
def test_socket_pair(self): def test_socket_pair(self):
a, b = socket.socketpair() a, b = socket.socketpair()

View File

@ -7,10 +7,7 @@ from moto import mock_s3
service_names = [ service_names = [
(d[5:], "") (d[5:], "")
for d in dir(moto) for d in dir(moto)
if d.startswith("mock_") if d.startswith("mock_") and not d == "mock_xray_client" and not d == "mock_all"
and not d.endswith("_deprecated")
and not d == "mock_xray_client"
and not d == "mock_all"
] ]

View File

@ -1,9 +1,7 @@
import boto.datapipeline
import sure # noqa # pylint: disable=unused-import
import boto3 import boto3
import sure # noqa # pylint: disable=unused-import
from moto import mock_datapipeline from moto import mock_datapipeline
from moto import mock_datapipeline_deprecated
from moto.datapipeline.utils import remove_capitalization_of_dict_keys from moto.datapipeline.utils import remove_capitalization_of_dict_keys
@ -13,28 +11,6 @@ def get_value_from_fields(key, fields):
return field["stringValue"] return field["stringValue"]
# Has boto3 equivalent
@mock_datapipeline_deprecated
def test_create_pipeline():
conn = boto.datapipeline.connect_to_region("us-west-2")
res = conn.create_pipeline("mypipeline", "some-unique-id")
pipeline_id = res["pipelineId"]
pipeline_descriptions = conn.describe_pipelines([pipeline_id])[
"pipelineDescriptionList"
]
pipeline_descriptions.should.have.length_of(1)
pipeline_description = pipeline_descriptions[0]
pipeline_description["name"].should.equal("mypipeline")
pipeline_description["pipelineId"].should.equal(pipeline_id)
fields = pipeline_description["fields"]
get_value_from_fields("@pipelineState", fields).should.equal("PENDING")
get_value_from_fields("uniqueId", fields).should.equal("some-unique-id")
@mock_datapipeline @mock_datapipeline
def test_create_pipeline_boto3(): def test_create_pipeline_boto3():
conn = boto3.client("datapipeline", region_name="us-west-2") conn = boto3.client("datapipeline", region_name="us-west-2")
@ -85,25 +61,6 @@ PIPELINE_OBJECTS = [
] ]
# Has boto3 equivalent
@mock_datapipeline_deprecated
def test_creating_pipeline_definition():
conn = boto.datapipeline.connect_to_region("us-west-2")
res = conn.create_pipeline("mypipeline", "some-unique-id")
pipeline_id = res["pipelineId"]
conn.put_pipeline_definition(PIPELINE_OBJECTS, pipeline_id)
pipeline_definition = conn.get_pipeline_definition(pipeline_id)
pipeline_definition["pipelineObjects"].should.have.length_of(3)
default_object = pipeline_definition["pipelineObjects"][0]
default_object["name"].should.equal("Default")
default_object["id"].should.equal("Default")
default_object["fields"].should.equal(
[{"key": "workerGroup", "stringValue": "workerGroup"}]
)
@mock_datapipeline @mock_datapipeline
def test_creating_pipeline_definition_boto3(): def test_creating_pipeline_definition_boto3():
conn = boto3.client("datapipeline", region_name="us-west-2") conn = boto3.client("datapipeline", region_name="us-west-2")
@ -124,27 +81,6 @@ def test_creating_pipeline_definition_boto3():
) )
# Has boto3 equivalent
@mock_datapipeline_deprecated
def test_describing_pipeline_objects():
conn = boto.datapipeline.connect_to_region("us-west-2")
res = conn.create_pipeline("mypipeline", "some-unique-id")
pipeline_id = res["pipelineId"]
conn.put_pipeline_definition(PIPELINE_OBJECTS, pipeline_id)
objects = conn.describe_objects(["Schedule", "Default"], pipeline_id)[
"pipelineObjects"
]
objects.should.have.length_of(2)
default_object = [x for x in objects if x["id"] == "Default"][0]
default_object["name"].should.equal("Default")
default_object["fields"].should.equal(
[{"key": "workerGroup", "stringValue": "workerGroup"}]
)
@mock_datapipeline @mock_datapipeline
def test_describing_pipeline_objects_boto3(): def test_describing_pipeline_objects_boto3():
conn = boto3.client("datapipeline", region_name="us-west-2") conn = boto3.client("datapipeline", region_name="us-west-2")
@ -167,26 +103,6 @@ def test_describing_pipeline_objects_boto3():
) )
# Has boto3 equivalent
@mock_datapipeline_deprecated
def test_activate_pipeline():
conn = boto.datapipeline.connect_to_region("us-west-2")
res = conn.create_pipeline("mypipeline", "some-unique-id")
pipeline_id = res["pipelineId"]
conn.activate_pipeline(pipeline_id)
pipeline_descriptions = conn.describe_pipelines([pipeline_id])[
"pipelineDescriptionList"
]
pipeline_descriptions.should.have.length_of(1)
pipeline_description = pipeline_descriptions[0]
fields = pipeline_description["fields"]
get_value_from_fields("@pipelineState", fields).should.equal("SCHEDULED")
@mock_datapipeline @mock_datapipeline
def test_activate_pipeline_boto3(): def test_activate_pipeline_boto3():
conn = boto3.client("datapipeline", region_name="us-west-2") conn = boto3.client("datapipeline", region_name="us-west-2")
@ -205,20 +121,6 @@ def test_activate_pipeline_boto3():
get_value_from_fields("@pipelineState", fields).should.equal("SCHEDULED") get_value_from_fields("@pipelineState", fields).should.equal("SCHEDULED")
# Has boto3 equivalent
@mock_datapipeline_deprecated
def test_delete_pipeline():
conn = boto.datapipeline.connect_to_region("us-west-2")
res = conn.create_pipeline("mypipeline", "some-unique-id")
pipeline_id = res["pipelineId"]
conn.delete_pipeline(pipeline_id)
response = conn.list_pipelines()
response["pipelineIdList"].should.have.length_of(0)
@mock_datapipeline @mock_datapipeline
def test_delete_pipeline_boto3(): def test_delete_pipeline_boto3():
conn = boto3.client("datapipeline", region_name="us-west-2") conn = boto3.client("datapipeline", region_name="us-west-2")
@ -232,26 +134,6 @@ def test_delete_pipeline_boto3():
response["pipelineIdList"].should.have.length_of(0) response["pipelineIdList"].should.have.length_of(0)
# Has boto3 equivalent
@mock_datapipeline_deprecated
def test_listing_pipelines():
conn = boto.datapipeline.connect_to_region("us-west-2")
res1 = conn.create_pipeline("mypipeline1", "some-unique-id1")
res2 = conn.create_pipeline("mypipeline2", "some-unique-id2")
response = conn.list_pipelines()
response["hasMoreResults"].should.be(False)
response["marker"].should.be.none
response["pipelineIdList"].should.have.length_of(2)
response["pipelineIdList"].should.contain(
{"id": res1["pipelineId"], "name": "mypipeline1"}
)
response["pipelineIdList"].should.contain(
{"id": res2["pipelineId"], "name": "mypipeline2"}
)
@mock_datapipeline @mock_datapipeline
def test_listing_pipelines_boto3(): def test_listing_pipelines_boto3():
conn = boto3.client("datapipeline", region_name="us-west-2") conn = boto3.client("datapipeline", region_name="us-west-2")
@ -271,20 +153,6 @@ def test_listing_pipelines_boto3():
) )
# Has boto3 equivalent
@mock_datapipeline_deprecated
def test_listing_paginated_pipelines():
conn = boto.datapipeline.connect_to_region("us-west-2")
for i in range(100):
conn.create_pipeline("mypipeline%d" % i, "some-unique-id%d" % i)
response = conn.list_pipelines()
response["hasMoreResults"].should.be(True)
response["marker"].should.equal(response["pipelineIdList"][-1]["id"])
response["pipelineIdList"].should.have.length_of(50)
@mock_datapipeline @mock_datapipeline
def test_listing_paginated_pipelines_boto3(): def test_listing_paginated_pipelines_boto3():
conn = boto3.client("datapipeline", region_name="us-west-2") conn = boto3.client("datapipeline", region_name="us-west-2")

View File

@ -1,12 +1,7 @@
import boto
import boto.dynamodb
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
import pytest import pytest
from moto import mock_dynamodb, mock_dynamodb_deprecated from moto import mock_dynamodb
from moto.dynamodb import dynamodb_backend
from boto.exception import DynamoDBResponseError
def test_deprecation_warning(): def test_deprecation_warning():
@ -15,45 +10,3 @@ def test_deprecation_warning():
str(record[0].message).should.contain( str(record[0].message).should.contain(
"Module mock_dynamodb has been deprecated, and will be repurposed in a later release" "Module mock_dynamodb has been deprecated, and will be repurposed in a later release"
) )
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_list_tables():
name = "TestTable"
dynamodb_backend.create_table(name, hash_key_attr="name", hash_key_type="S")
conn = boto.connect_dynamodb("the_key", "the_secret")
assert conn.list_tables() == ["TestTable"]
@mock_dynamodb_deprecated
def test_list_tables_layer_1():
dynamodb_backend.create_table("test_1", hash_key_attr="name", hash_key_type="S")
dynamodb_backend.create_table("test_2", hash_key_attr="name", hash_key_type="S")
conn = boto.connect_dynamodb("the_key", "the_secret")
res = conn.layer1.list_tables(limit=1)
expected = {"TableNames": ["test_1"], "LastEvaluatedTableName": "test_1"}
res.should.equal(expected)
res = conn.layer1.list_tables(limit=1, start_table="test_1")
expected = {"TableNames": ["test_2"]}
res.should.equal(expected)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_describe_missing_table():
conn = boto.connect_dynamodb("the_key", "the_secret")
with pytest.raises(DynamoDBResponseError):
conn.describe_table("messages")
# Has boto3 equivalent
# This test is pointless though, as we treat DynamoDB as a global resource
@mock_dynamodb_deprecated
def test_dynamodb_with_connect_to_region():
# this will work if connected with boto.connect_dynamodb()
dynamodb = boto.dynamodb.connect_to_region("us-west-2")
schema = dynamodb.create_schema("column1", str(), "column2", int())
dynamodb.create_table("table1", schema, 200, 200)

View File

@ -1,485 +0,0 @@
import boto
import sure # noqa # pylint: disable=unused-import
from freezegun import freeze_time
from moto import mock_dynamodb_deprecated
from boto.dynamodb import condition
from boto.dynamodb.exceptions import DynamoDBKeyNotFoundError, DynamoDBValidationError
from boto.exception import DynamoDBResponseError
def create_table(conn):
message_table_schema = conn.create_schema(
hash_key_name="forum_name",
hash_key_proto_value=str,
range_key_name="subject",
range_key_proto_value=str,
)
table = conn.create_table(
name="messages", schema=message_table_schema, read_units=10, write_units=10
)
return table
# Has boto3 equivalent
@freeze_time("2012-01-14")
@mock_dynamodb_deprecated
def test_create_table():
conn = boto.connect_dynamodb()
create_table(conn)
expected = {
"Table": {
"CreationDateTime": 1326499200.0,
"ItemCount": 0,
"KeySchema": {
"HashKeyElement": {"AttributeName": "forum_name", "AttributeType": "S"},
"RangeKeyElement": {"AttributeName": "subject", "AttributeType": "S"},
},
"ProvisionedThroughput": {
"ReadCapacityUnits": 10,
"WriteCapacityUnits": 10,
},
"TableName": "messages",
"TableSizeBytes": 0,
"TableStatus": "ACTIVE",
}
}
conn.describe_table("messages").should.equal(expected)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_delete_table():
conn = boto.connect_dynamodb()
create_table(conn)
conn.list_tables().should.have.length_of(1)
conn.layer1.delete_table("messages")
conn.list_tables().should.have.length_of(0)
conn.layer1.delete_table.when.called_with("messages").should.throw(
DynamoDBResponseError
)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_update_table_throughput():
conn = boto.connect_dynamodb()
table = create_table(conn)
table.read_units.should.equal(10)
table.write_units.should.equal(10)
table.update_throughput(5, 6)
table.refresh()
table.read_units.should.equal(5)
table.write_units.should.equal(6)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_item_add_and_describe_and_update():
conn = boto.connect_dynamodb()
table = create_table(conn)
item_data = {
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
item = table.new_item(
hash_key="LOLCat Forum", range_key="Check this out!", attrs=item_data
)
item.put()
table.has_item("LOLCat Forum", "Check this out!").should.equal(True)
returned_item = table.get_item(
hash_key="LOLCat Forum",
range_key="Check this out!",
attributes_to_get=["Body", "SentBy"],
)
dict(returned_item).should.equal(
{
"forum_name": "LOLCat Forum",
"subject": "Check this out!",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
}
)
item["SentBy"] = "User B"
item.put()
returned_item = table.get_item(
hash_key="LOLCat Forum",
range_key="Check this out!",
attributes_to_get=["Body", "SentBy"],
)
dict(returned_item).should.equal(
{
"forum_name": "LOLCat Forum",
"subject": "Check this out!",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User B",
}
)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_item_put_without_table():
conn = boto.connect_dynamodb()
conn.layer1.put_item.when.called_with(
table_name="undeclared-table",
item=dict(hash_key="LOLCat Forum", range_key="Check this out!"),
).should.throw(DynamoDBResponseError)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_get_missing_item():
conn = boto.connect_dynamodb()
table = create_table(conn)
table.get_item.when.called_with(hash_key="tester", range_key="other").should.throw(
DynamoDBKeyNotFoundError
)
table.has_item("foobar", "more").should.equal(False)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_get_item_with_undeclared_table():
conn = boto.connect_dynamodb()
conn.layer1.get_item.when.called_with(
table_name="undeclared-table",
key={"HashKeyElement": {"S": "tester"}, "RangeKeyElement": {"S": "test-range"}},
).should.throw(DynamoDBKeyNotFoundError)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_get_item_without_range_key():
conn = boto.connect_dynamodb()
message_table_schema = conn.create_schema(
hash_key_name="test_hash",
hash_key_proto_value=int,
range_key_name="test_range",
range_key_proto_value=int,
)
table = conn.create_table(
name="messages", schema=message_table_schema, read_units=10, write_units=10
)
hash_key = 3241526475
range_key = 1234567890987
new_item = table.new_item(hash_key=hash_key, range_key=range_key)
new_item.put()
table.get_item.when.called_with(hash_key=hash_key).should.throw(
DynamoDBValidationError
)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_delete_item():
conn = boto.connect_dynamodb()
table = create_table(conn)
item_data = {
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
item = table.new_item(
hash_key="LOLCat Forum", range_key="Check this out!", attrs=item_data
)
item.put()
table.refresh()
table.item_count.should.equal(1)
response = item.delete()
response.should.equal({"Attributes": [], "ConsumedCapacityUnits": 0.5})
table.refresh()
table.item_count.should.equal(0)
item.delete.when.called_with().should.throw(DynamoDBResponseError)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_delete_item_with_attribute_response():
conn = boto.connect_dynamodb()
table = create_table(conn)
item_data = {
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
item = table.new_item(
hash_key="LOLCat Forum", range_key="Check this out!", attrs=item_data
)
item.put()
table.refresh()
table.item_count.should.equal(1)
response = item.delete(return_values="ALL_OLD")
response.should.equal(
{
"Attributes": {
"Body": "http://url_to_lolcat.gif",
"forum_name": "LOLCat Forum",
"ReceivedTime": "12/9/2011 11:36:03 PM",
"SentBy": "User A",
"subject": "Check this out!",
},
"ConsumedCapacityUnits": 0.5,
}
)
table.refresh()
table.item_count.should.equal(0)
item.delete.when.called_with().should.throw(DynamoDBResponseError)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_delete_item_with_undeclared_table():
conn = boto.connect_dynamodb()
conn.layer1.delete_item.when.called_with(
table_name="undeclared-table",
key={"HashKeyElement": {"S": "tester"}, "RangeKeyElement": {"S": "test-range"}},
).should.throw(DynamoDBResponseError)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_query():
conn = boto.connect_dynamodb()
table = create_table(conn)
item_data = {
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
item = table.new_item(hash_key="the-key", range_key="456", attrs=item_data)
item.put()
item = table.new_item(hash_key="the-key", range_key="123", attrs=item_data)
item.put()
item = table.new_item(hash_key="the-key", range_key="789", attrs=item_data)
item.put()
results = table.query(hash_key="the-key", range_key_condition=condition.GT("1"))
results.response["Items"].should.have.length_of(3)
results = table.query(hash_key="the-key", range_key_condition=condition.GT("234"))
results.response["Items"].should.have.length_of(2)
results = table.query(hash_key="the-key", range_key_condition=condition.GT("9999"))
results.response["Items"].should.have.length_of(0)
results = table.query(
hash_key="the-key", range_key_condition=condition.CONTAINS("12")
)
results.response["Items"].should.have.length_of(1)
results = table.query(
hash_key="the-key", range_key_condition=condition.BEGINS_WITH("7")
)
results.response["Items"].should.have.length_of(1)
results = table.query(
hash_key="the-key", range_key_condition=condition.BETWEEN("567", "890")
)
results.response["Items"].should.have.length_of(1)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_query_with_undeclared_table():
conn = boto.connect_dynamodb()
conn.layer1.query.when.called_with(
table_name="undeclared-table",
hash_key_value={"S": "the-key"},
range_key_conditions={
"AttributeValueList": [{"S": "User B"}],
"ComparisonOperator": "EQ",
},
).should.throw(DynamoDBResponseError)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_scan():
conn = boto.connect_dynamodb()
table = create_table(conn)
item_data = {
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
item = table.new_item(hash_key="the-key", range_key="456", attrs=item_data)
item.put()
item = table.new_item(hash_key="the-key", range_key="123", attrs=item_data)
item.put()
item_data = {
"Body": "http://url_to_lolcat.gif",
"SentBy": "User B",
"ReceivedTime": "12/9/2011 11:36:03 PM",
"Ids": set([1, 2, 3]),
"PK": 7,
}
item = table.new_item(hash_key="the-key", range_key="789", attrs=item_data)
item.put()
results = table.scan()
results.response["Items"].should.have.length_of(3)
results = table.scan(scan_filter={"SentBy": condition.EQ("User B")})
results.response["Items"].should.have.length_of(1)
results = table.scan(scan_filter={"Body": condition.BEGINS_WITH("http")})
results.response["Items"].should.have.length_of(3)
results = table.scan(scan_filter={"Ids": condition.CONTAINS(2)})
results.response["Items"].should.have.length_of(1)
results = table.scan(scan_filter={"Ids": condition.NOT_NULL()})
results.response["Items"].should.have.length_of(1)
results = table.scan(scan_filter={"Ids": condition.NULL()})
results.response["Items"].should.have.length_of(2)
results = table.scan(scan_filter={"PK": condition.BETWEEN(8, 9)})
results.response["Items"].should.have.length_of(0)
results = table.scan(scan_filter={"PK": condition.BETWEEN(5, 8)})
results.response["Items"].should.have.length_of(1)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_scan_with_undeclared_table():
conn = boto.connect_dynamodb()
conn.layer1.scan.when.called_with(
table_name="undeclared-table",
scan_filter={
"SentBy": {
"AttributeValueList": [{"S": "User B"}],
"ComparisonOperator": "EQ",
}
},
).should.throw(DynamoDBResponseError)
@mock_dynamodb_deprecated
def test_scan_after_has_item():
conn = boto.connect_dynamodb()
table = create_table(conn)
list(table.scan()).should.equal([])
table.has_item(hash_key="the-key", range_key="123")
list(table.scan()).should.equal([])
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_write_batch():
conn = boto.connect_dynamodb()
table = create_table(conn)
batch_list = conn.new_batch_write_list()
items = []
items.append(
table.new_item(
hash_key="the-key",
range_key="123",
attrs={
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
},
)
)
items.append(
table.new_item(
hash_key="the-key",
range_key="789",
attrs={
"Body": "http://url_to_lolcat.gif",
"SentBy": "User B",
"ReceivedTime": "12/9/2011 11:36:03 PM",
"Ids": set([1, 2, 3]),
"PK": 7,
},
)
)
batch_list.add_batch(table, puts=items)
conn.batch_write_item(batch_list)
table.refresh()
table.item_count.should.equal(2)
batch_list = conn.new_batch_write_list()
batch_list.add_batch(table, deletes=[("the-key", "789")])
conn.batch_write_item(batch_list)
table.refresh()
table.item_count.should.equal(1)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_batch_read():
conn = boto.connect_dynamodb()
table = create_table(conn)
item_data = {
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
item = table.new_item(hash_key="the-key", range_key="456", attrs=item_data)
item.put()
item = table.new_item(hash_key="the-key", range_key="123", attrs=item_data)
item.put()
item_data = {
"Body": "http://url_to_lolcat.gif",
"SentBy": "User B",
"ReceivedTime": "12/9/2011 11:36:03 PM",
"Ids": set([1, 2, 3]),
"PK": 7,
}
item = table.new_item(hash_key="another-key", range_key="789", attrs=item_data)
item.put()
items = table.batch_get_item([("the-key", "123"), ("another-key", "789")])
# Iterate through so that batch_item gets called
count = len([x for x in items])
count.should.equal(2)

View File

@ -1,405 +0,0 @@
import boto
import sure # noqa # pylint: disable=unused-import
from freezegun import freeze_time
from moto import mock_dynamodb_deprecated
from boto.dynamodb import condition
from boto.dynamodb.exceptions import DynamoDBKeyNotFoundError
from boto.exception import DynamoDBResponseError
def create_table(conn):
message_table_schema = conn.create_schema(
hash_key_name="forum_name", hash_key_proto_value=str
)
table = conn.create_table(
name="messages", schema=message_table_schema, read_units=10, write_units=10
)
return table
# Has boto3 equivalent
@freeze_time("2012-01-14")
@mock_dynamodb_deprecated
def test_create_table():
conn = boto.connect_dynamodb()
create_table(conn)
expected = {
"Table": {
"CreationDateTime": 1326499200.0,
"ItemCount": 0,
"KeySchema": {
"HashKeyElement": {"AttributeName": "forum_name", "AttributeType": "S"}
},
"ProvisionedThroughput": {
"ReadCapacityUnits": 10,
"WriteCapacityUnits": 10,
},
"TableName": "messages",
"TableSizeBytes": 0,
"TableStatus": "ACTIVE",
}
}
conn.describe_table("messages").should.equal(expected)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_delete_table():
conn = boto.connect_dynamodb()
create_table(conn)
conn.list_tables().should.have.length_of(1)
conn.layer1.delete_table("messages")
conn.list_tables().should.have.length_of(0)
conn.layer1.delete_table.when.called_with("messages").should.throw(
DynamoDBResponseError
)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_update_table_throughput():
conn = boto.connect_dynamodb()
table = create_table(conn)
table.read_units.should.equal(10)
table.write_units.should.equal(10)
table.update_throughput(5, 6)
table.refresh()
table.read_units.should.equal(5)
table.write_units.should.equal(6)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_item_add_and_describe_and_update():
conn = boto.connect_dynamodb()
table = create_table(conn)
item_data = {
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
item = table.new_item(hash_key="LOLCat Forum", attrs=item_data)
item.put()
returned_item = table.get_item(
hash_key="LOLCat Forum", attributes_to_get=["Body", "SentBy"]
)
dict(returned_item).should.equal(
{
"forum_name": "LOLCat Forum",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
}
)
item["SentBy"] = "User B"
item.put()
returned_item = table.get_item(
hash_key="LOLCat Forum", attributes_to_get=["Body", "SentBy"]
)
dict(returned_item).should.equal(
{
"forum_name": "LOLCat Forum",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User B",
}
)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_item_put_without_table():
conn = boto.connect_dynamodb()
conn.layer1.put_item.when.called_with(
table_name="undeclared-table", item=dict(hash_key="LOLCat Forum")
).should.throw(DynamoDBResponseError)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_get_missing_item():
conn = boto.connect_dynamodb()
table = create_table(conn)
table.get_item.when.called_with(hash_key="tester").should.throw(
DynamoDBKeyNotFoundError
)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_get_item_with_undeclared_table():
conn = boto.connect_dynamodb()
conn.layer1.get_item.when.called_with(
table_name="undeclared-table", key={"HashKeyElement": {"S": "tester"}}
).should.throw(DynamoDBKeyNotFoundError)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_delete_item():
conn = boto.connect_dynamodb()
table = create_table(conn)
item_data = {
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
item = table.new_item(hash_key="LOLCat Forum", attrs=item_data)
item.put()
table.refresh()
table.item_count.should.equal(1)
response = item.delete()
response.should.equal({"Attributes": [], "ConsumedCapacityUnits": 0.5})
table.refresh()
table.item_count.should.equal(0)
item.delete.when.called_with().should.throw(DynamoDBResponseError)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_delete_item_with_attribute_response():
conn = boto.connect_dynamodb()
table = create_table(conn)
item_data = {
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
item = table.new_item(hash_key="LOLCat Forum", attrs=item_data)
item.put()
table.refresh()
table.item_count.should.equal(1)
response = item.delete(return_values="ALL_OLD")
response.should.equal(
{
"Attributes": {
"Body": "http://url_to_lolcat.gif",
"forum_name": "LOLCat Forum",
"ReceivedTime": "12/9/2011 11:36:03 PM",
"SentBy": "User A",
},
"ConsumedCapacityUnits": 0.5,
}
)
table.refresh()
table.item_count.should.equal(0)
item.delete.when.called_with().should.throw(DynamoDBResponseError)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_delete_item_with_undeclared_table():
conn = boto.connect_dynamodb()
conn.layer1.delete_item.when.called_with(
table_name="undeclared-table", key={"HashKeyElement": {"S": "tester"}}
).should.throw(DynamoDBResponseError)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_query():
conn = boto.connect_dynamodb()
table = create_table(conn)
item_data = {
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
item = table.new_item(hash_key="the-key", attrs=item_data)
item.put()
results = table.query(hash_key="the-key")
results.response["Items"].should.have.length_of(1)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_query_with_undeclared_table():
conn = boto.connect_dynamodb()
conn.layer1.query.when.called_with(
table_name="undeclared-table", hash_key_value={"S": "the-key"}
).should.throw(DynamoDBResponseError)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_scan():
conn = boto.connect_dynamodb()
table = create_table(conn)
item_data = {
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
item = table.new_item(hash_key="the-key", attrs=item_data)
item.put()
item = table.new_item(hash_key="the-key2", attrs=item_data)
item.put()
item_data = {
"Body": "http://url_to_lolcat.gif",
"SentBy": "User B",
"ReceivedTime": "12/9/2011 11:36:03 PM",
"Ids": set([1, 2, 3]),
"PK": 7,
}
item = table.new_item(hash_key="the-key3", attrs=item_data)
item.put()
results = table.scan()
results.response["Items"].should.have.length_of(3)
results = table.scan(scan_filter={"SentBy": condition.EQ("User B")})
results.response["Items"].should.have.length_of(1)
results = table.scan(scan_filter={"Body": condition.BEGINS_WITH("http")})
results.response["Items"].should.have.length_of(3)
results = table.scan(scan_filter={"Ids": condition.CONTAINS(2)})
results.response["Items"].should.have.length_of(1)
results = table.scan(scan_filter={"Ids": condition.NOT_NULL()})
results.response["Items"].should.have.length_of(1)
results = table.scan(scan_filter={"Ids": condition.NULL()})
results.response["Items"].should.have.length_of(2)
results = table.scan(scan_filter={"PK": condition.BETWEEN(8, 9)})
results.response["Items"].should.have.length_of(0)
results = table.scan(scan_filter={"PK": condition.BETWEEN(5, 8)})
results.response["Items"].should.have.length_of(1)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_scan_with_undeclared_table():
conn = boto.connect_dynamodb()
conn.layer1.scan.when.called_with(
table_name="undeclared-table",
scan_filter={
"SentBy": {
"AttributeValueList": [{"S": "User B"}],
"ComparisonOperator": "EQ",
}
},
).should.throw(DynamoDBResponseError)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_scan_after_has_item():
conn = boto.connect_dynamodb()
table = create_table(conn)
list(table.scan()).should.equal([])
table.has_item("the-key")
list(table.scan()).should.equal([])
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_write_batch():
conn = boto.connect_dynamodb()
table = create_table(conn)
batch_list = conn.new_batch_write_list()
items = []
items.append(
table.new_item(
hash_key="the-key",
attrs={
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
},
)
)
items.append(
table.new_item(
hash_key="the-key2",
attrs={
"Body": "http://url_to_lolcat.gif",
"SentBy": "User B",
"ReceivedTime": "12/9/2011 11:36:03 PM",
"Ids": set([1, 2, 3]),
"PK": 7,
},
)
)
batch_list.add_batch(table, puts=items)
conn.batch_write_item(batch_list)
table.refresh()
table.item_count.should.equal(2)
batch_list = conn.new_batch_write_list()
batch_list.add_batch(table, deletes=[("the-key")])
conn.batch_write_item(batch_list)
table.refresh()
table.item_count.should.equal(1)
# Has boto3 equivalent
@mock_dynamodb_deprecated
def test_batch_read():
conn = boto.connect_dynamodb()
table = create_table(conn)
item_data = {
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
item = table.new_item(hash_key="the-key1", attrs=item_data)
item.put()
item = table.new_item(hash_key="the-key2", attrs=item_data)
item.put()
item_data = {
"Body": "http://url_to_lolcat.gif",
"SentBy": "User B",
"ReceivedTime": "12/9/2011 11:36:03 PM",
"Ids": set([1, 2, 3]),
"PK": 7,
}
item = table.new_item(hash_key="another-key", attrs=item_data)
item.put()
items = table.batch_get_item([("the-key1"), ("another-key")])
# Iterate through so that batch_item gets called
count = len([x for x in items])
count.should.have.equal(2)

View File

@ -1,53 +1,20 @@
from __future__ import print_function
import uuid import uuid
from datetime import datetime from datetime import datetime
from decimal import Decimal from decimal import Decimal
import boto
import boto3 import boto3
from boto3.dynamodb.conditions import Attr, Key from boto3.dynamodb.conditions import Attr, Key
import re import re
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
from moto import mock_dynamodb2, mock_dynamodb2_deprecated from moto import mock_dynamodb2
from moto.dynamodb2 import dynamodb_backend2, dynamodb_backends2 from moto.dynamodb2 import dynamodb_backends2
from boto.exception import JSONResponseError
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
from tests.helpers import requires_boto_gte
import moto.dynamodb2.comparisons import moto.dynamodb2.comparisons
import moto.dynamodb2.models import moto.dynamodb2.models
import pytest import pytest
try:
import boto.dynamodb2
except ImportError:
print("This boto version is not supported")
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_list_tables():
name = "TestTable"
# Should make tables properly with boto
dynamodb_backend2.create_table(
name,
attr=[
{"AttributeType": "S", "AttributeName": "forum_name"},
{"AttributeType": "S", "AttributeName": "subject"},
],
schema=[
{"KeyType": "HASH", "AttributeName": "forum_name"},
{"KeyType": "RANGE", "AttributeName": "subject"},
],
)
conn = boto.dynamodb2.connect_to_region(
"us-east-1", aws_access_key_id="ak", aws_secret_access_key="sk"
)
assert conn.list_tables()["TableNames"] == [name]
@mock_dynamodb2 @mock_dynamodb2
@pytest.mark.parametrize( @pytest.mark.parametrize(
@ -67,34 +34,6 @@ def test_list_tables_boto3(names):
conn.list_tables()["TableNames"].should.equal(names) conn.list_tables()["TableNames"].should.equal(names)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_list_tables_layer_1():
# Should make tables properly with boto
dynamodb_backend2.create_table(
"test_1",
attr=[{"AttributeType": "S", "AttributeName": "name"},],
schema=[{"KeyType": "HASH", "AttributeName": "name"}],
)
dynamodb_backend2.create_table(
"test_2",
attr=[{"AttributeType": "S", "AttributeName": "name"}],
schema=[{"KeyType": "HASH", "AttributeName": "name"}],
)
conn = boto.dynamodb2.connect_to_region(
"us-east-1", aws_access_key_id="ak", aws_secret_access_key="sk"
)
res = conn.list_tables(limit=1)
expected = {"TableNames": ["test_1"], "LastEvaluatedTableName": "test_1"}
res.should.equal(expected)
res = conn.list_tables(limit=1, exclusive_start_table_name="test_1")
expected = {"TableNames": ["test_2"]}
res.should.equal(expected)
@mock_dynamodb2 @mock_dynamodb2
def test_list_tables_paginated(): def test_list_tables_paginated():
conn = boto3.client("dynamodb", region_name="us-west-2") conn = boto3.client("dynamodb", region_name="us-west-2")
@ -119,17 +58,6 @@ def test_list_tables_paginated():
res.shouldnt.have.key("LastEvaluatedTableName") res.shouldnt.have.key("LastEvaluatedTableName")
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_describe_missing_table():
conn = boto.dynamodb2.connect_to_region(
"us-west-2", aws_access_key_id="ak", aws_secret_access_key="sk"
)
with pytest.raises(JSONResponseError):
conn.describe_table("messages")
@mock_dynamodb2 @mock_dynamodb2
def test_describe_missing_table_boto3(): def test_describe_missing_table_boto3():
conn = boto3.client("dynamodb", region_name="us-west-2") conn = boto3.client("dynamodb", region_name="us-west-2")
@ -140,7 +68,6 @@ def test_describe_missing_table_boto3():
ex.value.response["Error"]["Message"].should.equal("Requested resource not found") ex.value.response["Error"]["Message"].should.equal("Requested resource not found")
@requires_boto_gte("2.9")
@mock_dynamodb2 @mock_dynamodb2
def test_list_table_tags(): def test_list_table_tags():
name = "TestTable" name = "TestTable"
@ -178,7 +105,6 @@ def test_list_table_tags():
assert resp["Tags"] == [{"Key": "TestTag2", "Value": "TestValue2"}] assert resp["Tags"] == [{"Key": "TestTag2", "Value": "TestValue2"}]
@requires_boto_gte("2.9")
@mock_dynamodb2 @mock_dynamodb2
def test_list_table_tags_empty(): def test_list_table_tags_empty():
name = "TestTable" name = "TestTable"
@ -200,7 +126,6 @@ def test_list_table_tags_empty():
assert resp["Tags"] == [] assert resp["Tags"] == []
@requires_boto_gte("2.9")
@mock_dynamodb2 @mock_dynamodb2
def test_list_table_tags_paginated(): def test_list_table_tags_paginated():
name = "TestTable" name = "TestTable"
@ -229,7 +154,6 @@ def test_list_table_tags_paginated():
assert "NextToken" not in resp2.keys() assert "NextToken" not in resp2.keys()
@requires_boto_gte("2.9")
@mock_dynamodb2 @mock_dynamodb2
def test_list_not_found_table_tags(): def test_list_not_found_table_tags():
conn = boto3.client( conn = boto3.client(
@ -384,7 +308,6 @@ def test_update_item_with_empty_string_attr_no_exception():
) )
@requires_boto_gte("2.9")
@mock_dynamodb2 @mock_dynamodb2
def test_query_invalid_table(): def test_query_invalid_table():
conn = boto3.client( conn = boto3.client(
@ -403,7 +326,6 @@ def test_query_invalid_table():
assert exception.response["Error"]["Code"] == "ResourceNotFoundException" assert exception.response["Error"]["Code"] == "ResourceNotFoundException"
@requires_boto_gte("2.9")
@mock_dynamodb2 @mock_dynamodb2
def test_put_item_with_special_chars(): def test_put_item_with_special_chars():
name = "TestTable" name = "TestTable"
@ -434,7 +356,6 @@ def test_put_item_with_special_chars():
) )
@requires_boto_gte("2.9")
@mock_dynamodb2 @mock_dynamodb2
def test_put_item_with_streams(): def test_put_item_with_streams():
name = "TestTable" name = "TestTable"
@ -3513,7 +3434,6 @@ def test_update_supports_list_append_maps():
) )
@requires_boto_gte("2.9")
@mock_dynamodb2 @mock_dynamodb2
def test_update_supports_nested_update_if_nested_value_not_exists(): def test_update_supports_nested_update_if_nested_value_not_exists():
dynamodb = boto3.resource("dynamodb", region_name="us-east-1") dynamodb = boto3.resource("dynamodb", region_name="us-east-1")

View File

@ -1,94 +1,15 @@
from decimal import Decimal from decimal import Decimal
import boto
import boto3 import boto3
from boto3.dynamodb.conditions import Key from boto3.dynamodb.conditions import Key
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
from datetime import datetime from datetime import datetime
from freezegun import freeze_time
import pytest import pytest
from moto import mock_dynamodb2, mock_dynamodb2_deprecated from moto import mock_dynamodb2
from boto.exception import JSONResponseError
from tests.helpers import requires_boto_gte
from uuid import uuid4 from uuid import uuid4
try:
from boto.dynamodb2.fields import GlobalAllIndex, HashKey, RangeKey, AllIndex
from boto.dynamodb2.table import Item, Table
from boto.dynamodb2.types import STRING, NUMBER
from boto.dynamodb2.exceptions import ValidationException
from boto.dynamodb2.exceptions import ConditionalCheckFailedException
except ImportError:
pass
def create_table():
table = Table.create(
"messages",
schema=[HashKey("forum_name"), RangeKey("subject")],
throughput={"read": 10, "write": 10},
)
return table
def create_table_with_local_indexes():
table = Table.create(
"messages",
schema=[HashKey("forum_name"), RangeKey("subject")],
throughput={"read": 10, "write": 10},
indexes=[
AllIndex(
"threads_index",
parts=[
HashKey("forum_name", data_type=STRING),
RangeKey("threads", data_type=NUMBER),
],
)
],
)
return table
def iterate_results(res):
for _ in res:
pass
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
@freeze_time("2012-01-14")
def test_create_table():
table = create_table()
expected = {
"Table": {
"AttributeDefinitions": [
{"AttributeName": "forum_name", "AttributeType": "S"},
{"AttributeName": "subject", "AttributeType": "S"},
],
"ProvisionedThroughput": {
"NumberOfDecreasesToday": 0,
"WriteCapacityUnits": 10,
"ReadCapacityUnits": 10,
},
"TableSizeBytes": 0,
"TableName": "messages",
"TableStatus": "ACTIVE",
"TableArn": "arn:aws:dynamodb:us-east-1:123456789011:table/messages",
"KeySchema": [
{"KeyType": "HASH", "AttributeName": "forum_name"},
{"KeyType": "RANGE", "AttributeName": "subject"},
],
"LocalSecondaryIndexes": [],
"ItemCount": 0,
"CreationDateTime": 1326499200.0,
"GlobalSecondaryIndexes": [],
}
}
table.describe().should.equal(expected)
@mock_dynamodb2 @mock_dynamodb2
def test_create_table_boto3(): def test_create_table_boto3():
@ -134,50 +55,6 @@ def test_create_table_boto3():
actual.should.have.key("ItemCount").equal(0) actual.should.have.key("ItemCount").equal(0)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
@freeze_time("2012-01-14")
def test_create_table_with_local_index():
table = create_table_with_local_indexes()
expected = {
"Table": {
"AttributeDefinitions": [
{"AttributeName": "forum_name", "AttributeType": "S"},
{"AttributeName": "subject", "AttributeType": "S"},
{"AttributeName": "threads", "AttributeType": "N"},
],
"ProvisionedThroughput": {
"NumberOfDecreasesToday": 0,
"WriteCapacityUnits": 10,
"ReadCapacityUnits": 10,
},
"TableSizeBytes": 0,
"TableName": "messages",
"TableStatus": "ACTIVE",
"TableArn": "arn:aws:dynamodb:us-east-1:123456789011:table/messages",
"KeySchema": [
{"KeyType": "HASH", "AttributeName": "forum_name"},
{"KeyType": "RANGE", "AttributeName": "subject"},
],
"LocalSecondaryIndexes": [
{
"IndexName": "threads_index",
"KeySchema": [
{"AttributeName": "forum_name", "KeyType": "HASH"},
{"AttributeName": "threads", "KeyType": "RANGE"},
],
"Projection": {"ProjectionType": "ALL"},
}
],
"ItemCount": 0,
"CreationDateTime": 1326499200.0,
"GlobalSecondaryIndexes": [],
}
}
table.describe().should.equal(expected)
@mock_dynamodb2 @mock_dynamodb2
def test_create_table_with_local_index_boto3(): def test_create_table_with_local_index_boto3():
client = boto3.client("dynamodb", region_name="us-east-1") client = boto3.client("dynamodb", region_name="us-east-1")
@ -245,169 +122,6 @@ def test_create_table_with_local_index_boto3():
actual.should.have.key("ItemCount").equal(0) actual.should.have.key("ItemCount").equal(0)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_delete_table():
conn = boto.dynamodb2.layer1.DynamoDBConnection()
table = create_table()
conn.list_tables()["TableNames"].should.have.length_of(1)
table.delete()
conn.list_tables()["TableNames"].should.have.length_of(0)
conn.delete_table.when.called_with("messages").should.throw(JSONResponseError)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_update_table_throughput():
table = create_table()
table.throughput["read"].should.equal(10)
table.throughput["write"].should.equal(10)
table.update(throughput={"read": 5, "write": 15})
table.throughput["read"].should.equal(5)
table.throughput["write"].should.equal(15)
table.update(throughput={"read": 5, "write": 6})
table.describe()
table.throughput["read"].should.equal(5)
table.throughput["write"].should.equal(6)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_item_add_and_describe_and_update():
table = create_table()
ok = table.put_item(
data={
"forum_name": "LOLCat Forum",
"subject": "Check this out!",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
)
ok.should.equal(True)
table.get_item(
forum_name="LOLCat Forum", subject="Check this out!"
).should_not.be.none
returned_item = table.get_item(forum_name="LOLCat Forum", subject="Check this out!")
dict(returned_item).should.equal(
{
"forum_name": "LOLCat Forum",
"subject": "Check this out!",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
)
returned_item["SentBy"] = "User B"
returned_item.save(overwrite=True)
returned_item = table.get_item(forum_name="LOLCat Forum", subject="Check this out!")
dict(returned_item).should.equal(
{
"forum_name": "LOLCat Forum",
"subject": "Check this out!",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User B",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_item_partial_save():
table = create_table()
data = {
"forum_name": "LOLCat Forum",
"subject": "The LOLz",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
}
table.put_item(data=data)
returned_item = table.get_item(forum_name="LOLCat Forum", subject="The LOLz")
returned_item["SentBy"] = "User B"
returned_item.partial_save()
returned_item = table.get_item(forum_name="LOLCat Forum", subject="The LOLz")
dict(returned_item).should.equal(
{
"forum_name": "LOLCat Forum",
"subject": "The LOLz",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User B",
}
)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_item_put_without_table():
table = Table("undeclared-table")
item_data = {
"forum_name": "LOLCat Forum",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
item = Item(table, item_data)
item.save.when.called_with().should.throw(JSONResponseError)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_get_missing_item():
table = create_table()
table.get_item.when.called_with(hash_key="tester", range_key="other").should.throw(
ValidationException
)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_get_item_with_undeclared_table():
table = Table("undeclared-table")
table.get_item.when.called_with(test_hash=3241526475).should.throw(
JSONResponseError
)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_get_item_without_range_key():
table = Table.create(
"messages",
schema=[HashKey("test_hash"), RangeKey("test_range")],
throughput={"read": 10, "write": 10},
)
hash_key = "3241526475"
range_key = "1234567890987"
table.put_item(data={"test_hash": hash_key, "test_range": range_key})
table.get_item.when.called_with(test_hash=hash_key).should.throw(
ValidationException
)
@mock_dynamodb2 @mock_dynamodb2
def test_get_item_without_range_key_boto3(): def test_get_item_without_range_key_boto3():
client = boto3.resource("dynamodb", region_name="us-east-1") client = boto3.resource("dynamodb", region_name="us-east-1")
@ -435,544 +149,6 @@ def test_get_item_without_range_key_boto3():
ex.value.response["Error"]["Message"].should.equal("Validation Exception") ex.value.response["Error"]["Message"].should.equal("Validation Exception")
@requires_boto_gte("2.30.0")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_delete_item():
table = create_table()
item_data = {
"forum_name": "LOLCat Forum",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
item = Item(table, item_data)
item["subject"] = "Check this out!"
item.save()
table.count().should.equal(1)
response = item.delete()
response.should.equal(True)
table.count().should.equal(0)
# Deletes are idempotent
item.delete().should.equal(True)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_delete_item_with_undeclared_table():
table = Table("undeclared-table")
item_data = {
"forum_name": "LOLCat Forum",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
item = Item(table, item_data)
item.delete.when.called_with().should.throw(JSONResponseError)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_query():
table = create_table()
item_data = {
"forum_name": "LOLCat Forum",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
"subject": "Check this out!",
}
item = Item(table, item_data)
item.save(overwrite=True)
item["forum_name"] = "the-key"
item["subject"] = "456"
item.save(overwrite=True)
item["forum_name"] = "the-key"
item["subject"] = "123"
item.save(overwrite=True)
item["forum_name"] = "the-key"
item["subject"] = "789"
item.save(overwrite=True)
table.count().should.equal(4)
results = table.query_2(forum_name__eq="the-key", subject__gt="1", consistent=True)
expected = ["123", "456", "789"]
for index, item in enumerate(results):
item["subject"].should.equal(expected[index])
results = table.query_2(forum_name__eq="the-key", subject__gt="1", reverse=True)
for index, item in enumerate(results):
item["subject"].should.equal(expected[len(expected) - 1 - index])
results = table.query_2(forum_name__eq="the-key", subject__gt="1", consistent=True)
sum(1 for _ in results).should.equal(3)
results = table.query_2(
forum_name__eq="the-key", subject__gt="234", consistent=True
)
sum(1 for _ in results).should.equal(2)
results = table.query_2(forum_name__eq="the-key", subject__gt="9999")
sum(1 for _ in results).should.equal(0)
results = table.query_2(forum_name__eq="the-key", subject__beginswith="12")
sum(1 for _ in results).should.equal(1)
results = table.query_2(forum_name__eq="the-key", subject__beginswith="7")
sum(1 for _ in results).should.equal(1)
results = table.query_2(forum_name__eq="the-key", subject__between=["567", "890"])
sum(1 for _ in results).should.equal(1)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_query_with_undeclared_table():
table = Table("undeclared")
results = table.query(
forum_name__eq="Amazon DynamoDB", subject__beginswith="DynamoDB", limit=1
)
iterate_results.when.called_with(results).should.throw(JSONResponseError)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_scan():
table = create_table()
item_data = {
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
item_data["forum_name"] = "the-key"
item_data["subject"] = "456"
item = Item(table, item_data)
item.save()
item["forum_name"] = "the-key"
item["subject"] = "123"
item.save()
item_data = {
"Body": "http://url_to_lolcat.gif",
"SentBy": "User B",
"ReceivedTime": "12/9/2011 11:36:09 PM",
"Ids": set([1, 2, 3]),
"PK": 7,
}
item_data["forum_name"] = "the-key"
item_data["subject"] = "789"
item = Item(table, item_data)
item.save()
results = table.scan()
sum(1 for _ in results).should.equal(3)
results = table.scan(SentBy__eq="User B")
sum(1 for _ in results).should.equal(1)
results = table.scan(Body__beginswith="http")
sum(1 for _ in results).should.equal(3)
results = table.scan(Ids__null=False)
sum(1 for _ in results).should.equal(1)
results = table.scan(Ids__null=True)
sum(1 for _ in results).should.equal(2)
results = table.scan(PK__between=[8, 9])
sum(1 for _ in results).should.equal(0)
results = table.scan(PK__between=[5, 8])
sum(1 for _ in results).should.equal(1)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_scan_with_undeclared_table():
conn = boto.dynamodb2.layer1.DynamoDBConnection()
conn.scan.when.called_with(
table_name="undeclared-table",
scan_filter={
"SentBy": {
"AttributeValueList": [{"S": "User B"}],
"ComparisonOperator": "EQ",
}
},
).should.throw(JSONResponseError)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_write_batch():
table = create_table()
with table.batch_write() as batch:
batch.put_item(
data={
"forum_name": "the-key",
"subject": "123",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
)
batch.put_item(
data={
"forum_name": "the-key",
"subject": "789",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User B",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
)
table.count().should.equal(2)
with table.batch_write() as batch:
batch.delete_item(forum_name="the-key", subject="789")
table.count().should.equal(1)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_batch_read():
table = create_table()
item_data = {
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
item_data["forum_name"] = "the-key"
item_data["subject"] = "456"
item = Item(table, item_data)
item.save()
item = Item(table, item_data)
item_data["forum_name"] = "the-key"
item_data["subject"] = "123"
item.save()
item_data = {
"Body": "http://url_to_lolcat.gif",
"SentBy": "User B",
"ReceivedTime": "12/9/2011 11:36:03 PM",
"Ids": set([1, 2, 3]),
"PK": 7,
}
item = Item(table, item_data)
item_data["forum_name"] = "another-key"
item_data["subject"] = "789"
item.save()
results = table.batch_get(
keys=[
{"forum_name": "the-key", "subject": "123"},
{"forum_name": "another-key", "subject": "789"},
]
)
# Iterate through so that batch_item gets called
count = len([x for x in results])
count.should.equal(2)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_get_key_fields():
table = create_table()
kf = table.get_key_fields()
kf.should.equal(["forum_name", "subject"])
@mock_dynamodb2_deprecated
# Has boto3 equivalent
def test_create_with_global_indexes():
conn = boto.dynamodb2.layer1.DynamoDBConnection()
Table.create(
"messages",
schema=[HashKey("subject"), RangeKey("version")],
global_indexes=[
GlobalAllIndex(
"topic-created_at-index",
parts=[HashKey("topic"), RangeKey("created_at", data_type="N")],
throughput={"read": 6, "write": 1},
)
],
)
table_description = conn.describe_table("messages")
table_description["Table"]["GlobalSecondaryIndexes"].should.equal(
[
{
"IndexName": "topic-created_at-index",
"KeySchema": [
{"AttributeName": "topic", "KeyType": "HASH"},
{"AttributeName": "created_at", "KeyType": "RANGE"},
],
"Projection": {"ProjectionType": "ALL"},
"ProvisionedThroughput": {
"ReadCapacityUnits": 6,
"WriteCapacityUnits": 1,
},
"IndexStatus": "ACTIVE",
}
]
)
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_query_with_global_indexes():
table = Table.create(
"messages",
schema=[HashKey("subject"), RangeKey("version")],
global_indexes=[
GlobalAllIndex(
"topic-created_at-index",
parts=[HashKey("topic"), RangeKey("created_at", data_type="N")],
throughput={"read": 6, "write": 1},
),
GlobalAllIndex(
"status-created_at-index",
parts=[HashKey("status"), RangeKey("created_at", data_type="N")],
throughput={"read": 2, "write": 1},
),
],
)
item_data = {
"subject": "Check this out!",
"version": "1",
"created_at": 0,
"status": "inactive",
}
item = Item(table, item_data)
item.save(overwrite=True)
item["version"] = "2"
item.save(overwrite=True)
results = table.query(status__eq="active")
list(results).should.have.length_of(0)
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_query_with_local_indexes():
table = create_table_with_local_indexes()
item_data = {
"forum_name": "Cool Forum",
"subject": "Check this out!",
"version": "1",
"threads": 1,
"status": "inactive",
}
item = Item(table, item_data)
item.save(overwrite=True)
item["version"] = "2"
item.save(overwrite=True)
results = table.query(
forum_name__eq="Cool Forum", index="threads_index", threads__eq=1
)
list(results).should.have.length_of(1)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_query_filter_eq():
table = create_table_with_local_indexes()
item_data = [
{
"forum_name": "Cool Forum",
"subject": "Check this out!",
"version": "1",
"threads": 1,
},
{
"forum_name": "Cool Forum",
"subject": "Read this now!",
"version": "1",
"threads": 5,
},
{
"forum_name": "Cool Forum",
"subject": "Please read this... please",
"version": "1",
"threads": 0,
},
]
for data in item_data:
item = Item(table, data)
item.save(overwrite=True)
results = table.query_2(
forum_name__eq="Cool Forum", index="threads_index", threads__eq=5
)
list(results).should.have.length_of(1)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_query_filter_lt():
table = create_table_with_local_indexes()
item_data = [
{
"forum_name": "Cool Forum",
"subject": "Check this out!",
"version": "1",
"threads": 1,
},
{
"forum_name": "Cool Forum",
"subject": "Read this now!",
"version": "1",
"threads": 5,
},
{
"forum_name": "Cool Forum",
"subject": "Please read this... please",
"version": "1",
"threads": 0,
},
]
for data in item_data:
item = Item(table, data)
item.save(overwrite=True)
results = table.query(
forum_name__eq="Cool Forum", index="threads_index", threads__lt=5
)
results = list(results)
results.should.have.length_of(2)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_query_filter_gt():
table = create_table_with_local_indexes()
item_data = [
{
"forum_name": "Cool Forum",
"subject": "Check this out!",
"version": "1",
"threads": 1,
},
{
"forum_name": "Cool Forum",
"subject": "Read this now!",
"version": "1",
"threads": 5,
},
{
"forum_name": "Cool Forum",
"subject": "Please read this... please",
"version": "1",
"threads": 0,
},
]
for data in item_data:
item = Item(table, data)
item.save(overwrite=True)
results = table.query(
forum_name__eq="Cool Forum", index="threads_index", threads__gt=1
)
list(results).should.have.length_of(1)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_query_filter_lte():
table = create_table_with_local_indexes()
item_data = [
{
"forum_name": "Cool Forum",
"subject": "Check this out!",
"version": "1",
"threads": 1,
},
{
"forum_name": "Cool Forum",
"subject": "Read this now!",
"version": "1",
"threads": 5,
},
{
"forum_name": "Cool Forum",
"subject": "Please read this... please",
"version": "1",
"threads": 0,
},
]
for data in item_data:
item = Item(table, data)
item.save(overwrite=True)
results = table.query(
forum_name__eq="Cool Forum", index="threads_index", threads__lte=5
)
list(results).should.have.length_of(3)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_query_filter_gte():
table = create_table_with_local_indexes()
item_data = [
{
"forum_name": "Cool Forum",
"subject": "Check this out!",
"version": "1",
"threads": 1,
},
{
"forum_name": "Cool Forum",
"subject": "Read this now!",
"version": "1",
"threads": 5,
},
{
"forum_name": "Cool Forum",
"subject": "Please read this... please",
"version": "1",
"threads": 0,
},
]
for data in item_data:
item = Item(table, data)
item.save(overwrite=True)
results = table.query(
forum_name__eq="Cool Forum", index="threads_index", threads__gte=1
)
list(results).should.have.length_of(2)
@mock_dynamodb2 @mock_dynamodb2
def test_query_filter_boto3(): def test_query_filter_boto3():
table_schema = { table_schema = {
@ -1016,135 +192,6 @@ def test_query_filter_boto3():
res["Items"].should.equal([{"pk": "pk", "sk": "sk-1"}, {"pk": "pk", "sk": "sk-2"}]) res["Items"].should.equal([{"pk": "pk", "sk": "sk-1"}, {"pk": "pk", "sk": "sk-2"}])
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_query_non_hash_range_key():
table = create_table_with_local_indexes()
item_data = [
{
"forum_name": "Cool Forum",
"subject": "Check this out!",
"version": "1",
"threads": 1,
},
{
"forum_name": "Cool Forum",
"subject": "Read this now!",
"version": "3",
"threads": 5,
},
{
"forum_name": "Cool Forum",
"subject": "Please read this... please",
"version": "2",
"threads": 0,
},
]
for data in item_data:
item = Item(table, data)
item.save(overwrite=True)
results = table.query(forum_name__eq="Cool Forum", version__gt="2")
results = list(results)
results.should.have.length_of(1)
results = table.query(forum_name__eq="Cool Forum", version__lt="3")
results = list(results)
results.should.have.length_of(2)
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_reverse_query():
boto.dynamodb2.layer1.DynamoDBConnection()
table = Table.create(
"messages", schema=[HashKey("subject"), RangeKey("created_at", data_type="N")]
)
for i in range(10):
table.put_item({"subject": "Hi", "created_at": i})
results = table.query_2(subject__eq="Hi", created_at__lt=6, limit=4, reverse=True)
expected = [Decimal(5), Decimal(4), Decimal(3), Decimal(2)]
[r["created_at"] for r in results].should.equal(expected)
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_lookup():
table = Table.create(
"messages",
schema=[
HashKey("test_hash", data_type=NUMBER),
RangeKey("test_range", data_type=NUMBER),
],
throughput={"read": 10, "write": 10},
)
hash_key = 3241526475
range_key = 1234567890987
data = {"test_hash": hash_key, "test_range": range_key}
table.put_item(data=data)
message = table.lookup(hash_key, range_key)
message.get("test_hash").should.equal(Decimal(hash_key))
message.get("test_range").should.equal(Decimal(range_key))
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_failed_overwrite():
table = Table.create(
"messages",
schema=[HashKey("id"), RangeKey("range")],
throughput={"read": 7, "write": 3},
)
data1 = {"id": "123", "range": "abc", "data": "678"}
table.put_item(data=data1)
data2 = {"id": "123", "range": "abc", "data": "345"}
table.put_item(data=data2, overwrite=True)
data3 = {"id": "123", "range": "abc", "data": "812"}
table.put_item.when.called_with(data=data3).should.throw(
ConditionalCheckFailedException
)
returned_item = table.lookup("123", "abc")
dict(returned_item).should.equal(data2)
data4 = {"id": "123", "range": "ghi", "data": 812}
table.put_item(data=data4)
returned_item = table.lookup("123", "ghi")
dict(returned_item).should.equal(data4)
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_conflicting_writes():
table = Table.create("messages", schema=[HashKey("id"), RangeKey("range")])
item_data = {"id": "123", "range": "abc", "data": "678"}
item1 = Item(table, item_data)
item2 = Item(table, item_data)
item1.save()
item1["data"] = "579"
item2["data"] = "912"
item1.save()
item2.save.when.called_with().should.throw(ConditionalCheckFailedException)
"""
boto3
"""
@mock_dynamodb2 @mock_dynamodb2
def test_boto3_create_table_with_gsi(): def test_boto3_create_table_with_gsi():
dynamodb = boto3.client("dynamodb", region_name="us-east-1") dynamodb = boto3.client("dynamodb", region_name="us-east-1")

View File

@ -1,66 +1,12 @@
import boto
import boto3 import boto3
from boto3.dynamodb.conditions import Key from boto3.dynamodb.conditions import Key
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
import pytest import pytest
from datetime import datetime from datetime import datetime
from freezegun import freeze_time
from boto.exception import JSONResponseError
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
from moto import mock_dynamodb2, mock_dynamodb2_deprecated from moto import mock_dynamodb2
from tests.helpers import requires_boto_gte
import botocore import botocore
try:
from boto.dynamodb2.types import NUMBER
from boto.dynamodb2.fields import HashKey
from boto.dynamodb2.table import Table
from boto.dynamodb2.table import Item
from boto.dynamodb2.exceptions import ConditionalCheckFailedException, ItemNotFound
except ImportError:
pass
def create_table():
table = Table.create(
"messages", schema=[HashKey("forum_name")], throughput={"read": 10, "write": 10}
)
return table
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
@freeze_time("2012-01-14")
def test_create_table():
create_table()
expected = {
"Table": {
"AttributeDefinitions": [
{"AttributeName": "forum_name", "AttributeType": "S"}
],
"ProvisionedThroughput": {
"NumberOfDecreasesToday": 0,
"WriteCapacityUnits": 10,
"ReadCapacityUnits": 10,
},
"TableSizeBytes": 0,
"TableName": "messages",
"TableStatus": "ACTIVE",
"TableArn": "arn:aws:dynamodb:us-east-1:123456789011:table/messages",
"KeySchema": [{"KeyType": "HASH", "AttributeName": "forum_name"}],
"ItemCount": 0,
"CreationDateTime": 1326499200.0,
"GlobalSecondaryIndexes": [],
"LocalSecondaryIndexes": [],
}
}
conn = boto.dynamodb2.connect_to_region(
"us-east-1", aws_access_key_id="ak", aws_secret_access_key="sk"
)
conn.describe_table("messages").should.equal(expected)
@mock_dynamodb2 @mock_dynamodb2
def test_create_table_boto3(): def test_create_table_boto3():
@ -125,20 +71,6 @@ def test_create_table_boto3():
actual.should.have.key("ItemCount").equal(0) actual.should.have.key("ItemCount").equal(0)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_delete_table():
create_table()
conn = boto.dynamodb2.layer1.DynamoDBConnection()
conn.list_tables()["TableNames"].should.have.length_of(1)
conn.delete_table("messages")
conn.list_tables()["TableNames"].should.have.length_of(0)
conn.delete_table.when.called_with("messages").should.throw(JSONResponseError)
@mock_dynamodb2 @mock_dynamodb2
def test_delete_table_boto3(): def test_delete_table_boto3():
conn = boto3.client("dynamodb", region_name="us-west-2") conn = boto3.client("dynamodb", region_name="us-west-2")
@ -161,20 +93,6 @@ def test_delete_table_boto3():
ex.value.response["Error"]["Message"].should.equal("Requested resource not found") ex.value.response["Error"]["Message"].should.equal("Requested resource not found")
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_update_table_throughput():
table = create_table()
table.throughput["read"].should.equal(10)
table.throughput["write"].should.equal(10)
table.update(throughput={"read": 5, "write": 6})
table.throughput["read"].should.equal(5)
table.throughput["write"].should.equal(6)
@mock_dynamodb2 @mock_dynamodb2
def test_update_table_throughput_boto3(): def test_update_table_throughput_boto3():
conn = boto3.resource("dynamodb", region_name="us-west-2") conn = boto3.resource("dynamodb", region_name="us-west-2")
@ -195,43 +113,6 @@ def test_update_table_throughput_boto3():
table.provisioned_throughput["WriteCapacityUnits"].should.equal(6) table.provisioned_throughput["WriteCapacityUnits"].should.equal(6)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_item_add_and_describe_and_update():
table = create_table()
data = {
"forum_name": "LOLCat Forum",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
}
table.put_item(data=data)
returned_item = table.get_item(forum_name="LOLCat Forum")
returned_item.should_not.be.none
dict(returned_item).should.equal(
{
"forum_name": "LOLCat Forum",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
}
)
returned_item["SentBy"] = "User B"
returned_item.save(overwrite=True)
returned_item = table.get_item(forum_name="LOLCat Forum")
dict(returned_item).should.equal(
{
"forum_name": "LOLCat Forum",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User B",
}
)
@mock_dynamodb2 @mock_dynamodb2
def test_item_add_and_describe_and_update_boto3(): def test_item_add_and_describe_and_update_boto3():
conn = boto3.resource("dynamodb", region_name="us-west-2") conn = boto3.resource("dynamodb", region_name="us-west-2")
@ -268,50 +149,6 @@ def test_item_add_and_describe_and_update_boto3():
) )
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_item_partial_save():
table = create_table()
data = {
"forum_name": "LOLCat Forum",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
}
table.put_item(data=data)
returned_item = table.get_item(forum_name="LOLCat Forum")
returned_item["SentBy"] = "User B"
returned_item.partial_save()
returned_item = table.get_item(forum_name="LOLCat Forum")
dict(returned_item).should.equal(
{
"forum_name": "LOLCat Forum",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User B",
}
)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_item_put_without_table():
conn = boto.dynamodb2.layer1.DynamoDBConnection()
conn.put_item.when.called_with(
table_name="undeclared-table",
item={
"forum_name": "LOLCat Forum",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
},
).should.throw(JSONResponseError)
@mock_dynamodb2 @mock_dynamodb2
def test_item_put_without_table_boto3(): def test_item_put_without_table_boto3():
conn = boto3.client("dynamodb", region_name="us-west-2") conn = boto3.client("dynamodb", region_name="us-west-2")
@ -331,17 +168,6 @@ def test_item_put_without_table_boto3():
ex.value.response["Error"]["Message"].should.equal("Requested resource not found") ex.value.response["Error"]["Message"].should.equal("Requested resource not found")
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_get_item_with_undeclared_table():
conn = boto.dynamodb2.layer1.DynamoDBConnection()
conn.get_item.when.called_with(
table_name="undeclared-table", key={"forum_name": {"S": "LOLCat Forum"}}
).should.throw(JSONResponseError)
@mock_dynamodb2 @mock_dynamodb2
def test_get_item_with_undeclared_table_boto3(): def test_get_item_with_undeclared_table_boto3():
conn = boto3.client("dynamodb", region_name="us-west-2") conn = boto3.client("dynamodb", region_name="us-west-2")
@ -354,32 +180,6 @@ def test_get_item_with_undeclared_table_boto3():
ex.value.response["Error"]["Message"].should.equal("Requested resource not found") ex.value.response["Error"]["Message"].should.equal("Requested resource not found")
@requires_boto_gte("2.30.0")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_delete_item():
table = create_table()
item_data = {
"forum_name": "LOLCat Forum",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
item = Item(table, item_data)
item.save()
table.count().should.equal(1)
response = item.delete()
response.should.equal(True)
table.count().should.equal(0)
# Deletes are idempotent and 'False' here would imply an error condition
item.delete().should.equal(True)
@mock_dynamodb2 @mock_dynamodb2
def test_delete_item_boto3(): def test_delete_item_boto3():
conn = boto3.resource("dynamodb", region_name="us-west-2") conn = boto3.resource("dynamodb", region_name="us-west-2")
@ -407,17 +207,6 @@ def test_delete_item_boto3():
table.delete_item(Key={"id": "LOLCat Forum"}) table.delete_item(Key={"id": "LOLCat Forum"})
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_delete_item_with_undeclared_table():
conn = boto.dynamodb2.layer1.DynamoDBConnection()
conn.delete_item.when.called_with(
table_name="undeclared-table", key={"forum_name": {"S": "LOLCat Forum"}}
).should.throw(JSONResponseError)
@mock_dynamodb2 @mock_dynamodb2
def test_delete_item_with_undeclared_table_boto3(): def test_delete_item_with_undeclared_table_boto3():
conn = boto3.client("dynamodb", region_name="us-west-2") conn = boto3.client("dynamodb", region_name="us-west-2")
@ -434,113 +223,6 @@ def test_delete_item_with_undeclared_table_boto3():
) )
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_query():
table = create_table()
item_data = {
"forum_name": "the-key",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
item = Item(table, item_data)
item.save(overwrite=True)
table.count().should.equal(1)
table = Table("messages")
results = table.query(forum_name__eq="the-key")
sum(1 for _ in results).should.equal(1)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_query_with_undeclared_table():
conn = boto.dynamodb2.layer1.DynamoDBConnection()
conn.query.when.called_with(
table_name="undeclared-table",
key_conditions={
"forum_name": {
"ComparisonOperator": "EQ",
"AttributeValueList": [{"S": "the-key"}],
}
},
).should.throw(JSONResponseError)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_scan():
table = create_table()
item_data = {
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
item_data["forum_name"] = "the-key"
item = Item(table, item_data)
item.save()
item["forum_name"] = "the-key2"
item.save(overwrite=True)
item_data = {
"Body": "http://url_to_lolcat.gif",
"SentBy": "User B",
"ReceivedTime": "12/9/2011 11:36:03 PM",
"Ids": set([1, 2, 3]),
"PK": 7,
}
item_data["forum_name"] = "the-key3"
item = Item(table, item_data)
item.save()
results = table.scan()
sum(1 for _ in results).should.equal(3)
results = table.scan(SentBy__eq="User B")
sum(1 for _ in results).should.equal(1)
results = table.scan(Body__beginswith="http")
sum(1 for _ in results).should.equal(3)
results = table.scan(Ids__null=False)
sum(1 for _ in results).should.equal(1)
results = table.scan(Ids__null=True)
sum(1 for _ in results).should.equal(2)
results = table.scan(PK__between=[8, 9])
sum(1 for _ in results).should.equal(0)
results = table.scan(PK__between=[5, 8])
sum(1 for _ in results).should.equal(1)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_scan_with_undeclared_table():
conn = boto.dynamodb2.layer1.DynamoDBConnection()
conn.scan.when.called_with(
table_name="undeclared-table",
scan_filter={
"SentBy": {
"AttributeValueList": [{"S": "User B"}],
"ComparisonOperator": "EQ",
}
},
).should.throw(JSONResponseError)
@mock_dynamodb2 @mock_dynamodb2
def test_scan_with_undeclared_table_boto3(): def test_scan_with_undeclared_table_boto3():
conn = boto3.client("dynamodb", region_name="us-west-2") conn = boto3.client("dynamodb", region_name="us-west-2")
@ -553,87 +235,6 @@ def test_scan_with_undeclared_table_boto3():
ex.value.response["Error"]["Message"].should.equal("Requested resource not found") ex.value.response["Error"]["Message"].should.equal("Requested resource not found")
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_write_batch():
table = create_table()
with table.batch_write() as batch:
batch.put_item(
data={
"forum_name": "the-key",
"subject": "123",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
)
batch.put_item(
data={
"forum_name": "the-key2",
"subject": "789",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User B",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
)
table.count().should.equal(2)
with table.batch_write() as batch:
batch.delete_item(forum_name="the-key", subject="789")
table.count().should.equal(1)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_batch_read():
table = create_table()
item_data = {
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
item_data["forum_name"] = "the-key1"
item = Item(table, item_data)
item.save()
item = Item(table, item_data)
item_data["forum_name"] = "the-key2"
item.save(overwrite=True)
item_data = {
"Body": "http://url_to_lolcat.gif",
"SentBy": "User B",
"ReceivedTime": "12/9/2011 11:36:03 PM",
"Ids": set([1, 2, 3]),
"PK": 7,
}
item = Item(table, item_data)
item_data["forum_name"] = "another-key"
item.save(overwrite=True)
results = table.batch_get(
keys=[{"forum_name": "the-key1"}, {"forum_name": "another-key"}]
)
# Iterate through so that batch_item gets called
count = len([x for x in results])
count.should.equal(2)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_get_key_fields():
table = create_table()
kf = table.get_key_fields()
kf[0].should.equal("forum_name")
@mock_dynamodb2 @mock_dynamodb2
def test_get_key_schema(): def test_get_key_schema():
conn = boto3.resource("dynamodb", region_name="us-west-2") conn = boto3.resource("dynamodb", region_name="us-west-2")
@ -647,64 +248,6 @@ def test_get_key_schema():
table.key_schema.should.equal([{"AttributeName": "id", "KeyType": "HASH"}]) table.key_schema.should.equal([{"AttributeName": "id", "KeyType": "HASH"}])
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_get_missing_item():
table = create_table()
table.get_item.when.called_with(forum_name="missing").should.throw(ItemNotFound)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_get_special_item():
table = Table.create(
"messages",
schema=[HashKey("date-joined", data_type=NUMBER)],
throughput={"read": 10, "write": 10},
)
data = {"date-joined": 127549192, "SentBy": "User A"}
table.put_item(data=data)
returned_item = table.get_item(**{"date-joined": 127549192})
dict(returned_item).should.equal(data)
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_update_item_remove():
conn = boto.dynamodb2.connect_to_region("us-east-1")
table = Table.create("messages", schema=[HashKey("username")])
data = {"username": "steve", "SentBy": "User A", "SentTo": "User B"}
table.put_item(data=data)
key_map = {"username": {"S": "steve"}}
# Then remove the SentBy field
conn.update_item("messages", key_map, update_expression="REMOVE SentBy, SentTo")
returned_item = table.get_item(username="steve")
dict(returned_item).should.equal({"username": "steve"})
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_update_item_nested_remove():
conn = boto.dynamodb2.connect_to_region("us-east-1")
table = Table.create("messages", schema=[HashKey("username")])
data = {"username": "steve", "Meta": {"FullName": "Steve Urkel"}}
table.put_item(data=data)
key_map = {"username": {"S": "steve"}}
# Then remove the Meta.FullName field
conn.update_item("messages", key_map, update_expression="REMOVE Meta.FullName")
returned_item = table.get_item(username="steve")
dict(returned_item).should.equal({"username": "steve", "Meta": {}})
@mock_dynamodb2 @mock_dynamodb2
def test_update_item_double_nested_remove(): def test_update_item_double_nested_remove():
conn = boto3.client("dynamodb", region_name="us-east-1") conn = boto3.client("dynamodb", region_name="us-east-1")
@ -740,27 +283,6 @@ def test_update_item_double_nested_remove():
dict(returned_item["Item"]).should.equal(expected_item) dict(returned_item["Item"]).should.equal(expected_item)
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_update_item_set():
conn = boto.dynamodb2.connect_to_region("us-east-1")
table = Table.create("messages", schema=[HashKey("username")])
data = {"username": "steve", "SentBy": "User A"}
table.put_item(data=data)
key_map = {"username": {"S": "steve"}}
conn.update_item(
"messages",
key_map,
update_expression="SET foo=:bar, blah=:baz REMOVE SentBy",
expression_attribute_values={":bar": {"S": "bar"}, ":baz": {"S": "baz"}},
)
returned_item = table.get_item(username="steve")
dict(returned_item).should.equal({"username": "steve", "foo": "bar", "blah": "baz"})
@mock_dynamodb2 @mock_dynamodb2
def test_update_item_set_boto3(): def test_update_item_set_boto3():
conn = boto3.resource("dynamodb", region_name="us-east-1") conn = boto3.resource("dynamodb", region_name="us-east-1")
@ -785,56 +307,6 @@ def test_update_item_set_boto3():
dict(returned_item).should.equal({"username": "steve", "foo": "bar", "blah": "baz"}) dict(returned_item).should.equal({"username": "steve", "foo": "bar", "blah": "baz"})
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_failed_overwrite():
table = Table.create(
"messages", schema=[HashKey("id")], throughput={"read": 7, "write": 3}
)
data1 = {"id": "123", "data": "678"}
table.put_item(data=data1)
data2 = {"id": "123", "data": "345"}
table.put_item(data=data2, overwrite=True)
data3 = {"id": "123", "data": "812"}
table.put_item.when.called_with(data=data3).should.throw(
ConditionalCheckFailedException
)
returned_item = table.lookup("123")
dict(returned_item).should.equal(data2)
data4 = {"id": "124", "data": 812}
table.put_item(data=data4)
returned_item = table.lookup("124")
dict(returned_item).should.equal(data4)
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_conflicting_writes():
table = Table.create("messages", schema=[HashKey("id")])
item_data = {"id": "123", "data": "678"}
item1 = Item(table, item_data)
item2 = Item(table, item_data)
item1.save()
item1["data"] = "579"
item2["data"] = "912"
item1.save()
item2.save.when.called_with().should.throw(ConditionalCheckFailedException)
"""
boto3
"""
@mock_dynamodb2 @mock_dynamodb2
def test_boto3_create_table(): def test_boto3_create_table():
dynamodb = boto3.resource("dynamodb", region_name="us-east-1") dynamodb = boto3.resource("dynamodb", region_name="us-east-1")

View File

@ -1,96 +1,17 @@
import boto
import boto.ec2
import boto3 import boto3
from boto.exception import EC2ResponseError
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
import pytest import pytest
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
import random import random
from moto import mock_ec2_deprecated, mock_ec2 from moto import mock_ec2
from moto.ec2.models import AMIS, OWNER_ID from moto.ec2.models import AMIS, OWNER_ID
from moto.core import ACCOUNT_ID from moto.core import ACCOUNT_ID
from tests import EXAMPLE_AMI_ID, EXAMPLE_AMI_PARAVIRTUAL from tests import EXAMPLE_AMI_ID, EXAMPLE_AMI_PARAVIRTUAL
from tests.helpers import requires_boto_gte
from uuid import uuid4 from uuid import uuid4
# Has boto3 equivalent
@mock_ec2_deprecated
def test_ami_create_and_delete():
conn = boto.connect_ec2("the_key", "the_secret")
initial_ami_count = len(AMIS)
conn.get_all_volumes().should.have.length_of(0)
conn.get_all_snapshots().should.have.length_of(initial_ami_count)
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
with pytest.raises(EC2ResponseError) as ex:
conn.create_image(instance.id, "test-ami", "this is a test ami", dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the CreateImage operation: Request would have succeeded, but DryRun flag is set"
)
image_id = conn.create_image(instance.id, "test-ami", "this is a test ami")
all_images = conn.get_all_images()
set([i.id for i in all_images]).should.contain(image_id)
retrieved_image = [i for i in all_images if i.id == image_id][0]
retrieved_image.id.should.equal(image_id)
retrieved_image.virtualization_type.should.equal(instance.virtualization_type)
retrieved_image.architecture.should.equal(instance.architecture)
retrieved_image.kernel_id.should.equal(instance.kernel)
retrieved_image.platform.should.equal(instance.platform)
retrieved_image.creationDate.should_not.be.none
instance.terminate()
# Ensure we're no longer creating a volume
volumes = conn.get_all_volumes()
volumes.should.have.length_of(0)
# Validate auto-created snapshot
snapshots = conn.get_all_snapshots()
snapshots.should.have.length_of(initial_ami_count + 1)
retrieved_image_snapshot_id = (
retrieved_image.block_device_mapping.current_value.snapshot_id
)
[s.id for s in snapshots].should.contain(retrieved_image_snapshot_id)
snapshot = [s for s in snapshots if s.id == retrieved_image_snapshot_id][0]
snapshot.description.should.match("Created by CreateImage")
# root device should be in AMI's block device mappings
root_mapping = retrieved_image.block_device_mapping.get(
retrieved_image.root_device_name
)
root_mapping.should_not.be.none
# Deregister
with pytest.raises(EC2ResponseError) as ex:
success = conn.deregister_image(image_id, dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the DeregisterImage operation: Request would have succeeded, but DryRun flag is set"
)
success = conn.deregister_image(image_id)
success.should.be.true
with pytest.raises(EC2ResponseError) as cm:
conn.deregister_image(image_id)
cm.value.code.should.equal("InvalidAMIID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_snapshots_for_initial_amis(): def test_snapshots_for_initial_amis():
ec2 = boto3.client("ec2", region_name="us-east-1") ec2 = boto3.client("ec2", region_name="us-east-1")
@ -199,89 +120,6 @@ def test_ami_create_and_delete_boto3():
ex.value.response["ResponseMetadata"]["RequestId"].should_not.be.none ex.value.response["ResponseMetadata"]["RequestId"].should_not.be.none
# Has boto3 equivalent
@requires_boto_gte("2.14.0")
@mock_ec2_deprecated
def test_ami_copy():
conn = boto.ec2.connect_to_region("us-west-1")
initial_ami_count = len(AMIS)
conn.get_all_volumes().should.have.length_of(0)
conn.get_all_snapshots().should.have.length_of(initial_ami_count)
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
source_image_id = conn.create_image(instance.id, "test-ami", "this is a test ami")
instance.terminate()
source_image = conn.get_all_images(image_ids=[source_image_id])[0]
# Boto returns a 'CopyImage' object with an image_id attribute here. Use
# the image_id to fetch the full info.
with pytest.raises(EC2ResponseError) as ex:
copy_image_ref = conn.copy_image(
source_image.region.name,
source_image.id,
"test-copy-ami",
"this is a test copy ami",
dry_run=True,
)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the CopyImage operation: Request would have succeeded, but DryRun flag is set"
)
copy_image_ref = conn.copy_image(
source_image.region.name,
source_image.id,
"test-copy-ami",
"this is a test copy ami",
)
copy_image_id = copy_image_ref.image_id
copy_image = conn.get_all_images(image_ids=[copy_image_id])[0]
copy_image.id.should.equal(copy_image_id)
copy_image.virtualization_type.should.equal(source_image.virtualization_type)
copy_image.architecture.should.equal(source_image.architecture)
copy_image.kernel_id.should.equal(source_image.kernel_id)
copy_image.platform.should.equal(source_image.platform)
# Ensure we're no longer creating a volume
conn.get_all_volumes().should.have.length_of(0)
# Validate auto-created snapshot
conn.get_all_snapshots().should.have.length_of(initial_ami_count + 2)
copy_image.block_device_mapping.current_value.snapshot_id.should_not.equal(
source_image.block_device_mapping.current_value.snapshot_id
)
# Copy from non-existent source ID.
with pytest.raises(EC2ResponseError) as cm:
conn.copy_image(
source_image.region.name,
"ami-abcd1234",
"test-copy-ami",
"this is a test copy ami",
)
cm.value.code.should.equal("InvalidAMIID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
# Copy from non-existent source region.
with pytest.raises(EC2ResponseError) as cm:
invalid_region = (
"us-east-1" if (source_image.region.name != "us-east-1") else "us-west-1"
)
conn.copy_image(
invalid_region, source_image.id, "test-copy-ami", "this is a test copy ami"
)
cm.value.code.should.equal("InvalidAMIID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_ami_copy_boto3_dryrun(): def test_ami_copy_boto3_dryrun():
ec2 = boto3.client("ec2", region_name="us-west-1") ec2 = boto3.client("ec2", region_name="us-west-1")
@ -430,35 +268,6 @@ def test_copy_image_changes_owner_id():
describe_resp[0]["ImageId"].should.equal(copy_resp["ImageId"]) describe_resp[0]["ImageId"].should.equal(copy_resp["ImageId"])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_ami_tagging():
conn = boto.connect_vpc("the_key", "the_secret")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
conn.create_image(instance.id, "test-ami", "this is a test ami")
image = conn.get_all_images()[0]
with pytest.raises(EC2ResponseError) as ex:
image.add_tag("a key", "some value", dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the CreateTags operation: Request would have succeeded, but DryRun flag is set"
)
image.add_tag("a key", "some value")
tag = conn.get_all_tags()[0]
tag.name.should.equal("a key")
tag.value.should.equal("some value")
# Refresh the DHCP options
image = conn.get_all_images()[0]
image.tags.should.have.length_of(1)
image.tags["a key"].should.equal("some value")
@mock_ec2 @mock_ec2
def test_ami_tagging_boto3(): def test_ami_tagging_boto3():
ec2 = boto3.client("ec2", region_name="us-east-1") ec2 = boto3.client("ec2", region_name="us-east-1")
@ -488,19 +297,6 @@ def test_ami_tagging_boto3():
image["Tags"].should.equal([{"Value": "some value", "Key": "a key"}]) image["Tags"].should.equal([{"Value": "some value", "Key": "a key"}])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_ami_create_from_missing_instance():
conn = boto.connect_ec2("the_key", "the_secret")
args = ["i-abcdefg", "test-ami", "this is a test ami"]
with pytest.raises(EC2ResponseError) as cm:
conn.create_image(*args)
cm.value.code.should.equal("InvalidInstanceID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_ami_create_from_missing_instance_boto3(): def test_ami_create_from_missing_instance_boto3():
ec2 = boto3.client("ec2", region_name="us-east-1") ec2 = boto3.client("ec2", region_name="us-east-1")
@ -514,19 +310,6 @@ def test_ami_create_from_missing_instance_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidInstanceID.NotFound") ex.value.response["Error"]["Code"].should.equal("InvalidInstanceID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_ami_pulls_attributes_from_instance():
conn = boto.connect_ec2("the_key", "the_secret")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
instance.modify_attribute("kernel", "test-kernel")
image_id = conn.create_image(instance.id, "test-ami", "this is a test ami")
image = conn.get_image(image_id)
image.kernel_id.should.equal("test-kernel")
@mock_ec2 @mock_ec2
def test_ami_pulls_attributes_from_instance_boto3(): def test_ami_pulls_attributes_from_instance_boto3():
ec2 = boto3.client("ec2", region_name="us-east-1") ec2 = boto3.client("ec2", region_name="us-east-1")
@ -543,20 +326,6 @@ def test_ami_pulls_attributes_from_instance_boto3():
image.kernel_id.should.equal("test-kernel") image.kernel_id.should.equal("test-kernel")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_ami_uses_account_id_if_valid_access_key_is_supplied():
access_key = "AKIAXXXXXXXXXXXXXXXX"
conn = boto.connect_ec2(access_key, "the_secret")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
instance.modify_attribute("kernel", "test-kernel")
image_id = conn.create_image(instance.id, "test-ami", "this is a test ami")
images = conn.get_all_images(owners=["self"])
[(ami.id, ami.owner_id) for ami in images].should.equal([(image_id, ACCOUNT_ID)])
@mock_ec2 @mock_ec2
def test_ami_uses_account_id_if_valid_access_key_is_supplied_boto3(): def test_ami_uses_account_id_if_valid_access_key_is_supplied_boto3():
# The boto-equivalent required an access_key to be passed in, but Moto will always mock this in boto3 # The boto-equivalent required an access_key to be passed in, but Moto will always mock this in boto3
@ -575,68 +344,6 @@ def test_ami_uses_account_id_if_valid_access_key_is_supplied_boto3():
) )
# Has boto3 equivalent
@mock_ec2_deprecated
def test_ami_filters():
conn = boto.connect_ec2("the_key", "the_secret")
reservationA = conn.run_instances(EXAMPLE_AMI_ID)
instanceA = reservationA.instances[0]
instanceA.modify_attribute("architecture", "i386")
instanceA.modify_attribute("kernel", "k-1234abcd")
instanceA.modify_attribute("platform", "windows")
instanceA.modify_attribute("virtualization_type", "hvm")
imageA_id = conn.create_image(instanceA.id, "test-ami-A", "this is a test ami")
imageA = conn.get_image(imageA_id)
reservationB = conn.run_instances(EXAMPLE_AMI_ID)
instanceB = reservationB.instances[0]
instanceB.modify_attribute("architecture", "x86_64")
instanceB.modify_attribute("kernel", "k-abcd1234")
instanceB.modify_attribute("platform", "linux")
instanceB.modify_attribute("virtualization_type", "paravirtual")
imageB_id = conn.create_image(instanceB.id, "test-ami-B", "this is a test ami")
imageB = conn.get_image(imageB_id)
imageB.set_launch_permissions(group_names=("all"))
amis_by_architecture = conn.get_all_images(filters={"architecture": "x86_64"})
set([ami.id for ami in amis_by_architecture]).should.contain(imageB.id)
len(amis_by_architecture).should.equal(39)
amis_by_kernel = conn.get_all_images(filters={"kernel-id": "k-abcd1234"})
set([ami.id for ami in amis_by_kernel]).should.equal(set([imageB.id]))
amis_by_virtualization = conn.get_all_images(
filters={"virtualization-type": "paravirtual"}
)
set([ami.id for ami in amis_by_virtualization]).should.contain(imageB.id)
len(amis_by_virtualization).should.equal(3)
amis_by_platform = conn.get_all_images(filters={"platform": "windows"})
set([ami.id for ami in amis_by_platform]).should.contain(imageA.id)
len(amis_by_platform).should.equal(25)
amis_by_id = conn.get_all_images(filters={"image-id": imageA.id})
set([ami.id for ami in amis_by_id]).should.equal(set([imageA.id]))
amis_by_state = conn.get_all_images(filters={"state": "available"})
ami_ids_by_state = [ami.id for ami in amis_by_state]
ami_ids_by_state.should.contain(imageA.id)
ami_ids_by_state.should.contain(imageB.id)
len(amis_by_state).should.equal(40)
amis_by_name = conn.get_all_images(filters={"name": imageA.name})
set([ami.id for ami in amis_by_name]).should.equal(set([imageA.id]))
amis_by_public = conn.get_all_images(filters={"is-public": "true"})
set([ami.id for ami in amis_by_public]).should.contain(imageB.id)
len(amis_by_public).should.equal(39)
amis_by_nonpublic = conn.get_all_images(filters={"is-public": "false"})
set([ami.id for ami in amis_by_nonpublic]).should.contain(imageA.id)
len(amis_by_nonpublic).should.equal(1)
@mock_ec2 @mock_ec2
def test_ami_filters_boto3(): def test_ami_filters_boto3():
image_name_A = f"test-ami-{str(uuid4())[0:6]}" image_name_A = f"test-ami-{str(uuid4())[0:6]}"
@ -723,30 +430,6 @@ def test_ami_filters_boto3():
assert len(amis_by_nonpublic) >= 2, "Should have at least 2 non-public images" assert len(amis_by_nonpublic) >= 2, "Should have at least 2 non-public images"
# Has boto3 equivalent
@mock_ec2_deprecated
def test_ami_filtering_via_tag():
conn = boto.connect_vpc("the_key", "the_secret")
reservationA = conn.run_instances(EXAMPLE_AMI_ID)
instanceA = reservationA.instances[0]
imageA_id = conn.create_image(instanceA.id, "test-ami-A", "this is a test ami")
imageA = conn.get_image(imageA_id)
imageA.add_tag("a key", "some value")
reservationB = conn.run_instances(EXAMPLE_AMI_ID)
instanceB = reservationB.instances[0]
imageB_id = conn.create_image(instanceB.id, "test-ami-B", "this is a test ami")
imageB = conn.get_image(imageB_id)
imageB.add_tag("another key", "some other value")
amis_by_tagA = conn.get_all_images(filters={"tag:a key": "some value"})
set([ami.id for ami in amis_by_tagA]).should.equal(set([imageA.id]))
amis_by_tagB = conn.get_all_images(filters={"tag:another key": "some other value"})
set([ami.id for ami in amis_by_tagB]).should.equal(set([imageB.id]))
@mock_ec2 @mock_ec2
def test_ami_filtering_via_tag_boto3(): def test_ami_filtering_via_tag_boto3():
tag_value = f"value {str(uuid4())}" tag_value = f"value {str(uuid4())}"
@ -780,18 +463,6 @@ def test_ami_filtering_via_tag_boto3():
[ami["ImageId"] for ami in amis_by_tagB].should.equal([imageB_id]) [ami["ImageId"] for ami in amis_by_tagB].should.equal([imageB_id])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_getting_missing_ami():
conn = boto.connect_ec2("the_key", "the_secret")
with pytest.raises(EC2ResponseError) as cm:
conn.get_image("ami-missing")
cm.value.code.should.equal("InvalidAMIID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_getting_missing_ami_boto3(): def test_getting_missing_ami_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1") ec2 = boto3.resource("ec2", region_name="us-east-1")
@ -803,18 +474,6 @@ def test_getting_missing_ami_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidAMIID.NotFound") ex.value.response["Error"]["Code"].should.equal("InvalidAMIID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_getting_malformed_ami():
conn = boto.connect_ec2("the_key", "the_secret")
with pytest.raises(EC2ResponseError) as cm:
conn.get_image("foo-missing")
cm.value.code.should.equal("InvalidAMIID.Malformed")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_getting_malformed_ami_boto3(): def test_getting_malformed_ami_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1") ec2 = boto3.resource("ec2", region_name="us-east-1")
@ -826,70 +485,6 @@ def test_getting_malformed_ami_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidAMIID.Malformed") ex.value.response["Error"]["Code"].should.equal("InvalidAMIID.Malformed")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_ami_attribute_group_permissions():
conn = boto.connect_ec2("the_key", "the_secret")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
image_id = conn.create_image(instance.id, "test-ami", "this is a test ami")
image = conn.get_image(image_id)
# Baseline
attributes = conn.get_image_attribute(image.id, attribute="launchPermission")
attributes.name.should.equal("launch_permission")
attributes.attrs.should.have.length_of(0)
ADD_GROUP_ARGS = {
"image_id": image.id,
"attribute": "launchPermission",
"operation": "add",
"groups": "all",
}
REMOVE_GROUP_ARGS = {
"image_id": image.id,
"attribute": "launchPermission",
"operation": "remove",
"groups": "all",
}
# Add 'all' group and confirm
with pytest.raises(EC2ResponseError) as ex:
conn.modify_image_attribute(**dict(ADD_GROUP_ARGS, **{"dry_run": True}))
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the ModifyImageAttribute operation: Request would have succeeded, but DryRun flag is set"
)
conn.modify_image_attribute(**ADD_GROUP_ARGS)
attributes = conn.get_image_attribute(image.id, attribute="launchPermission")
attributes.attrs["groups"].should.have.length_of(1)
attributes.attrs["groups"].should.equal(["all"])
image = conn.get_image(image_id)
image.is_public.should.equal(True)
# Add is idempotent
conn.modify_image_attribute.when.called_with(**ADD_GROUP_ARGS).should_not.throw(
EC2ResponseError
)
# Remove 'all' group and confirm
conn.modify_image_attribute(**REMOVE_GROUP_ARGS)
attributes = conn.get_image_attribute(image.id, attribute="launchPermission")
attributes.attrs.should.have.length_of(0)
image = conn.get_image(image_id)
image.is_public.should.equal(False)
# Remove is idempotent
conn.modify_image_attribute.when.called_with(**REMOVE_GROUP_ARGS).should_not.throw(
EC2ResponseError
)
@mock_ec2 @mock_ec2
def test_ami_attribute_group_permissions_boto3(): def test_ami_attribute_group_permissions_boto3():
ec2 = boto3.client("ec2", region_name="us-east-1") ec2 = boto3.client("ec2", region_name="us-east-1")
@ -956,82 +551,6 @@ def test_ami_attribute_group_permissions_boto3():
image.modify_attribute(**REMOVE_GROUP_ARGS) image.modify_attribute(**REMOVE_GROUP_ARGS)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_ami_attribute_user_permissions():
conn = boto.connect_ec2("the_key", "the_secret")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
image_id = conn.create_image(instance.id, "test-ami", "this is a test ami")
image = conn.get_image(image_id)
# Baseline
attributes = conn.get_image_attribute(image.id, attribute="launchPermission")
attributes.name.should.equal("launch_permission")
attributes.attrs.should.have.length_of(0)
# Both str and int values should work.
USER1 = "123456789011"
USER2 = 123456789022
ADD_USERS_ARGS = {
"image_id": image.id,
"attribute": "launchPermission",
"operation": "add",
"user_ids": [USER1, USER2],
}
REMOVE_USERS_ARGS = {
"image_id": image.id,
"attribute": "launchPermission",
"operation": "remove",
"user_ids": [USER1, USER2],
}
REMOVE_SINGLE_USER_ARGS = {
"image_id": image.id,
"attribute": "launchPermission",
"operation": "remove",
"user_ids": [USER1],
}
# Add multiple users and confirm
conn.modify_image_attribute(**ADD_USERS_ARGS)
attributes = conn.get_image_attribute(image.id, attribute="launchPermission")
attributes.attrs["user_ids"].should.have.length_of(2)
set(attributes.attrs["user_ids"]).should.equal(set([str(USER1), str(USER2)]))
image = conn.get_image(image_id)
image.is_public.should.equal(False)
# Add is idempotent
conn.modify_image_attribute.when.called_with(**ADD_USERS_ARGS).should_not.throw(
EC2ResponseError
)
# Remove single user and confirm
conn.modify_image_attribute(**REMOVE_SINGLE_USER_ARGS)
attributes = conn.get_image_attribute(image.id, attribute="launchPermission")
attributes.attrs["user_ids"].should.have.length_of(1)
set(attributes.attrs["user_ids"]).should.equal(set([str(USER2)]))
image = conn.get_image(image_id)
image.is_public.should.equal(False)
# Remove multiple users and confirm
conn.modify_image_attribute(**REMOVE_USERS_ARGS)
attributes = conn.get_image_attribute(image.id, attribute="launchPermission")
attributes.attrs.should.have.length_of(0)
image = conn.get_image(image_id)
image.is_public.should.equal(False)
# Remove is idempotent
conn.modify_image_attribute.when.called_with(**REMOVE_USERS_ARGS).should_not.throw(
EC2ResponseError
)
@mock_ec2 @mock_ec2
def test_ami_attribute_user_permissions_boto3(): def test_ami_attribute_user_permissions_boto3():
ec2 = boto3.client("ec2", region_name="us-east-1") ec2 = boto3.client("ec2", region_name="us-east-1")
@ -1216,63 +735,6 @@ def test_ami_describe_executable_users_and_filter():
images[0]["ImageId"].should.equal(image_id) images[0]["ImageId"].should.equal(image_id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_ami_attribute_user_and_group_permissions():
"""
Boto supports adding/removing both users and groups at the same time.
Just spot-check this -- input variations, idempotency, etc are validated
via user-specific and group-specific tests above.
"""
conn = boto.connect_ec2("the_key", "the_secret")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
image_id = conn.create_image(instance.id, "test-ami", "this is a test ami")
image = conn.get_image(image_id)
# Baseline
attributes = conn.get_image_attribute(image.id, attribute="launchPermission")
attributes.name.should.equal("launch_permission")
attributes.attrs.should.have.length_of(0)
USER1 = "123456789011"
USER2 = "123456789022"
ADD_ARGS = {
"image_id": image.id,
"attribute": "launchPermission",
"operation": "add",
"groups": ["all"],
"user_ids": [USER1, USER2],
}
REMOVE_ARGS = {
"image_id": image.id,
"attribute": "launchPermission",
"operation": "remove",
"groups": ["all"],
"user_ids": [USER1, USER2],
}
# Add and confirm
conn.modify_image_attribute(**ADD_ARGS)
attributes = conn.get_image_attribute(image.id, attribute="launchPermission")
attributes.attrs["user_ids"].should.have.length_of(2)
set(attributes.attrs["user_ids"]).should.equal(set([USER1, USER2]))
set(attributes.attrs["groups"]).should.equal(set(["all"]))
image = conn.get_image(image_id)
image.is_public.should.equal(True)
# Remove and confirm
conn.modify_image_attribute(**REMOVE_ARGS)
attributes = conn.get_image_attribute(image.id, attribute="launchPermission")
attributes.attrs.should.have.length_of(0)
image = conn.get_image(image_id)
image.is_public.should.equal(False)
@mock_ec2 @mock_ec2
def test_ami_attribute_user_and_group_permissions_boto3(): def test_ami_attribute_user_and_group_permissions_boto3():
""" """
@ -1363,98 +825,6 @@ def test_filter_description():
resp.should.have.length_of(1) resp.should.have.length_of(1)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_ami_attribute_error_cases():
conn = boto.connect_ec2("the_key", "the_secret")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
image_id = conn.create_image(instance.id, "test-ami", "this is a test ami")
image = conn.get_image(image_id)
# Error: Add with group != 'all'
with pytest.raises(EC2ResponseError) as cm:
conn.modify_image_attribute(
image.id, attribute="launchPermission", operation="add", groups="everyone"
)
cm.value.code.should.equal("InvalidAMIAttributeItemValue")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
# Error: Add with user ID that isn't an integer.
with pytest.raises(EC2ResponseError) as cm:
conn.modify_image_attribute(
image.id,
attribute="launchPermission",
operation="add",
user_ids="12345678901A",
)
cm.value.code.should.equal("InvalidAMIAttributeItemValue")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
# Error: Add with user ID that is > length 12.
with pytest.raises(EC2ResponseError) as cm:
conn.modify_image_attribute(
image.id,
attribute="launchPermission",
operation="add",
user_ids="1234567890123",
)
cm.value.code.should.equal("InvalidAMIAttributeItemValue")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
# Error: Add with user ID that is < length 12.
with pytest.raises(EC2ResponseError) as cm:
conn.modify_image_attribute(
image.id,
attribute="launchPermission",
operation="add",
user_ids="12345678901",
)
cm.value.code.should.equal("InvalidAMIAttributeItemValue")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
# Error: Add with one invalid user ID among other valid IDs, ensure no
# partial changes.
with pytest.raises(EC2ResponseError) as cm:
conn.modify_image_attribute(
image.id,
attribute="launchPermission",
operation="add",
user_ids=["123456789011", "foo", "123456789022"],
)
cm.value.code.should.equal("InvalidAMIAttributeItemValue")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
attributes = conn.get_image_attribute(image.id, attribute="launchPermission")
attributes.attrs.should.have.length_of(0)
# Error: Add with invalid image ID
with pytest.raises(EC2ResponseError) as cm:
conn.modify_image_attribute(
"ami-abcd1234", attribute="launchPermission", operation="add", groups="all"
)
cm.value.code.should.equal("InvalidAMIID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
# Error: Remove with invalid image ID
with pytest.raises(EC2ResponseError) as cm:
conn.modify_image_attribute(
"ami-abcd1234",
attribute="launchPermission",
operation="remove",
groups="all",
)
cm.value.code.should.equal("InvalidAMIID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_ami_attribute_error_cases_boto3(): def test_ami_attribute_error_cases_boto3():
ec2 = boto3.client("ec2", region_name="us-east-1") ec2 = boto3.client("ec2", region_name="us-east-1")

View File

@ -1,34 +1,9 @@
import boto
import boto.ec2
import boto3 import boto3
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
import pytest import pytest
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
from moto import mock_ec2, mock_ec2_deprecated from moto import mock_ec2
# Has boto3 equivalent
@mock_ec2_deprecated
def test_describe_regions():
conn = boto.connect_ec2("the_key", "the_secret")
regions = conn.get_all_regions()
len(regions).should.be.greater_than(1)
for region in regions:
region.endpoint.should.contain(region.name)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_availability_zones():
conn = boto.connect_ec2("the_key", "the_secret")
regions = conn.get_all_regions()
for region in regions:
conn = boto.ec2.connect_to_region(region.name)
if conn is None:
continue
for zone in conn.get_all_zones():
zone.name.should.contain(region.name)
@mock_ec2 @mock_ec2

View File

@ -1,24 +1,9 @@
import boto
import sure # noqa # pylint: disable=unused-import
import boto3 import boto3
import pytest import pytest
from boto.exception import EC2ResponseError import sure # noqa # pylint: disable=unused-import
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
from moto import mock_ec2
from moto import mock_ec2_deprecated, mock_ec2
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_customer_gateways():
conn = boto.connect_vpc("the_key", "the_secret")
customer_gateway = conn.create_customer_gateway("ipsec.1", "205.251.242.54", 65534)
customer_gateway.should_not.be.none
customer_gateway.id.should.match(r"cgw-\w+")
customer_gateway.type.should.equal("ipsec.1")
customer_gateway.bgp_asn.should.equal(65534)
customer_gateway.ip_address.should.equal("205.251.242.54")
@mock_ec2 @mock_ec2
@ -32,16 +17,6 @@ def test_create_customer_gateways_boto3():
customer_gateway.should.have.key("IpAddress").equal("205.251.242.54") customer_gateway.should.have.key("IpAddress").equal("205.251.242.54")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_describe_customer_gateways():
conn = boto.connect_vpc("the_key", "the_secret")
customer_gateway = conn.create_customer_gateway("ipsec.1", "205.251.242.54", 65534)
cgws = conn.get_all_customer_gateways()
cgws.should.have.length_of(1)
cgws[0].id.should.match(customer_gateway.id)
@mock_ec2 @mock_ec2
def test_describe_customer_gateways_dryrun(): def test_describe_customer_gateways_dryrun():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -81,21 +56,6 @@ def test_describe_customer_gateways_boto3():
), "Should have at least the one CustomerGateway we just created" ), "Should have at least the one CustomerGateway we just created"
# Has boto3 equivalent
@mock_ec2_deprecated
def test_delete_customer_gateways():
conn = boto.connect_vpc("the_key", "the_secret")
customer_gateway = conn.create_customer_gateway("ipsec.1", "205.251.242.54", 65534)
customer_gateway.should_not.be.none
cgws = conn.get_all_customer_gateways()
cgws[0].id.should.match(customer_gateway.id)
conn.delete_customer_gateway(customer_gateway.id)
cgws = conn.get_all_customer_gateways()
cgws[0].state.should.equal("deleted")
cgws.should.have.length_of(1)
@mock_ec2 @mock_ec2
def test_delete_customer_gateways_boto3(): def test_delete_customer_gateways_boto3():
ec2 = boto3.client("ec2", region_name="us-east-1") ec2 = boto3.client("ec2", region_name="us-east-1")
@ -118,14 +78,6 @@ def test_delete_customer_gateways_boto3():
cgws[0].should.have.key("State").equal("deleted") cgws[0].should.have.key("State").equal("deleted")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_delete_customer_gateways_bad_id():
conn = boto.connect_vpc("the_key", "the_secret")
with pytest.raises(EC2ResponseError):
conn.delete_customer_gateway("cgw-0123abcd")
@mock_ec2 @mock_ec2
def test_delete_customer_gateways_bad_id_boto3(): def test_delete_customer_gateways_bad_id_boto3():
ec2 = boto3.client("ec2", region_name="us-east-1") ec2 = boto3.client("ec2", region_name="us-east-1")

View File

@ -1,33 +1,19 @@
import pytest import pytest
import boto3 import boto3
import boto
from boto.exception import EC2ResponseError
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
import random import random
import uuid import uuid
from moto import mock_ec2, mock_ec2_deprecated, settings from moto import mock_ec2, settings
from unittest import SkipTest from unittest import SkipTest
SAMPLE_DOMAIN_NAME = "example.com" SAMPLE_DOMAIN_NAME = "example.com"
SAMPLE_NAME_SERVERS = ["10.0.0.6", "10.0.0.7"] SAMPLE_NAME_SERVERS = ["10.0.0.6", "10.0.0.7"]
# Has boto3 equivalent
@mock_ec2_deprecated
def test_dhcp_options_associate():
"""associate dhcp option"""
conn = boto.connect_vpc("the_key", "the_secret")
dhcp_options = conn.create_dhcp_options(SAMPLE_DOMAIN_NAME, SAMPLE_NAME_SERVERS)
vpc = conn.create_vpc("10.0.0.0/16")
rval = conn.associate_dhcp_options(dhcp_options.id, vpc.id)
rval.should.be.equal(True)
@mock_ec2 @mock_ec2
def test_dhcp_options_associate_boto3(): def test_dhcp_options_associate_boto3():
""" associate dhcp option """ """ associate dhcp option """
@ -48,20 +34,6 @@ def test_dhcp_options_associate_boto3():
vpc.dhcp_options_id.should.equal(dhcp_options.id) vpc.dhcp_options_id.should.equal(dhcp_options.id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_dhcp_options_associate_invalid_dhcp_id():
"""associate dhcp option bad dhcp options id"""
conn = boto.connect_vpc("the_key", "the_secret")
vpc = conn.create_vpc("10.0.0.0/16")
with pytest.raises(EC2ResponseError) as cm:
conn.associate_dhcp_options("foo", vpc.id)
cm.value.code.should.equal("InvalidDhcpOptionID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_dhcp_options_associate_invalid_dhcp_id_boto3(): def test_dhcp_options_associate_invalid_dhcp_id_boto3():
""" associate dhcp option bad dhcp options id """ """ associate dhcp option bad dhcp options id """
@ -76,20 +48,6 @@ def test_dhcp_options_associate_invalid_dhcp_id_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidDhcpOptionID.NotFound") ex.value.response["Error"]["Code"].should.equal("InvalidDhcpOptionID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_dhcp_options_associate_invalid_vpc_id():
"""associate dhcp option invalid vpc id"""
conn = boto.connect_vpc("the_key", "the_secret")
dhcp_options = conn.create_dhcp_options(SAMPLE_DOMAIN_NAME, SAMPLE_NAME_SERVERS)
with pytest.raises(EC2ResponseError) as cm:
conn.associate_dhcp_options(dhcp_options.id, "foo")
cm.value.code.should.equal("InvalidVpcID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_dhcp_options_associate_invalid_vpc_id_boto3(): def test_dhcp_options_associate_invalid_vpc_id_boto3():
""" associate dhcp option invalid vpc id """ """ associate dhcp option invalid vpc id """
@ -109,33 +67,6 @@ def test_dhcp_options_associate_invalid_vpc_id_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidVpcID.NotFound") ex.value.response["Error"]["Code"].should.equal("InvalidVpcID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_dhcp_options_delete_with_vpc():
"""Test deletion of dhcp options with vpc"""
conn = boto.connect_vpc("the_key", "the_secret")
dhcp_options = conn.create_dhcp_options(SAMPLE_DOMAIN_NAME, SAMPLE_NAME_SERVERS)
dhcp_options_id = dhcp_options.id
vpc = conn.create_vpc("10.0.0.0/16")
rval = conn.associate_dhcp_options(dhcp_options_id, vpc.id)
rval.should.be.equal(True)
with pytest.raises(EC2ResponseError) as cm:
conn.delete_dhcp_options(dhcp_options_id)
cm.value.code.should.equal("DependencyViolation")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
vpc.delete()
with pytest.raises(EC2ResponseError) as cm:
conn.get_all_dhcp_options([dhcp_options_id])
cm.value.code.should.equal("InvalidDhcpOptionID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_dhcp_options_delete_with_vpc_boto3(): def test_dhcp_options_delete_with_vpc_boto3():
"""Test deletion of dhcp options with vpc""" """Test deletion of dhcp options with vpc"""
@ -166,22 +97,6 @@ def test_dhcp_options_delete_with_vpc_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidDhcpOptionID.NotFound") ex.value.response["Error"]["Code"].should.equal("InvalidDhcpOptionID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_dhcp_options():
"""Create most basic dhcp option"""
conn = boto.connect_vpc("the_key", "the_secret")
dhcp_option = conn.create_dhcp_options(SAMPLE_DOMAIN_NAME, SAMPLE_NAME_SERVERS)
dhcp_option.options["domain-name"][0].should.be.equal(SAMPLE_DOMAIN_NAME)
dhcp_option.options["domain-name-servers"][0].should.be.equal(
SAMPLE_NAME_SERVERS[0]
)
dhcp_option.options["domain-name-servers"][1].should.be.equal(
SAMPLE_NAME_SERVERS[1]
)
@mock_ec2 @mock_ec2
def test_create_dhcp_options_boto3(): def test_create_dhcp_options_boto3():
"""Create most basic dhcp option""" """Create most basic dhcp option"""
@ -206,26 +121,6 @@ def test_create_dhcp_options_boto3():
) )
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_dhcp_options_invalid_options():
"""Create invalid dhcp options"""
conn = boto.connect_vpc("the_key", "the_secret")
servers = ["f", "f", "f", "f", "f"]
with pytest.raises(EC2ResponseError) as cm:
conn.create_dhcp_options(ntp_servers=servers)
cm.value.code.should.equal("InvalidParameterValue")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
with pytest.raises(EC2ResponseError) as cm:
conn.create_dhcp_options(netbios_node_type="0")
cm.value.code.should.equal("InvalidParameterValue")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_create_dhcp_options_invalid_options_boto3(): def test_create_dhcp_options_invalid_options_boto3():
"""Create invalid dhcp options""" """Create invalid dhcp options"""
@ -249,20 +144,6 @@ def test_create_dhcp_options_invalid_options_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidParameterValue") ex.value.response["Error"]["Code"].should.equal("InvalidParameterValue")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_describe_dhcp_options():
"""Test dhcp options lookup by id"""
conn = boto.connect_vpc("the_key", "the_secret")
dhcp_option = conn.create_dhcp_options()
dhcp_options = conn.get_all_dhcp_options([dhcp_option.id])
dhcp_options.should.be.length_of(1)
dhcp_options = conn.get_all_dhcp_options()
dhcp_options.should.be.length_of(1)
@mock_ec2 @mock_ec2
def test_describe_dhcp_options_boto3(): def test_describe_dhcp_options_boto3():
"""Test dhcp options lookup by id""" """Test dhcp options lookup by id"""
@ -299,19 +180,6 @@ def test_describe_dhcp_options_boto3():
) )
# Has boto3 equivalent
@mock_ec2_deprecated
def test_describe_dhcp_options_invalid_id():
"""get error on invalid dhcp_option_id lookup"""
conn = boto.connect_vpc("the_key", "the_secret")
with pytest.raises(EC2ResponseError) as cm:
conn.get_all_dhcp_options(["1"])
cm.value.code.should.equal("InvalidDhcpOptionID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_describe_dhcp_options_invalid_id_boto3(): def test_describe_dhcp_options_invalid_id_boto3():
"""get error on invalid dhcp_option_id lookup""" """get error on invalid dhcp_option_id lookup"""
@ -324,25 +192,6 @@ def test_describe_dhcp_options_invalid_id_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidDhcpOptionID.NotFound") ex.value.response["Error"]["Code"].should.equal("InvalidDhcpOptionID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_delete_dhcp_options():
"""delete dhcp option"""
conn = boto.connect_vpc("the_key", "the_secret")
dhcp_option = conn.create_dhcp_options()
dhcp_options = conn.get_all_dhcp_options([dhcp_option.id])
dhcp_options.should.be.length_of(1)
conn.delete_dhcp_options(dhcp_option.id) # .should.be.equal(True)
with pytest.raises(EC2ResponseError) as cm:
conn.get_all_dhcp_options([dhcp_option.id])
cm.value.code.should.equal("InvalidDhcpOptionID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_delete_dhcp_options_boto3(): def test_delete_dhcp_options_boto3():
"""delete dhcp option""" """delete dhcp option"""
@ -365,20 +214,6 @@ def test_delete_dhcp_options_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidDhcpOptionID.NotFound") ex.value.response["Error"]["Code"].should.equal("InvalidDhcpOptionID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_delete_dhcp_options_invalid_id():
conn = boto.connect_vpc("the_key", "the_secret")
conn.create_dhcp_options()
with pytest.raises(EC2ResponseError) as cm:
conn.delete_dhcp_options("dopt-abcd1234")
cm.value.code.should.equal("InvalidDhcpOptionID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_delete_dhcp_options_invalid_id_boto3(): def test_delete_dhcp_options_invalid_id_boto3():
client = boto3.client("ec2", region_name="us-west-1") client = boto3.client("ec2", region_name="us-west-1")
@ -390,20 +225,6 @@ def test_delete_dhcp_options_invalid_id_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidDhcpOptionID.NotFound") ex.value.response["Error"]["Code"].should.equal("InvalidDhcpOptionID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_delete_dhcp_options_malformed_id():
conn = boto.connect_vpc("the_key", "the_secret")
conn.create_dhcp_options()
with pytest.raises(EC2ResponseError) as cm:
conn.delete_dhcp_options("foo-abcd1234")
cm.value.code.should.equal("InvalidDhcpOptionsId.Malformed")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_delete_dhcp_options_malformed_id_boto3(): def test_delete_dhcp_options_malformed_id_boto3():
client = boto3.client("ec2", region_name="us-west-1") client = boto3.client("ec2", region_name="us-west-1")
@ -415,24 +236,6 @@ def test_delete_dhcp_options_malformed_id_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidDhcpOptionsId.Malformed") ex.value.response["Error"]["Code"].should.equal("InvalidDhcpOptionsId.Malformed")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_dhcp_tagging():
conn = boto.connect_vpc("the_key", "the_secret")
dhcp_option = conn.create_dhcp_options()
dhcp_option.add_tag("a key", "some value")
tag = conn.get_all_tags()[0]
tag.name.should.equal("a key")
tag.value.should.equal("some value")
# Refresh the DHCP options
dhcp_option = conn.get_all_dhcp_options()[0]
dhcp_option.tags.should.have.length_of(1)
dhcp_option.tags["a key"].should.equal("some value")
@mock_ec2 @mock_ec2
def test_dhcp_tagging_boto3(): def test_dhcp_tagging_boto3():
ec2 = boto3.resource("ec2", region_name="us-west-1") ec2 = boto3.resource("ec2", region_name="us-west-1")
@ -463,43 +266,6 @@ def test_dhcp_tagging_boto3():
dhcp_option["Tags"].should.equal([{"Key": "a tag", "Value": tag_value}]) dhcp_option["Tags"].should.equal([{"Key": "a tag", "Value": tag_value}])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_dhcp_options_get_by_tag():
conn = boto.connect_vpc("the_key", "the_secret")
dhcp1 = conn.create_dhcp_options("example.com", ["10.0.10.2"])
dhcp1.add_tag("Name", "TestDhcpOptions1")
dhcp1.add_tag("test-tag", "test-value")
dhcp2 = conn.create_dhcp_options("example.com", ["10.0.20.2"])
dhcp2.add_tag("Name", "TestDhcpOptions2")
dhcp2.add_tag("test-tag", "test-value")
filters = {"tag:Name": "TestDhcpOptions1", "tag:test-tag": "test-value"}
dhcp_options_sets = conn.get_all_dhcp_options(filters=filters)
dhcp_options_sets.should.have.length_of(1)
dhcp_options_sets[0].options["domain-name"][0].should.be.equal("example.com")
dhcp_options_sets[0].options["domain-name-servers"][0].should.be.equal("10.0.10.2")
dhcp_options_sets[0].tags["Name"].should.equal("TestDhcpOptions1")
dhcp_options_sets[0].tags["test-tag"].should.equal("test-value")
filters = {"tag:Name": "TestDhcpOptions2", "tag:test-tag": "test-value"}
dhcp_options_sets = conn.get_all_dhcp_options(filters=filters)
dhcp_options_sets.should.have.length_of(1)
dhcp_options_sets[0].options["domain-name"][0].should.be.equal("example.com")
dhcp_options_sets[0].options["domain-name-servers"][0].should.be.equal("10.0.20.2")
dhcp_options_sets[0].tags["Name"].should.equal("TestDhcpOptions2")
dhcp_options_sets[0].tags["test-tag"].should.equal("test-value")
filters = {"tag:test-tag": "test-value"}
dhcp_options_sets = conn.get_all_dhcp_options(filters=filters)
dhcp_options_sets.should.have.length_of(2)
@mock_ec2 @mock_ec2
def test_dhcp_options_get_by_tag_boto3(): def test_dhcp_options_get_by_tag_boto3():
ec2 = boto3.resource("ec2", region_name="us-west-1") ec2 = boto3.resource("ec2", region_name="us-west-1")
@ -580,37 +346,6 @@ def test_dhcp_options_get_by_tag_boto3():
dhcp_options_sets.should.have.length_of(2) dhcp_options_sets.should.have.length_of(2)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_dhcp_options_get_by_id():
conn = boto.connect_vpc("the_key", "the_secret")
dhcp1 = conn.create_dhcp_options("test1.com", ["10.0.10.2"])
dhcp1.add_tag("Name", "TestDhcpOptions1")
dhcp1.add_tag("test-tag", "test-value")
dhcp1_id = dhcp1.id
dhcp2 = conn.create_dhcp_options("test2.com", ["10.0.20.2"])
dhcp2.add_tag("Name", "TestDhcpOptions2")
dhcp2.add_tag("test-tag", "test-value")
dhcp2_id = dhcp2.id
dhcp_options_sets = conn.get_all_dhcp_options()
dhcp_options_sets.should.have.length_of(2)
dhcp_options_sets = conn.get_all_dhcp_options(filters={"dhcp-options-id": dhcp1_id})
dhcp_options_sets.should.have.length_of(1)
dhcp_options_sets[0].options["domain-name"][0].should.be.equal("test1.com")
dhcp_options_sets[0].options["domain-name-servers"][0].should.be.equal("10.0.10.2")
dhcp_options_sets = conn.get_all_dhcp_options(filters={"dhcp-options-id": dhcp2_id})
dhcp_options_sets.should.have.length_of(1)
dhcp_options_sets[0].options["domain-name"][0].should.be.equal("test2.com")
dhcp_options_sets[0].options["domain-name-servers"][0].should.be.equal("10.0.20.2")
@mock_ec2 @mock_ec2
def test_dhcp_options_get_by_id_boto3(): def test_dhcp_options_get_by_id_boto3():
ec2 = boto3.resource("ec2", region_name="us-west-1") ec2 = boto3.resource("ec2", region_name="us-west-1")
@ -724,19 +459,6 @@ def test_dhcp_options_get_by_key_filter():
servers.should.contain({"Value": "example.com"}) servers.should.contain({"Value": "example.com"})
# Has boto3 equivalent
@mock_ec2_deprecated
def test_dhcp_options_get_by_invalid_filter():
conn = boto.connect_vpc("the_key", "the_secret")
conn.create_dhcp_options(SAMPLE_DOMAIN_NAME, SAMPLE_NAME_SERVERS)
filters = {"invalid-filter": "invalid-value"}
conn.get_all_dhcp_options.when.called_with(filters=filters).should.throw(
NotImplementedError
)
@mock_ec2 @mock_ec2
def test_dhcp_options_get_by_invalid_filter_boto3(): def test_dhcp_options_get_by_invalid_filter_boto3():
if settings.TEST_SERVER_MODE: if settings.TEST_SERVER_MODE:

View File

@ -1,5 +1,4 @@
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
from moto import mock_cloudformation_deprecated, mock_ec2_deprecated
from moto import mock_cloudformation, mock_ec2 from moto import mock_cloudformation, mock_ec2
from tests import EXAMPLE_AMI_ID from tests import EXAMPLE_AMI_ID
from tests.test_cloudformation.fixtures import ec2_classic_eip from tests.test_cloudformation.fixtures import ec2_classic_eip
@ -8,10 +7,6 @@ from tests.test_cloudformation.fixtures import vpc_eip
from tests.test_cloudformation.fixtures import vpc_eni from tests.test_cloudformation.fixtures import vpc_eni
from tests.test_cloudformation.fixtures import vpc_single_instance_in_subnet from tests.test_cloudformation.fixtures import vpc_single_instance_in_subnet
from uuid import uuid4 from uuid import uuid4
import boto
import boto.ec2
import boto.cloudformation
import boto.vpc
import boto3 import boto3
import json import json
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
@ -113,31 +108,6 @@ def test_delete_stack_with_resource_missing_delete_attr():
ec2.describe_vpcs(VpcIds=[vpc_id])["Vpcs"].should.have.length_of(1) ec2.describe_vpcs(VpcIds=[vpc_id])["Vpcs"].should.have.length_of(1)
# Has boto3 equivalent
@mock_ec2_deprecated
@mock_cloudformation_deprecated
def test_elastic_network_interfaces_cloudformation():
template = vpc_eni.template
template_json = json.dumps(template)
conn = boto.cloudformation.connect_to_region("us-west-1")
conn.create_stack("test_stack", template_body=template_json)
ec2_conn = boto.ec2.connect_to_region("us-west-1")
eni = ec2_conn.get_all_network_interfaces()[0]
eni.private_ip_addresses.should.have.length_of(1)
stack = conn.describe_stacks()[0]
resources = stack.describe_resources()
cfn_eni = [
resource
for resource in resources
if resource.resource_type == "AWS::EC2::NetworkInterface"
][0]
cfn_eni.physical_resource_id.should.equal(eni.id)
outputs = {output.key: output.value for output in stack.outputs}
outputs["ENIIpAddress"].should.equal(eni.private_ip_addresses[0].private_ip_address)
@mock_ec2 @mock_ec2
@mock_cloudformation @mock_cloudformation
def test_elastic_network_interfaces_cloudformation_boto3(): def test_elastic_network_interfaces_cloudformation_boto3():

View File

@ -1,57 +1,15 @@
import boto
import boto.ec2
import boto3 import boto3
import pytest import pytest
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
from boto.exception import EC2ResponseError
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
from moto import mock_ec2, mock_ec2_deprecated from moto import mock_ec2
from moto.ec2 import ec2_backends
from moto.ec2.models import OWNER_ID from moto.ec2.models import OWNER_ID
from moto.kms import mock_kms from moto.kms import mock_kms
from tests import EXAMPLE_AMI_ID from tests import EXAMPLE_AMI_ID
from uuid import uuid4 from uuid import uuid4
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_and_delete_volume():
conn = boto.ec2.connect_to_region("us-east-1")
volume = conn.create_volume(80, "us-east-1a")
all_volumes = conn.get_all_volumes()
current_volume = [item for item in all_volumes if item.id == volume.id]
current_volume.should.have.length_of(1)
current_volume[0].size.should.equal(80)
current_volume[0].zone.should.equal("us-east-1a")
current_volume[0].encrypted.should.be(False)
volume = current_volume[0]
with pytest.raises(EC2ResponseError) as ex:
volume.delete(dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the DeleteVolume operation: Request would have succeeded, but DryRun flag is set"
)
volume.delete()
all_volumes = conn.get_all_volumes()
my_volume = [item for item in all_volumes if item.id == volume.id]
my_volume.should.have.length_of(0)
# Deleting something that was already deleted should throw an error
with pytest.raises(EC2ResponseError) as cm:
volume.delete()
cm.value.code.should.equal("InvalidVolume.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_create_and_delete_volume_boto3(): def test_create_and_delete_volume_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -88,46 +46,6 @@ def test_create_and_delete_volume_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidVolume.NotFound") ex.value.response["Error"]["Code"].should.equal("InvalidVolume.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_delete_attached_volume():
conn = boto.ec2.connect_to_region("us-east-1")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
# create an instance
instance = reservation.instances[0]
# create a volume
volume = conn.create_volume(80, "us-east-1a")
# attach volume to instance
volume.attach(instance.id, "/dev/sdh")
volume.update()
volume.volume_state().should.equal("in-use")
volume.attachment_state().should.equal("attached")
volume.attach_data.instance_id.should.equal(instance.id)
# attempt to delete volume
# assert raises VolumeInUseError
with pytest.raises(EC2ResponseError) as ex:
volume.delete()
ex.value.error_code.should.equal("VolumeInUse")
ex.value.status.should.equal(400)
ex.value.message.should.equal(
"Volume {0} is currently attached to {1}".format(volume.id, instance.id)
)
volume.detach()
volume.update()
volume.volume_state().should.equal("available")
volume.delete()
all_volumes = conn.get_all_volumes()
my_volume = [item for item in all_volumes if item.id == volume.id]
my_volume.should.have.length_of(0)
@mock_ec2 @mock_ec2
def test_delete_attached_volume_boto3(): def test_delete_attached_volume_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -168,19 +86,6 @@ def test_delete_attached_volume_boto3():
[v["VolumeId"] for v in all_volumes].shouldnt.contain(volume.id) [v["VolumeId"] for v in all_volumes].shouldnt.contain(volume.id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_encrypted_volume_dryrun():
conn = boto.ec2.connect_to_region("us-east-1")
with pytest.raises(EC2ResponseError) as ex:
conn.create_volume(80, "us-east-1a", encrypted=True, dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the CreateVolume operation: Request would have succeeded, but DryRun flag is set"
)
@mock_ec2 @mock_ec2
def test_create_encrypted_volume_dryrun_boto3(): def test_create_encrypted_volume_dryrun_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1") ec2 = boto3.resource("ec2", region_name="us-east-1")
@ -193,24 +98,6 @@ def test_create_encrypted_volume_dryrun_boto3():
) )
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_encrypted_volume():
conn = boto.ec2.connect_to_region("us-east-1")
volume = conn.create_volume(80, "us-east-1a", encrypted=True)
with pytest.raises(EC2ResponseError) as ex:
conn.create_volume(80, "us-east-1a", encrypted=True, dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the CreateVolume operation: Request would have succeeded, but DryRun flag is set"
)
all_volumes = [vol for vol in conn.get_all_volumes() if vol.id == volume.id]
all_volumes[0].encrypted.should.be(True)
@mock_ec2 @mock_ec2
def test_create_encrypted_volume_boto3(): def test_create_encrypted_volume_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -221,27 +108,6 @@ def test_create_encrypted_volume_boto3():
all_volumes[0]["Encrypted"].should.be(True) all_volumes[0]["Encrypted"].should.be(True)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_filter_volume_by_id():
conn = boto.ec2.connect_to_region("us-east-1")
volume1 = conn.create_volume(80, "us-east-1a")
volume2 = conn.create_volume(36, "us-east-1b")
volume3 = conn.create_volume(20, "us-east-1c")
vol1 = conn.get_all_volumes(volume_ids=volume3.id)
vol1.should.have.length_of(1)
vol1[0].size.should.equal(20)
vol1[0].zone.should.equal("us-east-1c")
vol2 = conn.get_all_volumes(volume_ids=[volume1.id, volume2.id])
vol2.should.have.length_of(2)
with pytest.raises(EC2ResponseError) as cm:
conn.get_all_volumes(volume_ids=["vol-does_not_exist"])
cm.value.code.should.equal("InvalidVolume.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_filter_volume_by_id_boto3(): def test_filter_volume_by_id_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -264,115 +130,6 @@ def test_filter_volume_by_id_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidVolume.NotFound") ex.value.response["Error"]["Code"].should.equal("InvalidVolume.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_volume_filters():
conn = boto.ec2.connect_to_region("us-east-1")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
instance.update()
volume1 = conn.create_volume(80, "us-east-1a", encrypted=True)
volume2 = conn.create_volume(36, "us-east-1b", encrypted=False)
volume3 = conn.create_volume(20, "us-east-1c", encrypted=True)
snapshot = volume3.create_snapshot(description="testsnap")
volume4 = conn.create_volume(25, "us-east-1a", snapshot=snapshot)
conn.create_tags([volume1.id], {"testkey1": "testvalue1"})
conn.create_tags([volume2.id], {"testkey2": "testvalue2"})
volume1.update()
volume2.update()
volume3.update()
volume4.update()
block_mapping = instance.block_device_mapping["/dev/sda1"]
volume_ids = (
volume1.id,
volume2.id,
volume3.id,
volume4.id,
block_mapping.volume_id,
)
volumes_by_attach_time = conn.get_all_volumes(
filters={"attachment.attach-time": block_mapping.attach_time}
)
set([vol.id for vol in volumes_by_attach_time]).should.equal(
{block_mapping.volume_id}
)
volumes_by_attach_device = conn.get_all_volumes(
filters={"attachment.device": "/dev/sda1"}
)
set([vol.id for vol in volumes_by_attach_device]).should.equal(
{block_mapping.volume_id}
)
volumes_by_attach_instance_id = conn.get_all_volumes(
filters={"attachment.instance-id": instance.id}
)
set([vol.id for vol in volumes_by_attach_instance_id]).should.equal(
{block_mapping.volume_id}
)
volumes_by_attach_status = conn.get_all_volumes(
filters={"attachment.status": "attached"}
)
set([vol.id for vol in volumes_by_attach_status]).should.equal(
{block_mapping.volume_id}
)
volumes_by_create_time = conn.get_all_volumes(
filters={"create-time": volume4.create_time}
)
set([vol.create_time for vol in volumes_by_create_time]).should.equal(
{volume4.create_time}
)
volumes_by_size = conn.get_all_volumes(filters={"size": volume2.size})
set([vol.id for vol in volumes_by_size]).should.equal({volume2.id})
volumes_by_snapshot_id = conn.get_all_volumes(filters={"snapshot-id": snapshot.id})
set([vol.id for vol in volumes_by_snapshot_id]).should.equal({volume4.id})
volumes_by_status = conn.get_all_volumes(filters={"status": "in-use"})
set([vol.id for vol in volumes_by_status]).should.equal({block_mapping.volume_id})
volumes_by_id = conn.get_all_volumes(filters={"volume-id": volume1.id})
set([vol.id for vol in volumes_by_id]).should.equal({volume1.id})
volumes_by_tag_key = conn.get_all_volumes(filters={"tag-key": "testkey1"})
set([vol.id for vol in volumes_by_tag_key]).should.equal({volume1.id})
volumes_by_tag_value = conn.get_all_volumes(filters={"tag-value": "testvalue1"})
set([vol.id for vol in volumes_by_tag_value]).should.equal({volume1.id})
volumes_by_tag = conn.get_all_volumes(filters={"tag:testkey1": "testvalue1"})
set([vol.id for vol in volumes_by_tag]).should.equal({volume1.id})
volumes_by_unencrypted = conn.get_all_volumes(filters={"encrypted": "false"})
set(
[vol.id for vol in volumes_by_unencrypted if vol.id in volume_ids]
).should.equal({block_mapping.volume_id, volume2.id})
volumes_by_encrypted = conn.get_all_volumes(filters={"encrypted": "true"})
set([vol.id for vol in volumes_by_encrypted if vol.id in volume_ids]).should.equal(
{volume1.id, volume3.id, volume4.id}
)
volumes_by_availability_zone = conn.get_all_volumes(
filters={"availability-zone": "us-east-1b"}
)
set(
[vol.id for vol in volumes_by_availability_zone if vol.id in volume_ids]
).should.equal({volume2.id})
@mock_ec2 @mock_ec2
def test_volume_filters_boto3(): def test_volume_filters_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -496,65 +253,6 @@ def test_volume_filters_boto3():
[vol["VolumeId"] for vol in volumes_by_attach_device].should.contain(volume4.id) [vol["VolumeId"] for vol in volumes_by_attach_device].should.contain(volume4.id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_volume_attach_and_detach():
conn = boto.ec2.connect_to_region("us-east-1")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
volume = conn.create_volume(80, "us-east-1a")
volume.update()
volume.volume_state().should.equal("available")
with pytest.raises(EC2ResponseError) as ex:
volume.attach(instance.id, "/dev/sdh", dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the AttachVolume operation: Request would have succeeded, but DryRun flag is set"
)
volume.attach(instance.id, "/dev/sdh")
volume.update()
volume.volume_state().should.equal("in-use")
volume.attachment_state().should.equal("attached")
volume.attach_data.instance_id.should.equal(instance.id)
with pytest.raises(EC2ResponseError) as ex:
volume.detach(dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the DetachVolume operation: Request would have succeeded, but DryRun flag is set"
)
volume.detach()
volume.update()
volume.volume_state().should.equal("available")
with pytest.raises(EC2ResponseError) as cm1:
volume.attach("i-1234abcd", "/dev/sdh")
cm1.value.code.should.equal("InvalidInstanceID.NotFound")
cm1.value.status.should.equal(400)
cm1.value.request_id.should_not.be.none
with pytest.raises(EC2ResponseError) as cm2:
conn.detach_volume(volume.id, instance.id, "/dev/sdh")
cm2.value.code.should.equal("InvalidAttachment.NotFound")
cm2.value.status.should.equal(400)
cm2.value.request_id.should_not.be.none
with pytest.raises(EC2ResponseError) as cm3:
conn.detach_volume(volume.id, "i-1234abcd", "/dev/sdh")
cm3.value.code.should.equal("InvalidInstanceID.NotFound")
cm3.value.status.should.equal(400)
cm3.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_volume_attach_and_detach_boto3(): def test_volume_attach_and_detach_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -621,47 +319,6 @@ def test_volume_attach_and_detach_boto3():
ex3.value.response["Error"]["Code"].should.equal("InvalidInstanceID.NotFound") ex3.value.response["Error"]["Code"].should.equal("InvalidInstanceID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_snapshot():
conn = boto.ec2.connect_to_region("us-east-1")
volume = conn.create_volume(80, "us-east-1a")
with pytest.raises(EC2ResponseError) as ex:
snapshot = volume.create_snapshot("a dryrun snapshot", dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the CreateSnapshot operation: Request would have succeeded, but DryRun flag is set"
)
snapshot = volume.create_snapshot("a test snapshot")
snapshot.update()
snapshot.status.should.equal("completed")
snapshots = [snap for snap in conn.get_all_snapshots() if snap.id == snapshot.id]
snapshots.should.have.length_of(1)
snapshots[0].description.should.equal("a test snapshot")
snapshots[0].start_time.should_not.be.none
snapshots[0].encrypted.should.be(False)
# Create snapshot without description
num_snapshots = len(conn.get_all_snapshots())
snapshot = volume.create_snapshot()
conn.get_all_snapshots().should.have.length_of(num_snapshots + 1)
snapshot.delete()
conn.get_all_snapshots().should.have.length_of(num_snapshots)
# Deleting something that was already deleted should throw an error
with pytest.raises(EC2ResponseError) as cm:
snapshot.delete()
cm.value.code.should.equal("InvalidSnapshot.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_create_snapshot_boto3(): def test_create_snapshot_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -706,22 +363,6 @@ def test_create_snapshot_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidSnapshot.NotFound") ex.value.response["Error"]["Code"].should.equal("InvalidSnapshot.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_encrypted_snapshot():
conn = boto.ec2.connect_to_region("us-east-1")
volume = conn.create_volume(80, "us-east-1a", encrypted=True)
snapshot = volume.create_snapshot("a test snapshot")
snapshot.update()
snapshot.status.should.equal("completed")
snapshots = [snap for snap in conn.get_all_snapshots() if snap.id == snapshot.id]
snapshots.should.have.length_of(1)
snapshots[0].description.should.equal("a test snapshot")
snapshots[0].start_time.should_not.be.none
snapshots[0].encrypted.should.be(True)
@mock_ec2 @mock_ec2
@pytest.mark.parametrize("encrypted", [True, False]) @pytest.mark.parametrize("encrypted", [True, False])
def test_create_encrypted_snapshot_boto3(encrypted): def test_create_encrypted_snapshot_boto3(encrypted):
@ -746,34 +387,6 @@ def test_create_encrypted_snapshot_boto3(encrypted):
snapshots[0]["Encrypted"].should.be(encrypted) snapshots[0]["Encrypted"].should.be(encrypted)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_filter_snapshot_by_id():
conn = boto.ec2.connect_to_region("us-east-1")
volume1 = conn.create_volume(36, "us-east-1a")
volume1.create_snapshot("a test snapshot 1")
volume2 = conn.create_volume(42, "us-east-1a")
snap2 = volume2.create_snapshot("a test snapshot 2")
volume3 = conn.create_volume(84, "us-east-1a")
snap3 = volume3.create_snapshot("a test snapshot 3")
snapshots1 = conn.get_all_snapshots(snapshot_ids=snap2.id)
snapshots1.should.have.length_of(1)
snapshots1[0].volume_id.should.equal(volume2.id)
snapshots1[0].region.name.should.equal(conn.region.name)
snapshots2 = conn.get_all_snapshots(snapshot_ids=[snap2.id, snap3.id])
snapshots2.should.have.length_of(2)
for s in snapshots2:
s.start_time.should_not.be.none
s.volume_id.should.be.within([volume2.id, volume3.id])
s.region.name.should.equal(conn.region.name)
with pytest.raises(EC2ResponseError) as cm:
conn.get_all_snapshots(snapshot_ids=["snap-does_not_exist"])
cm.value.code.should.equal("InvalidSnapshot.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_filter_snapshot_by_id_boto3(): def test_filter_snapshot_by_id_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -802,71 +415,6 @@ def test_filter_snapshot_by_id_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidSnapshot.NotFound") ex.value.response["Error"]["Code"].should.equal("InvalidSnapshot.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_snapshot_filters():
conn = boto.ec2.connect_to_region("us-east-1")
volume1 = conn.create_volume(20, "us-east-1a", encrypted=False)
volume2 = conn.create_volume(25, "us-east-1a", encrypted=True)
snapshot1 = volume1.create_snapshot(description="testsnapshot1")
snapshot2 = volume1.create_snapshot(description="testsnapshot2")
snapshot3 = volume2.create_snapshot(description="testsnapshot3")
conn.create_tags([snapshot1.id], {"testkey1": "testvalue1"})
conn.create_tags([snapshot2.id], {"testkey2": "testvalue2"})
snapshots_by_description = conn.get_all_snapshots(
filters={"description": "testsnapshot1"}
)
set([snap.id for snap in snapshots_by_description]).should.equal({snapshot1.id})
snapshots_by_id = conn.get_all_snapshots(filters={"snapshot-id": snapshot1.id})
set([snap.id for snap in snapshots_by_id]).should.equal({snapshot1.id})
snapshots_by_start_time = conn.get_all_snapshots(
filters={"start-time": snapshot1.start_time}
)
set([snap.start_time for snap in snapshots_by_start_time]).should.equal(
{snapshot1.start_time}
)
snapshots_by_volume_id = conn.get_all_snapshots(filters={"volume-id": volume1.id})
set([snap.id for snap in snapshots_by_volume_id]).should.equal(
{snapshot1.id, snapshot2.id}
)
snapshots_by_status = conn.get_all_snapshots(filters={"status": "completed"})
(
{snapshot1.id, snapshot2.id, snapshot3.id}
- {snap.id for snap in snapshots_by_status}
).should.have.length_of(0)
snapshots_by_volume_size = conn.get_all_snapshots(
filters={"volume-size": volume1.size}
)
set([snap.id for snap in snapshots_by_volume_size]).should.equal(
{snapshot1.id, snapshot2.id}
)
snapshots_by_tag_key = conn.get_all_snapshots(filters={"tag-key": "testkey1"})
set([snap.id for snap in snapshots_by_tag_key]).should.equal({snapshot1.id})
snapshots_by_tag_value = conn.get_all_snapshots(filters={"tag-value": "testvalue1"})
set([snap.id for snap in snapshots_by_tag_value]).should.equal({snapshot1.id})
snapshots_by_tag = conn.get_all_snapshots(filters={"tag:testkey1": "testvalue1"})
set([snap.id for snap in snapshots_by_tag]).should.equal({snapshot1.id})
snapshots_by_encrypted = conn.get_all_snapshots(filters={"encrypted": "true"})
set([snap.id for snap in snapshots_by_encrypted]).should.equal({snapshot3.id})
snapshots_by_owner_id = conn.get_all_snapshots(filters={"owner-id": OWNER_ID})
set([snap.id for snap in snapshots_by_owner_id]).should.equal(
{snapshot1.id, snapshot2.id, snapshot3.id}
)
@mock_ec2 @mock_ec2
def test_snapshot_filters_boto3(): def test_snapshot_filters_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -937,115 +485,6 @@ def test_snapshot_filters_boto3():
[s["SnapshotId"] for s in snapshots].should.contain(snapshot3.id) [s["SnapshotId"] for s in snapshots].should.contain(snapshot3.id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_snapshot_attribute():
conn = boto.ec2.connect_to_region("us-east-1")
volume = conn.create_volume(80, "us-east-1a")
snapshot = volume.create_snapshot()
# Baseline
attributes = conn.get_snapshot_attribute(
snapshot.id, attribute="createVolumePermission"
)
attributes.name.should.equal("create_volume_permission")
attributes.attrs.should.have.length_of(0)
ADD_GROUP_ARGS = {
"snapshot_id": snapshot.id,
"attribute": "createVolumePermission",
"operation": "add",
"groups": "all",
}
REMOVE_GROUP_ARGS = {
"snapshot_id": snapshot.id,
"attribute": "createVolumePermission",
"operation": "remove",
"groups": "all",
}
# Add 'all' group and confirm
with pytest.raises(EC2ResponseError) as ex:
conn.modify_snapshot_attribute(**dict(ADD_GROUP_ARGS, **{"dry_run": True}))
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the ModifySnapshotAttribute operation: Request would have succeeded, but DryRun flag is set"
)
conn.modify_snapshot_attribute(**ADD_GROUP_ARGS)
attributes = conn.get_snapshot_attribute(
snapshot.id, attribute="createVolumePermission"
)
attributes.attrs["groups"].should.have.length_of(1)
attributes.attrs["groups"].should.equal(["all"])
# Add is idempotent
conn.modify_snapshot_attribute.when.called_with(**ADD_GROUP_ARGS).should_not.throw(
EC2ResponseError
)
# Remove 'all' group and confirm
with pytest.raises(EC2ResponseError) as ex:
conn.modify_snapshot_attribute(**dict(REMOVE_GROUP_ARGS, **{"dry_run": True}))
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the ModifySnapshotAttribute operation: Request would have succeeded, but DryRun flag is set"
)
conn.modify_snapshot_attribute(**REMOVE_GROUP_ARGS)
attributes = conn.get_snapshot_attribute(
snapshot.id, attribute="createVolumePermission"
)
attributes.attrs.should.have.length_of(0)
# Remove is idempotent
conn.modify_snapshot_attribute.when.called_with(
**REMOVE_GROUP_ARGS
).should_not.throw(EC2ResponseError)
# Error: Add with group != 'all'
with pytest.raises(EC2ResponseError) as cm:
conn.modify_snapshot_attribute(
snapshot.id,
attribute="createVolumePermission",
operation="add",
groups="everyone",
)
cm.value.code.should.equal("InvalidAMIAttributeItemValue")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
# Error: Add with invalid snapshot ID
with pytest.raises(EC2ResponseError) as cm:
conn.modify_snapshot_attribute(
"snapshot-abcd1234",
attribute="createVolumePermission",
operation="add",
groups="all",
)
cm.value.code.should.equal("InvalidSnapshot.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
# Error: Remove with invalid snapshot ID
with pytest.raises(EC2ResponseError) as cm:
conn.modify_snapshot_attribute(
"snapshot-abcd1234",
attribute="createVolumePermission",
operation="remove",
groups="all",
)
cm.value.code.should.equal("InvalidSnapshot.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_modify_snapshot_attribute(): def test_modify_snapshot_attribute():
ec2_client = boto3.client("ec2", region_name="us-east-1") ec2_client = boto3.client("ec2", region_name="us-east-1")
@ -1215,46 +654,6 @@ def test_modify_snapshot_attribute():
assert len(attributes["CreateVolumePermissions"]) == 0 assert len(attributes["CreateVolumePermissions"]) == 0
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_volume_from_snapshot():
conn = boto.ec2.connect_to_region("us-east-1")
volume = conn.create_volume(80, "us-east-1a")
snapshot = volume.create_snapshot("a test snapshot")
with pytest.raises(EC2ResponseError) as ex:
snapshot = volume.create_snapshot("a test snapshot", dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the CreateSnapshot operation: Request would have succeeded, but DryRun flag is set"
)
snapshot = volume.create_snapshot("a test snapshot")
snapshot.update()
snapshot.status.should.equal("completed")
new_volume = snapshot.create_volume("us-east-1a")
new_volume.size.should.equal(80)
new_volume.snapshot_id.should.equal(snapshot.id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_volume_from_encrypted_snapshot():
conn = boto.ec2.connect_to_region("us-east-1")
volume = conn.create_volume(80, "us-east-1a", encrypted=True)
snapshot = volume.create_snapshot("a test snapshot")
snapshot.update()
snapshot.status.should.equal("completed")
new_volume = snapshot.create_volume("us-east-1a")
new_volume.size.should.equal(80)
new_volume.snapshot_id.should.equal(snapshot.id)
new_volume.encrypted.should.be(True)
@mock_ec2 @mock_ec2
@pytest.mark.parametrize("encrypted", [True, False]) @pytest.mark.parametrize("encrypted", [True, False])
def test_create_volume_from_snapshot_boto3(encrypted): def test_create_volume_from_snapshot_boto3(encrypted):
@ -1275,38 +674,6 @@ def test_create_volume_from_snapshot_boto3(encrypted):
new_volume["Encrypted"].should.equal(encrypted) new_volume["Encrypted"].should.equal(encrypted)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_modify_attribute_blockDeviceMapping():
"""
Reproduces the missing feature explained at [0], where we want to mock a
call to modify an instance attribute of type: blockDeviceMapping.
[0] https://github.com/spulec/moto/issues/160
"""
conn = boto.ec2.connect_to_region("us-east-1")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
with pytest.raises(EC2ResponseError) as ex:
instance.modify_attribute(
"blockDeviceMapping", {"/dev/sda1": True}, dry_run=True
)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the ModifyInstanceAttribute operation: Request would have succeeded, but DryRun flag is set"
)
instance.modify_attribute("blockDeviceMapping", {"/dev/sda1": True})
instance = ec2_backends[conn.region.name].get_instance(instance.id)
instance.block_device_mapping.should.have.key("/dev/sda1")
instance.block_device_mapping["/dev/sda1"].delete_on_termination.should.be(True)
@mock_ec2 @mock_ec2
def test_modify_attribute_blockDeviceMapping_boto3(): def test_modify_attribute_blockDeviceMapping_boto3():
""" """
@ -1346,29 +713,6 @@ def test_modify_attribute_blockDeviceMapping_boto3():
mapping["Ebs"]["DeleteOnTermination"].should.be(True) mapping["Ebs"]["DeleteOnTermination"].should.be(True)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_volume_tag_escaping():
conn = boto.ec2.connect_to_region("us-east-1")
vol = conn.create_volume(10, "us-east-1a")
snapshot = conn.create_snapshot(vol.id, "Desc")
with pytest.raises(EC2ResponseError) as ex:
snapshot.add_tags({"key": "</closed>"}, dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the CreateTags operation: Request would have succeeded, but DryRun flag is set"
)
snaps = [snap for snap in conn.get_all_snapshots() if snap.id == snapshot.id]
dict(snaps[0].tags).should_not.be.equal({"key": "</closed>"})
snapshot.add_tags({"key": "</closed>"})
snaps = [snap for snap in conn.get_all_snapshots() if snap.id == snapshot.id]
dict(snaps[0].tags).should.equal({"key": "</closed>"})
@mock_ec2 @mock_ec2
def test_volume_tag_escaping_boto3(): def test_volume_tag_escaping_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")

View File

@ -1,51 +1,17 @@
import pytest import pytest
import boto
import boto3 import boto3
from boto.exception import EC2ResponseError
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
from uuid import uuid4 from uuid import uuid4
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
from moto import mock_ec2, mock_ec2_deprecated from moto import mock_ec2
from tests import EXAMPLE_AMI_ID from tests import EXAMPLE_AMI_ID
import logging import logging
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_allocate_classic():
"""Allocate/release Classic EIP"""
conn = boto.connect_ec2("the_key", "the_secret")
with pytest.raises(EC2ResponseError) as ex:
standard = conn.allocate_address(dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the AllocateAddress operation: Request would have succeeded, but DryRun flag is set"
)
standard = conn.allocate_address()
standard.should.be.a(boto.ec2.address.Address)
standard.public_ip.should.be.a(str)
standard.instance_id.should.be.none
standard.domain.should.be.equal("standard")
with pytest.raises(EC2ResponseError) as ex:
standard.release(dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the ReleaseAddress operation: Request would have succeeded, but DryRun flag is set"
)
standard.release()
standard.should_not.be.within(conn.get_all_addresses())
@mock_ec2 @mock_ec2
def test_eip_allocate_classic_boto3(): def test_eip_allocate_classic_boto3():
"""Allocate/release Classic EIP""" """Allocate/release Classic EIP"""
@ -83,27 +49,6 @@ def test_eip_allocate_classic_boto3():
[a["PublicIp"] for a in all_addresses].shouldnt.contain(public_ip) [a["PublicIp"] for a in all_addresses].shouldnt.contain(public_ip)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_allocate_vpc():
"""Allocate/release VPC EIP"""
conn = boto.connect_ec2("the_key", "the_secret")
with pytest.raises(EC2ResponseError) as ex:
vpc = conn.allocate_address(domain="vpc", dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the AllocateAddress operation: Request would have succeeded, but DryRun flag is set"
)
vpc = conn.allocate_address(domain="vpc")
vpc.should.be.a(boto.ec2.address.Address)
vpc.domain.should.be.equal("vpc")
logging.debug("vpc alloc_id:".format(vpc.allocation_id))
vpc.release()
@mock_ec2 @mock_ec2
def test_describe_addresses_dryrun(): def test_describe_addresses_dryrun():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -162,19 +107,6 @@ def test_specific_eip_allocate_vpc():
logging.debug("vpc alloc_id:".format(vpc["AllocationId"])) logging.debug("vpc alloc_id:".format(vpc["AllocationId"]))
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_allocate_invalid_domain():
"""Allocate EIP invalid domain"""
conn = boto.connect_ec2("the_key", "the_secret")
with pytest.raises(EC2ResponseError) as cm:
conn.allocate_address(domain="bogus")
cm.value.code.should.equal("InvalidParameterValue")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_eip_allocate_invalid_domain_boto3(): def test_eip_allocate_invalid_domain_boto3():
"""Allocate EIP invalid domain""" """Allocate EIP invalid domain"""
@ -187,58 +119,6 @@ def test_eip_allocate_invalid_domain_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidParameterValue") ex.value.response["Error"]["Code"].should.equal("InvalidParameterValue")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_associate_classic():
"""Associate/Disassociate EIP to classic instance"""
conn = boto.connect_ec2("the_key", "the_secret")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
eip = conn.allocate_address()
eip.instance_id.should.be.none
with pytest.raises(EC2ResponseError) as cm:
conn.associate_address(public_ip=eip.public_ip)
cm.value.code.should.equal("MissingParameter")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
with pytest.raises(EC2ResponseError) as ex:
conn.associate_address(
instance_id=instance.id, public_ip=eip.public_ip, dry_run=True
)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the AssociateAddress operation: Request would have succeeded, but DryRun flag is set"
)
conn.associate_address(instance_id=instance.id, public_ip=eip.public_ip)
# no .update() on address ):
eip = conn.get_all_addresses(addresses=[eip.public_ip])[0]
eip.instance_id.should.be.equal(instance.id)
with pytest.raises(EC2ResponseError) as ex:
conn.disassociate_address(public_ip=eip.public_ip, dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the DisAssociateAddress operation: Request would have succeeded, but DryRun flag is set"
)
conn.disassociate_address(public_ip=eip.public_ip)
# no .update() on address ):
eip = conn.get_all_addresses(addresses=[eip.public_ip])[0]
eip.instance_id.should.be.equal("")
eip.release()
eip.should_not.be.within(conn.get_all_addresses())
eip = None
instance.terminate()
@mock_ec2 @mock_ec2
def test_eip_associate_classic_boto3(): def test_eip_associate_classic_boto3():
"""Associate/Disassociate EIP to classic instance""" """Associate/Disassociate EIP to classic instance"""
@ -297,48 +177,6 @@ def test_eip_associate_classic_boto3():
instance.terminate() instance.terminate()
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_associate_vpc():
"""Associate/Disassociate EIP to VPC instance"""
conn = boto.connect_ec2("the_key", "the_secret")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
eip = conn.allocate_address(domain="vpc")
eip.instance_id.should.be.none
with pytest.raises(EC2ResponseError) as cm:
conn.associate_address(allocation_id=eip.allocation_id)
cm.value.code.should.equal("MissingParameter")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
conn.associate_address(instance_id=instance.id, allocation_id=eip.allocation_id)
# no .update() on address ):
eip = conn.get_all_addresses(addresses=[eip.public_ip])[0]
eip.instance_id.should.be.equal(instance.id)
conn.disassociate_address(association_id=eip.association_id)
# no .update() on address ):
eip = conn.get_all_addresses(addresses=[eip.public_ip])[0]
eip.instance_id.should.be.equal("")
eip.association_id.should.be.none
with pytest.raises(EC2ResponseError) as ex:
eip.release(dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the ReleaseAddress operation: Request would have succeeded, but DryRun flag is set"
)
eip.release()
eip = None
instance.terminate()
@mock_ec2 @mock_ec2
def test_eip_associate_vpc_boto3(): def test_eip_associate_vpc_boto3():
"""Associate/Disassociate EIP to VPC instance""" """Associate/Disassociate EIP to VPC instance"""
@ -430,38 +268,6 @@ def test_eip_boto3_vpc_association():
address.instance_id.should.be.empty address.instance_id.should.be.empty
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_associate_network_interface():
"""Associate/Disassociate EIP to NIC"""
conn = boto.connect_vpc("the_key", "the_secret")
vpc = conn.create_vpc("10.0.0.0/16")
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
eni = conn.create_network_interface(subnet.id)
eip = conn.allocate_address(domain="vpc")
eip.network_interface_id.should.be.none
with pytest.raises(EC2ResponseError) as cm:
conn.associate_address(network_interface_id=eni.id)
cm.value.code.should.equal("MissingParameter")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
conn.associate_address(network_interface_id=eni.id, allocation_id=eip.allocation_id)
# no .update() on address ):
eip = conn.get_all_addresses(addresses=[eip.public_ip])[0]
eip.network_interface_id.should.be.equal(eni.id)
conn.disassociate_address(association_id=eip.association_id)
# no .update() on address ):
eip = conn.get_all_addresses(addresses=[eip.public_ip])[0]
eip.network_interface_id.should.be.equal("")
eip.association_id.should.be.none
eip.release()
eip = None
@mock_ec2 @mock_ec2
def test_eip_associate_network_interface_boto3(): def test_eip_associate_network_interface_boto3():
"""Associate/Disassociate EIP to NIC""" """Associate/Disassociate EIP to NIC"""
@ -497,40 +303,6 @@ def test_eip_associate_network_interface_boto3():
eip.release() eip.release()
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_reassociate():
"""reassociate EIP"""
conn = boto.connect_ec2("the_key", "the_secret")
reservation = conn.run_instances(EXAMPLE_AMI_ID, min_count=2)
instance1, instance2 = reservation.instances
eip = conn.allocate_address()
conn.associate_address(instance_id=instance1.id, public_ip=eip.public_ip)
# Same ID is idempotent
conn.associate_address(instance_id=instance1.id, public_ip=eip.public_ip)
# Different ID detects resource association
with pytest.raises(EC2ResponseError) as cm:
conn.associate_address(
instance_id=instance2.id, public_ip=eip.public_ip, allow_reassociation=False
)
cm.value.code.should.equal("Resource.AlreadyAssociated")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
conn.associate_address.when.called_with(
instance_id=instance2.id, public_ip=eip.public_ip, allow_reassociation=True
).should_not.throw(EC2ResponseError)
eip.release()
instance1.terminate()
instance2.terminate()
@mock_ec2 @mock_ec2
def test_eip_reassociate_boto3(): def test_eip_reassociate_boto3():
"""reassociate EIP""" """reassociate EIP"""
@ -572,38 +344,6 @@ def test_eip_reassociate_boto3():
instance2.terminate() instance2.terminate()
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_reassociate_nic():
"""reassociate EIP"""
conn = boto.connect_vpc("the_key", "the_secret")
vpc = conn.create_vpc("10.0.0.0/16")
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
eni1 = conn.create_network_interface(subnet.id)
eni2 = conn.create_network_interface(subnet.id)
eip = conn.allocate_address()
conn.associate_address(network_interface_id=eni1.id, public_ip=eip.public_ip)
# Same ID is idempotent
conn.associate_address(network_interface_id=eni1.id, public_ip=eip.public_ip)
# Different ID detects resource association
with pytest.raises(EC2ResponseError) as cm:
conn.associate_address(network_interface_id=eni2.id, public_ip=eip.public_ip)
cm.value.code.should.equal("Resource.AlreadyAssociated")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
conn.associate_address.when.called_with(
network_interface_id=eni2.id, public_ip=eip.public_ip, allow_reassociation=True
).should_not.throw(EC2ResponseError)
eip.release()
eip = None
@mock_ec2 @mock_ec2
def test_eip_reassociate_nic_boto3(): def test_eip_reassociate_nic_boto3():
"""reassociate EIP""" """reassociate EIP"""
@ -641,26 +381,6 @@ def test_eip_reassociate_nic_boto3():
eip.release() eip.release()
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_associate_invalid_args():
"""Associate EIP, invalid args"""
conn = boto.connect_ec2("the_key", "the_secret")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
conn.allocate_address()
with pytest.raises(EC2ResponseError) as cm:
conn.associate_address(instance_id=instance.id)
cm.value.code.should.equal("MissingParameter")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
instance.terminate()
@mock_ec2 @mock_ec2
def test_eip_associate_invalid_args_boto3(): def test_eip_associate_invalid_args_boto3():
"""Associate EIP, invalid args """ """Associate EIP, invalid args """
@ -681,19 +401,6 @@ def test_eip_associate_invalid_args_boto3():
instance.terminate() instance.terminate()
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_disassociate_bogus_association():
"""Disassociate bogus EIP"""
conn = boto.connect_ec2("the_key", "the_secret")
with pytest.raises(EC2ResponseError) as cm:
conn.disassociate_address(association_id="bogus")
cm.value.code.should.equal("InvalidAssociationID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_eip_disassociate_bogus_association_boto3(): def test_eip_disassociate_bogus_association_boto3():
"""Disassociate bogus EIP""" """Disassociate bogus EIP"""
@ -706,19 +413,6 @@ def test_eip_disassociate_bogus_association_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidAssociationID.NotFound") ex.value.response["Error"]["Code"].should.equal("InvalidAssociationID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_release_bogus_eip():
"""Release bogus EIP"""
conn = boto.connect_ec2("the_key", "the_secret")
with pytest.raises(EC2ResponseError) as cm:
conn.release_address(allocation_id="bogus")
cm.value.code.should.equal("InvalidAllocationID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_eip_release_bogus_eip_boto3(): def test_eip_release_bogus_eip_boto3():
"""Release bogus EIP""" """Release bogus EIP"""
@ -731,19 +425,6 @@ def test_eip_release_bogus_eip_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidAllocationID.NotFound") ex.value.response["Error"]["Code"].should.equal("InvalidAllocationID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_disassociate_arg_error():
"""Invalid arguments disassociate address"""
conn = boto.connect_ec2("the_key", "the_secret")
with pytest.raises(EC2ResponseError) as cm:
conn.disassociate_address()
cm.value.code.should.equal("MissingParameter")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_eip_disassociate_arg_error_boto3(): def test_eip_disassociate_arg_error_boto3():
"""Invalid arguments disassociate address""" """Invalid arguments disassociate address"""
@ -756,19 +437,6 @@ def test_eip_disassociate_arg_error_boto3():
ex.value.response["Error"]["Code"].should.equal("MissingParameter") ex.value.response["Error"]["Code"].should.equal("MissingParameter")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_release_arg_error():
"""Invalid arguments release address"""
conn = boto.connect_ec2("the_key", "the_secret")
with pytest.raises(EC2ResponseError) as cm:
conn.release_address()
cm.value.code.should.equal("MissingParameter")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_eip_release_arg_error_boto3(): def test_eip_release_arg_error_boto3():
"""Invalid arguments release address""" """Invalid arguments release address"""
@ -781,47 +449,6 @@ def test_eip_release_arg_error_boto3():
ex.value.response["Error"]["Code"].should.equal("MissingParameter") ex.value.response["Error"]["Code"].should.equal("MissingParameter")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_describe():
"""Listing of allocated Elastic IP Addresses."""
conn = boto.connect_ec2("the_key", "the_secret")
eips = []
number_of_classic_ips = 2
number_of_vpc_ips = 2
# allocate some IPs
for _ in range(number_of_classic_ips):
eips.append(conn.allocate_address())
for _ in range(number_of_vpc_ips):
eips.append(conn.allocate_address(domain="vpc"))
len(eips).should.be.equal(number_of_classic_ips + number_of_vpc_ips)
# Can we find each one individually?
for eip in eips:
if eip.allocation_id:
lookup_addresses = conn.get_all_addresses(
allocation_ids=[eip.allocation_id]
)
else:
lookup_addresses = conn.get_all_addresses(addresses=[eip.public_ip])
len(lookup_addresses).should.be.equal(1)
lookup_addresses[0].public_ip.should.be.equal(eip.public_ip)
# Can we find first two when we search for them?
lookup_addresses = conn.get_all_addresses(
addresses=[eips[0].public_ip, eips[1].public_ip]
)
len(lookup_addresses).should.be.equal(2)
lookup_addresses[0].public_ip.should.be.equal(eips[0].public_ip)
lookup_addresses[1].public_ip.should.be.equal(eips[1].public_ip)
# Release all IPs
for eip in eips:
eip.release()
len(conn.get_all_addresses()).should.be.equal(0)
@mock_ec2 @mock_ec2
def test_eip_describe_boto3(): def test_eip_describe_boto3():
"""Listing of allocated Elastic IP Addresses.""" """Listing of allocated Elastic IP Addresses."""
@ -868,19 +495,6 @@ def test_eip_describe_boto3():
[a["PublicIp"] for a in all_addresses].shouldnt.contain(eips[1].public_ip) [a["PublicIp"] for a in all_addresses].shouldnt.contain(eips[1].public_ip)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_describe_none():
"""Error when search for bogus IP"""
conn = boto.connect_ec2("the_key", "the_secret")
with pytest.raises(EC2ResponseError) as cm:
conn.get_all_addresses(addresses=["256.256.256.256"])
cm.value.code.should.equal("InvalidAddress.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_eip_describe_none_boto3(): def test_eip_describe_none_boto3():
"""Error when search for bogus IP""" """Error when search for bogus IP"""

View File

@ -3,62 +3,14 @@ import random
import boto3 import boto3
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
import boto
import boto.ec2
from boto.exception import EC2ResponseError
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
from moto import mock_ec2, mock_ec2_deprecated, settings from moto import mock_ec2, settings
from moto.ec2.utils import random_private_ip from moto.ec2.utils import random_private_ip
from tests import EXAMPLE_AMI_ID from tests import EXAMPLE_AMI_ID
from tests.helpers import requires_boto_gte
from uuid import uuid4 from uuid import uuid4
# Has boto3 equivalent
@mock_ec2_deprecated
def test_elastic_network_interfaces():
conn = boto.connect_vpc("the_key", "the_secret")
vpc = conn.create_vpc("10.0.0.0/16")
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
with pytest.raises(EC2ResponseError) as ex:
eni = conn.create_network_interface(subnet.id, dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the CreateNetworkInterface operation: Request would have succeeded, but DryRun flag is set"
)
conn.create_network_interface(subnet.id)
all_enis = conn.get_all_network_interfaces()
all_enis.should.have.length_of(1)
eni = all_enis[0]
eni.groups.should.have.length_of(1)
eni.private_ip_addresses.should.have.length_of(1)
eni.private_ip_addresses[0].private_ip_address.startswith("10.").should.be.true
with pytest.raises(EC2ResponseError) as ex:
conn.delete_network_interface(eni.id, dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the DeleteNetworkInterface operation: Request would have succeeded, but DryRun flag is set"
)
conn.delete_network_interface(eni.id)
all_enis = conn.get_all_network_interfaces()
all_enis.should.have.length_of(0)
with pytest.raises(EC2ResponseError) as cm:
conn.delete_network_interface(eni.id)
cm.value.error_code.should.equal("InvalidNetworkInterfaceID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_elastic_network_interfaces_boto3(): def test_elastic_network_interfaces_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1") ec2 = boto3.resource("ec2", region_name="us-east-1")
@ -116,18 +68,6 @@ def test_elastic_network_interfaces_boto3():
) )
# Has boto3 equivalent
@mock_ec2_deprecated
def test_elastic_network_interfaces_subnet_validation():
conn = boto.connect_vpc("the_key", "the_secret")
with pytest.raises(EC2ResponseError) as cm:
conn.create_network_interface("subnet-abcd1234")
cm.value.error_code.should.equal("InvalidSubnetID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_elastic_network_interfaces_subnet_validation_boto3(): def test_elastic_network_interfaces_subnet_validation_boto3():
client = boto3.client("ec2", "us-east-1") client = boto3.client("ec2", "us-east-1")
@ -139,25 +79,6 @@ def test_elastic_network_interfaces_subnet_validation_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidSubnetID.NotFound") ex.value.response["Error"]["Code"].should.equal("InvalidSubnetID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_elastic_network_interfaces_with_private_ip():
conn = boto.connect_vpc("the_key", "the_secret")
vpc = conn.create_vpc("10.0.0.0/16")
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
private_ip = "54.0.0.1"
eni = conn.create_network_interface(subnet.id, private_ip)
all_enis = conn.get_all_network_interfaces()
all_enis.should.have.length_of(1)
eni = all_enis[0]
eni.groups.should.have.length_of(1)
eni.private_ip_addresses.should.have.length_of(1)
eni.private_ip_addresses[0].private_ip_address.should.equal(private_ip)
@mock_ec2 @mock_ec2
def test_elastic_network_interfaces_with_private_ip_boto3(): def test_elastic_network_interfaces_with_private_ip_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1") ec2 = boto3.resource("ec2", region_name="us-east-1")
@ -183,32 +104,6 @@ def test_elastic_network_interfaces_with_private_ip_boto3():
eni["PrivateIpAddresses"][0]["PrivateIpAddress"].should.equal(private_ip) eni["PrivateIpAddresses"][0]["PrivateIpAddress"].should.equal(private_ip)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_elastic_network_interfaces_with_groups():
conn = boto.connect_vpc("the_key", "the_secret")
vpc = conn.create_vpc("10.0.0.0/16")
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
security_group1 = conn.create_security_group(
"test security group #1", "this is a test security group"
)
security_group2 = conn.create_security_group(
"test security group #2", "this is a test security group"
)
conn.create_network_interface(
subnet.id, groups=[security_group1.id, security_group2.id]
)
all_enis = conn.get_all_network_interfaces()
all_enis.should.have.length_of(1)
eni = all_enis[0]
eni.groups.should.have.length_of(2)
set([group.id for group in eni.groups]).should.equal(
set([security_group1.id, security_group2.id])
)
@mock_ec2 @mock_ec2
def test_elastic_network_interfaces_with_groups_boto3(): def test_elastic_network_interfaces_with_groups_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1") ec2 = boto3.resource("ec2", region_name="us-east-1")
@ -250,51 +145,6 @@ def test_elastic_network_interfaces_without_group():
my_eni["Groups"][0]["GroupName"].should.equal("default") my_eni["Groups"][0]["GroupName"].should.equal("default")
# Has boto3 equivalent
@requires_boto_gte("2.12.0")
@mock_ec2_deprecated
def test_elastic_network_interfaces_modify_attribute():
conn = boto.connect_vpc("the_key", "the_secret")
vpc = conn.create_vpc("10.0.0.0/16")
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
security_group1 = conn.create_security_group(
"test security group #1", "this is a test security group"
)
security_group2 = conn.create_security_group(
"test security group #2", "this is a test security group"
)
conn.create_network_interface(subnet.id, groups=[security_group1.id])
all_enis = conn.get_all_network_interfaces()
all_enis.should.have.length_of(1)
eni = all_enis[0]
eni.groups.should.have.length_of(1)
eni.groups[0].id.should.equal(security_group1.id)
with pytest.raises(EC2ResponseError) as ex:
conn.modify_network_interface_attribute(
eni.id, "groupset", [security_group1.id, security_group2.id], dry_run=True
)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the ModifyNetworkInterface operation: Request would have succeeded, but DryRun flag is set"
)
conn.modify_network_interface_attribute(
eni.id, "groupset", [security_group1.id, security_group2.id]
)
all_enis = conn.get_all_network_interfaces()
all_enis.should.have.length_of(1)
eni = all_enis[0]
eni.groups.should.have.length_of(2)
eni.groups[0].id.should.equal(security_group1.id)
eni.groups[1].id.should.equal(security_group2.id)
@mock_ec2 @mock_ec2
def test_elastic_network_interfaces_modify_attribute_boto3(): def test_elastic_network_interfaces_modify_attribute_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1") ec2 = boto3.resource("ec2", region_name="us-east-1")
@ -334,68 +184,6 @@ def test_elastic_network_interfaces_modify_attribute_boto3():
my_eni["Groups"][0]["GroupId"].should.equal(sec_group2.id) my_eni["Groups"][0]["GroupId"].should.equal(sec_group2.id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_elastic_network_interfaces_filtering():
conn = boto.connect_vpc("the_key", "the_secret")
vpc = conn.create_vpc("10.0.0.0/16")
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
security_group1 = conn.create_security_group(
"test security group #1", "this is a test security group"
)
security_group2 = conn.create_security_group(
"test security group #2", "this is a test security group"
)
eni1 = conn.create_network_interface(
subnet.id, groups=[security_group1.id, security_group2.id]
)
eni2 = conn.create_network_interface(subnet.id, groups=[security_group1.id])
eni3 = conn.create_network_interface(subnet.id, description="test description")
all_enis = conn.get_all_network_interfaces()
all_enis.should.have.length_of(3)
# Filter by NetworkInterfaceId
enis_by_id = conn.get_all_network_interfaces([eni1.id])
enis_by_id.should.have.length_of(1)
set([eni.id for eni in enis_by_id]).should.equal(set([eni1.id]))
# Filter by ENI ID
enis_by_id = conn.get_all_network_interfaces(
filters={"network-interface-id": eni1.id}
)
enis_by_id.should.have.length_of(1)
set([eni.id for eni in enis_by_id]).should.equal(set([eni1.id]))
# Filter by Security Group
enis_by_group = conn.get_all_network_interfaces(
filters={"group-id": security_group1.id}
)
enis_by_group.should.have.length_of(2)
set([eni.id for eni in enis_by_group]).should.equal(set([eni1.id, eni2.id]))
# Filter by ENI ID and Security Group
enis_by_group = conn.get_all_network_interfaces(
filters={"network-interface-id": eni1.id, "group-id": security_group1.id}
)
enis_by_group.should.have.length_of(1)
set([eni.id for eni in enis_by_group]).should.equal(set([eni1.id]))
# Filter by Description
enis_by_description = conn.get_all_network_interfaces(
filters={"description": eni3.description}
)
enis_by_description.should.have.length_of(1)
enis_by_description[0].description.should.equal(eni3.description)
# Unsupported filter
conn.get_all_network_interfaces.when.called_with(
filters={"not-implemented-filter": "foobar"}
).should.throw(NotImplementedError)
@mock_ec2 @mock_ec2
def test_elastic_network_interfaces_filtering_boto3(): def test_elastic_network_interfaces_filtering_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1") ec2 = boto3.resource("ec2", region_name="us-east-1")

View File

@ -1,37 +1,13 @@
import pytest import pytest
import boto
import boto3 import boto3
from boto.exception import EC2ResponseError
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
from moto import mock_ec2_deprecated, mock_ec2 from moto import mock_ec2
from tests import EXAMPLE_AMI_ID from tests import EXAMPLE_AMI_ID
# Has boto3 equivalent
@mock_ec2_deprecated
def test_console_output():
conn = boto.connect_ec2("the_key", "the_secret")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance_id = reservation.instances[0].id
output = conn.get_console_output(instance_id)
output.output.should_not.equal(None)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_console_output_without_instance():
conn = boto.connect_ec2("the_key", "the_secret")
with pytest.raises(EC2ResponseError) as cm:
conn.get_console_output("i-1234abcd")
cm.value.error_code.should.equal("InvalidInstanceID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_console_output_boto3(): def test_console_output_boto3():
conn = boto3.resource("ec2", "us-east-1") conn = boto3.resource("ec2", "us-east-1")

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,12 @@
import pytest import pytest
import boto
import boto3 import boto3
from boto.exception import EC2ResponseError
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
from moto import mock_ec2_deprecated, mock_ec2 from moto import mock_ec2
from uuid import uuid4 from uuid import uuid4
@ -17,30 +15,6 @@ BAD_VPC = "vpc-deadbeef"
BAD_IGW = "igw-deadbeef" BAD_IGW = "igw-deadbeef"
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_create():
"""internet gateway create"""
conn = boto.connect_vpc("the_key", "the_secret")
conn.get_all_internet_gateways().should.have.length_of(0)
with pytest.raises(EC2ResponseError) as ex:
igw = conn.create_internet_gateway(dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the CreateInternetGateway operation: Request would have succeeded, but DryRun flag is set"
)
igw = conn.create_internet_gateway()
conn.get_all_internet_gateways().should.have.length_of(1)
igw.id.should.match(r"igw-[0-9a-f]+")
igw = conn.get_all_internet_gateways()[0]
igw.attachments.should.have.length_of(0)
@mock_ec2 @mock_ec2
def test_igw_create_boto3(): def test_igw_create_boto3():
""" internet gateway create """ """ internet gateway create """
@ -64,28 +38,6 @@ def test_igw_create_boto3():
igw["Attachments"].should.have.length_of(0) igw["Attachments"].should.have.length_of(0)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_attach():
"""internet gateway attach"""
conn = boto.connect_vpc("the_key", "the_secret")
igw = conn.create_internet_gateway()
vpc = conn.create_vpc(VPC_CIDR)
with pytest.raises(EC2ResponseError) as ex:
conn.attach_internet_gateway(igw.id, vpc.id, dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the AttachInternetGateway operation: Request would have succeeded, but DryRun flag is set"
)
conn.attach_internet_gateway(igw.id, vpc.id)
igw = conn.get_all_internet_gateways()[0]
igw.attachments[0].vpc_id.should.be.equal(vpc.id)
@mock_ec2 @mock_ec2
def test_igw_attach_boto3(): def test_igw_attach_boto3():
""" internet gateway attach """ """ internet gateway attach """
@ -111,20 +63,6 @@ def test_igw_attach_boto3():
igw["Attachments"].should.equal([{"State": "available", "VpcId": vpc.id}]) igw["Attachments"].should.equal([{"State": "available", "VpcId": vpc.id}])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_attach_bad_vpc():
"""internet gateway fail to attach w/ bad vpc"""
conn = boto.connect_vpc("the_key", "the_secret")
igw = conn.create_internet_gateway()
with pytest.raises(EC2ResponseError) as cm:
conn.attach_internet_gateway(igw.id, BAD_VPC)
cm.value.code.should.equal("InvalidVpcID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_igw_attach_bad_vpc_boto3(): def test_igw_attach_bad_vpc_boto3():
""" internet gateway fail to attach w/ bad vpc """ """ internet gateway fail to attach w/ bad vpc """
@ -138,23 +76,6 @@ def test_igw_attach_bad_vpc_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidVpcID.NotFound") ex.value.response["Error"]["Code"].should.equal("InvalidVpcID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_attach_twice():
"""internet gateway fail to attach twice"""
conn = boto.connect_vpc("the_key", "the_secret")
igw = conn.create_internet_gateway()
vpc1 = conn.create_vpc(VPC_CIDR)
vpc2 = conn.create_vpc(VPC_CIDR)
conn.attach_internet_gateway(igw.id, vpc1.id)
with pytest.raises(EC2ResponseError) as cm:
conn.attach_internet_gateway(igw.id, vpc2.id)
cm.value.code.should.equal("Resource.AlreadyAssociated")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_igw_attach_twice_boto3(): def test_igw_attach_twice_boto3():
""" internet gateway fail to attach twice """ """ internet gateway fail to attach twice """
@ -172,28 +93,6 @@ def test_igw_attach_twice_boto3():
ex.value.response["Error"]["Code"].should.equal("Resource.AlreadyAssociated") ex.value.response["Error"]["Code"].should.equal("Resource.AlreadyAssociated")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_detach():
"""internet gateway detach"""
conn = boto.connect_vpc("the_key", "the_secret")
igw = conn.create_internet_gateway()
vpc = conn.create_vpc(VPC_CIDR)
conn.attach_internet_gateway(igw.id, vpc.id)
with pytest.raises(EC2ResponseError) as ex:
conn.detach_internet_gateway(igw.id, vpc.id, dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the DetachInternetGateway operation: Request would have succeeded, but DryRun flag is set"
)
conn.detach_internet_gateway(igw.id, vpc.id)
igw = conn.get_all_internet_gateways()[0]
igw.attachments.should.have.length_of(0)
@mock_ec2 @mock_ec2
def test_igw_detach_boto3(): def test_igw_detach_boto3():
""" internet gateway detach""" """ internet gateway detach"""
@ -220,23 +119,6 @@ def test_igw_detach_boto3():
igw["Attachments"].should.have.length_of(0) igw["Attachments"].should.have.length_of(0)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_detach_wrong_vpc():
"""internet gateway fail to detach w/ wrong vpc"""
conn = boto.connect_vpc("the_key", "the_secret")
igw = conn.create_internet_gateway()
vpc1 = conn.create_vpc(VPC_CIDR)
vpc2 = conn.create_vpc(VPC_CIDR)
conn.attach_internet_gateway(igw.id, vpc1.id)
with pytest.raises(EC2ResponseError) as cm:
conn.detach_internet_gateway(igw.id, vpc2.id)
cm.value.code.should.equal("Gateway.NotAttached")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_igw_detach_wrong_vpc_boto3(): def test_igw_detach_wrong_vpc_boto3():
""" internet gateway fail to detach w/ wrong vpc """ """ internet gateway fail to detach w/ wrong vpc """
@ -254,22 +136,6 @@ def test_igw_detach_wrong_vpc_boto3():
ex.value.response["Error"]["Code"].should.equal("Gateway.NotAttached") ex.value.response["Error"]["Code"].should.equal("Gateway.NotAttached")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_detach_invalid_vpc():
"""internet gateway fail to detach w/ invalid vpc"""
conn = boto.connect_vpc("the_key", "the_secret")
igw = conn.create_internet_gateway()
vpc = conn.create_vpc(VPC_CIDR)
conn.attach_internet_gateway(igw.id, vpc.id)
with pytest.raises(EC2ResponseError) as cm:
conn.detach_internet_gateway(igw.id, BAD_VPC)
cm.value.code.should.equal("Gateway.NotAttached")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_igw_detach_invalid_vpc_boto3(): def test_igw_detach_invalid_vpc_boto3():
""" internet gateway fail to detach w/ invalid vpc """ """ internet gateway fail to detach w/ invalid vpc """
@ -286,21 +152,6 @@ def test_igw_detach_invalid_vpc_boto3():
ex.value.response["Error"]["Code"].should.equal("Gateway.NotAttached") ex.value.response["Error"]["Code"].should.equal("Gateway.NotAttached")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_detach_unattached():
"""internet gateway fail to detach unattached"""
conn = boto.connect_vpc("the_key", "the_secret")
igw = conn.create_internet_gateway()
vpc = conn.create_vpc(VPC_CIDR)
with pytest.raises(EC2ResponseError) as cm:
conn.detach_internet_gateway(igw.id, vpc.id)
cm.value.code.should.equal("Gateway.NotAttached")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_igw_detach_unattached_boto3(): def test_igw_detach_unattached_boto3():
""" internet gateway fail to detach unattached """ """ internet gateway fail to detach unattached """
@ -316,28 +167,6 @@ def test_igw_detach_unattached_boto3():
ex.value.response["Error"]["Code"].should.equal("Gateway.NotAttached") ex.value.response["Error"]["Code"].should.equal("Gateway.NotAttached")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_delete():
"""internet gateway delete"""
conn = boto.connect_vpc("the_key", "the_secret")
conn.create_vpc(VPC_CIDR)
conn.get_all_internet_gateways().should.have.length_of(0)
igw = conn.create_internet_gateway()
conn.get_all_internet_gateways().should.have.length_of(1)
with pytest.raises(EC2ResponseError) as ex:
conn.delete_internet_gateway(igw.id, dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the DeleteInternetGateway operation: Request would have succeeded, but DryRun flag is set"
)
conn.delete_internet_gateway(igw.id)
conn.get_all_internet_gateways().should.have.length_of(0)
@mock_ec2 @mock_ec2
def test_igw_delete_boto3(): def test_igw_delete_boto3():
""" internet gateway delete""" """ internet gateway delete"""
@ -360,22 +189,6 @@ def test_igw_delete_boto3():
[i["InternetGatewayId"] for i in (retrieve_all(client))].shouldnt.contain(igw.id) [i["InternetGatewayId"] for i in (retrieve_all(client))].shouldnt.contain(igw.id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_delete_attached():
"""internet gateway fail to delete attached"""
conn = boto.connect_vpc("the_key", "the_secret")
igw = conn.create_internet_gateway()
vpc = conn.create_vpc(VPC_CIDR)
conn.attach_internet_gateway(igw.id, vpc.id)
with pytest.raises(EC2ResponseError) as cm:
conn.delete_internet_gateway(igw.id)
cm.value.code.should.equal("DependencyViolation")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_igw_delete_attached_boto3(): def test_igw_delete_attached_boto3():
""" internet gateway fail to delete attached """ """ internet gateway fail to delete attached """
@ -392,16 +205,6 @@ def test_igw_delete_attached_boto3():
ex.value.response["Error"]["Code"].should.equal("DependencyViolation") ex.value.response["Error"]["Code"].should.equal("DependencyViolation")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_desribe():
"""internet gateway fetch by id"""
conn = boto.connect_vpc("the_key", "the_secret")
igw = conn.create_internet_gateway()
igw_by_search = conn.get_all_internet_gateways([igw.id])[0]
igw.id.should.equal(igw_by_search.id)
@mock_ec2 @mock_ec2
def test_igw_describe_boto3(): def test_igw_describe_boto3():
""" internet gateway fetch by id """ """ internet gateway fetch by id """
@ -414,18 +217,6 @@ def test_igw_describe_boto3():
igw.id.should.equal(igw_by_search["InternetGatewayId"]) igw.id.should.equal(igw_by_search["InternetGatewayId"])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_describe_bad_id():
"""internet gateway fail to fetch by bad id"""
conn = boto.connect_vpc("the_key", "the_secret")
with pytest.raises(EC2ResponseError) as cm:
conn.get_all_internet_gateways([BAD_IGW])
cm.value.code.should.equal("InvalidInternetGatewayID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_igw_describe_bad_id_boto3(): def test_igw_describe_bad_id_boto3():
""" internet gateway fail to fetch by bad id """ """ internet gateway fail to fetch by bad id """
@ -437,22 +228,6 @@ def test_igw_describe_bad_id_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidInternetGatewayID.NotFound") ex.value.response["Error"]["Code"].should.equal("InvalidInternetGatewayID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_filter_by_vpc_id():
"""internet gateway filter by vpc id"""
conn = boto.connect_vpc("the_key", "the_secret")
igw1 = conn.create_internet_gateway()
conn.create_internet_gateway()
vpc = conn.create_vpc(VPC_CIDR)
conn.attach_internet_gateway(igw1.id, vpc.id)
result = conn.get_all_internet_gateways(filters={"attachment.vpc-id": vpc.id})
result.should.have.length_of(1)
result[0].id.should.equal(igw1.id)
@mock_ec2 @mock_ec2
def test_igw_filter_by_vpc_id_boto3(): def test_igw_filter_by_vpc_id_boto3():
""" internet gateway filter by vpc id """ """ internet gateway filter by vpc id """
@ -471,21 +246,6 @@ def test_igw_filter_by_vpc_id_boto3():
result["InternetGateways"][0]["InternetGatewayId"].should.equal(igw1.id) result["InternetGateways"][0]["InternetGatewayId"].should.equal(igw1.id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_filter_by_tags():
"""internet gateway filter by vpc id"""
conn = boto.connect_vpc("the_key", "the_secret")
igw1 = conn.create_internet_gateway()
conn.create_internet_gateway()
igw1.add_tag("tests", "yes")
result = conn.get_all_internet_gateways(filters={"tag:tests": "yes"})
result.should.have.length_of(1)
result[0].id.should.equal(igw1.id)
@mock_ec2 @mock_ec2
def test_igw_filter_by_tags_boto3(): def test_igw_filter_by_tags_boto3():
""" internet gateway filter by vpc id """ """ internet gateway filter by vpc id """
@ -502,20 +262,6 @@ def test_igw_filter_by_tags_boto3():
result[0]["InternetGatewayId"].should.equal(igw1.id) result[0]["InternetGatewayId"].should.equal(igw1.id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_filter_by_internet_gateway_id():
"""internet gateway filter by internet gateway id"""
conn = boto.connect_vpc("the_key", "the_secret")
igw1 = conn.create_internet_gateway()
conn.create_internet_gateway()
result = conn.get_all_internet_gateways(filters={"internet-gateway-id": igw1.id})
result.should.have.length_of(1)
result[0].id.should.equal(igw1.id)
@mock_ec2 @mock_ec2
def test_igw_filter_by_internet_gateway_id_boto3(): def test_igw_filter_by_internet_gateway_id_boto3():
""" internet gateway filter by internet gateway id """ """ internet gateway filter by internet gateway id """
@ -532,22 +278,6 @@ def test_igw_filter_by_internet_gateway_id_boto3():
result["InternetGateways"][0]["InternetGatewayId"].should.equal(igw1.id) result["InternetGateways"][0]["InternetGatewayId"].should.equal(igw1.id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_filter_by_attachment_state():
"""internet gateway filter by attachment state"""
conn = boto.connect_vpc("the_key", "the_secret")
igw1 = conn.create_internet_gateway()
conn.create_internet_gateway()
vpc = conn.create_vpc(VPC_CIDR)
conn.attach_internet_gateway(igw1.id, vpc.id)
result = conn.get_all_internet_gateways(filters={"attachment.state": "available"})
result.should.have.length_of(1)
result[0].id.should.equal(igw1.id)
@mock_ec2 @mock_ec2
def test_igw_filter_by_attachment_state_boto3(): def test_igw_filter_by_attachment_state_boto3():
""" internet gateway filter by attachment state """ """ internet gateway filter by attachment state """

View File

@ -1,12 +1,10 @@
import pytest import pytest
import boto
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
import boto3 import boto3
from boto.exception import EC2ResponseError
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
from moto import mock_ec2, mock_ec2_deprecated, settings from moto import mock_ec2, settings
from uuid import uuid4 from uuid import uuid4
from unittest import SkipTest from unittest import SkipTest
@ -46,13 +44,6 @@ ffsm7UIHtCBYERr9Nx0u20ldfhkgB1lhaJb5o0ZJ3pmJ38KChfyHe5EUcqRdEFo89Mp72VI2Z6UHyL17
moto@github.com""" moto@github.com"""
# Has boto3 equivalent
@mock_ec2_deprecated
def test_key_pairs_empty():
conn = boto.connect_ec2("the_key", "the_secret")
assert len(conn.get_all_key_pairs()) == 0
@mock_ec2 @mock_ec2
def test_key_pairs_empty_boto3(): def test_key_pairs_empty_boto3():
if settings.TEST_SERVER_MODE: if settings.TEST_SERVER_MODE:
@ -61,18 +52,6 @@ def test_key_pairs_empty_boto3():
client.describe_key_pairs()["KeyPairs"].should.be.empty client.describe_key_pairs()["KeyPairs"].should.be.empty
# Has boto3 equivalent
@mock_ec2_deprecated
def test_key_pairs_invalid_id():
conn = boto.connect_ec2("the_key", "the_secret")
with pytest.raises(EC2ResponseError) as cm:
conn.get_all_key_pairs("foo")
cm.value.code.should.equal("InvalidKeyPair.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_key_pairs_invalid_id_boto3(): def test_key_pairs_invalid_id_boto3():
client = boto3.client("ec2", "us-west-1") client = boto3.client("ec2", "us-west-1")
@ -84,49 +63,6 @@ def test_key_pairs_invalid_id_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidKeyPair.NotFound") ex.value.response["Error"]["Code"].should.equal("InvalidKeyPair.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_key_pairs_create():
conn = boto.connect_ec2("the_key", "the_secret")
with pytest.raises(EC2ResponseError) as ex:
conn.create_key_pair("foo", dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the CreateKeyPair operation: Request would have succeeded, but DryRun flag is set"
)
kp = conn.create_key_pair("foo")
rsa_check_private_key(kp.material)
kps = conn.get_all_key_pairs()
assert len(kps) == 1
assert kps[0].name == "foo"
# Has boto3 equivalent
@mock_ec2_deprecated
def test_key_pairs_create_two():
conn = boto.connect_ec2("the_key", "the_secret")
kp1 = conn.create_key_pair("foo")
rsa_check_private_key(kp1.material)
kp2 = conn.create_key_pair("bar")
rsa_check_private_key(kp2.material)
assert kp1.material != kp2.material
kps = conn.get_all_key_pairs()
kps.should.have.length_of(2)
assert {i.name for i in kps} == {"foo", "bar"}
kps = conn.get_all_key_pairs("foo")
kps.should.have.length_of(1)
kps[0].name.should.equal("foo")
@mock_ec2 @mock_ec2
def test_key_pairs_create_dryrun_boto3(): def test_key_pairs_create_dryrun_boto3():
ec2 = boto3.resource("ec2", "us-west-1") ec2 = boto3.resource("ec2", "us-west-1")
@ -166,20 +102,6 @@ def test_key_pairs_create_boto3():
kps[0].should.have.key("KeyFingerprint") kps[0].should.have.key("KeyFingerprint")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_key_pairs_create_exist():
conn = boto.connect_ec2("the_key", "the_secret")
conn.create_key_pair("foo")
assert len(conn.get_all_key_pairs()) == 1
with pytest.raises(EC2ResponseError) as cm:
conn.create_key_pair("foo")
cm.value.code.should.equal("InvalidKeyPair.Duplicate")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_key_pairs_create_exist_boto3(): def test_key_pairs_create_exist_boto3():
client = boto3.client("ec2", "us-west-1") client = boto3.client("ec2", "us-west-1")
@ -193,40 +115,12 @@ def test_key_pairs_create_exist_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidKeyPair.Duplicate") ex.value.response["Error"]["Code"].should.equal("InvalidKeyPair.Duplicate")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_key_pairs_delete_no_exist():
conn = boto.connect_ec2("the_key", "the_secret")
assert len(conn.get_all_key_pairs()) == 0
r = conn.delete_key_pair("foo")
r.should.be.ok
@mock_ec2 @mock_ec2
def test_key_pairs_delete_no_exist_boto3(): def test_key_pairs_delete_no_exist_boto3():
client = boto3.client("ec2", "us-west-1") client = boto3.client("ec2", "us-west-1")
client.delete_key_pair(KeyName=str(uuid4())[0:6]) client.delete_key_pair(KeyName=str(uuid4())[0:6])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_key_pairs_delete_exist():
conn = boto.connect_ec2("the_key", "the_secret")
conn.create_key_pair("foo")
with pytest.raises(EC2ResponseError) as ex:
r = conn.delete_key_pair("foo", dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the DeleteKeyPair operation: Request would have succeeded, but DryRun flag is set"
)
r = conn.delete_key_pair("foo")
r.should.be.ok
assert len(conn.get_all_key_pairs()) == 0
@mock_ec2 @mock_ec2
def test_key_pairs_delete_exist_boto3(): def test_key_pairs_delete_exist_boto3():
client = boto3.client("ec2", "us-west-1") client = boto3.client("ec2", "us-west-1")
@ -247,33 +141,6 @@ def test_key_pairs_delete_exist_boto3():
) )
# Has boto3 equivalent
@mock_ec2_deprecated
def test_key_pairs_import():
conn = boto.connect_ec2("the_key", "the_secret")
with pytest.raises(EC2ResponseError) as ex:
conn.import_key_pair("foo", RSA_PUBLIC_KEY_OPENSSH, dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the ImportKeyPair operation: Request would have succeeded, but DryRun flag is set"
)
kp1 = conn.import_key_pair("foo", RSA_PUBLIC_KEY_OPENSSH)
assert kp1.name == "foo"
assert kp1.fingerprint == RSA_PUBLIC_KEY_FINGERPRINT
kp2 = conn.import_key_pair("foo2", RSA_PUBLIC_KEY_RFC4716)
assert kp2.name == "foo2"
assert kp2.fingerprint == RSA_PUBLIC_KEY_FINGERPRINT
kps = conn.get_all_key_pairs()
assert len(kps) == 2
assert kps[0].name == kp1.name
assert kps[1].name == kp2.name
@mock_ec2 @mock_ec2
def test_key_pairs_import_boto3(): def test_key_pairs_import_boto3():
client = boto3.client("ec2", "us-west-1") client = boto3.client("ec2", "us-west-1")
@ -309,21 +176,6 @@ def test_key_pairs_import_boto3():
all_names.should.contain(kp2["KeyName"]) all_names.should.contain(kp2["KeyName"])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_key_pairs_import_exist():
conn = boto.connect_ec2("the_key", "the_secret")
kp = conn.import_key_pair("foo", RSA_PUBLIC_KEY_OPENSSH)
assert kp.name == "foo"
assert len(conn.get_all_key_pairs()) == 1
with pytest.raises(EC2ResponseError) as cm:
conn.create_key_pair("foo")
cm.value.code.should.equal("InvalidKeyPair.Duplicate")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_key_pairs_import_exist_boto3(): def test_key_pairs_import_exist_boto3():
client = boto3.client("ec2", "us-west-1") client = boto3.client("ec2", "us-west-1")
@ -343,30 +195,6 @@ def test_key_pairs_import_exist_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidKeyPair.Duplicate") ex.value.response["Error"]["Code"].should.equal("InvalidKeyPair.Duplicate")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_key_pairs_invalid():
conn = boto.connect_ec2("the_key", "the_secret")
with pytest.raises(EC2ResponseError) as ex:
conn.import_key_pair("foo", b"")
ex.value.error_code.should.equal("InvalidKeyPair.Format")
ex.value.status.should.equal(400)
ex.value.message.should.equal("Key is not in valid OpenSSH public key format")
with pytest.raises(EC2ResponseError) as ex:
conn.import_key_pair("foo", b"garbage")
ex.value.error_code.should.equal("InvalidKeyPair.Format")
ex.value.status.should.equal(400)
ex.value.message.should.equal("Key is not in valid OpenSSH public key format")
with pytest.raises(EC2ResponseError) as ex:
conn.import_key_pair("foo", DSA_PUBLIC_KEY_OPENSSH)
ex.value.error_code.should.equal("InvalidKeyPair.Format")
ex.value.status.should.equal(400)
ex.value.message.should.equal("Key is not in valid OpenSSH public key format")
@mock_ec2 @mock_ec2
def test_key_pairs_invalid_boto3(): def test_key_pairs_invalid_boto3():
client = boto3.client("ec2", "us-west-1") client = boto3.client("ec2", "us-west-1")
@ -393,22 +221,6 @@ def test_key_pairs_invalid_boto3():
err["Message"].should.equal("Key is not in valid OpenSSH public key format") err["Message"].should.equal("Key is not in valid OpenSSH public key format")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_key_pair_filters():
conn = boto.connect_ec2("the_key", "the_secret")
_ = conn.create_key_pair("kpfltr1")
kp2 = conn.create_key_pair("kpfltr2")
kp3 = conn.create_key_pair("kpfltr3")
kp_by_name = conn.get_all_key_pairs(filters={"key-name": "kpfltr2"})
set([kp.name for kp in kp_by_name]).should.equal(set([kp2.name]))
kp_by_name = conn.get_all_key_pairs(filters={"fingerprint": kp3.fingerprint})
set([kp.name for kp in kp_by_name]).should.equal(set([kp3.name]))
@mock_ec2 @mock_ec2
def test_key_pair_filters_boto3(): def test_key_pair_filters_boto3():
ec2 = boto3.resource("ec2", "us-west-1") ec2 = boto3.resource("ec2", "us-west-1")

View File

@ -1,24 +1,14 @@
import boto
import boto3 import boto3
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
import pytest import pytest
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
from moto import mock_ec2_deprecated, mock_ec2, settings from moto import mock_ec2, settings
from moto.ec2.models import OWNER_ID from moto.ec2.models import OWNER_ID
from random import randint from random import randint
from unittest import SkipTest from unittest import SkipTest
# Has boto3 equivalent
@mock_ec2_deprecated
def test_default_network_acl_created_with_vpc():
conn = boto.connect_vpc("the_key", "the secret")
conn.create_vpc("10.0.0.0/16")
all_network_acls = conn.get_all_network_acls()
all_network_acls.should.have.length_of(2)
@mock_ec2 @mock_ec2
def test_default_network_acl_created_with_vpc_boto3(): def test_default_network_acl_created_with_vpc_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -31,16 +21,6 @@ def test_default_network_acl_created_with_vpc_boto3():
our_acl[0].should.have.key("IsDefault").equals(True) our_acl[0].should.have.key("IsDefault").equals(True)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_network_acls():
conn = boto.connect_vpc("the_key", "the secret")
vpc = conn.create_vpc("10.0.0.0/16")
conn.create_network_acl(vpc.id)
all_network_acls = conn.get_all_network_acls()
all_network_acls.should.have.length_of(3)
@mock_ec2 @mock_ec2
def test_network_create_and_list_acls_boto3(): def test_network_create_and_list_acls_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -58,21 +38,6 @@ def test_network_create_and_list_acls_boto3():
acl_found["IsDefault"].should.equal(False) acl_found["IsDefault"].should.equal(False)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_new_subnet_associates_with_default_network_acl():
conn = boto.connect_vpc("the_key", "the secret")
vpc = conn.get_all_vpcs()[0]
subnet = conn.create_subnet(vpc.id, "172.31.112.0/20")
all_network_acls = conn.get_all_network_acls()
all_network_acls.should.have.length_of(1)
acl = all_network_acls[0]
acl.associations.should.have.length_of(7)
[a.subnet_id for a in acl.associations].should.contain(subnet.id)
@mock_ec2 @mock_ec2
def test_new_subnet_associates_with_default_network_acl_boto3(): def test_new_subnet_associates_with_default_network_acl_boto3():
if settings.TEST_SERVER_MODE: if settings.TEST_SERVER_MODE:
@ -90,36 +55,6 @@ def test_new_subnet_associates_with_default_network_acl_boto3():
[a["SubnetId"] for a in acl["Associations"]].should.contain(subnet.id) [a["SubnetId"] for a in acl["Associations"]].should.contain(subnet.id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_network_acl_entries():
conn = boto.connect_vpc("the_key", "the secret")
vpc = conn.create_vpc("10.0.0.0/16")
network_acl = conn.create_network_acl(vpc.id)
conn.create_network_acl_entry(
network_acl.id,
110,
6,
"ALLOW",
"0.0.0.0/0",
False,
port_range_from="443",
port_range_to="443",
)
all_network_acls = conn.get_all_network_acls()
all_network_acls.should.have.length_of(3)
test_network_acl = next(na for na in all_network_acls if na.id == network_acl.id)
entries = test_network_acl.network_acl_entries
entries.should.have.length_of(1)
entries[0].rule_number.should.equal("110")
entries[0].protocol.should.equal("6")
entries[0].rule_action.should.equal("ALLOW")
@mock_ec2 @mock_ec2
def test_network_acl_entries_boto3(): def test_network_acl_entries_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -155,33 +90,6 @@ def test_network_acl_entries_boto3():
entries[0]["CidrBlock"].should.equal("0.0.0.0/0") entries[0]["CidrBlock"].should.equal("0.0.0.0/0")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_delete_network_acl_entry():
conn = boto.connect_vpc("the_key", "the secret")
vpc = conn.create_vpc("10.0.0.0/16")
network_acl = conn.create_network_acl(vpc.id)
conn.create_network_acl_entry(
network_acl.id,
110,
6,
"ALLOW",
"0.0.0.0/0",
False,
port_range_from="443",
port_range_to="443",
)
conn.delete_network_acl_entry(network_acl.id, 110, False)
all_network_acls = conn.get_all_network_acls()
test_network_acl = next(na for na in all_network_acls if na.id == network_acl.id)
entries = test_network_acl.network_acl_entries
entries.should.have.length_of(0)
@mock_ec2 @mock_ec2
def test_delete_network_acl_entry_boto3(): def test_delete_network_acl_entry_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -211,45 +119,6 @@ def test_delete_network_acl_entry_boto3():
test_network_acl["Entries"].should.have.length_of(0) test_network_acl["Entries"].should.have.length_of(0)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_replace_network_acl_entry():
conn = boto.connect_vpc("the_key", "the secret")
vpc = conn.create_vpc("10.0.0.0/16")
network_acl = conn.create_network_acl(vpc.id)
conn.create_network_acl_entry(
network_acl.id,
110,
6,
"ALLOW",
"0.0.0.0/0",
False,
port_range_from="443",
port_range_to="443",
)
conn.replace_network_acl_entry(
network_acl.id,
110,
-1,
"DENY",
"0.0.0.0/0",
False,
port_range_from="22",
port_range_to="22",
)
all_network_acls = conn.get_all_network_acls()
test_network_acl = next(na for na in all_network_acls if na.id == network_acl.id)
entries = test_network_acl.network_acl_entries
entries.should.have.length_of(1)
entries[0].rule_number.should.equal("110")
entries[0].protocol.should.equal("-1")
entries[0].rule_action.should.equal("DENY")
@mock_ec2 @mock_ec2
def test_replace_network_acl_entry_boto3(): def test_replace_network_acl_entry_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -290,46 +159,6 @@ def test_replace_network_acl_entry_boto3():
entries[0]["PortRange"].should.equal({"To": 22, "From": 22}) entries[0]["PortRange"].should.equal({"To": 22, "From": 22})
# TODO: How to convert 'associate_network_acl' to boto3?
@mock_ec2_deprecated
def test_associate_new_network_acl_with_subnet():
conn = boto.connect_vpc("the_key", "the secret")
vpc = conn.create_vpc("10.0.0.0/16")
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
network_acl = conn.create_network_acl(vpc.id)
conn.associate_network_acl(network_acl.id, subnet.id)
all_network_acls = conn.get_all_network_acls()
all_network_acls.should.have.length_of(3)
test_network_acl = next(na for na in all_network_acls if na.id == network_acl.id)
test_network_acl.associations.should.have.length_of(1)
test_network_acl.associations[0].subnet_id.should.equal(subnet.id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_delete_network_acl():
conn = boto.connect_vpc("the_key", "the secret")
vpc = conn.create_vpc("10.0.0.0/16")
conn.create_subnet(vpc.id, "10.0.0.0/18")
network_acl = conn.create_network_acl(vpc.id)
all_network_acls = conn.get_all_network_acls()
all_network_acls.should.have.length_of(3)
any(acl.id == network_acl.id for acl in all_network_acls).should.be.ok
conn.delete_network_acl(network_acl.id)
updated_network_acls = conn.get_all_network_acls()
updated_network_acls.should.have.length_of(2)
any(acl.id == network_acl.id for acl in updated_network_acls).shouldnt.be.ok
@mock_ec2 @mock_ec2
def test_delete_network_acl_boto3(): def test_delete_network_acl_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -350,25 +179,6 @@ def test_delete_network_acl_boto3():
).shouldnt.be.ok ).shouldnt.be.ok
# Has boto3 equivalent
@mock_ec2_deprecated
def test_network_acl_tagging():
conn = boto.connect_vpc("the_key", "the secret")
vpc = conn.create_vpc("10.0.0.0/16")
network_acl = conn.create_network_acl(vpc.id)
network_acl.add_tag("a key", "some value")
tag = conn.get_all_tags()[0]
tag.name.should.equal("a key")
tag.value.should.equal("some value")
all_network_acls = conn.get_all_network_acls()
test_network_acl = next(na for na in all_network_acls if na.id == network_acl.id)
test_network_acl.tags.should.have.length_of(1)
test_network_acl.tags["a key"].should.equal("some value")
@mock_ec2 @mock_ec2
def test_network_acl_tagging_boto3(): def test_network_acl_tagging_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")

View File

@ -1,46 +1,20 @@
import boto.ec2
import boto.ec2.autoscale
import boto.ec2.elb
import boto3 import boto3
import pytest import pytest
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
from moto import mock_ec2_deprecated, mock_autoscaling_deprecated, mock_elb_deprecated
from moto import mock_autoscaling, mock_ec2, mock_elb from moto import mock_autoscaling, mock_ec2, mock_elb
from moto.ec2 import ec2_backends
from tests import EXAMPLE_AMI_ID, EXAMPLE_AMI_ID2 from tests import EXAMPLE_AMI_ID, EXAMPLE_AMI_ID2
from uuid import uuid4 from uuid import uuid4
from .test_instances import retrieve_all_instances from .test_instances import retrieve_all_instances
def add_servers_to_region(ami_id, count, region):
conn = boto.ec2.connect_to_region(region)
for _ in range(count):
conn.run_instances(ami_id)
def add_servers_to_region_boto3(ami_id, count, region): def add_servers_to_region_boto3(ami_id, count, region):
ec2 = boto3.resource("ec2", region_name=region) ec2 = boto3.resource("ec2", region_name=region)
return ec2.create_instances(ImageId=ami_id, MinCount=count, MaxCount=count) return ec2.create_instances(ImageId=ami_id, MinCount=count, MaxCount=count)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_add_servers_to_a_single_region():
region = "ap-northeast-1"
add_servers_to_region(EXAMPLE_AMI_ID, 1, region)
add_servers_to_region(EXAMPLE_AMI_ID2, 1, region)
conn = boto.ec2.connect_to_region(region)
reservations = conn.get_all_reservations()
len(reservations).should.equal(2)
image_ids = [r.instances[0].image_id for r in reservations]
image_ids.should.equal([EXAMPLE_AMI_ID, EXAMPLE_AMI_ID2])
@mock_ec2 @mock_ec2
def test_add_servers_to_a_single_region_boto3(): def test_add_servers_to_a_single_region_boto3():
region = "ap-northeast-1" region = "ap-northeast-1"
@ -56,26 +30,6 @@ def test_add_servers_to_a_single_region_boto3():
instance2["ImageId"].should.equal(EXAMPLE_AMI_ID2) instance2["ImageId"].should.equal(EXAMPLE_AMI_ID2)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_add_servers_to_multiple_regions():
region1 = "us-east-1"
region2 = "ap-northeast-1"
add_servers_to_region(EXAMPLE_AMI_ID, 1, region1)
add_servers_to_region(EXAMPLE_AMI_ID2, 1, region2)
us_conn = boto.ec2.connect_to_region(region1)
ap_conn = boto.ec2.connect_to_region(region2)
us_reservations = us_conn.get_all_reservations()
ap_reservations = ap_conn.get_all_reservations()
len(us_reservations).should.equal(1)
len(ap_reservations).should.equal(1)
us_reservations[0].instances[0].image_id.should.equal(EXAMPLE_AMI_ID)
ap_reservations[0].instances[0].image_id.should.equal(EXAMPLE_AMI_ID2)
@mock_ec2 @mock_ec2
def test_add_servers_to_multiple_regions_boto3(): def test_add_servers_to_multiple_regions_boto3():
region1 = "us-east-1" region1 = "us-east-1"
@ -103,107 +57,6 @@ def test_add_servers_to_multiple_regions_boto3():
ap_instance["ImageId"].should.equal(EXAMPLE_AMI_ID2) ap_instance["ImageId"].should.equal(EXAMPLE_AMI_ID2)
# Has boto3 equivalent
@mock_autoscaling_deprecated
@mock_elb_deprecated
def test_create_autoscaling_group():
elb_conn = boto.ec2.elb.connect_to_region("us-east-1")
elb_conn.create_load_balancer(
"us_test_lb", zones=[], listeners=[(80, 8080, "http")]
)
elb_conn = boto.ec2.elb.connect_to_region("ap-northeast-1")
elb_conn.create_load_balancer(
"ap_test_lb", zones=[], listeners=[(80, 8080, "http")]
)
us_conn = boto.ec2.autoscale.connect_to_region("us-east-1")
config = boto.ec2.autoscale.LaunchConfiguration(
name="us_tester", image_id=EXAMPLE_AMI_ID, instance_type="m1.small"
)
us_conn.create_launch_configuration(config)
us_subnet_id = list(ec2_backends["us-east-1"].subnets["us-east-1c"].keys())[0]
ap_subnet_id = list(
ec2_backends["ap-northeast-1"].subnets["ap-northeast-1a"].keys()
)[0]
group = boto.ec2.autoscale.AutoScalingGroup(
name="us_tester_group",
availability_zones=["us-east-1c"],
default_cooldown=60,
desired_capacity=2,
health_check_period=100,
health_check_type="EC2",
max_size=2,
min_size=2,
launch_config=config,
load_balancers=["us_test_lb"],
placement_group="us_test_placement",
vpc_zone_identifier=us_subnet_id,
termination_policies=["OldestInstance", "NewestInstance"],
)
us_conn.create_auto_scaling_group(group)
ap_conn = boto.ec2.autoscale.connect_to_region("ap-northeast-1")
config = boto.ec2.autoscale.LaunchConfiguration(
name="ap_tester", image_id=EXAMPLE_AMI_ID, instance_type="m1.small"
)
ap_conn.create_launch_configuration(config)
group = boto.ec2.autoscale.AutoScalingGroup(
name="ap_tester_group",
availability_zones=["ap-northeast-1a"],
default_cooldown=60,
desired_capacity=2,
health_check_period=100,
health_check_type="EC2",
max_size=2,
min_size=2,
launch_config=config,
load_balancers=["ap_test_lb"],
placement_group="ap_test_placement",
vpc_zone_identifier=ap_subnet_id,
termination_policies=["OldestInstance", "NewestInstance"],
)
ap_conn.create_auto_scaling_group(group)
len(us_conn.get_all_groups()).should.equal(1)
len(ap_conn.get_all_groups()).should.equal(1)
us_group = us_conn.get_all_groups()[0]
us_group.name.should.equal("us_tester_group")
list(us_group.availability_zones).should.equal(["us-east-1c"])
us_group.desired_capacity.should.equal(2)
us_group.max_size.should.equal(2)
us_group.min_size.should.equal(2)
us_group.vpc_zone_identifier.should.equal(us_subnet_id)
us_group.launch_config_name.should.equal("us_tester")
us_group.default_cooldown.should.equal(60)
us_group.health_check_period.should.equal(100)
us_group.health_check_type.should.equal("EC2")
list(us_group.load_balancers).should.equal(["us_test_lb"])
us_group.placement_group.should.equal("us_test_placement")
list(us_group.termination_policies).should.equal(
["OldestInstance", "NewestInstance"]
)
ap_group = ap_conn.get_all_groups()[0]
ap_group.name.should.equal("ap_tester_group")
list(ap_group.availability_zones).should.equal(["ap-northeast-1a"])
ap_group.desired_capacity.should.equal(2)
ap_group.max_size.should.equal(2)
ap_group.min_size.should.equal(2)
ap_group.vpc_zone_identifier.should.equal(ap_subnet_id)
ap_group.launch_config_name.should.equal("ap_tester")
ap_group.default_cooldown.should.equal(60)
ap_group.health_check_period.should.equal(100)
ap_group.health_check_type.should.equal("EC2")
list(ap_group.load_balancers).should.equal(["ap_test_lb"])
ap_group.placement_group.should.equal("ap_test_placement")
list(ap_group.termination_policies).should.equal(
["OldestInstance", "NewestInstance"]
)
@mock_autoscaling @mock_autoscaling
@mock_elb @mock_elb
@mock_ec2 @mock_ec2

View File

@ -1,43 +1,14 @@
import pytest import pytest
import boto
import boto3 import boto3
from boto.exception import EC2ResponseError
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
from moto import mock_ec2, mock_ec2_deprecated, settings from moto import mock_ec2, settings
from tests import EXAMPLE_AMI_ID from tests import EXAMPLE_AMI_ID
from tests.helpers import requires_boto_gte
from uuid import uuid4 from uuid import uuid4
# Has boto3 equivalent
@mock_ec2_deprecated
def test_route_tables_defaults():
conn = boto.connect_vpc("the_key", "the_secret")
vpc = conn.create_vpc("10.0.0.0/16")
all_route_tables = conn.get_all_route_tables(filters={"vpc-id": vpc.id})
all_route_tables.should.have.length_of(1)
main_route_table = all_route_tables[0]
main_route_table.vpc_id.should.equal(vpc.id)
routes = main_route_table.routes
routes.should.have.length_of(1)
local_route = routes[0]
local_route.gateway_id.should.equal("local")
local_route.state.should.equal("active")
local_route.destination_cidr_block.should.equal(vpc.cidr_block)
vpc.delete()
all_route_tables = conn.get_all_route_tables(filters={"vpc-id": vpc.id})
all_route_tables.should.have.length_of(0)
@mock_ec2 @mock_ec2
def test_route_tables_defaults_boto3(): def test_route_tables_defaults_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -68,47 +39,6 @@ def test_route_tables_defaults_boto3():
all_route_tables.should.have.length_of(0) all_route_tables.should.have.length_of(0)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_route_tables_additional():
conn = boto.connect_vpc("the_key", "the_secret")
vpc = conn.create_vpc("10.0.0.0/16")
route_table = conn.create_route_table(vpc.id)
all_route_tables = conn.get_all_route_tables(filters={"vpc-id": vpc.id})
all_route_tables.should.have.length_of(2)
all_route_tables[0].vpc_id.should.equal(vpc.id)
all_route_tables[1].vpc_id.should.equal(vpc.id)
all_route_table_ids = [route_table.id for route_table in all_route_tables]
all_route_table_ids.should.contain(route_table.id)
routes = route_table.routes
routes.should.have.length_of(1)
local_route = routes[0]
local_route.gateway_id.should.equal("local")
local_route.state.should.equal("active")
local_route.destination_cidr_block.should.equal(vpc.cidr_block)
with pytest.raises(EC2ResponseError) as cm:
conn.delete_vpc(vpc.id)
cm.value.code.should.equal("DependencyViolation")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
conn.delete_route_table(route_table.id)
all_route_tables = conn.get_all_route_tables(filters={"vpc-id": vpc.id})
all_route_tables.should.have.length_of(1)
with pytest.raises(EC2ResponseError) as cm:
conn.delete_route_table("rtb-1234abcd")
cm.value.code.should.equal("InvalidRouteTableID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_route_tables_additional_boto3(): def test_route_tables_additional_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -154,51 +84,6 @@ def test_route_tables_additional_boto3():
ex.value.response["ResponseMetadata"].should.have.key("RequestId") ex.value.response["ResponseMetadata"].should.have.key("RequestId")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_route_tables_filters_standard():
conn = boto.connect_vpc("the_key", "the_secret")
vpc1 = conn.create_vpc("10.0.0.0/16")
route_table1 = conn.create_route_table(vpc1.id)
vpc2 = conn.create_vpc("10.0.0.0/16")
route_table2 = conn.create_route_table(vpc2.id)
all_route_tables = conn.get_all_route_tables()
all_route_tables.should.have.length_of(5)
# Filter by main route table
main_route_tables = conn.get_all_route_tables(filters={"association.main": "true"})
main_route_tables.should.have.length_of(3)
main_route_table_ids = [route_table.id for route_table in main_route_tables]
main_route_table_ids.should_not.contain(route_table1.id)
main_route_table_ids.should_not.contain(route_table2.id)
# Filter by VPC
vpc1_route_tables = conn.get_all_route_tables(filters={"vpc-id": vpc1.id})
vpc1_route_tables.should.have.length_of(2)
vpc1_route_table_ids = [route_table.id for route_table in vpc1_route_tables]
vpc1_route_table_ids.should.contain(route_table1.id)
vpc1_route_table_ids.should_not.contain(route_table2.id)
# Filter by VPC and main route table
vpc2_main_route_tables = conn.get_all_route_tables(
filters={"association.main": "true", "vpc-id": vpc2.id}
)
vpc2_main_route_tables.should.have.length_of(1)
vpc2_main_route_table_ids = [
route_table.id for route_table in vpc2_main_route_tables
]
vpc2_main_route_table_ids.should_not.contain(route_table1.id)
vpc2_main_route_table_ids.should_not.contain(route_table2.id)
# Unsupported filter
conn.get_all_route_tables.when.called_with(
filters={"not-implemented-filter": "foobar"}
).should.throw(NotImplementedError)
@mock_ec2 @mock_ec2
def test_route_tables_filters_standard_boto3(): def test_route_tables_filters_standard_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -259,50 +144,6 @@ def test_route_tables_filters_standard_boto3():
) )
# Has boto3 equivalent
@mock_ec2_deprecated
def test_route_tables_filters_associations():
conn = boto.connect_vpc("the_key", "the_secret")
vpc = conn.create_vpc("10.0.0.0/16")
subnet1 = conn.create_subnet(vpc.id, "10.0.0.0/24")
subnet2 = conn.create_subnet(vpc.id, "10.0.1.0/24")
subnet3 = conn.create_subnet(vpc.id, "10.0.2.0/24")
route_table1 = conn.create_route_table(vpc.id)
route_table2 = conn.create_route_table(vpc.id)
association_id1 = conn.associate_route_table(route_table1.id, subnet1.id)
conn.associate_route_table(route_table1.id, subnet2.id)
conn.associate_route_table(route_table2.id, subnet3.id)
all_route_tables = conn.get_all_route_tables()
all_route_tables.should.have.length_of(4)
# Filter by association ID
association1_route_tables = conn.get_all_route_tables(
filters={"association.route-table-association-id": association_id1}
)
association1_route_tables.should.have.length_of(1)
association1_route_tables[0].id.should.equal(route_table1.id)
association1_route_tables[0].associations.should.have.length_of(3)
# Filter by route table ID
route_table2_route_tables = conn.get_all_route_tables(
filters={"association.route-table-id": route_table2.id}
)
route_table2_route_tables.should.have.length_of(1)
route_table2_route_tables[0].id.should.equal(route_table2.id)
route_table2_route_tables[0].associations.should.have.length_of(2)
# Filter by subnet ID
subnet_route_tables = conn.get_all_route_tables(
filters={"association.subnet-id": subnet1.id}
)
subnet_route_tables.should.have.length_of(1)
subnet_route_tables[0].id.should.equal(route_table1.id)
association1_route_tables[0].associations.should.have.length_of(3)
@mock_ec2 @mock_ec2
def test_route_tables_filters_associations_boto3(): def test_route_tables_filters_associations_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -351,73 +192,6 @@ def test_route_tables_filters_associations_boto3():
subnet_route_tables[0]["Associations"].should.have.length_of(3) subnet_route_tables[0]["Associations"].should.have.length_of(3)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_route_table_associations():
conn = boto.connect_vpc("the_key", "the_secret")
vpc = conn.create_vpc("10.0.0.0/16")
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
route_table = conn.create_route_table(vpc.id)
all_route_tables = conn.get_all_route_tables()
all_route_tables.should.have.length_of(3)
# Refresh
route_table = conn.get_all_route_tables(route_table.id)[0]
route_table.associations.should.have.length_of(1)
# Associate
association_id = conn.associate_route_table(route_table.id, subnet.id)
# Refresh
route_table = conn.get_all_route_tables(route_table.id)[0]
route_table.associations.should.have.length_of(2)
route_table.associations[1].id.should.equal(association_id)
route_table.associations[1].main.should.equal(False)
route_table.associations[1].route_table_id.should.equal(route_table.id)
route_table.associations[1].subnet_id.should.equal(subnet.id)
# Associate is idempotent
association_id_idempotent = conn.associate_route_table(route_table.id, subnet.id)
association_id_idempotent.should.equal(association_id)
# Error: Attempt delete associated route table.
with pytest.raises(EC2ResponseError) as cm:
conn.delete_route_table(route_table.id)
cm.value.code.should.equal("DependencyViolation")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
# Disassociate
conn.disassociate_route_table(association_id)
# Refresh
route_table = conn.get_all_route_tables(route_table.id)[0]
route_table.associations.should.have.length_of(1)
# Error: Disassociate with invalid association ID
with pytest.raises(EC2ResponseError) as cm:
conn.disassociate_route_table(association_id)
cm.value.code.should.equal("InvalidAssociationID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
# Error: Associate with invalid subnet ID
with pytest.raises(EC2ResponseError) as cm:
conn.associate_route_table(route_table.id, "subnet-1234abcd")
cm.value.code.should.equal("InvalidSubnetID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
# Error: Associate with invalid route table ID
with pytest.raises(EC2ResponseError) as cm:
conn.associate_route_table("rtb-1234abcd", subnet.id)
cm.value.code.should.equal("InvalidRouteTableID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_route_table_associations_boto3(): def test_route_table_associations_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -497,84 +271,6 @@ def test_route_table_associations_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidRouteTableID.NotFound") ex.value.response["Error"]["Code"].should.equal("InvalidRouteTableID.NotFound")
# Has boto3 equivalent
@requires_boto_gte("2.16.0")
@mock_ec2_deprecated
def test_route_table_replace_route_table_association():
"""
Note: Boto has deprecated replace_route_table_association (which returns status)
and now uses replace_route_table_association_with_assoc (which returns association ID).
"""
conn = boto.connect_vpc("the_key", "the_secret")
vpc = conn.create_vpc("10.0.0.0/16")
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
route_table1 = conn.create_route_table(vpc.id)
route_table2 = conn.create_route_table(vpc.id)
all_route_tables = conn.get_all_route_tables()
all_route_tables.should.have.length_of(4)
# Refresh
route_table1 = conn.get_all_route_tables(route_table1.id)[0]
route_table1.associations.should.have.length_of(1)
# Associate
association_id1 = conn.associate_route_table(route_table1.id, subnet.id)
# Refresh
route_table1 = conn.get_all_route_tables(route_table1.id)[0]
route_table2 = conn.get_all_route_tables(route_table2.id)[0]
# Validate
route_table1.associations.should.have.length_of(2)
route_table2.associations.should.have.length_of(1)
route_table1.associations[1].id.should.equal(association_id1)
route_table1.associations[1].main.should.equal(False)
route_table1.associations[1].route_table_id.should.equal(route_table1.id)
route_table1.associations[1].subnet_id.should.equal(subnet.id)
# Replace Association
association_id2 = conn.replace_route_table_association_with_assoc(
association_id1, route_table2.id
)
# Refresh
route_table1 = conn.get_all_route_tables(route_table1.id)[0]
route_table2 = conn.get_all_route_tables(route_table2.id)[0]
# Validate
route_table1.associations.should.have.length_of(1)
route_table2.associations.should.have.length_of(2)
route_table2.associations[1].id.should.equal(association_id2)
route_table2.associations[1].main.should.equal(False)
route_table2.associations[1].route_table_id.should.equal(route_table2.id)
route_table2.associations[1].subnet_id.should.equal(subnet.id)
# Replace Association is idempotent
association_id_idempotent = conn.replace_route_table_association_with_assoc(
association_id2, route_table2.id
)
association_id_idempotent.should.equal(association_id2)
# Error: Replace association with invalid association ID
with pytest.raises(EC2ResponseError) as cm:
conn.replace_route_table_association_with_assoc(
"rtbassoc-1234abcd", route_table1.id
)
cm.value.code.should.equal("InvalidAssociationID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
# Error: Replace association with invalid route table ID
with pytest.raises(EC2ResponseError) as cm:
conn.replace_route_table_association_with_assoc(association_id2, "rtb-1234abcd")
cm.value.code.should.equal("InvalidRouteTableID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_route_table_replace_route_table_association_boto3(): def test_route_table_replace_route_table_association_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -669,25 +365,6 @@ def test_route_table_replace_route_table_association_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidRouteTableID.NotFound") ex.value.response["Error"]["Code"].should.equal("InvalidRouteTableID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_route_table_get_by_tag():
conn = boto.connect_vpc("the_key", "the_secret")
vpc = conn.create_vpc("10.0.0.0/16")
route_table = conn.create_route_table(vpc.id)
route_table.add_tag("Name", "TestRouteTable")
route_tables = conn.get_all_route_tables(filters={"tag:Name": "TestRouteTable"})
route_tables.should.have.length_of(1)
route_tables[0].vpc_id.should.equal(vpc.id)
route_tables[0].id.should.equal(route_table.id)
route_tables[0].tags.should.have.length_of(1)
route_tables[0].tags["Name"].should.equal("TestRouteTable")
@mock_ec2 @mock_ec2
def test_route_table_get_by_tag_boto3(): def test_route_table_get_by_tag_boto3():
ec2 = boto3.resource("ec2", region_name="eu-central-1") ec2 = boto3.resource("ec2", region_name="eu-central-1")
@ -708,57 +385,6 @@ def test_route_table_get_by_tag_boto3():
route_tables[0].tags[0].should.equal({"Key": "Name", "Value": tag_value}) route_tables[0].tags[0].should.equal({"Key": "Name", "Value": tag_value})
# Has boto3 equivalent
@mock_ec2_deprecated
def test_routes_additional():
conn = boto.connect_vpc("the_key", "the_secret")
vpc = conn.create_vpc("10.0.0.0/16")
main_route_table = conn.get_all_route_tables(filters={"vpc-id": vpc.id})[0]
igw = conn.create_internet_gateway()
ROUTE_CIDR = "10.0.0.4/24"
conn.create_route(main_route_table.id, ROUTE_CIDR, gateway_id=igw.id)
main_route_table = conn.get_all_route_tables(filters={"vpc-id": vpc.id})[
0
] # Refresh route table
main_route_table.routes.should.have.length_of(2)
new_routes = [
route
for route in main_route_table.routes
if route.destination_cidr_block != vpc.cidr_block
]
new_routes.should.have.length_of(1)
new_route = new_routes[0]
new_route.gateway_id.should.equal(igw.id)
new_route.instance_id.should.be.none
new_route.state.should.equal("active")
new_route.destination_cidr_block.should.equal(ROUTE_CIDR)
conn.delete_route(main_route_table.id, ROUTE_CIDR)
main_route_table = conn.get_all_route_tables(filters={"vpc-id": vpc.id})[
0
] # Refresh route table
main_route_table.routes.should.have.length_of(1)
new_routes = [
route
for route in main_route_table.routes
if route.destination_cidr_block != vpc.cidr_block
]
new_routes.should.have.length_of(0)
with pytest.raises(EC2ResponseError) as cm:
conn.delete_route(main_route_table.id, ROUTE_CIDR)
cm.value.code.should.equal("InvalidRoute.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_routes_additional_boto3(): def test_routes_additional_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -812,60 +438,6 @@ def test_routes_additional_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidRoute.NotFound") ex.value.response["Error"]["Code"].should.equal("InvalidRoute.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_routes_replace():
conn = boto.connect_vpc("the_key", "the_secret")
vpc = conn.create_vpc("10.0.0.0/16")
main_route_table = conn.get_all_route_tables(
filters={"association.main": "true", "vpc-id": vpc.id}
)[0]
ROUTE_CIDR = "10.0.0.4/24"
# Various route targets
igw = conn.create_internet_gateway()
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
# Create initial route
conn.create_route(main_route_table.id, ROUTE_CIDR, gateway_id=igw.id)
# Replace...
def get_target_route():
route_table = conn.get_all_route_tables(main_route_table.id)[0]
routes = [
route
for route in route_table.routes
if route.destination_cidr_block != vpc.cidr_block
]
routes.should.have.length_of(1)
return routes[0]
conn.replace_route(main_route_table.id, ROUTE_CIDR, instance_id=instance.id)
target_route = get_target_route()
target_route.gateway_id.should.be.none
target_route.instance_id.should.equal(instance.id)
target_route.state.should.equal("active")
target_route.destination_cidr_block.should.equal(ROUTE_CIDR)
conn.replace_route(main_route_table.id, ROUTE_CIDR, gateway_id=igw.id)
target_route = get_target_route()
target_route.gateway_id.should.equal(igw.id)
target_route.instance_id.should.be.none
target_route.state.should.equal("active")
target_route.destination_cidr_block.should.equal(ROUTE_CIDR)
with pytest.raises(EC2ResponseError) as cm:
conn.replace_route("rtb-1234abcd", ROUTE_CIDR, gateway_id=igw.id)
cm.value.code.should.equal("InvalidRouteTableID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_routes_replace_boto3(): def test_routes_replace_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -937,30 +509,6 @@ def test_routes_replace_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidRouteTableID.NotFound") ex.value.response["Error"]["Code"].should.equal("InvalidRouteTableID.NotFound")
# Has boto3 equivalent
@requires_boto_gte("2.19.0")
@mock_ec2_deprecated
def test_routes_not_supported():
conn = boto.connect_vpc("the_key", "the_secret")
conn.create_vpc("10.0.0.0/16")
main_route_table = conn.get_all_route_tables()[0]
conn.create_internet_gateway()
ROUTE_CIDR = "10.0.0.4/24"
# Create
conn.create_route.when.called_with(
main_route_table.id, ROUTE_CIDR, interface_id="eni-1234abcd"
).should.throw("InvalidNetworkInterfaceID.NotFound")
# Replace
igw = conn.create_internet_gateway()
conn.create_route(main_route_table.id, ROUTE_CIDR, gateway_id=igw.id)
conn.replace_route.when.called_with(
main_route_table.id, ROUTE_CIDR, interface_id="eni-1234abcd"
).should.throw(NotImplementedError)
@mock_ec2 @mock_ec2
def test_routes_not_supported_boto3(): def test_routes_not_supported_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -1002,42 +550,6 @@ def test_routes_not_supported_boto3():
client.replace_route.when.called_with(**args).should.throw(NotImplementedError) client.replace_route.when.called_with(**args).should.throw(NotImplementedError)
# Has boto3 equivalent
@requires_boto_gte("2.34.0")
@mock_ec2_deprecated
def test_routes_vpc_peering_connection():
conn = boto.connect_vpc("the_key", "the_secret")
vpc = conn.create_vpc("10.0.0.0/16")
main_route_table = conn.get_all_route_tables(
filters={"association.main": "true", "vpc-id": vpc.id}
)[0]
ROUTE_CIDR = "10.0.0.4/24"
peer_vpc = conn.create_vpc("11.0.0.0/16")
vpc_pcx = conn.create_vpc_peering_connection(vpc.id, peer_vpc.id)
conn.create_route(
main_route_table.id, ROUTE_CIDR, vpc_peering_connection_id=vpc_pcx.id
)
# Refresh route table
main_route_table = conn.get_all_route_tables(main_route_table.id)[0]
new_routes = [
route
for route in main_route_table.routes
if route.destination_cidr_block != vpc.cidr_block
]
new_routes.should.have.length_of(1)
new_route = new_routes[0]
new_route.gateway_id.should.be.none
new_route.instance_id.should.be.none
new_route.vpc_peering_connection_id.should.equal(vpc_pcx.id)
new_route.state.should.equal("active")
new_route.destination_cidr_block.should.equal(ROUTE_CIDR)
@mock_ec2 @mock_ec2
def test_routes_vpc_peering_connection_boto3(): def test_routes_vpc_peering_connection_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -1076,36 +588,6 @@ def test_routes_vpc_peering_connection_boto3():
new_route.destination_cidr_block.should.equal(ROUTE_CIDR) new_route.destination_cidr_block.should.equal(ROUTE_CIDR)
# Has boto3 equivalent
@requires_boto_gte("2.34.0")
@mock_ec2_deprecated
def test_routes_vpn_gateway():
conn = boto.connect_vpc("the_key", "the_secret")
vpc = conn.create_vpc("10.0.0.0/16")
main_route_table = conn.get_all_route_tables(
filters={"association.main": "true", "vpc-id": vpc.id}
)[0]
ROUTE_CIDR = "10.0.0.4/24"
vpn_gw = conn.create_vpn_gateway(type="ipsec.1")
conn.create_route(main_route_table.id, ROUTE_CIDR, gateway_id=vpn_gw.id)
main_route_table = conn.get_all_route_tables(main_route_table.id)[0]
new_routes = [
route
for route in main_route_table.routes
if route.destination_cidr_block != vpc.cidr_block
]
new_routes.should.have.length_of(1)
new_route = new_routes[0]
new_route.gateway_id.should.equal(vpn_gw.id)
new_route.instance_id.should.be.none
new_route.vpc_peering_connection_id.should.be.none
@mock_ec2 @mock_ec2
def test_routes_vpn_gateway_boto3(): def test_routes_vpn_gateway_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -1139,26 +621,6 @@ def test_routes_vpn_gateway_boto3():
new_route.vpc_peering_connection_id.should.be.none new_route.vpc_peering_connection_id.should.be.none
# Has boto3 equivalent
@mock_ec2_deprecated
def test_network_acl_tagging():
conn = boto.connect_vpc("the_key", "the secret")
vpc = conn.create_vpc("10.0.0.0/16")
route_table = conn.create_route_table(vpc.id)
route_table.add_tag("a key", "some value")
tag = conn.get_all_tags()[0]
tag.name.should.equal("a key")
tag.value.should.equal("some value")
all_route_tables = conn.get_all_route_tables()
test_route_table = next(na for na in all_route_tables if na.id == route_table.id)
test_route_table.tags.should.have.length_of(1)
test_route_table.tags["a key"].should.equal("some value")
@mock_ec2 @mock_ec2
def test_network_acl_tagging_boto3(): def test_network_acl_tagging_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")

View File

@ -5,57 +5,16 @@ import unittest
import pytest import pytest
import boto3 import boto3
import boto
import boto.ec2
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
from boto.exception import EC2ResponseError
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
from moto import mock_ec2, mock_ec2_deprecated, settings from moto import mock_ec2, settings
from moto.ec2 import ec2_backend from moto.ec2 import ec2_backend
from random import randint from random import randint
from uuid import uuid4 from uuid import uuid4
from unittest import SkipTest from unittest import SkipTest
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_and_describe_security_group():
conn = boto.connect_ec2("the_key", "the_secret")
with pytest.raises(EC2ResponseError) as ex:
security_group = conn.create_security_group(
"test security group", "this is a test security group", dry_run=True
)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the CreateSecurityGroup operation: Request would have succeeded, but DryRun flag is set"
)
security_group = conn.create_security_group(
"test security group", "this is a test security group"
)
security_group.name.should.equal("test security group")
security_group.description.should.equal("this is a test security group")
# Trying to create another group with the same name should throw an error
with pytest.raises(EC2ResponseError) as cm:
conn.create_security_group(
"test security group", "this is a test security group"
)
cm.value.code.should.equal("InvalidGroup.Duplicate")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
all_groups = conn.get_all_security_groups()
# The default group gets created automatically
all_groups.should.have.length_of(2)
group_names = [group.name for group in all_groups]
set(group_names).should.equal(set(["default", "test security group"]))
@mock_ec2 @mock_ec2
def test_create_and_describe_security_group_boto3(): def test_create_and_describe_security_group_boto3():
ec2 = boto3.resource("ec2", "us-west-1") ec2 = boto3.resource("ec2", "us-west-1")
@ -90,18 +49,6 @@ def test_create_and_describe_security_group_boto3():
group_names.should.contain(sec_name) group_names.should.contain(sec_name)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_security_group_without_description_raises_error():
conn = boto.connect_ec2("the_key", "the_secret")
with pytest.raises(EC2ResponseError) as cm:
conn.create_security_group("test security group", "")
cm.value.code.should.equal("MissingParameter")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_create_security_group_without_description_raises_error_boto3(): def test_create_security_group_without_description_raises_error_boto3():
ec2 = boto3.resource("ec2", "us-west-1") ec2 = boto3.resource("ec2", "us-west-1")
@ -113,15 +60,6 @@ def test_create_security_group_without_description_raises_error_boto3():
ex.value.response["Error"]["Code"].should.equal("MissingParameter") ex.value.response["Error"]["Code"].should.equal("MissingParameter")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_default_security_group():
conn = boto.ec2.connect_to_region("us-east-1")
groups = conn.get_all_security_groups()
groups.should.have.length_of(1)
groups[0].name.should.equal("default")
@mock_ec2 @mock_ec2
def test_default_security_group_boto3(): def test_default_security_group_boto3():
client = boto3.client("ec2", "us-west-1") client = boto3.client("ec2", "us-west-1")
@ -129,38 +67,6 @@ def test_default_security_group_boto3():
[g["GroupName"] for g in groups].should.contain("default") [g["GroupName"] for g in groups].should.contain("default")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_and_describe_vpc_security_group():
conn = boto.connect_ec2("the_key", "the_secret")
vpc_id = "vpc-5300000c"
security_group = conn.create_security_group(
"test security group", "this is a test security group", vpc_id=vpc_id
)
security_group.vpc_id.should.equal(vpc_id)
security_group.name.should.equal("test security group")
security_group.description.should.equal("this is a test security group")
# Trying to create another group with the same name in the same VPC should
# throw an error
with pytest.raises(EC2ResponseError) as cm:
conn.create_security_group(
"test security group", "this is a test security group", vpc_id
)
cm.value.code.should.equal("InvalidGroup.Duplicate")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
all_groups = conn.get_all_security_groups(filters={"vpc-id": [vpc_id]})
all_groups[0].vpc_id.should.equal(vpc_id)
all_groups.should.have.length_of(1)
all_groups[0].name.should.equal("test security group")
@mock_ec2 @mock_ec2
def test_create_and_describe_vpc_security_group_boto3(): def test_create_and_describe_vpc_security_group_boto3():
ec2 = boto3.resource("ec2", "us-west-1") ec2 = boto3.resource("ec2", "us-west-1")
@ -203,28 +109,6 @@ def test_create_and_describe_vpc_security_group_boto3():
all_groups[0]["GroupName"].should.equal(name) all_groups[0]["GroupName"].should.equal(name)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_two_security_groups_with_same_name_in_different_vpc():
conn = boto.connect_ec2("the_key", "the_secret")
vpc_id = "vpc-5300000c"
vpc_id2 = "vpc-5300000d"
conn.create_security_group(
"test security group", "this is a test security group", vpc_id
)
conn.create_security_group(
"test security group", "this is a test security group", vpc_id2
)
all_groups = conn.get_all_security_groups()
all_groups.should.have.length_of(3)
group_names = [group.name for group in all_groups]
# The default group is created automatically
set(group_names).should.equal(set(["default", "test security group"]))
@mock_ec2 @mock_ec2
def test_create_two_security_groups_with_same_name_in_different_vpc_boto3(): def test_create_two_security_groups_with_same_name_in_different_vpc_boto3():
ec2 = boto3.resource("ec2", "us-east-1") ec2 = boto3.resource("ec2", "us-east-1")
@ -259,39 +143,6 @@ def test_create_two_security_groups_in_vpc_with_ipv6_enabled():
security_group.ip_permissions_egress.should.have.length_of(2) security_group.ip_permissions_egress.should.have.length_of(2)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_deleting_security_groups():
conn = boto.connect_ec2("the_key", "the_secret")
security_group1 = conn.create_security_group("test1", "test1")
conn.create_security_group("test2", "test2")
conn.get_all_security_groups().should.have.length_of(3)
# Deleting a group that doesn't exist should throw an error
with pytest.raises(EC2ResponseError) as cm:
conn.delete_security_group("foobar")
cm.value.code.should.equal("InvalidGroup.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
# Delete by name
with pytest.raises(EC2ResponseError) as ex:
conn.delete_security_group("test2", dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the DeleteSecurityGroup operation: Request would have succeeded, but DryRun flag is set"
)
conn.delete_security_group("test2")
conn.get_all_security_groups().should.have.length_of(2)
# Delete by group id
conn.delete_security_group(group_id=security_group1.id)
conn.get_all_security_groups().should.have.length_of(1)
@mock_ec2 @mock_ec2
def test_deleting_security_groups_boto3(): def test_deleting_security_groups_boto3():
ec2 = boto3.resource("ec2", "us-west-1") ec2 = boto3.resource("ec2", "us-west-1")
@ -334,17 +185,6 @@ def test_deleting_security_groups_boto3():
[g["GroupId"] for g in all_groups].shouldnt.contain(group1.id) [g["GroupId"] for g in all_groups].shouldnt.contain(group1.id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_delete_security_group_in_vpc():
conn = boto.connect_ec2("the_key", "the_secret")
vpc_id = "vpc-12345"
security_group1 = conn.create_security_group("test1", "test1", vpc_id)
# this should not throw an exception
conn.delete_security_group(group_id=security_group1.id)
@mock_ec2 @mock_ec2
def test_delete_security_group_in_vpc_boto3(): def test_delete_security_group_in_vpc_boto3():
ec2 = boto3.resource("ec2", "us-west-1") ec2 = boto3.resource("ec2", "us-west-1")
@ -364,144 +204,6 @@ def test_delete_security_group_in_vpc_boto3():
[g["GroupId"] for g in all_groups].shouldnt.contain(group.id) [g["GroupId"] for g in all_groups].shouldnt.contain(group.id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_authorize_ip_range_and_revoke():
conn = boto.connect_ec2("the_key", "the_secret")
security_group = conn.create_security_group("test", "test")
with pytest.raises(EC2ResponseError) as ex:
success = security_group.authorize(
ip_protocol="tcp",
from_port="22",
to_port="2222",
cidr_ip="123.123.123.123/32",
dry_run=True,
)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the GrantSecurityGroupIngress operation: Request would have succeeded, but DryRun flag is set"
)
success = security_group.authorize(
ip_protocol="tcp", from_port="22", to_port="2222", cidr_ip="123.123.123.123/32"
)
assert success.should.be.true
security_group = conn.get_all_security_groups(groupnames=["test"])[0]
int(security_group.rules[0].to_port).should.equal(2222)
security_group.rules[0].grants[0].cidr_ip.should.equal("123.123.123.123/32")
# Wrong Cidr should throw error
with pytest.raises(EC2ResponseError) as cm:
security_group.revoke(
ip_protocol="tcp",
from_port="22",
to_port="2222",
cidr_ip="123.123.123.122/32",
)
cm.value.code.should.equal("InvalidPermission.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
# Actually revoke
with pytest.raises(EC2ResponseError) as ex:
security_group.revoke(
ip_protocol="tcp",
from_port="22",
to_port="2222",
cidr_ip="123.123.123.123/32",
dry_run=True,
)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the RevokeSecurityGroupIngress operation: Request would have succeeded, but DryRun flag is set"
)
security_group.revoke(
ip_protocol="tcp", from_port="22", to_port="2222", cidr_ip="123.123.123.123/32"
)
security_group = conn.get_all_security_groups()[0]
security_group.rules.should.have.length_of(0)
# Test for egress as well
vpc_conn = boto.connect_vpc()
vpc = vpc_conn.create_vpc("10.0.0.0/16")
egress_security_group = conn.create_security_group(
"testegress", "testegress", vpc_id=vpc.id
)
with pytest.raises(EC2ResponseError) as ex:
success = conn.authorize_security_group_egress(
egress_security_group.id,
"tcp",
from_port="22",
to_port="2222",
cidr_ip="123.123.123.123/32",
dry_run=True,
)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the GrantSecurityGroupEgress operation: Request would have succeeded, but DryRun flag is set"
)
success = conn.authorize_security_group_egress(
egress_security_group.id,
"tcp",
from_port="22",
to_port="2222",
cidr_ip="123.123.123.123/32",
)
assert success.should.be.true
egress_security_group = conn.get_all_security_groups(groupnames="testegress")[0]
# There are two egress rules associated with the security group:
# the default outbound rule and the new one
int(egress_security_group.rules_egress[1].to_port).should.equal(2222)
actual_cidr = egress_security_group.rules_egress[1].grants[0].cidr_ip
actual_cidr.should.equal("123.123.123.123/32")
# Wrong Cidr should throw error
egress_security_group.revoke.when.called_with(
ip_protocol="tcp", from_port="22", to_port="2222", cidr_ip="123.123.123.122/32"
).should.throw(EC2ResponseError)
# Actually revoke
with pytest.raises(EC2ResponseError) as ex:
conn.revoke_security_group_egress(
egress_security_group.id,
"tcp",
from_port="22",
to_port="2222",
cidr_ip="123.123.123.123/32",
dry_run=True,
)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the RevokeSecurityGroupEgress operation: Request would have succeeded, but DryRun flag is set"
)
conn.revoke_security_group_egress(
egress_security_group.id,
"tcp",
from_port="22",
to_port="2222",
cidr_ip="123.123.123.123/32",
)
egress_security_group = [
group
for group in conn.get_all_security_groups()
if group.id == egress_security_group.id
][0]
# There is still the default outbound rule
egress_security_group.rules_egress.should.have.length_of(1)
@mock_ec2 @mock_ec2
def test_authorize_ip_range_and_revoke_boto3(): def test_authorize_ip_range_and_revoke_boto3():
ec2 = boto3.resource("ec2", "us-west-1") ec2 = boto3.resource("ec2", "us-west-1")
@ -623,51 +325,6 @@ def test_authorize_ip_range_and_revoke_boto3():
egress_security_group["IpPermissionsEgress"].should.have.length_of(1) egress_security_group["IpPermissionsEgress"].should.have.length_of(1)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_authorize_other_group_and_revoke():
conn = boto.connect_ec2("the_key", "the_secret")
security_group = conn.create_security_group("test", "test")
other_security_group = conn.create_security_group("other", "other")
wrong_group = conn.create_security_group("wrong", "wrong")
success = security_group.authorize(
ip_protocol="tcp",
from_port="22",
to_port="2222",
src_group=other_security_group,
)
assert success.should.be.true
security_group = [
group for group in conn.get_all_security_groups() if group.name == "test"
][0]
int(security_group.rules[0].to_port).should.equal(2222)
security_group.rules[0].grants[0].group_id.should.equal(other_security_group.id)
# Wrong source group should throw error
with pytest.raises(EC2ResponseError) as cm:
security_group.revoke(
ip_protocol="tcp", from_port="22", to_port="2222", src_group=wrong_group
)
cm.value.code.should.equal("InvalidPermission.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
# Actually revoke
security_group.revoke(
ip_protocol="tcp",
from_port="22",
to_port="2222",
src_group=other_security_group,
)
security_group = [
group for group in conn.get_all_security_groups() if group.name == "test"
][0]
security_group.rules.should.have.length_of(0)
@mock_ec2 @mock_ec2
def test_authorize_other_group_and_revoke_boto3(): def test_authorize_other_group_and_revoke_boto3():
ec2 = boto3.resource("ec2", "us-west-1") ec2 = boto3.resource("ec2", "us-west-1")
@ -759,47 +416,6 @@ def test_authorize_other_group_egress_and_revoke():
sg01.ip_permissions_egress.should.have.length_of(1) sg01.ip_permissions_egress.should.have.length_of(1)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_authorize_group_in_vpc():
conn = boto.connect_ec2("the_key", "the_secret")
vpc_id = "vpc-12345"
# create 2 groups in a vpc
security_group = conn.create_security_group("test1", "test1", vpc_id)
other_security_group = conn.create_security_group("test2", "test2", vpc_id)
success = security_group.authorize(
ip_protocol="tcp",
from_port="22",
to_port="2222",
src_group=other_security_group,
)
success.should.be.true
# Check that the rule is accurate
security_group = [
group for group in conn.get_all_security_groups() if group.name == "test1"
][0]
int(security_group.rules[0].to_port).should.equal(2222)
security_group.rules[0].grants[0].group_id.should.equal(other_security_group.id)
# Now remove the rule
success = security_group.revoke(
ip_protocol="tcp",
from_port="22",
to_port="2222",
src_group=other_security_group,
)
success.should.be.true
# And check that it gets revoked
security_group = [
group for group in conn.get_all_security_groups() if group.name == "test1"
][0]
security_group.rules.should.have.length_of(0)
@mock_ec2 @mock_ec2
def test_authorize_group_in_vpc_boto3(): def test_authorize_group_in_vpc_boto3():
ec2 = boto3.resource("ec2", "ap-south-1") ec2 = boto3.resource("ec2", "ap-south-1")
@ -851,44 +467,6 @@ def test_authorize_group_in_vpc_boto3():
found_sec_group["IpPermissions"].should.have.length_of(0) found_sec_group["IpPermissions"].should.have.length_of(0)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_get_all_security_groups():
conn = boto.connect_ec2()
sg1 = conn.create_security_group(
name="test1", description="test1", vpc_id="vpc-mjm05d27"
)
conn.create_security_group(name="test2", description="test2")
resp = conn.get_all_security_groups(groupnames=["test1"])
resp.should.have.length_of(1)
resp[0].id.should.equal(sg1.id)
with pytest.raises(EC2ResponseError) as cm:
conn.get_all_security_groups(groupnames=["does_not_exist"])
cm.value.code.should.equal("InvalidGroup.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
resp.should.have.length_of(1)
resp[0].id.should.equal(sg1.id)
resp = conn.get_all_security_groups(filters={"vpc-id": ["vpc-mjm05d27"]})
resp.should.have.length_of(1)
resp[0].id.should.equal(sg1.id)
resp = conn.get_all_security_groups(filters={"vpc-id": ["vpc-mjm05d27"]})
resp.should.have.length_of(1)
resp[0].id.should.equal(sg1.id)
resp = conn.get_all_security_groups(filters={"description": ["test1"]})
resp.should.have.length_of(1)
resp[0].id.should.equal(sg1.id)
resp = conn.get_all_security_groups()
resp.should.have.length_of(3)
@mock_ec2 @mock_ec2
def test_describe_security_groups(): def test_describe_security_groups():
ec2 = boto3.resource("ec2", "us-west-1") ec2 = boto3.resource("ec2", "us-west-1")
@ -927,20 +505,6 @@ def test_describe_security_groups():
sg_ids.should.contain(sg2.id) sg_ids.should.contain(sg2.id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_authorize_bad_cidr_throws_invalid_parameter_value():
conn = boto.connect_ec2("the_key", "the_secret")
security_group = conn.create_security_group("test", "test")
with pytest.raises(EC2ResponseError) as cm:
security_group.authorize(
ip_protocol="tcp", from_port="22", to_port="2222", cidr_ip="123.123.123.123"
)
cm.value.code.should.equal("InvalidParameterValue")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_authorize_bad_cidr_throws_invalid_parameter_value_boto3(): def test_authorize_bad_cidr_throws_invalid_parameter_value_boto3():
ec2 = boto3.resource("ec2", "us-west-1") ec2 = boto3.resource("ec2", "us-west-1")
@ -960,44 +524,6 @@ def test_authorize_bad_cidr_throws_invalid_parameter_value_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidParameterValue") ex.value.response["Error"]["Code"].should.equal("InvalidParameterValue")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_security_group_tagging():
conn = boto.connect_vpc()
vpc = conn.create_vpc("10.0.0.0/16")
sg = conn.create_security_group("test-sg", "Test SG", vpc.id)
with pytest.raises(EC2ResponseError) as ex:
sg.add_tag("Test", "Tag", dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the CreateTags operation: Request would have succeeded, but DryRun flag is set"
)
sg.add_tag("Test", "Tag")
tag = conn.get_all_tags()[0]
tag.name.should.equal("Test")
tag.value.should.equal("Tag")
group = conn.get_all_security_groups("test-sg")[0]
group.tags.should.have.length_of(1)
group.tags["Test"].should.equal("Tag")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_security_group_tag_filtering():
conn = boto.connect_ec2()
sg = conn.create_security_group("test-sg", "Test SG")
sg.add_tag("test-tag", "test-value")
groups = conn.get_all_security_groups(filters={"tag:test-tag": "test-value"})
groups.should.have.length_of(1)
@mock_ec2 @mock_ec2
def test_security_group_tag_filtering_boto3(): def test_security_group_tag_filtering_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1") ec2 = boto3.resource("ec2", region_name="us-east-1")
@ -1018,20 +544,6 @@ def test_security_group_tag_filtering_boto3():
groups.should.have.length_of(0) groups.should.have.length_of(0)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_authorize_all_protocols_with_no_port_specification():
conn = boto.connect_ec2()
sg = conn.create_security_group("test", "test")
success = sg.authorize(ip_protocol="-1", cidr_ip="0.0.0.0/0")
success.should.be.true
sg = conn.get_all_security_groups("test")[0]
sg.rules[0].from_port.should.equal(None)
sg.rules[0].to_port.should.equal(None)
@mock_ec2 @mock_ec2
def test_authorize_all_protocols_with_no_port_specification_boto3(): def test_authorize_all_protocols_with_no_port_specification_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1") ec2 = boto3.resource("ec2", region_name="us-east-1")
@ -1050,72 +562,6 @@ def test_authorize_all_protocols_with_no_port_specification_boto3():
permission.shouldnt.have.key("ToPort") permission.shouldnt.have.key("ToPort")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_sec_group_rule_limit():
ec2_conn = boto.connect_ec2()
sg = ec2_conn.create_security_group("test", "test")
other_sg = ec2_conn.create_security_group("test_2", "test_other")
# INGRESS
with pytest.raises(EC2ResponseError) as cm:
ec2_conn.authorize_security_group(
group_id=sg.id,
ip_protocol="-1",
cidr_ip=["{0}.0.0.0/0".format(i) for i in range(110)],
)
cm.value.error_code.should.equal("RulesPerSecurityGroupLimitExceeded")
sg.rules.should.be.empty
# authorize a rule targeting a different sec group (because this count too)
success = ec2_conn.authorize_security_group(
group_id=sg.id, ip_protocol="-1", src_security_group_group_id=other_sg.id
)
success.should.be.true
# fill the rules up the limit
success = ec2_conn.authorize_security_group(
group_id=sg.id,
ip_protocol="-1",
cidr_ip=["{0}.0.0.0/0".format(i) for i in range(1, 60)],
)
success.should.be.true
# verify that we cannot authorize past the limit for a CIDR IP
with pytest.raises(EC2ResponseError) as cm:
ec2_conn.authorize_security_group(
group_id=sg.id, ip_protocol="-1", cidr_ip=["100.0.0.0/0"]
)
cm.value.error_code.should.equal("RulesPerSecurityGroupLimitExceeded")
# verify that we cannot authorize past the limit for a different sec group
with pytest.raises(EC2ResponseError) as cm:
ec2_conn.authorize_security_group(
group_id=sg.id, ip_protocol="-1", src_security_group_group_id=other_sg.id
)
cm.value.error_code.should.equal("RulesPerSecurityGroupLimitExceeded")
# EGRESS
# authorize a rule targeting a different sec group (because this count too)
ec2_conn.authorize_security_group_egress(
group_id=sg.id, ip_protocol="-1", src_group_id=other_sg.id
)
# fill the rules up the limit, 59 + 1 default rule
for i in range(1, 59):
ec2_conn.authorize_security_group_egress(
group_id=sg.id, ip_protocol="-1", cidr_ip="{0}.0.0.0/0".format(i)
)
# verify that we cannot authorize past the limit for a CIDR IP
with pytest.raises(EC2ResponseError) as cm:
ec2_conn.authorize_security_group_egress(
group_id=sg.id, ip_protocol="-1", cidr_ip="101.0.0.0/0"
)
cm.value.error_code.should.equal("RulesPerSecurityGroupLimitExceeded")
# verify that we cannot authorize past the limit for a different sec group
with pytest.raises(EC2ResponseError) as cm:
ec2_conn.authorize_security_group_egress(
group_id=sg.id, ip_protocol="-1", src_group_id=other_sg.id
)
cm.value.error_code.should.equal("RulesPerSecurityGroupLimitExceeded")
@mock_ec2 @mock_ec2
@pytest.mark.parametrize( @pytest.mark.parametrize(
"use_vpc", [True, False], ids=["Use VPC", "Without VPC"], "use_vpc", [True, False], ids=["Use VPC", "Without VPC"],
@ -1232,83 +678,6 @@ def test_sec_group_rule_limit_boto3(use_vpc):
) )
# Has boto3 equivalent
@mock_ec2_deprecated
def test_sec_group_rule_limit_vpc():
ec2_conn = boto.connect_ec2()
vpc_conn = boto.connect_vpc()
vpc = vpc_conn.create_vpc("10.0.0.0/16")
sg = ec2_conn.create_security_group("test", "test", vpc_id=vpc.id)
other_sg = ec2_conn.create_security_group("test_2", "test", vpc_id=vpc.id)
# INGRESS
with pytest.raises(EC2ResponseError) as cm:
ec2_conn.authorize_security_group(
group_id=sg.id,
ip_protocol="-1",
cidr_ip=["{0}.0.0.0/0".format(i) for i in range(110)],
)
cm.value.error_code.should.equal("RulesPerSecurityGroupLimitExceeded")
sg.rules.should.be.empty
# authorize a rule targeting a different sec group (because this count too)
success = ec2_conn.authorize_security_group(
group_id=sg.id, ip_protocol="-1", src_security_group_group_id=other_sg.id
)
success.should.be.true
# fill the rules up the limit
success = ec2_conn.authorize_security_group(
group_id=sg.id,
ip_protocol="-1",
cidr_ip=["{0}.0.0.0/0".format(i) for i in range(59)],
)
# verify that we cannot authorize past the limit for a CIDR IP
success.should.be.true
with pytest.raises(EC2ResponseError) as cm:
ec2_conn.authorize_security_group(
group_id=sg.id, ip_protocol="-1", cidr_ip=["100.0.0.0/0"]
)
cm.value.error_code.should.equal("RulesPerSecurityGroupLimitExceeded")
# verify that we cannot authorize past the limit for a different sec group
with pytest.raises(EC2ResponseError) as cm:
ec2_conn.authorize_security_group(
group_id=sg.id, ip_protocol="-1", src_security_group_group_id=other_sg.id
)
cm.value.error_code.should.equal("RulesPerSecurityGroupLimitExceeded")
# EGRESS
# authorize a rule targeting a different sec group (because this count too)
ec2_conn.authorize_security_group_egress(
group_id=sg.id, ip_protocol="-1", src_group_id=other_sg.id
)
# fill the rules up the limit
# remember that by default, when created a sec group contains 1 egress rule
# so our other_sg rule + 48 CIDR IP rules + 1 by default == 50 the limit
for i in range(1, 59):
ec2_conn.authorize_security_group_egress(
group_id=sg.id, ip_protocol="-1", cidr_ip="{0}.0.0.0/0".format(i)
)
# verify that we cannot authorize past the limit for a CIDR IP
with pytest.raises(EC2ResponseError) as cm:
ec2_conn.authorize_security_group_egress(
group_id=sg.id, ip_protocol="-1", cidr_ip="50.0.0.0/0"
)
cm.value.error_code.should.equal("RulesPerSecurityGroupLimitExceeded")
# verify that we cannot authorize past the limit for a different sec group
with pytest.raises(EC2ResponseError) as cm:
ec2_conn.authorize_security_group_egress(
group_id=sg.id, ip_protocol="-1", src_group_id=other_sg.id
)
cm.value.error_code.should.equal("RulesPerSecurityGroupLimitExceeded")
"""
Boto3
"""
@mock_ec2 @mock_ec2
def test_add_same_rule_twice_throws_error(): def test_add_same_rule_twice_throws_error():
ec2 = boto3.resource("ec2", region_name="us-west-1") ec2 = boto3.resource("ec2", region_name="us-west-1")
@ -1669,29 +1038,6 @@ def test_security_group_ingress_without_multirule_after_reload():
assert len(sg_after.ip_permissions) == 1 assert len(sg_after.ip_permissions) == 1
# Has boto3 equivalent
@mock_ec2_deprecated
def test_get_all_security_groups_filter_with_same_vpc_id():
conn = boto.connect_ec2("the_key", "the_secret")
vpc_id = "vpc-5300000c"
security_group = conn.create_security_group("test1", "test1", vpc_id=vpc_id)
security_group2 = conn.create_security_group("test2", "test2", vpc_id=vpc_id)
security_group.vpc_id.should.equal(vpc_id)
security_group2.vpc_id.should.equal(vpc_id)
security_groups = conn.get_all_security_groups(
group_ids=[security_group.id], filters={"vpc-id": [vpc_id]}
)
security_groups.should.have.length_of(1)
with pytest.raises(EC2ResponseError) as cm:
conn.get_all_security_groups(group_ids=["does_not_exist"])
cm.value.code.should.equal("InvalidGroup.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_get_all_security_groups_filter_with_same_vpc_id_boto3(): def test_get_all_security_groups_filter_with_same_vpc_id_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1") ec2 = boto3.resource("ec2", region_name="us-east-1")

View File

@ -1,15 +1,12 @@
import pytest import pytest
import datetime import datetime
import boto
import boto.ec2
import boto3 import boto3
from boto.exception import EC2ResponseError
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
import pytz import pytz
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
from moto import mock_ec2, mock_ec2_deprecated, settings from moto import mock_ec2, settings
from moto.ec2.models import ec2_backends from moto.ec2.models import ec2_backends
from moto.core.utils import iso_8601_datetime_with_milliseconds from moto.core.utils import iso_8601_datetime_with_milliseconds
from tests import EXAMPLE_AMI_ID from tests import EXAMPLE_AMI_ID
@ -155,30 +152,6 @@ def test_request_spot_instances_default_arguments():
request.shouldnt.contain("SubnetId") request.shouldnt.contain("SubnetId")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_cancel_spot_instance_request():
conn = boto.connect_ec2()
conn.request_spot_instances(price=0.5, image_id=EXAMPLE_AMI_ID)
requests = conn.get_all_spot_instance_requests()
requests.should.have.length_of(1)
with pytest.raises(EC2ResponseError) as ex:
conn.cancel_spot_instance_requests([requests[0].id], dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the CancelSpotInstance operation: Request would have succeeded, but DryRun flag is set"
)
conn.cancel_spot_instance_requests([requests[0].id])
requests = conn.get_all_spot_instance_requests()
requests.should.have.length_of(0)
@mock_ec2 @mock_ec2
def test_cancel_spot_instance_request_boto3(): def test_cancel_spot_instance_request_boto3():
client = boto3.client("ec2", region_name="us-west-1") client = boto3.client("ec2", region_name="us-west-1")
@ -219,32 +192,6 @@ def test_cancel_spot_instance_request_boto3():
requests.should.have.length_of(0) requests.should.have.length_of(0)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_request_spot_instances_fulfilled():
"""
Test that moto correctly fullfills a spot instance request
"""
conn = boto.ec2.connect_to_region("us-east-1")
request = conn.request_spot_instances(price=0.5, image_id=EXAMPLE_AMI_ID)
requests = conn.get_all_spot_instance_requests()
requests.should.have.length_of(1)
request = requests[0]
request.state.should.equal("open")
if not settings.TEST_SERVER_MODE:
ec2_backends["us-east-1"].spot_instance_requests[request.id].state = "active"
requests = conn.get_all_spot_instance_requests()
requests.should.have.length_of(1)
request = requests[0]
request.state.should.equal("active")
@mock_ec2 @mock_ec2
def test_request_spot_instances_fulfilled_boto3(): def test_request_spot_instances_fulfilled_boto3():
""" """
@ -277,26 +224,6 @@ def test_request_spot_instances_fulfilled_boto3():
request["State"].should.equal("active") request["State"].should.equal("active")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_tag_spot_instance_request():
"""
Test that moto correctly tags a spot instance request
"""
conn = boto.connect_ec2()
request = conn.request_spot_instances(price=0.5, image_id=EXAMPLE_AMI_ID)
request[0].add_tag("tag1", "value1")
request[0].add_tag("tag2", "value2")
requests = conn.get_all_spot_instance_requests()
requests.should.have.length_of(1)
request = requests[0]
tag_dict = dict(request.tags)
tag_dict.should.equal({"tag1": "value1", "tag2": "value2"})
@mock_ec2 @mock_ec2
def test_tag_spot_instance_request_boto3(): def test_tag_spot_instance_request_boto3():
""" """
@ -324,37 +251,6 @@ def test_tag_spot_instance_request_boto3():
request["Tags"].should.contain({"Key": "tag2", "Value": "value2"}) request["Tags"].should.contain({"Key": "tag2", "Value": "value2"})
# Has boto3 equivalent
@mock_ec2_deprecated
def test_get_all_spot_instance_requests_filtering():
"""
Test that moto correctly filters spot instance requests
"""
conn = boto.connect_ec2()
request1 = conn.request_spot_instances(price=0.5, image_id=EXAMPLE_AMI_ID)
request2 = conn.request_spot_instances(price=0.5, image_id=EXAMPLE_AMI_ID)
conn.request_spot_instances(price=0.5, image_id=EXAMPLE_AMI_ID)
request1[0].add_tag("tag1", "value1")
request1[0].add_tag("tag2", "value2")
request2[0].add_tag("tag1", "value1")
request2[0].add_tag("tag2", "wrong")
requests = conn.get_all_spot_instance_requests(filters={"state": "active"})
requests.should.have.length_of(0)
requests = conn.get_all_spot_instance_requests(filters={"state": "open"})
requests.should.have.length_of(3)
requests = conn.get_all_spot_instance_requests(filters={"tag:tag1": "value1"})
requests.should.have.length_of(2)
requests = conn.get_all_spot_instance_requests(
filters={"tag:tag1": "value1", "tag:tag2": "value2"}
)
requests.should.have.length_of(1)
@mock_ec2 @mock_ec2
def test_get_all_spot_instance_requests_filtering_boto3(): def test_get_all_spot_instance_requests_filtering_boto3():
""" """
@ -411,22 +307,6 @@ def test_get_all_spot_instance_requests_filtering_boto3():
requests.should.have.length_of(1) requests.should.have.length_of(1)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_request_spot_instances_setting_instance_id():
conn = boto.ec2.connect_to_region("us-east-1")
request = conn.request_spot_instances(price=0.5, image_id=EXAMPLE_AMI_ID)
if not settings.TEST_SERVER_MODE:
req = ec2_backends["us-east-1"].spot_instance_requests[request[0].id]
req.state = "active"
req.instance_id = "i-12345678"
request = conn.get_all_spot_instance_requests()[0]
assert request.state == "active"
assert request.instance_id == "i-12345678"
@mock_ec2 @mock_ec2
def test_request_spot_instances_instance_lifecycle(): def test_request_spot_instances_instance_lifecycle():
if settings.TEST_SERVER_MODE: if settings.TEST_SERVER_MODE:

View File

@ -1,42 +1,16 @@
import random import random
import boto
import boto3 import boto3
import boto.vpc
import pytest import pytest
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
from boto.exception import EC2ResponseError
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
from moto import mock_ec2, mock_ec2_deprecated, settings from moto import mock_ec2, settings
from tests import EXAMPLE_AMI_ID from tests import EXAMPLE_AMI_ID
from uuid import uuid4 from uuid import uuid4
from unittest import SkipTest from unittest import SkipTest
# Has boto3 equivalent
@mock_ec2_deprecated
def test_subnets():
ec2 = boto.connect_ec2("the_key", "the_secret")
conn = boto.connect_vpc("the_key", "the_secret")
vpc = conn.create_vpc("10.0.0.0/16")
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
all_subnets = conn.get_all_subnets()
all_subnets.should.have.length_of(1 + len(ec2.get_all_zones()))
conn.delete_subnet(subnet.id)
all_subnets = conn.get_all_subnets()
all_subnets.should.have.length_of(0 + len(ec2.get_all_zones()))
with pytest.raises(EC2ResponseError) as cm:
conn.delete_subnet(subnet.id)
cm.value.code.should.equal("InvalidSubnetID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_subnets_boto3(): def test_subnets_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1") ec2 = boto3.resource("ec2", region_name="us-east-1")
@ -61,18 +35,6 @@ def test_subnets_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidSubnetID.NotFound") ex.value.response["Error"]["Code"].should.equal("InvalidSubnetID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_subnet_create_vpc_validation():
conn = boto.connect_vpc("the_key", "the_secret")
with pytest.raises(EC2ResponseError) as cm:
conn.create_subnet("vpc-abcd1234", "10.0.0.0/18")
cm.value.code.should.equal("InvalidVpcID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_subnet_create_vpc_validation_boto3(): def test_subnet_create_vpc_validation_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1") ec2 = boto3.resource("ec2", region_name="us-east-1")
@ -84,25 +46,6 @@ def test_subnet_create_vpc_validation_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidVpcID.NotFound") ex.value.response["Error"]["Code"].should.equal("InvalidVpcID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_subnet_tagging():
conn = boto.connect_vpc("the_key", "the_secret")
vpc = conn.create_vpc("10.0.0.0/16")
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
subnet.add_tag("a key", "some value")
tag = conn.get_all_tags()[0]
tag.name.should.equal("a key")
tag.value.should.equal("some value")
# Refresh the subnet
subnet = conn.get_all_subnets(subnet_ids=[subnet.id])[0]
subnet.tags.should.have.length_of(1)
subnet.tags["a key"].should.equal("some value")
@mock_ec2 @mock_ec2
def test_subnet_tagging_boto3(): def test_subnet_tagging_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1") ec2 = boto3.resource("ec2", region_name="us-east-1")
@ -123,15 +66,6 @@ def test_subnet_tagging_boto3():
subnet["Tags"].should.equal([{"Key": "a key", "Value": "some value"}]) subnet["Tags"].should.equal([{"Key": "a key", "Value": "some value"}])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_subnet_should_have_proper_availability_zone_set():
conn = boto.vpc.connect_to_region("us-west-1")
vpcA = conn.create_vpc("10.0.0.0/16")
subnetA = conn.create_subnet(vpcA.id, "10.0.0.0/24", availability_zone="us-west-1b")
subnetA.availability_zone.should.equal("us-west-1b")
@mock_ec2 @mock_ec2
def test_subnet_should_have_proper_availability_zone_set_boto3(): def test_subnet_should_have_proper_availability_zone_set_boto3():
ec2 = boto3.resource("ec2", region_name="us-west-1") ec2 = boto3.resource("ec2", region_name="us-west-1")
@ -172,20 +106,6 @@ def test_default_subnet():
subnet.map_public_ip_on_launch.shouldnt.be.ok subnet.map_public_ip_on_launch.shouldnt.be.ok
# Has boto3 equivalent
@mock_ec2_deprecated
def test_non_default_subnet():
vpc_cli = boto.vpc.connect_to_region("us-west-1")
# Create the non default VPC
vpc = vpc_cli.create_vpc("10.0.0.0/16")
vpc.is_default.shouldnt.be.ok
subnet = vpc_cli.create_subnet(vpc.id, "10.0.0.0/24")
subnet = vpc_cli.get_all_subnets(subnet_ids=[subnet.id])[0]
subnet.mapPublicIpOnLaunch.should.equal("false")
@mock_ec2 @mock_ec2
def test_boto3_non_default_subnet(): def test_boto3_non_default_subnet():
ec2 = boto3.resource("ec2", region_name="us-west-1") ec2 = boto3.resource("ec2", region_name="us-west-1")
@ -279,31 +199,6 @@ def test_modify_subnet_attribute_validation():
) )
# Has boto3 equivalent
@mock_ec2_deprecated
def test_subnet_get_by_id():
conn = boto.vpc.connect_to_region("us-west-1")
vpcA = conn.create_vpc("10.0.0.0/16")
subnetA = conn.create_subnet(vpcA.id, "10.0.0.0/24", availability_zone="us-west-1a")
vpcB = conn.create_vpc("10.0.0.0/16")
subnetB1 = conn.create_subnet(
vpcB.id, "10.0.0.0/24", availability_zone="us-west-1a"
)
conn.create_subnet(vpcB.id, "10.0.1.0/24", availability_zone="us-west-1b")
subnets_by_id = conn.get_all_subnets(subnet_ids=[subnetA.id, subnetB1.id])
subnets_by_id.should.have.length_of(2)
subnets_by_id = tuple(map(lambda s: s.id, subnets_by_id))
subnetA.id.should.be.within(subnets_by_id)
subnetB1.id.should.be.within(subnets_by_id)
with pytest.raises(EC2ResponseError) as cm:
conn.get_all_subnets(subnet_ids=["subnet-does_not_exist"])
cm.value.code.should.equal("InvalidSubnetID.NotFound")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_subnet_get_by_id_boto3(): def test_subnet_get_by_id_boto3():
ec2 = boto3.resource("ec2", region_name="us-west-1") ec2 = boto3.resource("ec2", region_name="us-west-1")
@ -335,82 +230,6 @@ def test_subnet_get_by_id_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidSubnetID.NotFound") ex.value.response["Error"]["Code"].should.equal("InvalidSubnetID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_get_subnets_filtering():
ec2 = boto.ec2.connect_to_region("us-west-1")
conn = boto.vpc.connect_to_region("us-west-1")
vpcA = conn.create_vpc("10.0.0.0/16")
subnetA = conn.create_subnet(vpcA.id, "10.0.0.0/24", availability_zone="us-west-1a")
vpcB = conn.create_vpc("10.0.0.0/16")
subnetB1 = conn.create_subnet(
vpcB.id, "10.0.0.0/24", availability_zone="us-west-1a"
)
subnetB2 = conn.create_subnet(
vpcB.id, "10.0.1.0/24", availability_zone="us-west-1b"
)
all_subnets = conn.get_all_subnets()
all_subnets.should.have.length_of(3 + len(ec2.get_all_zones()))
# Filter by VPC ID
subnets_by_vpc = conn.get_all_subnets(filters={"vpc-id": vpcB.id})
subnets_by_vpc.should.have.length_of(2)
set([subnet.id for subnet in subnets_by_vpc]).should.equal(
set([subnetB1.id, subnetB2.id])
)
# Filter by CIDR variations
subnets_by_cidr1 = conn.get_all_subnets(filters={"cidr": "10.0.0.0/24"})
subnets_by_cidr1.should.have.length_of(2)
set([subnet.id for subnet in subnets_by_cidr1]).should.equal(
set([subnetA.id, subnetB1.id])
)
subnets_by_cidr2 = conn.get_all_subnets(filters={"cidr-block": "10.0.0.0/24"})
subnets_by_cidr2.should.have.length_of(2)
set([subnet.id for subnet in subnets_by_cidr2]).should.equal(
set([subnetA.id, subnetB1.id])
)
subnets_by_cidr3 = conn.get_all_subnets(filters={"cidrBlock": "10.0.0.0/24"})
subnets_by_cidr3.should.have.length_of(2)
set([subnet.id for subnet in subnets_by_cidr3]).should.equal(
set([subnetA.id, subnetB1.id])
)
# Filter by VPC ID and CIDR
subnets_by_vpc_and_cidr = conn.get_all_subnets(
filters={"vpc-id": vpcB.id, "cidr": "10.0.0.0/24"}
)
subnets_by_vpc_and_cidr.should.have.length_of(1)
set([subnet.id for subnet in subnets_by_vpc_and_cidr]).should.equal(
set([subnetB1.id])
)
# Filter by subnet ID
subnets_by_id = conn.get_all_subnets(filters={"subnet-id": subnetA.id})
subnets_by_id.should.have.length_of(1)
set([subnet.id for subnet in subnets_by_id]).should.equal(set([subnetA.id]))
# Filter by availabilityZone
subnets_by_az = conn.get_all_subnets(
filters={"availabilityZone": "us-west-1a", "vpc-id": vpcB.id}
)
subnets_by_az.should.have.length_of(1)
set([subnet.id for subnet in subnets_by_az]).should.equal(set([subnetB1.id]))
# Filter by defaultForAz
subnets_by_az = conn.get_all_subnets(filters={"defaultForAz": "true"})
subnets_by_az.should.have.length_of(len(conn.get_all_zones()))
# Unsupported filter
conn.get_all_subnets.when.called_with(
filters={"not-implemented-filter": "foobar"}
).should.throw(NotImplementedError)
@mock_ec2 @mock_ec2
def test_get_subnets_filtering_boto3(): def test_get_subnets_filtering_boto3():
ec2 = boto3.resource("ec2", region_name="us-west-1") ec2 = boto3.resource("ec2", region_name="us-west-1")

View File

@ -1,45 +1,15 @@
import boto3
import sure # noqa # pylint: disable=unused-import
import pytest import pytest
import itertools
import boto
import boto3
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
from boto.exception import EC2ResponseError from moto import mock_ec2
from boto.ec2.instance import Reservation
import sure # noqa # pylint: disable=unused-import
from moto import mock_ec2_deprecated, mock_ec2
from tests import EXAMPLE_AMI_ID from tests import EXAMPLE_AMI_ID
from .test_instances import retrieve_all_instances from .test_instances import retrieve_all_instances
from uuid import uuid4 from uuid import uuid4
# Has boto3 equivalent
@mock_ec2_deprecated
def test_add_tag():
conn = boto.connect_ec2("the_key", "the_secret")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
with pytest.raises(EC2ResponseError) as ex:
instance.add_tag("a key", "some value", dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the CreateTags operation: Request would have succeeded, but DryRun flag is set"
)
instance.add_tag("a key", "some value")
chain = itertools.chain.from_iterable
existing_instances = list(
chain([res.instances for res in conn.get_all_reservations()])
)
existing_instances.should.have.length_of(1)
existing_instance = existing_instances[0]
existing_instance.tags["a key"].should.equal("some value")
@mock_ec2 @mock_ec2
def test_instance_create_tags(): def test_instance_create_tags():
ec2 = boto3.resource("ec2", "us-west-1") ec2 = boto3.resource("ec2", "us-west-1")
@ -62,36 +32,6 @@ def test_instance_create_tags():
ours["Tags"].should.equal([{"Key": "a key", "Value": "some value"}]) ours["Tags"].should.equal([{"Key": "a key", "Value": "some value"}])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_remove_tag():
conn = boto.connect_ec2("the_key", "the_secret")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
instance.add_tag("a key", "some value")
tags = conn.get_all_tags()
tag = tags[0]
tag.name.should.equal("a key")
tag.value.should.equal("some value")
with pytest.raises(EC2ResponseError) as ex:
instance.remove_tag("a key", dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the DeleteTags operation: Request would have succeeded, but DryRun flag is set"
)
instance.remove_tag("a key")
conn.get_all_tags().should.have.length_of(0)
instance.add_tag("a key", "some value")
conn.get_all_tags().should.have.length_of(1)
instance.remove_tag("a key", "some value")
@mock_ec2 @mock_ec2
def test_instance_delete_tags(): def test_instance_delete_tags():
ec2 = boto3.resource("ec2", region_name="us-east-1") ec2 = boto3.resource("ec2", region_name="us-east-1")
@ -133,36 +73,6 @@ def test_instance_delete_tags():
].should.have.length_of(0) ].should.have.length_of(0)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_get_all_tags():
conn = boto.connect_ec2("the_key", "the_secret")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
instance.add_tag("a key", "some value")
tags = conn.get_all_tags()
tag = tags[0]
tag.name.should.equal("a key")
tag.value.should.equal("some value")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_get_all_tags_with_special_characters():
conn = boto.connect_ec2("the_key", "the_secret")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
instance.add_tag("a key", "some<> value")
tags = conn.get_all_tags()
tag = tags[0]
tag.name.should.equal("a key")
tag.value.should.equal("some<> value")
@mock_ec2 @mock_ec2
def test_get_all_tags_with_special_characters_boto3(): def test_get_all_tags_with_special_characters_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1") ec2 = boto3.resource("ec2", region_name="us-east-1")
@ -179,34 +89,6 @@ def test_get_all_tags_with_special_characters_boto3():
tag.should.have.key("Value").equal("some<> value") tag.should.have.key("Value").equal("some<> value")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_tags():
conn = boto.connect_ec2("the_key", "the_secret")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
tag_dict = {
"a key": "some value",
"another key": "some other value",
"blank key": "",
}
with pytest.raises(EC2ResponseError) as ex:
conn.create_tags(instance.id, tag_dict, dry_run=True)
ex.value.error_code.should.equal("DryRunOperation")
ex.value.status.should.equal(412)
ex.value.message.should.equal(
"An error occurred (DryRunOperation) when calling the CreateTags operation: Request would have succeeded, but DryRun flag is set"
)
conn.create_tags(instance.id, tag_dict)
tags = conn.get_all_tags()
set([key for key in tag_dict]).should.equal(set([tag.name for tag in tags]))
set([tag_dict[key] for key in tag_dict]).should.equal(
set([tag.value for tag in tags])
)
@mock_ec2 @mock_ec2
def test_create_tags_boto3(): def test_create_tags_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1") ec2 = boto3.resource("ec2", region_name="us-east-1")
@ -242,36 +124,6 @@ def test_create_tags_boto3():
) )
# Has boto3 equivalent
@mock_ec2_deprecated
def test_tag_limit_exceeded():
conn = boto.connect_ec2("the_key", "the_secret")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
tag_dict = {}
for i in range(51):
tag_dict["{0:02d}".format(i + 1)] = ""
with pytest.raises(EC2ResponseError) as cm:
conn.create_tags(instance.id, tag_dict)
cm.value.code.should.equal("TagLimitExceeded")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
instance.add_tag("a key", "a value")
with pytest.raises(EC2ResponseError) as cm:
conn.create_tags(instance.id, tag_dict)
cm.value.code.should.equal("TagLimitExceeded")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
tags = conn.get_all_tags()
tag = tags[0]
tags.should.have.length_of(1)
tag.name.should.equal("a key")
tag.value.should.equal("a value")
@mock_ec2 @mock_ec2
def test_tag_limit_exceeded_boto3(): def test_tag_limit_exceeded_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1") ec2 = boto3.resource("ec2", region_name="us-east-1")
@ -302,37 +154,6 @@ def test_tag_limit_exceeded_boto3():
tags[0].should.have.key("Value").equal("a value") tags[0].should.have.key("Value").equal("a value")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_invalid_parameter_tag_null():
conn = boto.connect_ec2("the_key", "the_secret")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
with pytest.raises(EC2ResponseError) as cm:
instance.add_tag("a key", None)
cm.value.code.should.equal("InvalidParameterValue")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
# Has boto3 equivalent
@mock_ec2_deprecated
def test_invalid_id():
conn = boto.connect_ec2("the_key", "the_secret")
with pytest.raises(EC2ResponseError) as cm:
conn.create_tags("ami-blah", {"key": "tag"})
cm.value.code.should.equal("InvalidID")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
with pytest.raises(EC2ResponseError) as cm:
conn.create_tags("blah-blah", {"key": "tag"})
cm.value.code.should.equal("InvalidID")
cm.value.status.should.equal(400)
cm.value.request_id.should_not.be.none
@mock_ec2 @mock_ec2
def test_invalid_id_boto3(): def test_invalid_id_boto3():
client = boto3.client("ec2", region_name="us-east-1") client = boto3.client("ec2", region_name="us-east-1")
@ -353,34 +174,6 @@ def test_invalid_id_boto3():
ex.value.response["Error"]["Code"].should.equal("InvalidID") ex.value.response["Error"]["Code"].should.equal("InvalidID")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_get_all_tags_resource_id_filter():
conn = boto.connect_ec2("the_key", "the_secret")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
instance.add_tag("an instance key", "some value")
image_id = conn.create_image(instance.id, "test-ami", "this is a test ami")
image = conn.get_image(image_id)
image.add_tag("an image key", "some value")
tags = conn.get_all_tags(filters={"resource-id": instance.id})
tag = tags[0]
tags.should.have.length_of(1)
tag.res_id.should.equal(instance.id)
tag.res_type.should.equal("instance")
tag.name.should.equal("an instance key")
tag.value.should.equal("some value")
tags = conn.get_all_tags(filters={"resource-id": image_id})
tag = tags[0]
tags.should.have.length_of(1)
tag.res_id.should.equal(image_id)
tag.res_type.should.equal("image")
tag.name.should.equal("an image key")
tag.value.should.equal("some value")
@mock_ec2 @mock_ec2
def test_get_all_tags_resource_filter_boto3(): def test_get_all_tags_resource_filter_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1") ec2 = boto3.resource("ec2", region_name="us-east-1")
@ -433,99 +226,6 @@ def test_get_all_tags_resource_filter_boto3():
tags.should.equal([]) tags.should.equal([])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_get_all_tags_resource_type_filter():
conn = boto.connect_ec2("the_key", "the_secret")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
instance.add_tag("an instance key", "some value")
image_id = conn.create_image(instance.id, "test-ami", "this is a test ami")
image = conn.get_image(image_id)
image.add_tag("an image key", "some value")
tags = conn.get_all_tags(filters={"resource-type": "instance"})
tag = tags[0]
tags.should.have.length_of(1)
tag.res_id.should.equal(instance.id)
tag.res_type.should.equal("instance")
tag.name.should.equal("an instance key")
tag.value.should.equal("some value")
tags = conn.get_all_tags(filters={"resource-type": "image"})
tag = tags[0]
tags.should.have.length_of(1)
tag.res_id.should.equal(image_id)
tag.res_type.should.equal("image")
tag.name.should.equal("an image key")
tag.value.should.equal("some value")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_get_all_tags_key_filter():
conn = boto.connect_ec2("the_key", "the_secret")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
instance.add_tag("an instance key", "some value")
image_id = conn.create_image(instance.id, "test-ami", "this is a test ami")
image = conn.get_image(image_id)
image.add_tag("an image key", "some value")
tags = conn.get_all_tags(filters={"key": "an instance key"})
tag = tags[0]
tags.should.have.length_of(1)
tag.res_id.should.equal(instance.id)
tag.res_type.should.equal("instance")
tag.name.should.equal("an instance key")
tag.value.should.equal("some value")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_get_all_tags_value_filter():
conn = boto.connect_ec2("the_key", "the_secret")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance = reservation.instances[0]
instance.add_tag("an instance key", "some value")
reservation_b = conn.run_instances(EXAMPLE_AMI_ID)
instance_b = reservation_b.instances[0]
instance_b.add_tag("an instance key", "some other value")
reservation_c = conn.run_instances(EXAMPLE_AMI_ID)
instance_c = reservation_c.instances[0]
instance_c.add_tag("an instance key", "other value*")
reservation_d = conn.run_instances(EXAMPLE_AMI_ID)
instance_d = reservation_d.instances[0]
instance_d.add_tag("an instance key", "other value**")
reservation_e = conn.run_instances(EXAMPLE_AMI_ID)
instance_e = reservation_e.instances[0]
instance_e.add_tag("an instance key", "other value*?")
image_id = conn.create_image(instance.id, "test-ami", "this is a test ami")
image = conn.get_image(image_id)
image.add_tag("an image key", "some value")
tags = conn.get_all_tags(filters={"value": "some value"})
tags.should.have.length_of(2)
tags = conn.get_all_tags(filters={"value": "some*value"})
tags.should.have.length_of(3)
tags = conn.get_all_tags(filters={"value": "*some*value"})
tags.should.have.length_of(3)
tags = conn.get_all_tags(filters={"value": "*some*value*"})
tags.should.have.length_of(3)
tags = conn.get_all_tags(filters={"value": r"*value\*"})
tags.should.have.length_of(1)
tags = conn.get_all_tags(filters={"value": r"*value\*\*"})
tags.should.have.length_of(1)
tags = conn.get_all_tags(filters={"value": r"*value\*\?"})
tags.should.have.length_of(1)
@mock_ec2 @mock_ec2
def test_get_all_tags_value_filter_boto3(): def test_get_all_tags_value_filter_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1") ec2 = boto3.resource("ec2", region_name="us-east-1")
@ -564,38 +264,6 @@ def test_get_all_tags_value_filter_boto3():
filter_by_value(r"*value\*\?", [instance_e.id]) filter_by_value(r"*value\*\?", [instance_e.id])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_retrieved_instances_must_contain_their_tags():
tag_key = "Tag name"
tag_value = "Tag value"
tags_to_be_set = {tag_key: tag_value}
conn = boto.connect_ec2("the_key", "the_secret")
reservation = conn.run_instances(EXAMPLE_AMI_ID)
reservation.should.be.a(Reservation)
reservation.instances.should.have.length_of(1)
instance = reservation.instances[0]
reservations = conn.get_all_reservations()
reservations.should.have.length_of(1)
reservations[0].id.should.equal(reservation.id)
instances = reservations[0].instances
instances.should.have.length_of(1)
instances[0].id.should.equal(instance.id)
conn.create_tags([instance.id], tags_to_be_set)
reservations = conn.get_all_reservations()
instance = reservations[0].instances[0]
retrieved_tags = instance.tags
# Cleanup of instance
conn.terminate_instances([instances[0].id])
# Check whether tag is present with correct value
retrieved_tags[tag_key].should.equal(tag_value)
@mock_ec2 @mock_ec2
def test_retrieved_instances_must_contain_their_tags_boto3(): def test_retrieved_instances_must_contain_their_tags_boto3():
tag_key = "Tag name" tag_key = "Tag name"
@ -622,30 +290,6 @@ def test_retrieved_instances_must_contain_their_tags_boto3():
retrieved_tags.should.equal([{"Key": tag_key, "Value": tag_value}]) retrieved_tags.should.equal([{"Key": tag_key, "Value": tag_value}])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_retrieved_volumes_must_contain_their_tags():
tag_key = "Tag name"
tag_value = "Tag value"
tags_to_be_set = {tag_key: tag_value}
conn = boto.connect_ec2("the_key", "the_secret")
volume = conn.create_volume(80, "us-east-1a")
all_volumes = conn.get_all_volumes()
volume = all_volumes[0]
conn.create_tags([volume.id], tags_to_be_set)
# Fetch the volume again
all_volumes = conn.get_all_volumes()
volume = all_volumes[0]
retrieved_tags = volume.tags
volume.delete()
# Check whether tag is present with correct value
retrieved_tags[tag_key].should.equal(tag_value)
@mock_ec2 @mock_ec2
def test_retrieved_volumes_must_contain_their_tags_boto3(): def test_retrieved_volumes_must_contain_their_tags_boto3():
tag_key = "Tag name" tag_key = "Tag name"
@ -663,31 +307,6 @@ def test_retrieved_volumes_must_contain_their_tags_boto3():
volume.tags.should.equal([{"Key": tag_key, "Value": tag_value}]) volume.tags.should.equal([{"Key": tag_key, "Value": tag_value}])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_retrieved_snapshots_must_contain_their_tags():
tag_key = "Tag name"
tag_value = "Tag value"
tags_to_be_set = {tag_key: tag_value}
conn = boto.connect_ec2(
aws_access_key_id="the_key", aws_secret_access_key="the_secret"
)
volume = conn.create_volume(80, "eu-west-1a")
snapshot = conn.create_snapshot(volume.id)
conn.create_tags([snapshot.id], tags_to_be_set)
# Fetch the snapshot again
all_snapshots = conn.get_all_snapshots()
snapshot = [item for item in all_snapshots if item.id == snapshot.id][0]
retrieved_tags = snapshot.tags
conn.delete_snapshot(snapshot.id)
volume.delete()
# Check whether tag is present with correct value
retrieved_tags[tag_key].should.equal(tag_value)
@mock_ec2 @mock_ec2
def test_retrieved_snapshots_must_contain_their_tags_boto3(): def test_retrieved_snapshots_must_contain_their_tags_boto3():
tag_key = "Tag name" tag_key = "Tag name"
@ -705,29 +324,6 @@ def test_retrieved_snapshots_must_contain_their_tags_boto3():
snapshot["Tags"].should.equal([{"Key": tag_key, "Value": tag_value}]) snapshot["Tags"].should.equal([{"Key": tag_key, "Value": tag_value}])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_filter_instances_by_wildcard_tags():
conn = boto.connect_ec2(
aws_access_key_id="the_key", aws_secret_access_key="the_secret"
)
reservation = conn.run_instances(EXAMPLE_AMI_ID)
instance_a = reservation.instances[0]
instance_a.add_tag("Key1", "Value1")
reservation_b = conn.run_instances(EXAMPLE_AMI_ID)
instance_b = reservation_b.instances[0]
instance_b.add_tag("Key1", "Value2")
reservations = conn.get_all_reservations(filters={"tag:Key1": "Value*"})
reservations.should.have.length_of(2)
reservations = conn.get_all_reservations(filters={"tag-key": "Key*"})
reservations.should.have.length_of(2)
reservations = conn.get_all_reservations(filters={"tag-value": "Value*"})
reservations.should.have.length_of(2)
@mock_ec2 @mock_ec2
def test_filter_instances_by_wildcard_tags_boto3(): def test_filter_instances_by_wildcard_tags_boto3():
ec2 = boto3.resource("ec2", region_name="eu-west-1") ec2 = boto3.resource("ec2", region_name="eu-west-1")

View File

@ -1,9 +1,8 @@
import boto
import boto3 import boto3
import pytest import pytest
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
from moto import mock_ec2_deprecated, mock_ec2 from moto import mock_ec2
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
from .test_tags import retrieve_all_tagged from .test_tags import retrieve_all_tagged
@ -97,6 +96,41 @@ def test_describe_vpn_connections_state_filter_attached():
my_gateway["VpcAttachments"].should.contain({"State": "attached", "VpcId": vpc_id}) my_gateway["VpcAttachments"].should.contain({"State": "attached", "VpcId": vpc_id})
@mock_ec2
def test_virtual_private_gateways_boto3():
client = boto3.client("ec2", region_name="us-west-1")
vpn_gateway = client.create_vpn_gateway(
Type="ipsec.1", AvailabilityZone="us-east-1a"
)["VpnGateway"]
vpn_gateway["VpnGatewayId"].should.match(r"vgw-\w+")
vpn_gateway["Type"].should.equal("ipsec.1")
vpn_gateway["State"].should.equal("available")
vpn_gateway["AvailabilityZone"].should.equal("us-east-1a")
@mock_ec2
def test_describe_vpn_gateway_boto3():
client = boto3.client("ec2", region_name="us-west-1")
vpn_gateway = client.create_vpn_gateway(
Type="ipsec.1", AvailabilityZone="us-east-1a"
)["VpnGateway"]
vgws = client.describe_vpn_gateways(VpnGatewayIds=[vpn_gateway["VpnGatewayId"]])[
"VpnGateways"
]
vgws.should.have.length_of(1)
gateway = vgws[0]
gateway["VpnGatewayId"].should.match(r"vgw-\w+")
gateway["VpnGatewayId"].should.equal(vpn_gateway["VpnGatewayId"])
# TODO: fixme. This currently returns the ID
# gateway["Type"].should.equal("ipsec.1")
gateway["State"].should.equal("available")
gateway["AvailabilityZone"].should.equal("us-east-1a")
@mock_ec2 @mock_ec2
def test_describe_vpn_connections_state_filter_deatched(): def test_describe_vpn_connections_state_filter_deatched():
"""describe_vpn_gateways attachment.state filter - don't match detatched""" """describe_vpn_gateways attachment.state filter - don't match detatched"""
@ -178,87 +212,6 @@ def test_describe_vpn_connections_type_filter_miss():
gateways["VpnGateways"].should.have.length_of(0) gateways["VpnGateways"].should.have.length_of(0)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_virtual_private_gateways():
conn = boto.connect_vpc("the_key", "the_secret")
vpn_gateway = conn.create_vpn_gateway("ipsec.1", "us-east-1a")
vpn_gateway.should_not.be.none
vpn_gateway.id.should.match(r"vgw-\w+")
vpn_gateway.type.should.equal("ipsec.1")
vpn_gateway.state.should.equal("available")
vpn_gateway.availability_zone.should.equal("us-east-1a")
@mock_ec2
def test_virtual_private_gateways_boto3():
client = boto3.client("ec2", region_name="us-west-1")
vpn_gateway = client.create_vpn_gateway(
Type="ipsec.1", AvailabilityZone="us-east-1a"
)["VpnGateway"]
vpn_gateway["VpnGatewayId"].should.match(r"vgw-\w+")
vpn_gateway["Type"].should.equal("ipsec.1")
vpn_gateway["State"].should.equal("available")
vpn_gateway["AvailabilityZone"].should.equal("us-east-1a")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_describe_vpn_gateway():
conn = boto.connect_vpc("the_key", "the_secret")
vpn_gateway = conn.create_vpn_gateway("ipsec.1", "us-east-1a")
vgws = conn.get_all_vpn_gateways()
vgws.should.have.length_of(1)
gateway = vgws[0]
gateway.id.should.match(r"vgw-\w+")
gateway.id.should.equal(vpn_gateway.id)
vpn_gateway.type.should.equal("ipsec.1")
vpn_gateway.state.should.equal("available")
vpn_gateway.availability_zone.should.equal("us-east-1a")
@mock_ec2
def test_describe_vpn_gateway_boto3():
client = boto3.client("ec2", region_name="us-west-1")
vpn_gateway = client.create_vpn_gateway(
Type="ipsec.1", AvailabilityZone="us-east-1a"
)["VpnGateway"]
vgws = client.describe_vpn_gateways(VpnGatewayIds=[vpn_gateway["VpnGatewayId"]])[
"VpnGateways"
]
vgws.should.have.length_of(1)
gateway = vgws[0]
gateway["VpnGatewayId"].should.match(r"vgw-\w+")
gateway["VpnGatewayId"].should.equal(vpn_gateway["VpnGatewayId"])
# TODO: fixme. This currently returns the ID
# gateway["Type"].should.equal("ipsec.1")
gateway["State"].should.equal("available")
gateway["AvailabilityZone"].should.equal("us-east-1a")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_vpn_gateway_vpc_attachment():
conn = boto.connect_vpc("the_key", "the_secret")
vpc = conn.create_vpc("10.0.0.0/16")
vpn_gateway = conn.create_vpn_gateway("ipsec.1", "us-east-1a")
conn.attach_vpn_gateway(vpn_gateway_id=vpn_gateway.id, vpc_id=vpc.id)
gateway = conn.get_all_vpn_gateways()[0]
attachments = gateway.attachments
attachments.should.have.length_of(1)
attachments[0].vpc_id.should.equal(vpc.id)
attachments[0].state.should.equal("attached")
@mock_ec2 @mock_ec2
def test_vpn_gateway_vpc_attachment_boto3(): def test_vpn_gateway_vpc_attachment_boto3():
ec2 = boto3.resource("ec2", region_name="us-west-1") ec2 = boto3.resource("ec2", region_name="us-west-1")
@ -276,18 +229,6 @@ def test_vpn_gateway_vpc_attachment_boto3():
attachments.should.equal([{"State": "attached", "VpcId": vpc.id}]) attachments.should.equal([{"State": "attached", "VpcId": vpc.id}])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_delete_vpn_gateway():
conn = boto.connect_vpc("the_key", "the_secret")
vpn_gateway = conn.create_vpn_gateway("ipsec.1", "us-east-1a")
conn.delete_vpn_gateway(vpn_gateway.id)
vgws = conn.get_all_vpn_gateways()
vgws.should.have.length_of(1)
vgws[0].state.should.equal("deleted")
@mock_ec2 @mock_ec2
def test_delete_vpn_gateway_boto3(): def test_delete_vpn_gateway_boto3():
client = boto3.client("ec2", region_name="us-west-1") client = boto3.client("ec2", region_name="us-west-1")
@ -302,23 +243,6 @@ def test_delete_vpn_gateway_boto3():
gateways[0].should.have.key("State").equal("deleted") gateways[0].should.have.key("State").equal("deleted")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_vpn_gateway_tagging():
conn = boto.connect_vpc("the_key", "the_secret")
vpn_gateway = conn.create_vpn_gateway("ipsec.1", "us-east-1a")
vpn_gateway.add_tag("a key", "some value")
tag = conn.get_all_tags()[0]
tag.name.should.equal("a key")
tag.value.should.equal("some value")
# Refresh the subnet
vpn_gateway = conn.get_all_vpn_gateways()[0]
vpn_gateway.tags.should.have.length_of(1)
vpn_gateway.tags["a key"].should.equal("some value")
@mock_ec2 @mock_ec2
def test_vpn_gateway_tagging_boto3(): def test_vpn_gateway_tagging_boto3():
client = boto3.client("ec2", region_name="us-west-1") client = boto3.client("ec2", region_name="us-west-1")
@ -340,30 +264,6 @@ def test_vpn_gateway_tagging_boto3():
# vpn_gateway["Tags"].should.equal([{'Key': 'a key', 'Value': 'some value'}]) # vpn_gateway["Tags"].should.equal([{'Key': 'a key', 'Value': 'some value'}])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_detach_vpn_gateway():
conn = boto.connect_vpc("the_key", "the_secret")
vpc = conn.create_vpc("10.0.0.0/16")
vpn_gateway = conn.create_vpn_gateway("ipsec.1", "us-east-1a")
conn.attach_vpn_gateway(vpn_gateway_id=vpn_gateway.id, vpc_id=vpc.id)
gateway = conn.get_all_vpn_gateways()[0]
attachments = gateway.attachments
attachments.should.have.length_of(1)
attachments[0].vpc_id.should.equal(vpc.id)
attachments[0].state.should.equal("attached")
conn.detach_vpn_gateway(vpn_gateway_id=vpn_gateway.id, vpc_id=vpc.id)
gateway = conn.get_all_vpn_gateways()[0]
attachments = gateway.attachments
attachments.should.have.length_of(1)
attachments[0].state.should.equal("detached")
@mock_ec2 @mock_ec2
def test_detach_vpn_gateway_boto3(): def test_detach_vpn_gateway_boto3():
ec2 = boto3.resource("ec2", region_name="us-west-1") ec2 = boto3.resource("ec2", region_name="us-west-1")

Some files were not shown because too many files have changed in this diff Show More