DynamoDB - Improve handling of ReturnConsumedCapacity-param (#4241)
This commit is contained in:
parent
58da62cc71
commit
cc568c1656
@ -5,6 +5,7 @@ import json
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
import itertools
|
import itertools
|
||||||
|
from functools import wraps
|
||||||
|
|
||||||
from moto.core.responses import BaseResponse
|
from moto.core.responses import BaseResponse
|
||||||
from moto.core.utils import camelcase_to_underscores, amz_crc32, amzn_request_id
|
from moto.core.utils import camelcase_to_underscores, amz_crc32, amzn_request_id
|
||||||
@ -19,6 +20,55 @@ from moto.dynamodb2.models import dynamodb_backends, dynamo_json_dump
|
|||||||
TRANSACTION_MAX_ITEMS = 25
|
TRANSACTION_MAX_ITEMS = 25
|
||||||
|
|
||||||
|
|
||||||
|
def include_consumed_capacity(val=1.0):
|
||||||
|
def _inner(f):
|
||||||
|
@wraps(f)
|
||||||
|
def _wrapper(*args, **kwargs):
|
||||||
|
(handler,) = args
|
||||||
|
expected_capacity = handler.body.get("ReturnConsumedCapacity", "NONE")
|
||||||
|
if expected_capacity not in ["NONE", "TOTAL", "INDEXES"]:
|
||||||
|
type_ = "ValidationException"
|
||||||
|
message = "1 validation error detected: Value '{}' at 'returnConsumedCapacity' failed to satisfy constraint: Member must satisfy enum value set: [INDEXES, TOTAL, NONE]".format(
|
||||||
|
expected_capacity
|
||||||
|
)
|
||||||
|
return (
|
||||||
|
400,
|
||||||
|
handler.response_headers,
|
||||||
|
dynamo_json_dump({"__type": type_, "message": message}),
|
||||||
|
)
|
||||||
|
table_name = handler.body.get("TableName", "")
|
||||||
|
index_name = handler.body.get("IndexName", None)
|
||||||
|
|
||||||
|
response = f(*args, **kwargs)
|
||||||
|
|
||||||
|
if isinstance(response, str):
|
||||||
|
body = json.loads(response)
|
||||||
|
|
||||||
|
if expected_capacity == "TOTAL":
|
||||||
|
body["ConsumedCapacity"] = {
|
||||||
|
"TableName": table_name,
|
||||||
|
"CapacityUnits": val,
|
||||||
|
}
|
||||||
|
elif expected_capacity == "INDEXES":
|
||||||
|
body["ConsumedCapacity"] = {
|
||||||
|
"TableName": table_name,
|
||||||
|
"CapacityUnits": val,
|
||||||
|
"Table": {"CapacityUnits": val},
|
||||||
|
}
|
||||||
|
if index_name:
|
||||||
|
body["ConsumedCapacity"]["LocalSecondaryIndexes"] = {
|
||||||
|
index_name: {"CapacityUnits": val}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dynamo_json_dump(body)
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
return _wrapper
|
||||||
|
|
||||||
|
return _inner
|
||||||
|
|
||||||
|
|
||||||
def put_has_empty_keys(field_updates, table):
|
def put_has_empty_keys(field_updates, table):
|
||||||
if table:
|
if table:
|
||||||
key_names = table.key_attributes
|
key_names = table.key_attributes
|
||||||
@ -254,6 +304,7 @@ class DynamoHandler(BaseResponse):
|
|||||||
er = "com.amazonaws.dynamodb.v20111205#ResourceNotFoundException"
|
er = "com.amazonaws.dynamodb.v20111205#ResourceNotFoundException"
|
||||||
return self.error(er, "Requested resource not found")
|
return self.error(er, "Requested resource not found")
|
||||||
|
|
||||||
|
@include_consumed_capacity()
|
||||||
def put_item(self):
|
def put_item(self):
|
||||||
name = self.body["TableName"]
|
name = self.body["TableName"]
|
||||||
item = self.body["Item"]
|
item = self.body["Item"]
|
||||||
@ -310,7 +361,6 @@ class DynamoHandler(BaseResponse):
|
|||||||
|
|
||||||
if result:
|
if result:
|
||||||
item_dict = result.to_json()
|
item_dict = result.to_json()
|
||||||
item_dict["ConsumedCapacity"] = {"TableName": name, "CapacityUnits": 1}
|
|
||||||
if return_values == "ALL_OLD":
|
if return_values == "ALL_OLD":
|
||||||
item_dict["Attributes"] = existing_attributes
|
item_dict["Attributes"] = existing_attributes
|
||||||
else:
|
else:
|
||||||
@ -349,6 +399,7 @@ class DynamoHandler(BaseResponse):
|
|||||||
|
|
||||||
return dynamo_json_dump(response)
|
return dynamo_json_dump(response)
|
||||||
|
|
||||||
|
@include_consumed_capacity(0.5)
|
||||||
def get_item(self):
|
def get_item(self):
|
||||||
name = self.body["TableName"]
|
name = self.body["TableName"]
|
||||||
table = self.dynamodb_backend.get_table(name)
|
table = self.dynamodb_backend.get_table(name)
|
||||||
@ -372,11 +423,10 @@ class DynamoHandler(BaseResponse):
|
|||||||
return self.error(er, "Validation Exception")
|
return self.error(er, "Validation Exception")
|
||||||
if item:
|
if item:
|
||||||
item_dict = item.describe_attrs(attributes=None)
|
item_dict = item.describe_attrs(attributes=None)
|
||||||
item_dict["ConsumedCapacity"] = {"TableName": name, "CapacityUnits": 0.5}
|
|
||||||
return dynamo_json_dump(item_dict)
|
return dynamo_json_dump(item_dict)
|
||||||
else:
|
else:
|
||||||
# Item not found
|
# Item not found
|
||||||
return 200, self.response_headers, "{}"
|
return dynamo_json_dump({})
|
||||||
|
|
||||||
def batch_get_item(self):
|
def batch_get_item(self):
|
||||||
table_batches = self.body["RequestItems"]
|
table_batches = self.body["RequestItems"]
|
||||||
@ -441,6 +491,7 @@ class DynamoHandler(BaseResponse):
|
|||||||
unique_keys.append(k)
|
unique_keys.append(k)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@include_consumed_capacity()
|
||||||
def query(self):
|
def query(self):
|
||||||
name = self.body["TableName"]
|
name = self.body["TableName"]
|
||||||
key_condition_expression = self.body.get("KeyConditionExpression")
|
key_condition_expression = self.body.get("KeyConditionExpression")
|
||||||
@ -618,7 +669,6 @@ class DynamoHandler(BaseResponse):
|
|||||||
|
|
||||||
result = {
|
result = {
|
||||||
"Count": len(items),
|
"Count": len(items),
|
||||||
"ConsumedCapacity": {"TableName": name, "CapacityUnits": 1},
|
|
||||||
"ScannedCount": scanned_count,
|
"ScannedCount": scanned_count,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -649,6 +699,7 @@ class DynamoHandler(BaseResponse):
|
|||||||
|
|
||||||
return projection_expression
|
return projection_expression
|
||||||
|
|
||||||
|
@include_consumed_capacity()
|
||||||
def scan(self):
|
def scan(self):
|
||||||
name = self.body["TableName"]
|
name = self.body["TableName"]
|
||||||
|
|
||||||
@ -700,7 +751,6 @@ class DynamoHandler(BaseResponse):
|
|||||||
result = {
|
result = {
|
||||||
"Count": len(items),
|
"Count": len(items),
|
||||||
"Items": [item.attrs for item in items],
|
"Items": [item.attrs for item in items],
|
||||||
"ConsumedCapacity": {"TableName": name, "CapacityUnits": 1},
|
|
||||||
"ScannedCount": scanned_count,
|
"ScannedCount": scanned_count,
|
||||||
}
|
}
|
||||||
if last_evaluated_key is not None:
|
if last_evaluated_key is not None:
|
||||||
|
@ -589,42 +589,6 @@ def test_query_invalid_table():
|
|||||||
assert exception.response["Error"]["Code"] == "ResourceNotFoundException"
|
assert exception.response["Error"]["Code"] == "ResourceNotFoundException"
|
||||||
|
|
||||||
|
|
||||||
@requires_boto_gte("2.9")
|
|
||||||
@mock_dynamodb2
|
|
||||||
def test_scan_returns_consumed_capacity():
|
|
||||||
name = "TestTable"
|
|
||||||
conn = boto3.client(
|
|
||||||
"dynamodb",
|
|
||||||
region_name="us-west-2",
|
|
||||||
aws_access_key_id="ak",
|
|
||||||
aws_secret_access_key="sk",
|
|
||||||
)
|
|
||||||
|
|
||||||
conn.create_table(
|
|
||||||
TableName=name,
|
|
||||||
KeySchema=[{"AttributeName": "forum_name", "KeyType": "HASH"}],
|
|
||||||
AttributeDefinitions=[{"AttributeName": "forum_name", "AttributeType": "S"}],
|
|
||||||
ProvisionedThroughput={"ReadCapacityUnits": 5, "WriteCapacityUnits": 5},
|
|
||||||
)
|
|
||||||
|
|
||||||
conn.put_item(
|
|
||||||
TableName=name,
|
|
||||||
Item={
|
|
||||||
"forum_name": {"S": "LOLCat Forum"},
|
|
||||||
"subject": {"S": "Check this out!"},
|
|
||||||
"Body": {"S": "http://url_to_lolcat.gif"},
|
|
||||||
"SentBy": {"S": "test"},
|
|
||||||
"ReceivedTime": {"S": "12/9/2011 11:36:03 PM"},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
response = conn.scan(TableName=name)
|
|
||||||
|
|
||||||
assert "ConsumedCapacity" in response
|
|
||||||
assert "CapacityUnits" in response["ConsumedCapacity"]
|
|
||||||
assert response["ConsumedCapacity"]["TableName"] == name
|
|
||||||
|
|
||||||
|
|
||||||
@requires_boto_gte("2.9")
|
@requires_boto_gte("2.9")
|
||||||
@mock_dynamodb2
|
@mock_dynamodb2
|
||||||
def test_put_item_with_special_chars():
|
def test_put_item_with_special_chars():
|
||||||
@ -710,37 +674,6 @@ def test_put_item_with_streams():
|
|||||||
stream_record["dynamodb"]["SizeBytes"].should.be.equal(447)
|
stream_record["dynamodb"]["SizeBytes"].should.be.equal(447)
|
||||||
|
|
||||||
|
|
||||||
@requires_boto_gte("2.9")
|
|
||||||
@mock_dynamodb2
|
|
||||||
def test_query_returns_consumed_capacity():
|
|
||||||
dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
|
|
||||||
|
|
||||||
# Create the DynamoDB table.
|
|
||||||
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"}
|
|
||||||
)
|
|
||||||
|
|
||||||
results = table.query(KeyConditionExpression=Key("forum_name").eq("the-key"))
|
|
||||||
|
|
||||||
assert "ConsumedCapacity" in results
|
|
||||||
assert "CapacityUnits" in results["ConsumedCapacity"]
|
|
||||||
assert results["ConsumedCapacity"]["CapacityUnits"] == 1
|
|
||||||
|
|
||||||
|
|
||||||
@mock_dynamodb2
|
@mock_dynamodb2
|
||||||
def test_basic_projection_expression_using_get_item():
|
def test_basic_projection_expression_using_get_item():
|
||||||
dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
|
dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
|
||||||
@ -1435,96 +1368,6 @@ def test_nested_projection_expression_using_scan_with_attr_expression_names():
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@mock_dynamodb2
|
|
||||||
def test_put_item_returns_consumed_capacity():
|
|
||||||
dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
|
|
||||||
|
|
||||||
# Create the DynamoDB table.
|
|
||||||
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")
|
|
||||||
|
|
||||||
response = table.put_item(
|
|
||||||
Item={"forum_name": "the-key", "subject": "123", "body": "some test message"}
|
|
||||||
)
|
|
||||||
|
|
||||||
assert "ConsumedCapacity" in response
|
|
||||||
|
|
||||||
|
|
||||||
@mock_dynamodb2
|
|
||||||
def test_update_item_returns_consumed_capacity():
|
|
||||||
dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
|
|
||||||
|
|
||||||
# Create the DynamoDB table.
|
|
||||||
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"}
|
|
||||||
)
|
|
||||||
|
|
||||||
response = table.update_item(
|
|
||||||
Key={"forum_name": "the-key", "subject": "123"},
|
|
||||||
UpdateExpression="set body=:tb",
|
|
||||||
ExpressionAttributeValues={":tb": "a new message"},
|
|
||||||
)
|
|
||||||
|
|
||||||
assert "ConsumedCapacity" in response
|
|
||||||
assert "CapacityUnits" in response["ConsumedCapacity"]
|
|
||||||
assert "TableName" in response["ConsumedCapacity"]
|
|
||||||
|
|
||||||
|
|
||||||
@mock_dynamodb2
|
|
||||||
def test_get_item_returns_consumed_capacity():
|
|
||||||
dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
|
|
||||||
|
|
||||||
# Create the DynamoDB table.
|
|
||||||
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"}
|
|
||||||
)
|
|
||||||
|
|
||||||
response = table.get_item(Key={"forum_name": "the-key", "subject": "123"})
|
|
||||||
|
|
||||||
assert "ConsumedCapacity" in response
|
|
||||||
assert "CapacityUnits" in response["ConsumedCapacity"]
|
|
||||||
assert "TableName" in response["ConsumedCapacity"]
|
|
||||||
|
|
||||||
|
|
||||||
@mock_dynamodb2
|
@mock_dynamodb2
|
||||||
def test_put_empty_item():
|
def test_put_empty_item():
|
||||||
dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
|
dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
|
||||||
|
147
tests/test_dynamodb2/test_dynamodb_consumedcapacity.py
Normal file
147
tests/test_dynamodb2/test_dynamodb_consumedcapacity.py
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
import boto3
|
||||||
|
import pytest
|
||||||
|
import sure # noqa
|
||||||
|
|
||||||
|
from botocore.exceptions import ClientError
|
||||||
|
from moto import mock_dynamodb2
|
||||||
|
|
||||||
|
|
||||||
|
@mock_dynamodb2
|
||||||
|
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"]
|
||||||
|
err["Code"].should.equal("ValidationException")
|
||||||
|
err["Message"].should.equal(
|
||||||
|
"1 validation error detected: Value 'Garbage' at 'returnConsumedCapacity' failed to satisfy constraint: Member must satisfy enum value set: [INDEXES, TOTAL, NONE]"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_dynamodb2
|
||||||
|
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"}],
|
||||||
|
)
|
||||||
|
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
|
||||||
|
response.should.have.key("ConsumedCapacity")
|
||||||
|
response["ConsumedCapacity"].should.equal(
|
||||||
|
{"TableName": "test_table", "CapacityUnits": 0.5}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_dynamodb2
|
||||||
|
@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"
|
||||||
|
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:
|
||||||
|
response.should.have.key("ConsumedCapacity")
|
||||||
|
response["ConsumedCapacity"]["TableName"].should.equal("jobs")
|
||||||
|
response["ConsumedCapacity"]["CapacityUnits"].should.equal(value)
|
||||||
|
if should_have_table:
|
||||||
|
response["ConsumedCapacity"]["Table"].should.equal({"CapacityUnits": value})
|
||||||
|
if is_index:
|
||||||
|
response["ConsumedCapacity"].should.have.key("LocalSecondaryIndexes")
|
||||||
|
response["ConsumedCapacity"]["LocalSecondaryIndexes"].should.equal(
|
||||||
|
{"job_name-index": {"CapacityUnits": value}}
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
response.shouldnt.have.key("ConsumedCapacity")
|
Loading…
Reference in New Issue
Block a user