@@ -385,6 +385,7 @@ module {:options "-functionSyntax:4"} DdbEncryptionTestVectors {
385385 BasicIoTestPutItem (c1, c2, globalRecords);
386386 BasicIoTestTransactWriteItems (c1, c2, globalRecords);
387387 BasicIoTestExecuteStatement (c1, c2);
388+ BasicIoTestExecuteTransaction (c1, c2);
388389 }
389390 }
390391
@@ -879,6 +880,47 @@ module {:options "-functionSyntax:4"} DdbEncryptionTestVectors {
879880 expect resultForSelectStatement. error. OpaqueWithText?, "Error should have been of type OpaqueWithText";
880881 }
881882
883+ method BasicIoTestExecuteTransaction (writeConfig : TableConfig , readConfig : TableConfig )
884+ {
885+ var wClient :- expect newGazelle (writeConfig);
886+ var rClient :- expect newGazelle (readConfig);
887+ DeleteTable (wClient);
888+ var _ :- expect wClient. CreateTable (schemaOnEncrypt);
889+
890+ // Create a PartiQL transaction with INSERT and SELECT statements
891+ // The dynamodb attributes are random and non-existent because ExecuteTransaction is supposed to fail before going to dynamodb
892+ var statements := [
893+ DDB. ParameterizedStatement (
894+ Statement := "INSERT INTO \"" + TableName + "\" VALUE {'partition_key': 'a', 'sort_key': 'b', 'attribute1': 'value1'}",
895+ Parameters := None
896+ ),
897+ DDB. ParameterizedStatement (
898+ Statement := "SELECT * FROM " + TableName + " WHERE partition_key = 'a' AND sort_key = 'b'",
899+ Parameters := None
900+ )
901+ ];
902+
903+ var inputForTransaction := DDB. ExecuteTransactionInput (
904+ TransactStatements := statements,
905+ ClientRequestToken := None
906+ );
907+
908+ // Test with write client
909+ var resultForWriteTransaction := wClient. ExecuteTransaction (inputForTransaction);
910+ expect resultForWriteTransaction. Failure?, "ExecuteTransaction should have failed";
911+ // This error is of type DynamoDbEncryptionTransformsException
912+ // but AWS SDK wraps it into its own type for which customers should be unwrapping.
913+ // In test vectors, we still have to change the error from AWS SDK to dafny so it turns out to be OpaqueWithText.
914+ print (resultForWriteTransaction);
915+ expect resultForWriteTransaction. error. OpaqueWithText?, "Error should have been of type OpaqueWithText";
916+
917+ // Test with read client
918+ var resultForReadTransaction := rClient. ExecuteTransaction (inputForTransaction);
919+ expect resultForReadTransaction. Failure?, "ExecuteTransaction should have failed";
920+ print (resultForReadTransaction);
921+ expect resultForReadTransaction. error. OpaqueWithText?, "Error should have been of type OpaqueWithText";
922+ }
923+
882924 method FindMatchingRecord (expected : DDB .AttributeMap, actual : DDB .ItemList) returns (output : bool )
883925 {
884926 var exp := NormalizeItem (expected);
0 commit comments