This commit is contained in:
Bert Blommers 2020-11-11 15:55:37 +00:00
commit 273ca63d59
92 changed files with 515 additions and 1200 deletions

View file

@ -1347,13 +1347,9 @@ def test_get_item_returns_consumed_capacity():
def test_put_empty_item():
dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
dynamodb.create_table(
AttributeDefinitions=[
{"AttributeName": "structure_id", "AttributeType": "S"},
],
AttributeDefinitions=[{"AttributeName": "structure_id", "AttributeType": "S"},],
TableName="test",
KeySchema=[
{"AttributeName": "structure_id", "KeyType": "HASH"},
],
KeySchema=[{"AttributeName": "structure_id", "KeyType": "HASH"},],
ProvisionedThroughput={"ReadCapacityUnits": 123, "WriteCapacityUnits": 123},
)
table = dynamodb.Table("test")
@ -1370,13 +1366,9 @@ def test_put_empty_item():
def test_put_item_nonexisting_hash_key():
dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
dynamodb.create_table(
AttributeDefinitions=[
{"AttributeName": "structure_id", "AttributeType": "S"},
],
AttributeDefinitions=[{"AttributeName": "structure_id", "AttributeType": "S"},],
TableName="test",
KeySchema=[
{"AttributeName": "structure_id", "KeyType": "HASH"},
],
KeySchema=[{"AttributeName": "structure_id", "KeyType": "HASH"},],
ProvisionedThroughput={"ReadCapacityUnits": 123, "WriteCapacityUnits": 123},
)
table = dynamodb.Table("test")
@ -2295,10 +2287,7 @@ def test_update_item_on_map():
table.update_item(
Key={"forum_name": "the-key", "subject": "123"},
UpdateExpression="SET body.#nested.#data = :tb",
ExpressionAttributeNames={
"#nested": "nested",
"#data": "data",
},
ExpressionAttributeNames={"#nested": "nested", "#data": "data",},
ExpressionAttributeValues={":tb": "new_value"},
)
# Running this against AWS DDB gives an exception so make sure it also fails.:
@ -3962,30 +3951,19 @@ def test_update_supports_nested_update_if_nested_value_not_exists():
table = dynamodb.Table(name)
table.put_item(
Item={
"user_id": "1234",
"friends": {"5678": {"name": "friend_5678"}},
},
Item={"user_id": "1234", "friends": {"5678": {"name": "friend_5678"}},},
)
table.update_item(
Key={"user_id": "1234"},
ExpressionAttributeNames={
"#friends": "friends",
"#friendid": "0000",
},
ExpressionAttributeValues={
":friend": {"name": "friend_0000"},
},
ExpressionAttributeNames={"#friends": "friends", "#friendid": "0000",},
ExpressionAttributeValues={":friend": {"name": "friend_0000"},},
UpdateExpression="SET #friends.#friendid = :friend",
ReturnValues="UPDATED_NEW",
)
item = table.get_item(Key={"user_id": "1234"})["Item"]
assert item == {
"user_id": "1234",
"friends": {
"5678": {"name": "friend_5678"},
"0000": {"name": "friend_0000"},
},
"friends": {"5678": {"name": "friend_5678"}, "0000": {"name": "friend_0000"},},
}
@ -4208,17 +4186,11 @@ def test_invalid_transact_get_items():
)
table = dynamodb.Table("test1")
table.put_item(
Item={
"id": "1",
"val": "1",
}
Item={"id": "1", "val": "1",}
)
table.put_item(
Item={
"id": "1",
"val": "2",
}
Item={"id": "1", "val": "2",}
)
client = boto3.client("dynamodb", region_name="us-east-1")
@ -4240,22 +4212,8 @@ def test_invalid_transact_get_items():
with pytest.raises(ClientError) as ex:
client.transact_get_items(
TransactItems=[
{
"Get": {
"Key": {
"id": {"S": "1"},
},
"TableName": "test1",
}
},
{
"Get": {
"Key": {
"id": {"S": "1"},
},
"TableName": "non_exists_table",
}
},
{"Get": {"Key": {"id": {"S": "1"},}, "TableName": "test1",}},
{"Get": {"Key": {"id": {"S": "1"},}, "TableName": "non_exists_table",}},
]
)
@ -4281,17 +4239,11 @@ def test_valid_transact_get_items():
)
table1 = dynamodb.Table("test1")
table1.put_item(
Item={
"id": "1",
"sort_key": "1",
}
Item={"id": "1", "sort_key": "1",}
)
table1.put_item(
Item={
"id": "1",
"sort_key": "2",
}
Item={"id": "1", "sort_key": "2",}
)
dynamodb.create_table(
@ -4308,10 +4260,7 @@ def test_valid_transact_get_items():
)
table2 = dynamodb.Table("test2")
table2.put_item(
Item={
"id": "1",
"sort_key": "1",
}
Item={"id": "1", "sort_key": "1",}
)
client = boto3.client("dynamodb", region_name="us-east-1")
@ -4425,10 +4374,7 @@ def test_valid_transact_get_items():
"TableName": "test1",
"CapacityUnits": 4.0,
"ReadCapacityUnits": 4.0,
"Table": {
"CapacityUnits": 4.0,
"ReadCapacityUnits": 4.0,
},
"Table": {"CapacityUnits": 4.0, "ReadCapacityUnits": 4.0,},
}
)
@ -4437,10 +4383,7 @@ def test_valid_transact_get_items():
"TableName": "test2",
"CapacityUnits": 2.0,
"ReadCapacityUnits": 2.0,
"Table": {
"CapacityUnits": 2.0,
"ReadCapacityUnits": 2.0,
},
"Table": {"CapacityUnits": 2.0, "ReadCapacityUnits": 2.0,},
}
)
@ -4456,9 +4399,7 @@ def test_gsi_verify_negative_number_order():
{"AttributeName": "gsiK1PartitionKey", "KeyType": "HASH"},
{"AttributeName": "gsiK1SortKey", "KeyType": "RANGE"},
],
"Projection": {
"ProjectionType": "KEYS_ONLY",
},
"Projection": {"ProjectionType": "KEYS_ONLY",},
}
],
"AttributeDefinitions": [
@ -4509,9 +4450,7 @@ def test_gsi_verify_negative_number_order():
def test_transact_write_items_put():
table_schema = {
"KeySchema": [{"AttributeName": "id", "KeyType": "HASH"}],
"AttributeDefinitions": [
{"AttributeName": "id", "AttributeType": "S"},
],
"AttributeDefinitions": [{"AttributeName": "id", "AttributeType": "S"},],
}
dynamodb = boto3.client("dynamodb", region_name="us-east-1")
dynamodb.create_table(
@ -4522,10 +4461,7 @@ def test_transact_write_items_put():
TransactItems=[
{
"Put": {
"Item": {
"id": {"S": "foo{}".format(str(i))},
"foo": {"S": "bar"},
},
"Item": {"id": {"S": "foo{}".format(str(i))}, "foo": {"S": "bar"},},
"TableName": "test-table",
}
}
@ -4541,19 +4477,14 @@ def test_transact_write_items_put():
def test_transact_write_items_put_conditional_expressions():
table_schema = {
"KeySchema": [{"AttributeName": "id", "KeyType": "HASH"}],
"AttributeDefinitions": [
{"AttributeName": "id", "AttributeType": "S"},
],
"AttributeDefinitions": [{"AttributeName": "id", "AttributeType": "S"},],
}
dynamodb = boto3.client("dynamodb", region_name="us-east-1")
dynamodb.create_table(
TableName="test-table", BillingMode="PAY_PER_REQUEST", **table_schema
)
dynamodb.put_item(
TableName="test-table",
Item={
"id": {"S": "foo2"},
},
TableName="test-table", Item={"id": {"S": "foo2"},},
)
# Put multiple items
with pytest.raises(ClientError) as ex:
@ -4591,9 +4522,7 @@ def test_transact_write_items_put_conditional_expressions():
def test_transact_write_items_conditioncheck_passes():
table_schema = {
"KeySchema": [{"AttributeName": "id", "KeyType": "HASH"}],
"AttributeDefinitions": [
{"AttributeName": "id", "AttributeType": "S"},
],
"AttributeDefinitions": [{"AttributeName": "id", "AttributeType": "S"},],
}
dynamodb = boto3.client("dynamodb", region_name="us-east-1")
dynamodb.create_table(
@ -4601,10 +4530,7 @@ def test_transact_write_items_conditioncheck_passes():
)
# Insert an item without email address
dynamodb.put_item(
TableName="test-table",
Item={
"id": {"S": "foo"},
},
TableName="test-table", Item={"id": {"S": "foo"},},
)
# Put an email address, after verifying it doesn't exist yet
dynamodb.transact_write_items(
@ -4638,9 +4564,7 @@ def test_transact_write_items_conditioncheck_passes():
def test_transact_write_items_conditioncheck_fails():
table_schema = {
"KeySchema": [{"AttributeName": "id", "KeyType": "HASH"}],
"AttributeDefinitions": [
{"AttributeName": "id", "AttributeType": "S"},
],
"AttributeDefinitions": [{"AttributeName": "id", "AttributeType": "S"},],
}
dynamodb = boto3.client("dynamodb", region_name="us-east-1")
dynamodb.create_table(
@ -4689,9 +4613,7 @@ def test_transact_write_items_conditioncheck_fails():
def test_transact_write_items_delete():
table_schema = {
"KeySchema": [{"AttributeName": "id", "KeyType": "HASH"}],
"AttributeDefinitions": [
{"AttributeName": "id", "AttributeType": "S"},
],
"AttributeDefinitions": [{"AttributeName": "id", "AttributeType": "S"},],
}
dynamodb = boto3.client("dynamodb", region_name="us-east-1")
dynamodb.create_table(
@ -4699,20 +4621,12 @@ def test_transact_write_items_delete():
)
# Insert an item
dynamodb.put_item(
TableName="test-table",
Item={
"id": {"S": "foo"},
},
TableName="test-table", Item={"id": {"S": "foo"},},
)
# Delete the item
dynamodb.transact_write_items(
TransactItems=[
{
"Delete": {
"Key": {"id": {"S": "foo"}},
"TableName": "test-table",
}
}
{"Delete": {"Key": {"id": {"S": "foo"}}, "TableName": "test-table",}}
]
)
# Assert the item is deleted
@ -4724,9 +4638,7 @@ def test_transact_write_items_delete():
def test_transact_write_items_delete_with_successful_condition_expression():
table_schema = {
"KeySchema": [{"AttributeName": "id", "KeyType": "HASH"}],
"AttributeDefinitions": [
{"AttributeName": "id", "AttributeType": "S"},
],
"AttributeDefinitions": [{"AttributeName": "id", "AttributeType": "S"},],
}
dynamodb = boto3.client("dynamodb", region_name="us-east-1")
dynamodb.create_table(
@ -4734,19 +4646,14 @@ def test_transact_write_items_delete_with_successful_condition_expression():
)
# Insert an item without email address
dynamodb.put_item(
TableName="test-table",
Item={
"id": {"S": "foo"},
},
TableName="test-table", Item={"id": {"S": "foo"},},
)
# ConditionExpression will pass - no email address has been specified yet
dynamodb.transact_write_items(
TransactItems=[
{
"Delete": {
"Key": {
"id": {"S": "foo"},
},
"Key": {"id": {"S": "foo"},},
"TableName": "test-table",
"ConditionExpression": "attribute_not_exists(#e)",
"ExpressionAttributeNames": {"#e": "email_address"},
@ -4763,9 +4670,7 @@ def test_transact_write_items_delete_with_successful_condition_expression():
def test_transact_write_items_delete_with_failed_condition_expression():
table_schema = {
"KeySchema": [{"AttributeName": "id", "KeyType": "HASH"}],
"AttributeDefinitions": [
{"AttributeName": "id", "AttributeType": "S"},
],
"AttributeDefinitions": [{"AttributeName": "id", "AttributeType": "S"},],
}
dynamodb = boto3.client("dynamodb", region_name="us-east-1")
dynamodb.create_table(
@ -4783,9 +4688,7 @@ def test_transact_write_items_delete_with_failed_condition_expression():
TransactItems=[
{
"Delete": {
"Key": {
"id": {"S": "foo"},
},
"Key": {"id": {"S": "foo"},},
"TableName": "test-table",
"ConditionExpression": "attribute_not_exists(#e)",
"ExpressionAttributeNames": {"#e": "email_address"},
@ -4806,9 +4709,7 @@ def test_transact_write_items_delete_with_failed_condition_expression():
def test_transact_write_items_update():
table_schema = {
"KeySchema": [{"AttributeName": "id", "KeyType": "HASH"}],
"AttributeDefinitions": [
{"AttributeName": "id", "AttributeType": "S"},
],
"AttributeDefinitions": [{"AttributeName": "id", "AttributeType": "S"},],
}
dynamodb = boto3.client("dynamodb", region_name="us-east-1")
dynamodb.create_table(
@ -4840,9 +4741,7 @@ def test_transact_write_items_update():
def test_transact_write_items_update_with_failed_condition_expression():
table_schema = {
"KeySchema": [{"AttributeName": "id", "KeyType": "HASH"}],
"AttributeDefinitions": [
{"AttributeName": "id", "AttributeType": "S"},
],
"AttributeDefinitions": [{"AttributeName": "id", "AttributeType": "S"},],
}
dynamodb = boto3.client("dynamodb", region_name="us-east-1")
dynamodb.create_table(
@ -5032,18 +4931,12 @@ def create_simple_table_and_return_client():
dynamodb.create_table(
TableName="moto-test",
KeySchema=[{"AttributeName": "id", "KeyType": "HASH"}],
AttributeDefinitions=[
{"AttributeName": "id", "AttributeType": "S"},
],
AttributeDefinitions=[{"AttributeName": "id", "AttributeType": "S"},],
ProvisionedThroughput={"ReadCapacityUnits": 1, "WriteCapacityUnits": 1},
)
dynamodb.put_item(
TableName="moto-test",
Item={
"id": {"S": "1"},
"myNum": {"N": "1"},
"MyStr": {"S": "1"},
},
Item={"id": {"S": "1"}, "myNum": {"N": "1"}, "MyStr": {"S": "1"},},
)
return dynamodb
@ -5107,11 +5000,7 @@ def test_update_expression_with_plus_in_attribute_name():
dynamodb.put_item(
TableName="moto-test",
Item={
"id": {"S": "1"},
"my+Num": {"S": "1"},
"MyStr": {"S": "aaa"},
},
Item={"id": {"S": "1"}, "my+Num": {"S": "1"}, "MyStr": {"S": "aaa"},},
)
try:
dynamodb.update_item(
@ -5138,11 +5027,7 @@ def test_update_expression_with_minus_in_attribute_name():
dynamodb.put_item(
TableName="moto-test",
Item={
"id": {"S": "1"},
"my-Num": {"S": "1"},
"MyStr": {"S": "aaa"},
},
Item={"id": {"S": "1"}, "my-Num": {"S": "1"}, "MyStr": {"S": "aaa"},},
)
try:
dynamodb.update_item(
@ -5169,11 +5054,7 @@ def test_update_expression_with_space_in_attribute_name():
dynamodb.put_item(
TableName="moto-test",
Item={
"id": {"S": "1"},
"my Num": {"S": "1"},
"MyStr": {"S": "aaa"},
},
Item={"id": {"S": "1"}, "my Num": {"S": "1"}, "MyStr": {"S": "aaa"},},
)
try:
@ -5356,8 +5237,7 @@ def test_update_item_atomic_counter_from_zero():
key = {"t_id": {"S": "item1"}}
ddb_mock.put_item(
TableName=table,
Item=key,
TableName=table, Item=key,
)
ddb_mock.update_item(
@ -5383,8 +5263,7 @@ def test_update_item_add_to_non_existent_set():
)
key = {"t_id": {"S": "item1"}}
ddb_mock.put_item(
TableName=table,
Item=key,
TableName=table, Item=key,
)
ddb_mock.update_item(
@ -5409,8 +5288,7 @@ def test_update_item_add_to_non_existent_number_set():
)
key = {"t_id": {"S": "item1"}}
ddb_mock.put_item(
TableName=table,
Item=key,
TableName=table, Item=key,
)
ddb_mock.update_item(
@ -5427,9 +5305,7 @@ def test_update_item_add_to_non_existent_number_set():
def test_transact_write_items_fails_with_transaction_canceled_exception():
table_schema = {
"KeySchema": [{"AttributeName": "id", "KeyType": "HASH"}],
"AttributeDefinitions": [
{"AttributeName": "id", "AttributeType": "S"},
],
"AttributeDefinitions": [{"AttributeName": "id", "AttributeType": "S"},],
}
dynamodb = boto3.client("dynamodb", region_name="us-east-1")
dynamodb.create_table(
@ -5481,9 +5357,7 @@ def test_gsi_projection_type_keys_only():
{"AttributeName": "gsiK1PartitionKey", "KeyType": "HASH"},
{"AttributeName": "gsiK1SortKey", "KeyType": "RANGE"},
],
"Projection": {
"ProjectionType": "KEYS_ONLY",
},
"Projection": {"ProjectionType": "KEYS_ONLY",},
}
],
"AttributeDefinitions": [
@ -5536,9 +5410,7 @@ def test_lsi_projection_type_keys_only():
{"AttributeName": "partitionKey", "KeyType": "HASH"},
{"AttributeName": "lsiK1SortKey", "KeyType": "RANGE"},
],
"Projection": {
"ProjectionType": "KEYS_ONLY",
},
"Projection": {"ProjectionType": "KEYS_ONLY",},
}
],
"AttributeDefinitions": [
@ -5563,8 +5435,7 @@ def test_lsi_projection_type_keys_only():
table.put_item(Item=item)
items = table.query(
KeyConditionExpression=Key("partitionKey").eq("pk-1"),
IndexName="LSI",
KeyConditionExpression=Key("partitionKey").eq("pk-1"), IndexName="LSI",
)["Items"]
items.should.have.length_of(1)
# Item should only include GSI Keys and Table Keys, as per the ProjectionType

View file

@ -212,11 +212,7 @@ def test_execution_of_remove_in_map():
"itemlist": {
"L": [
{"M": {"foo00": {"S": "bar1"}, "foo01": {"S": "bar2"}}},
{
"M": {
"foo10": {"S": "bar1"},
}
},
{"M": {"foo10": {"S": "bar1"},}},
]
}
}
@ -265,9 +261,7 @@ def test_execution_of_remove_in_list():
"itemmap": {
"M": {
"itemlist": {
"L": [
{"M": {"foo00": {"S": "bar1"}, "foo01": {"S": "bar2"}}},
]
"L": [{"M": {"foo00": {"S": "bar1"}, "foo01": {"S": "bar2"}}},]
}
}
},
@ -284,10 +278,7 @@ def test_execution_of_delete_element_from_set():
hash_key_type="TYPE",
range_key=None,
range_key_type=None,
attrs={
"id": {"S": "foo2"},
"s": {"SS": ["value1", "value2", "value3"]},
},
attrs={"id": {"S": "foo2"}, "s": {"SS": ["value1", "value2", "value3"]},},
)
validated_ast = UpdateExpressionValidator(
update_expression_ast,
@ -301,10 +292,7 @@ def test_execution_of_delete_element_from_set():
hash_key_type="TYPE",
range_key=None,
range_key_type=None,
attrs={
"id": {"S": "foo2"},
"s": {"SS": ["value1", "value3"]},
},
attrs={"id": {"S": "foo2"}, "s": {"SS": ["value1", "value3"]},},
)
assert expected_item == item
@ -317,10 +305,7 @@ def test_execution_of_add_number():
hash_key_type="TYPE",
range_key=None,
range_key_type=None,
attrs={
"id": {"S": "foo2"},
"s": {"N": "5"},
},
attrs={"id": {"S": "foo2"}, "s": {"N": "5"},},
)
validated_ast = UpdateExpressionValidator(
update_expression_ast,
@ -347,10 +332,7 @@ def test_execution_of_add_set_to_a_number():
hash_key_type="TYPE",
range_key=None,
range_key_type=None,
attrs={
"id": {"S": "foo2"},
"s": {"N": "5"},
},
attrs={"id": {"S": "foo2"}, "s": {"N": "5"},},
)
try:
validated_ast = UpdateExpressionValidator(
@ -381,10 +363,7 @@ def test_execution_of_add_to_a_set():
hash_key_type="TYPE",
range_key=None,
range_key_type=None,
attrs={
"id": {"S": "foo2"},
"s": {"SS": ["value1", "value2", "value3"]},
},
attrs={"id": {"S": "foo2"}, "s": {"SS": ["value1", "value2", "value3"]},},
)
validated_ast = UpdateExpressionValidator(
update_expression_ast,
@ -406,37 +385,17 @@ def test_execution_of_add_to_a_set():
assert expected_item == item
@pytest.mark.parametrize("expression_attribute_values,unexpected_data_type",
@pytest.mark.parametrize(
"expression_attribute_values,unexpected_data_type",
[
(
{":value": {"S": "10"}},
"STRING",
),
(
{":value": {"N": "10"}},
"NUMBER",
),
(
{":value": {"B": "10"}},
"BINARY",
),
(
{":value": {"BOOL": True}},
"BOOLEAN",
),
(
{":value": {"NULL": True}},
"NULL",
),
(
{":value": {"M": {"el0": {"S": "10"}}}},
"MAP",
),
(
{":value": {"L": []}},
"LIST",
),
]
({":value": {"S": "10"}}, "STRING",),
({":value": {"N": "10"}}, "NUMBER",),
({":value": {"B": "10"}}, "BINARY",),
({":value": {"BOOL": True}}, "BOOLEAN",),
({":value": {"NULL": True}}, "NULL",),
({":value": {"M": {"el0": {"S": "10"}}}}, "MAP",),
({":value": {"L": []}}, "LIST",),
],
)
def test_execution_of__delete_element_from_set_invalid_value(
expression_attribute_values, unexpected_data_type
@ -449,10 +408,7 @@ def test_execution_of__delete_element_from_set_invalid_value(
hash_key_type="TYPE",
range_key=None,
range_key_type=None,
attrs={
"id": {"S": "foo2"},
"s": {"SS": ["value1", "value2", "value3"]},
},
attrs={"id": {"S": "foo2"}, "s": {"SS": ["value1", "value2", "value3"]},},
)
try:
validated_ast = UpdateExpressionValidator(
@ -477,10 +433,7 @@ def test_execution_of_delete_element_from_a_string_attribute():
hash_key_type="TYPE",
range_key=None,
range_key_type=None,
attrs={
"id": {"S": "foo2"},
"s": {"S": "5"},
},
attrs={"id": {"S": "foo2"}, "s": {"S": "5"},},
)
try:
validated_ast = UpdateExpressionValidator(

View file

@ -41,11 +41,8 @@ def test_validation_of_update_expression_with_keyword():
assert e.keyword == "path"
@pytest.mark.parametrize("update_expression",
[
"SET a = #b + :val2",
"SET a = :val2 + #b",
]
@pytest.mark.parametrize(
"update_expression", ["SET a = #b + :val2", "SET a = :val2 + #b",]
)
def test_validation_of_a_set_statement_with_incorrect_passed_value(update_expression):
"""
@ -101,12 +98,7 @@ def test_validation_of_update_expression_with_attribute_that_does_not_exist_in_i
assert True
@pytest.mark.parametrize("update_expression",
[
"SET a = #c",
"SET a = #c + #d",
]
)
@pytest.mark.parametrize("update_expression", ["SET a = #c", "SET a = #c + #d",])
def test_validation_of_update_expression_with_attribute_name_that_is_not_defined(
update_expression,
):