2021-08-29 18:04:42 +00:00
import boto3
import pytest
from botocore . exceptions import ClientError
2023-11-30 15:55:51 +00:00
2024-01-07 12:03:33 +00:00
from moto import mock_aws
2021-08-29 18:04:42 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2021-08-29 18:04:42 +00:00
def test_error_on_wrong_value_for_consumed_capacity ( ) :
resource = boto3 . resource ( " dynamodb " , region_name = " ap-northeast-3 " )
client = boto3 . client ( " dynamodb " , region_name = " ap-northeast-3 " )
client . create_table (
TableName = " jobs " ,
KeySchema = [ { " AttributeName " : " job_id " , " KeyType " : " HASH " } ] ,
AttributeDefinitions = [ { " AttributeName " : " job_id " , " AttributeType " : " S " } ] ,
ProvisionedThroughput = { " ReadCapacityUnits " : 5 , " WriteCapacityUnits " : 5 } ,
)
table = resource . Table ( " jobs " )
item = { " job_id " : " asdasdasd " , " expires_at " : " 1 " }
# PUT_ITEM
with pytest . raises ( ClientError ) as ex :
table . put_item ( Item = item , ReturnConsumedCapacity = " Garbage " )
err = ex . value . response [ " Error " ]
2023-07-13 10:21:47 +00:00
assert err [ " Code " ] == " ValidationException "
assert (
err [ " Message " ]
== " 1 validation error detected: Value ' Garbage ' at ' returnConsumedCapacity ' failed to satisfy constraint: Member must satisfy enum value set: [INDEXES, TOTAL, NONE] "
2021-08-29 18:04:42 +00:00
)
2024-01-07 12:03:33 +00:00
@mock_aws
2021-08-29 18:04:42 +00:00
def test_consumed_capacity_get_unknown_item ( ) :
conn = boto3 . client ( " dynamodb " , region_name = " us-east-1 " )
conn . create_table (
TableName = " test_table " ,
KeySchema = [ { " AttributeName " : " u " , " KeyType " : " HASH " } ] ,
AttributeDefinitions = [ { " AttributeName " : " u " , " AttributeType " : " S " } ] ,
2022-02-10 20:09:45 +00:00
BillingMode = " PAY_PER_REQUEST " ,
2021-08-29 18:04:42 +00:00
)
response = conn . get_item (
TableName = " test_table " ,
Key = { " u " : { " S " : " does_not_exist " } } ,
ReturnConsumedCapacity = " TOTAL " ,
)
# Should still return ConsumedCapacity, even if it does not return an item
2023-07-13 10:21:47 +00:00
assert response [ " ConsumedCapacity " ] == {
" TableName " : " test_table " ,
" CapacityUnits " : 0.5 ,
}
2021-08-29 18:04:42 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2021-08-29 18:04:42 +00:00
@pytest.mark.parametrize (
" capacity,should_have_capacity,should_have_table " ,
[
[ None , False , False ] ,
[ " NONE " , False , False ] ,
[ " TOTAL " , True , False ] ,
[ " INDEXES " , True , True ] ,
] ,
)
def test_only_return_consumed_capacity_when_required (
capacity , should_have_capacity , should_have_table
) :
resource = boto3 . resource ( " dynamodb " , region_name = " ap-northeast-3 " )
client = boto3 . client ( " dynamodb " , region_name = " ap-northeast-3 " )
client . create_table (
TableName = " jobs " ,
KeySchema = [ { " AttributeName " : " job_id " , " KeyType " : " HASH " } ] ,
LocalSecondaryIndexes = [
{
" IndexName " : " job_name-index " ,
" KeySchema " : [ { " AttributeName " : " job_name " , " KeyType " : " HASH " } ] ,
" Projection " : { " ProjectionType " : " ALL " } ,
}
] ,
AttributeDefinitions = [
{ " AttributeName " : " job_id " , " AttributeType " : " S " } ,
{ " AttributeName " : " job_name " , " AttributeType " : " S " } ,
] ,
ProvisionedThroughput = { " ReadCapacityUnits " : 5 , " WriteCapacityUnits " : 5 } ,
)
table = resource . Table ( " jobs " )
item = { " job_id " : " asdasdasd " , " expires_at " : " 1 " }
# PUT_ITEM
args = { " Item " : item }
if capacity :
args [ " ReturnConsumedCapacity " ] = capacity
response = table . put_item ( * * args )
validate_response ( response , should_have_capacity , should_have_table )
# GET_ITEM
args = { " Key " : item }
if capacity :
args [ " ReturnConsumedCapacity " ] = capacity
response = table . get_item ( * * args )
validate_response ( response , should_have_capacity , should_have_table , value = 0.5 )
# SCAN
args = { " TableName " : " jobs " }
if capacity :
args [ " ReturnConsumedCapacity " ] = capacity
response = client . scan ( * * args )
validate_response ( response , should_have_capacity , should_have_table )
# SCAN_INDEX
args [ " IndexName " ] = " job_name-index "
response = client . scan ( * * args )
validate_response ( response , should_have_capacity , should_have_table , is_index = True )
# QUERY
args = {
" TableName " : " jobs " ,
" KeyConditionExpression " : " job_id = :id " ,
" ExpressionAttributeValues " : { " :id " : { " S " : " asdasdasd " } } ,
}
if capacity :
args [ " ReturnConsumedCapacity " ] = capacity
response = client . query ( * * args )
validate_response ( response , should_have_capacity , should_have_table )
# QUERY_INDEX
args [ " IndexName " ] = " job_name-index "
2022-09-07 11:45:34 +00:00
args [ " KeyConditionExpression " ] = " job_name = :id "
2021-08-29 18:04:42 +00:00
response = client . query ( * * args )
validate_response ( response , should_have_capacity , should_have_table , is_index = True )
def validate_response (
response , should_have_capacity , should_have_table , is_index = False , value = 1.0
) :
if should_have_capacity :
2023-07-13 10:21:47 +00:00
capacity = response [ " ConsumedCapacity " ]
assert capacity [ " TableName " ] == " jobs "
assert capacity [ " CapacityUnits " ] == value
2021-08-29 18:04:42 +00:00
if should_have_table :
2023-07-13 10:21:47 +00:00
assert capacity [ " Table " ] == { " CapacityUnits " : value }
2021-08-29 18:04:42 +00:00
if is_index :
2023-07-13 10:21:47 +00:00
assert capacity [ " LocalSecondaryIndexes " ] == {
" job_name-index " : { " CapacityUnits " : value }
}
2021-08-29 18:04:42 +00:00
else :
2023-07-13 10:21:47 +00:00
assert " ConsumedCapacity " not in response