Remove DynamoDB2/RDS2 decorators (#5383)
This commit is contained in:
parent
3d913f8f15
commit
5d897cc7e1
@ -3,30 +3,8 @@ import sys
|
||||
from contextlib import ContextDecorator
|
||||
|
||||
|
||||
def lazy_load(
|
||||
module_name,
|
||||
element,
|
||||
boto3_name=None,
|
||||
backend=None,
|
||||
warn_repurpose=False,
|
||||
use_instead=None,
|
||||
):
|
||||
def lazy_load(module_name, element, boto3_name=None, backend=None):
|
||||
def f(*args, **kwargs):
|
||||
if warn_repurpose:
|
||||
import warnings
|
||||
|
||||
warnings.warn(
|
||||
f"Module {element} has been deprecated, and will be repurposed in a later release. "
|
||||
"Please see https://github.com/spulec/moto/issues/4526 for more information."
|
||||
)
|
||||
if use_instead:
|
||||
import warnings
|
||||
|
||||
used, recommended = use_instead
|
||||
warnings.warn(
|
||||
f"Module {used} has been deprecated, and will be removed in a later release. Please use {recommended} instead. "
|
||||
"See https://github.com/spulec/moto/issues/4526 for more information."
|
||||
)
|
||||
module = importlib.import_module(module_name, "moto")
|
||||
return getattr(module, element)(*args, **kwargs)
|
||||
|
||||
@ -77,9 +55,6 @@ mock_dax = lazy_load(".dax", "mock_dax")
|
||||
mock_dms = lazy_load(".dms", "mock_dms")
|
||||
mock_ds = lazy_load(".ds", "mock_ds")
|
||||
mock_dynamodb = lazy_load(".dynamodb", "mock_dynamodb")
|
||||
mock_dynamodb2 = lazy_load(
|
||||
".dynamodb", "mock_dynamodb", use_instead=("mock_dynamodb2", "mock_dynamodb")
|
||||
)
|
||||
mock_dynamodbstreams = lazy_load(".dynamodbstreams", "mock_dynamodbstreams")
|
||||
mock_elasticbeanstalk = lazy_load(
|
||||
".elasticbeanstalk", "mock_elasticbeanstalk", backend="eb_backends"
|
||||
@ -137,7 +112,6 @@ mock_polly = lazy_load(".polly", "mock_polly")
|
||||
mock_quicksight = lazy_load(".quicksight", "mock_quicksight")
|
||||
mock_ram = lazy_load(".ram", "mock_ram")
|
||||
mock_rds = lazy_load(".rds", "mock_rds")
|
||||
mock_rds2 = lazy_load(".rds", "mock_rds", use_instead=("mock_rds2", "mock_rds"))
|
||||
mock_redshift = lazy_load(".redshift", "mock_redshift")
|
||||
mock_redshiftdata = lazy_load(
|
||||
".redshiftdata", "mock_redshiftdata", boto3_name="redshift-data"
|
||||
@ -190,11 +164,7 @@ class MockAll(ContextDecorator):
|
||||
def __init__(self):
|
||||
self.mocks = []
|
||||
for mock in dir(sys.modules["moto"]):
|
||||
if (
|
||||
mock.startswith("mock_")
|
||||
and not mock.endswith("_deprecated")
|
||||
and not mock == ("mock_all")
|
||||
):
|
||||
if mock.startswith("mock_") and not mock == ("mock_all"):
|
||||
self.mocks.append(globals()[mock]())
|
||||
|
||||
def __enter__(self):
|
||||
|
@ -3,11 +3,7 @@ import moto
|
||||
import sys
|
||||
|
||||
|
||||
decorators = [
|
||||
d
|
||||
for d in dir(moto)
|
||||
if d.startswith("mock_") and not d.endswith("_deprecated") and not d == "mock_all"
|
||||
]
|
||||
decorators = [d for d in dir(moto) if d.startswith("mock_") and not d == "mock_all"]
|
||||
decorator_functions = [getattr(moto, f) for f in decorators]
|
||||
BACKENDS = {f.boto3_name: (f.name, f.backend) for f in decorator_functions}
|
||||
BACKENDS["dynamodb_v20111205"] = ("dynamodb_v20111205", "dynamodb_backends")
|
||||
|
@ -270,7 +270,7 @@ class UpdateExpressionExecutor(object):
|
||||
|
||||
def execute(self, node=None):
|
||||
"""
|
||||
As explained in moto.dynamodb2.parsing.expressions.NestableExpressionParserMixin._create_node the order of nodes
|
||||
As explained in moto.dynamodb.parsing.expressions.NestableExpressionParserMixin._create_node the order of nodes
|
||||
in the AST can be translated of the order of statements in the expression. As such we can start at the root node
|
||||
and process the nodes 1-by-1. If no specific execution for the node type is defined we can execute the children
|
||||
in order since it will be a container node that is expandable and left child will be first in the statement.
|
||||
|
@ -116,7 +116,7 @@ class NestableExpressionParserMixin(object):
|
||||
|
||||
self.target_clauses looks like: ( SET a=3 >> REMOVE b )
|
||||
Returns:
|
||||
moto.dynamodb2.ast_nodes.Node: Node of an AST representing the Expression as produced by the factory.
|
||||
moto.dynamodb.ast_nodes.Node: Node of an AST representing the Expression as produced by the factory.
|
||||
"""
|
||||
assert len(self.target_clauses) > 0, "No nodes for {cn}".format(
|
||||
cn=self.__class__.__name__
|
||||
@ -151,7 +151,7 @@ class ExpressionParser(metaclass=abc.ABCMeta):
|
||||
Start parsing the token_list from token_pos for the factory type.
|
||||
|
||||
Returns:
|
||||
moto.dynamodb2.ast_nodes.Node: AST which is root node of resulting abstract syntax tree
|
||||
moto.dynamodb.ast_nodes.Node: AST which is root node of resulting abstract syntax tree
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
@ -164,7 +164,7 @@ class ExpressionParser(metaclass=abc.ABCMeta):
|
||||
"""
|
||||
|
||||
Args:
|
||||
token(moto.dynamodb2.tokens.Token):
|
||||
token(moto.dynamodb.tokens.Token):
|
||||
|
||||
Returns:
|
||||
bool: True if token is a possible start for entries processed by `cls`
|
||||
@ -200,7 +200,7 @@ class ExpressionParser(metaclass=abc.ABCMeta):
|
||||
Get the next token to be processed
|
||||
|
||||
Returns:
|
||||
moto.dynamodb2.tokens.Token: or None if no more next token
|
||||
moto.dynamodb.tokens.Token: or None if no more next token
|
||||
"""
|
||||
try:
|
||||
return self.token_list[self.token_pos]
|
||||
@ -413,7 +413,7 @@ class NestableBinExpressionParser(ExpressionParser):
|
||||
|
||||
self.target_nodes looks like: ( a >> + >> :val >> - >> :val2 )
|
||||
Returns:
|
||||
moto.dynamodb2.ast_nodes.Node: Node of an AST representing the Expression as produced by the factory.
|
||||
moto.dynamodb.ast_nodes.Node: Node of an AST representing the Expression as produced by the factory.
|
||||
"""
|
||||
if len(self.target_nodes) == 1:
|
||||
return UpdateExpressionValue(children=[self.target_nodes.popleft()])
|
||||
|
@ -134,8 +134,8 @@ class DynamoHandler(BaseResponse):
|
||||
@property
|
||||
def dynamodb_backend(self):
|
||||
"""
|
||||
:return: DynamoDB2 Backend
|
||||
:rtype: moto.dynamodb2.models.DynamoDBBackend
|
||||
:return: DynamoDB Backend
|
||||
:rtype: moto.dynamodb.models.DynamoDBBackend
|
||||
"""
|
||||
return dynamodb_backends[self.current_account][self.region]
|
||||
|
||||
|
@ -1,140 +0,0 @@
|
||||
import boto3
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
import pytest
|
||||
|
||||
from boto3.dynamodb.conditions import Key
|
||||
from moto import mock_dynamodb2
|
||||
|
||||
|
||||
def test_deprecation_warning():
|
||||
with pytest.warns(None) as record:
|
||||
mock_dynamodb2()
|
||||
str(record[0].message).should.contain(
|
||||
"Module mock_dynamodb2 has been deprecated, and will be removed in a later release"
|
||||
)
|
||||
|
||||
|
||||
"""
|
||||
Copy some basics test from DynamoDB
|
||||
Verify that the behaviour still works using the 'mock_dynamodb2' decorator
|
||||
"""
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
def test_basic_projection_expression_using_get_item():
|
||||
dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
|
||||
|
||||
# Create the DynamoDB table.
|
||||
dynamodb.create_table(
|
||||
TableName="users",
|
||||
KeySchema=[
|
||||
{"AttributeName": "forum_name", "KeyType": "HASH"},
|
||||
{"AttributeName": "subject", "KeyType": "RANGE"},
|
||||
],
|
||||
AttributeDefinitions=[
|
||||
{"AttributeName": "forum_name", "AttributeType": "S"},
|
||||
{"AttributeName": "subject", "AttributeType": "S"},
|
||||
],
|
||||
ProvisionedThroughput={"ReadCapacityUnits": 5, "WriteCapacityUnits": 5},
|
||||
)
|
||||
table = dynamodb.Table("users")
|
||||
|
||||
table.put_item(
|
||||
Item={"forum_name": "the-key", "subject": "123", "body": "some test message"}
|
||||
)
|
||||
|
||||
table.put_item(
|
||||
Item={
|
||||
"forum_name": "not-the-key",
|
||||
"subject": "123",
|
||||
"body": "some other test message",
|
||||
}
|
||||
)
|
||||
result = table.get_item(
|
||||
Key={"forum_name": "the-key", "subject": "123"},
|
||||
ProjectionExpression="body, subject",
|
||||
)
|
||||
|
||||
result["Item"].should.be.equal({"subject": "123", "body": "some test message"})
|
||||
|
||||
# The projection expression should not remove data from storage
|
||||
result = table.get_item(Key={"forum_name": "the-key", "subject": "123"})
|
||||
|
||||
result["Item"].should.be.equal(
|
||||
{"forum_name": "the-key", "subject": "123", "body": "some test message"}
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
def test_condition_expression_with_dot_in_attr_name():
|
||||
dynamodb = boto3.resource("dynamodb", region_name="us-east-2")
|
||||
table_name = "Test"
|
||||
dynamodb.create_table(
|
||||
TableName=table_name,
|
||||
KeySchema=[{"AttributeName": "id", "KeyType": "HASH"}],
|
||||
AttributeDefinitions=[{"AttributeName": "id", "AttributeType": "S"}],
|
||||
BillingMode="PAY_PER_REQUEST",
|
||||
)
|
||||
table = dynamodb.Table(table_name)
|
||||
|
||||
email_like_str = "test@foo.com"
|
||||
record = {"id": "key-0", "first": {email_like_str: {"third": {"VALUE"}}}}
|
||||
table.put_item(Item=record)
|
||||
|
||||
table.update_item(
|
||||
Key={"id": "key-0"},
|
||||
UpdateExpression="REMOVE #first.#second, #other",
|
||||
ExpressionAttributeNames={
|
||||
"#first": "first",
|
||||
"#second": email_like_str,
|
||||
"#third": "third",
|
||||
"#other": "other",
|
||||
},
|
||||
ExpressionAttributeValues={":value": "VALUE", ":one": 1},
|
||||
ConditionExpression="size(#first.#second.#third) = :one AND contains(#first.#second.#third, :value)",
|
||||
ReturnValues="ALL_NEW",
|
||||
)
|
||||
|
||||
item = table.get_item(Key={"id": "key-0"})["Item"]
|
||||
item.should.equal({"id": "key-0", "first": {}})
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
def test_query_filter_boto3():
|
||||
table_schema = {
|
||||
"KeySchema": [
|
||||
{"AttributeName": "pk", "KeyType": "HASH"},
|
||||
{"AttributeName": "sk", "KeyType": "RANGE"},
|
||||
],
|
||||
"AttributeDefinitions": [
|
||||
{"AttributeName": "pk", "AttributeType": "S"},
|
||||
{"AttributeName": "sk", "AttributeType": "S"},
|
||||
],
|
||||
}
|
||||
|
||||
dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
|
||||
table = dynamodb.create_table(
|
||||
TableName="test-table", BillingMode="PAY_PER_REQUEST", **table_schema
|
||||
)
|
||||
|
||||
for i in range(0, 3):
|
||||
table.put_item(Item={"pk": "pk", "sk": "sk-{}".format(i)})
|
||||
|
||||
res = table.query(KeyConditionExpression=Key("pk").eq("pk"))
|
||||
res["Items"].should.have.length_of(3)
|
||||
|
||||
res = table.query(KeyConditionExpression=Key("pk").eq("pk") & Key("sk").lt("sk-1"))
|
||||
res["Items"].should.have.length_of(1)
|
||||
res["Items"].should.equal([{"pk": "pk", "sk": "sk-0"}])
|
||||
|
||||
res = table.query(KeyConditionExpression=Key("pk").eq("pk") & Key("sk").lte("sk-1"))
|
||||
res["Items"].should.have.length_of(2)
|
||||
res["Items"].should.equal([{"pk": "pk", "sk": "sk-0"}, {"pk": "pk", "sk": "sk-1"}])
|
||||
|
||||
res = table.query(KeyConditionExpression=Key("pk").eq("pk") & Key("sk").gt("sk-1"))
|
||||
res["Items"].should.have.length_of(1)
|
||||
res["Items"].should.equal([{"pk": "pk", "sk": "sk-2"}])
|
||||
|
||||
res = table.query(KeyConditionExpression=Key("pk").eq("pk") & Key("sk").gte("sk-1"))
|
||||
res["Items"].should.have.length_of(2)
|
||||
res["Items"].should.equal([{"pk": "pk", "sk": "sk-1"}, {"pk": "pk", "sk": "sk-2"}])
|
@ -1,80 +0,0 @@
|
||||
import boto3
|
||||
import pytest
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
|
||||
from moto import mock_rds2
|
||||
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
|
||||
|
||||
|
||||
def test_deprecation_warning():
|
||||
with pytest.warns(None) as record:
|
||||
mock_rds2()
|
||||
str(record[0].message).should.contain(
|
||||
"Module mock_rds2 has been deprecated, and will be removed in a later release."
|
||||
)
|
||||
str(record[0].message).should.contain("Please use mock_rds instead.")
|
||||
|
||||
|
||||
@mock_rds2
|
||||
def test_create_db_cluster__verify_default_properties():
|
||||
client = boto3.client("rds", region_name="eu-north-1")
|
||||
|
||||
resp = client.create_db_cluster(
|
||||
DBClusterIdentifier="cluster-id",
|
||||
Engine="aurora",
|
||||
MasterUsername="root",
|
||||
MasterUserPassword="hunter2_",
|
||||
)
|
||||
resp.should.have.key("DBCluster")
|
||||
|
||||
cluster = resp["DBCluster"]
|
||||
|
||||
cluster.shouldnt.have.key(
|
||||
"DatabaseName"
|
||||
) # This was not supplied, so should not be returned
|
||||
|
||||
cluster.should.have.key("AllocatedStorage").equal(1)
|
||||
cluster.should.have.key("AvailabilityZones")
|
||||
set(cluster["AvailabilityZones"]).should.equal(
|
||||
{"eu-north-1a", "eu-north-1b", "eu-north-1c"}
|
||||
)
|
||||
cluster.should.have.key("BackupRetentionPeriod").equal(1)
|
||||
cluster.should.have.key("DBClusterIdentifier").equal("cluster-id")
|
||||
cluster.should.have.key("DBClusterParameterGroup").equal("default.aurora8.0")
|
||||
cluster.should.have.key("DBSubnetGroup").equal("default")
|
||||
cluster.should.have.key("Status").equal("creating")
|
||||
cluster.should.have.key("Endpoint").match(
|
||||
"cluster-id.cluster-[a-z0-9]{12}.eu-north-1.rds.amazonaws.com"
|
||||
)
|
||||
endpoint = cluster["Endpoint"]
|
||||
expected_readonly = endpoint.replace(
|
||||
"cluster-id.cluster-", "cluster-id.cluster-ro-"
|
||||
)
|
||||
cluster.should.have.key("ReaderEndpoint").equal(expected_readonly)
|
||||
cluster.should.have.key("MultiAZ").equal(False)
|
||||
cluster.should.have.key("Engine").equal("aurora")
|
||||
cluster.should.have.key("EngineVersion").equal("5.6.mysql_aurora.1.22.5")
|
||||
cluster.should.have.key("Port").equal(3306)
|
||||
cluster.should.have.key("MasterUsername").equal("root")
|
||||
cluster.should.have.key("PreferredBackupWindow").equal("01:37-02:07")
|
||||
cluster.should.have.key("PreferredMaintenanceWindow").equal("wed:02:40-wed:03:10")
|
||||
cluster.should.have.key("ReadReplicaIdentifiers").equal([])
|
||||
cluster.should.have.key("DBClusterMembers").equal([])
|
||||
cluster.should.have.key("VpcSecurityGroups")
|
||||
cluster.should.have.key("HostedZoneId")
|
||||
cluster.should.have.key("StorageEncrypted").equal(False)
|
||||
cluster.should.have.key("DbClusterResourceId").match(r"cluster-[A-Z0-9]{26}")
|
||||
cluster.should.have.key("DBClusterArn").equal(
|
||||
f"arn:aws:rds:eu-north-1:{ACCOUNT_ID}:cluster:cluster-id"
|
||||
)
|
||||
cluster.should.have.key("AssociatedRoles").equal([])
|
||||
cluster.should.have.key("IAMDatabaseAuthenticationEnabled").equal(False)
|
||||
cluster.should.have.key("EngineMode").equal("provisioned")
|
||||
cluster.should.have.key("DeletionProtection").equal(False)
|
||||
cluster.should.have.key("HttpEndpointEnabled").equal(False)
|
||||
cluster.should.have.key("CopyTagsToSnapshot").equal(False)
|
||||
cluster.should.have.key("CrossAccountClone").equal(False)
|
||||
cluster.should.have.key("DeletionProtection").equal(False)
|
||||
cluster.should.have.key("DomainMemberships").equal([])
|
||||
cluster.should.have.key("TagList").equal([])
|
||||
cluster.should.have.key("ClusterCreateTime")
|
Loading…
Reference in New Issue
Block a user