Remove deprecated decorators + boto dependency (#4378)
This commit is contained in:
parent
3adb5ea84f
commit
aa70ee254d
@ -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
|
@ -33,7 +33,6 @@ Additional Resources
|
||||
docs/getting_started
|
||||
docs/server_mode
|
||||
docs/faq
|
||||
docs/boto
|
||||
docs/iam
|
||||
docs/aws_config
|
||||
|
||||
|
@ -26,68 +26,47 @@ def lazy_load(
|
||||
|
||||
mock_acm = lazy_load(".acm", "mock_acm")
|
||||
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_athena = lazy_load(".athena", "mock_athena")
|
||||
mock_applicationautoscaling = lazy_load(
|
||||
".applicationautoscaling", "mock_applicationautoscaling"
|
||||
)
|
||||
mock_autoscaling = lazy_load(".autoscaling", "mock_autoscaling")
|
||||
mock_autoscaling_deprecated = lazy_load(".autoscaling", "mock_autoscaling_deprecated")
|
||||
mock_lambda = lazy_load(
|
||||
".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_budgets = lazy_load(".budgets", "mock_budgets")
|
||||
mock_cloudformation = lazy_load(".cloudformation", "mock_cloudformation")
|
||||
mock_cloudformation_deprecated = lazy_load(
|
||||
".cloudformation", "mock_cloudformation_deprecated"
|
||||
)
|
||||
mock_cloudfront = lazy_load(".cloudfront", "mock_cloudfront")
|
||||
mock_cloudtrail = lazy_load(".cloudtrail", "mock_cloudtrail", boto3_name="cloudtrail")
|
||||
mock_cloudwatch = lazy_load(".cloudwatch", "mock_cloudwatch")
|
||||
mock_cloudwatch_deprecated = lazy_load(".cloudwatch", "mock_cloudwatch_deprecated")
|
||||
mock_codecommit = lazy_load(".codecommit", "mock_codecommit")
|
||||
mock_codepipeline = lazy_load(".codepipeline", "mock_codepipeline")
|
||||
mock_cognitoidentity = lazy_load(
|
||||
".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_deprecated = lazy_load(".cognitoidp", "mock_cognitoidp_deprecated")
|
||||
mock_config = lazy_load(".config", "mock_config")
|
||||
mock_datapipeline = lazy_load(".datapipeline", "mock_datapipeline")
|
||||
mock_datapipeline_deprecated = lazy_load(
|
||||
".datapipeline", "mock_datapipeline_deprecated"
|
||||
)
|
||||
mock_datasync = lazy_load(".datasync", "mock_datasync")
|
||||
mock_dax = lazy_load(".dax", "mock_dax")
|
||||
mock_dms = lazy_load(".dms", "mock_dms")
|
||||
mock_ds = lazy_load(".ds", "mock_ds", boto3_name="ds")
|
||||
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_deprecated = lazy_load(".dynamodb2", "mock_dynamodb2_deprecated")
|
||||
mock_dynamodbstreams = lazy_load(".dynamodbstreams", "mock_dynamodbstreams")
|
||||
mock_elasticbeanstalk = lazy_load(
|
||||
".elasticbeanstalk", "mock_elasticbeanstalk", backend="eb_backends"
|
||||
)
|
||||
mock_ec2 = lazy_load(".ec2", "mock_ec2")
|
||||
mock_ec2_deprecated = lazy_load(".ec2", "mock_ec2_deprecated")
|
||||
mock_ec2instanceconnect = lazy_load(".ec2instanceconnect", "mock_ec2instanceconnect")
|
||||
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_deprecated = lazy_load(".ecs", "mock_ecs_deprecated")
|
||||
mock_elastictranscoder = lazy_load(".elastictranscoder", "mock_elastictranscoder")
|
||||
mock_elb = lazy_load(".elb", "mock_elb")
|
||||
mock_elb_deprecated = lazy_load(".elb", "mock_elb_deprecated")
|
||||
mock_elbv2 = lazy_load(".elbv2", "mock_elbv2")
|
||||
mock_emr = lazy_load(".emr", "mock_emr")
|
||||
mock_emr_deprecated = lazy_load(".emr", "mock_emr_deprecated")
|
||||
mock_emrcontainers = lazy_load(
|
||||
".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_forecast = lazy_load(".forecast", "mock_forecast")
|
||||
mock_glacier = lazy_load(".glacier", "mock_glacier")
|
||||
mock_glacier_deprecated = lazy_load(".glacier", "mock_glacier_deprecated")
|
||||
mock_glue = lazy_load(".glue", "mock_glue")
|
||||
mock_guardduty = lazy_load(".guardduty", "mock_guardduty")
|
||||
mock_iam = lazy_load(".iam", "mock_iam")
|
||||
mock_iam_deprecated = lazy_load(".iam", "mock_iam_deprecated")
|
||||
mock_iot = lazy_load(".iot", "mock_iot")
|
||||
mock_iotdata = lazy_load(".iotdata", "mock_iotdata", boto3_name="iot-data")
|
||||
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_deprecated = lazy_load(".kms", "mock_kms_deprecated")
|
||||
mock_logs = lazy_load(".logs", "mock_logs")
|
||||
mock_logs_deprecated = lazy_load(".logs", "mock_logs_deprecated")
|
||||
mock_managedblockchain = lazy_load(".managedblockchain", "mock_managedblockchain")
|
||||
mock_opsworks = lazy_load(".opsworks", "mock_opsworks")
|
||||
mock_opsworks_deprecated = lazy_load(".opsworks", "mock_opsworks_deprecated")
|
||||
mock_organizations = lazy_load(".organizations", "mock_organizations")
|
||||
mock_polly = lazy_load(".polly", "mock_polly")
|
||||
mock_ram = lazy_load(".ram", "mock_ram")
|
||||
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_deprecated = lazy_load(".rds2", "mock_rds2_deprecated")
|
||||
mock_redshift = lazy_load(".redshift", "mock_redshift")
|
||||
mock_redshift_deprecated = lazy_load(".redshift", "mock_redshift_deprecated")
|
||||
mock_resourcegroups = lazy_load(
|
||||
".resourcegroups", "mock_resourcegroups", boto3_name="resource-groups"
|
||||
)
|
||||
@ -128,29 +98,22 @@ mock_resourcegroupstaggingapi = lazy_load(
|
||||
".resourcegroupstaggingapi", "mock_resourcegroupstaggingapi"
|
||||
)
|
||||
mock_route53 = lazy_load(".route53", "mock_route53")
|
||||
mock_route53_deprecated = lazy_load(".route53", "mock_route53_deprecated")
|
||||
mock_route53resolver = lazy_load(
|
||||
".route53resolver", "mock_route53resolver", boto3_name="route53resolver"
|
||||
)
|
||||
mock_s3 = lazy_load(".s3", "mock_s3")
|
||||
mock_s3_deprecated = lazy_load(".s3", "mock_s3_deprecated")
|
||||
mock_sagemaker = lazy_load(".sagemaker", "mock_sagemaker")
|
||||
mock_secretsmanager = lazy_load(".secretsmanager", "mock_secretsmanager")
|
||||
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_deprecated = lazy_load(".sns", "mock_sns_deprecated")
|
||||
mock_sqs = lazy_load(".sqs", "mock_sqs")
|
||||
mock_sqs_deprecated = lazy_load(".sqs", "mock_sqs_deprecated")
|
||||
mock_ssm = lazy_load(".ssm", "mock_ssm")
|
||||
mock_ssoadmin = lazy_load(".ssoadmin", "mock_ssoadmin", boto3_name="sso-admin")
|
||||
mock_stepfunctions = lazy_load(
|
||||
".stepfunctions", "mock_stepfunctions", backend="stepfunction_backends"
|
||||
)
|
||||
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_deprecated = lazy_load(".swf", "mock_swf_deprecated")
|
||||
mock_timestreamwrite = lazy_load(
|
||||
".timestreamwrite", "mock_timestreamwrite", boto3_name="timestream-write"
|
||||
)
|
||||
|
@ -1,6 +1,5 @@
|
||||
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"]
|
||||
mock_apigateway = base_decorator(apigateway_backends)
|
||||
mock_apigateway_deprecated = deprecated_base_decorator(apigateway_backends)
|
||||
|
@ -1,6 +1,5 @@
|
||||
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"]
|
||||
mock_athena = base_decorator(athena_backends)
|
||||
mock_athena_deprecated = deprecated_base_decorator(athena_backends)
|
||||
|
@ -1,6 +1,5 @@
|
||||
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"]
|
||||
mock_autoscaling = base_decorator(autoscaling_backends)
|
||||
mock_autoscaling_deprecated = deprecated_base_decorator(autoscaling_backends)
|
||||
|
@ -1,6 +1,5 @@
|
||||
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"]
|
||||
mock_lambda = base_decorator(lambda_backends)
|
||||
mock_lambda_deprecated = deprecated_base_decorator(lambda_backends)
|
||||
|
@ -1,6 +1,5 @@
|
||||
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"]
|
||||
mock_cloudformation = base_decorator(cloudformation_backends)
|
||||
mock_cloudformation_deprecated = deprecated_base_decorator(cloudformation_backends)
|
||||
|
@ -57,7 +57,6 @@ from .exceptions import (
|
||||
ValidationError,
|
||||
UnsupportedAttribute,
|
||||
)
|
||||
from moto.packages.boto.cloudformation.stack import Output
|
||||
|
||||
# List of supported CloudFormation models
|
||||
MODEL_LIST = CloudFormationModel.__subclasses__()
|
||||
@ -78,6 +77,17 @@ DEFAULT_REGION = "us-east-1"
|
||||
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):
|
||||
def __getitem__(self, key):
|
||||
val = dict.__getitem__(self, key)
|
||||
|
@ -1,5 +1,4 @@
|
||||
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_deprecated = deprecated_base_decorator(cloudwatch_backends)
|
||||
|
@ -1,5 +1,4 @@
|
||||
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_deprecated = deprecated_base_decorator(cognitoidentity_backends)
|
||||
|
@ -1,5 +1,4 @@
|
||||
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_deprecated = deprecated_base_decorator(cognitoidp_backends)
|
||||
|
@ -16,7 +16,6 @@ from botocore.awsrequest import AWSResponse
|
||||
|
||||
from moto import settings
|
||||
import responses
|
||||
from moto.packages.httpretty import HTTPretty
|
||||
from unittest.mock import patch
|
||||
from .custom_responses_mock import (
|
||||
get_response_mock,
|
||||
@ -25,7 +24,6 @@ from .custom_responses_mock import (
|
||||
reset_responses_mock,
|
||||
)
|
||||
from .utils import (
|
||||
convert_httpretty_response,
|
||||
convert_regex_to_flask_path,
|
||||
convert_flask_to_responses_response,
|
||||
)
|
||||
@ -177,28 +175,6 @@ class BaseMockAWS:
|
||||
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.GET,
|
||||
responses.DELETE,
|
||||
@ -681,12 +657,6 @@ class BaseBackend:
|
||||
else:
|
||||
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):
|
||||
# """For AWS Config. This will list all of the resources of the given type and optional resource name and region"""
|
||||
# raise NotImplementedError()
|
||||
@ -792,7 +762,7 @@ class base_decorator:
|
||||
self.backends = backends
|
||||
|
||||
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)
|
||||
else:
|
||||
mocked_backend = self.mock_backend(self.backends)
|
||||
@ -803,10 +773,6 @@ class base_decorator:
|
||||
return mocked_backend
|
||||
|
||||
|
||||
class deprecated_base_decorator(base_decorator):
|
||||
mock_backend = HttprettyMockAWS
|
||||
|
||||
|
||||
class MotoAPIBackend(BaseBackend):
|
||||
def reset(self):
|
||||
import moto.backends as backends
|
||||
|
@ -106,29 +106,7 @@ def convert_regex_to_flask_path(url_path):
|
||||
return url_path
|
||||
|
||||
|
||||
class convert_httpretty_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):
|
||||
class convert_to_flask_response(object):
|
||||
def __init__(self, callback):
|
||||
self.callback = callback
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
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_deprecated = deprecated_base_decorator(datapipeline_backends)
|
||||
|
@ -1,6 +1,5 @@
|
||||
from ..core.models import base_decorator, deprecated_base_decorator
|
||||
from ..core.models import base_decorator
|
||||
from .models import datasync_backends
|
||||
|
||||
datasync_backend = datasync_backends["us-east-1"]
|
||||
mock_datasync = base_decorator(datasync_backends)
|
||||
mock_datasync_deprecated = deprecated_base_decorator(datasync_backends)
|
||||
|
@ -2,4 +2,3 @@ from .models import dynamodb_backend
|
||||
|
||||
dynamodb_backends = {"global": dynamodb_backend}
|
||||
mock_dynamodb = dynamodb_backend.decorator
|
||||
mock_dynamodb_deprecated = dynamodb_backend.deprecated_decorator
|
||||
|
@ -1,6 +1,5 @@
|
||||
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"]
|
||||
mock_dynamodb2 = base_decorator(dynamodb_backends2)
|
||||
mock_dynamodb2_deprecated = deprecated_base_decorator(dynamodb_backends2)
|
||||
|
@ -1,5 +1,4 @@
|
||||
import re
|
||||
import sys
|
||||
|
||||
from moto.dynamodb2.exceptions import (
|
||||
InvalidTokenException,
|
||||
@ -148,16 +147,9 @@ class ExpressionTokenizer(object):
|
||||
self.token_list = []
|
||||
self.staged_characters = ""
|
||||
|
||||
@classmethod
|
||||
def is_py2(cls):
|
||||
return sys.version_info[0] == 2
|
||||
|
||||
@classmethod
|
||||
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()
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
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"]
|
||||
mock_ec2 = base_decorator(ec2_backends)
|
||||
mock_ec2_deprecated = deprecated_base_decorator(ec2_backends)
|
||||
|
@ -1,6 +1,5 @@
|
||||
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"]
|
||||
mock_ecr = base_decorator(ecr_backends)
|
||||
mock_ecr_deprecated = deprecated_base_decorator(ecr_backends)
|
||||
|
@ -1,6 +1,5 @@
|
||||
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"]
|
||||
mock_ecs = base_decorator(ecs_backends)
|
||||
mock_ecs_deprecated = deprecated_base_decorator(ecs_backends)
|
||||
|
@ -1,6 +1,5 @@
|
||||
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"]
|
||||
mock_elb = base_decorator(elb_backends)
|
||||
mock_elb_deprecated = deprecated_base_decorator(elb_backends)
|
||||
|
@ -2,13 +2,6 @@ import datetime
|
||||
|
||||
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 collections import OrderedDict
|
||||
from moto.core import BaseBackend, BaseModel, CloudFormationModel
|
||||
@ -248,23 +241,11 @@ class FakeLoadBalancer(CloudFormationModel):
|
||||
|
||||
@classmethod
|
||||
def get_default_attributes(cls):
|
||||
attributes = LbAttributes()
|
||||
|
||||
cross_zone_load_balancing = CrossZoneLoadBalancingAttribute()
|
||||
cross_zone_load_balancing.enabled = False
|
||||
attributes.cross_zone_load_balancing = cross_zone_load_balancing
|
||||
|
||||
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
|
||||
attributes = dict()
|
||||
attributes["cross_zone_load_balancing"] = {"enabled": False}
|
||||
attributes["connection_draining"] = {"enabled": False}
|
||||
attributes["access_log"] = {"enabled": False}
|
||||
attributes["connection_settings"] = {"idle_timeout": 60}
|
||||
|
||||
return attributes
|
||||
|
||||
@ -468,25 +449,27 @@ class ELBBackend(BaseBackend):
|
||||
|
||||
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.attributes.cross_zone_load_balancing = attribute
|
||||
return load_balancer
|
||||
|
||||
def set_access_log_attribute(self, load_balancer_name, attribute):
|
||||
load_balancer = self.get_load_balancer(load_balancer_name)
|
||||
load_balancer.attributes.access_log = attribute
|
||||
return load_balancer
|
||||
|
||||
def set_connection_draining_attribute(self, load_balancer_name, attribute):
|
||||
load_balancer = self.get_load_balancer(load_balancer_name)
|
||||
load_balancer.attributes.connection_draining = attribute
|
||||
return load_balancer
|
||||
|
||||
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
|
||||
if cross_zone:
|
||||
load_balancer.attributes["cross_zone_load_balancing"] = cross_zone
|
||||
if connection_settings:
|
||||
load_balancer.attributes["connection_settings"] = connection_settings
|
||||
if connection_draining:
|
||||
load_balancer.attributes["connection_draining"] = connection_draining
|
||||
if "timeout" not in connection_draining:
|
||||
load_balancer.attributes["connection_draining"][
|
||||
"timeout"
|
||||
] = 300 # default
|
||||
if access_log:
|
||||
load_balancer.attributes["access_log"] = access_log
|
||||
|
||||
def create_lb_other_policy(self, load_balancer_name, other_policy):
|
||||
load_balancer = self.get_load_balancer(load_balancer_name)
|
||||
|
@ -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.core.responses import BaseResponse
|
||||
@ -153,40 +147,30 @@ class ELBResponse(BaseResponse):
|
||||
"LoadBalancerAttributes.CrossZoneLoadBalancing."
|
||||
)
|
||||
if cross_zone:
|
||||
attribute = CrossZoneLoadBalancingAttribute()
|
||||
attribute.enabled = cross_zone["enabled"] == "true"
|
||||
self.elb_backend.set_cross_zone_load_balancing_attribute(
|
||||
load_balancer_name, attribute
|
||||
self.elb_backend.modify_load_balancer_attributes(
|
||||
load_balancer_name, cross_zone=cross_zone
|
||||
)
|
||||
|
||||
access_log = self._get_dict_param("LoadBalancerAttributes.AccessLog.")
|
||||
if access_log:
|
||||
attribute = AccessLogAttribute()
|
||||
attribute.enabled = access_log["enabled"] == "true"
|
||||
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)
|
||||
self.elb_backend.modify_load_balancer_attributes(
|
||||
load_balancer_name, access_log=access_log
|
||||
)
|
||||
|
||||
connection_draining = self._get_dict_param(
|
||||
"LoadBalancerAttributes.ConnectionDraining."
|
||||
)
|
||||
if connection_draining:
|
||||
attribute = ConnectionDrainingAttribute()
|
||||
attribute.enabled = connection_draining["enabled"] == "true"
|
||||
attribute.timeout = connection_draining.get("timeout", 300)
|
||||
self.elb_backend.set_connection_draining_attribute(
|
||||
load_balancer_name, attribute
|
||||
self.elb_backend.modify_load_balancer_attributes(
|
||||
load_balancer_name, connection_draining=connection_draining
|
||||
)
|
||||
|
||||
connection_settings = self._get_dict_param(
|
||||
"LoadBalancerAttributes.ConnectionSettings."
|
||||
)
|
||||
if connection_settings:
|
||||
attribute = ConnectionSettingAttribute()
|
||||
attribute.idle_timeout = connection_settings["idle_timeout"]
|
||||
self.elb_backend.set_connection_settings_attribute(
|
||||
load_balancer_name, attribute
|
||||
self.elb_backend.modify_load_balancer_attributes(
|
||||
load_balancer_name, connection_settings=connection_settings
|
||||
)
|
||||
|
||||
template = self.response_template(MODIFY_ATTRIBUTES_TEMPLATE)
|
||||
@ -628,23 +612,23 @@ DESCRIBE_ATTRIBUTES_TEMPLATE = """<DescribeLoadBalancerAttributesResponse xmlns
|
||||
<DescribeLoadBalancerAttributesResult>
|
||||
<LoadBalancerAttributes>
|
||||
<AccessLog>
|
||||
<Enabled>{{ attributes.access_log.enabled }}</Enabled>
|
||||
{% if attributes.access_log.enabled %}
|
||||
<S3BucketName>{{ attributes.access_log.s3_bucket_name }}</S3BucketName>
|
||||
<S3BucketPrefix>{{ attributes.access_log.s3_bucket_prefix }}</S3BucketPrefix>
|
||||
<EmitInterval>{{ attributes.access_log.emit_interval }}</EmitInterval>
|
||||
<Enabled>{{ attributes["access_log"]["enabled"] }}</Enabled>
|
||||
{% if attributes["access_log"]["enabled"] == 'true' %}
|
||||
<S3BucketName>{{ attributes["access_log"]["s3_bucket_name"] }}</S3BucketName>
|
||||
<S3BucketPrefix>{{ attributes["access_log"]["s3_bucket_prefix"] }}</S3BucketPrefix>
|
||||
<EmitInterval>{{ attributes["access_log"]["emit_interval"] }}</EmitInterval>
|
||||
{% endif %}
|
||||
</AccessLog>
|
||||
<ConnectionSettings>
|
||||
<IdleTimeout>{{ attributes.connecting_settings.idle_timeout }}</IdleTimeout>
|
||||
<IdleTimeout>{{ attributes["connection_settings"]["idle_timeout"] }}</IdleTimeout>
|
||||
</ConnectionSettings>
|
||||
<CrossZoneLoadBalancing>
|
||||
<Enabled>{{ attributes.cross_zone_load_balancing.enabled }}</Enabled>
|
||||
</CrossZoneLoadBalancing>
|
||||
<ConnectionDraining>
|
||||
{% if attributes.connection_draining.enabled %}
|
||||
{% if attributes["connection_draining"]["enabled"] == 'true' %}
|
||||
<Enabled>true</Enabled>
|
||||
<Timeout>{{ attributes.connection_draining.timeout }}</Timeout>
|
||||
<Timeout>{{ attributes["connection_draining"]["timeout"] }}</Timeout>
|
||||
{% else %}
|
||||
<Enabled>false</Enabled>
|
||||
{% endif %}
|
||||
@ -662,23 +646,23 @@ MODIFY_ATTRIBUTES_TEMPLATE = """<ModifyLoadBalancerAttributesResponse xmlns="htt
|
||||
<LoadBalancerName>{{ load_balancer.name }}</LoadBalancerName>
|
||||
<LoadBalancerAttributes>
|
||||
<AccessLog>
|
||||
<Enabled>{{ attributes.access_log.enabled }}</Enabled>
|
||||
{% if attributes.access_log.enabled %}
|
||||
<S3BucketName>{{ attributes.access_log.s3_bucket_name }}</S3BucketName>
|
||||
<S3BucketPrefix>{{ attributes.access_log.s3_bucket_prefix }}</S3BucketPrefix>
|
||||
<EmitInterval>{{ attributes.access_log.emit_interval }}</EmitInterval>
|
||||
<Enabled>{{ attributes["access_log"]["enabled"] == 'true' }}</Enabled>
|
||||
{% if attributes["access_log"]["enabled"] == 'true' %}
|
||||
<S3BucketName>{{ attributes["access_log"]["s3_bucket_name"] }}</S3BucketName>
|
||||
<S3BucketPrefix>{{ attributes["access_log"]["s3_bucket_prefix"] }}</S3BucketPrefix>
|
||||
<EmitInterval>{{ attributes["access_log"]["emit_interval"] }}</EmitInterval>
|
||||
{% endif %}
|
||||
</AccessLog>
|
||||
<ConnectionSettings>
|
||||
<IdleTimeout>{{ attributes.connecting_settings.idle_timeout }}</IdleTimeout>
|
||||
<IdleTimeout>{{ attributes["connection_settings"]["idle_timeout"] }}</IdleTimeout>
|
||||
</ConnectionSettings>
|
||||
<CrossZoneLoadBalancing>
|
||||
<Enabled>{{ attributes.cross_zone_load_balancing.enabled }}</Enabled>
|
||||
</CrossZoneLoadBalancing>
|
||||
<ConnectionDraining>
|
||||
{% if attributes.connection_draining.enabled %}
|
||||
{% if attributes["connection_draining"]["enabled"] == 'true' %}
|
||||
<Enabled>true</Enabled>
|
||||
<Timeout>{{ attributes.connection_draining.timeout }}</Timeout>
|
||||
<Timeout>{{ attributes["connection_draining"]["timeout"] }}</Timeout>
|
||||
{% else %}
|
||||
<Enabled>false</Enabled>
|
||||
{% endif %}
|
||||
|
@ -1,6 +1,5 @@
|
||||
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"]
|
||||
mock_emr = base_decorator(emr_backends)
|
||||
mock_emr_deprecated = deprecated_base_decorator(emr_backends)
|
||||
|
@ -1,6 +1,5 @@
|
||||
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"]
|
||||
mock_glacier = base_decorator(glacier_backends)
|
||||
mock_glacier_deprecated = deprecated_base_decorator(glacier_backends)
|
||||
|
@ -2,4 +2,3 @@ from .models import iam_backend
|
||||
|
||||
iam_backends = {"global": iam_backend}
|
||||
mock_iam = iam_backend.decorator
|
||||
mock_iam_deprecated = iam_backend.deprecated_decorator
|
||||
|
@ -1,6 +1,5 @@
|
||||
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"]
|
||||
mock_kinesis = base_decorator(kinesis_backends)
|
||||
mock_kinesis_deprecated = deprecated_base_decorator(kinesis_backends)
|
||||
|
@ -1,6 +1,5 @@
|
||||
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"]
|
||||
mock_kms = base_decorator(kms_backends)
|
||||
mock_kms_deprecated = deprecated_base_decorator(kms_backends)
|
||||
|
@ -1,5 +1,4 @@
|
||||
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_deprecated = deprecated_base_decorator(logs_backends)
|
||||
|
@ -1,8 +1,5 @@
|
||||
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"]
|
||||
mock_managedblockchain = base_decorator(managedblockchain_backends)
|
||||
mock_managedblockchain_deprecated = deprecated_base_decorator(
|
||||
managedblockchain_backends
|
||||
)
|
||||
|
@ -1,6 +1,5 @@
|
||||
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"]
|
||||
mock_opsworks = base_decorator(opsworks_backends)
|
||||
mock_opsworks_deprecated = deprecated_base_decorator(opsworks_backends)
|
||||
|
@ -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)
|
@ -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),
|
||||
)
|
@ -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)
|
@ -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
@ -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)."
|
||||
)
|
@ -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
|
@ -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)
|
@ -1,5 +1,4 @@
|
||||
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_deprecated = deprecated_base_decorator(rds_backends)
|
||||
|
@ -1,6 +1,5 @@
|
||||
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"]
|
||||
mock_rds2 = base_decorator(rds2_backends)
|
||||
mock_rds2_deprecated = deprecated_base_decorator(rds2_backends)
|
||||
|
@ -1,5 +1,4 @@
|
||||
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_deprecated = deprecated_base_decorator(redshift_backends)
|
||||
|
@ -2,4 +2,3 @@ from .models import route53_backend
|
||||
|
||||
route53_backends = {"global": route53_backend}
|
||||
mock_route53 = route53_backend.decorator
|
||||
mock_route53_deprecated = route53_backend.deprecated_decorator
|
||||
|
@ -2,4 +2,3 @@ from .models import s3_backend
|
||||
|
||||
s3_backends = {"global": s3_backend}
|
||||
mock_s3 = s3_backend.decorator
|
||||
mock_s3_deprecated = s3_backend.deprecated_decorator
|
||||
|
@ -196,18 +196,6 @@ class FakeKey(BaseModel):
|
||||
def set_acl(self, 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):
|
||||
self._expiry = datetime.datetime.utcnow() + datetime.timedelta(days)
|
||||
|
||||
@ -1674,11 +1662,6 @@ class S3Backend(BaseBackend, CloudWatchMetricProvider):
|
||||
key.lock_mode = retention[0]
|
||||
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):
|
||||
key_name = clean_key_name(key_name)
|
||||
bucket = self.get_bucket(bucket_name)
|
||||
|
@ -5,10 +5,10 @@ from typing import List, Union
|
||||
|
||||
from botocore.awsrequest import AWSPreparedRequest
|
||||
|
||||
from moto import settings
|
||||
from moto.core.utils import amzn_request_id, str_to_rfc_1123_datetime
|
||||
from urllib.parse import (
|
||||
parse_qs,
|
||||
parse_qsl,
|
||||
urlparse,
|
||||
unquote,
|
||||
urlencode,
|
||||
@ -17,8 +17,6 @@ from urllib.parse import (
|
||||
|
||||
import xmltodict
|
||||
|
||||
from moto import settings
|
||||
from moto.packages.httpretty.core import HTTPrettyRequest
|
||||
from moto.core.responses import _TemplateEnvironmentMixin, ActionAuthenticatorMixin
|
||||
from moto.core.utils import path_url
|
||||
from moto.core import ACCOUNT_ID
|
||||
@ -972,13 +970,7 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin):
|
||||
self._authenticate_and_authorize_s3_action()
|
||||
|
||||
# POST to bucket-url should create file from form
|
||||
if hasattr(request, "form"):
|
||||
# Not HTTPretty
|
||||
form = request.form
|
||||
else:
|
||||
# HTTPretty, build new form object
|
||||
body = body.decode()
|
||||
form = dict(parse_qsl(body))
|
||||
form = request.form
|
||||
|
||||
key = form["key"]
|
||||
if "file" in form:
|
||||
@ -1028,15 +1020,11 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin):
|
||||
|
||||
@staticmethod
|
||||
def _get_path(request):
|
||||
if isinstance(request, HTTPrettyRequest):
|
||||
path = request.path
|
||||
else:
|
||||
path = (
|
||||
request.full_path
|
||||
if hasattr(request, "full_path")
|
||||
else path_url(request.url)
|
||||
)
|
||||
return path
|
||||
return (
|
||||
request.full_path
|
||||
if hasattr(request, "full_path")
|
||||
else path_url(request.url)
|
||||
)
|
||||
|
||||
def _bucket_response_delete_keys(self, request, body, bucket_name):
|
||||
template = self.response_template(S3_DELETE_KEYS_RESPONSE)
|
||||
@ -1587,39 +1575,29 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin):
|
||||
template = self.response_template(S3_OBJECT_COPY_RESPONSE)
|
||||
response_headers.update(new_key.response_dict)
|
||||
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
|
||||
new_key = self.backend.put_object(
|
||||
bucket_name,
|
||||
key_name,
|
||||
body,
|
||||
storage=storage_class,
|
||||
encryption=encryption,
|
||||
kms_key_id=kms_key_id,
|
||||
bucket_key_enabled=bucket_key_enabled,
|
||||
lock_mode=lock_mode,
|
||||
lock_legal_status=legal_hold,
|
||||
lock_until=lock_until,
|
||||
)
|
||||
# Initial data
|
||||
new_key = self.backend.put_object(
|
||||
bucket_name,
|
||||
key_name,
|
||||
body,
|
||||
storage=storage_class,
|
||||
encryption=encryption,
|
||||
kms_key_id=kms_key_id,
|
||||
bucket_key_enabled=bucket_key_enabled,
|
||||
lock_mode=lock_mode,
|
||||
lock_legal_status=legal_hold,
|
||||
lock_until=lock_until,
|
||||
)
|
||||
|
||||
request.streaming = True
|
||||
metadata = metadata_from_headers(request.headers)
|
||||
metadata.update(metadata_from_headers(query))
|
||||
new_key.set_metadata(metadata)
|
||||
new_key.set_acl(acl)
|
||||
new_key.website_redirect_location = request.headers.get(
|
||||
"x-amz-website-redirect-location"
|
||||
)
|
||||
self.backend.set_key_tags(new_key, tagging)
|
||||
metadata = metadata_from_headers(request.headers)
|
||||
metadata.update(metadata_from_headers(query))
|
||||
new_key.set_metadata(metadata)
|
||||
new_key.set_acl(acl)
|
||||
new_key.website_redirect_location = request.headers.get(
|
||||
"x-amz-website-redirect-location"
|
||||
)
|
||||
self.backend.set_key_tags(new_key, tagging)
|
||||
|
||||
response_headers.update(new_key.response_dict)
|
||||
return 200, response_headers, ""
|
||||
|
@ -17,7 +17,7 @@ from werkzeug.serving import run_simple
|
||||
|
||||
import moto.backends as backends
|
||||
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"]
|
||||
|
||||
@ -291,7 +291,7 @@ def create_backend_app(service):
|
||||
backend = backend_dict["global"]
|
||||
|
||||
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":
|
||||
endpoint = "{0}.dispatch".format(handler.__self__.__name__)
|
||||
else:
|
||||
|
@ -2,4 +2,3 @@ from .models import ses_backend
|
||||
|
||||
ses_backends = {"global": ses_backend}
|
||||
mock_ses = ses_backend.decorator
|
||||
mock_ses_deprecated = ses_backend.deprecated_decorator
|
||||
|
@ -1,6 +1,5 @@
|
||||
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"]
|
||||
mock_sns = base_decorator(sns_backends)
|
||||
mock_sns_deprecated = deprecated_base_decorator(sns_backends)
|
||||
|
@ -1,6 +1,5 @@
|
||||
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"]
|
||||
mock_sqs = base_decorator(sqs_backends)
|
||||
mock_sqs_deprecated = deprecated_base_decorator(sqs_backends)
|
||||
|
@ -2,4 +2,3 @@ from .models import sts_backend
|
||||
|
||||
sts_backends = {"global": sts_backend}
|
||||
mock_sts = sts_backend.decorator
|
||||
mock_sts_deprecated = sts_backend.deprecated_decorator
|
||||
|
@ -1,6 +1,5 @@
|
||||
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"]
|
||||
mock_swf = base_decorator(swf_backends)
|
||||
mock_swf_deprecated = deprecated_base_decorator(swf_backends)
|
||||
|
@ -4,7 +4,6 @@
|
||||
black==19.10b0
|
||||
regex==2019.11.1
|
||||
flake8==3.7.8
|
||||
boto>=2.45.0
|
||||
click
|
||||
inflection==0.3.1
|
||||
lxml
|
||||
|
1
setup.py
1
setup.py
@ -3,7 +3,6 @@ from io import open
|
||||
import os
|
||||
import re
|
||||
from setuptools import setup, find_packages
|
||||
import sys
|
||||
import moto.__init__ as service_list
|
||||
|
||||
# Borrowed from pip at https://github.com/pypa/pip/blob/62c27dee45625e1b63d1e023b0656310f276e050/setup.py#L11-L15
|
||||
|
@ -1,33 +1,7 @@
|
||||
import boto
|
||||
from unittest import SkipTest
|
||||
from collections.abc import Iterable, Mapping
|
||||
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
|
||||
def containing_item_with_attributes(context, **kwargs):
|
||||
contains = False
|
||||
|
@ -1,123 +1,22 @@
|
||||
import boto
|
||||
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
|
||||
from botocore.exceptions import ClientError
|
||||
import pytest
|
||||
|
||||
from moto import (
|
||||
mock_autoscaling,
|
||||
mock_ec2_deprecated,
|
||||
mock_elb_deprecated,
|
||||
mock_elb,
|
||||
mock_autoscaling_deprecated,
|
||||
mock_ec2,
|
||||
)
|
||||
from moto.core import ACCOUNT_ID
|
||||
from tests.helpers import requires_boto_gte
|
||||
|
||||
from .utils import (
|
||||
setup_networking,
|
||||
setup_networking_deprecated,
|
||||
setup_instance_with_networking,
|
||||
)
|
||||
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_ec2
|
||||
@mock_elb
|
||||
@ -222,47 +121,6 @@ def test_create_autoscaling_group_boto3_within_elb():
|
||||
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
|
||||
def test_create_autoscaling_groups_defaults_boto3():
|
||||
"""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"})
|
||||
|
||||
|
||||
# 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
|
||||
def test_autoscaling_group_delete_boto3():
|
||||
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_elb
|
||||
def test_describe_load_balancers():
|
||||
|
@ -1,54 +1,15 @@
|
||||
import base64
|
||||
|
||||
import boto
|
||||
import boto3
|
||||
from boto.ec2.autoscale.launchconfig import LaunchConfiguration
|
||||
from boto.ec2.blockdevicemapping import BlockDeviceType, BlockDeviceMapping
|
||||
from botocore.exceptions import ClientError
|
||||
|
||||
import pytest
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
|
||||
from moto import mock_autoscaling_deprecated
|
||||
from moto import mock_autoscaling
|
||||
from moto.core import ACCOUNT_ID
|
||||
from tests.helpers import requires_boto_gte
|
||||
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
|
||||
def test_create_launch_configuration_boto3():
|
||||
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||
@ -84,76 +45,6 @@ def test_create_launch_configuration_boto3():
|
||||
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
|
||||
def test_create_launch_configuration_with_block_device_mappings_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_create_launch_configuration_additional_parameters():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_create_launch_configuration_additional_params_default_to_false():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_create_launch_configuration_defaults_boto3():
|
||||
"""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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_launch_configuration_describe_filter_boto3():
|
||||
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()
|
||||
|
||||
|
||||
# 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
|
||||
def test_launch_configuration_delete_boto3():
|
||||
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||
|
@ -1,36 +1,13 @@
|
||||
import boto
|
||||
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 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
|
||||
|
||||
|
||||
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():
|
||||
mocked_networking = setup_networking()
|
||||
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
|
||||
def test_create_policy_boto3():
|
||||
setup_autoscale_group_boto3()
|
||||
@ -91,26 +46,6 @@ def test_create_policy_boto3():
|
||||
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
|
||||
def test_create_policy_default_values_boto3():
|
||||
setup_autoscale_group_boto3()
|
||||
@ -129,34 +64,6 @@ def test_create_policy_default_values_boto3():
|
||||
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
|
||||
def test_update_policy_boto3():
|
||||
setup_autoscale_group_boto3()
|
||||
@ -184,25 +91,6 @@ def test_update_policy_boto3():
|
||||
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
|
||||
def test_delete_policy_boto3():
|
||||
setup_autoscale_group_boto3()
|
||||
@ -220,25 +108,6 @@ def test_delete_policy_boto3():
|
||||
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
|
||||
def test_execute_policy_exact_capacity_boto3():
|
||||
setup_autoscale_group_boto3()
|
||||
@ -256,25 +125,6 @@ def test_execute_policy_exact_capacity_boto3():
|
||||
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
|
||||
def test_execute_policy_positive_change_in_capacity_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)
|
||||
|
||||
|
||||
# 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(
|
||||
"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["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)
|
||||
|
@ -1,6 +1,5 @@
|
||||
import boto3
|
||||
from boto import vpc as boto_vpc
|
||||
from moto import mock_ec2, mock_ec2_deprecated
|
||||
from moto import 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}
|
||||
|
||||
|
||||
@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
|
||||
def setup_instance_with_networking(image_id, instance_type):
|
||||
mock_data = setup_networking()
|
||||
|
@ -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
|
@ -25,7 +25,6 @@ from moto import (
|
||||
from moto import settings
|
||||
from moto.core import ACCOUNT_ID
|
||||
from moto.cloudformation import cloudformation_backends
|
||||
from .test_cloudformation_stack_crud import dummy_template_json2, dummy_template_json4
|
||||
|
||||
from tests import EXAMPLE_AMI_ID
|
||||
|
||||
@ -48,6 +47,12 @@ dummy_template = {
|
||||
},
|
||||
}
|
||||
|
||||
dummy_template2 = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Description": "Stack 2",
|
||||
"Resources": {},
|
||||
}
|
||||
|
||||
dummy_template3 = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"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 = {
|
||||
"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_import_template_json = json.dumps(dummy_import_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)
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
from __future__ import absolute_import, division, print_function
|
||||
from __future__ import absolute_import, division
|
||||
|
||||
# Standard library modules
|
||||
import unittest
|
||||
|
@ -12,12 +12,12 @@ from moto.cloudformation.models import FakeStack
|
||||
from moto.cloudformation.parsing import (
|
||||
resource_class_from_type,
|
||||
parse_condition,
|
||||
Output,
|
||||
)
|
||||
from moto import mock_cloudformation, mock_sqs, mock_ssm, settings
|
||||
from moto.sqs.models import Queue
|
||||
from moto.s3.models import FakeBucket
|
||||
from moto.cloudformation.utils import yaml_tag_constructor
|
||||
from moto.packages.boto.cloudformation.stack import Output
|
||||
|
||||
|
||||
dummy_template = {
|
||||
|
@ -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")
|
@ -24,10 +24,9 @@ def test_put_metric_data_no_dimensions():
|
||||
)
|
||||
|
||||
metrics = conn.list_metrics()["Metrics"]
|
||||
metrics.should.have.length_of(1)
|
||||
metric = metrics[0]
|
||||
metric["Namespace"].should.equal("tester")
|
||||
metric["MetricName"].should.equal("metric")
|
||||
metrics.should.contain(
|
||||
{"Namespace": "tester", "MetricName": "metric", "Dimensions": []}
|
||||
)
|
||||
|
||||
|
||||
@mock_cloudwatch
|
||||
@ -75,10 +74,9 @@ def test_put_metric_data_with_statistics():
|
||||
)
|
||||
|
||||
metrics = conn.list_metrics()["Metrics"]
|
||||
metrics.should.have.length_of(1)
|
||||
metric = metrics[0]
|
||||
metric["Namespace"].should.equal("tester")
|
||||
metric["MetricName"].should.equal("statmetric")
|
||||
metrics.should.contain(
|
||||
{"Namespace": "tester", "MetricName": "statmetric", "Dimensions": []}
|
||||
)
|
||||
# TODO: test statistics - https://github.com/spulec/moto/issues/1615
|
||||
|
||||
|
||||
@ -170,7 +168,6 @@ def test_get_metric_statistics_dimensions():
|
||||
Statistics=["Average", "Sum"],
|
||||
**params[0],
|
||||
)
|
||||
print(stats)
|
||||
stats["Datapoints"].should.have.length_of(1)
|
||||
datapoint = stats["Datapoints"][0]
|
||||
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)
|
||||
# Verify we can retrieve everything
|
||||
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
|
||||
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")[
|
||||
"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
|
||||
res.should.equal(
|
||||
[
|
||||
@ -353,29 +350,34 @@ def test_list_metrics_paginated():
|
||||
# Add a boatload of metrics
|
||||
create_metrics(cloudwatch, namespace="test", metrics=100, data_points=1)
|
||||
# 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
|
||||
|
||||
len(first_page["Metrics"]).should.equal(100)
|
||||
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)
|
||||
first_page.shouldnt.contain("NextToken")
|
||||
# Verify that adding more data points results in pagination
|
||||
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)
|
||||
first_page["NextToken"].shouldnt.be.empty
|
||||
# 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)
|
||||
second_page.should.contain("NextToken")
|
||||
# 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)
|
||||
third_page.shouldnt.contain("NextToken")
|
||||
# Verify that we can't reuse an existing token
|
||||
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(
|
||||
"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)
|
||||
|
||||
# duplicating existing metric
|
||||
@ -443,7 +445,7 @@ def test_list_metrics_with_same_dimensions_different_metric_name():
|
||||
)
|
||||
|
||||
# asserting only unique values are returned
|
||||
results = cloudwatch.list_metrics()["Metrics"]
|
||||
results = cloudwatch.list_metrics(Namespace="unique/")["Metrics"]
|
||||
results.should.have.length_of(2)
|
||||
|
||||
|
||||
|
@ -1,60 +1,70 @@
|
||||
import boto
|
||||
from boto.exception import EC2ResponseError
|
||||
import boto3
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
import os
|
||||
import unittest
|
||||
|
||||
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
|
||||
"""
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
def test_basic_connect():
|
||||
boto.connect_ec2()
|
||||
|
||||
|
||||
@mock_ec2_deprecated
|
||||
@mock_ec2
|
||||
def test_basic_decorator():
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
list(conn.get_all_reservations()).should.equal([])
|
||||
client = boto3.client("ec2", region_name="us-west-1")
|
||||
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
|
||||
def test_context_manager():
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
with pytest.raises(EC2ResponseError):
|
||||
conn.get_all_reservations()
|
||||
def test_context_manager(aws_credentials):
|
||||
client = boto3.client("ec2", region_name="us-west-1")
|
||||
with pytest.raises(ClientError) as exc:
|
||||
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():
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
list(conn.get_all_reservations()).should.equal([])
|
||||
|
||||
with pytest.raises(EC2ResponseError):
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
conn.get_all_reservations()
|
||||
with mock_ec2():
|
||||
client = boto3.client("ec2", region_name="us-west-1")
|
||||
client.describe_addresses()["Addresses"].should.equal([])
|
||||
|
||||
|
||||
@pytest.mark.network
|
||||
def test_decorator_start_and_stop():
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
with pytest.raises(EC2ResponseError):
|
||||
conn.get_all_reservations()
|
||||
|
||||
mock = mock_ec2_deprecated()
|
||||
if settings.TEST_SERVER_MODE:
|
||||
raise SkipTest("Authentication always works in ServerMode")
|
||||
mock = mock_ec2()
|
||||
mock.start()
|
||||
conn = boto.connect_ec2("the_key", "the_secret")
|
||||
list(conn.get_all_reservations()).should.equal([])
|
||||
client = boto3.client("ec2", region_name="us-west-1")
|
||||
client.describe_addresses()["Addresses"].should.equal([])
|
||||
mock.stop()
|
||||
|
||||
with pytest.raises(EC2ResponseError):
|
||||
conn.get_all_reservations()
|
||||
with pytest.raises(ClientError) as exc:
|
||||
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():
|
||||
"""
|
||||
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):
|
||||
def test_the_class(self):
|
||||
conn = boto.connect_ec2()
|
||||
list(conn.get_all_reservations()).should.have.length_of(0)
|
||||
client = boto3.client("ec2", region_name="us-west-1")
|
||||
client.describe_addresses()["Addresses"].should.equal([])
|
||||
|
||||
def test_still_the_same(self):
|
||||
conn = boto.connect_ec2()
|
||||
list(conn.get_all_reservations()).should.have.length_of(0)
|
||||
client = boto3.client("ec2", region_name="us-west-1")
|
||||
client.describe_addresses()["Addresses"].should.equal([])
|
||||
|
||||
|
||||
@mock_s3_deprecated
|
||||
@mock_s3
|
||||
class TesterWithSetup(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.conn = boto.connect_s3()
|
||||
self.conn.create_bucket("mybucket")
|
||||
self.client = boto3.client("s3")
|
||||
self.client.create_bucket(Bucket="mybucket")
|
||||
|
||||
def test_still_the_same(self):
|
||||
bucket = self.conn.get_bucket("mybucket")
|
||||
bucket.name.should.equal("mybucket")
|
||||
buckets = self.client.list_buckets()["Buckets"]
|
||||
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):
|
||||
@staticmethod
|
||||
def static(*args):
|
||||
|
@ -1,38 +1,12 @@
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
import unittest
|
||||
|
||||
from boto.sqs.connection import SQSConnection
|
||||
from boto.sqs.message import Message
|
||||
from boto.ec2 import EC2Connection
|
||||
import boto3
|
||||
|
||||
from moto import mock_sqs_deprecated, mock_ec2_deprecated
|
||||
from moto import mock_sqs, mock_ec2
|
||||
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):
|
||||
@mock_sqs
|
||||
def setup_sqs_queue(self):
|
||||
|
@ -1,37 +1,9 @@
|
||||
import unittest
|
||||
from moto import mock_dynamodb2_deprecated, mock_dynamodb2
|
||||
from moto import mock_dynamodb2
|
||||
import socket
|
||||
|
||||
|
||||
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
|
||||
def test_socket_pair(self):
|
||||
a, b = socket.socketpair()
|
||||
|
@ -7,10 +7,7 @@ from moto import mock_s3
|
||||
service_names = [
|
||||
(d[5:], "")
|
||||
for d in dir(moto)
|
||||
if d.startswith("mock_")
|
||||
and not d.endswith("_deprecated")
|
||||
and not d == "mock_xray_client"
|
||||
and not d == "mock_all"
|
||||
if d.startswith("mock_") and not d == "mock_xray_client" and not d == "mock_all"
|
||||
]
|
||||
|
||||
|
||||
|
@ -1,9 +1,7 @@
|
||||
import boto.datapipeline
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
import boto3
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
|
||||
from moto import mock_datapipeline
|
||||
from moto import mock_datapipeline_deprecated
|
||||
from moto.datapipeline.utils import remove_capitalization_of_dict_keys
|
||||
|
||||
|
||||
@ -13,28 +11,6 @@ def get_value_from_fields(key, fields):
|
||||
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
|
||||
def test_create_pipeline_boto3():
|
||||
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
|
||||
def test_creating_pipeline_definition_boto3():
|
||||
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
|
||||
def test_describing_pipeline_objects_boto3():
|
||||
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
|
||||
def test_activate_pipeline_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_delete_pipeline_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_listing_pipelines_boto3():
|
||||
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
|
||||
def test_listing_paginated_pipelines_boto3():
|
||||
conn = boto3.client("datapipeline", region_name="us-west-2")
|
||||
|
@ -1,12 +1,7 @@
|
||||
import boto
|
||||
import boto.dynamodb
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
import pytest
|
||||
|
||||
from moto import mock_dynamodb, mock_dynamodb_deprecated
|
||||
from moto.dynamodb import dynamodb_backend
|
||||
|
||||
from boto.exception import DynamoDBResponseError
|
||||
from moto import mock_dynamodb
|
||||
|
||||
|
||||
def test_deprecation_warning():
|
||||
@ -15,45 +10,3 @@ def test_deprecation_warning():
|
||||
str(record[0].message).should.contain(
|
||||
"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)
|
||||
|
@ -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)
|
@ -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)
|
@ -1,53 +1,20 @@
|
||||
from __future__ import print_function
|
||||
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
from decimal import Decimal
|
||||
|
||||
import boto
|
||||
import boto3
|
||||
from boto3.dynamodb.conditions import Attr, Key
|
||||
import re
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
from moto import mock_dynamodb2, mock_dynamodb2_deprecated
|
||||
from moto.dynamodb2 import dynamodb_backend2, dynamodb_backends2
|
||||
from boto.exception import JSONResponseError
|
||||
from moto import mock_dynamodb2
|
||||
from moto.dynamodb2 import dynamodb_backends2
|
||||
from botocore.exceptions import ClientError
|
||||
from tests.helpers import requires_boto_gte
|
||||
|
||||
import moto.dynamodb2.comparisons
|
||||
import moto.dynamodb2.models
|
||||
|
||||
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
|
||||
@pytest.mark.parametrize(
|
||||
@ -67,34 +34,6 @@ def test_list_tables_boto3(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
|
||||
def test_list_tables_paginated():
|
||||
conn = boto3.client("dynamodb", region_name="us-west-2")
|
||||
@ -119,17 +58,6 @@ def test_list_tables_paginated():
|
||||
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
|
||||
def test_describe_missing_table_boto3():
|
||||
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")
|
||||
|
||||
|
||||
@requires_boto_gte("2.9")
|
||||
@mock_dynamodb2
|
||||
def test_list_table_tags():
|
||||
name = "TestTable"
|
||||
@ -178,7 +105,6 @@ def test_list_table_tags():
|
||||
assert resp["Tags"] == [{"Key": "TestTag2", "Value": "TestValue2"}]
|
||||
|
||||
|
||||
@requires_boto_gte("2.9")
|
||||
@mock_dynamodb2
|
||||
def test_list_table_tags_empty():
|
||||
name = "TestTable"
|
||||
@ -200,7 +126,6 @@ def test_list_table_tags_empty():
|
||||
assert resp["Tags"] == []
|
||||
|
||||
|
||||
@requires_boto_gte("2.9")
|
||||
@mock_dynamodb2
|
||||
def test_list_table_tags_paginated():
|
||||
name = "TestTable"
|
||||
@ -229,7 +154,6 @@ def test_list_table_tags_paginated():
|
||||
assert "NextToken" not in resp2.keys()
|
||||
|
||||
|
||||
@requires_boto_gte("2.9")
|
||||
@mock_dynamodb2
|
||||
def test_list_not_found_table_tags():
|
||||
conn = boto3.client(
|
||||
@ -384,7 +308,6 @@ def test_update_item_with_empty_string_attr_no_exception():
|
||||
)
|
||||
|
||||
|
||||
@requires_boto_gte("2.9")
|
||||
@mock_dynamodb2
|
||||
def test_query_invalid_table():
|
||||
conn = boto3.client(
|
||||
@ -403,7 +326,6 @@ def test_query_invalid_table():
|
||||
assert exception.response["Error"]["Code"] == "ResourceNotFoundException"
|
||||
|
||||
|
||||
@requires_boto_gte("2.9")
|
||||
@mock_dynamodb2
|
||||
def test_put_item_with_special_chars():
|
||||
name = "TestTable"
|
||||
@ -434,7 +356,6 @@ def test_put_item_with_special_chars():
|
||||
)
|
||||
|
||||
|
||||
@requires_boto_gte("2.9")
|
||||
@mock_dynamodb2
|
||||
def test_put_item_with_streams():
|
||||
name = "TestTable"
|
||||
@ -3513,7 +3434,6 @@ def test_update_supports_list_append_maps():
|
||||
)
|
||||
|
||||
|
||||
@requires_boto_gte("2.9")
|
||||
@mock_dynamodb2
|
||||
def test_update_supports_nested_update_if_nested_value_not_exists():
|
||||
dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
|
||||
|
@ -1,94 +1,15 @@
|
||||
from decimal import Decimal
|
||||
|
||||
import boto
|
||||
import boto3
|
||||
from boto3.dynamodb.conditions import Key
|
||||
from botocore.exceptions import ClientError
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
from datetime import datetime
|
||||
from freezegun import freeze_time
|
||||
import pytest
|
||||
|
||||
from moto import mock_dynamodb2, mock_dynamodb2_deprecated
|
||||
from boto.exception import JSONResponseError
|
||||
from tests.helpers import requires_boto_gte
|
||||
from moto import mock_dynamodb2
|
||||
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
|
||||
def test_create_table_boto3():
|
||||
@ -134,50 +55,6 @@ def test_create_table_boto3():
|
||||
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
|
||||
def test_create_table_with_local_index_boto3():
|
||||
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)
|
||||
|
||||
|
||||
@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
|
||||
def test_get_item_without_range_key_boto3():
|
||||
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")
|
||||
|
||||
|
||||
@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
|
||||
def test_query_filter_boto3():
|
||||
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"}])
|
||||
|
||||
|
||||
@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
|
||||
def test_boto3_create_table_with_gsi():
|
||||
dynamodb = boto3.client("dynamodb", region_name="us-east-1")
|
||||
|
@ -1,66 +1,12 @@
|
||||
import boto
|
||||
import boto3
|
||||
from boto3.dynamodb.conditions import Key
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
import pytest
|
||||
from datetime import datetime
|
||||
from freezegun import freeze_time
|
||||
from boto.exception import JSONResponseError
|
||||
from botocore.exceptions import ClientError
|
||||
from moto import mock_dynamodb2, mock_dynamodb2_deprecated
|
||||
from tests.helpers import requires_boto_gte
|
||||
from moto import mock_dynamodb2
|
||||
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
|
||||
def test_create_table_boto3():
|
||||
@ -125,20 +71,6 @@ def test_create_table_boto3():
|
||||
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
|
||||
def test_delete_table_boto3():
|
||||
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")
|
||||
|
||||
|
||||
@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
|
||||
def test_update_table_throughput_boto3():
|
||||
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)
|
||||
|
||||
|
||||
@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
|
||||
def test_item_add_and_describe_and_update_boto3():
|
||||
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
|
||||
def test_item_put_without_table_boto3():
|
||||
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")
|
||||
|
||||
|
||||
@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
|
||||
def test_get_item_with_undeclared_table_boto3():
|
||||
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")
|
||||
|
||||
|
||||
@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
|
||||
def test_delete_item_boto3():
|
||||
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"})
|
||||
|
||||
|
||||
@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
|
||||
def test_delete_item_with_undeclared_table_boto3():
|
||||
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
|
||||
def test_scan_with_undeclared_table_boto3():
|
||||
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")
|
||||
|
||||
|
||||
@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
|
||||
def test_get_key_schema():
|
||||
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"}])
|
||||
|
||||
|
||||
@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
|
||||
def test_update_item_double_nested_remove():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_update_item_set_boto3():
|
||||
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"})
|
||||
|
||||
|
||||
# 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
|
||||
def test_boto3_create_table():
|
||||
dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
|
||||
|
@ -1,96 +1,17 @@
|
||||
import boto
|
||||
import boto.ec2
|
||||
import boto3
|
||||
from boto.exception import EC2ResponseError
|
||||
from botocore.exceptions import ClientError
|
||||
|
||||
import pytest
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
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.core import ACCOUNT_ID
|
||||
from tests import EXAMPLE_AMI_ID, EXAMPLE_AMI_PARAVIRTUAL
|
||||
from tests.helpers import requires_boto_gte
|
||||
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
|
||||
def test_snapshots_for_initial_amis():
|
||||
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
|
||||
|
||||
|
||||
# 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
|
||||
def test_ami_copy_boto3_dryrun():
|
||||
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"])
|
||||
|
||||
|
||||
# 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
|
||||
def test_ami_tagging_boto3():
|
||||
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"}])
|
||||
|
||||
|
||||
# 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
|
||||
def test_ami_create_from_missing_instance_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_ami_pulls_attributes_from_instance_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
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
|
||||
@ -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
|
||||
def test_ami_filters_boto3():
|
||||
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"
|
||||
|
||||
|
||||
# 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
|
||||
def test_ami_filtering_via_tag_boto3():
|
||||
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])
|
||||
|
||||
|
||||
# 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
|
||||
def test_getting_missing_ami_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_getting_malformed_ami_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_ami_attribute_group_permissions_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_ami_attribute_user_permissions_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_ami_attribute_user_and_group_permissions_boto3():
|
||||
"""
|
||||
@ -1363,98 +825,6 @@ def test_filter_description():
|
||||
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
|
||||
def test_ami_attribute_error_cases_boto3():
|
||||
ec2 = boto3.client("ec2", region_name="us-east-1")
|
||||
|
@ -1,34 +1,9 @@
|
||||
import boto
|
||||
import boto.ec2
|
||||
import boto3
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
import pytest
|
||||
|
||||
from botocore.exceptions import ClientError
|
||||
from moto import mock_ec2, mock_ec2_deprecated
|
||||
|
||||
|
||||
# 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)
|
||||
from moto import mock_ec2
|
||||
|
||||
|
||||
@mock_ec2
|
||||
|
@ -1,24 +1,9 @@
|
||||
import boto
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
import boto3
|
||||
import pytest
|
||||
from boto.exception import EC2ResponseError
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
|
||||
from botocore.exceptions import ClientError
|
||||
|
||||
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")
|
||||
from moto import 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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_describe_customer_gateways_dryrun():
|
||||
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"
|
||||
|
||||
|
||||
# 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
|
||||
def test_delete_customer_gateways_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_delete_customer_gateways_bad_id_boto3():
|
||||
ec2 = boto3.client("ec2", region_name="us-east-1")
|
||||
|
@ -1,33 +1,19 @@
|
||||
import pytest
|
||||
|
||||
import boto3
|
||||
import boto
|
||||
from boto.exception import EC2ResponseError
|
||||
from botocore.exceptions import ClientError
|
||||
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
import random
|
||||
import uuid
|
||||
|
||||
from moto import mock_ec2, mock_ec2_deprecated, settings
|
||||
from moto import mock_ec2, settings
|
||||
from unittest import SkipTest
|
||||
|
||||
SAMPLE_DOMAIN_NAME = "example.com"
|
||||
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
|
||||
def test_dhcp_options_associate_boto3():
|
||||
""" associate dhcp option """
|
||||
@ -48,20 +34,6 @@ def test_dhcp_options_associate_boto3():
|
||||
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
|
||||
def test_dhcp_options_associate_invalid_dhcp_id_boto3():
|
||||
""" 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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_dhcp_options_associate_invalid_vpc_id_boto3():
|
||||
""" 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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_dhcp_options_delete_with_vpc_boto3():
|
||||
"""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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_create_dhcp_options_boto3():
|
||||
"""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
|
||||
def test_create_dhcp_options_invalid_options_boto3():
|
||||
"""Create invalid dhcp options"""
|
||||
@ -249,20 +144,6 @@ def test_create_dhcp_options_invalid_options_boto3():
|
||||
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
|
||||
def test_describe_dhcp_options_boto3():
|
||||
"""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
|
||||
def test_describe_dhcp_options_invalid_id_boto3():
|
||||
"""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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_delete_dhcp_options_boto3():
|
||||
"""delete dhcp option"""
|
||||
@ -365,20 +214,6 @@ def test_delete_dhcp_options_boto3():
|
||||
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
|
||||
def test_delete_dhcp_options_invalid_id_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_delete_dhcp_options_malformed_id_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_dhcp_tagging_boto3():
|
||||
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}])
|
||||
|
||||
|
||||
# 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
|
||||
def test_dhcp_options_get_by_tag_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_dhcp_options_get_by_id_boto3():
|
||||
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"})
|
||||
|
||||
|
||||
# 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
|
||||
def test_dhcp_options_get_by_invalid_filter_boto3():
|
||||
if settings.TEST_SERVER_MODE:
|
||||
|
@ -1,5 +1,4 @@
|
||||
from botocore.exceptions import ClientError
|
||||
from moto import mock_cloudformation_deprecated, mock_ec2_deprecated
|
||||
from moto import mock_cloudformation, mock_ec2
|
||||
from tests import EXAMPLE_AMI_ID
|
||||
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_single_instance_in_subnet
|
||||
from uuid import uuid4
|
||||
import boto
|
||||
import boto.ec2
|
||||
import boto.cloudformation
|
||||
import boto.vpc
|
||||
import boto3
|
||||
import json
|
||||
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)
|
||||
|
||||
|
||||
# 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_cloudformation
|
||||
def test_elastic_network_interfaces_cloudformation_boto3():
|
||||
|
@ -1,57 +1,15 @@
|
||||
import boto
|
||||
import boto.ec2
|
||||
import boto3
|
||||
|
||||
import pytest
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
from boto.exception import EC2ResponseError
|
||||
from botocore.exceptions import ClientError
|
||||
from moto import mock_ec2, mock_ec2_deprecated
|
||||
from moto.ec2 import ec2_backends
|
||||
from moto import mock_ec2
|
||||
from moto.ec2.models import OWNER_ID
|
||||
from moto.kms import mock_kms
|
||||
from tests import EXAMPLE_AMI_ID
|
||||
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
|
||||
def test_create_and_delete_volume_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_delete_attached_volume_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_create_encrypted_volume_dryrun_boto3():
|
||||
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
|
||||
def test_create_encrypted_volume_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_filter_volume_by_id_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_volume_filters_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_volume_attach_and_detach_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_create_snapshot_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
@pytest.mark.parametrize("encrypted", [True, False])
|
||||
def test_create_encrypted_snapshot_boto3(encrypted):
|
||||
@ -746,34 +387,6 @@ def test_create_encrypted_snapshot_boto3(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
|
||||
def test_filter_snapshot_by_id_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_snapshot_filters_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_modify_snapshot_attribute():
|
||||
ec2_client = boto3.client("ec2", region_name="us-east-1")
|
||||
@ -1215,46 +654,6 @@ def test_modify_snapshot_attribute():
|
||||
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
|
||||
@pytest.mark.parametrize("encrypted", [True, False])
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_modify_attribute_blockDeviceMapping_boto3():
|
||||
"""
|
||||
@ -1346,29 +713,6 @@ def test_modify_attribute_blockDeviceMapping_boto3():
|
||||
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
|
||||
def test_volume_tag_escaping_boto3():
|
||||
client = boto3.client("ec2", region_name="us-east-1")
|
||||
|
@ -1,51 +1,17 @@
|
||||
import pytest
|
||||
|
||||
import boto
|
||||
import boto3
|
||||
from boto.exception import EC2ResponseError
|
||||
from botocore.exceptions import ClientError
|
||||
from uuid import uuid4
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
def test_eip_allocate_classic_boto3():
|
||||
"""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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_describe_addresses_dryrun():
|
||||
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"]))
|
||||
|
||||
|
||||
# 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
|
||||
def test_eip_allocate_invalid_domain_boto3():
|
||||
"""Allocate EIP invalid domain"""
|
||||
@ -187,58 +119,6 @@ def test_eip_allocate_invalid_domain_boto3():
|
||||
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
|
||||
def test_eip_associate_classic_boto3():
|
||||
"""Associate/Disassociate EIP to classic instance"""
|
||||
@ -297,48 +177,6 @@ def test_eip_associate_classic_boto3():
|
||||
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
|
||||
def test_eip_associate_vpc_boto3():
|
||||
"""Associate/Disassociate EIP to VPC instance"""
|
||||
@ -430,38 +268,6 @@ def test_eip_boto3_vpc_association():
|
||||
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
|
||||
def test_eip_associate_network_interface_boto3():
|
||||
"""Associate/Disassociate EIP to NIC"""
|
||||
@ -497,40 +303,6 @@ def test_eip_associate_network_interface_boto3():
|
||||
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
|
||||
def test_eip_reassociate_boto3():
|
||||
"""reassociate EIP"""
|
||||
@ -572,38 +344,6 @@ def test_eip_reassociate_boto3():
|
||||
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
|
||||
def test_eip_reassociate_nic_boto3():
|
||||
"""reassociate EIP"""
|
||||
@ -641,26 +381,6 @@ def test_eip_reassociate_nic_boto3():
|
||||
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
|
||||
def test_eip_associate_invalid_args_boto3():
|
||||
"""Associate EIP, invalid args """
|
||||
@ -681,19 +401,6 @@ def test_eip_associate_invalid_args_boto3():
|
||||
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
|
||||
def test_eip_disassociate_bogus_association_boto3():
|
||||
"""Disassociate bogus EIP"""
|
||||
@ -706,19 +413,6 @@ def test_eip_disassociate_bogus_association_boto3():
|
||||
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
|
||||
def test_eip_release_bogus_eip_boto3():
|
||||
"""Release bogus EIP"""
|
||||
@ -731,19 +425,6 @@ def test_eip_release_bogus_eip_boto3():
|
||||
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
|
||||
def test_eip_disassociate_arg_error_boto3():
|
||||
"""Invalid arguments disassociate address"""
|
||||
@ -756,19 +437,6 @@ def test_eip_disassociate_arg_error_boto3():
|
||||
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
|
||||
def test_eip_release_arg_error_boto3():
|
||||
"""Invalid arguments release address"""
|
||||
@ -781,47 +449,6 @@ def test_eip_release_arg_error_boto3():
|
||||
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
|
||||
def test_eip_describe_boto3():
|
||||
"""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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_eip_describe_none_boto3():
|
||||
"""Error when search for bogus IP"""
|
||||
|
@ -3,62 +3,14 @@ import random
|
||||
|
||||
import boto3
|
||||
from botocore.exceptions import ClientError
|
||||
import boto
|
||||
import boto.ec2
|
||||
from boto.exception import EC2ResponseError
|
||||
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 tests import EXAMPLE_AMI_ID
|
||||
from tests.helpers import requires_boto_gte
|
||||
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
|
||||
def test_elastic_network_interfaces_boto3():
|
||||
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
|
||||
def test_elastic_network_interfaces_subnet_validation_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_elastic_network_interfaces_with_private_ip_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_elastic_network_interfaces_with_groups_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_elastic_network_interfaces_modify_attribute_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_elastic_network_interfaces_filtering_boto3():
|
||||
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
||||
|
@ -1,37 +1,13 @@
|
||||
import pytest
|
||||
|
||||
import boto
|
||||
import boto3
|
||||
from boto.exception import EC2ResponseError
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
from botocore.exceptions import ClientError
|
||||
|
||||
from moto import mock_ec2_deprecated, mock_ec2
|
||||
from moto import mock_ec2
|
||||
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
|
||||
def test_console_output_boto3():
|
||||
conn = boto3.resource("ec2", "us-east-1")
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,14 +1,12 @@
|
||||
import pytest
|
||||
|
||||
import boto
|
||||
import boto3
|
||||
|
||||
from boto.exception import EC2ResponseError
|
||||
from botocore.exceptions import ClientError
|
||||
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
|
||||
from moto import mock_ec2_deprecated, mock_ec2
|
||||
from moto import mock_ec2
|
||||
from uuid import uuid4
|
||||
|
||||
|
||||
@ -17,30 +15,6 @@ BAD_VPC = "vpc-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
|
||||
def test_igw_create_boto3():
|
||||
""" internet gateway create """
|
||||
@ -64,28 +38,6 @@ def test_igw_create_boto3():
|
||||
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
|
||||
def test_igw_attach_boto3():
|
||||
""" internet gateway attach """
|
||||
@ -111,20 +63,6 @@ def test_igw_attach_boto3():
|
||||
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
|
||||
def test_igw_attach_bad_vpc_boto3():
|
||||
""" 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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_igw_attach_twice_boto3():
|
||||
""" 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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_igw_detach_boto3():
|
||||
""" internet gateway detach"""
|
||||
@ -220,23 +119,6 @@ def test_igw_detach_boto3():
|
||||
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
|
||||
def test_igw_detach_wrong_vpc_boto3():
|
||||
""" 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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_igw_detach_invalid_vpc_boto3():
|
||||
""" 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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_igw_detach_unattached_boto3():
|
||||
""" 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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_igw_delete_boto3():
|
||||
""" internet gateway delete"""
|
||||
@ -360,22 +189,6 @@ def test_igw_delete_boto3():
|
||||
[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
|
||||
def test_igw_delete_attached_boto3():
|
||||
""" internet gateway fail to delete attached """
|
||||
@ -392,16 +205,6 @@ def test_igw_delete_attached_boto3():
|
||||
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
|
||||
def test_igw_describe_boto3():
|
||||
""" internet gateway fetch by id """
|
||||
@ -414,18 +217,6 @@ def test_igw_describe_boto3():
|
||||
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
|
||||
def test_igw_describe_bad_id_boto3():
|
||||
""" 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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_igw_filter_by_vpc_id_boto3():
|
||||
""" 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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_igw_filter_by_tags_boto3():
|
||||
""" internet gateway filter by vpc id """
|
||||
@ -502,20 +262,6 @@ def test_igw_filter_by_tags_boto3():
|
||||
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
|
||||
def test_igw_filter_by_internet_gateway_id_boto3():
|
||||
""" 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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_igw_filter_by_attachment_state_boto3():
|
||||
""" internet gateway filter by attachment state """
|
||||
|
@ -1,12 +1,10 @@
|
||||
import pytest
|
||||
|
||||
import boto
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
import boto3
|
||||
|
||||
from boto.exception import EC2ResponseError
|
||||
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 unittest import SkipTest
|
||||
|
||||
@ -46,13 +44,6 @@ ffsm7UIHtCBYERr9Nx0u20ldfhkgB1lhaJb5o0ZJ3pmJ38KChfyHe5EUcqRdEFo89Mp72VI2Z6UHyL17
|
||||
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
|
||||
def test_key_pairs_empty_boto3():
|
||||
if settings.TEST_SERVER_MODE:
|
||||
@ -61,18 +52,6 @@ def test_key_pairs_empty_boto3():
|
||||
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
|
||||
def test_key_pairs_invalid_id_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_key_pairs_create_dryrun_boto3():
|
||||
ec2 = boto3.resource("ec2", "us-west-1")
|
||||
@ -166,20 +102,6 @@ def test_key_pairs_create_boto3():
|
||||
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
|
||||
def test_key_pairs_create_exist_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_key_pairs_delete_no_exist_boto3():
|
||||
client = boto3.client("ec2", "us-west-1")
|
||||
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
|
||||
def test_key_pairs_delete_exist_boto3():
|
||||
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
|
||||
def test_key_pairs_import_boto3():
|
||||
client = boto3.client("ec2", "us-west-1")
|
||||
@ -309,21 +176,6 @@ def test_key_pairs_import_boto3():
|
||||
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
|
||||
def test_key_pairs_import_exist_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_key_pairs_invalid_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_key_pair_filters_boto3():
|
||||
ec2 = boto3.resource("ec2", "us-west-1")
|
||||
|
@ -1,24 +1,14 @@
|
||||
import boto
|
||||
import boto3
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
import pytest
|
||||
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 random import randint
|
||||
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
|
||||
def test_default_network_acl_created_with_vpc_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_network_create_and_list_acls_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_new_subnet_associates_with_default_network_acl_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_network_acl_entries_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_delete_network_acl_entry_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_replace_network_acl_entry_boto3():
|
||||
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})
|
||||
|
||||
|
||||
# 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
|
||||
def test_delete_network_acl_boto3():
|
||||
client = boto3.client("ec2", region_name="us-east-1")
|
||||
@ -350,25 +179,6 @@ def test_delete_network_acl_boto3():
|
||||
).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
|
||||
def test_network_acl_tagging_boto3():
|
||||
client = boto3.client("ec2", region_name="us-east-1")
|
||||
|
@ -1,46 +1,20 @@
|
||||
import boto.ec2
|
||||
import boto.ec2.autoscale
|
||||
import boto.ec2.elb
|
||||
import boto3
|
||||
import pytest
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
|
||||
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.ec2 import ec2_backends
|
||||
from tests import EXAMPLE_AMI_ID, EXAMPLE_AMI_ID2
|
||||
from uuid import uuid4
|
||||
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):
|
||||
ec2 = boto3.resource("ec2", region_name=region)
|
||||
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
|
||||
def test_add_servers_to_a_single_region_boto3():
|
||||
region = "ap-northeast-1"
|
||||
@ -56,26 +30,6 @@ def test_add_servers_to_a_single_region_boto3():
|
||||
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
|
||||
def test_add_servers_to_multiple_regions_boto3():
|
||||
region1 = "us-east-1"
|
||||
@ -103,107 +57,6 @@ def test_add_servers_to_multiple_regions_boto3():
|
||||
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_elb
|
||||
@mock_ec2
|
||||
|
@ -1,43 +1,14 @@
|
||||
import pytest
|
||||
|
||||
import boto
|
||||
import boto3
|
||||
from boto.exception import EC2ResponseError
|
||||
from botocore.exceptions import ClientError
|
||||
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.helpers import requires_boto_gte
|
||||
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
|
||||
def test_route_tables_defaults_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_route_tables_additional_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_route_tables_filters_standard_boto3():
|
||||
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
|
||||
def test_route_tables_filters_associations_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_route_table_associations_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_route_table_replace_route_table_association_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_route_table_get_by_tag_boto3():
|
||||
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})
|
||||
|
||||
|
||||
# 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
|
||||
def test_routes_additional_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_routes_replace_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_routes_not_supported_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_routes_vpc_peering_connection_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_routes_vpn_gateway_boto3():
|
||||
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
|
||||
|
||||
|
||||
# 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
|
||||
def test_network_acl_tagging_boto3():
|
||||
client = boto3.client("ec2", region_name="us-east-1")
|
||||
|
@ -5,57 +5,16 @@ import unittest
|
||||
import pytest
|
||||
|
||||
import boto3
|
||||
import boto
|
||||
import boto.ec2
|
||||
from botocore.exceptions import ClientError
|
||||
from boto.exception import EC2ResponseError
|
||||
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 random import randint
|
||||
from uuid import uuid4
|
||||
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
|
||||
def test_create_and_describe_security_group_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_create_security_group_without_description_raises_error_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_default_security_group_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_create_and_describe_vpc_security_group_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_create_two_security_groups_with_same_name_in_different_vpc_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_deleting_security_groups_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_delete_security_group_in_vpc_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_authorize_ip_range_and_revoke_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_authorize_other_group_and_revoke_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_authorize_group_in_vpc_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_describe_security_groups():
|
||||
ec2 = boto3.resource("ec2", "us-west-1")
|
||||
@ -927,20 +505,6 @@ def test_describe_security_groups():
|
||||
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
|
||||
def test_authorize_bad_cidr_throws_invalid_parameter_value_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_security_group_tag_filtering_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_authorize_all_protocols_with_no_port_specification_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
@pytest.mark.parametrize(
|
||||
"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
|
||||
def test_add_same_rule_twice_throws_error():
|
||||
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
|
||||
|
||||
|
||||
# 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
|
||||
def test_get_all_security_groups_filter_with_same_vpc_id_boto3():
|
||||
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
||||
|
@ -1,15 +1,12 @@
|
||||
import pytest
|
||||
import datetime
|
||||
|
||||
import boto
|
||||
import boto.ec2
|
||||
import boto3
|
||||
from boto.exception import EC2ResponseError
|
||||
from botocore.exceptions import ClientError
|
||||
import pytz
|
||||
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.core.utils import iso_8601_datetime_with_milliseconds
|
||||
from tests import EXAMPLE_AMI_ID
|
||||
@ -155,30 +152,6 @@ def test_request_spot_instances_default_arguments():
|
||||
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
|
||||
def test_cancel_spot_instance_request_boto3():
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_request_spot_instances_fulfilled_boto3():
|
||||
"""
|
||||
@ -277,26 +224,6 @@ def test_request_spot_instances_fulfilled_boto3():
|
||||
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
|
||||
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"})
|
||||
|
||||
|
||||
# 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
|
||||
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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_request_spot_instances_instance_lifecycle():
|
||||
if settings.TEST_SERVER_MODE:
|
||||
|
@ -1,42 +1,16 @@
|
||||
import random
|
||||
|
||||
import boto
|
||||
import boto3
|
||||
import boto.vpc
|
||||
|
||||
import pytest
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
from boto.exception import EC2ResponseError
|
||||
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 uuid import uuid4
|
||||
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
|
||||
def test_subnets_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_subnet_create_vpc_validation_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_subnet_tagging_boto3():
|
||||
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"}])
|
||||
|
||||
|
||||
# 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
|
||||
def test_subnet_should_have_proper_availability_zone_set_boto3():
|
||||
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
|
||||
|
||||
|
||||
# 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
|
||||
def test_boto3_non_default_subnet():
|
||||
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
|
||||
def test_subnet_get_by_id_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_get_subnets_filtering_boto3():
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
@ -1,45 +1,15 @@
|
||||
import boto3
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
import pytest
|
||||
|
||||
import itertools
|
||||
|
||||
import boto
|
||||
import boto3
|
||||
from botocore.exceptions import ClientError
|
||||
from boto.exception import EC2ResponseError
|
||||
from boto.ec2.instance import Reservation
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
from moto import mock_ec2
|
||||
|
||||
from moto import mock_ec2_deprecated, mock_ec2
|
||||
from tests import EXAMPLE_AMI_ID
|
||||
from .test_instances import retrieve_all_instances
|
||||
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
|
||||
def test_instance_create_tags():
|
||||
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"}])
|
||||
|
||||
|
||||
# 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
|
||||
def test_instance_delete_tags():
|
||||
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
||||
@ -133,36 +73,6 @@ def test_instance_delete_tags():
|
||||
].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
|
||||
def test_get_all_tags_with_special_characters_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_create_tags_boto3():
|
||||
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
|
||||
def test_tag_limit_exceeded_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_invalid_id_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_get_all_tags_resource_filter_boto3():
|
||||
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
||||
@ -433,99 +226,6 @@ def test_get_all_tags_resource_filter_boto3():
|
||||
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
|
||||
def test_get_all_tags_value_filter_boto3():
|
||||
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])
|
||||
|
||||
|
||||
# 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
|
||||
def test_retrieved_instances_must_contain_their_tags_boto3():
|
||||
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}])
|
||||
|
||||
|
||||
# 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
|
||||
def test_retrieved_volumes_must_contain_their_tags_boto3():
|
||||
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}])
|
||||
|
||||
|
||||
# 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
|
||||
def test_retrieved_snapshots_must_contain_their_tags_boto3():
|
||||
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}])
|
||||
|
||||
|
||||
# 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
|
||||
def test_filter_instances_by_wildcard_tags_boto3():
|
||||
ec2 = boto3.resource("ec2", region_name="eu-west-1")
|
||||
|
@ -1,9 +1,8 @@
|
||||
import boto
|
||||
import boto3
|
||||
import pytest
|
||||
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 .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})
|
||||
|
||||
|
||||
@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
|
||||
def test_describe_vpn_connections_state_filter_deatched():
|
||||
"""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)
|
||||
|
||||
|
||||
# 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
|
||||
def test_vpn_gateway_vpc_attachment_boto3():
|
||||
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}])
|
||||
|
||||
|
||||
# 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
|
||||
def test_delete_vpn_gateway_boto3():
|
||||
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")
|
||||
|
||||
|
||||
# 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
|
||||
def test_vpn_gateway_tagging_boto3():
|
||||
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'}])
|
||||
|
||||
|
||||
# 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
|
||||
def test_detach_vpn_gateway_boto3():
|
||||
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
Loading…
x
Reference in New Issue
Block a user