Rewrite deprecated DynamoDB2 tests (#3904)

This commit is contained in:
Bert Blommers 2021-09-22 18:13:28 +00:00 committed by GitHub
parent f17b4a3904
commit 9d1dd79813
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 560 additions and 0 deletions

View File

@ -15,6 +15,7 @@ class TestSocketPair(unittest.TestCase):
self.assertIsNotNone(asyncio.get_event_loop())
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_socket_pair_deprecated(self):

View File

@ -28,6 +28,7 @@ except ImportError:
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_list_tables():
name = "TestTable"
@ -45,7 +46,26 @@ def test_list_tables():
assert conn.list_tables()["TableNames"] == [name]
@mock_dynamodb2
@pytest.mark.parametrize(
"names",
[[], ["TestTable"], ["TestTable1", "TestTable2"]],
ids=["no-table", "one-table", "multiple-tables"],
)
def test_list_tables_boto3(names):
conn = boto3.client("dynamodb", region_name="us-west-2")
for name in names:
conn.create_table(
TableName=name,
KeySchema=[{"AttributeName": "id", "KeyType": "HASH"}],
AttributeDefinitions=[{"AttributeName": "id", "AttributeType": "S"}],
ProvisionedThroughput={"ReadCapacityUnits": 5, "WriteCapacityUnits": 5},
)
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
@ -68,7 +88,32 @@ def test_list_tables_layer_1():
res.should.equal(expected)
@mock_dynamodb2
def test_list_tables_paginated():
conn = boto3.client("dynamodb", region_name="us-west-2")
for name in ["name1", "name2", "name3"]:
conn.create_table(
TableName=name,
KeySchema=[{"AttributeName": "id", "KeyType": "HASH"}],
AttributeDefinitions=[{"AttributeName": "id", "AttributeType": "S"}],
ProvisionedThroughput={"ReadCapacityUnits": 5, "WriteCapacityUnits": 5},
)
res = conn.list_tables(Limit=2)
res.should.have.key("TableNames").equal(["name1", "name2"])
res.should.have.key("LastEvaluatedTableName").equal("name2")
res = conn.list_tables(Limit=1, ExclusiveStartTableName="name1")
res.should.have.key("TableNames").equal(["name2"])
res.should.have.key("LastEvaluatedTableName").equal("name2")
res = conn.list_tables(ExclusiveStartTableName="name1")
res.should.have.key("TableNames").equal(["name2", "name3"])
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(
@ -78,6 +123,16 @@ def test_describe_missing_table():
conn.describe_table("messages")
@mock_dynamodb2
def test_describe_missing_table_boto3():
conn = boto3.client("dynamodb", region_name="us-west-2")
with pytest.raises(ClientError) as ex:
conn.describe_table(TableName="messages")
ex.value.response["Error"]["Code"].should.equal("ResourceNotFoundException")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["Error"]["Message"].should.equal("Requested resource not found")
@requires_boto_gte("2.9")
@mock_dynamodb2
def test_list_table_tags():

View File

@ -6,6 +6,7 @@ import boto
import boto3
from boto3.dynamodb.conditions import Key
from botocore.exceptions import ClientError
from datetime import datetime
import sure # noqa
from freezegun import freeze_time
import pytest
@ -57,6 +58,7 @@ def iterate_results(res):
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
@freeze_time("2012-01-14")
def test_create_table():
@ -89,7 +91,52 @@ def test_create_table():
table.describe().should.equal(expected)
@mock_dynamodb2
def test_create_table_boto3():
client = boto3.client("dynamodb", region_name="us-east-1")
client.create_table(
TableName="messages",
KeySchema=[
{"AttributeName": "id", "KeyType": "HASH"},
{"AttributeName": "subject", "KeyType": "RANGE"},
],
AttributeDefinitions=[
{"AttributeName": "id", "AttributeType": "S"},
{"AttributeName": "subject", "AttributeType": "S"},
],
ProvisionedThroughput={"ReadCapacityUnits": 1, "WriteCapacityUnits": 5},
)
actual = client.describe_table(TableName="messages")["Table"]
actual.should.have.key("AttributeDefinitions").equal(
[
{"AttributeName": "id", "AttributeType": "S"},
{"AttributeName": "subject", "AttributeType": "S"},
]
)
actual.should.have.key("CreationDateTime").be.a(datetime)
actual.should.have.key("GlobalSecondaryIndexes").equal([])
actual.should.have.key("LocalSecondaryIndexes").equal([])
actual.should.have.key("ProvisionedThroughput").equal(
{"NumberOfDecreasesToday": 0, "ReadCapacityUnits": 1, "WriteCapacityUnits": 5}
)
actual.should.have.key("TableSizeBytes").equal(0)
actual.should.have.key("TableName").equal("messages")
actual.should.have.key("TableStatus").equal("ACTIVE")
actual.should.have.key("TableArn").equal(
"arn:aws:dynamodb:us-east-1:123456789011:table/messages"
)
actual.should.have.key("KeySchema").equal(
[
{"AttributeName": "id", "KeyType": "HASH"},
{"AttributeName": "subject", "KeyType": "RANGE"},
]
)
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():
@ -132,7 +179,75 @@ def test_create_table_with_local_index():
table.describe().should.equal(expected)
@mock_dynamodb2
def test_create_table_with_local_index_boto3():
client = boto3.client("dynamodb", region_name="us-east-1")
client.create_table(
TableName="messages",
KeySchema=[
{"AttributeName": "id", "KeyType": "HASH"},
{"AttributeName": "subject", "KeyType": "RANGE"},
],
AttributeDefinitions=[
{"AttributeName": "id", "AttributeType": "S"},
{"AttributeName": "subject", "AttributeType": "S"},
{"AttributeName": "threads", "AttributeType": "S"},
],
LocalSecondaryIndexes=[
{
"IndexName": "threads_index",
"KeySchema": [
{"AttributeName": "id", "KeyType": "HASH"},
{"AttributeName": "threads", "KeyType": "RANGE"},
],
"Projection": {"ProjectionType": "ALL"},
}
],
ProvisionedThroughput={"ReadCapacityUnits": 1, "WriteCapacityUnits": 5},
)
actual = client.describe_table(TableName="messages")["Table"]
actual.should.have.key("AttributeDefinitions").equal(
[
{"AttributeName": "id", "AttributeType": "S"},
{"AttributeName": "subject", "AttributeType": "S"},
{"AttributeName": "threads", "AttributeType": "S"},
]
)
actual.should.have.key("CreationDateTime").be.a(datetime)
actual.should.have.key("GlobalSecondaryIndexes").equal([])
actual.should.have.key("LocalSecondaryIndexes").equal(
[
{
"IndexName": "threads_index",
"KeySchema": [
{"AttributeName": "id", "KeyType": "HASH"},
{"AttributeName": "threads", "KeyType": "RANGE"},
],
"Projection": {"ProjectionType": "ALL"},
}
]
)
actual.should.have.key("ProvisionedThroughput").equal(
{"NumberOfDecreasesToday": 0, "ReadCapacityUnits": 1, "WriteCapacityUnits": 5}
)
actual.should.have.key("TableSizeBytes").equal(0)
actual.should.have.key("TableName").equal("messages")
actual.should.have.key("TableStatus").equal("ACTIVE")
actual.should.have.key("TableArn").equal(
"arn:aws:dynamodb:us-east-1:123456789011:table/messages"
)
actual.should.have.key("KeySchema").equal(
[
{"AttributeName": "id", "KeyType": "HASH"},
{"AttributeName": "subject", "KeyType": "RANGE"},
]
)
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()
@ -145,6 +260,7 @@ def test_delete_table():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_update_table_throughput():
table = create_table()
@ -164,6 +280,7 @@ def test_update_table_throughput():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_item_add_and_describe_and_update():
table = create_table()
@ -209,6 +326,7 @@ def test_item_add_and_describe_and_update():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_item_partial_save():
table = create_table()
@ -238,6 +356,7 @@ def test_item_partial_save():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_item_put_without_table():
table = Table("undeclared-table")
@ -252,6 +371,7 @@ def test_item_put_without_table():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_get_missing_item():
table = create_table()
@ -262,6 +382,7 @@ def test_get_missing_item():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_get_item_with_undeclared_table():
table = Table("undeclared-table")
@ -271,6 +392,7 @@ def test_get_item_with_undeclared_table():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_get_item_without_range_key():
table = Table.create(
@ -287,7 +409,35 @@ def test_get_item_without_range_key():
)
@mock_dynamodb2
def test_get_item_without_range_key_boto3():
client = boto3.resource("dynamodb", region_name="us-east-1")
table = client.create_table(
TableName="messages",
KeySchema=[
{"AttributeName": "id", "KeyType": "HASH"},
{"AttributeName": "subject", "KeyType": "RANGE"},
],
AttributeDefinitions=[
{"AttributeName": "id", "AttributeType": "S"},
{"AttributeName": "subject", "AttributeType": "S"},
],
ProvisionedThroughput={"ReadCapacityUnits": 1, "WriteCapacityUnits": 5},
)
hash_key = 3241526475
range_key = 1234567890987
table.put_item(Item={"id": hash_key, "subject": range_key})
with pytest.raises(ClientError) as ex:
table.get_item(Key={"id": hash_key})
ex.value.response["Error"]["Code"].should.equal("ValidationException")
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()
@ -311,6 +461,7 @@ def test_delete_item():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_delete_item_with_undeclared_table():
table = Table("undeclared-table")
@ -325,6 +476,7 @@ def test_delete_item_with_undeclared_table():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_query():
table = create_table()
@ -384,6 +536,7 @@ def test_query():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_query_with_undeclared_table():
table = Table("undeclared")
@ -394,6 +547,7 @@ def test_query_with_undeclared_table():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_scan():
table = create_table()
@ -449,6 +603,7 @@ def test_scan():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_scan_with_undeclared_table():
conn = boto.dynamodb2.layer1.DynamoDBConnection()
@ -464,6 +619,7 @@ def test_scan_with_undeclared_table():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_write_batch():
table = create_table()
@ -495,6 +651,7 @@ def test_write_batch():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_batch_read():
table = create_table()
@ -539,6 +696,7 @@ def test_batch_read():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_get_key_fields():
table = create_table()
@ -547,6 +705,7 @@ def test_get_key_fields():
@mock_dynamodb2_deprecated
# Has boto3 equivalent
def test_create_with_global_indexes():
conn = boto.dynamodb2.layer1.DynamoDBConnection()
@ -582,6 +741,7 @@ def test_create_with_global_indexes():
)
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_query_with_global_indexes():
table = Table.create(
@ -617,6 +777,7 @@ def test_query_with_global_indexes():
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()
@ -639,6 +800,7 @@ def test_query_with_local_indexes():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_query_filter_eq():
table = create_table_with_local_indexes()
@ -672,6 +834,7 @@ def test_query_filter_eq():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_query_filter_lt():
table = create_table_with_local_indexes()
@ -707,6 +870,7 @@ def test_query_filter_lt():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_query_filter_gt():
table = create_table_with_local_indexes()
@ -741,6 +905,7 @@ def test_query_filter_gt():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_query_filter_lte():
table = create_table_with_local_indexes()
@ -775,6 +940,7 @@ def test_query_filter_lte():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_query_filter_gte():
table = create_table_with_local_indexes()
@ -808,7 +974,51 @@ def test_query_filter_gte():
list(results).should.have.length_of(2)
@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".format(i), "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"}])
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_query_non_hash_range_key():
table = create_table_with_local_indexes()
@ -845,6 +1055,7 @@ def test_query_non_hash_range_key():
results.should.have.length_of(2)
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_reverse_query():
conn = boto.dynamodb2.layer1.DynamoDBConnection()
@ -862,6 +1073,7 @@ def test_reverse_query():
[r["created_at"] for r in results].should.equal(expected)
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_lookup():
from decimal import Decimal
@ -881,6 +1093,7 @@ def test_lookup():
message.get("test_range").should.equal(Decimal(range_key))
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_failed_overwrite():
table = Table.create(
@ -910,6 +1123,7 @@ def test_failed_overwrite():
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")])

View File

@ -3,9 +3,12 @@ from __future__ import unicode_literals
import boto
import boto3
from boto3.dynamodb.conditions import Key
import pytest
import sure # noqa
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
import botocore
@ -27,6 +30,7 @@ def create_table():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
@freeze_time("2012-01-14")
def test_create_table():
@ -59,7 +63,71 @@ def test_create_table():
conn.describe_table("messages").should.equal(expected)
@mock_dynamodb2
def test_create_table_boto3():
client = boto3.client("dynamodb", region_name="us-east-1")
client.create_table(
TableName="messages",
KeySchema=[{"AttributeName": "id", "KeyType": "HASH"}],
AttributeDefinitions=[
{"AttributeName": "id", "AttributeType": "S"},
{"AttributeName": "gsi_col", "AttributeType": "S"},
],
ProvisionedThroughput={"ReadCapacityUnits": 1, "WriteCapacityUnits": 1},
GlobalSecondaryIndexes=[
{
"IndexName": "test_gsi",
"KeySchema": [{"AttributeName": "gsi_col", "KeyType": "HASH"}],
"Projection": {"ProjectionType": "ALL"},
"ProvisionedThroughput": {
"ReadCapacityUnits": 1,
"WriteCapacityUnits": 1,
},
}
],
)
actual = client.describe_table(TableName="messages")["Table"]
actual.should.have.key("AttributeDefinitions").equal(
[
{"AttributeName": "id", "AttributeType": "S"},
{"AttributeName": "gsi_col", "AttributeType": "S"},
]
)
actual.should.have.key("CreationDateTime").be.a(datetime)
actual.should.have.key("GlobalSecondaryIndexes").equal(
[
{
"IndexName": "test_gsi",
"KeySchema": [{"AttributeName": "gsi_col", "KeyType": "HASH"}],
"Projection": {"ProjectionType": "ALL"},
"IndexStatus": "ACTIVE",
"ProvisionedThroughput": {
"ReadCapacityUnits": 1,
"WriteCapacityUnits": 1,
},
}
]
)
actual.should.have.key("LocalSecondaryIndexes").equal([])
actual.should.have.key("ProvisionedThroughput").equal(
{"NumberOfDecreasesToday": 0, "ReadCapacityUnits": 1, "WriteCapacityUnits": 1}
)
actual.should.have.key("TableSizeBytes").equal(0)
actual.should.have.key("TableName").equal("messages")
actual.should.have.key("TableStatus").equal("ACTIVE")
actual.should.have.key("TableArn").equal(
"arn:aws:dynamodb:us-east-1:123456789011:table/messages"
)
actual.should.have.key("KeySchema").equal(
[{"AttributeName": "id", "KeyType": "HASH"}]
)
actual.should.have.key("ItemCount").equal(0)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_delete_table():
create_table()
@ -72,7 +140,30 @@ def test_delete_table():
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")
conn.create_table(
TableName="messages",
KeySchema=[{"AttributeName": "id", "KeyType": "HASH"}],
AttributeDefinitions=[{"AttributeName": "id", "AttributeType": "S"}],
ProvisionedThroughput={"ReadCapacityUnits": 5, "WriteCapacityUnits": 5},
)
conn.list_tables()["TableNames"].should.have.length_of(1)
conn.delete_table(TableName="messages")
conn.list_tables()["TableNames"].should.have.length_of(0)
with pytest.raises(ClientError) as ex:
conn.delete_table(TableName="messages")
ex.value.response["Error"]["Code"].should.equal("ResourceNotFoundException")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
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()
@ -85,7 +176,28 @@ def test_update_table_throughput():
table.throughput["write"].should.equal(6)
@mock_dynamodb2
def test_update_table_throughput_boto3():
conn = boto3.resource("dynamodb", region_name="us-west-2")
table = conn.create_table(
TableName="messages",
KeySchema=[{"AttributeName": "id", "KeyType": "HASH"}],
AttributeDefinitions=[{"AttributeName": "id", "AttributeType": "S"}],
ProvisionedThroughput={"ReadCapacityUnits": 5, "WriteCapacityUnits": 5},
)
table.provisioned_throughput["ReadCapacityUnits"].should.equal(5)
table.provisioned_throughput["WriteCapacityUnits"].should.equal(5)
table.update(
ProvisionedThroughput={"ReadCapacityUnits": 5, "WriteCapacityUnits": 6}
)
table.provisioned_throughput["ReadCapacityUnits"].should.equal(5)
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()
@ -121,7 +233,44 @@ def test_item_add_and_describe_and_update():
)
@mock_dynamodb2
def test_item_add_and_describe_and_update_boto3():
conn = boto3.resource("dynamodb", region_name="us-west-2")
table = conn.create_table(
TableName="messages",
KeySchema=[{"AttributeName": "id", "KeyType": "HASH"}],
AttributeDefinitions=[{"AttributeName": "id", "AttributeType": "S"}],
ProvisionedThroughput={"ReadCapacityUnits": 5, "WriteCapacityUnits": 5},
)
data = {
"id": "LOLCat Forum",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
}
table.put_item(Item=data)
returned_item = table.get_item(Key={"id": "LOLCat Forum"})
returned_item.shouldnt.have.key("ConsumedCapacity")
dict(returned_item["Item"]).should.equal(
{"id": "LOLCat Forum", "Body": "http://url_to_lolcat.gif", "SentBy": "User A",}
)
table.update_item(
Key={"id": "LOLCat Forum"},
UpdateExpression="SET SentBy=:user",
ExpressionAttributeValues={":user": "User B"},
)
returned_item = table.get_item(Key={"id": "LOLCat Forum"})
returned_item["Item"].should.equal(
{"id": "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_partial_save():
table = create_table()
@ -149,6 +298,7 @@ def test_item_partial_save():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_item_put_without_table():
conn = boto.dynamodb2.layer1.DynamoDBConnection()
@ -163,7 +313,27 @@ def test_item_put_without_table():
).should.throw(JSONResponseError)
@mock_dynamodb2
def test_item_put_without_table_boto3():
conn = boto3.client("dynamodb", region_name="us-west-2")
with pytest.raises(ClientError) as ex:
conn.put_item(
TableName="messages",
Item={
"forum_name": {"S": "LOLCat Forum"},
"Body": {"S": "http://url_to_lolcat.gif"},
"SentBy": {"S": "User A"},
},
)
ex.value.response["Error"]["Code"].should.equal("ResourceNotFoundException")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
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()
@ -173,7 +343,20 @@ def test_get_item_with_undeclared_table():
).should.throw(JSONResponseError)
@mock_dynamodb2
def test_get_item_with_undeclared_table_boto3():
conn = boto3.client("dynamodb", region_name="us-west-2")
with pytest.raises(ClientError) as ex:
conn.get_item(TableName="messages", Key={"forum_name": {"S": "LOLCat Forum"}})
ex.value.response["Error"]["Code"].should.equal("ResourceNotFoundException")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
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()
@ -198,7 +381,35 @@ def test_delete_item():
item.delete().should.equal(True)
@mock_dynamodb2
def test_delete_item_boto3():
conn = boto3.resource("dynamodb", region_name="us-west-2")
table = conn.create_table(
TableName="messages",
KeySchema=[{"AttributeName": "id", "KeyType": "HASH"}],
AttributeDefinitions=[{"AttributeName": "id", "AttributeType": "S"}],
ProvisionedThroughput={"ReadCapacityUnits": 5, "WriteCapacityUnits": 5},
)
item_data = {
"id": "LOLCat Forum",
"Body": "http://url_to_lolcat.gif",
"SentBy": "User A",
"ReceivedTime": "12/9/2011 11:36:03 PM",
}
table.put_item(Item=item_data)
table.item_count.should.equal(1)
table.delete_item(Key={"id": "LOLCat Forum"})
table.item_count.should.equal(0)
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()
@ -208,7 +419,24 @@ def test_delete_item_with_undeclared_table():
).should.throw(JSONResponseError)
@mock_dynamodb2
def test_delete_item_with_undeclared_table_boto3():
conn = boto3.client("dynamodb", region_name="us-west-2")
with pytest.raises(ClientError) as ex:
conn.delete_item(
TableName="messages", Key={"forum_name": {"S": "LOLCat Forum"}}
)
ex.value.response["Error"]["Code"].should.equal("ConditionalCheckFailedException")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["Error"]["Message"].should.equal(
"A condition specified in the operation could not be evaluated."
)
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_query():
table = create_table()
@ -229,6 +457,7 @@ def test_query():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_query_with_undeclared_table():
conn = boto.dynamodb2.layer1.DynamoDBConnection()
@ -245,6 +474,7 @@ def test_query_with_undeclared_table():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_scan():
table = create_table()
@ -296,6 +526,7 @@ def test_scan():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_scan_with_undeclared_table():
conn = boto.dynamodb2.layer1.DynamoDBConnection()
@ -311,7 +542,20 @@ def test_scan_with_undeclared_table():
).should.throw(JSONResponseError)
@mock_dynamodb2
def test_scan_with_undeclared_table_boto3():
conn = boto3.client("dynamodb", region_name="us-west-2")
with pytest.raises(ClientError) as ex:
conn.scan(TableName="messages")
ex.value.response["Error"]["Code"].should.equal("ResourceNotFoundException")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
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()
@ -344,6 +588,7 @@ def test_write_batch():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_batch_read():
table = create_table()
@ -382,6 +627,7 @@ def test_batch_read():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_get_key_fields():
table = create_table()
@ -389,7 +635,21 @@ def test_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")
table = conn.create_table(
TableName="messages",
KeySchema=[{"AttributeName": "id", "KeyType": "HASH"}],
AttributeDefinitions=[{"AttributeName": "id", "AttributeType": "S"}],
ProvisionedThroughput={"ReadCapacityUnits": 5, "WriteCapacityUnits": 5},
)
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()
@ -397,6 +657,7 @@ def test_get_missing_item():
@requires_boto_gte("2.9")
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_get_special_item():
table = Table.create(
@ -411,6 +672,7 @@ def test_get_special_item():
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")
@ -427,6 +689,7 @@ def test_update_item_remove():
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")
@ -478,6 +741,7 @@ 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")
@ -498,6 +762,31 @@ def test_update_item_set():
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")
table = conn.create_table(
TableName="messages",
KeySchema=[{"AttributeName": "username", "KeyType": "HASH"}],
AttributeDefinitions=[{"AttributeName": "username", "AttributeType": "S"}],
BillingMode="PAY_PER_REQUEST",
)
data = {"username": "steve", "SentBy": "User A"}
table.put_item(Item=data)
key_map = {"username": "steve"}
table.update_item(
Key=key_map,
UpdateExpression="SET foo=:bar, blah=:baz REMOVE SentBy",
ExpressionAttributeValues={":bar": "bar", ":baz": "baz"},
)
returned_item = table.get_item(Key=key_map)["Item"]
dict(returned_item).should.equal({"username": "steve", "foo": "bar", "blah": "baz"})
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_failed_overwrite():
table = Table.create(
@ -525,6 +814,7 @@ def test_failed_overwrite():
dict(returned_item).should.equal(data4)
# Has boto3 equivalent
@mock_dynamodb2_deprecated
def test_conflicting_writes():
table = Table.create("messages", schema=[HashKey("id")])