test/alternator: several more simple tests for UpdateItem

This patch adds several more tests for Alternator's UpdateItem operation.
These tests verify a few simple cases that, surprisingly, never had test
coverage. The new tests pass (on both DynamoDB and Alternator) so did not
expose any bug.

Signed-off-by: Nadav Har'El <nyh@scylladb.com>

Closes #11025
This commit is contained in:
Nadav Har'El
2022-07-12 16:38:48 +03:00
committed by Piotr Sarna
parent e1e4a73793
commit eaf3579c15
2 changed files with 50 additions and 0 deletions

View File

@@ -403,6 +403,21 @@ def test_put_item_replace(test_table_s, test_table):
test_table.put_item(Item={'p': p, 'c': c, 'b': 'hello'})
assert test_table.get_item(Key={'p': p, 'c': c}, ConsistentRead=True)['Item'] == {'p': p, 'c': c, 'b': 'hello'}
# Test that UpdateItem merges the change with a previously existing item -
# it doesn't outright replace it like PutItem does in test_put_item_replace()
def test_update_item_merge(test_table_s):
p = random_string()
test_table_s.put_item(Item={'p': p, 'a': 'hi'})
assert test_table_s.get_item(Key={'p': p}, ConsistentRead=True)['Item'] == {'p': p, 'a': 'hi'}
test_table_s.update_item(Key={'p': p}, AttributeUpdates={'b': {'Value': 'hello', 'Action': 'PUT'}})
assert test_table_s.get_item(Key={'p': p}, ConsistentRead=True)['Item'] == {'p': p, 'a': 'hi', 'b': 'hello'}
test_table_s.update_item(Key={'p': p}, AttributeUpdates={'a': {'Value': 'hey', 'Action': 'PUT'}})
assert test_table_s.get_item(Key={'p': p}, ConsistentRead=True)['Item'] == {'p': p, 'a': 'hey', 'b': 'hello'}
test_table_s.update_item(Key={'p': p}, AttributeUpdates={'a': {'Action': 'DELETE'}})
assert test_table_s.get_item(Key={'p': p}, ConsistentRead=True)['Item'] == {'p': p, 'b': 'hello'}
test_table_s.update_item(Key={'p': p}, AttributeUpdates={'b': {'Action': 'DELETE'}})
assert test_table_s.get_item(Key={'p': p}, ConsistentRead=True)['Item'] == {'p': p}
# Test what UpdateItem does on a non-existent item. An operation that puts an
# attribute, creates this item. Even an empty operation creates an item
# (this is test_empty_update() above). But an operation that only deletes
@@ -751,3 +766,26 @@ def test_key_empty_bytes_value(test_table_b, test_table_sb):
test_table_b.put_item(Item={'p': b''})
with pytest.raises(ClientError, match='ValidationException.*empty'):
test_table_sb.put_item(Item={'p': p, 'c': b''})
# And UpdateItem's AttributeUpdates may specify an operation on more than
# one attribute. Note that because AttributeUpdates is a map, by definition
# these are operations on *different* attributes.
def test_update_item_multiple(test_table_s):
p = random_string()
test_table_s.update_item(Key={'p': p},
AttributeUpdates={'a': {'Value': 'hello', 'Action': 'PUT'},
'b': {'Value': 'hi', 'Action': 'PUT'}})
assert test_table_s.get_item(Key={'p': p}, ConsistentRead=True)['Item'] == {'p': p, 'a': 'hello', 'b': 'hi'}
test_table_s.update_item(Key={'p': p},
AttributeUpdates={'a': {'Action': 'DELETE'},
'b': {'Action': 'DELETE'}})
assert test_table_s.get_item(Key={'p': p}, ConsistentRead=True)['Item'] == {'p': p}
# Using UpdateItem DELETE on a non-existent attribute of an existing item
# succeeds but does nothing. Note that we have a separate test for the case
# the whole item doesn't exist (test_update_item_non_existent)
def test_update_item_delete_nonexistent_attribute(test_table_s):
p = random_string()
test_table_s.put_item(Item={'p': p, 'a': 'hello'})
test_table_s.update_item(Key={'p': p}, AttributeUpdates={'b': {'Action': 'DELETE'}})
assert test_table_s.get_item(Key={'p': p}, ConsistentRead=True)['Item'] == {'p': p, 'a': 'hello'}

View File

@@ -37,6 +37,18 @@ def test_update_expression_set_multi(test_table_s):
ExpressionAttributeValues={':val1': 4})
assert test_table_s.get_item(Key={'p': p}, ConsistentRead=True)['Item'] == {'p': p, 'x': 4, 'y': 4}
# Test that UpdateItem merges the change with a previously existing item -
# it doesn't outright replace it like PutItem does. This merge is done
# even if the expression doesn't need to read the old value of the item.
def test_update_expression_set_merge(test_table_s):
p = random_string()
test_table_s.put_item(Item={'p': p, 'a': 'hi'})
assert test_table_s.get_item(Key={'p': p}, ConsistentRead=True)['Item'] == {'p': p, 'a': 'hi'}
test_table_s.update_item(Key={'p': p}, UpdateExpression='SET b = :val', ExpressionAttributeValues={':val': 'hello'})
assert test_table_s.get_item(Key={'p': p}, ConsistentRead=True)['Item'] == {'p': p, 'a': 'hi', 'b': 'hello'}
test_table_s.update_item(Key={'p': p}, UpdateExpression='SET a = :val', ExpressionAttributeValues={':val': 'hey'})
assert test_table_s.get_item(Key={'p': p}, ConsistentRead=True)['Item'] == {'p': p, 'a': 'hey', 'b': 'hello'}
# SET can be used to copy an existing attribute to a new one
def test_update_expression_set_copy(test_table_s):
p = random_string()