-
Notifications
You must be signed in to change notification settings - Fork 16
chore(dafny): Add Update and delete test #1942
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
482e76b
Update and delete test:
rishav-karanjit 7210baf
auto commit
rishav-karanjit 9353e17
auto commit
rishav-karanjit 8757192
auto commit
rishav-karanjit 83a739f
Merge branch 'main' into rishav/addUpdateDeleteTest
rishav-karanjit f185c1e
auto commit
rishav-karanjit cd82fb9
Merge branch 'rishav/addUpdateDeleteTest' of https://github.com/aws/a…
rishav-karanjit 9582321
auto commit
rishav-karanjit b8c918e
auto commit
rishav-karanjit c578e37
Merge branch 'main' into rishav/addUpdateDeleteTest
rishav-karanjit eeee4b3
Add ReturnValues
rishav-karanjit 4a29b02
Add ReturnValues
rishav-karanjit fa7b783
Merge branch 'rishav/addUpdateDeleteTest' of https://github.com/aws/a…
rishav-karanjit 2a9c145
auto commit
rishav-karanjit e7c6dd3
remove commented code
rishav-karanjit cda4f5e
formatting
rishav-karanjit 956f4a8
Update TestVectors/dafny/DDBEncryption/src/TestVectors.dfy
rishav-karanjit 93af3cc
WithoutConditionExpressionCase
rishav-karanjit db23d9e
Merge branch 'rishav/addUpdateDeleteTest' of https://github.com/aws/a…
rishav-karanjit b79963f
BasicIoTestDeleteItemWithoutConditionExpression
rishav-karanjit ad60db0
auto commit
rishav-karanjit 13a5649
auto commit
rishav-karanjit ca0b0fb
verify
rishav-karanjit f222c89
Update TestVectors/dafny/DDBEncryption/src/TestVectors.dfy
rishav-karanjit File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -397,6 +397,12 @@ module {:options "-functionSyntax:4"} DdbEncryptionTestVectors { | |
BasicIoTestBatchWriteItem(c1, c2, globalRecords); | ||
BasicIoTestPutItem(c1, c2, globalRecords); | ||
BasicIoTestTransactWriteItems(c1, c2, globalRecords); | ||
BasicIoTestUpdateItem(c1, c2, globalRecords, "One"); | ||
BasicIoTestUpdateItem(c1, c2, globalRecords, "Two"); | ||
BasicIoTestDeleteItem(c1, c2, globalRecords, "One", "Uno"); | ||
BasicIoTestDeleteItem(c1, c2, globalRecords, "Two", "Dos"); | ||
BasicIoTestDeleteItemWithoutConditionExpression(c1, c2, globalRecords, "One", "Uno"); | ||
BasicIoTestDeleteItemWithoutConditionExpression(c1, c2, globalRecords, "Two", "Dos"); | ||
BasicIoTestExecuteStatement(c1, c2); | ||
BasicIoTestExecuteTransaction(c1, c2); | ||
BasicIoTestBatchExecuteStatement(c1, c2); | ||
|
@@ -844,6 +850,108 @@ module {:options "-functionSyntax:4"} DdbEncryptionTestVectors { | |
BasicIoTestTransactGetItems(rClient, records); | ||
} | ||
|
||
method BasicIoTestUpdateItem(writeConfig : TableConfig, readConfig : TableConfig, records : seq<Record>, attributeToUpdate: DDB.AttributeName) | ||
{ | ||
var wClient, rClient := SetupTestTable(writeConfig, readConfig); | ||
WriteAllRecords(wClient, records); | ||
// Update each record by appending "updated" to the partition key | ||
for i := 0 to |records| { | ||
var newValue := "updated"; | ||
// Create an update expression to update the partition key | ||
var updateExpr := "SET #att = :val"; | ||
expect attributeToUpdate in writeConfig.config.attributeActionsOnEncrypt, "`attributeToUpdate` not in attributeActionsOnEncrypt"; | ||
var exprAttrNames := map["#att" := attributeToUpdate]; | ||
var exprAttrValues := map[":val" := DDB.AttributeValue.S(newValue)]; | ||
expect HashName in records[i].item, "`HashName` is not in records."; | ||
var updateInput := DDB.UpdateItemInput( | ||
TableName := TableName, | ||
Key := map[HashName := records[i].item[HashName]], | ||
UpdateExpression := Some(updateExpr), | ||
ExpressionAttributeNames := Some(exprAttrNames), | ||
ExpressionAttributeValues := Some(exprAttrValues), | ||
ReturnValues := None, | ||
ReturnConsumedCapacity := None, | ||
ReturnItemCollectionMetrics := None, | ||
ConditionExpression := None | ||
); | ||
var updateResult := wClient.UpdateItem(updateInput); | ||
if writeConfig.config.attributeActionsOnEncrypt[attributeToUpdate] == SE.ENCRYPT_AND_SIGN || writeConfig.config.attributeActionsOnEncrypt[attributeToUpdate] == SE.SIGN_ONLY { | ||
expect updateResult.Failure?, "UpdateItem should have failed for signed item."; | ||
// This error is of type DynamoDbEncryptionTransformsException | ||
// but AWS SDK wraps it into its own type for which customers should be unwrapping. | ||
// In test vectors, we still have to change the error from AWS SDK to dafny so it turns out to be OpaqueWithText. | ||
expect updateResult.error.OpaqueWithText?, "Error should have been of type OpaqueWithText"; | ||
var hasDynamoDbEncryptionTransformsException? := String.HasSubString(updateResult.error.objMessage, "Update Expressions forbidden on signed attributes"); | ||
expect hasDynamoDbEncryptionTransformsException?.Some?, "Error might is not be of type DynamoDbEncryptionTransformsException"; | ||
} else { | ||
expect updateResult.Success?; | ||
} | ||
} | ||
} | ||
|
||
method BasicIoTestDeleteItem(writeConfig : TableConfig, readConfig : TableConfig, records : seq<Record>, attributeToDelete: DDB.AttributeName, expectedAttributeValue: string) | ||
{ | ||
var wClient, rClient := SetupTestTable(writeConfig, readConfig); | ||
WriteAllRecords(wClient, records); | ||
// Try to delete records with a condition expression with condition to | ||
// delete records if the record has an attribute attributeToDelete with value expectedAttributeValue | ||
for i := 0 to |records| { | ||
lucasmcdonald3 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// Set up condition expression to only delete if Two = expectedAttributeValue | ||
var conditionExpr := "#attr = :val"; | ||
var exprAttrNames := map["#attr" := attributeToDelete]; | ||
var exprAttrValues := map[":val" := DDB.AttributeValue.S(expectedAttributeValue)]; | ||
expect HashName in records[i].item, "`HashName` is not in records."; | ||
var deleteInput := DDB.DeleteItemInput( | ||
TableName := TableName, | ||
Key := map[HashName := records[i].item[HashName]], | ||
ConditionExpression := Some(conditionExpr), | ||
Comment on lines
+904
to
+907
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If these are meant to be basic smoke tests, I think it's worth adding a case where we don't specify a condition expression at all -- is that feasible/worth testing? (I think the expected result would be that the delete passes) |
||
ExpressionAttributeNames := Some(exprAttrNames), | ||
ExpressionAttributeValues := Some(exprAttrValues), | ||
ReturnValues := Some(DDB.ReturnValue.ALL_OLD) | ||
); | ||
var deleteResult := wClient.DeleteItem(deleteInput); | ||
expect attributeToDelete in writeConfig.config.attributeActionsOnEncrypt, "`attributeToDelete` not found in attributeActionsOnEncrypt of config."; | ||
if writeConfig.config.attributeActionsOnEncrypt[attributeToDelete] == SE.ENCRYPT_AND_SIGN { | ||
expect deleteResult.Failure?, "DeleteItem should have failed."; | ||
// This error is of type DynamoDbEncryptionTransformsException | ||
// but AWS SDK wraps it into its own type for which customers should be unwrapping. | ||
// In test vectors, we still have to change the error from AWS SDK to dafny so it turns out to be OpaqueWithText. | ||
expect deleteResult.error.OpaqueWithText?, "Error should have been of type OpaqueWithText"; | ||
var hasDynamoDbEncryptionTransformsException? := String.HasSubString(deleteResult.error.objMessage, "Condition Expressions forbidden on encrypted attributes"); | ||
expect hasDynamoDbEncryptionTransformsException?.Some?, "Error might is not be of type DynamoDbEncryptionTransformsException"; | ||
} else if attributeToDelete in records[i].item && records[i].item[attributeToDelete].S? && records[i].item[attributeToDelete].S == expectedAttributeValue { | ||
expect deleteResult.Success?, "DeleteItem should have succeeded."; | ||
expect deleteResult.value.Attributes.Some?, "DeleteItemOutput should have had some attribute because ReturnValues was set as `ALL_OLD` in DeleteItemInput"; | ||
expect HashName in deleteResult.value.Attributes.value, "Deleted item does not have right partition key:" + HashName; | ||
expect deleteResult.value.Attributes.value[HashName] == records[i].item[HashName], "Wrong item was deleted."; | ||
} else { | ||
expect deleteResult.Failure?, "DeleteItem should have failed."; | ||
expect deleteResult.error.ConditionalCheckFailedException?, "DeleteItem should have failed with ConditionalCheckFailedException"; | ||
} | ||
} | ||
} | ||
|
||
method BasicIoTestDeleteItemWithoutConditionExpression(writeConfig : TableConfig, readConfig : TableConfig, records : seq<Record>, attributeToDelete: DDB.AttributeName, expectedAttributeValue: string) | ||
{ | ||
var wClient, rClient := SetupTestTable(writeConfig, readConfig); | ||
WriteAllRecords(wClient, records); | ||
for i := 0 to |records| { | ||
expect HashName in records[i].item, "`HashName` is not in records."; | ||
var deleteInputWithoutConditionExpression := DDB.DeleteItemInput( | ||
TableName := TableName, | ||
Key := map[HashName := records[i].item[HashName]], | ||
ReturnValues := Some(DDB.ReturnValue.ALL_OLD) | ||
); | ||
var deleteResultForWithoutConditionExpressionCase := wClient.DeleteItem(deleteInputWithoutConditionExpression); | ||
expect deleteResultForWithoutConditionExpressionCase.Success?, "DeleteItem should have succeeded."; | ||
expect deleteResultForWithoutConditionExpressionCase.value.Attributes.Some?, "DeleteItemOutput should have had some attribute because ReturnValues was set as `ALL_OLD` in DeleteItemInput"; | ||
if attributeToDelete in records[i].item { | ||
expect HashName in deleteResultForWithoutConditionExpressionCase.value.Attributes.value, "Deleted item does not have right partition key:" + HashName; | ||
expect deleteResultForWithoutConditionExpressionCase.value.Attributes.value[HashName] == records[i].item[HashName], "Wrong item was deleted."; | ||
} | ||
} | ||
} | ||
|
||
method BasicIoTestExecuteStatement(writeConfig : TableConfig, readConfig : TableConfig) | ||
{ | ||
var wClient, rClient := SetupTestTable(writeConfig, readConfig); | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we also check for
SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT
here? I think yes, even if the item under test doesn't have that attributeThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT
is not here because delete operation is not forbidden on signed attributes. Its only forbidden when the condition attribute contains encrypted attribute. https://github.com/aws/aws-database-encryption-sdk-dynamodb/blob/main/specification/dynamodb-encryption-client/ddb-support.md#testconditionexpression