From 45ba138611c3a1d5ce71063f75798fe1378ed94d Mon Sep 17 00:00:00 2001 From: jonathan343 Date: Wed, 10 Jul 2024 10:29:06 -0700 Subject: [PATCH 01/11] Fix minor typos in test_protocols.py --- tests/unit/test_protocols.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/unit/test_protocols.py b/tests/unit/test_protocols.py index 253ec5f7a5..3bf84c9935 100644 --- a/tests/unit/test_protocols.py +++ b/tests/unit/test_protocols.py @@ -37,11 +37,11 @@ To run tests from only a single file, you can set the BOTOCORE_TEST env var:: - BOTOCORE_TEST=tests/unit/compliance/input/json.json pytest tests/unit/test_protocols.py + BOTOCORE_TEST=tests/unit/protocols/input/json.json pytest tests/unit/test_protocols.py To run a single test suite you can set the BOTOCORE_TEST_ID env var: - BOTOCORE_TEST=tests/unit/compliance/input/json.json BOTOCORE_TEST_ID=5 \ + BOTOCORE_TEST=tests/unit/protocols/input/json.json BOTOCORE_TEST_ID=5 \ pytest tests/unit/test_protocols.py To run a single test case in a suite (useful when debugging a single test), you @@ -462,7 +462,7 @@ def _get_suite_test_id(): if len(split) == 2: suite_id, test_id = int(split[0]), int(split[1]) else: - suite_id = int(split([0])) + suite_id = int(split[0]) except TypeError: # Same exception, just give a better error message. raise TypeError( From 4714a35cc7215b20d977abd875644a5115e10bab Mon Sep 17 00:00:00 2001 From: jonathan343 Date: Wed, 10 Jul 2024 10:31:00 -0700 Subject: [PATCH 02/11] Add smithy generated response parsing protocol tests --- tests/unit/protocols/output/ec2.json | 2421 +++++++-- tests/unit/protocols/output/json.json | 2966 +++++++--- tests/unit/protocols/output/json_1_0.json | 1157 ++++ tests/unit/protocols/output/query.json | 3252 ++++++++--- tests/unit/protocols/output/rest-json.json | 5557 ++++++++++++++----- tests/unit/protocols/output/rest-xml.json | 5741 +++++++++++++++----- 6 files changed, 16298 insertions(+), 4796 deletions(-) create mode 100644 tests/unit/protocols/output/json_1_0.json diff --git a/tests/unit/protocols/output/ec2.json b/tests/unit/protocols/output/ec2.json index fa21de0ace..a13e0bad85 100644 --- a/tests/unit/protocols/output/ec2.json +++ b/tests/unit/protocols/output/ec2.json @@ -1,612 +1,1847 @@ [ - { - "description": "Scalar members", - "metadata": { - "protocol": "ec2" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Str": { - "shape": "StringType" - }, - "Num": { - "shape": "IntegerType", - "locationName": "FooNum" - }, - "FalseBool": { - "shape": "BooleanType" - }, - "TrueBool": { - "shape": "BooleanType" - }, - "Float": { - "shape": "FloatType" - }, - "Double": { - "shape": "DoubleType" - }, - "Long": { - "shape": "LongType" - }, - "Char": { - "shape": "CharType" - } - } - }, - "StringType": { - "type": "string" - }, - "IntegerType": { - "type": "integer" - }, - "BooleanType": { - "type": "boolean" - }, - "FloatType": { - "type": "float" - }, - "DoubleType": { - "type": "double" - }, - "LongType": { - "type": "long" - }, - "CharType": { - "type": "character" - } - }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Str": "myname", - "Num": 123, - "FalseBool": false, - "TrueBool": true, - "Float": 1.2, - "Double": 1.3, - "Long": 200, - "Char": "a" - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "myname123falsetrue1.21.3200arequest-id" - } - } - ] - }, - { - "description": "Blob", - "metadata": { - "protocol": "ec2" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Blob": { - "shape": "BlobType" - } - } - }, - "BlobType": { - "type": "blob" - } - }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Blob": "value" - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "dmFsdWU=requestid" - } - } - ] - }, - { - "description": "Lists", - "metadata": { - "protocol": "ec2" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "ListMember": { - "shape": "ListShape" - } - } - }, - "ListShape": { - "type": "list", - "member": { - "shape": "StringType" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for DatetimeOffsets operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "DatetimeOffsetsOutput": { + "type": "structure", + "members": { + "datetime": { + "shape": "DateTime" + } + } + }, + "DateTime": { + "type": "timestamp", + "timestampFormat": "iso8601" + } + }, + "cases": [ + { + "id": "Ec2QueryDateTimeWithNegativeOffset", + "given": { + "name": "DatetimeOffsets", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "DatetimeOffsetsOutput" + } + }, + "description": "Ensures that clients can correctly parse datetime (timestamps) with offsets", + "result": { + "datetime": 1576540098 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n 2019-12-16T22:48:18-01:00\n requestid\n\n" + } + }, + { + "id": "Ec2QueryDateTimeWithPositiveOffset", + "given": { + "name": "DatetimeOffsets", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "DatetimeOffsetsOutput" + } + }, + "description": "Ensures that clients can correctly parse datetime (timestamps) with offsets", + "result": { + "datetime": 1576540098 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n 2019-12-17T00:48:18+01:00\n requestid\n\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "ListMember": ["abc", "123"] - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "abc123requestid" - } - } - ] - }, - { - "description": "List with custom member name", - "metadata": { - "protocol": "ec2" + { + "description": "Test cases for EmptyInputAndEmptyOutput operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "EmptyInputAndEmptyOutputOutput": { + "type": "structure", + "members": {} + } + }, + "cases": [ + { + "id": "Ec2QueryEmptyInputAndEmptyOutput", + "given": { + "name": "EmptyInputAndEmptyOutput", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "EmptyInputAndEmptyOutputOutput" + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response members.

While this should be rare, code generators must support this.

" + }, + "description": "Empty output", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n requestid\n\n" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "ListMember": { - "shape": "ListShape" - } - } - }, - "ListShape": { - "type": "list", - "member": { - "shape": "StringType", - "locationName": "item" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for FractionalSeconds operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "FractionalSecondsOutput": { + "type": "structure", + "members": { + "datetime": { + "shape": "DateTime" + } + } + }, + "DateTime": { + "type": "timestamp", + "timestampFormat": "iso8601" + } + }, + "cases": [ + { + "id": "Ec2QueryDateTimeWithFractionalSeconds", + "given": { + "name": "FractionalSeconds", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "FractionalSecondsOutput" + } + }, + "description": "Ensures that clients can correctly parse datetime timestamps with fractional seconds", + "result": { + "datetime": 9.46845296123E8 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n 2000-01-02T20:34:56.123Z\n requestid\n\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "ListMember": ["abc", "123"] - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "abc123requestid" - } - } - ] - }, - { - "description": "Flattened List", - "metadata": { - "protocol": "ec2" + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "GreetingWithErrorsOutput": { + "type": "structure", + "members": { + "greeting": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "Ec2GreetingWithErrors", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "GreetingWithErrorsOutput" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A BadRequest error.
" + }, + "description": "Ensures that operations with errors successfully know how to deserialize the successful response", + "result": { + "greeting": "Hello" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n Hello\n requestid\n\n" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "ListMember": { - "shape": "ListType", - "flattened": true - } - } - }, - "ListType": { - "type": "list", - "member": { - "shape": "StringType" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "InvalidGreeting": { + "type": "structure", + "members": { + "Message": { + "shape": "String" + } + }, + "documentation": "

This error is thrown when an invalid greeting value is provided.

", + "exception": true + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "Ec2InvalidGreetingError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A BadRequest error.
", + "errors": [ + { + "shape": "InvalidGreeting" + } + ] + }, + "description": "Parses simple XML errors", + "errorCode": "InvalidGreeting", + "errorMessage": "Hi", + "error": { + "Message": "Hi" + }, + "response": { + "status_code": 400, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n \n \n InvalidGreeting\n Hi\n \n \n foo-id\n\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "ListMember": ["abc", "123"] - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "abc123requestid" - } - } - ] - }, - { - "description": "Normal map", - "metadata": { - "protocol": "ec2" + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "ComplexError": { + "type": "structure", + "members": { + "TopLevel": { + "shape": "String" + }, + "Nested": { + "shape": "ComplexNestedErrorData" + } + }, + "documentation": "

This error is thrown when a request is invalid.

", + "exception": true + }, + "String": { + "type": "string" + }, + "ComplexNestedErrorData": { + "type": "structure", + "members": { + "Foo": { + "shape": "String" + } + } + } + }, + "cases": [ + { + "id": "Ec2ComplexError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A BadRequest error.
", + "errors": [ + { + "shape": "ComplexError" + } + ] + }, + "errorCode": "ComplexError", + "error": { + "TopLevel": "Top level", + "Nested": { + "Foo": "bar" + } + }, + "response": { + "status_code": 400, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n \n \n ComplexError\n Hi\n Top level\n \n bar\n \n \n \n foo-id\n\n" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Map": { - "shape": "MapType" - } - } - }, - "MapType": { - "type": "map", - "key": { - "shape": "StringType" - }, - "value": { - "shape": "StructureType" - } - }, - "StructureType": { - "type": "structure", - "members": { - "foo": { - "shape": "StringType" - } - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for IgnoresWrappingXmlName operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "IgnoresWrappingXmlNameOutput": { + "type": "structure", + "members": { + "foo": { + "shape": "String" + } + }, + "locationName": "IgnoreMe" + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "Ec2IgnoresWrappingXmlName", + "given": { + "name": "IgnoresWrappingXmlName", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "IgnoresWrappingXmlNameOutput" + }, + "documentation": "

The xmlName trait on the output structure is ignored in AWS Query.

The wrapping element is always operation name + "Response".

" + }, + "description": "The xmlName trait on the output structure is ignored in the ec2 protocol", + "result": { + "foo": "bar" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n bar\n requestid\n\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Map": { - "qux": { - "foo": "bar" - }, - "baz": { - "foo": "bam" - } - } - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "quxbarbazbamrequestid" - } - } - ] - }, - { - "description": "Flattened map", - "metadata": { - "protocol": "ec2" + { + "description": "Test cases for NoInputAndOutput operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "NoInputAndOutputOutput": { + "type": "structure", + "members": {} + } + }, + "cases": [ + { + "id": "Ec2QueryNoInputAndOutput", + "given": { + "name": "NoInputAndOutput", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "NoInputAndOutputOutput" + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request payload or response members.

While this should be rare, code generators must support this.

" + }, + "description": "Empty output", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n requestid\n\n" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Map": { - "shape": "MapType", - "flattened": true - } - } - }, - "MapType": { - "type": "map", - "key": { - "shape": "StringType" - }, - "value": { - "shape": "StringType" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for RecursiveXmlShapes operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "RecursiveXmlShapesOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "RecursiveXmlShapesOutputNested1" + } + } + }, + "RecursiveXmlShapesOutputNested1": { + "type": "structure", + "members": { + "foo": { + "shape": "String" + }, + "nested": { + "shape": "RecursiveXmlShapesOutputNested2" + } + } + }, + "String": { + "type": "string" + }, + "RecursiveXmlShapesOutputNested2": { + "type": "structure", + "members": { + "bar": { + "shape": "String" + }, + "recursiveMember": { + "shape": "RecursiveXmlShapesOutputNested1" + } + } + } + }, + "cases": [ + { + "id": "Ec2RecursiveShapes", + "given": { + "name": "RecursiveXmlShapes", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "RecursiveXmlShapesOutput" + }, + "documentation": "

Recursive shapes

" + }, + "description": "Serializes recursive structures", + "result": { + "nested": { + "foo": "Foo1", + "nested": { + "bar": "Bar1", + "recursiveMember": { + "foo": "Foo2", + "nested": { + "bar": "Bar2" + } + } + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n \n Foo1\n \n Bar1\n \n Foo2\n \n Bar2\n \n \n \n \n requestid\n\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Map": { - "qux": "bar", - "baz": "bam" - } - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "quxbarbazbamrequestid" - } - } - ] - }, - { - "description": "Named map", - "metadata": { - "protocol": "ec2" + { + "description": "Test cases for SimpleScalarXmlProperties operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "SimpleScalarXmlPropertiesOutput": { + "type": "structure", + "members": { + "stringValue": { + "shape": "String" + }, + "emptyStringValue": { + "shape": "String" + }, + "trueBooleanValue": { + "shape": "Boolean" + }, + "falseBooleanValue": { + "shape": "Boolean" + }, + "byteValue": { + "shape": "Integer" + }, + "shortValue": { + "shape": "Integer" + }, + "integerValue": { + "shape": "Integer" + }, + "longValue": { + "shape": "Long" + }, + "floatValue": { + "shape": "Float" + }, + "doubleValue": { + "shape": "Double", + "locationName": "DoubleDribble" + } + } + }, + "String": { + "type": "string" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + }, + "Long": { + "type": "long", + "box": true + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + } + }, + "cases": [ + { + "id": "Ec2SimpleScalarProperties", + "given": { + "name": "SimpleScalarXmlProperties", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "SimpleScalarXmlPropertiesOutput" + } + }, + "description": "Serializes simple scalar properties", + "result": { + "stringValue": "string", + "emptyStringValue": "", + "trueBooleanValue": true, + "falseBooleanValue": false, + "byteValue": 1, + "shortValue": 2, + "integerValue": 3, + "longValue": 4, + "floatValue": 5.5, + "doubleValue": 6.5 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n string\n \n true\n false\n 1\n 2\n 3\n 4\n 5.5\n 6.5\n requestid\n\n" + } + }, + { + "id": "Ec2QuerySupportsNaNFloatOutputs", + "given": { + "name": "SimpleScalarXmlProperties", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "SimpleScalarXmlPropertiesOutput" + } + }, + "description": "Supports handling NaN float values.", + "result": { + "floatValue": "NaN", + "doubleValue": "NaN" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n NaN\n NaN\n\n" + } + }, + { + "id": "Ec2QuerySupportsInfinityFloatOutputs", + "given": { + "name": "SimpleScalarXmlProperties", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "SimpleScalarXmlPropertiesOutput" + } + }, + "description": "Supports handling Infinity float values.", + "result": { + "floatValue": "Infinity", + "doubleValue": "Infinity" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n Infinity\n Infinity\n\n" + } + }, + { + "id": "Ec2QuerySupportsNegativeInfinityFloatOutputs", + "given": { + "name": "SimpleScalarXmlProperties", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "SimpleScalarXmlPropertiesOutput" + } + }, + "description": "Supports handling -Infinity float values.", + "result": { + "floatValue": "-Infinity", + "doubleValue": "-Infinity" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n -Infinity\n -Infinity\n\n" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Map": { - "shape": "MapType", - "flattened": true - } - } - }, - "MapType": { - "type": "map", - "key": { - "shape": "StringType", - "locationName": "foo" - }, - "value": { - "shape": "StringType", - "locationName": "bar" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for XmlBlobs operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "XmlBlobsOutput": { + "type": "structure", + "members": { + "data": { + "shape": "Blob" + } + } + }, + "Blob": { + "type": "blob" + } + }, + "cases": [ + { + "id": "Ec2XmlBlobs", + "given": { + "name": "XmlBlobs", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlBlobsOutput" + }, + "documentation": "

Blobs are base64 encoded

" + }, + "description": "Blobs are base64 encoded", + "result": { + "data": "value" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n dmFsdWU=\n requestid\n\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Map": { - "qux": "bar", - "baz": "bam" - } - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "quxbarbazbamrequestid" - } - } - ] - }, - { - "description": "Empty string", - "metadata": { - "protocol": "ec2" + { + "description": "Test cases for XmlEmptyBlobs operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "XmlBlobsOutput": { + "type": "structure", + "members": { + "data": { + "shape": "Blob" + } + } + }, + "Blob": { + "type": "blob" + } + }, + "cases": [ + { + "id": "Ec2XmlEmptyBlobs", + "given": { + "name": "XmlEmptyBlobs", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlBlobsOutput" + } + }, + "description": "Empty blobs are deserialized as empty string", + "result": { + "data": "" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n \n requestid\n\n" + } + }, + { + "id": "Ec2XmlEmptySelfClosedBlobs", + "given": { + "name": "XmlEmptyBlobs", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlBlobsOutput" + } + }, + "description": "Empty self closed blobs are deserialized as empty string", + "result": { + "data": "" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n \n requestid\n\n" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Foo": { - "shape": "StringType" - } - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for XmlEmptyLists operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "XmlListsOutput": { + "type": "structure", + "members": { + "stringList": { + "shape": "StringList" + }, + "stringSet": { + "shape": "StringSet" + }, + "integerList": { + "shape": "IntegerList" + }, + "booleanList": { + "shape": "BooleanList" + }, + "timestampList": { + "shape": "TimestampList" + }, + "enumList": { + "shape": "FooEnumList" + }, + "intEnumList": { + "shape": "IntegerEnumList" + }, + "nestedStringList": { + "shape": "NestedStringList" + }, + "renamedListMembers": { + "shape": "RenamedListMembers", + "locationName": "renamed" + }, + "flattenedList": { + "shape": "RenamedListMembers", + "flattened": true + }, + "flattenedList2": { + "shape": "RenamedListMembers", + "flattened": true, + "locationName": "customName" + }, + "flattenedListWithMemberNamespace": { + "shape": "ListWithMemberNamespace", + "flattened": true + }, + "flattenedListWithNamespace": { + "shape": "ListWithNamespace", + "flattened": true + }, + "structureList": { + "shape": "StructureList", + "locationName": "myStructureList" + } + } + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringSet": { + "type": "list", + "member": { + "shape": "String" + } + }, + "IntegerList": { + "type": "list", + "member": { + "shape": "Integer" + } + }, + "BooleanList": { + "type": "list", + "member": { + "shape": "Boolean" + } + }, + "TimestampList": { + "type": "list", + "member": { + "shape": "Timestamp" + } + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "IntegerEnumList": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "NestedStringList": { + "type": "list", + "member": { + "shape": "StringList" + }, + "documentation": "

A list of lists of strings.

" + }, + "RenamedListMembers": { + "type": "list", + "member": { + "shape": "String", + "locationName": "item" + } + }, + "ListWithMemberNamespace": { + "type": "list", + "member": { + "shape": "String", + "xmlNamespace": "https://xml-member.example.com" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "ListWithNamespace": { + "type": "list", + "member": { + "shape": "String" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "StructureList": { + "type": "list", + "member": { + "shape": "StructureListMember", + "locationName": "item" + } + }, + "StructureListMember": { + "type": "structure", + "members": { + "a": { + "shape": "String", + "locationName": "value" + }, + "b": { + "shape": "String", + "locationName": "other" + } + } + }, + "String": { + "type": "string" + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "Timestamp": { + "type": "timestamp" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + } + }, + "cases": [ + { + "id": "Ec2XmlEmptyLists", + "given": { + "name": "XmlEmptyLists", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlListsOutput" + } + }, + "description": "Deserializes empty XML lists", + "result": { + "stringList": [], + "stringSet": [] + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n \n\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Foo": "" - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "requestid" - } - } - ] - }, - { - "description": "Timestamp members", - "metadata": { - "protocol": "ec2" + { + "description": "Test cases for XmlEnums operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "XmlEnumsOutput": { + "type": "structure", + "members": { + "fooEnum1": { + "shape": "FooEnum" + }, + "fooEnum2": { + "shape": "FooEnum" + }, + "fooEnum3": { + "shape": "FooEnum" + }, + "fooEnumList": { + "shape": "FooEnumList" + }, + "fooEnumSet": { + "shape": "FooEnumSet" + }, + "fooEnumMap": { + "shape": "FooEnumMap" + } + } + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "FooEnumSet": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "FooEnumMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "FooEnum" + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "Ec2XmlEnums", + "given": { + "name": "XmlEnums", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlEnumsOutput" + }, + "documentation": "

This example serializes enums as top level properties, in lists, sets, and maps.

" + }, + "description": "Serializes simple scalar properties", + "result": { + "fooEnum1": "Foo", + "fooEnum2": "0", + "fooEnum3": "1", + "fooEnumList": [ + "Foo", + "0" + ], + "fooEnumSet": [ + "Foo", + "0" + ], + "fooEnumMap": { + "hi": "Foo", + "zero": "0" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n Foo\n 0\n 1\n \n Foo\n 0\n \n \n Foo\n 0\n \n \n \n hi\n Foo\n \n \n zero\n 0\n \n \n requestid\n\n" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "TimeArg": { - "shape": "TimestampType" - }, - "TimeCustom": { - "timestampFormat": "rfc822", - "shape": "TimestampType" - }, - "TimeFormat": { - "shape": "TimestampFormatType" - }, - "StructMember": { - "shape": "TimeContainer" - } - } - }, - "TimeContainer": { - "type": "structure", - "members": { - "foo": { - "shape": "TimestampType" - }, - "bar": { - "shape": "TimestampFormatType" - } - } - }, - "TimestampFormatType": { - "timestampFormat": "unixTimestamp", - "type": "timestamp" - }, - "TimestampType": { - "type": "timestamp" - } + { + "description": "Test cases for XmlIntEnums operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "XmlIntEnumsOutput": { + "type": "structure", + "members": { + "intEnum1": { + "shape": "IntegerEnum" + }, + "intEnum2": { + "shape": "IntegerEnum" + }, + "intEnum3": { + "shape": "IntegerEnum" + }, + "intEnumList": { + "shape": "IntegerEnumList" + }, + "intEnumSet": { + "shape": "IntegerEnumSet" + }, + "intEnumMap": { + "shape": "IntegerEnumMap" + } + } + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "IntegerEnumList": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "IntegerEnumSet": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "IntegerEnumMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "IntegerEnum" + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "Ec2XmlIntEnums", + "given": { + "name": "XmlIntEnums", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlIntEnumsOutput" + }, + "documentation": "

This example serializes intEnums as top level properties, in lists, sets, and maps.

" + }, + "description": "Serializes simple scalar properties", + "result": { + "intEnum1": 1, + "intEnum2": 2, + "intEnum3": 3, + "intEnumList": [ + 1, + 2 + ], + "intEnumSet": [ + 1, + 2 + ], + "intEnumMap": { + "a": 1, + "b": 2 + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n 1\n 2\n 3\n \n 1\n 2\n \n \n 1\n 2\n \n \n \n a\n 1\n \n \n b\n 2\n \n \n requestid\n\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "TimeArg": 1398796238, - "TimeCustom": 1398796238, - "TimeFormat": 1398796238, - "StructMember": { - "foo": 1398796238, - "bar": 1398796238 - } - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "2014-04-29T18:30:38+00:0013987962382014-04-29T18:30:38+00:00Tue, 29 Apr 2014 18:30:38 GMT1398796238requestid" - } - } - ] - }, - { - "description": "Modeled exceptions", - "metadata": { - "protocol": "ec2" + { + "description": "Test cases for XmlLists operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "XmlListsOutput": { + "type": "structure", + "members": { + "stringList": { + "shape": "StringList" + }, + "stringSet": { + "shape": "StringSet" + }, + "integerList": { + "shape": "IntegerList" + }, + "booleanList": { + "shape": "BooleanList" + }, + "timestampList": { + "shape": "TimestampList" + }, + "enumList": { + "shape": "FooEnumList" + }, + "intEnumList": { + "shape": "IntegerEnumList" + }, + "nestedStringList": { + "shape": "NestedStringList" + }, + "renamedListMembers": { + "shape": "RenamedListMembers", + "locationName": "renamed" + }, + "flattenedList": { + "shape": "RenamedListMembers", + "flattened": true + }, + "flattenedList2": { + "shape": "RenamedListMembers", + "flattened": true, + "locationName": "customName" + }, + "flattenedListWithMemberNamespace": { + "shape": "ListWithMemberNamespace", + "flattened": true + }, + "flattenedListWithNamespace": { + "shape": "ListWithNamespace", + "flattened": true + }, + "structureList": { + "shape": "StructureList", + "locationName": "myStructureList" + } + } + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringSet": { + "type": "list", + "member": { + "shape": "String" + } + }, + "IntegerList": { + "type": "list", + "member": { + "shape": "Integer" + } + }, + "BooleanList": { + "type": "list", + "member": { + "shape": "Boolean" + } + }, + "TimestampList": { + "type": "list", + "member": { + "shape": "Timestamp" + } + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "IntegerEnumList": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "NestedStringList": { + "type": "list", + "member": { + "shape": "StringList" + }, + "documentation": "

A list of lists of strings.

" + }, + "RenamedListMembers": { + "type": "list", + "member": { + "shape": "String", + "locationName": "item" + } + }, + "ListWithMemberNamespace": { + "type": "list", + "member": { + "shape": "String", + "xmlNamespace": "https://xml-member.example.com" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "ListWithNamespace": { + "type": "list", + "member": { + "shape": "String" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "StructureList": { + "type": "list", + "member": { + "shape": "StructureListMember", + "locationName": "item" + } + }, + "StructureListMember": { + "type": "structure", + "members": { + "a": { + "shape": "String", + "locationName": "value" + }, + "b": { + "shape": "String", + "locationName": "other" + } + } + }, + "String": { + "type": "string" + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "Timestamp": { + "type": "timestamp" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + } + }, + "cases": [ + { + "id": "Ec2XmlLists", + "given": { + "name": "XmlLists", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlListsOutput" + }, + "documentation": "

This test case serializes XML lists for the following cases for both input and output:

  1. Normal XML lists.
  2. Normal XML sets.
  3. XML lists of lists.
  4. XML lists with @xmlName on its members
  5. Flattened XML lists.
  6. Flattened XML lists with @xmlName.
  7. Flattened XML lists with @xmlNamespace.
  8. Lists of structures.
" + }, + "description": "Tests for XML list serialization", + "result": { + "stringList": [ + "foo", + "bar" + ], + "stringSet": [ + "foo", + "bar" + ], + "integerList": [ + 1, + 2 + ], + "booleanList": [ + true, + false + ], + "timestampList": [ + 1398796238, + 1398796238 + ], + "enumList": [ + "Foo", + "0" + ], + "intEnumList": [ + 1, + 2 + ], + "nestedStringList": [ + [ + "foo", + "bar" + ], + [ + "baz", + "qux" + ] + ], + "renamedListMembers": [ + "foo", + "bar" + ], + "flattenedList": [ + "hi", + "bye" + ], + "flattenedList2": [ + "yep", + "nope" + ], + "flattenedListWithMemberNamespace": [ + "a", + "b" + ], + "flattenedListWithNamespace": [ + "a", + "b" + ], + "structureList": [ + { + "a": "1", + "b": "2" + }, + { + "a": "3", + "b": "4" + } + ] + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n \n foo\n bar\n \n \n foo\n bar\n \n \n 1\n 2\n \n \n true\n false\n \n \n 2014-04-29T18:30:38Z\n 2014-04-29T18:30:38Z\n \n \n Foo\n 0\n \n \n 1\n 2\n \n \n \n foo\n bar\n \n \n baz\n qux\n \n \n \n foo\n bar\n \n hi\n bye\n yep\n nope\n a\n b\n a\n b\n \n \n 1\n 2\n \n \n 3\n 4\n \n \n requestid\n\n" + } + } + ] }, - "shapes": { - "ExceptionShape": { - "exception": true, - "type": "structure", - "members": { - "BodyMember": { - "shape": "StringType" - }, - "Message": { - "shape": "StringType" - } - } - }, - "OtherExceptionShape": { - "exception": true, - "type": "structure", - "members": { - "BodyMember": { - "shape": "StringType" - } - } - }, - "StatusShape": { - "type": "integer" - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for XmlNamespaces operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "XmlNamespacesOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "XmlNamespaceNested" + } + }, + "xmlNamespace": "http://foo.com" + }, + "XmlNamespaceNested": { + "type": "structure", + "members": { + "foo": { + "shape": "String", + "xmlNamespace": { + "prefix": "baz", + "uri": "http://baz.com" + } + }, + "values": { + "shape": "XmlNamespacedList", + "xmlNamespace": "http://qux.com" + } + }, + "xmlNamespace": "http://foo.com" + }, + "String": { + "type": "string" + }, + "XmlNamespacedList": { + "type": "list", + "member": { + "shape": "String", + "xmlNamespace": "http://bux.com" + } + } + }, + "cases": [ + { + "id": "Ec2XmlNamespaces", + "given": { + "name": "XmlNamespaces", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlNamespacesOutput" + } + }, + "description": "Serializes XML namespaces", + "result": { + "nested": { + "foo": "Foo", + "values": [ + "Bar", + "Baz" + ] + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n \n Foo\n \n Bar\n Baz\n \n \n requestid\n\n" + } + } + ] }, - "cases": [ - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" - }, - "error": { - "BodyMember": "mybody", - "Message": "mymessage" - }, - "errorCode": "ExceptionShape", - "errorMessage": "mymessage", - "response": { - "status_code": 400, - "headers": {}, - "body": "ExceptionShapemymessagemybody" - } - }, - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" - }, - "error": { - "BodyMember": "mybody" - }, - "errorCode": "OtherExceptionShape", - "errorMessage": "mymessage", - "response": { - "status_code": 400, - "headers": {}, - "body": "OtherExceptionShapemymessagemybody" - } - }, - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" - }, - "error": {}, - "errorCode": "UndefinedShape", - "errorMessage": "mymessage", - "response": { - "status_code": 400, - "headers": {}, - "body": "UndefinedShapemymessagemybody" - } - } - ] - } + { + "description": "Test cases for XmlTimestamps operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "XmlTimestampsOutput": { + "type": "structure", + "members": { + "normal": { + "shape": "Timestamp" + }, + "dateTime": { + "shape": "SyntheticTimestamp_date_time" + }, + "dateTimeOnTarget": { + "shape": "DateTime" + }, + "epochSeconds": { + "shape": "SyntheticTimestamp_epoch_seconds" + }, + "epochSecondsOnTarget": { + "shape": "EpochSeconds" + }, + "httpDate": { + "shape": "SyntheticTimestamp_http_date" + }, + "httpDateOnTarget": { + "shape": "HttpDate" + } + } + }, + "Timestamp": { + "type": "timestamp" + }, + "SyntheticTimestamp_date_time": { + "type": "timestamp", + "timestampFormat": "iso8601" + }, + "DateTime": { + "type": "timestamp", + "timestampFormat": "iso8601" + }, + "SyntheticTimestamp_epoch_seconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "EpochSeconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "SyntheticTimestamp_http_date": { + "type": "timestamp", + "timestampFormat": "rfc822" + }, + "HttpDate": { + "type": "timestamp", + "timestampFormat": "rfc822" + } + }, + "cases": [ + { + "id": "Ec2XmlTimestamps", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlTimestampsOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Tests how normal timestamps are serialized", + "result": { + "normal": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n 2014-04-29T18:30:38Z\n requestid\n\n" + } + }, + { + "id": "Ec2XmlTimestampsWithDateTimeFormat", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlTimestampsOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of date-time works like normal timestamps", + "result": { + "dateTime": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n 2014-04-29T18:30:38Z\n requestid\n\n" + } + }, + { + "id": "Ec2XmlTimestampsWithDateTimeOnTargetFormat", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlTimestampsOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of date-time on the target shape works like normal timestamps", + "result": { + "dateTimeOnTarget": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n 2014-04-29T18:30:38Z\n requestid\n\n" + } + }, + { + "id": "Ec2XmlTimestampsWithEpochSecondsFormat", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlTimestampsOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of epoch-seconds works", + "result": { + "epochSeconds": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n 1398796238\n requestid\n\n" + } + }, + { + "id": "Ec2XmlTimestampsWithEpochSecondsOnTargetFormat", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlTimestampsOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of epoch-seconds on the target shape works", + "result": { + "epochSecondsOnTarget": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n 1398796238\n requestid\n\n" + } + }, + { + "id": "Ec2XmlTimestampsWithHttpDateFormat", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlTimestampsOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of http-date works", + "result": { + "httpDate": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n Tue, 29 Apr 2014 18:30:38 GMT\n requestid\n\n" + } + }, + { + "id": "Ec2XmlTimestampsWithHttpDateOnTargetFormat", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlTimestampsOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of http-date on the target shape works", + "result": { + "httpDateOnTarget": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "\n Tue, 29 Apr 2014 18:30:38 GMT\n requestid\n\n" + } + } + ] + } ] diff --git a/tests/unit/protocols/output/json.json b/tests/unit/protocols/output/json.json index c463aac2bc..48aec77721 100644 --- a/tests/unit/protocols/output/json.json +++ b/tests/unit/protocols/output/json.json @@ -1,824 +1,2218 @@ [ - { - "description": "Scalar members", - "metadata": { - "protocol": "json" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Str": { - "shape": "StringType" - }, - "Num": { - "shape": "IntegerType" - }, - "FalseBool": { - "shape": "BooleanType" - }, - "TrueBool": { - "shape": "BooleanType" - }, - "Float": { - "shape": "FloatType" - }, - "Double": { - "shape": "DoubleType" - }, - "Long": { - "shape": "LongType" - }, - "Char": { - "shape": "CharType" - } - } - }, - "StringType": { - "type": "string" - }, - "IntegerType": { - "type": "integer" - }, - "BooleanType": { - "type": "boolean" - }, - "FloatType": { - "type": "float" - }, - "DoubleType": { - "type": "double" - }, - "LongType": { - "type": "long" - }, - "CharType": { - "type": "character" - } - }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" + { + "description": "Test cases for DatetimeOffsets operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "result": { - "Str": "myname", - "Num": 123, - "FalseBool": false, - "TrueBool": true, - "Float": 1.2, - "Double": 1.3, - "Long": 200, - "Char": "a" + "shapes": { + "DatetimeOffsetsOutput": { + "type": "structure", + "members": { + "datetime": { + "shape": "DateTime" + } + } + }, + "DateTime": { + "type": "timestamp", + "timestampFormat": "iso8601" + } }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"Str\": \"myname\", \"Num\": 123, \"FalseBool\": false, \"TrueBool\": true, \"Float\": 1.2, \"Double\": 1.3, \"Long\": 200, \"Char\": \"a\"}" - } - } - ] - }, - { - "description": "Blob members", - "metadata": { - "protocol": "json" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "BlobMember": { - "shape": "BlobType" - }, - "StructMember": { - "shape": "BlobContainer" - } - } - }, - "BlobType": { - "type": "blob" - }, - "BlobContainer": { - "type": "structure", - "members": { - "foo": { - "shape": "BlobType" - } - } - } + "cases": [ + { + "id": "AwsJson11DateTimeWithNegativeOffset", + "given": { + "name": "DatetimeOffsets", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "DatetimeOffsetsOutput" + } + }, + "description": "Ensures that clients can correctly parse datetime (timestamps) with offsets", + "result": { + "datetime": 1576540098 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": " {\n \"datetime\": \"2019-12-16T22:48:18-01:00\"\n }\n" + } + }, + { + "id": "AwsJson11DateTimeWithPositiveOffset", + "given": { + "name": "DatetimeOffsets", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "DatetimeOffsetsOutput" + } + }, + "description": "Ensures that clients can correctly parse datetime (timestamps) with offsets", + "result": { + "datetime": 1576540098 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": " {\n \"datetime\": \"2019-12-17T00:48:18+01:00\"\n }\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "BlobMember": "hi!", - "StructMember": { - "foo": "there!" - } + { + "description": "Test cases for EmptyOperation operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"BlobMember\": \"aGkh\", \"StructMember\": {\"foo\": \"dGhlcmUh\"}}" - } - } - ] - }, - { - "description": "Timestamp members", - "metadata": { - "protocol": "json" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "TimeArg": { - "shape": "TimestampType" - }, - "TimeCustom": { - "timestampFormat": "rfc822", - "shape": "TimestampType" - }, - "TimeFormat": { - "shape": "TimestampFormatType" - }, - "StructMember": { - "shape": "TimeContainer" - } - } - }, - "TimeContainer": { - "type": "structure", - "members": { - "foo": { - "shape": "TimestampType" - }, - "bar": { - "shape": "TimestampFormatType" - } - } - }, - "TimestampFormatType": { - "timestampFormat": "iso8601", - "type": "timestamp" - }, - "TimestampType": { - "type": "timestamp" - } + "shapes": {}, + "cases": [ + { + "id": "handles_empty_output_shape", + "given": { + "name": "EmptyOperation", + "http": { + "method": "POST", + "requestUri": "/" + } + }, + "description": "When no output is defined, the service is expected to return\nan empty payload, however, client must ignore a JSON payload\nif one is returned. This ensures that if output is added later,\nthen it will not break the client.", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{}" + } + }, + { + "id": "handles_unexpected_json_output", + "given": { + "name": "EmptyOperation", + "http": { + "method": "POST", + "requestUri": "/" + } + }, + "description": "This client-only test builds on handles_empty_output_shape,\nby including unexpected fields in the JSON. A client\nneeds to ignore JSON output that is empty or that contains\nJSON object data.", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"foo\": true\n}" + } + }, + { + "id": "json_1_1_service_responds_with_no_payload", + "given": { + "name": "EmptyOperation", + "http": { + "method": "POST", + "requestUri": "/" + } + }, + "description": "When no output is defined, the service is expected to return\nan empty payload. Despite the lack of a payload, the service\nis expected to always send a Content-Type header. Clients must\nhandle cases where a service returns a JSON object and where\na service returns no JSON at all.", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" + { + "description": "Test cases for FractionalSeconds operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "result": { - "TimeArg": 1398796238, - "TimeCustom": 1398796238, - "TimeFormat": 1398796238, - "StructMember": { - "foo": 1398796238, - "bar": 1398796238 - } + "shapes": { + "FractionalSecondsOutput": { + "type": "structure", + "members": { + "datetime": { + "shape": "DateTime" + } + } + }, + "DateTime": { + "type": "timestamp", + "timestampFormat": "iso8601" + } }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"TimeArg\": 1398796238, \"TimeCustom\": \"Tue, 29 Apr 2014 18:30:38 GMT\", \"TimeFormat\": \"2014-04-29T18:30:38+00:00\", \"StructMember\": {\"foo\": 1398796238, \"bar\": \"2014-04-29T18:30:38+00:00\"}}" - } - } - ] - }, - { - "description": "Lists", - "metadata": { - "protocol": "json" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "ListMember": { - "shape": "ListType" - }, - "ListMemberMap": { - "shape": "ListTypeMap" - }, - "ListMemberStruct": { - "shape": "ListTypeStruct" - } - } - }, - "ListType": { - "type": "list", - "member": { - "shape": "StringType" - } - }, - "ListTypeMap": { - "type": "list", - "member": { - "shape": "MapType" - } - }, - "ListTypeStruct": { - "type": "list", - "member": { - "shape": "StructType" - } - }, - "StringType": { - "type": "string" - }, - "StructType": { - "type": "structure", - "members": { - } - }, - "MapType": { - "type": "string", - "key": { "shape": "StringType" }, - "value": { "shape": "StringType" } - } + "cases": [ + { + "id": "AwsJson11DateTimeWithFractionalSeconds", + "given": { + "name": "FractionalSeconds", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "FractionalSecondsOutput" + } + }, + "description": "Ensures that clients can correctly parse datetime timestamps with fractional seconds", + "result": { + "datetime": 9.46845296123E8 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": " {\n \"datetime\": \"2000-01-02T20:34:56.123Z\"\n }\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "ListMember": ["a", "b"] - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"ListMember\": [\"a\", \"b\"]}" - } - }, - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "result": { - "ListMember": ["a", null], - "ListMemberMap": [{}, null, null, {}], - "ListMemberStruct": [{}, null, null, {}] - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"ListMember\": [\"a\", null], \"ListMemberMap\": [{}, null, null, {}], \"ListMemberStruct\": [{}, null, null, {}]}" - } - } - ] - }, - { - "description": "Maps", - "metadata": { - "protocol": "json" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "MapMember": { - "shape": "MapType" - } - } - }, - "MapType": { - "type": "map", - "key": { - "shape": "StringType" + "shapes": { + "InvalidGreeting": { + "type": "structure", + "members": { + "Message": { + "shape": "String" + } + }, + "documentation": "

This error is thrown when an invalid greeting value is provided.

", + "exception": true + }, + "String": { + "type": "string" + } }, - "value": { - "shape": "NumberList" - } - }, - "StringType": { - "type": "string" - }, - "NumberList": { - "type": "list", - "member": { - "shape": "IntegerType" - } - }, - "IntegerType": { - "type": "integer" - } + "cases": [ + { + "id": "AwsJson11InvalidGreetingError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A ComplexError error.

Implementations must be able to successfully take a response and properly deserialize successful and error responses.

", + "idempotent": true, + "errors": [ + { + "shape": "InvalidGreeting" + } + ] + }, + "description": "Parses simple JSON errors", + "errorCode": "InvalidGreeting", + "errorMessage": "Hi", + "error": { + "Message": "Hi" + }, + "response": { + "status_code": 400, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"__type\": \"InvalidGreeting\",\n \"Message\": \"Hi\"\n}" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "result": { - "MapMember": { - "a": [1, 2], - "b": [3, 4] - } - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"MapMember\": {\"a\": [1, 2], \"b\": [3, 4]}}" - } - } - ] - }, - { - "description": "Ignores extra data", - "metadata": { - "protocol": "json" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "StrType": { - "shape": "StrType" - } - } - }, - "StrType": { - "type": "string" - } - }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" + "shapes": { + "ComplexError": { + "type": "structure", + "members": { + "TopLevel": { + "shape": "String" + }, + "Nested": { + "shape": "ComplexNestedErrorData" + } + }, + "documentation": "

This error is thrown when a request is invalid.

", + "exception": true + }, + "String": { + "type": "string" + }, + "ComplexNestedErrorData": { + "type": "structure", + "members": { + "Foo": { + "shape": "String" + } + } + } }, - "result": {}, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"foo\": \"bar\"}" - } - } - ] - }, - { - "description": "RPC JSON Event Stream", - "metadata": { - "protocol": "json" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Payload": {"shape": "EventStream"}, - "InitialResponse": {"shape": "StringType"} - } - }, - "EventStream": { - "type": "structure", - "eventstream": true, - "members": { - "TypeA": {"shape": "TypeAEvent"}, - "TypeB": {"shape": "TypeBEvent"} - } - }, - "TypeAEvent": { - "type": "structure", - "event": true, - "members": { - "Payload": { - "shape": "BlobType", - "eventpayload": true - } - } - }, - "TypeBEvent": { - "type": "structure", - "event": true, - "members": { - "Details": { - "shape": "Details", - "eventpayload": true - } - } - }, - "Details": { - "type": "structure", - "members": { - "StringField": {"shape": "StringType"}, - "IntegerField": {"shape": "IntegerType"} - } - }, - "StringType": { - "type": "string" - }, - "IntegerType": { - "type": "integer" - }, - "BlobType": { - "type": "blob" - } + "cases": [ + { + "id": "AwsJson11ComplexError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A ComplexError error.

Implementations must be able to successfully take a response and properly deserialize successful and error responses.

", + "idempotent": true, + "errors": [ + { + "shape": "ComplexError" + } + ] + }, + "description": "Parses a complex error with no message member", + "errorCode": "ComplexError", + "error": { + "TopLevel": "Top level", + "Nested": { + "Foo": "bar" + } + }, + "response": { + "status_code": 400, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"__type\": \"ComplexError\",\n \"TopLevel\": \"Top level\",\n \"Nested\": {\n \"Foo\": \"bar\"\n }\n}" + } + }, + { + "id": "AwsJson11EmptyComplexError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A ComplexError error.

Implementations must be able to successfully take a response and properly deserialize successful and error responses.

", + "idempotent": true, + "errors": [ + { + "shape": "ComplexError" + } + ] + }, + "errorCode": "ComplexError", + "error": {}, + "response": { + "status_code": 400, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"__type\": \"ComplexError\"\n}" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "result": { - "InitialResponse": "sometext", - "Payload": [ - { - "TypeA": {"Payload": "somebytes"} - }, - { - "TypeB": { - "Details": { - "StringField": "somestring", - "IntegerField": 123 - } - } - } - ] + "shapes": { + "FooError": { + "type": "structure", + "members": {}, + "documentation": "

This error has test cases that test some of the dark corners of Amazon service framework history. It should only be implemented by clients.

", + "exception": true, + "fault": true + } }, - "response": { - "status_code": 200, - "headers": {}, - "body": "AAAAfgAAAE/Fo93GDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAEGluaXRpYWwtcmVzcG9uc2UNOmNvbnRlbnQtdHlwZQcACXRleHQvanNvbnsiSW5pdGlhbFJlc3BvbnNlIjogInNvbWV0ZXh0In32mCSDAAAAbAAAAFPLgkVrDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcABVR5cGVBDTpjb250ZW50LXR5cGUHABhhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW1zb21lYnl0ZXMesj2HAAAAhgAAAEQqNR/SDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcABVR5cGVCDTpjb250ZW50LXR5cGUHAAl0ZXh0L2pzb257IlN0cmluZ0ZpZWxkIjogInNvbWVzdHJpbmciLCAiSW50ZWdlckZpZWxkIjogMTIzfffGN30=" - } - } - ] - }, - { - "description": "Modeled exceptions", - "metadata": { - "protocol": "json" - }, - "shapes": { - "ExceptionShape": { - "exception": true, - "type": "structure", - "members": { - "BodyMember": { - "shape": "StringType" - }, - "Code": { - "shape": "StringType" - }, - "Message": { - "shape": "StringType" - } - } - }, - "OtherExceptionShape": { - "exception": true, - "type": "structure", - "members": { - "BodyMember": { - "shape": "StringType" - } - } - }, - "StringType": { - "type": "string" - } + "cases": [ + { + "id": "AwsJson11FooErrorUsingXAmznErrorType", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A ComplexError error.

Implementations must be able to successfully take a response and properly deserialize successful and error responses.

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Serializes the X-Amzn-ErrorType header. For an example service, see Amazon EKS.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 400, + "headers": { + "X-Amzn-Errortype": "FooError" + } + } + }, + { + "id": "AwsJson11FooErrorUsingXAmznErrorTypeWithUri", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A ComplexError error.

Implementations must be able to successfully take a response and properly deserialize successful and error responses.

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some X-Amzn-Errortype headers contain URLs. Clients need to split the URL on ':' and take only the first half of the string. For example, 'ValidationException:http://internal.amazon.com/coral/com.amazon.coral.validate/'\nis to be interpreted as 'ValidationException'.\n\nFor an example service see Amazon Polly.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "X-Amzn-Errortype": "FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/" + } + } + }, + { + "id": "AwsJson11FooErrorUsingXAmznErrorTypeWithUriAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A ComplexError error.

Implementations must be able to successfully take a response and properly deserialize successful and error responses.

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "X-Amzn-Errortype might contain a URL and a namespace. Client should extract only the shape name. This is a pathalogical case that might not actually happen in any deployed AWS service.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "X-Amzn-Errortype": "aws.protocoltests.restjson#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/" + } + } + }, + { + "id": "AwsJson11FooErrorUsingCode", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A ComplexError error.

Implementations must be able to successfully take a response and properly deserialize successful and error responses.

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "This example uses the 'code' property in the output rather than X-Amzn-Errortype. Some services do this though it's preferable to send the X-Amzn-Errortype. Client implementations must first check for the X-Amzn-Errortype and then check for a top-level 'code' property.\n\nFor example service see Amazon S3 Glacier.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"code\": \"FooError\"\n}" + } + }, + { + "id": "AwsJson11FooErrorUsingCodeAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A ComplexError error.

Implementations must be able to successfully take a response and properly deserialize successful and error responses.

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using code, and it might contain a namespace. Clients should just take the last part of the string after '#'.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"code\": \"aws.protocoltests.restjson#FooError\"\n}" + } + }, + { + "id": "AwsJson11FooErrorUsingCodeUriAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A ComplexError error.

Implementations must be able to successfully take a response and properly deserialize successful and error responses.

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using code, and it might contain a namespace. It also might contain a URI. Clients should just take the last part of the string after '#' and before \":\". This is a pathalogical case that might not occur in any deployed AWS service.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"code\": \"aws.protocoltests.restjson#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/\"\n}" + } + }, + { + "id": "AwsJson11FooErrorWithDunderType", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A ComplexError error.

Implementations must be able to successfully take a response and properly deserialize successful and error responses.

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using __type.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"__type\": \"FooError\"\n}" + } + }, + { + "id": "AwsJson11FooErrorWithDunderTypeAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A ComplexError error.

Implementations must be able to successfully take a response and properly deserialize successful and error responses.

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using __type, and it might contain a namespace. Clients should just take the last part of the string after '#'.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"__type\": \"aws.protocoltests.restjson#FooError\"\n}" + } + }, + { + "id": "AwsJson11FooErrorWithDunderTypeUriAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A ComplexError error.

Implementations must be able to successfully take a response and properly deserialize successful and error responses.

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using __type, and it might contain a namespace. It also might contain a URI. Clients should just take the last part of the string after '#' and before \":\". This is a pathalogical case that might not occur in any deployed AWS service.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"__type\": \"aws.protocoltests.restjson#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/\"\n}" + } + } + ] }, - "cases": [ - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" + { + "description": "Test cases for JsonEnums operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "error": { - "BodyMember": "mybody", - "Code": "OtherExceptionShape", - "Message": "mymessage" - }, - "errorCode": "ExceptionShape", - "errorMessage": "mymessage", - "response": { - "status_code": 400, - "headers": {}, - "body": "{ \"__type\": \"ExceptionShape\", \"Code\": \"OtherExceptionShape\", \"BodyMember\": \"mybody\", \"Message\": \"mymessage\"}" - } - }, - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" - }, - "error": { - "BodyMember": "mybody" - }, - "errorCode": "OtherExceptionShape", - "errorMessage": "mymessage", - "response": { - "status_code": 400, - "headers": {}, - "body": "{ \"__type\": \"OtherExceptionShape\", \"Code\": \"ExceptionShape\", \"BodyMember\": \"mybody\", \"Message\": \"mymessage\"}" - } - }, - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" + "shapes": { + "JsonEnumsInputOutput": { + "type": "structure", + "members": { + "fooEnum1": { + "shape": "FooEnum" + }, + "fooEnum2": { + "shape": "FooEnum" + }, + "fooEnum3": { + "shape": "FooEnum" + }, + "fooEnumList": { + "shape": "FooEnumList" + }, + "fooEnumSet": { + "shape": "FooEnumSet" + }, + "fooEnumMap": { + "shape": "FooEnumMap" + } + } + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "FooEnumSet": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "FooEnumMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "FooEnum" + } + }, + "String": { + "type": "string" + } }, - "error": {}, - "errorCode": "UndefinedShape", - "response": { - "status_code": 400, - "headers": { - "ImaHeader": "test", - "X-Foo": "abc" - }, - "body": "{ \"__type\": \"UndefinedShape\", \"Code\": \"ExceptionShape\", \"BodyMember\": \"mybody\"}" - } - } - ] - }, - { - "description": "Modeled exceptions with jsonVersion 1.0", - "metadata": { - "protocol": "json", - "jsonVersion": "1.0" - }, - "shapes": { - "ExceptionShape": { - "exception": true, - "type": "structure", - "members": { - "BodyMember": { - "shape": "StringType" - }, - "Message": { - "shape": "StringType" - } - } - }, - "StringType": { - "type": "string" - } + "cases": [ + { + "id": "AwsJson11Enums", + "given": { + "name": "JsonEnums", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonEnumsInputOutput" + }, + "documentation": "

This example serializes enums as top level properties, in lists, sets, and maps.

", + "idempotent": true + }, + "description": "Serializes simple scalar properties", + "result": { + "fooEnum1": "Foo", + "fooEnum2": "0", + "fooEnum3": "1", + "fooEnumList": [ + "Foo", + "0" + ], + "fooEnumSet": [ + "Foo", + "0" + ], + "fooEnumMap": { + "hi": "Foo", + "zero": "0" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"fooEnum1\": \"Foo\",\n \"fooEnum2\": \"0\",\n \"fooEnum3\": \"1\",\n \"fooEnumList\": [\n \"Foo\",\n \"0\"\n ],\n \"fooEnumSet\": [\n \"Foo\",\n \"0\"\n ],\n \"fooEnumMap\": {\n \"hi\": \"Foo\",\n \"zero\": \"0\"\n }\n}" + } + } + ] }, - "cases": [ - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" + { + "description": "Test cases for JsonUnions operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "error": { - "BodyMember": "mybody", - "Message": "mymessage" + "shapes": { + "UnionInputOutput": { + "type": "structure", + "members": { + "contents": { + "shape": "MyUnion" + } + }, + "documentation": "

A shared structure that contains a single union member.

" + }, + "MyUnion": { + "type": "structure", + "members": { + "stringValue": { + "shape": "String" + }, + "booleanValue": { + "shape": "Boolean" + }, + "numberValue": { + "shape": "Integer" + }, + "blobValue": { + "shape": "Blob" + }, + "timestampValue": { + "shape": "Timestamp" + }, + "enumValue": { + "shape": "FooEnum" + }, + "listValue": { + "shape": "StringList" + }, + "mapValue": { + "shape": "StringMap" + }, + "structureValue": { + "shape": "GreetingStruct" + } + }, + "documentation": "

A union with a representative set of types for members.

", + "union": true + }, + "String": { + "type": "string" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + }, + "Blob": { + "type": "blob" + }, + "Timestamp": { + "type": "timestamp" + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "String" + } + }, + "GreetingStruct": { + "type": "structure", + "members": { + "hi": { + "shape": "String" + } + } + } }, - "errorCode": "ExceptionShape", - "errorMessage": "mymessage", - "response": { - "status_code": 400, - "headers": {}, - "body": "{ \"__type\": \"FooPrefix#ExceptionShape\", \"BodyMember\": \"mybody\", \"Message\": \"mymessage\"}" - } - } - ] - }, - { - "description": "Serialize document with standalone primitive type in a JSON response", - "metadata": { - "protocol": "json" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "inlineDocument": { - "shape": "DocumentType" + "cases": [ + { + "id": "AwsJson11DeserializeStringUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes a string union value", + "result": { + "contents": { + "stringValue": "foo" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"contents\": {\n \"stringValue\": \"foo\"\n }\n}" + } + }, + { + "id": "AwsJson11DeserializeBooleanUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes a boolean union value", + "result": { + "contents": { + "booleanValue": true + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"contents\": {\n \"booleanValue\": true\n }\n}" + } + }, + { + "id": "AwsJson11DeserializeNumberUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes a number union value", + "result": { + "contents": { + "numberValue": 1 + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"contents\": {\n \"numberValue\": 1\n }\n}" + } + }, + { + "id": "AwsJson11DeserializeBlobUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes a blob union value", + "result": { + "contents": { + "blobValue": "foo" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"contents\": {\n \"blobValue\": \"Zm9v\"\n }\n}" + } + }, + { + "id": "AwsJson11DeserializeTimestampUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes a timestamp union value", + "result": { + "contents": { + "timestampValue": 1398796238 + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"contents\": {\n \"timestampValue\": 1398796238\n }\n}" + } + }, + { + "id": "AwsJson11DeserializeEnumUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes an enum union value", + "result": { + "contents": { + "enumValue": "Foo" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"contents\": {\n \"enumValue\": \"Foo\"\n }\n}" + } + }, + { + "id": "AwsJson11DeserializeListUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes a list union value", + "result": { + "contents": { + "listValue": [ + "foo", + "bar" + ] + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"contents\": {\n \"listValue\": [\"foo\", \"bar\"]\n }\n}" + } + }, + { + "id": "AwsJson11DeserializeMapUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes a map union value", + "result": { + "contents": { + "mapValue": { + "foo": "bar", + "spam": "eggs" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"contents\": {\n \"mapValue\": {\n \"foo\": \"bar\",\n \"spam\": \"eggs\"\n }\n }\n}" + } + }, + { + "id": "AwsJson11DeserializeStructureUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes a structure union value", + "result": { + "contents": { + "structureValue": { + "hi": "hello" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"contents\": {\n \"structureValue\": {\n \"hi\": \"hello\"\n }\n }\n}" + } + }, + { + "id": "AwsJson11DeserializeIgnoreType", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Ignores an unrecognized __type property", + "result": { + "contents": { + "structureValue": { + "hi": "hello" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"contents\": {\n \"__type\": \"aws.protocoltests.json10#MyUnion\",\n \"structureValue\": {\n \"hi\": \"hello\"\n }\n }\n}" + } } - } - }, - "DocumentType": { - "type": "structure", - "document": true - } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "inlineDocument": "foo" - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"inlineDocument\": \"foo\"}" - } - }, - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "inlineDocument": 123 - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"inlineDocument\": 123}" - } - }, - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "inlineDocument": 1.2 + { + "description": "Test cases for KitchenSinkOperation operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"inlineDocument\": 1.2}" - } - }, - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "inlineDocument": true - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"inlineDocument\": true}" - } - }, - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "inlineDocument": "" + "shapes": { + "KitchenSink": { + "type": "structure", + "members": { + "Blob": { + "shape": "Blob" + }, + "Boolean": { + "shape": "Boolean" + }, + "Double": { + "shape": "Double" + }, + "EmptyStruct": { + "shape": "EmptyStruct" + }, + "Float": { + "shape": "Float" + }, + "HttpdateTimestamp": { + "shape": "SyntheticTimestamp_http_date" + }, + "Integer": { + "shape": "Integer" + }, + "Iso8601Timestamp": { + "shape": "SyntheticTimestamp_date_time" + }, + "JsonValue": { + "shape": "JsonValue", + "jsonvalue": true + }, + "ListOfLists": { + "shape": "ListOfListOfStrings" + }, + "ListOfMapsOfStrings": { + "shape": "ListOfMapsOfStrings" + }, + "ListOfStrings": { + "shape": "ListOfStrings" + }, + "ListOfStructs": { + "shape": "ListOfStructs" + }, + "Long": { + "shape": "Long" + }, + "MapOfListsOfStrings": { + "shape": "MapOfListsOfStrings" + }, + "MapOfMaps": { + "shape": "MapOfMapOfStrings" + }, + "MapOfStrings": { + "shape": "MapOfStrings" + }, + "MapOfStructs": { + "shape": "MapOfStructs" + }, + "RecursiveList": { + "shape": "ListOfKitchenSinks" + }, + "RecursiveMap": { + "shape": "MapOfKitchenSinks" + }, + "RecursiveStruct": { + "shape": "KitchenSink" + }, + "SimpleStruct": { + "shape": "SimpleStruct" + }, + "String": { + "shape": "String" + }, + "StructWithJsonName": { + "shape": "StructWithJsonName" + }, + "Timestamp": { + "shape": "Timestamp" + }, + "UnixTimestamp": { + "shape": "SyntheticTimestamp_epoch_seconds" + } + } + }, + "Blob": { + "type": "blob" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Double": { + "type": "double", + "box": true + }, + "EmptyStruct": { + "type": "structure", + "members": {} + }, + "Float": { + "type": "float", + "box": true + }, + "SyntheticTimestamp_http_date": { + "type": "timestamp", + "timestampFormat": "rfc822" + }, + "Integer": { + "type": "integer", + "box": true + }, + "SyntheticTimestamp_date_time": { + "type": "timestamp", + "timestampFormat": "iso8601" + }, + "JsonValue": { + "type": "string" + }, + "ListOfListOfStrings": { + "type": "list", + "member": { + "shape": "ListOfStrings" + } + }, + "ListOfMapsOfStrings": { + "type": "list", + "member": { + "shape": "MapOfStrings" + } + }, + "ListOfStrings": { + "type": "list", + "member": { + "shape": "String" + } + }, + "ListOfStructs": { + "type": "list", + "member": { + "shape": "SimpleStruct" + } + }, + "Long": { + "type": "long", + "box": true + }, + "MapOfListsOfStrings": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "ListOfStrings" + } + }, + "MapOfMapOfStrings": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "MapOfStrings" + } + }, + "MapOfStrings": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "String" + } + }, + "MapOfStructs": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "SimpleStruct" + } + }, + "ListOfKitchenSinks": { + "type": "list", + "member": { + "shape": "KitchenSink" + } + }, + "MapOfKitchenSinks": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "KitchenSink" + } + }, + "SimpleStruct": { + "type": "structure", + "members": { + "Value": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + }, + "StructWithJsonName": { + "type": "structure", + "members": { + "Value": { + "shape": "String" + } + } + }, + "Timestamp": { + "type": "timestamp" + }, + "SyntheticTimestamp_epoch_seconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + } }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"inlineDocument\": \"\"}" - } - } - ] - }, - { - "description": "Serialize inline document in a JSON response", - "metadata": { - "protocol": "json" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "inlineDocument": { - "shape": "DocumentType" + "cases": [ + { + "id": "parses_operations_with_empty_json_bodies", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses operations with empty JSON bodies", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{}" + } + }, + { + "id": "parses_string_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses string shapes", + "result": { + "String": "string-value" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"String\":\"string-value\"}" + } + }, + { + "id": "parses_integer_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses integer shapes", + "result": { + "Integer": 1234 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"Integer\":1234}" + } + }, + { + "id": "parses_long_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses long shapes", + "result": { + "Long": 1234567890123456789 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"Long\":1234567890123456789}" + } + }, + { + "id": "parses_float_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses float shapes", + "result": { + "Float": 1234.5 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"Float\":1234.5}" + } + }, + { + "id": "parses_double_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses double shapes", + "result": { + "Double": 1.2345678912345679E8 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"Double\":123456789.12345679}" + } + }, + { + "id": "parses_boolean_shapes_true", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses boolean shapes (true)", + "result": { + "Boolean": true + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"Boolean\":true}" + } + }, + { + "id": "parses_boolean_false", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses boolean (false)", + "result": { + "Boolean": false + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"Boolean\":false}" + } + }, + { + "id": "parses_blob_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses blob shapes", + "result": { + "Blob": "binary-value" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"Blob\":\"YmluYXJ5LXZhbHVl\"}" + } + }, + { + "id": "parses_timestamp_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses timestamp shapes", + "result": { + "Timestamp": 946845296 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"Timestamp\":946845296}" + } + }, + { + "id": "parses_iso8601_timestamps", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses iso8601 timestamps", + "result": { + "Iso8601Timestamp": 946845296 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"Iso8601Timestamp\":\"2000-01-02T20:34:56Z\"}" + } + }, + { + "id": "parses_httpdate_timestamps", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses httpdate timestamps", + "result": { + "HttpdateTimestamp": 946845296 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"HttpdateTimestamp\":\"Sun, 02 Jan 2000 20:34:56 GMT\"}" + } + }, + { + "id": "parses_list_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses list shapes", + "result": { + "ListOfStrings": [ + "abc", + "mno", + "xyz" + ] + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"ListOfStrings\":[\"abc\",\"mno\",\"xyz\"]}" + } + }, + { + "id": "parses_list_of_map_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses list of map shapes", + "result": { + "ListOfMapsOfStrings": [ + { + "size": "large" + }, + { + "color": "red" + } + ] + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"ListOfMapsOfStrings\":[{\"size\":\"large\"},{\"color\":\"red\"}]}" + } + }, + { + "id": "parses_list_of_list_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses list of list shapes", + "result": { + "ListOfLists": [ + [ + "abc", + "mno", + "xyz" + ], + [ + "hjk", + "qrs", + "tuv" + ] + ] + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"ListOfLists\":[[\"abc\",\"mno\",\"xyz\"],[\"hjk\",\"qrs\",\"tuv\"]]}" + } + }, + { + "id": "parses_list_of_structure_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses list of structure shapes", + "result": { + "ListOfStructs": [ + { + "Value": "value-1" + }, + { + "Value": "value-2" + } + ] + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"ListOfStructs\":[{\"Value\":\"value-1\"},{\"Value\":\"value-2\"}]}" + } + }, + { + "id": "parses_list_of_recursive_structure_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses list of recursive structure shapes", + "result": { + "RecursiveList": [ + { + "RecursiveList": [ + { + "RecursiveList": [ + { + "String": "value" + } + ] + } + ] + } + ] + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"RecursiveList\":[{\"RecursiveList\":[{\"RecursiveList\":[{\"String\":\"value\"}]}]}]}" + } + }, + { + "id": "parses_map_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses map shapes", + "result": { + "MapOfStrings": { + "size": "large", + "color": "red" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"MapOfStrings\":{\"size\":\"large\",\"color\":\"red\"}}" + } + }, + { + "id": "parses_map_of_list_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses map of list shapes", + "result": { + "MapOfListsOfStrings": { + "sizes": [ + "large", + "small" + ], + "colors": [ + "red", + "green" + ] + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"MapOfListsOfStrings\":{\"sizes\":[\"large\",\"small\"],\"colors\":[\"red\",\"green\"]}}" + } + }, + { + "id": "parses_map_of_map_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses map of map shapes", + "result": { + "MapOfMaps": { + "sizes": { + "large": "L", + "medium": "M" + }, + "colors": { + "red": "R", + "blue": "B" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"MapOfMaps\":{\"sizes\":{\"large\":\"L\",\"medium\":\"M\"},\"colors\":{\"red\":\"R\",\"blue\":\"B\"}}}" + } + }, + { + "id": "parses_map_of_structure_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses map of structure shapes", + "result": { + "MapOfStructs": { + "size": { + "Value": "small" + }, + "color": { + "Value": "red" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"MapOfStructs\":{\"size\":{\"Value\":\"small\"},\"color\":{\"Value\":\"red\"}}}" + } + }, + { + "id": "parses_map_of_recursive_structure_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses map of recursive structure shapes", + "result": { + "RecursiveMap": { + "key-1": { + "RecursiveMap": { + "key-2": { + "RecursiveMap": { + "key-3": { + "String": "value" + } + } + } + } + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"RecursiveMap\":{\"key-1\":{\"RecursiveMap\":{\"key-2\":{\"RecursiveMap\":{\"key-3\":{\"String\":\"value\"}}}}}}}" + } + }, + { + "id": "parses_the_request_id_from_the_response", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses the request id from the response", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amzn-Requestid": "amazon-uniq-request-id" + }, + "body": "{}" + } } - } - }, - "DocumentType": { - "type": "structure", - "document": true - } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" + { + "description": "Test cases for NullOperation operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "result": { - "inlineDocument": {"foo": "bar"} + "shapes": { + "NullOperationInputOutput": { + "type": "structure", + "members": { + "string": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"inlineDocument\": {\"foo\": \"bar\"}}" - } - } - ] - }, - { - "description": "Serialize aggregate documents in a JSON response", - "metadata": { - "protocol": "json" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "parentDocument": { - "shape": "DocumentType" + "cases": [ + { + "id": "AwsJson11StructuresDontDeserializeNullValues", + "given": { + "name": "NullOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "NullOperationInputOutput" + } + }, + "description": "Null structure values are dropped", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"string\": null\n}" + } } - } - }, - "DocumentType": { - "type": "structure", - "document": true - } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" + { + "description": "Test cases for PutAndGetInlineDocuments operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "result": { - "parentDocument": { - "str": "test", - "num": 123, - "float": 1.2, - "bool": true, - "null": "", - "document": {"foo": false}, - "list": ["myname", 321, 1.3, true, "", {"nested": true}, [200, ""]] - } + "shapes": { + "PutAndGetInlineDocumentsInputOutput": { + "type": "structure", + "members": { + "inlineDocument": { + "shape": "Document" + } + } + }, + "Document": { + "type": "structure", + "members": {}, + "document": true + } }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"parentDocument\": {\"str\": \"test\", \"num\": 123, \"float\": 1.2, \"bool\": true, \"null\": \"\", \"document\": {\"foo\": false}, \"list\": [\"myname\", 321, 1.3, true, \"\", {\"nested\": true}, [200, \"\"]]}}" - } - }, - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" + "cases": [ + { + "id": "PutAndGetInlineDocumentsInput", + "given": { + "name": "PutAndGetInlineDocuments", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "PutAndGetInlineDocumentsInputOutput" + }, + "documentation": "

This example serializes an inline document as part of the payload.

" + }, + "description": "Serializes inline documents in a JSON response.", + "result": { + "inlineDocument": { + "foo": "bar" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"inlineDocument\": {\"foo\": \"bar\"}\n}" + } + } + ] + }, + { + "description": "Test cases for SimpleScalarProperties operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "result": { - "parentDocument": [ - "test", - 123, - 1.2, - true, - "", - {"str": "myname", "num": 321, "float": 1.3, "bool": true, "null": "", "document": {"nested": true}, "list": [200, ""]}, - ["foo", false] - ] + "shapes": { + "SimpleScalarPropertiesInputOutput": { + "type": "structure", + "members": { + "floatValue": { + "shape": "Float" + }, + "doubleValue": { + "shape": "Double" + } + } + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + } }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"parentDocument\": [\"test\", 123, 1.2, true, \"\", {\"str\": \"myname\", \"num\": 321, \"float\": 1.3, \"bool\": true, \"null\": \"\", \"document\": {\"nested\": true}, \"list\": [200, \"\"]}, [\"foo\", false]]}" - } - } - ] - } + "cases": [ + { + "id": "AwsJson11SupportsNaNFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "SimpleScalarPropertiesInputOutput" + } + }, + "description": "Supports handling NaN float values.", + "result": { + "floatValue": "NaN", + "doubleValue": "NaN" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"floatValue\": \"NaN\",\n \"doubleValue\": \"NaN\"\n}" + } + }, + { + "id": "AwsJson11SupportsInfinityFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "SimpleScalarPropertiesInputOutput" + } + }, + "description": "Supports handling Infinity float values.", + "result": { + "floatValue": "Infinity", + "doubleValue": "Infinity" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"floatValue\": \"Infinity\",\n \"doubleValue\": \"Infinity\"\n}" + } + }, + { + "id": "AwsJson11SupportsNegativeInfinityFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "SimpleScalarPropertiesInputOutput" + } + }, + "description": "Supports handling -Infinity float values.", + "result": { + "floatValue": "-Infinity", + "doubleValue": "-Infinity" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"floatValue\": \"-Infinity\",\n \"doubleValue\": \"-Infinity\"\n}" + } + } + ] + } ] diff --git a/tests/unit/protocols/output/json_1_0.json b/tests/unit/protocols/output/json_1_0.json new file mode 100644 index 0000000000..920a8bebae --- /dev/null +++ b/tests/unit/protocols/output/json_1_0.json @@ -0,0 +1,1157 @@ +[ + { + "description": "Test cases for EmptyInputAndEmptyOutput operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2020-07-14", + "jsonVersion": "1.0", + "targetPrefix": "JsonRpc10" + }, + "shapes": { + "EmptyInputAndEmptyOutputOutput": { + "type": "structure", + "members": {} + } + }, + "cases": [ + { + "id": "AwsJson10EmptyInputAndEmptyOutputSendJsonObject", + "given": { + "name": "EmptyInputAndEmptyOutput", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "EmptyInputAndEmptyOutputOutput" + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response payload because the operation has an empty input and empty output structure that reuses the same shape. While this should be rare, code generators must support this.

" + }, + "description": "A service will always return a JSON object for operations with modeled output.", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{}" + } + } + ] + }, + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2020-07-14", + "jsonVersion": "1.0", + "targetPrefix": "JsonRpc10" + }, + "shapes": { + "InvalidGreeting": { + "type": "structure", + "members": { + "Message": { + "shape": "String" + } + }, + "documentation": "

This error is thrown when an invalid greeting value is provided.

", + "exception": true + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "AwsJson10InvalidGreetingError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A ComplexError error.

Implementations must be able to successfully take a response and properly deserialize successful and error responses.

", + "idempotent": true, + "errors": [ + { + "shape": "InvalidGreeting" + } + ] + }, + "description": "Parses simple JSON errors", + "errorCode": "InvalidGreeting", + "errorMessage": "Hi", + "error": { + "Message": "Hi" + }, + "response": { + "status_code": 400, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"__type\": \"aws.protocoltests.json10#InvalidGreeting\",\n \"Message\": \"Hi\"\n}" + } + } + ] + }, + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2020-07-14", + "jsonVersion": "1.0", + "targetPrefix": "JsonRpc10" + }, + "shapes": { + "FooError": { + "type": "structure", + "members": {}, + "documentation": "

This error has test cases that test some of the dark corners of Amazon service framework history. It should only be implemented by clients.

", + "exception": true, + "fault": true + } + }, + "cases": [ + { + "id": "AwsJson10FooErrorUsingXAmznErrorType", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A ComplexError error.

Implementations must be able to successfully take a response and properly deserialize successful and error responses.

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Serializes the X-Amzn-ErrorType header. For an example service, see Amazon EKS.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "X-Amzn-Errortype": "FooError" + } + } + }, + { + "id": "AwsJson10FooErrorUsingXAmznErrorTypeWithUri", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A ComplexError error.

Implementations must be able to successfully take a response and properly deserialize successful and error responses.

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some X-Amzn-Errortype headers contain URLs. Clients need to split the URL on ':' and take only the first half of the string. For example, 'ValidationException:http://internal.amazon.com/coral/com.amazon.coral.validate/'\nis to be interpreted as 'ValidationException'.\n\nFor an example service see Amazon Polly.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "X-Amzn-Errortype": "FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/" + } + } + }, + { + "id": "AwsJson10FooErrorUsingXAmznErrorTypeWithUriAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A ComplexError error.

Implementations must be able to successfully take a response and properly deserialize successful and error responses.

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "X-Amzn-Errortype might contain a URL and a namespace. Client should extract only the shape name. This is a pathalogical case that might not actually happen in any deployed AWS service.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "X-Amzn-Errortype": "aws.protocoltests.json10#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/" + } + } + }, + { + "id": "AwsJson10FooErrorUsingCode", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A ComplexError error.

Implementations must be able to successfully take a response and properly deserialize successful and error responses.

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "This example uses the 'code' property in the output rather than X-Amzn-Errortype. Some services do this though it's preferable to send the X-Amzn-Errortype. Client implementations must first check for the X-Amzn-Errortype and then check for a top-level 'code' property.\n\nFor example service see Amazon S3 Glacier.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"code\": \"FooError\"\n}" + } + }, + { + "id": "AwsJson10FooErrorUsingCodeAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A ComplexError error.

Implementations must be able to successfully take a response and properly deserialize successful and error responses.

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using code, and it might contain a namespace. Clients should just take the last part of the string after '#'.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"code\": \"aws.protocoltests.json10#FooError\"\n}" + } + }, + { + "id": "AwsJson10FooErrorUsingCodeUriAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A ComplexError error.

Implementations must be able to successfully take a response and properly deserialize successful and error responses.

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using code, and it might contain a namespace. It also might contain a URI. Clients should just take the last part of the string after '#' and before \":\". This is a pathalogical case that might not occur in any deployed AWS service.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"code\": \"aws.protocoltests.json10#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/\"\n}" + } + }, + { + "id": "AwsJson10FooErrorWithDunderType", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A ComplexError error.

Implementations must be able to successfully take a response and properly deserialize successful and error responses.

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using __type.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"__type\": \"FooError\"\n}" + } + }, + { + "id": "AwsJson10FooErrorWithDunderTypeAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A ComplexError error.

Implementations must be able to successfully take a response and properly deserialize successful and error responses.

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using __type, and it might contain a namespace. Clients should just take the last part of the string after '#'.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"__type\": \"aws.protocoltests.json10#FooError\"\n}" + } + }, + { + "id": "AwsJson10FooErrorWithDunderTypeUriAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A ComplexError error.

Implementations must be able to successfully take a response and properly deserialize successful and error responses.

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using __type, and it might contain a namespace. It also might contain a URI. Clients should just take the last part of the string after '#' and before \":\". This is a pathalogical case that might not occur in any deployed AWS service.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"__type\": \"aws.protocoltests.json10#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/\"\n}" + } + } + ] + }, + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2020-07-14", + "jsonVersion": "1.0", + "targetPrefix": "JsonRpc10" + }, + "shapes": { + "ComplexError": { + "type": "structure", + "members": { + "TopLevel": { + "shape": "String" + }, + "Nested": { + "shape": "ComplexNestedErrorData" + } + }, + "documentation": "

This error is thrown when a request is invalid.

", + "exception": true + }, + "String": { + "type": "string" + }, + "ComplexNestedErrorData": { + "type": "structure", + "members": { + "Foo": { + "shape": "String" + } + } + } + }, + "cases": [ + { + "id": "AwsJson10ComplexError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A ComplexError error.

Implementations must be able to successfully take a response and properly deserialize successful and error responses.

", + "idempotent": true, + "errors": [ + { + "shape": "ComplexError" + } + ] + }, + "description": "Parses a complex error with no message member", + "errorCode": "ComplexError", + "error": { + "TopLevel": "Top level", + "Nested": { + "Foo": "bar" + } + }, + "response": { + "status_code": 400, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"__type\": \"aws.protocoltests.json10#ComplexError\",\n \"TopLevel\": \"Top level\",\n \"Nested\": {\n \"Foo\": \"bar\"\n }\n}" + } + }, + { + "id": "AwsJson10EmptyComplexError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A ComplexError error.

Implementations must be able to successfully take a response and properly deserialize successful and error responses.

", + "idempotent": true, + "errors": [ + { + "shape": "ComplexError" + } + ] + }, + "description": "Parses a complex error with an empty body", + "errorCode": "ComplexError", + "error": {}, + "response": { + "status_code": 400, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"__type\": \"aws.protocoltests.json10#ComplexError\"\n}" + } + } + ] + }, + { + "description": "Test cases for JsonUnions operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2020-07-14", + "jsonVersion": "1.0", + "targetPrefix": "JsonRpc10" + }, + "shapes": { + "JsonUnionsOutput": { + "type": "structure", + "members": { + "contents": { + "shape": "MyUnion" + } + } + }, + "MyUnion": { + "type": "structure", + "members": { + "stringValue": { + "shape": "String" + }, + "booleanValue": { + "shape": "Boolean" + }, + "numberValue": { + "shape": "Integer" + }, + "blobValue": { + "shape": "Blob" + }, + "timestampValue": { + "shape": "Timestamp" + }, + "enumValue": { + "shape": "FooEnum" + }, + "intEnumValue": { + "shape": "IntegerEnum" + }, + "listValue": { + "shape": "StringList" + }, + "mapValue": { + "shape": "StringMap" + }, + "structureValue": { + "shape": "GreetingStruct" + } + }, + "documentation": "

A union with a representative set of types for members.

", + "union": true + }, + "String": { + "type": "string" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + }, + "Blob": { + "type": "blob" + }, + "Timestamp": { + "type": "timestamp" + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "String" + } + }, + "GreetingStruct": { + "type": "structure", + "members": { + "hi": { + "shape": "String" + } + } + } + }, + "cases": [ + { + "id": "AwsJson10DeserializeStringUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonUnionsOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes a string union value", + "result": { + "contents": { + "stringValue": "foo" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"contents\": {\n \"stringValue\": \"foo\"\n }\n}" + } + }, + { + "id": "AwsJson10DeserializeBooleanUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonUnionsOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes a boolean union value", + "result": { + "contents": { + "booleanValue": true + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"contents\": {\n \"booleanValue\": true\n }\n}" + } + }, + { + "id": "AwsJson10DeserializeNumberUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonUnionsOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes a number union value", + "result": { + "contents": { + "numberValue": 1 + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"contents\": {\n \"numberValue\": 1\n }\n}" + } + }, + { + "id": "AwsJson10DeserializeBlobUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonUnionsOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes a blob union value", + "result": { + "contents": { + "blobValue": "foo" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"contents\": {\n \"blobValue\": \"Zm9v\"\n }\n}" + } + }, + { + "id": "AwsJson10DeserializeTimestampUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonUnionsOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes a timestamp union value", + "result": { + "contents": { + "timestampValue": 1398796238 + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"contents\": {\n \"timestampValue\": 1398796238\n }\n}" + } + }, + { + "id": "AwsJson10DeserializeEnumUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonUnionsOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes an enum union value", + "result": { + "contents": { + "enumValue": "Foo" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"contents\": {\n \"enumValue\": \"Foo\"\n }\n}" + } + }, + { + "id": "AwsJson10DeserializeIntEnumUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonUnionsOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes an intEnum union value", + "result": { + "contents": { + "intEnumValue": 1 + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"contents\": {\n \"intEnumValue\": 1\n }\n}" + } + }, + { + "id": "AwsJson10DeserializeListUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonUnionsOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes a list union value", + "result": { + "contents": { + "listValue": [ + "foo", + "bar" + ] + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"contents\": {\n \"listValue\": [\"foo\", \"bar\"]\n }\n}" + } + }, + { + "id": "AwsJson10DeserializeMapUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonUnionsOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes a map union value", + "result": { + "contents": { + "mapValue": { + "foo": "bar", + "spam": "eggs" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"contents\": {\n \"mapValue\": {\n \"foo\": \"bar\",\n \"spam\": \"eggs\"\n }\n }\n}" + } + }, + { + "id": "AwsJson10DeserializeStructureUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonUnionsOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes a structure union value", + "result": { + "contents": { + "structureValue": { + "hi": "hello" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"contents\": {\n \"structureValue\": {\n \"hi\": \"hello\"\n }\n }\n}" + } + }, + { + "id": "AwsJson10DeserializeIgnoreType", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonUnionsOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Ignores an unrecognized __type property", + "result": { + "contents": { + "structureValue": { + "hi": "hello" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"contents\": {\n \"__type\": \"aws.protocoltests.json10#MyUnion\",\n \"structureValue\": {\n \"hi\": \"hello\"\n }\n }\n}" + } + }, + { + "id": "AwsJson10DeserializeAllowNulls", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonUnionsOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Allows for `: null` to be set for all unset fields", + "result": { + "contents": { + "structureValue": { + "hi": "hello" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"contents\": {\n \"stringValue\": null,\n \"booleanValue\": null,\n \"numberValue\": null,\n \"blobValue\": null,\n \"timestampValue\": null,\n \"enumValue\": null,\n \"intEnumValue\": null,\n \"listValue\": null,\n \"mapValue\": null,\n \"structureValue\": {\n \"hi\": \"hello\"\n }\n }\n}" + } + } + ] + }, + { + "description": "Test cases for NoInputAndNoOutput operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2020-07-14", + "jsonVersion": "1.0", + "targetPrefix": "JsonRpc10" + }, + "shapes": {}, + "cases": [ + { + "id": "AwsJson10HandlesEmptyOutputShape", + "given": { + "name": "NoInputAndNoOutput", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input or output. While this should be rare, code generators must support this.

" + }, + "description": "When no output is defined, the service is expected to return\nan empty payload, however, client must ignore a JSON payload\nif one is returned. This ensures that if output is added later,\nthen it will not break the client.", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{}" + } + }, + { + "id": "AwsJson10HandlesUnexpectedJsonOutput", + "given": { + "name": "NoInputAndNoOutput", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input or output. While this should be rare, code generators must support this.

" + }, + "description": "This client-only test builds on handles_empty_output_shape,\nby including unexpected fields in the JSON. A client\nneeds to ignore JSON output that is empty or that contains\nJSON object data.", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"foo\": true\n}" + } + }, + { + "id": "AwsJson10ServiceRespondsWithNoPayload", + "given": { + "name": "NoInputAndNoOutput", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input or output. While this should be rare, code generators must support this.

" + }, + "description": "When no output is defined, the service is expected to return\nan empty payload. Despite the lack of a payload, the service\nis expected to always send a Content-Type header. Clients must\nhandle cases where a service returns a JSON object and where\na service returns no JSON at all.", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "" + } + } + ] + }, + { + "description": "Test cases for NoInputAndOutput operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2020-07-14", + "jsonVersion": "1.0", + "targetPrefix": "JsonRpc10" + }, + "shapes": { + "NoInputAndOutputOutput": { + "type": "structure", + "members": {} + } + }, + "cases": [ + { + "id": "AwsJson10NoInputAndOutput", + "given": { + "name": "NoInputAndOutput", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "NoInputAndOutputOutput" + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input and the output is empty. While this should be rare, code generators must support this.

" + }, + "description": "Empty output always serializes an empty object payload.", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{}" + } + } + ] + }, + { + "description": "Test cases for SimpleScalarProperties operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2020-07-14", + "jsonVersion": "1.0", + "targetPrefix": "JsonRpc10" + }, + "shapes": { + "SimpleScalarPropertiesOutput": { + "type": "structure", + "members": { + "floatValue": { + "shape": "Float" + }, + "doubleValue": { + "shape": "Double" + } + } + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + } + }, + "cases": [ + { + "id": "AwsJson10SupportsNaNFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "SimpleScalarPropertiesOutput" + } + }, + "description": "Supports handling NaN float values.", + "result": { + "floatValue": "NaN", + "doubleValue": "NaN" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"floatValue\": \"NaN\",\n \"doubleValue\": \"NaN\"\n}" + } + }, + { + "id": "AwsJson10SupportsInfinityFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "SimpleScalarPropertiesOutput" + } + }, + "description": "Supports handling Infinity float values.", + "result": { + "floatValue": "Infinity", + "doubleValue": "Infinity" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"floatValue\": \"Infinity\",\n \"doubleValue\": \"Infinity\"\n}" + } + }, + { + "id": "AwsJson10SupportsNegativeInfinityFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "SimpleScalarPropertiesOutput" + } + }, + "description": "Supports handling -Infinity float values.", + "result": { + "floatValue": "-Infinity", + "doubleValue": "-Infinity" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"floatValue\": \"-Infinity\",\n \"doubleValue\": \"-Infinity\"\n}" + } + } + ] + } +] diff --git a/tests/unit/protocols/output/query.json b/tests/unit/protocols/output/query.json index 3faf5eb041..d492d0cf6e 100644 --- a/tests/unit/protocols/output/query.json +++ b/tests/unit/protocols/output/query.json @@ -1,931 +1,2375 @@ [ - { - "description": "Scalar members", - "metadata": { - "protocol": "query" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Str": { - "shape": "StringType" - }, - "Num": { - "shape": "IntegerType", - "locationName": "FooNum" - }, - "FalseBool": { - "shape": "BooleanType" - }, - "TrueBool": { - "shape": "BooleanType" - }, - "Float": { - "shape": "FloatType" - }, - "Double": { - "shape": "DoubleType" - }, - "Long": { - "shape": "LongType" - }, - "Char": { - "shape": "CharType" - }, - "Timestamp": { - "shape": "TimestampType" - } - } - }, - "StringType": { - "type": "string" - }, - "IntegerType": { - "type": "integer" - }, - "BooleanType": { - "type": "boolean" - }, - "FloatType": { - "type": "float" - }, - "DoubleType": { - "type": "double" - }, - "LongType": { - "type": "long" - }, - "CharType": { - "type": "character" - }, - "TimestampType": { - "type": "timestamp" - } - }, - "cases": [ - { - "given": { - "output": { - "resultWrapper": "OperationNameResult", - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Str": "myname", - "Num": 123, - "FalseBool": false, - "TrueBool": true, - "Float": 1.2, - "Double": 1.3, - "Long": 200, - "Char": "a", - "Timestamp": 1422172800 - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "myname123falsetrue1.21.3200a2015-01-25T08:00:00Zrequest-id" - } - } - ] - }, - { - "description": "Not all members in response", - "metadata": { - "protocol": "query" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Str": { - "shape": "StringType" - }, - "Num": { - "shape": "IntegerType" - } - } - }, - "StringType": { - "type": "string" - }, - "IntegerType": { - "type": "integer" - } - }, - "cases": [ - { - "given": { - "output": { - "resultWrapper": "OperationNameResult", - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Str": "myname" - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "mynamerequest-id" - } - } - ] - }, - { - "description": "Blob", - "metadata": { - "protocol": "query" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Blob": { - "shape": "BlobType" - } - } - }, - "BlobType": { - "type": "blob" - } - }, - "cases": [ - { - "given": { - "output": { - "resultWrapper": "OperationNameResult", - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Blob": "value" - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "dmFsdWU=requestid" - } - } - ] - }, - { - "description": "Lists", - "metadata": { - "protocol": "query" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "ListMember": { - "shape": "ListShape" - } - } - }, - "ListShape": { - "type": "list", - "member": { - "shape": "StringType" - } - }, - "StringType": { - "type": "string" - } - }, - "cases": [ - { - "given": { - "output": { - "resultWrapper": "OperationNameResult", - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "ListMember": ["abc", "123"] - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "abc123requestid" - } - } - ] - }, - { - "description": "List with custom member name", - "metadata": { - "protocol": "query" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "ListMember": { - "shape": "ListShape" - } - } - }, - "ListShape": { - "type": "list", - "member": { - "shape": "StringType", - "locationName": "item" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for DatetimeOffsets operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "DatetimeOffsetsOutput": { + "type": "structure", + "members": { + "datetime": { + "shape": "DateTime" + } + } + }, + "DateTime": { + "type": "timestamp", + "timestampFormat": "iso8601" + } + }, + "cases": [ + { + "id": "AwsQueryDateTimeWithNegativeOffset", + "given": { + "name": "DatetimeOffsets", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "DatetimeOffsetsOutput" + } + }, + "description": "Ensures that clients can correctly parse datetime (timestamps) with offsets", + "result": { + "datetime": 1576540098 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n 2019-12-16T22:48:18-01:00\n \n\n" + } + }, + { + "id": "AwsQueryDateTimeWithPositiveOffset", + "given": { + "name": "DatetimeOffsets", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "DatetimeOffsetsOutput" + } + }, + "description": "Ensures that clients can correctly parse datetime (timestamps) with offsets", + "result": { + "datetime": 1576540098 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n 2019-12-17T00:48:18+01:00\n \n\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "resultWrapper": "OperationNameResult", - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "ListMember": ["abc", "123"] - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "abc123requestid" - } - } - ] - }, - { - "description": "Flattened List", - "metadata": { - "protocol": "query" + { + "description": "Test cases for EmptyInputAndEmptyOutput operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "EmptyInputAndEmptyOutputOutput": { + "type": "structure", + "members": {} + } + }, + "cases": [ + { + "id": "QueryEmptyInputAndEmptyOutput", + "given": { + "name": "EmptyInputAndEmptyOutput", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "EmptyInputAndEmptyOutputOutput" + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response members.

While this should be rare, code generators must support this.

" + }, + "description": "Empty output", + "result": {}, + "response": { + "status_code": 200 + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "ListMember": { - "shape": "ListType" - } - } - }, - "ListType": { - "type": "list", - "flattened": true, - "member": { - "shape": "StringType" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for FlattenedXmlMap operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "FlattenedXmlMapOutput": { + "type": "structure", + "members": { + "myMap": { + "shape": "FooEnumMap", + "flattened": true + } + } + }, + "FooEnumMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "FooEnum" + } + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "QueryQueryFlattenedXmlMap", + "given": { + "name": "FlattenedXmlMap", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "FlattenedXmlMapOutput" + }, + "documentation": "

Flattened maps

" + }, + "description": "Serializes flattened XML maps in responses", + "result": { + "myMap": { + "foo": "Foo", + "baz": "Baz" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n \n foo\n Foo\n \n \n baz\n Baz\n \n \n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "resultWrapper": "OperationNameResult", - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "ListMember": ["abc", "123"] - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "abc123requestid" - } - } - ] - }, - { - "description": "Flattened single element list", - "metadata": { - "protocol": "query" + { + "description": "Test cases for FlattenedXmlMapWithXmlName operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "FlattenedXmlMapWithXmlNameOutput": { + "type": "structure", + "members": { + "myMap": { + "shape": "FlattenedXmlMapWithXmlNameOutputMap", + "flattened": true, + "locationName": "KVP" + } + } + }, + "FlattenedXmlMapWithXmlNameOutputMap": { + "type": "map", + "key": { + "shape": "String", + "locationName": "K" + }, + "value": { + "shape": "String", + "locationName": "V" + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "QueryQueryFlattenedXmlMapWithXmlName", + "given": { + "name": "FlattenedXmlMapWithXmlName", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "FlattenedXmlMapWithXmlNameOutput" + }, + "documentation": "

Flattened maps with @xmlName

" + }, + "description": "Serializes flattened XML maps in responses that have xmlName on members", + "result": { + "myMap": { + "a": "A", + "b": "B" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n \n a\n A\n \n \n b\n B\n \n \n" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "ListMember": { - "shape": "ListType" - } - } - }, - "ListType": { - "type": "list", - "flattened": true, - "member": { - "shape": "StringType" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for FlattenedXmlMapWithXmlNamespace operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "FlattenedXmlMapWithXmlNamespaceOutput": { + "type": "structure", + "members": { + "myMap": { + "shape": "FlattenedXmlMapWithXmlNamespaceOutputMap", + "flattened": true, + "locationName": "KVP", + "xmlNamespace": "https://the-member.example.com" + } + } + }, + "FlattenedXmlMapWithXmlNamespaceOutputMap": { + "type": "map", + "key": { + "shape": "String", + "locationName": "K", + "xmlNamespace": "https://the-key.example.com" + }, + "value": { + "shape": "String", + "locationName": "V", + "xmlNamespace": "https://the-value.example.com" + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "QueryQueryFlattenedXmlMapWithXmlNamespace", + "given": { + "name": "FlattenedXmlMapWithXmlNamespace", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "FlattenedXmlMapWithXmlNamespaceOutput" + }, + "documentation": "

Flattened maps with @xmlNamespace and @xmlName

" + }, + "description": "Serializes flattened XML maps in responses that have xmlNamespace and xmlName on members", + "result": { + "myMap": { + "a": "A", + "b": "B" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n \n a\n A\n \n \n b\n B\n \n \n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "resultWrapper": "OperationNameResult", - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "ListMember": ["abc"] - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "abcrequestid" - } - } - ] - }, - { - "description": "List of structures", - "metadata": { - "protocol": "query" + { + "description": "Test cases for FractionalSeconds operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "FractionalSecondsOutput": { + "type": "structure", + "members": { + "datetime": { + "shape": "DateTime" + } + } + }, + "DateTime": { + "type": "timestamp", + "timestampFormat": "iso8601" + } + }, + "cases": [ + { + "id": "AwsQueryDateTimeWithFractionalSeconds", + "given": { + "name": "FractionalSeconds", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "FractionalSecondsOutput" + } + }, + "description": "Ensures that clients can correctly parse datetime timestamps with fractional seconds", + "result": { + "datetime": 9.46845296123E8 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n 2000-01-02T20:34:56.123Z\n \n\n" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "List": { - "shape": "ListOfStructs" - } - } - }, - "ListOfStructs": { - "type": "list", - "member": { - "shape": "StructureShape" - } - }, - "StructureShape": { - "type": "structure", - "members": { - "Foo": { - "shape": "StringShape" - }, - "Bar": { - "shape": "StringShape" - }, - "Baz": { - "shape": "StringShape" - } - } - }, - "StringShape": { - "type": "string" - } + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "GreetingWithErrorsOutput": { + "type": "structure", + "members": { + "greeting": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "QueryGreetingWithErrors", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "GreetingWithErrorsOutput" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A BadRequest error.
" + }, + "description": "Ensures that operations with errors successfully know how to deserialize the successful response", + "result": { + "greeting": "Hello" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n Hello\n \n\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "resultWrapper": "OperationNameResult", - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "List": [{"Foo": "firstfoo", "Bar": "firstbar", "Baz": "firstbaz"}, {"Foo": "secondfoo", "Bar": "secondbar", "Baz": "secondbaz"}] - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "firstfoofirstbarfirstbazsecondfoosecondbarsecondbazrequestid" - } - } - ] - }, - { - "description": "Flattened list of structures", - "metadata": { - "protocol": "query" + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "InvalidGreeting": { + "type": "structure", + "members": { + "Message": { + "shape": "String" + } + }, + "documentation": "

This error is thrown when an invalid greeting value is provided.

", + "exception": true + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "QueryInvalidGreetingError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A BadRequest error.
", + "errors": [ + { + "shape": "InvalidGreeting" + } + ] + }, + "description": "Parses simple XML errors", + "errorCode": "InvalidGreeting", + "errorMessage": "Hi", + "error": { + "Message": "Hi" + }, + "response": { + "status_code": 400, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n Sender\n InvalidGreeting\n Hi\n \n foo-id\n\n" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "resultWrapper": "OperationNameResult", - "members": { - "List": { - "shape": "ListOfStructs" - } - } - }, - "ListOfStructs": { - "type": "list", - "flattened": true, - "member": { - "shape": "StructureShape" - } - }, - "StructureShape": { - "type": "structure", - "members": { - "Foo": { - "shape": "StringShape" - }, - "Bar": { - "shape": "StringShape" - }, - "Baz": { - "shape": "StringShape" - } - } - }, - "StringShape": { - "type": "string" - } + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "CustomCodeError": { + "type": "structure", + "members": { + "Message": { + "shape": "String" + } + }, + "error": { + "code": "Customized", + "httpStatusCode": 402, + "senderFault": true + }, + "exception": true + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "QueryCustomizedError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A BadRequest error.
", + "errors": [ + { + "shape": "CustomCodeError" + } + ] + }, + "description": "Parses customized XML errors", + "errorCode": "CustomCodeError", + "errorMessage": "Hi", + "error": { + "Message": "Hi" + }, + "response": { + "status_code": 402, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n Sender\n Customized\n Hi\n \n foo-id\n\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "List": [{"Foo": "firstfoo", "Bar": "firstbar", "Baz": "firstbaz"}, {"Foo": "secondfoo", "Bar": "secondbar", "Baz": "secondbaz"}] - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "firstfoofirstbarfirstbazsecondfoosecondbarsecondbazrequestid" - } - } - ] - }, - { - "description": "Flattened list with location name", - "metadata": { - "protocol": "query" + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "ComplexError": { + "type": "structure", + "members": { + "TopLevel": { + "shape": "String" + }, + "Nested": { + "shape": "ComplexNestedErrorData" + } + }, + "documentation": "

This error is thrown when a request is invalid.

", + "exception": true + }, + "String": { + "type": "string" + }, + "ComplexNestedErrorData": { + "type": "structure", + "members": { + "Foo": { + "shape": "String" + } + } + } + }, + "cases": [ + { + "id": "QueryComplexError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A BadRequest error.
", + "errors": [ + { + "shape": "ComplexError" + } + ] + }, + "errorCode": "ComplexError", + "error": { + "TopLevel": "Top level", + "Nested": { + "Foo": "bar" + } + }, + "response": { + "status_code": 400, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n Sender\n ComplexError\n Top level\n \n bar\n \n \n foo-id\n\n" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "List": { - "shape": "ListType" - } - } - }, - "ListType": { - "type": "list", - "flattened": true, - "member": { - "shape": "StringShape", - "locationName": "NamedList" - } - }, - "StringShape": { - "type": "string" - } + { + "description": "Test cases for IgnoresWrappingXmlName operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "IgnoresWrappingXmlNameOutput": { + "type": "structure", + "members": { + "foo": { + "shape": "String" + } + }, + "locationName": "IgnoreMe" + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "QueryIgnoresWrappingXmlName", + "given": { + "name": "IgnoresWrappingXmlName", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "IgnoresWrappingXmlNameOutput" + }, + "documentation": "

The xmlName trait on the output structure is ignored in AWS Query.

The wrapping element is always operation name + "Response", and inside of that wrapper is another wrapper named operation name + "Result".

" + }, + "description": "The xmlName trait on the output structure is ignored in AWS Query", + "result": { + "foo": "bar" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n bar\n \n\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "resultWrapper": "OperationNameResult", - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "List": ["a", "b"] - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "abrequestid" - } - } - ] - }, - { - "description": "Normal map", - "metadata": { - "protocol": "query" + { + "description": "Test cases for NoInputAndNoOutput operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": {}, + "cases": [ + { + "id": "QueryNoInputAndNoOutput", + "given": { + "name": "NoInputAndNoOutput", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input or output.

While this should be rare, code generators must support this.

" + }, + "description": "Empty output. Note that no assertion is made on the output body itself.", + "result": {}, + "response": { + "status_code": 200 + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Map": { - "shape": "StringMap" - } - } - }, - "StringMap": { - "type": "map", - "key": { - "shape": "StringType" - }, - "value": { - "shape": "StructType" - } - }, - "StringType": { - "type": "string" - }, - "StructType": { - "type": "structure", - "members": { - "foo": { - "shape": "StringType" - } - } - } + { + "description": "Test cases for NoInputAndOutput operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "NoInputAndOutputOutput": { + "type": "structure", + "members": {} + } + }, + "cases": [ + { + "id": "QueryNoInputAndOutput", + "given": { + "name": "NoInputAndOutput", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "NoInputAndOutputOutput" + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request payload or response members.

While this should be rare, code generators must support this.

" + }, + "description": "Empty output", + "result": {}, + "response": { + "status_code": 200 + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "resultWrapper": "OperationNameResult", - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Map": { - "qux": { - "foo": "bar" - }, - "baz": { - "foo": "bam" - } - } - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "quxbarbazbamrequestid" - } - } - ] - }, - { - "description": "Flattened map", - "metadata": { - "protocol": "query" + { + "description": "Test cases for RecursiveXmlShapes operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "RecursiveXmlShapesOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "RecursiveXmlShapesOutputNested1" + } + } + }, + "RecursiveXmlShapesOutputNested1": { + "type": "structure", + "members": { + "foo": { + "shape": "String" + }, + "nested": { + "shape": "RecursiveXmlShapesOutputNested2" + } + } + }, + "String": { + "type": "string" + }, + "RecursiveXmlShapesOutputNested2": { + "type": "structure", + "members": { + "bar": { + "shape": "String" + }, + "recursiveMember": { + "shape": "RecursiveXmlShapesOutputNested1" + } + } + } + }, + "cases": [ + { + "id": "QueryRecursiveShapes", + "given": { + "name": "RecursiveXmlShapes", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "RecursiveXmlShapesOutput" + }, + "documentation": "

Recursive shapes

" + }, + "description": "Serializes recursive structures", + "result": { + "nested": { + "foo": "Foo1", + "nested": { + "bar": "Bar1", + "recursiveMember": { + "foo": "Foo2", + "nested": { + "bar": "Bar2" + } + } + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n \n Foo1\n \n Bar1\n \n Foo2\n \n Bar2\n \n \n \n \n \n\n" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Map": { - "shape": "StringMap", - "flattened": true - } - } - }, - "StringMap": { - "type": "map", - "key": { - "shape": "StringType" - }, - "value": { - "shape": "StringType" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for SimpleScalarXmlProperties operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "SimpleScalarXmlPropertiesOutput": { + "type": "structure", + "members": { + "stringValue": { + "shape": "String" + }, + "emptyStringValue": { + "shape": "String" + }, + "trueBooleanValue": { + "shape": "Boolean" + }, + "falseBooleanValue": { + "shape": "Boolean" + }, + "byteValue": { + "shape": "Integer" + }, + "shortValue": { + "shape": "Integer" + }, + "integerValue": { + "shape": "Integer" + }, + "longValue": { + "shape": "Long" + }, + "floatValue": { + "shape": "Float" + }, + "doubleValue": { + "shape": "Double", + "locationName": "DoubleDribble" + } + } + }, + "String": { + "type": "string" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + }, + "Long": { + "type": "long", + "box": true + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + } + }, + "cases": [ + { + "id": "QuerySimpleScalarProperties", + "given": { + "name": "SimpleScalarXmlProperties", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "SimpleScalarXmlPropertiesOutput" + } + }, + "description": "Serializes simple scalar properties", + "result": { + "stringValue": "string", + "emptyStringValue": "", + "trueBooleanValue": true, + "falseBooleanValue": false, + "byteValue": 1, + "shortValue": 2, + "integerValue": 3, + "longValue": 4, + "floatValue": 5.5, + "doubleValue": 6.5 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n string\n \n true\n false\n 1\n 2\n 3\n 4\n 5.5\n 6.5\n \n\n" + } + }, + { + "id": "AwsQuerySupportsNaNFloatOutputs", + "given": { + "name": "SimpleScalarXmlProperties", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "SimpleScalarXmlPropertiesOutput" + } + }, + "description": "Supports handling NaN float values.", + "result": { + "floatValue": "NaN", + "doubleValue": "NaN" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n NaN\n NaN\n \n\n" + } + }, + { + "id": "AwsQuerySupportsInfinityFloatOutputs", + "given": { + "name": "SimpleScalarXmlProperties", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "SimpleScalarXmlPropertiesOutput" + } + }, + "description": "Supports handling Infinity float values.", + "result": { + "floatValue": "Infinity", + "doubleValue": "Infinity" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n Infinity\n Infinity\n \n\n" + } + }, + { + "id": "AwsQuerySupportsNegativeInfinityFloatOutputs", + "given": { + "name": "SimpleScalarXmlProperties", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "SimpleScalarXmlPropertiesOutput" + } + }, + "description": "Supports handling -Infinity float values.", + "result": { + "floatValue": "-Infinity", + "doubleValue": "-Infinity" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n -Infinity\n -Infinity\n \n\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "resultWrapper": "OperationNameResult", - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Map": { - "qux": "bar", - "baz": "bam" - } - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "quxbarbazbamrequestid" - } - } - ] - }, - { - "description": "Flattened map in shape definition", - "metadata": { - "protocol": "query" + { + "description": "Test cases for XmlBlobs operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "XmlBlobsOutput": { + "type": "structure", + "members": { + "data": { + "shape": "Blob" + } + } + }, + "Blob": { + "type": "blob" + } + }, + "cases": [ + { + "id": "QueryXmlBlobs", + "given": { + "name": "XmlBlobs", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlBlobsOutput" + }, + "documentation": "

Blobs are base64 encoded

" + }, + "description": "Blobs are base64 encoded", + "result": { + "data": "value" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n dmFsdWU=\n \n\n" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Map": { - "shape": "StringMap", - "locationName": "Attribute" - } - } - }, - "StringMap": { - "type": "map", - "key": { - "shape": "StringType", - "locationName": "Name" - }, - "value": { - "shape": "StringType", - "locationName": "Value" - }, - "flattened": true, - "locationName": "Attribute" - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for XmlEmptyBlobs operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "XmlBlobsOutput": { + "type": "structure", + "members": { + "data": { + "shape": "Blob" + } + } + }, + "Blob": { + "type": "blob" + } + }, + "cases": [ + { + "id": "QueryXmlEmptyBlobs", + "given": { + "name": "XmlEmptyBlobs", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlBlobsOutput" + } + }, + "description": "Empty blobs are deserialized as empty string", + "result": { + "data": "" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n \n \n\n" + } + }, + { + "id": "QueryXmlEmptySelfClosedBlobs", + "given": { + "name": "XmlEmptyBlobs", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlBlobsOutput" + } + }, + "description": "Empty self closed blobs are deserialized as empty string", + "result": { + "data": "" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n \n \n\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "resultWrapper": "OperationNameResult", - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Map": { - "qux": "bar" - } - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "quxbarrequestid" - } - } - ] - }, - { - "description": "Named map", - "metadata": { - "protocol": "query" + { + "description": "Test cases for XmlEmptyLists operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "XmlListsOutput": { + "type": "structure", + "members": { + "stringList": { + "shape": "StringList" + }, + "stringSet": { + "shape": "StringSet" + }, + "integerList": { + "shape": "IntegerList" + }, + "booleanList": { + "shape": "BooleanList" + }, + "timestampList": { + "shape": "TimestampList" + }, + "enumList": { + "shape": "FooEnumList" + }, + "intEnumList": { + "shape": "IntegerEnumList" + }, + "nestedStringList": { + "shape": "NestedStringList" + }, + "renamedListMembers": { + "shape": "RenamedListMembers", + "locationName": "renamed" + }, + "flattenedList": { + "shape": "RenamedListMembers", + "flattened": true + }, + "flattenedList2": { + "shape": "RenamedListMembers", + "flattened": true, + "locationName": "customName" + }, + "flattenedListWithMemberNamespace": { + "shape": "ListWithMemberNamespace", + "flattened": true + }, + "flattenedListWithNamespace": { + "shape": "ListWithNamespace", + "flattened": true + }, + "structureList": { + "shape": "StructureList", + "locationName": "myStructureList" + } + } + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringSet": { + "type": "list", + "member": { + "shape": "String" + } + }, + "IntegerList": { + "type": "list", + "member": { + "shape": "Integer" + } + }, + "BooleanList": { + "type": "list", + "member": { + "shape": "Boolean" + } + }, + "TimestampList": { + "type": "list", + "member": { + "shape": "Timestamp" + } + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "IntegerEnumList": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "NestedStringList": { + "type": "list", + "member": { + "shape": "StringList" + }, + "documentation": "

A list of lists of strings.

" + }, + "RenamedListMembers": { + "type": "list", + "member": { + "shape": "String", + "locationName": "item" + } + }, + "ListWithMemberNamespace": { + "type": "list", + "member": { + "shape": "String", + "xmlNamespace": "https://xml-member.example.com" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "ListWithNamespace": { + "type": "list", + "member": { + "shape": "String" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "StructureList": { + "type": "list", + "member": { + "shape": "StructureListMember", + "locationName": "item" + } + }, + "StructureListMember": { + "type": "structure", + "members": { + "a": { + "shape": "String", + "locationName": "value" + }, + "b": { + "shape": "String", + "locationName": "other" + } + } + }, + "String": { + "type": "string" + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "Timestamp": { + "type": "timestamp" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + } + }, + "cases": [ + { + "id": "QueryXmlEmptyLists", + "given": { + "name": "XmlEmptyLists", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlListsOutput" + } + }, + "description": "Deserializes empty XML lists", + "result": { + "stringList": [], + "stringSet": [] + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n \n \n \n\n" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Map": { - "shape": "MapType" - } - } - }, - "MapType": { - "type": "map", - "flattened": true, - "key": { - "locationName": "foo", - "shape": "StringType" - }, - "value": { - "locationName": "bar", - "shape": "StringType" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for XmlEmptyMaps operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "XmlMapsOutput": { + "type": "structure", + "members": { + "myMap": { + "shape": "XmlMapsOutputMap" + } + } + }, + "XmlMapsOutputMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "GreetingStruct" + } + }, + "GreetingStruct": { + "type": "structure", + "members": { + "hi": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "QueryXmlEmptyMaps", + "given": { + "name": "XmlEmptyMaps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlMapsOutput" + } + }, + "description": "Deserializes Empty XML maps", + "result": { + "myMap": {} + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n \n \n \n\n" + } + }, + { + "id": "QueryXmlEmptySelfClosedMaps", + "given": { + "name": "XmlEmptyMaps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlMapsOutput" + } + }, + "description": "Deserializes Self-Closed XML maps", + "result": { + "myMap": {} + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n \n \n\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "resultWrapper": "OperationNameResult", - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Map": { - "qux": "bar", - "baz": "bam" - } - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "quxbarbazbamrequestid" - } - } - ] - }, - { - "description": "Empty string", - "metadata": { - "protocol": "query" + { + "description": "Test cases for XmlEnums operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "XmlEnumsOutput": { + "type": "structure", + "members": { + "fooEnum1": { + "shape": "FooEnum" + }, + "fooEnum2": { + "shape": "FooEnum" + }, + "fooEnum3": { + "shape": "FooEnum" + }, + "fooEnumList": { + "shape": "FooEnumList" + }, + "fooEnumSet": { + "shape": "FooEnumSet" + }, + "fooEnumMap": { + "shape": "FooEnumMap" + } + } + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "FooEnumSet": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "FooEnumMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "FooEnum" + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "QueryXmlEnums", + "given": { + "name": "XmlEnums", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlEnumsOutput" + }, + "documentation": "

This example serializes enums as top level properties, in lists, sets, and maps.

" + }, + "description": "Serializes simple scalar properties", + "result": { + "fooEnum1": "Foo", + "fooEnum2": "0", + "fooEnum3": "1", + "fooEnumList": [ + "Foo", + "0" + ], + "fooEnumSet": [ + "Foo", + "0" + ], + "fooEnumMap": { + "hi": "Foo", + "zero": "0" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n Foo\n 0\n 1\n \n Foo\n 0\n \n \n Foo\n 0\n \n \n \n hi\n Foo\n \n \n zero\n 0\n \n \n \n\n" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Foo": { - "shape": "StringType" - } - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for XmlIntEnums operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "XmlIntEnumsOutput": { + "type": "structure", + "members": { + "intEnum1": { + "shape": "IntegerEnum" + }, + "intEnum2": { + "shape": "IntegerEnum" + }, + "intEnum3": { + "shape": "IntegerEnum" + }, + "intEnumList": { + "shape": "IntegerEnumList" + }, + "intEnumSet": { + "shape": "IntegerEnumSet" + }, + "intEnumMap": { + "shape": "IntegerEnumMap" + } + } + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "IntegerEnumList": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "IntegerEnumSet": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "IntegerEnumMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "IntegerEnum" + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "QueryXmlIntEnums", + "given": { + "name": "XmlIntEnums", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlIntEnumsOutput" + }, + "documentation": "

This example serializes enums as top level properties, in lists, sets, and maps.

" + }, + "description": "Serializes simple scalar properties", + "result": { + "intEnum1": 1, + "intEnum2": 2, + "intEnum3": 3, + "intEnumList": [ + 1, + 2 + ], + "intEnumSet": [ + 1, + 2 + ], + "intEnumMap": { + "a": 1, + "b": 2 + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n 1\n 2\n 3\n \n 1\n 2\n \n \n 1\n 2\n \n \n \n a\n 1\n \n \n b\n 2\n \n \n \n\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "resultWrapper": "OperationNameResult", - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Foo": "" - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "requestid" - } - } - ] - }, - { - "description": "Timestamp members", - "metadata": { - "protocol": "query" + { + "description": "Test cases for XmlLists operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "XmlListsOutput": { + "type": "structure", + "members": { + "stringList": { + "shape": "StringList" + }, + "stringSet": { + "shape": "StringSet" + }, + "integerList": { + "shape": "IntegerList" + }, + "booleanList": { + "shape": "BooleanList" + }, + "timestampList": { + "shape": "TimestampList" + }, + "enumList": { + "shape": "FooEnumList" + }, + "intEnumList": { + "shape": "IntegerEnumList" + }, + "nestedStringList": { + "shape": "NestedStringList" + }, + "renamedListMembers": { + "shape": "RenamedListMembers", + "locationName": "renamed" + }, + "flattenedList": { + "shape": "RenamedListMembers", + "flattened": true + }, + "flattenedList2": { + "shape": "RenamedListMembers", + "flattened": true, + "locationName": "customName" + }, + "flattenedListWithMemberNamespace": { + "shape": "ListWithMemberNamespace", + "flattened": true + }, + "flattenedListWithNamespace": { + "shape": "ListWithNamespace", + "flattened": true + }, + "structureList": { + "shape": "StructureList", + "locationName": "myStructureList" + } + } + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringSet": { + "type": "list", + "member": { + "shape": "String" + } + }, + "IntegerList": { + "type": "list", + "member": { + "shape": "Integer" + } + }, + "BooleanList": { + "type": "list", + "member": { + "shape": "Boolean" + } + }, + "TimestampList": { + "type": "list", + "member": { + "shape": "Timestamp" + } + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "IntegerEnumList": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "NestedStringList": { + "type": "list", + "member": { + "shape": "StringList" + }, + "documentation": "

A list of lists of strings.

" + }, + "RenamedListMembers": { + "type": "list", + "member": { + "shape": "String", + "locationName": "item" + } + }, + "ListWithMemberNamespace": { + "type": "list", + "member": { + "shape": "String", + "xmlNamespace": "https://xml-member.example.com" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "ListWithNamespace": { + "type": "list", + "member": { + "shape": "String" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "StructureList": { + "type": "list", + "member": { + "shape": "StructureListMember", + "locationName": "item" + } + }, + "StructureListMember": { + "type": "structure", + "members": { + "a": { + "shape": "String", + "locationName": "value" + }, + "b": { + "shape": "String", + "locationName": "other" + } + } + }, + "String": { + "type": "string" + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "Timestamp": { + "type": "timestamp" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + } + }, + "cases": [ + { + "id": "QueryXmlLists", + "given": { + "name": "XmlLists", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlListsOutput" + }, + "documentation": "

This test case serializes XML lists for the following cases for both input and output:

  1. Normal XML lists.
  2. Normal XML sets.
  3. XML lists of lists.
  4. XML lists with @xmlName on its members
  5. Flattened XML lists.
  6. Flattened XML lists with @xmlName.
  7. Lists of structures.
" + }, + "description": "Tests for XML list serialization", + "result": { + "stringList": [ + "foo", + "bar" + ], + "stringSet": [ + "foo", + "bar" + ], + "integerList": [ + 1, + 2 + ], + "booleanList": [ + true, + false + ], + "timestampList": [ + 1398796238, + 1398796238 + ], + "enumList": [ + "Foo", + "0" + ], + "intEnumList": [ + 1, + 2 + ], + "nestedStringList": [ + [ + "foo", + "bar" + ], + [ + "baz", + "qux" + ] + ], + "renamedListMembers": [ + "foo", + "bar" + ], + "flattenedList": [ + "hi", + "bye" + ], + "flattenedList2": [ + "yep", + "nope" + ], + "flattenedListWithMemberNamespace": [ + "a", + "b" + ], + "flattenedListWithNamespace": [ + "a", + "b" + ], + "structureList": [ + { + "a": "1", + "b": "2" + }, + { + "a": "3", + "b": "4" + } + ] + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n \n foo\n bar\n \n \n foo\n bar\n \n \n 1\n 2\n \n \n true\n false\n \n \n 2014-04-29T18:30:38Z\n 2014-04-29T18:30:38Z\n \n \n Foo\n 0\n \n \n 1\n 2\n \n \n \n foo\n bar\n \n \n baz\n qux\n \n \n \n foo\n bar\n \n hi\n bye\n yep\n nope\n a\n b\n a\n b\n \n \n 1\n 2\n \n \n 3\n 4\n \n \n \n\n" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "TimeArg": { - "shape": "TimestampType" - }, - "TimeCustom": { - "timestampFormat": "rfc822", - "shape": "TimestampType" - }, - "TimeFormat": { - "shape": "TimestampFormatType" - }, - "StructMember": { - "shape": "TimeContainer" - } - } - }, - "TimeContainer": { - "type": "structure", - "members": { - "foo": { - "shape": "TimestampType" - }, - "bar": { - "shape": "TimestampFormatType" - } - } - }, - "TimestampFormatType": { - "timestampFormat": "unixTimestamp", - "type": "timestamp" - }, - "TimestampType": { - "type": "timestamp" - } + { + "description": "Test cases for XmlMaps operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "XmlMapsOutput": { + "type": "structure", + "members": { + "myMap": { + "shape": "XmlMapsOutputMap" + } + } + }, + "XmlMapsOutputMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "GreetingStruct" + } + }, + "GreetingStruct": { + "type": "structure", + "members": { + "hi": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "QueryXmlMaps", + "given": { + "name": "XmlMaps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlMapsOutput" + }, + "documentation": "

The example tests basic map serialization.

" + }, + "description": "Tests for XML map serialization", + "result": { + "myMap": { + "foo": { + "hi": "there" + }, + "baz": { + "hi": "bye" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n \n \n foo\n \n there\n \n \n \n baz\n \n bye\n \n \n \n \n\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "TimeArg": 1398796238, - "TimeCustom": 1398796238, - "TimeFormat": 1398796238, - "StructMember": { - "foo": 1398796238, - "bar": 1398796238 - } - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "2014-04-29T18:30:38+00:0013987962382014-04-29T18:30:38+00:00Tue, 29 Apr 2014 18:30:38 GMT1398796238requestid" - } - } - ] - }, - { - "description": "Modeled exceptions", - "metadata": { - "protocol": "query" + { + "description": "Test cases for XmlMapsXmlName operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "XmlMapsXmlNameOutput": { + "type": "structure", + "members": { + "myMap": { + "shape": "XmlMapsXmlNameOutputMap" + } + } + }, + "XmlMapsXmlNameOutputMap": { + "type": "map", + "key": { + "shape": "String", + "locationName": "Attribute" + }, + "value": { + "shape": "GreetingStruct", + "locationName": "Setting" + } + }, + "GreetingStruct": { + "type": "structure", + "members": { + "hi": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "QueryQueryXmlMapsXmlName", + "given": { + "name": "XmlMapsXmlName", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlMapsXmlNameOutput" + } + }, + "description": "Serializes XML lists", + "result": { + "myMap": { + "foo": { + "hi": "there" + }, + "baz": { + "hi": "bye" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n \n \n foo\n \n there\n \n \n \n baz\n \n bye\n \n \n \n \n\n" + } + } + ] }, - "shapes": { - "ExceptionShape": { - "exception": true, - "type": "structure", - "members": { - "BodyMember": { - "shape": "StringType" - }, - "Message": { - "shape": "StringType" - } - } - }, - "OtherExceptionShape": { - "exception": true, - "type": "structure", - "members": { - "BodyMember": { - "shape": "StringType" - } - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for XmlNamespaces operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "XmlNamespacesOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "XmlNamespaceNested" + } + }, + "xmlNamespace": "http://foo.com" + }, + "XmlNamespaceNested": { + "type": "structure", + "members": { + "foo": { + "shape": "String", + "xmlNamespace": { + "prefix": "baz", + "uri": "http://baz.com" + } + }, + "values": { + "shape": "XmlNamespacedList", + "xmlNamespace": "http://qux.com" + } + }, + "xmlNamespace": "http://boo.com" + }, + "String": { + "type": "string" + }, + "XmlNamespacedList": { + "type": "list", + "member": { + "shape": "String", + "xmlNamespace": "http://bux.com" + } + } + }, + "cases": [ + { + "id": "QueryXmlNamespaces", + "given": { + "name": "XmlNamespaces", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlNamespacesOutput" + } + }, + "description": "Serializes XML namespaces", + "result": { + "nested": { + "foo": "Foo", + "values": [ + "Bar", + "Baz" + ] + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n \n Foo\n \n Bar\n Baz\n \n \n \n\n" + } + } + ] }, - "cases": [ - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" - }, - "error": { - "BodyMember": "mybody", - "Message": "mymessage" - }, - "errorCode": "ExceptionShape", - "errorMessage": "mymessage", - "response": { - "status_code": 400, - "headers": {}, - "body": "SomeTypeExceptionShapemymessagemybody" - } - }, - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" - }, - "error": { - "BodyMember": "mybody" - }, - "errorCode": "OtherExceptionShape", - "errorMessage": "mymessage", - "response": { - "status_code": 400, - "headers": {}, - "body": "SomeTypeOtherExceptionShapemymessagemybody" - } - }, - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" - }, - "error": {}, - "errorCode": "UndefinedShape", - "errorMessage": "mymessage", - "response": { - "status_code": 400, - "headers": {}, - "body": "SomeTypeUndefinedShapemymessagemybody" - } - } - ] - } + { + "description": "Test cases for XmlTimestamps operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "XmlTimestampsOutput": { + "type": "structure", + "members": { + "normal": { + "shape": "Timestamp" + }, + "dateTime": { + "shape": "SyntheticTimestamp_date_time" + }, + "dateTimeOnTarget": { + "shape": "DateTime" + }, + "epochSeconds": { + "shape": "SyntheticTimestamp_epoch_seconds" + }, + "epochSecondsOnTarget": { + "shape": "EpochSeconds" + }, + "httpDate": { + "shape": "SyntheticTimestamp_http_date" + }, + "httpDateOnTarget": { + "shape": "HttpDate" + } + } + }, + "Timestamp": { + "type": "timestamp" + }, + "SyntheticTimestamp_date_time": { + "type": "timestamp", + "timestampFormat": "iso8601" + }, + "DateTime": { + "type": "timestamp", + "timestampFormat": "iso8601" + }, + "SyntheticTimestamp_epoch_seconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "EpochSeconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "SyntheticTimestamp_http_date": { + "type": "timestamp", + "timestampFormat": "rfc822" + }, + "HttpDate": { + "type": "timestamp", + "timestampFormat": "rfc822" + } + }, + "cases": [ + { + "id": "QueryXmlTimestamps", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlTimestampsOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Tests how normal timestamps are serialized", + "result": { + "normal": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n 2014-04-29T18:30:38Z\n \n\n" + } + }, + { + "id": "QueryXmlTimestampsWithDateTimeFormat", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlTimestampsOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of date-time works like normal timestamps", + "result": { + "dateTime": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n 2014-04-29T18:30:38Z\n \n\n" + } + }, + { + "id": "QueryXmlTimestampsWithDateTimeOnTargetFormat", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlTimestampsOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of date-time on the target shape works like normal timestamps", + "result": { + "dateTimeOnTarget": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n 2014-04-29T18:30:38Z\n \n\n" + } + }, + { + "id": "QueryXmlTimestampsWithEpochSecondsFormat", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlTimestampsOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of epoch-seconds works", + "result": { + "epochSeconds": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n 1398796238\n \n\n" + } + }, + { + "id": "QueryXmlTimestampsWithEpochSecondsOnTargetFormat", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlTimestampsOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of epoch-seconds on the target shape works", + "result": { + "epochSecondsOnTarget": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n 1398796238\n \n\n" + } + }, + { + "id": "QueryXmlTimestampsWithHttpDateFormat", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlTimestampsOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of http-date works", + "result": { + "httpDate": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n Tue, 29 Apr 2014 18:30:38 GMT\n \n\n" + } + }, + { + "id": "QueryXmlTimestampsWithHttpDateOnTargetFormat", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlTimestampsOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of http-date on the target shape works", + "result": { + "httpDateOnTarget": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "\n \n Tue, 29 Apr 2014 18:30:38 GMT\n \n\n" + } + } + ] + } ] diff --git a/tests/unit/protocols/output/rest-json.json b/tests/unit/protocols/output/rest-json.json index c6bd958b92..cac62dd5e1 100644 --- a/tests/unit/protocols/output/rest-json.json +++ b/tests/unit/protocols/output/rest-json.json @@ -1,1312 +1,4317 @@ [ - { - "description": "Scalar members", - "metadata": { - "protocol": "rest-json" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "ImaHeader": { - "shape": "HeaderShape" - }, - "ImaHeaderLocation": { - "shape": "HeaderShape", - "locationName": "X-Foo" - }, - "Status": { - "shape": "StatusShape", - "location": "statusCode" - }, - "Str": { - "shape": "StringType" - }, - "Num": { - "shape": "IntegerType" - }, - "FalseBool": { - "shape": "BooleanType" - }, - "TrueBool": { - "shape": "BooleanType" - }, - "Float": { - "shape": "FloatType" - }, - "Double": { - "shape": "DoubleType" - }, - "Long": { - "shape": "LongType" - }, - "Char": { - "shape": "CharType" - } - } - }, - "HeaderShape": { - "type": "string", - "location": "header" - }, - "StatusShape": { - "type": "integer" - }, - "StringType": { - "type": "string" - }, - "IntegerType": { - "type": "integer" - }, - "BooleanType": { - "type": "boolean" - }, - "FloatType": { - "type": "float" - }, - "DoubleType": { - "type": "double" - }, - "LongType": { - "type": "long" - }, - "CharType": { - "type": "character" - } - }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "ImaHeader": "test", - "ImaHeaderLocation": "abc", - "Status": 200, - "Str": "myname", - "Num": 123, - "FalseBool": false, - "TrueBool": true, - "Float": 1.2, - "Double": 1.3, - "Long": 200, - "Char": "a" - }, - "response": { - "status_code": 200, - "headers": { - "ImaHeader": "test", - "X-Foo": "abc" - }, - "body": "{\"Str\": \"myname\", \"Num\": 123, \"FalseBool\": false, \"TrueBool\": true, \"Float\": 1.2, \"Double\": 1.3, \"Long\": 200, \"Char\": \"a\"}" - } - } - ] - }, - { - "description": "Blob members", - "metadata": { - "protocol": "rest-json" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "BlobMember": { - "shape": "BlobType" - }, - "StructMember": { - "shape": "BlobContainer" - } - } - }, - "BlobType": { - "type": "blob" - }, - "BlobContainer": { - "type": "structure", - "members": { - "foo": { - "shape": "BlobType" - } - } - } - }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "BlobMember": "hi!", - "StructMember": { - "foo": "there!" - } - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"BlobMember\": \"aGkh\", \"StructMember\": {\"foo\": \"dGhlcmUh\"}}" - } - } - ] - }, - { - "description": "Timestamp members", - "metadata": { - "protocol": "rest-json" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "TimeArg": { - "shape": "TimestampType" - }, - "TimeArgInHeader": { - "shape": "TimestampType", - "location": "header", - "locationName": "x-amz-timearg" - }, - "TimeCustom": { - "timestampFormat": "rfc822", - "shape": "TimestampType" - }, - "TimeCustomInHeader": { - "timestampFormat": "unixTimestamp", - "shape": "TimestampType", - "location": "header", - "locationName": "x-amz-timecustom" - }, - "TimeFormat": { - "shape": "TimestampFormatType" - }, - "TimeFormatInHeader": { - "shape": "TimestampFormatType", - "location": "header", - "locationName": "x-amz-timeformat" - }, - "StructMember": { - "shape": "TimeContainer" - } - } - }, - "TimeContainer": { - "type": "structure", - "members": { - "foo": { - "shape": "TimestampType" - }, - "bar": { - "shape": "TimestampFormatType" - } - } - }, - "TimestampFormatType": { - "timestampFormat": "iso8601", - "type": "timestamp" - }, - "TimestampType": { - "type": "timestamp" - } + { + "description": "Test cases for DatetimeOffsets operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "DatetimeOffsetsOutput": { + "type": "structure", + "members": { + "datetime": { + "shape": "DateTime" + } + } + }, + "DateTime": { + "type": "timestamp", + "timestampFormat": "iso8601" + } + }, + "cases": [ + { + "id": "RestJsonDateTimeWithNegativeOffset", + "given": { + "name": "DatetimeOffsets", + "http": { + "method": "POST", + "requestUri": "/DatetimeOffsets", + "responseCode": 200 + }, + "output": { + "shape": "DatetimeOffsetsOutput" + } + }, + "description": "Ensures that clients can correctly parse datetime (timestamps) with offsets", + "result": { + "datetime": 1576540098 + }, + "response": { + "status_code": 200, + "body": " {\n \"datetime\": \"2019-12-16T22:48:18-01:00\"\n }\n" + } + }, + { + "id": "RestJsonDateTimeWithPositiveOffset", + "given": { + "name": "DatetimeOffsets", + "http": { + "method": "POST", + "requestUri": "/DatetimeOffsets", + "responseCode": 200 + }, + "output": { + "shape": "DatetimeOffsetsOutput" + } + }, + "description": "Ensures that clients can correctly parse datetime (timestamps) with offsets", + "result": { + "datetime": 1576540098 + }, + "response": { + "status_code": 200, + "body": " {\n \"datetime\": \"2019-12-17T00:48:18+01:00\"\n }\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "TimeArg": 1398796238, - "TimeArgInHeader": 1398796238, - "TimeCustom": 1398796238, - "TimeCustomInHeader": 1398796238, - "TimeFormat": 1398796238, - "TimeFormatInHeader": 1398796238, - "StructMember": { - "foo": 1398796238, - "bar": 1398796238 - } - }, - "response": { - "status_code": 200, - "headers": { - "x-amz-timearg": "Tue, 29 Apr 2014 18:30:38 GMT", - "x-amz-timecustom": "1398796238", - "x-amz-timeformat": "2014-04-29T18:30:38+00:00" - }, - "body": "{\"TimeArg\": 1398796238, \"TimeCustom\": \"Tue, 29 Apr 2014 18:30:38 GMT\", \"TimeFormat\": \"2014-04-29T18:30:38+00:00\", \"StructMember\": {\"foo\": 1398796238, \"bar\": \"2014-04-29T18:30:38+00:00\"}}" - } - } - ] - }, - { - "description": "Lists", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for DocumentType operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "DocumentTypeInputOutput": { + "type": "structure", + "members": { + "stringValue": { + "shape": "String" + }, + "documentValue": { + "shape": "Document" + } + } + }, + "String": { + "type": "string" + }, + "Document": { + "type": "structure", + "members": {}, + "document": true + } + }, + "cases": [ + { + "id": "DocumentOutput", + "given": { + "name": "DocumentType", + "http": { + "method": "PUT", + "requestUri": "/DocumentType", + "responseCode": 200 + }, + "output": { + "shape": "DocumentTypeInputOutput" + }, + "documentation": "

This example serializes a document as part of the payload.

", + "idempotent": true + }, + "description": "Serializes documents as part of the JSON response payload with no escaping.", + "result": { + "stringValue": "string", + "documentValue": { + "foo": "bar" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"stringValue\": \"string\",\n \"documentValue\": {\n \"foo\": \"bar\"\n }\n}" + } + }, + { + "id": "DocumentOutputString", + "given": { + "name": "DocumentType", + "http": { + "method": "PUT", + "requestUri": "/DocumentType", + "responseCode": 200 + }, + "output": { + "shape": "DocumentTypeInputOutput" + }, + "documentation": "

This example serializes a document as part of the payload.

", + "idempotent": true + }, + "description": "Document types can be JSON scalars too.", + "result": { + "stringValue": "string", + "documentValue": "hello" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"stringValue\": \"string\",\n \"documentValue\": \"hello\"\n}" + } + }, + { + "id": "DocumentOutputNumber", + "given": { + "name": "DocumentType", + "http": { + "method": "PUT", + "requestUri": "/DocumentType", + "responseCode": 200 + }, + "output": { + "shape": "DocumentTypeInputOutput" + }, + "documentation": "

This example serializes a document as part of the payload.

", + "idempotent": true + }, + "description": "Document types can be JSON scalars too.", + "result": { + "stringValue": "string", + "documentValue": 10 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"stringValue\": \"string\",\n \"documentValue\": 10\n}" + } + }, + { + "id": "DocumentOutputBoolean", + "given": { + "name": "DocumentType", + "http": { + "method": "PUT", + "requestUri": "/DocumentType", + "responseCode": 200 + }, + "output": { + "shape": "DocumentTypeInputOutput" + }, + "documentation": "

This example serializes a document as part of the payload.

", + "idempotent": true + }, + "description": "Document types can be JSON scalars too.", + "result": { + "stringValue": "string", + "documentValue": false + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"stringValue\": \"string\",\n \"documentValue\": false\n}" + } + }, + { + "id": "DocumentOutputArray", + "given": { + "name": "DocumentType", + "http": { + "method": "PUT", + "requestUri": "/DocumentType", + "responseCode": 200 + }, + "output": { + "shape": "DocumentTypeInputOutput" + }, + "documentation": "

This example serializes a document as part of the payload.

", + "idempotent": true + }, + "description": "Document types can be JSON arrays.", + "result": { + "stringValue": "string", + "documentValue": [ + true, + false + ] + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"stringValue\": \"string\",\n \"documentValue\": [\n true,\n false\n ]\n}" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "ListMember": { - "shape": "ListType" - } - } - }, - "ListType": { - "type": "list", - "member": { - "shape": "StringType" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for DocumentTypeAsMapValue operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "DocumentTypeAsMapValueInputOutput": { + "type": "structure", + "members": { + "docValuedMap": { + "shape": "DocumentValuedMap" + } + } + }, + "DocumentValuedMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "Document" + } + }, + "Document": { + "type": "structure", + "members": {}, + "document": true + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "DocumentTypeAsMapValueOutput", + "given": { + "name": "DocumentTypeAsMapValue", + "http": { + "method": "PUT", + "requestUri": "/DocumentTypeAsMapValue", + "responseCode": 200 + }, + "output": { + "shape": "DocumentTypeAsMapValueInputOutput" + }, + "documentation": "

This example serializes documents as the value of maps.

", + "idempotent": true + }, + "description": "Serializes a map that uses documents as the value.", + "result": { + "docValuedMap": { + "foo": { + "f": 1, + "o": 2 + }, + "bar": [ + "b", + "a", + "r" + ], + "baz": "BAZ" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"docValuedMap\": {\n \"foo\": { \"f\": 1, \"o\": 2 },\n \"bar\": [ \"b\", \"a\", \"r\" ],\n \"baz\": \"BAZ\"\n }\n}" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "ListMember": ["a", "b"] - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"ListMember\": [\"a\", \"b\"]}" - } - } - ] - }, - { - "description": "Lists with structure member", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for DocumentTypeAsPayload operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "DocumentTypeAsPayloadInputOutput": { + "type": "structure", + "members": { + "documentValue": { + "shape": "Document" + } + }, + "payload": "documentValue" + }, + "Document": { + "type": "structure", + "members": {}, + "document": true + } + }, + "cases": [ + { + "id": "DocumentTypeAsPayloadOutput", + "given": { + "name": "DocumentTypeAsPayload", + "http": { + "method": "PUT", + "requestUri": "/DocumentTypeAsPayload", + "responseCode": 200 + }, + "output": { + "shape": "DocumentTypeAsPayloadInputOutput" + }, + "documentation": "

This example serializes a document as the entire HTTP payload.

", + "idempotent": true + }, + "description": "Serializes a document as the target of the httpPayload trait.", + "result": { + "documentValue": { + "foo": "bar" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"foo\": \"bar\"\n}" + } + }, + { + "id": "DocumentTypeAsPayloadOutputString", + "given": { + "name": "DocumentTypeAsPayload", + "http": { + "method": "PUT", + "requestUri": "/DocumentTypeAsPayload", + "responseCode": 200 + }, + "output": { + "shape": "DocumentTypeAsPayloadInputOutput" + }, + "documentation": "

This example serializes a document as the entire HTTP payload.

", + "idempotent": true + }, + "description": "Serializes a document as a payload string.", + "result": { + "documentValue": "hello" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "\"hello\"" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "ListMember": { - "shape": "ListType" - } - } - }, - "ListType": { - "type": "list", - "member": { - "shape": "SingleStruct" - } - }, - "StringType": { - "type": "string" - }, - "SingleStruct": { - "type": "structure", - "members": { - "Foo": { - "shape": "StringType" - } - } - } + { + "description": "Test cases for EmptyInputAndEmptyOutput operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "EmptyInputAndEmptyOutputOutput": { + "type": "structure", + "members": {} + } + }, + "cases": [ + { + "id": "RestJsonEmptyInputAndEmptyOutput", + "given": { + "name": "EmptyInputAndEmptyOutput", + "http": { + "method": "POST", + "requestUri": "/EmptyInputAndEmptyOutput", + "responseCode": 200 + }, + "output": { + "shape": "EmptyInputAndEmptyOutputOutput" + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response payload because the operation has an empty input and empty output structure that reuses the same shape. While this should be rare, code generators must support this.

" + }, + "description": "As of January 2021, server implementations are expected to\nrespond with a JSON object regardless of if the output\nparameters are empty.", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{}" + } + }, + { + "id": "RestJsonEmptyInputAndEmptyOutputJsonObjectOutput", + "given": { + "name": "EmptyInputAndEmptyOutput", + "http": { + "method": "POST", + "requestUri": "/EmptyInputAndEmptyOutput", + "responseCode": 200 + }, + "output": { + "shape": "EmptyInputAndEmptyOutputOutput" + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response payload because the operation has an empty input and empty output structure that reuses the same shape. While this should be rare, code generators must support this.

" + }, + "description": "This test ensures that clients can gracefully handle\nsituations where a service omits a JSON payload entirely.", + "result": {}, + "response": { + "status_code": 200, + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "ListMember": [{"Foo": "a"}, {"Foo": "b"}] - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"ListMember\": [{\"Foo\": \"a\"}, {\"Foo\": \"b\"}]}" - } - } - ] - }, - { - "description": "Maps", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for FractionalSeconds operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "FractionalSecondsOutput": { + "type": "structure", + "members": { + "datetime": { + "shape": "DateTime" + } + } + }, + "DateTime": { + "type": "timestamp", + "timestampFormat": "iso8601" + } + }, + "cases": [ + { + "id": "RestJsonDateTimeWithFractionalSeconds", + "given": { + "name": "FractionalSeconds", + "http": { + "method": "POST", + "requestUri": "/FractionalSeconds", + "responseCode": 200 + }, + "output": { + "shape": "FractionalSecondsOutput" + } + }, + "description": "Ensures that clients can correctly parse datetime timestamps with fractional seconds", + "result": { + "datetime": 9.46845296123E8 + }, + "response": { + "status_code": 200, + "body": " {\n \"datetime\": \"2000-01-02T20:34:56.123Z\"\n }\n" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "MapMember": { - "shape": "MapType" - } - } - }, - "MapType": { - "type": "map", - "key": { - "shape": "StringType" - }, - "value": { - "shape": "ListType" - } - }, - "ListType": { - "type": "list", - "member": { - "shape": "IntegerType" - } - }, - "StringType": { - "type": "string" - }, - "IntegerType": { - "type": "integer" - } + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "GreetingWithErrorsOutput": { + "type": "structure", + "members": { + "greeting": { + "shape": "String", + "location": "header", + "locationName": "X-Greeting" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonGreetingWithErrors", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "output": { + "shape": "GreetingWithErrorsOutput" + }, + "documentation": "

This operation has four possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A BadRequest error.
  4. A FooError.

Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the

", + "idempotent": true + }, + "description": "Ensures that operations with errors successfully know how\nto deserialize a successful response. As of January 2021,\nserver implementations are expected to respond with a\nJSON object regardless of if the output parameters are\nempty.", + "result": { + "greeting": "Hello" + }, + "response": { + "status_code": 200, + "headers": { + "X-Greeting": "Hello" + }, + "body": "{}" + } + }, + { + "id": "RestJsonGreetingWithErrorsNoPayload", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "output": { + "shape": "GreetingWithErrorsOutput" + }, + "documentation": "

This operation has four possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A BadRequest error.
  4. A FooError.

Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the

", + "idempotent": true + }, + "description": "This test is similar to RestJsonGreetingWithErrors, but it\nensures that clients can gracefully deal with a server\nomitting a response payload.", + "result": { + "greeting": "Hello" + }, + "response": { + "status_code": 200, + "headers": { + "X-Greeting": "Hello" + }, + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "MapMember": { - "a": [1, 2], - "b": [3, 4] - } - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"MapMember\": {\"a\": [1, 2], \"b\": [3, 4]}}" - } - } - ] - }, - { - "description": "Complex Map Values", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "FooError": { + "type": "structure", + "members": {}, + "documentation": "

This error has test cases that test some of the dark corners of Amazon service framework history. It should only be implemented by clients.

", + "error": { + "httpStatusCode": 500 + }, + "exception": true, + "fault": true + } + }, + "cases": [ + { + "id": "RestJsonFooErrorUsingXAmznErrorType", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "

This operation has four possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A BadRequest error.
  4. A FooError.

Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Serializes the X-Amzn-ErrorType header. For an example service, see Amazon EKS.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "X-Amzn-Errortype": "FooError" + } + } + }, + { + "id": "RestJsonFooErrorUsingXAmznErrorTypeWithUri", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "

This operation has four possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A BadRequest error.
  4. A FooError.

Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some X-Amzn-Errortype headers contain URLs. Clients need to split the URL on ':' and take only the first half of the string. For example, 'ValidationException:http://internal.amazon.com/coral/com.amazon.coral.validate/'\nis to be interpreted as 'ValidationException'.\n\nFor an example service see Amazon Polly.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "X-Amzn-Errortype": "FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/" + } + } + }, + { + "id": "RestJsonFooErrorUsingXAmznErrorTypeWithUriAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "

This operation has four possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A BadRequest error.
  4. A FooError.

Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "X-Amzn-Errortype might contain a URL and a namespace. Client should extract only the shape name. This is a pathalogical case that might not actually happen in any deployed AWS service.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "X-Amzn-Errortype": "aws.protocoltests.restjson#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/" + } + } + }, + { + "id": "RestJsonFooErrorUsingCode", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "

This operation has four possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A BadRequest error.
  4. A FooError.

Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "This example uses the 'code' property in the output rather than X-Amzn-Errortype. Some services do this though it's preferable to send the X-Amzn-Errortype. Client implementations must first check for the X-Amzn-Errortype and then check for a top-level 'code' property.\n\nFor example service see Amazon S3 Glacier.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"code\": \"FooError\"\n}" + } + }, + { + "id": "RestJsonFooErrorUsingCodeAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "

This operation has four possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A BadRequest error.
  4. A FooError.

Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using code, and it might contain a namespace. Clients should just take the last part of the string after '#'.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"code\": \"aws.protocoltests.restjson#FooError\"\n}" + } + }, + { + "id": "RestJsonFooErrorUsingCodeUriAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "

This operation has four possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A BadRequest error.
  4. A FooError.

Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using code, and it might contain a namespace. It also might contain a URI. Clients should just take the last part of the string after '#' and before \":\". This is a pathalogical case that might not occur in any deployed AWS service.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"code\": \"aws.protocoltests.restjson#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/\"\n}" + } + }, + { + "id": "RestJsonFooErrorWithDunderType", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "

This operation has four possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A BadRequest error.
  4. A FooError.

Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using __type.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"__type\": \"FooError\"\n}" + } + }, + { + "id": "RestJsonFooErrorWithDunderTypeAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "

This operation has four possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A BadRequest error.
  4. A FooError.

Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using __type, and it might contain a namespace. Clients should just take the last part of the string after '#'.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"__type\": \"aws.protocoltests.restjson#FooError\"\n}" + } + }, + { + "id": "RestJsonFooErrorWithDunderTypeUriAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "

This operation has four possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A BadRequest error.
  4. A FooError.

Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the

", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using __type, and it might contain a namespace. It also might contain a URI. Clients should just take the last part of the string after '#' and before \":\". This is a pathalogical case that might not occur in any deployed AWS service.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"__type\": \"aws.protocoltests.restjson#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/\"\n}" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "MapMember": { - "shape": "MapType" - } - } - }, - "MapType": { - "type": "map", - "key": { - "shape": "StringType" - }, - "value": { - "shape": "TimeType" - } - }, - "TimeType": { - "type": "timestamp" - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "ComplexError": { + "type": "structure", + "members": { + "Header": { + "shape": "String", + "location": "header", + "locationName": "X-Header" + }, + "TopLevel": { + "shape": "String" + }, + "Nested": { + "shape": "ComplexNestedErrorData" + } + }, + "documentation": "

This error is thrown when a request is invalid.

", + "error": { + "httpStatusCode": 403, + "senderFault": true + }, + "exception": true + }, + "String": { + "type": "string" + }, + "ComplexNestedErrorData": { + "type": "structure", + "members": { + "Foo": { + "shape": "String", + "locationName": "Fooooo" + } + } + } + }, + "cases": [ + { + "id": "RestJsonComplexErrorWithNoMessage", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "

This operation has four possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A BadRequest error.
  4. A FooError.

Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the

", + "idempotent": true, + "errors": [ + { + "shape": "ComplexError" + } + ] + }, + "description": "Serializes a complex error with no message member", + "errorCode": "ComplexError", + "error": { + "Header": "Header", + "TopLevel": "Top level", + "Nested": { + "Foo": "bar" + } + }, + "response": { + "status_code": 403, + "headers": { + "Content-Type": "application/json", + "X-Amzn-Errortype": "ComplexError", + "X-Header": "Header" + }, + "body": "{\n \"TopLevel\": \"Top level\",\n \"Nested\": {\n \"Fooooo\": \"bar\"\n }\n}" + } + }, + { + "id": "RestJsonEmptyComplexErrorWithNoMessage", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "

This operation has four possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A BadRequest error.
  4. A FooError.

Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the

", + "idempotent": true, + "errors": [ + { + "shape": "ComplexError" + } + ] + }, + "errorCode": "ComplexError", + "error": {}, + "response": { + "status_code": 403, + "headers": { + "Content-Type": "application/json", + "X-Amzn-Errortype": "ComplexError" + }, + "body": "{}" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "MapMember": { - "a": 1398796238, - "b": 1398796238 - } - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"MapMember\": {\"a\": 1398796238, \"b\": 1398796238}}" - } - } - ] - }, - { - "description": "Ignores extra data", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "InvalidGreeting": { + "type": "structure", + "members": { + "Message": { + "shape": "String" + } + }, + "documentation": "

This error is thrown when an invalid greeting value is provided.

", + "error": { + "httpStatusCode": 400, + "senderFault": true + }, + "exception": true + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonInvalidGreetingError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "

This operation has four possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A BadRequest error.
  4. A FooError.

Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the

", + "idempotent": true, + "errors": [ + { + "shape": "InvalidGreeting" + } + ] + }, + "description": "Parses simple JSON errors", + "errorCode": "InvalidGreeting", + "errorMessage": "Hi", + "error": { + "Message": "Hi" + }, + "response": { + "status_code": 400, + "headers": { + "Content-Type": "application/json", + "X-Amzn-Errortype": "InvalidGreeting" + }, + "body": "{\n \"Message\": \"Hi\"\n}" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "StrType": { - "shape": "StrType" - } - } - }, - "StrType": { - "type": "string" - } + { + "description": "Test cases for HttpEnumPayload operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "EnumPayloadInput": { + "type": "structure", + "members": { + "payload": { + "shape": "StringEnum" + } + }, + "payload": "payload" + }, + "StringEnum": { + "type": "string", + "enum": [ + "enumvalue" + ] + } + }, + "cases": [ + { + "id": "RestJsonEnumPayloadResponse", + "given": { + "name": "HttpEnumPayload", + "http": { + "method": "POST", + "requestUri": "/EnumPayload", + "responseCode": 200 + }, + "output": { + "shape": "EnumPayloadInput" + } + }, + "result": { + "payload": "enumvalue" + }, + "response": { + "status_code": 200, + "body": "enumvalue" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": {}, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"foo\": \"bar\"}" - } - } - ] - }, - { - "description": "Ignores undefined output", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for HttpPayloadTraits operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPayloadTraitsInputOutput": { + "type": "structure", + "members": { + "foo": { + "shape": "String", + "location": "header", + "locationName": "X-Foo" + }, + "blob": { + "shape": "Blob" + } + }, + "payload": "blob" + }, + "String": { + "type": "string" + }, + "Blob": { + "type": "blob" + } + }, + "cases": [ + { + "id": "RestJsonHttpPayloadTraitsWithBlob", + "given": { + "name": "HttpPayloadTraits", + "http": { + "method": "POST", + "requestUri": "/HttpPayloadTraits", + "responseCode": 200 + }, + "output": { + "shape": "HttpPayloadTraitsInputOutput" + }, + "documentation": "

This example serializes a blob shape in the payload.

In this example, no JSON document is synthesized because the payload is not a structure or a union type.

" + }, + "description": "Serializes a blob in the HTTP payload", + "result": { + "foo": "Foo", + "blob": "blobby blob blob" + }, + "response": { + "status_code": 200, + "headers": { + "X-Foo": "Foo" + }, + "body": "blobby blob blob" + } + }, + { + "id": "RestJsonHttpPayloadTraitsWithNoBlobBody", + "given": { + "name": "HttpPayloadTraits", + "http": { + "method": "POST", + "requestUri": "/HttpPayloadTraits", + "responseCode": 200 + }, + "output": { + "shape": "HttpPayloadTraitsInputOutput" + }, + "documentation": "

This example serializes a blob shape in the payload.

In this example, no JSON document is synthesized because the payload is not a structure or a union type.

" + }, + "description": "Serializes an empty blob in the HTTP payload", + "result": { + "foo": "Foo" + }, + "response": { + "status_code": 200, + "headers": { + "X-Foo": "Foo" + }, + "body": "" + } + } + ] }, - "shapes": {}, - "cases": [ - { - "given": { - "name": "OperationName" - }, - "result": {}, - "response": { - "status_code": 200, - "headers": {}, - "body": "OK" - } - } - ] - }, - { - "description": "Supports header maps", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for HttpPayloadWithStructure operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPayloadWithStructureInputOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "NestedPayload" + } + }, + "payload": "nested" + }, + "NestedPayload": { + "type": "structure", + "members": { + "greeting": { + "shape": "String" + }, + "name": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonHttpPayloadWithStructure", + "given": { + "name": "HttpPayloadWithStructure", + "http": { + "method": "PUT", + "requestUri": "/HttpPayloadWithStructure", + "responseCode": 200 + }, + "output": { + "shape": "HttpPayloadWithStructureInputOutput" + }, + "documentation": "

This example serializes a structure in the payload.

Note that serializing a structure changes the wrapper element name to match the targeted structure.

", + "idempotent": true + }, + "description": "Serializes a structure in the payload", + "result": { + "nested": { + "greeting": "hello", + "name": "Phreddy" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"greeting\": \"hello\",\n \"name\": \"Phreddy\"\n}" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "AllHeaders": { - "shape": "HeaderMap", - "location": "headers" - }, - "PrefixedHeaders": { - "shape": "HeaderMap", - "location": "headers", - "locationName": "X-" - } - } - }, - "HeaderMap": { - "type": "map", - "key": { - "shape": "StringType" - }, - "value": { - "shape": "StringType" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for HttpPayloadWithUnion operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPayloadWithUnionInputOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "UnionPayload" + } + }, + "payload": "nested" + }, + "UnionPayload": { + "type": "structure", + "members": { + "greeting": { + "shape": "String" + } + }, + "union": true + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonHttpPayloadWithUnion", + "given": { + "name": "HttpPayloadWithUnion", + "http": { + "method": "PUT", + "requestUri": "/HttpPayloadWithUnion", + "responseCode": 200 + }, + "output": { + "shape": "HttpPayloadWithUnionInputOutput" + }, + "documentation": "

This example serializes a union in the payload.

", + "idempotent": true + }, + "description": "Serializes a union in the payload.", + "result": { + "nested": { + "greeting": "hello" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"greeting\": \"hello\"\n}" + } + }, + { + "id": "RestJsonHttpPayloadWithUnsetUnion", + "given": { + "name": "HttpPayloadWithUnion", + "http": { + "method": "PUT", + "requestUri": "/HttpPayloadWithUnion", + "responseCode": 200 + }, + "output": { + "shape": "HttpPayloadWithUnionInputOutput" + }, + "documentation": "

This example serializes a union in the payload.

", + "idempotent": true + }, + "description": "No payload is sent if the union has no value.", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Length": "0" + }, + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "AllHeaders": { - "Content-Length": "10", - "x-Foo": "bar", - "X-bam": "boo" - }, - "PrefixedHeaders": { - "Foo": "bar", - "bam": "boo" - } - }, - "response": { - "status_code": 200, - "headers": { - "Content-Length": "10", - "x-Foo": "bar", - "X-bam": "boo" - }, - "body": "{}" - } - } - ] - }, - { - "description": "JSON payload", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for HttpPrefixHeaders operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPrefixHeadersOutput": { + "type": "structure", + "members": { + "foo": { + "shape": "String", + "location": "header", + "locationName": "X-Foo" + }, + "fooMap": { + "shape": "StringMap", + "location": "headers", + "locationName": "X-Foo-" + } + } + }, + "String": { + "type": "string" + }, + "StringMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "String" + } + } + }, + "cases": [ + { + "id": "RestJsonHttpPrefixHeadersArePresent", + "given": { + "name": "HttpPrefixHeaders", + "http": { + "method": "GET", + "requestUri": "/HttpPrefixHeaders", + "responseCode": 200 + }, + "output": { + "shape": "HttpPrefixHeadersOutput" + }, + "documentation": "

This examples adds headers to the input of a request and response by prefix.

" + }, + "description": "Adds headers by prefix", + "result": { + "foo": "Foo", + "fooMap": { + "Abc": "Abc value", + "Def": "Def value" + } + }, + "response": { + "status_code": 200, + "headers": { + "X-Foo": "Foo", + "X-Foo-Abc": "Abc value", + "X-Foo-Def": "Def value" + } + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "payload": "Data", - "members": { - "Header": { - "shape": "StringType", - "location": "header", - "locationName": "X-Foo" - }, - "Data": { - "shape": "BodyStructure" - } - } - }, - "BodyStructure": { - "type": "structure", - "members": { - "Foo": { - "shape": "StringType" - } - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for HttpPrefixHeadersInResponse operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPrefixHeadersInResponseOutput": { + "type": "structure", + "members": { + "prefixHeaders": { + "shape": "StringMap", + "location": "headers", + "locationName": "" + } + } + }, + "StringMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "String" + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "HttpPrefixHeadersResponse", + "given": { + "name": "HttpPrefixHeadersInResponse", + "http": { + "method": "GET", + "requestUri": "/HttpPrefixHeadersResponse", + "responseCode": 200 + }, + "output": { + "shape": "HttpPrefixHeadersInResponseOutput" + }, + "documentation": "

Clients that perform this test extract all headers from the response.

" + }, + "description": "(de)serializes all response headers", + "result": { + "prefixHeaders": { + "X-Foo": "Foo", + "Hello": "Hello" + } + }, + "response": { + "status_code": 200, + "headers": { + "Hello": "Hello", + "X-Foo": "Foo" + } + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Header": "baz", - "Data": { - "Foo": "abc" - } - }, - "response": { - "status_code": 200, - "headers": { - "X-Foo": "baz" - }, - "body": "{\"Foo\": \"abc\"}" - } - } - ] - }, - { - "description": "Streaming payload", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for HttpResponseCode operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpResponseCodeOutput": { + "type": "structure", + "members": { + "Status": { + "shape": "Integer", + "location": "statusCode" + } + } + }, + "Integer": { + "type": "integer", + "box": true + } + }, + "cases": [ + { + "id": "RestJsonHttpResponseCode", + "given": { + "name": "HttpResponseCode", + "http": { + "method": "PUT", + "requestUri": "/HttpResponseCode", + "responseCode": 200 + }, + "output": { + "shape": "HttpResponseCodeOutput" + }, + "idempotent": true + }, + "description": "Binds the http response code to an output structure. Note that\neven though all members are bound outside of the payload, an\nempty JSON object is serialized in the response. However,\nclients should be able to handle an empty JSON object or an\nempty payload without failing to deserialize a response.", + "result": { + "Status": 201 + }, + "response": { + "status_code": 201, + "headers": { + "Content-Type": "application/json" + }, + "body": "{}" + } + }, + { + "id": "RestJsonHttpResponseCodeWithNoPayload", + "given": { + "name": "HttpResponseCode", + "http": { + "method": "PUT", + "requestUri": "/HttpResponseCode", + "responseCode": 200 + }, + "output": { + "shape": "HttpResponseCodeOutput" + }, + "idempotent": true + }, + "description": "This test ensures that clients gracefully handle cases where\nthe service responds with no payload rather than an empty JSON\nobject.", + "result": { + "Status": 201 + }, + "response": { + "status_code": 201, + "body": "" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "payload": "Stream", - "members": { - "Stream": { - "shape": "Stream" - } - } - }, - "Stream": { - "type": "blob" - } + { + "description": "Test cases for HttpStringPayload operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "StringPayloadInput": { + "type": "structure", + "members": { + "payload": { + "shape": "String" + } + }, + "payload": "payload" + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonStringPayloadResponse", + "given": { + "name": "HttpStringPayload", + "http": { + "method": "POST", + "requestUri": "/StringPayload", + "responseCode": 200 + }, + "output": { + "shape": "StringPayloadInput" + } + }, + "result": { + "payload": "rawstring" + }, + "response": { + "status_code": 200, + "body": "rawstring" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Stream": "abc" - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "abc" - } - } - ] - }, - { - "description": "JSON value trait", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for IgnoreQueryParamsInResponse operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "IgnoreQueryParamsInResponseOutput": { + "type": "structure", + "members": { + "baz": { + "shape": "String", + "location": "uri", + "locationName": "baz" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonIgnoreQueryParamsInResponse", + "given": { + "name": "IgnoreQueryParamsInResponse", + "http": { + "method": "GET", + "requestUri": "/IgnoreQueryParamsInResponse", + "responseCode": 200 + }, + "output": { + "shape": "IgnoreQueryParamsInResponseOutput" + }, + "documentation": "

This example ensures that query string bound request parameters are serialized in the body of responses if the structure is used in both the request and response.

" + }, + "description": "Query parameters must be ignored when serializing the output\nof an operation. As of January 2021, server implementations\nare expected to respond with a JSON object regardless of\nif the output parameters are empty.", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{}" + } + }, + { + "id": "RestJsonIgnoreQueryParamsInResponseNoPayload", + "given": { + "name": "IgnoreQueryParamsInResponse", + "http": { + "method": "GET", + "requestUri": "/IgnoreQueryParamsInResponse", + "responseCode": 200 + }, + "output": { + "shape": "IgnoreQueryParamsInResponseOutput" + }, + "documentation": "

This example ensures that query string bound request parameters are serialized in the body of responses if the structure is used in both the request and response.

" + }, + "description": "This test is similar to RestJsonIgnoreQueryParamsInResponse,\nbut it ensures that clients gracefully handle responses from\nthe server that do not serialize an empty JSON object.", + "result": {}, + "response": { + "status_code": 200, + "body": "" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Attr": { - "shape": "StringType", - "jsonvalue": true, - "location": "header", - "locationName": "X-Amz-Foo" - } - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for InputAndOutputWithHeaders operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "InputAndOutputWithHeadersIO": { + "type": "structure", + "members": { + "headerString": { + "shape": "String", + "location": "header", + "locationName": "X-String" + }, + "headerByte": { + "shape": "Integer", + "location": "header", + "locationName": "X-Byte" + }, + "headerShort": { + "shape": "Integer", + "location": "header", + "locationName": "X-Short" + }, + "headerInteger": { + "shape": "Integer", + "location": "header", + "locationName": "X-Integer" + }, + "headerLong": { + "shape": "Long", + "location": "header", + "locationName": "X-Long" + }, + "headerFloat": { + "shape": "Float", + "location": "header", + "locationName": "X-Float" + }, + "headerDouble": { + "shape": "Double", + "location": "header", + "locationName": "X-Double" + }, + "headerTrueBool": { + "shape": "Boolean", + "location": "header", + "locationName": "X-Boolean1" + }, + "headerFalseBool": { + "shape": "Boolean", + "location": "header", + "locationName": "X-Boolean2" + }, + "headerStringList": { + "shape": "StringList", + "location": "header", + "locationName": "X-StringList" + }, + "headerStringSet": { + "shape": "StringSet", + "location": "header", + "locationName": "X-StringSet" + }, + "headerIntegerList": { + "shape": "IntegerList", + "location": "header", + "locationName": "X-IntegerList" + }, + "headerBooleanList": { + "shape": "BooleanList", + "location": "header", + "locationName": "X-BooleanList" + }, + "headerTimestampList": { + "shape": "TimestampList", + "location": "header", + "locationName": "X-TimestampList" + }, + "headerEnum": { + "shape": "FooEnum", + "location": "header", + "locationName": "X-Enum" + }, + "headerEnumList": { + "shape": "FooEnumList", + "location": "header", + "locationName": "X-EnumList" + }, + "headerIntegerEnum": { + "shape": "IntegerEnum", + "location": "header", + "locationName": "X-IntegerEnum" + }, + "headerIntegerEnumList": { + "shape": "IntegerEnumList", + "location": "header", + "locationName": "X-IntegerEnumList" + } + } + }, + "String": { + "type": "string" + }, + "Integer": { + "type": "integer", + "box": true + }, + "Long": { + "type": "long", + "box": true + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringSet": { + "type": "list", + "member": { + "shape": "String" + } + }, + "IntegerList": { + "type": "list", + "member": { + "shape": "Integer" + } + }, + "BooleanList": { + "type": "list", + "member": { + "shape": "Boolean" + } + }, + "TimestampList": { + "type": "list", + "member": { + "shape": "Timestamp" + } + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "IntegerEnumList": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "Timestamp": { + "type": "timestamp" + } + }, + "cases": [ + { + "id": "RestJsonInputAndOutputWithStringHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Tests responses with string header bindings", + "result": { + "headerString": "Hello", + "headerStringList": [ + "a", + "b", + "c" + ], + "headerStringSet": [ + "a", + "b", + "c" + ] + }, + "response": { + "status_code": 200, + "headers": { + "X-String": "Hello", + "X-StringList": "a, b, c", + "X-StringSet": "a, b, c" + } + } + }, + { + "id": "RestJsonInputAndOutputWithQuotedStringHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Tests responses with string list header bindings that require quoting", + "result": { + "headerStringList": [ + "b,c", + "\"def\"", + "a" + ] + }, + "response": { + "status_code": 200, + "headers": { + "X-StringList": "\"b,c\", \"\\\"def\\\"\", a" + } + } + }, + { + "id": "RestJsonInputAndOutputWithNumericHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Tests responses with numeric header bindings", + "result": { + "headerByte": 1, + "headerShort": 123, + "headerInteger": 123, + "headerLong": 123, + "headerFloat": 1.1, + "headerDouble": 1.1, + "headerIntegerList": [ + 1, + 2, + 3 + ] + }, + "response": { + "status_code": 200, + "headers": { + "X-Byte": "1", + "X-Double": "1.1", + "X-Float": "1.1", + "X-Integer": "123", + "X-IntegerList": "1, 2, 3", + "X-Long": "123", + "X-Short": "123" + } + } + }, + { + "id": "RestJsonInputAndOutputWithBooleanHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Tests responses with boolean header bindings", + "result": { + "headerTrueBool": true, + "headerFalseBool": false, + "headerBooleanList": [ + true, + false, + true + ] + }, + "response": { + "status_code": 200, + "headers": { + "X-Boolean1": "true", + "X-Boolean2": "false", + "X-BooleanList": "true, false, true" + } + } + }, + { + "id": "RestJsonInputAndOutputWithTimestampHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Tests responses with timestamp header bindings", + "result": { + "headerTimestampList": [ + 1576540098, + 1576540098 + ] + }, + "response": { + "status_code": 200, + "headers": { + "X-TimestampList": "Mon, 16 Dec 2019 23:48:18 GMT, Mon, 16 Dec 2019 23:48:18 GMT" + } + } + }, + { + "id": "RestJsonInputAndOutputWithEnumHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Tests responses with enum header bindings", + "result": { + "headerEnum": "Foo", + "headerEnumList": [ + "Foo", + "Bar", + "Baz" + ] + }, + "response": { + "status_code": 200, + "headers": { + "X-Enum": "Foo", + "X-EnumList": "Foo, Bar, Baz" + } + } + }, + { + "id": "RestJsonInputAndOutputWithIntEnumHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Tests responses with intEnum header bindings", + "result": { + "headerIntegerEnum": 1, + "headerIntegerEnumList": [ + 1, + 2, + 3 + ] + }, + "response": { + "status_code": 200, + "headers": { + "X-IntegerEnum": "1", + "X-IntegerEnumList": "1, 2, 3" + } + } + }, + { + "id": "RestJsonSupportsNaNFloatHeaderOutputs", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Supports handling NaN float header values.", + "result": { + "headerFloat": "NaN", + "headerDouble": "NaN" + }, + "response": { + "status_code": 200, + "headers": { + "X-Double": "NaN", + "X-Float": "NaN" + } + } + }, + { + "id": "RestJsonSupportsInfinityFloatHeaderOutputs", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Supports handling Infinity float header values.", + "result": { + "headerFloat": "Infinity", + "headerDouble": "Infinity" + }, + "response": { + "status_code": 200, + "headers": { + "X-Double": "Infinity", + "X-Float": "Infinity" + } + } + }, + { + "id": "RestJsonSupportsNegativeInfinityFloatHeaderOutputs", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Supports handling -Infinity float header values.", + "result": { + "headerFloat": "-Infinity", + "headerDouble": "-Infinity" + }, + "response": { + "status_code": 200, + "headers": { + "X-Double": "-Infinity", + "X-Float": "-Infinity" + } + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Attr": {"Foo":"Bar"} - }, - "response": { - "status_code": 200, - "headers": {"X-Amz-Foo": "eyJGb28iOiJCYXIifQ=="}, - "body": "" - } - } - ] - }, - { - "description": "Modeled exceptions", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for JsonBlobs operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "JsonBlobsInputOutput": { + "type": "structure", + "members": { + "data": { + "shape": "Blob" + } + } + }, + "Blob": { + "type": "blob" + } + }, + "cases": [ + { + "id": "RestJsonJsonBlobs", + "given": { + "name": "JsonBlobs", + "http": { + "method": "POST", + "requestUri": "/JsonBlobs", + "responseCode": 200 + }, + "output": { + "shape": "JsonBlobsInputOutput" + }, + "documentation": "

Blobs are base64 encoded

" + }, + "description": "Blobs are base64 encoded", + "result": { + "data": "value" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"data\": \"dmFsdWU=\"\n}" + } + } + ] }, - "shapes": { - "ExceptionShape": { - "exception": true, - "type": "structure", - "members": { - "ImaHeader": { - "shape": "HeaderShape" - }, - "ImaHeaderLocation": { - "shape": "HeaderShape", - "locationName": "X-Foo" - }, - "Status": { - "shape": "StatusShape", - "location": "statusCode" - }, - "BodyMember": { - "shape": "StringType" - }, - "Message": { - "shape": "StringType" - } - } - }, - "OtherExceptionShape": { - "exception": true, - "type": "structure", - "members": { - "BodyMember": { - "shape": "StringType" - } - } - }, - "HeaderShape": { - "type": "string", - "location": "header" - }, - "StatusShape": { - "type": "integer" - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for JsonEnums operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "JsonEnumsInputOutput": { + "type": "structure", + "members": { + "fooEnum1": { + "shape": "FooEnum" + }, + "fooEnum2": { + "shape": "FooEnum" + }, + "fooEnum3": { + "shape": "FooEnum" + }, + "fooEnumList": { + "shape": "FooEnumList" + }, + "fooEnumSet": { + "shape": "FooEnumSet" + }, + "fooEnumMap": { + "shape": "FooEnumMap" + } + } + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "FooEnumSet": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "FooEnumMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "FooEnum" + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonJsonEnums", + "given": { + "name": "JsonEnums", + "http": { + "method": "PUT", + "requestUri": "/JsonEnums", + "responseCode": 200 + }, + "output": { + "shape": "JsonEnumsInputOutput" + }, + "documentation": "

This example serializes enums as top level properties, in lists, sets, and maps.

", + "idempotent": true + }, + "description": "Serializes simple scalar properties", + "result": { + "fooEnum1": "Foo", + "fooEnum2": "0", + "fooEnum3": "1", + "fooEnumList": [ + "Foo", + "0" + ], + "fooEnumSet": [ + "Foo", + "0" + ], + "fooEnumMap": { + "hi": "Foo", + "zero": "0" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"fooEnum1\": \"Foo\",\n \"fooEnum2\": \"0\",\n \"fooEnum3\": \"1\",\n \"fooEnumList\": [\n \"Foo\",\n \"0\"\n ],\n \"fooEnumSet\": [\n \"Foo\",\n \"0\"\n ],\n \"fooEnumMap\": {\n \"hi\": \"Foo\",\n \"zero\": \"0\"\n }\n}" + } + } + ] }, - "cases": [ - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" - }, - "error": { - "ImaHeader": "test", - "ImaHeaderLocation": "abc", - "Status": 400, - "BodyMember": "mybody", - "Message": "mymessage" - }, - "errorCode": "ExceptionShape", - "errorMessage": "mymessage", - "response": { - "status_code": 400, - "headers": { - "ImaHeader": "test", - "X-Foo": "abc", - "X-Amzn-Errortype": "ExceptionShape" - }, - "body": "{\"BodyMember\": \"mybody\", \"Message\": \"mymessage\"}" - } - }, - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" - }, - "error": { - "ImaHeader": "test", - "ImaHeaderLocation": "abc", - "Status": 400, - "BodyMember": "mybody", - "Message": "mymessage" - }, - "errorCode": "ExceptionShape", - "errorMessage": "mymessage", - "response": { - "status_code": 400, - "headers": { - "ImaHeader": "test", - "X-Foo": "abc" - }, - "body": "{ \"code\": \"ExceptionShape\", \"BodyMember\": \"mybody\", \"Message\": \"mymessage\"}" - } - }, - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" - }, - "error": { - "ImaHeader": "test", - "ImaHeaderLocation": "abc", - "Status": 400, - "BodyMember": "mybody", - "Message": "mymessage" - }, - "errorCode": "ExceptionShape", - "errorMessage": "mymessage", - "response": { - "status_code": 400, - "headers": { - "ImaHeader": "test", - "X-Foo": "abc", - "X-Amzn-Errortype": "ExceptionShape" - }, - "body": "{ \"code\": \"OtherExceptionShape\", \"BodyMember\": \"mybody\", \"Message\": \"mymessage\"}" - } - }, - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" - }, - "error": { - "BodyMember": "mybody" - }, - "errorCode": "OtherExceptionShape", - "errorMessage": "mymessage", - "response": { - "status_code": 400, - "headers": { - "ImaHeader": "test", - "X-Foo": "abc", - "X-Amzn-Errortype": "OtherExceptionShape" - }, - "body": "{ \"BodyMember\": \"mybody\", \"Message\": \"mymessage\"}" - } - }, - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" - }, - "error": { - "BodyMember": "mybody" - }, - "errorCode": "OtherExceptionShape", - "errorMessage": "mymessage", - "response": { - "status_code": 400, - "headers": { - "ImaHeader": "test", - "X-Foo": "abc" - }, - "body": "{ \"code\": \"OtherExceptionShape\", \"BodyMember\": \"mybody\", \"Message\": \"mymessage\"}" - } - }, - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" - }, - "error": {}, - "errorCode": "UndefinedShape", - "response": { - "status_code": 400, - "headers": { - "ImaHeader": "test", - "X-Foo": "abc", - "X-Amzn-Errortype": "UndefinedShape" - }, - "body": "{ \"BodyMember\": \"mybody\"}" - } - }, - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" - }, - "error": {}, - "errorCode": "UndefinedShape", - "response": { - "status_code": 400, - "headers": { - "ImaHeader": "test", - "X-Foo": "abc" - }, - "body": "{ \"code\": \"UndefinedShape\", \"BodyMember\": \"mybody\"}" - } - } - ] - }, - { - "description": "Serializes document with standalone primitive as part of the JSON response payload with no escaping.", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for JsonIntEnums operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "JsonIntEnumsInputOutput": { + "type": "structure", + "members": { + "integerEnum1": { + "shape": "IntegerEnum" + }, + "integerEnum2": { + "shape": "IntegerEnum" + }, + "integerEnum3": { + "shape": "IntegerEnum" + }, + "integerEnumList": { + "shape": "IntegerEnumList" + }, + "integerEnumSet": { + "shape": "IntegerEnumSet" + }, + "integerEnumMap": { + "shape": "IntegerEnumMap" + } + } + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "IntegerEnumList": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "IntegerEnumSet": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "IntegerEnumMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "IntegerEnum" + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonJsonIntEnums", + "given": { + "name": "JsonIntEnums", + "http": { + "method": "PUT", + "requestUri": "/JsonIntEnums", + "responseCode": 200 + }, + "output": { + "shape": "JsonIntEnumsInputOutput" + }, + "documentation": "

This example serializes intEnums as top level properties, in lists, sets, and maps.

", + "idempotent": true + }, + "description": "Serializes intEnums as integers", + "result": { + "integerEnum1": 1, + "integerEnum2": 2, + "integerEnum3": 3, + "integerEnumList": [ + 1, + 2, + 3 + ], + "integerEnumSet": [ + 1, + 2 + ], + "integerEnumMap": { + "abc": 1, + "def": 2 + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"integerEnum1\": 1,\n \"integerEnum2\": 2,\n \"integerEnum3\": 3,\n \"integerEnumList\": [\n 1,\n 2,\n 3\n ],\n \"integerEnumSet\": [\n 1,\n 2\n ],\n \"integerEnumMap\": {\n \"abc\": 1,\n \"def\": 2\n }\n}" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "documentValue": { - "shape": "DocumentType" - } - } - }, - "DocumentType": { - "type": "structure", - "document": true - } + { + "description": "Test cases for JsonLists operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "JsonListsInputOutput": { + "type": "structure", + "members": { + "stringList": { + "shape": "StringList" + }, + "stringSet": { + "shape": "StringSet" + }, + "integerList": { + "shape": "IntegerList" + }, + "booleanList": { + "shape": "BooleanList" + }, + "timestampList": { + "shape": "TimestampList" + }, + "enumList": { + "shape": "FooEnumList" + }, + "intEnumList": { + "shape": "IntegerEnumList" + }, + "nestedStringList": { + "shape": "NestedStringList" + }, + "structureList": { + "shape": "StructureList", + "locationName": "myStructureList" + } + } + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringSet": { + "type": "list", + "member": { + "shape": "String" + } + }, + "IntegerList": { + "type": "list", + "member": { + "shape": "Integer" + } + }, + "BooleanList": { + "type": "list", + "member": { + "shape": "Boolean" + } + }, + "TimestampList": { + "type": "list", + "member": { + "shape": "Timestamp" + } + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "IntegerEnumList": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "NestedStringList": { + "type": "list", + "member": { + "shape": "StringList" + }, + "documentation": "

A list of lists of strings.

" + }, + "StructureList": { + "type": "list", + "member": { + "shape": "StructureListMember" + } + }, + "StructureListMember": { + "type": "structure", + "members": { + "a": { + "shape": "String", + "locationName": "value" + }, + "b": { + "shape": "String", + "locationName": "other" + } + } + }, + "String": { + "type": "string" + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "Timestamp": { + "type": "timestamp" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + } + }, + "cases": [ + { + "id": "RestJsonLists", + "given": { + "name": "JsonLists", + "http": { + "method": "PUT", + "requestUri": "/JsonLists", + "responseCode": 200 + }, + "output": { + "shape": "JsonListsInputOutput" + }, + "documentation": "

This test case serializes JSON lists for the following cases for both input and output:

  1. Normal JSON lists.
  2. Normal JSON sets.
  3. JSON lists of lists.
  4. Lists of structures.
", + "idempotent": true + }, + "description": "Serializes JSON lists", + "result": { + "stringList": [ + "foo", + "bar" + ], + "stringSet": [ + "foo", + "bar" + ], + "integerList": [ + 1, + 2 + ], + "booleanList": [ + true, + false + ], + "timestampList": [ + 1398796238, + 1398796238 + ], + "enumList": [ + "Foo", + "0" + ], + "intEnumList": [ + 1, + 2 + ], + "nestedStringList": [ + [ + "foo", + "bar" + ], + [ + "baz", + "qux" + ] + ], + "structureList": [ + { + "a": "1", + "b": "2" + }, + { + "a": "3", + "b": "4" + } + ] + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"stringList\": [\n \"foo\",\n \"bar\"\n ],\n \"stringSet\": [\n \"foo\",\n \"bar\"\n ],\n \"integerList\": [\n 1,\n 2\n ],\n \"booleanList\": [\n true,\n false\n ],\n \"timestampList\": [\n 1398796238,\n 1398796238\n ],\n \"enumList\": [\n \"Foo\",\n \"0\"\n ],\n \"intEnumList\": [\n 1,\n 2\n ],\n \"nestedStringList\": [\n [\n \"foo\",\n \"bar\"\n ],\n [\n \"baz\",\n \"qux\"\n ]\n ],\n \"myStructureList\": [\n {\n \"value\": \"1\",\n \"other\": \"2\"\n },\n {\n \"value\": \"3\",\n \"other\": \"4\"\n }\n ]\n}" + } + }, + { + "id": "RestJsonListsEmpty", + "given": { + "name": "JsonLists", + "http": { + "method": "PUT", + "requestUri": "/JsonLists", + "responseCode": 200 + }, + "output": { + "shape": "JsonListsInputOutput" + }, + "documentation": "

This test case serializes JSON lists for the following cases for both input and output:

  1. Normal JSON lists.
  2. Normal JSON sets.
  3. JSON lists of lists.
  4. Lists of structures.
", + "idempotent": true + }, + "description": "Serializes empty JSON lists", + "result": { + "stringList": [] + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"stringList\": []\n}" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "documentValue": "foo" - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"documentValue\": \"foo\"}" - } - }, - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "documentValue": 123 - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"documentValue\": 123}" - } - }, - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "documentValue": 1.2 - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"documentValue\": 1.2}" - } - }, - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "documentValue": true - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"documentValue\": true}" - } - }, - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "documentValue": "" - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"documentValue\": \"\"}" - } - } - ] - }, - { - "description": "Serializes inline documents as part of the JSON response payload with no escaping.", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for JsonMaps operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "JsonMapsInputOutput": { + "type": "structure", + "members": { + "denseStructMap": { + "shape": "DenseStructMap" + }, + "denseNumberMap": { + "shape": "DenseNumberMap" + }, + "denseBooleanMap": { + "shape": "DenseBooleanMap" + }, + "denseStringMap": { + "shape": "DenseStringMap" + }, + "denseSetMap": { + "shape": "DenseSetMap" + } + } + }, + "DenseStructMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "GreetingStruct" + } + }, + "DenseNumberMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "Integer" + } + }, + "DenseBooleanMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "Boolean" + } + }, + "DenseStringMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "String" + } + }, + "DenseSetMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "StringSet" + } + }, + "StringSet": { + "type": "list", + "member": { + "shape": "String" + } + }, + "String": { + "type": "string" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + }, + "GreetingStruct": { + "type": "structure", + "members": { + "hi": { + "shape": "String" + } + } + } + }, + "cases": [ + { + "id": "RestJsonJsonMaps", + "given": { + "name": "JsonMaps", + "http": { + "method": "POST", + "requestUri": "/JsonMaps", + "responseCode": 200 + }, + "output": { + "shape": "JsonMapsInputOutput" + }, + "documentation": "

The example tests basic map serialization.

" + }, + "description": "Deserializes JSON maps", + "result": { + "denseStructMap": { + "foo": { + "hi": "there" + }, + "baz": { + "hi": "bye" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"denseStructMap\": {\n \"foo\": {\n \"hi\": \"there\"\n },\n \"baz\": {\n \"hi\": \"bye\"\n }\n }\n}" + } + }, + { + "id": "RestJsonDeserializesZeroValuesInMaps", + "given": { + "name": "JsonMaps", + "http": { + "method": "POST", + "requestUri": "/JsonMaps", + "responseCode": 200 + }, + "output": { + "shape": "JsonMapsInputOutput" + }, + "documentation": "

The example tests basic map serialization.

" + }, + "description": "Ensure that 0 and false are sent over the wire in all maps and lists", + "result": { + "denseNumberMap": { + "x": 0 + }, + "denseBooleanMap": { + "x": false + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"denseNumberMap\": {\n \"x\": 0\n },\n \"denseBooleanMap\": {\n \"x\": false\n }\n}" + } + }, + { + "id": "RestJsonDeserializesDenseSetMap", + "given": { + "name": "JsonMaps", + "http": { + "method": "POST", + "requestUri": "/JsonMaps", + "responseCode": 200 + }, + "output": { + "shape": "JsonMapsInputOutput" + }, + "documentation": "

The example tests basic map serialization.

" + }, + "description": "A response that contains a dense map of sets.", + "result": { + "denseSetMap": { + "x": [], + "y": [ + "a", + "b" + ] + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"denseSetMap\": {\n \"x\": [],\n \"y\": [\"a\", \"b\"]\n }\n}" + } + }, + { + "id": "RestJsonDeserializesDenseSetMapAndSkipsNull", + "given": { + "name": "JsonMaps", + "http": { + "method": "POST", + "requestUri": "/JsonMaps", + "responseCode": 200 + }, + "output": { + "shape": "JsonMapsInputOutput" + }, + "documentation": "

The example tests basic map serialization.

" + }, + "description": "Clients SHOULD tolerate seeing a null value in a dense map, and they SHOULD\ndrop the null key-value pair.", + "result": { + "denseSetMap": { + "x": [], + "y": [ + "a", + "b" + ] + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"denseSetMap\": {\n \"x\": [],\n \"y\": [\"a\", \"b\"],\n \"z\": null\n }\n}" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "documentValue": { - "shape": "DocumentType" - } - } - }, - "DocumentType": { - "type": "structure", - "document": true - } + { + "description": "Test cases for JsonTimestamps operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "JsonTimestampsInputOutput": { + "type": "structure", + "members": { + "normal": { + "shape": "Timestamp" + }, + "dateTime": { + "shape": "SyntheticTimestamp_date_time" + }, + "dateTimeOnTarget": { + "shape": "DateTime" + }, + "epochSeconds": { + "shape": "SyntheticTimestamp_epoch_seconds" + }, + "epochSecondsOnTarget": { + "shape": "EpochSeconds" + }, + "httpDate": { + "shape": "SyntheticTimestamp_http_date" + }, + "httpDateOnTarget": { + "shape": "HttpDate" + } + } + }, + "Timestamp": { + "type": "timestamp" + }, + "SyntheticTimestamp_date_time": { + "type": "timestamp", + "timestampFormat": "iso8601" + }, + "DateTime": { + "type": "timestamp", + "timestampFormat": "iso8601" + }, + "SyntheticTimestamp_epoch_seconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "EpochSeconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "SyntheticTimestamp_http_date": { + "type": "timestamp", + "timestampFormat": "rfc822" + }, + "HttpDate": { + "type": "timestamp", + "timestampFormat": "rfc822" + } + }, + "cases": [ + { + "id": "RestJsonJsonTimestamps", + "given": { + "name": "JsonTimestamps", + "http": { + "method": "POST", + "requestUri": "/JsonTimestamps", + "responseCode": 200 + }, + "output": { + "shape": "JsonTimestampsInputOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Tests how normal timestamps are serialized", + "result": { + "normal": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"normal\": 1398796238\n}" + } + }, + { + "id": "RestJsonJsonTimestampsWithDateTimeFormat", + "given": { + "name": "JsonTimestamps", + "http": { + "method": "POST", + "requestUri": "/JsonTimestamps", + "responseCode": 200 + }, + "output": { + "shape": "JsonTimestampsInputOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of date-time works like normal timestamps", + "result": { + "dateTime": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"dateTime\": \"2014-04-29T18:30:38Z\"\n}" + } + }, + { + "id": "RestJsonJsonTimestampsWithDateTimeOnTargetFormat", + "given": { + "name": "JsonTimestamps", + "http": { + "method": "POST", + "requestUri": "/JsonTimestamps", + "responseCode": 200 + }, + "output": { + "shape": "JsonTimestampsInputOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of date-time on the target shape works like normal timestamps", + "result": { + "dateTimeOnTarget": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"dateTimeOnTarget\": \"2014-04-29T18:30:38Z\"\n}" + } + }, + { + "id": "RestJsonJsonTimestampsWithEpochSecondsFormat", + "given": { + "name": "JsonTimestamps", + "http": { + "method": "POST", + "requestUri": "/JsonTimestamps", + "responseCode": 200 + }, + "output": { + "shape": "JsonTimestampsInputOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of epoch-seconds works", + "result": { + "epochSeconds": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"epochSeconds\": 1398796238\n}" + } + }, + { + "id": "RestJsonJsonTimestampsWithEpochSecondsOnTargetFormat", + "given": { + "name": "JsonTimestamps", + "http": { + "method": "POST", + "requestUri": "/JsonTimestamps", + "responseCode": 200 + }, + "output": { + "shape": "JsonTimestampsInputOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of epoch-seconds on the target shape works", + "result": { + "epochSecondsOnTarget": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"epochSecondsOnTarget\": 1398796238\n}" + } + }, + { + "id": "RestJsonJsonTimestampsWithHttpDateFormat", + "given": { + "name": "JsonTimestamps", + "http": { + "method": "POST", + "requestUri": "/JsonTimestamps", + "responseCode": 200 + }, + "output": { + "shape": "JsonTimestampsInputOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of http-date works", + "result": { + "httpDate": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"httpDate\": \"Tue, 29 Apr 2014 18:30:38 GMT\"\n}" + } + }, + { + "id": "RestJsonJsonTimestampsWithHttpDateOnTargetFormat", + "given": { + "name": "JsonTimestamps", + "http": { + "method": "POST", + "requestUri": "/JsonTimestamps", + "responseCode": 200 + }, + "output": { + "shape": "JsonTimestampsInputOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of http-date on the target shape works", + "result": { + "httpDateOnTarget": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"httpDateOnTarget\": \"Tue, 29 Apr 2014 18:30:38 GMT\"\n}" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "documentValue": {"foo": "bar"} - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"documentValue\": {\"foo\": \"bar\"}}" - } - } - ] - }, - { - "description": "Serializes aggregate documents as part of the JSON response payload with no escaping.", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for JsonUnions operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "UnionInputOutput": { + "type": "structure", + "members": { + "contents": { + "shape": "MyUnion" + } + }, + "documentation": "

A shared structure that contains a single union member.

" + }, + "MyUnion": { + "type": "structure", + "members": { + "stringValue": { + "shape": "String" + }, + "booleanValue": { + "shape": "Boolean" + }, + "numberValue": { + "shape": "Integer" + }, + "blobValue": { + "shape": "Blob" + }, + "timestampValue": { + "shape": "Timestamp" + }, + "enumValue": { + "shape": "FooEnum" + }, + "listValue": { + "shape": "StringList" + }, + "mapValue": { + "shape": "StringMap" + }, + "structureValue": { + "shape": "GreetingStruct" + }, + "renamedStructureValue": { + "shape": "RenamedGreeting" + } + }, + "documentation": "

A union with a representative set of types for members.

", + "union": true + }, + "String": { + "type": "string" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + }, + "Blob": { + "type": "blob" + }, + "Timestamp": { + "type": "timestamp" + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "String" + } + }, + "GreetingStruct": { + "type": "structure", + "members": { + "hi": { + "shape": "String" + } + } + }, + "RenamedGreeting": { + "type": "structure", + "members": { + "salutation": { + "shape": "String" + } + } + } + }, + "cases": [ + { + "id": "RestJsonDeserializeStringUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes a string union value", + "result": { + "contents": { + "stringValue": "foo" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"contents\": {\n \"stringValue\": \"foo\"\n }\n}" + } + }, + { + "id": "RestJsonDeserializeBooleanUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes a boolean union value", + "result": { + "contents": { + "booleanValue": true + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"contents\": {\n \"booleanValue\": true\n }\n}" + } + }, + { + "id": "RestJsonDeserializeNumberUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes a number union value", + "result": { + "contents": { + "numberValue": 1 + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"contents\": {\n \"numberValue\": 1\n }\n}" + } + }, + { + "id": "RestJsonDeserializeBlobUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes a blob union value", + "result": { + "contents": { + "blobValue": "foo" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"contents\": {\n \"blobValue\": \"Zm9v\"\n }\n}" + } + }, + { + "id": "RestJsonDeserializeTimestampUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes a timestamp union value", + "result": { + "contents": { + "timestampValue": 1398796238 + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"contents\": {\n \"timestampValue\": 1398796238\n }\n}" + } + }, + { + "id": "RestJsonDeserializeEnumUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes an enum union value", + "result": { + "contents": { + "enumValue": "Foo" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"contents\": {\n \"enumValue\": \"Foo\"\n }\n}" + } + }, + { + "id": "RestJsonDeserializeListUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes a list union value", + "result": { + "contents": { + "listValue": [ + "foo", + "bar" + ] + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"contents\": {\n \"listValue\": [\"foo\", \"bar\"]\n }\n}" + } + }, + { + "id": "RestJsonDeserializeMapUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes a map union value", + "result": { + "contents": { + "mapValue": { + "foo": "bar", + "spam": "eggs" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"contents\": {\n \"mapValue\": {\n \"foo\": \"bar\",\n \"spam\": \"eggs\"\n }\n }\n}" + } + }, + { + "id": "RestJsonDeserializeStructureUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Deserializes a structure union value", + "result": { + "contents": { + "structureValue": { + "hi": "hello" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"contents\": {\n \"structureValue\": {\n \"hi\": \"hello\"\n }\n }\n}" + } + }, + { + "id": "RestJsonDeserializeIgnoreType", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Ignores an unrecognized __type property", + "result": { + "contents": { + "structureValue": { + "hi": "hello" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"contents\": {\n \"__type\": \"aws.protocoltests.json10#MyUnion\",\n \"structureValue\": {\n \"hi\": \"hello\"\n }\n }\n}" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "documentValue": { - "shape": "DocumentType" - } - } - }, - "DocumentType": { - "type": "structure", - "document": true - } + { + "description": "Test cases for MediaTypeHeader operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "MediaTypeHeaderOutput": { + "type": "structure", + "members": { + "json": { + "shape": "JsonValue", + "jsonvalue": true, + "location": "header", + "locationName": "X-Json" + } + } + }, + "JsonValue": { + "type": "string" + } + }, + "cases": [ + { + "id": "MediaTypeHeaderOutputBase64", + "given": { + "name": "MediaTypeHeader", + "http": { + "method": "GET", + "requestUri": "/MediaTypeHeader", + "responseCode": 200 + }, + "output": { + "shape": "MediaTypeHeaderOutput" + }, + "documentation": "

This example ensures that mediaType strings are base64 encoded in headers.

" + }, + "description": "Headers that target strings with a mediaType are base64 encoded", + "result": { + "json": "true" + }, + "response": { + "status_code": 200, + "headers": { + "X-Json": "dHJ1ZQ==" + } + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "documentValue": { - "str": "test", - "num": 123, - "float": 1.2, - "bool": true, - "null": "", - "document": {"foo": false}, - "list": ["myname", 321, 1.3, true, "", {"nested": true}, [200, ""]] - } - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"documentValue\": {\"str\": \"test\", \"num\": 123, \"float\": 1.2, \"bool\": true, \"null\": \"\", \"document\": {\"foo\": false}, \"list\": [\"myname\", 321, 1.3, true, \"\", {\"nested\": true}, [200, \"\"]]}}" - } - }, - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "documentValue": [ - "test", - 123, - 1.2, - true, - "", - {"str": "myname", "num": 321, "float": 1.3, "bool": true, "null": "", "document": {"nested": true}, "list": [200, ""]}, - ["foo", false] - ] - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"documentValue\": [\"test\", 123, 1.2, true, \"\", {\"str\": \"myname\", \"num\": 321, \"float\": 1.3, \"bool\": true, \"null\": \"\", \"document\": {\"nested\": true}, \"list\": [200, \"\"]}, [\"foo\", false]]}" - } - } - ] - }, - { - "description": "Tagged Unions", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for NoInputAndNoOutput operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": {}, + "cases": [ + { + "id": "RestJsonNoInputAndNoOutput", + "given": { + "name": "NoInputAndNoOutput", + "http": { + "method": "POST", + "requestUri": "/NoInputAndNoOutput", + "responseCode": 200 + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input or output. While this should be rare, code generators must support this.

" + }, + "description": "When an operation does not define output, the service will respond\nwith an empty payload, and may optionally include the content-type\nheader.", + "result": {}, + "response": { + "status_code": 200, + "body": "" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "UnionMember": { - "shape": "UnionType" - } - } - }, - "UnionType": { - "type": "structure", - "members": { - "S":{"shape":"StringType"}, - "L": {"shape": "ListType"} - }, - "union": true - }, - "ListType": { - "type": "list", - "member": { - "shape": "StringType" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for NoInputAndOutput operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "NoInputAndOutputOutput": { + "type": "structure", + "members": {} + } + }, + "cases": [ + { + "id": "RestJsonNoInputAndOutputWithJson", + "given": { + "name": "NoInputAndOutput", + "http": { + "method": "POST", + "requestUri": "/NoInputAndOutputOutput", + "responseCode": 200 + }, + "output": { + "shape": "NoInputAndOutputOutput" + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input and the output is empty. While this should be rare, code generators must support this.

" + }, + "description": "Operations that define output and do not bind anything to\nthe payload return a JSON object in the response.", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{}" + } + }, + { + "id": "RestJsonNoInputAndOutputNoPayload", + "given": { + "name": "NoInputAndOutput", + "http": { + "method": "POST", + "requestUri": "/NoInputAndOutputOutput", + "responseCode": 200 + }, + "output": { + "shape": "NoInputAndOutputOutput" + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input and the output is empty. While this should be rare, code generators must support this.

" + }, + "description": "This test is similar to RestJsonNoInputAndOutputWithJson, but\nit ensures that clients can gracefully handle responses that\nomit a JSON payload.", + "result": {}, + "response": { + "status_code": 200, + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "UnionMember": {"S": "mystring"} - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"UnionMember\": {\"S\": \"mystring\"}}" - } - }, - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "UnionMember": {"L": ["a", "b"]} - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"UnionMember\": {\"L\": [\"a\", \"b\"]}}" - } - }, - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "UnionMember": {"SDK_UNKNOWN_MEMBER": {"name": "SomeUnknownMember"}} - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"UnionMember\": {\"SomeUnknownMember\": \"foo\"}}" - } - } - ] - }, - { - "description": "List in header", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for PostUnionWithJsonName operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "PostUnionWithJsonNameOutput": { + "type": "structure", + "required": [ + "value" + ], + "members": { + "value": { + "shape": "UnionWithJsonName" + } + } + }, + "UnionWithJsonName": { + "type": "structure", + "members": { + "foo": { + "shape": "String", + "locationName": "FOO" + }, + "bar": { + "shape": "String" + }, + "baz": { + "shape": "String", + "locationName": "_baz" + } + }, + "union": true + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "PostUnionWithJsonNameResponse1", + "given": { + "name": "PostUnionWithJsonName", + "http": { + "method": "POST", + "requestUri": "/PostUnionWithJsonName", + "responseCode": 200 + }, + "output": { + "shape": "PostUnionWithJsonNameOutput" + }, + "documentation": "

This operation defines a union that uses jsonName on some members.

" + }, + "description": "Tests that jsonName works with union members.", + "result": { + "value": { + "foo": "hi" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"value\": {\n \"FOO\": \"hi\"\n }\n}" + } + }, + { + "id": "PostUnionWithJsonNameResponse2", + "given": { + "name": "PostUnionWithJsonName", + "http": { + "method": "POST", + "requestUri": "/PostUnionWithJsonName", + "responseCode": 200 + }, + "output": { + "shape": "PostUnionWithJsonNameOutput" + }, + "documentation": "

This operation defines a union that uses jsonName on some members.

" + }, + "description": "Tests that jsonName works with union members.", + "result": { + "value": { + "baz": "hi" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"value\": {\n \"_baz\": \"hi\"\n }\n}" + } + }, + { + "id": "PostUnionWithJsonNameResponse3", + "given": { + "name": "PostUnionWithJsonName", + "http": { + "method": "POST", + "requestUri": "/PostUnionWithJsonName", + "responseCode": 200 + }, + "output": { + "shape": "PostUnionWithJsonNameOutput" + }, + "documentation": "

This operation defines a union that uses jsonName on some members.

" + }, + "description": "Tests that jsonName works with union members.", + "result": { + "value": { + "bar": "hi" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"value\": {\n \"bar\": \"hi\"\n }\n}" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "ListMember": { - "shape": "ListShape", - "location": "header", - "locationName": "x-amz-list-member" - } - } - }, - "ListShape": { - "type": "list", - "member": { - "shape": "EnumType" - } - }, - "EnumType": { - "type": "string", - "enum": ["one", "two", "three"] - } + { + "description": "Test cases for RecursiveShapes operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "RecursiveShapesInputOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "RecursiveShapesInputOutputNested1" + } + } + }, + "RecursiveShapesInputOutputNested1": { + "type": "structure", + "members": { + "foo": { + "shape": "String" + }, + "nested": { + "shape": "RecursiveShapesInputOutputNested2" + } + } + }, + "String": { + "type": "string" + }, + "RecursiveShapesInputOutputNested2": { + "type": "structure", + "members": { + "bar": { + "shape": "String" + }, + "recursiveMember": { + "shape": "RecursiveShapesInputOutputNested1" + } + } + } + }, + "cases": [ + { + "id": "RestJsonRecursiveShapes", + "given": { + "name": "RecursiveShapes", + "http": { + "method": "PUT", + "requestUri": "/RecursiveShapes", + "responseCode": 200 + }, + "output": { + "shape": "RecursiveShapesInputOutput" + }, + "documentation": "

Recursive shapes

", + "idempotent": true + }, + "description": "Serializes recursive structures", + "result": { + "nested": { + "foo": "Foo1", + "nested": { + "bar": "Bar1", + "recursiveMember": { + "foo": "Foo2", + "nested": { + "bar": "Bar2" + } + } + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"nested\": {\n \"foo\": \"Foo1\",\n \"nested\": {\n \"bar\": \"Bar1\",\n \"recursiveMember\": {\n \"foo\": \"Foo2\",\n \"nested\": {\n \"bar\": \"Bar2\"\n }\n }\n }\n }\n}" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "ListMember": ["one", "two", "three"] - }, - "response": { - "status_code": 200, - "headers": { - "x-amz-list-member": " one,two , three " - }, - "body": "" - } - } - ] - }, - { - "description": "Number in header", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for SimpleScalarProperties operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "SimpleScalarPropertiesInputOutput": { + "type": "structure", + "members": { + "foo": { + "shape": "String", + "location": "header", + "locationName": "X-Foo" + }, + "stringValue": { + "shape": "String" + }, + "trueBooleanValue": { + "shape": "Boolean" + }, + "falseBooleanValue": { + "shape": "Boolean" + }, + "byteValue": { + "shape": "Integer" + }, + "shortValue": { + "shape": "Integer" + }, + "integerValue": { + "shape": "Integer" + }, + "longValue": { + "shape": "Long" + }, + "floatValue": { + "shape": "Float" + }, + "doubleValue": { + "shape": "Double", + "locationName": "DoubleDribble" + } + } + }, + "String": { + "type": "string" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + }, + "Long": { + "type": "long", + "box": true + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + } + }, + "cases": [ + { + "id": "RestJsonSimpleScalarProperties", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "output": { + "shape": "SimpleScalarPropertiesInputOutput" + }, + "idempotent": true + }, + "description": "Serializes simple scalar properties", + "result": { + "foo": "Foo", + "stringValue": "string", + "trueBooleanValue": true, + "falseBooleanValue": false, + "byteValue": 1, + "shortValue": 2, + "integerValue": 3, + "longValue": 4, + "floatValue": 5.5, + "doubleValue": 6.5 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json", + "X-Foo": "Foo" + }, + "body": "{\n \"stringValue\": \"string\",\n \"trueBooleanValue\": true,\n \"falseBooleanValue\": false,\n \"byteValue\": 1,\n \"shortValue\": 2,\n \"integerValue\": 3,\n \"longValue\": 4,\n \"floatValue\": 5.5,\n \"DoubleDribble\": 6.5\n}" + } + }, + { + "id": "RestJsonDoesntDeserializeNullStructureValues", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "output": { + "shape": "SimpleScalarPropertiesInputOutput" + }, + "idempotent": true + }, + "description": "Rest Json should not deserialize null structure values", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"stringValue\": null\n}" + } + }, + { + "id": "RestJsonSupportsNaNFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "output": { + "shape": "SimpleScalarPropertiesInputOutput" + }, + "idempotent": true + }, + "description": "Supports handling NaN float values.", + "result": { + "floatValue": "NaN", + "doubleValue": "NaN" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"floatValue\": \"NaN\",\n \"DoubleDribble\": \"NaN\"\n}" + } + }, + { + "id": "RestJsonSupportsInfinityFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "output": { + "shape": "SimpleScalarPropertiesInputOutput" + }, + "idempotent": true + }, + "description": "Supports handling Infinity float values.", + "result": { + "floatValue": "Infinity", + "doubleValue": "Infinity" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"floatValue\": \"Infinity\",\n \"DoubleDribble\": \"Infinity\"\n}" + } + }, + { + "id": "RestJsonSupportsNegativeInfinityFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "output": { + "shape": "SimpleScalarPropertiesInputOutput" + }, + "idempotent": true + }, + "description": "Supports handling -Infinity float values.", + "result": { + "floatValue": "-Infinity", + "doubleValue": "-Infinity" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"floatValue\": \"-Infinity\",\n \"DoubleDribble\": \"-Infinity\"\n}" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "IntegerMember": { - "shape": "IntegerShape", - "location": "header", - "locationName": "x-amz-integer-member" - }, - "LongMember": { - "shape": "LongShape", - "location": "header", - "locationName": "x-amz-long-member" - } - } - }, - "IntegerShape": { - "type": "integer" - }, - "LongShape": { - "type": "long" - } + { + "description": "Test cases for TimestampFormatHeaders operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "TimestampFormatHeadersIO": { + "type": "structure", + "members": { + "memberEpochSeconds": { + "shape": "SyntheticTimestamp_epoch_seconds", + "location": "header", + "locationName": "X-memberEpochSeconds" + }, + "memberHttpDate": { + "shape": "SyntheticTimestamp_http_date", + "location": "header", + "locationName": "X-memberHttpDate" + }, + "memberDateTime": { + "shape": "SyntheticTimestamp_date_time", + "location": "header", + "locationName": "X-memberDateTime" + }, + "defaultFormat": { + "shape": "Timestamp", + "location": "header", + "locationName": "X-defaultFormat" + }, + "targetEpochSeconds": { + "shape": "EpochSeconds", + "location": "header", + "locationName": "X-targetEpochSeconds" + }, + "targetHttpDate": { + "shape": "HttpDate", + "location": "header", + "locationName": "X-targetHttpDate" + }, + "targetDateTime": { + "shape": "DateTime", + "location": "header", + "locationName": "X-targetDateTime" + } + } + }, + "SyntheticTimestamp_epoch_seconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "SyntheticTimestamp_http_date": { + "type": "timestamp", + "timestampFormat": "rfc822" + }, + "SyntheticTimestamp_date_time": { + "type": "timestamp", + "timestampFormat": "iso8601" + }, + "Timestamp": { + "type": "timestamp" + }, + "EpochSeconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "HttpDate": { + "type": "timestamp", + "timestampFormat": "rfc822" + }, + "DateTime": { + "type": "timestamp", + "timestampFormat": "iso8601" + } + }, + "cases": [ + { + "id": "RestJsonTimestampFormatHeaders", + "given": { + "name": "TimestampFormatHeaders", + "http": { + "method": "POST", + "requestUri": "/TimestampFormatHeaders", + "responseCode": 200 + }, + "output": { + "shape": "TimestampFormatHeadersIO" + }, + "documentation": "

This example tests how timestamp request and response headers are serialized.

" + }, + "description": "Tests how timestamp response headers are serialized", + "result": { + "memberEpochSeconds": 1576540098, + "memberHttpDate": 1576540098, + "memberDateTime": 1576540098, + "defaultFormat": 1576540098, + "targetEpochSeconds": 1576540098, + "targetHttpDate": 1576540098, + "targetDateTime": 1576540098 + }, + "response": { + "status_code": 200, + "headers": { + "X-defaultFormat": "Mon, 16 Dec 2019 23:48:18 GMT", + "X-memberDateTime": "2019-12-16T23:48:18Z", + "X-memberEpochSeconds": "1576540098", + "X-memberHttpDate": "Mon, 16 Dec 2019 23:48:18 GMT", + "X-targetDateTime": "2019-12-16T23:48:18Z", + "X-targetEpochSeconds": "1576540098", + "X-targetHttpDate": "Mon, 16 Dec 2019 23:48:18 GMT" + } + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "IntegerMember": 123, - "LongMember": 200 - }, - "response": { - "status_code": 200, - "headers": { - "x-amz-integer-member": "123", - "x-amz-long-member": "200" - }, - "body": "" - } - } - ] - } + { + "description": "Test cases for UnitInputAndOutput operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": {}, + "cases": [ + { + "id": "RestJsonUnitInputAndOutputNoOutput", + "given": { + "name": "UnitInputAndOutput", + "http": { + "method": "POST", + "requestUri": "/UnitInputAndOutput", + "responseCode": 200 + }, + "documentation": "

This test is similar to NoInputAndNoOutput, but uses explicit Unit types.

" + }, + "description": "When an operation defines Unit output, the service will respond\nwith an empty payload, and may optionally include the content-type\nheader.", + "result": {}, + "response": { + "status_code": 200, + "body": "" + } + } + ] + } ] diff --git a/tests/unit/protocols/output/rest-xml.json b/tests/unit/protocols/output/rest-xml.json index 8da4680960..25ddff80e3 100644 --- a/tests/unit/protocols/output/rest-xml.json +++ b/tests/unit/protocols/output/rest-xml.json @@ -1,1273 +1,4540 @@ [ - { - "description": "Scalar members", - "metadata": { - "protocol": "rest-xml" + { + "description": "Test cases for BodyWithXmlName operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "BodyWithXmlNameInputOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "PayloadWithXmlName" + } + }, + "locationName": "Ahoy" + }, + "PayloadWithXmlName": { + "type": "structure", + "members": { + "name": { + "shape": "String" + } + }, + "locationName": "Hello" + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "BodyWithXmlName", + "given": { + "name": "BodyWithXmlName", + "http": { + "method": "PUT", + "requestUri": "/BodyWithXmlName", + "responseCode": 200 + }, + "output": { + "shape": "BodyWithXmlNameInputOutput" + }, + "documentation": "

The following example serializes a body that uses an XML name, changing the wrapper name.

", + "idempotent": true + }, + "description": "Serializes a payload using a wrapper name based on the xmlName", + "result": { + "nested": { + "name": "Phreddy" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "Phreddy" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "ImaHeader": { - "shape": "HeaderShape" - }, - "ImaHeaderLocation": { - "shape": "HeaderShape", - "locationName": "X-Foo" - }, - "Str": { - "shape": "StringType" - }, - "Num": { - "shape": "IntegerType", - "locationName": "FooNum" - }, - "FalseBool": { - "shape": "BooleanType" - }, - "TrueBool": { - "shape": "BooleanType" - }, - "Float": { - "shape": "FloatType" - }, - "Double": { - "shape": "DoubleType" - }, - "Long": { - "shape": "LongType" - }, - "Char": { - "shape": "CharType" - }, - "Timestamp": { - "shape": "TimestampType" - } - } - }, - "StringType": { - "type": "string" - }, - "IntegerType": { - "type": "integer" - }, - "BooleanType": { - "type": "boolean" - }, - "FloatType": { - "type": "float" - }, - "DoubleType": { - "type": "double" - }, - "LongType": { - "type": "long" - }, - "CharType": { - "type": "character" - }, - "HeaderShape": { - "type": "string", - "location": "header" - }, - "StatusShape": { - "type": "integer", - "location": "statusCode" - }, - "TimestampType": { - "type": "timestamp" - } + { + "description": "Test cases for DatetimeOffsets operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "DatetimeOffsetsOutput": { + "type": "structure", + "members": { + "datetime": { + "shape": "DateTime" + } + } + }, + "DateTime": { + "type": "timestamp", + "timestampFormat": "iso8601" + } + }, + "cases": [ + { + "id": "RestXmlDateTimeWithNegativeOffset", + "given": { + "name": "DatetimeOffsets", + "http": { + "method": "POST", + "requestUri": "/DatetimeOffsets", + "responseCode": 200 + }, + "output": { + "shape": "DatetimeOffsetsOutput" + } + }, + "description": "Ensures that clients can correctly parse datetime (timestamps) with offsets", + "result": { + "datetime": 1576540098 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n 2019-12-16T22:48:18-01:00\n\n" + } + }, + { + "id": "RestXmlDateTimeWithPositiveOffset", + "given": { + "name": "DatetimeOffsets", + "http": { + "method": "POST", + "requestUri": "/DatetimeOffsets", + "responseCode": 200 + }, + "output": { + "shape": "DatetimeOffsetsOutput" + } + }, + "description": "Ensures that clients can correctly parse datetime (timestamps) with offsets", + "result": { + "datetime": 1576540098 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n 2019-12-17T00:48:18+01:00\n\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "ImaHeader": "test", - "ImaHeaderLocation": "abc", - "Str": "myname", - "Num": 123, - "FalseBool": false, - "TrueBool": true, - "Float": 1.2, - "Double": 1.3, - "Long": 200, - "Char": "a", - "Timestamp": 1422172800 - }, - "response": { - "status_code": 200, - "headers": { - "ImaHeader": "test", - "X-Foo": "abc" - }, - "body": "myname123falsetrue1.21.3200a2015-01-25T08:00:00Z" - } - }, - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "ImaHeader": "test", - "ImaHeaderLocation": "abc", - "Str": "", - "Num": 123, - "FalseBool": false, - "TrueBool": true, - "Float": 1.2, - "Double": 1.3, - "Long": 200, - "Char": "a", - "Timestamp": 1422172800 - }, - "response": { - "status_code": 200, - "headers": { - "ImaHeader": "test", - "X-Foo": "abc" - }, - "body": "123falsetrue1.21.3200a2015-01-25T08:00:00Z" - } - } - ] - }, - { - "description": "Blob", - "metadata": { - "protocol": "rest-xml" + { + "description": "Test cases for EmptyInputAndEmptyOutput operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "EmptyInputAndEmptyOutputOutput": { + "type": "structure", + "members": {} + } + }, + "cases": [ + { + "id": "EmptyInputAndEmptyOutput", + "given": { + "name": "EmptyInputAndEmptyOutput", + "http": { + "method": "POST", + "requestUri": "/EmptyInputAndEmptyOutput", + "responseCode": 200 + }, + "output": { + "shape": "EmptyInputAndEmptyOutputOutput" + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response payload because the operation has an empty input and empty output structure that reuses the same shape. While this should be rare, code generators must support this.

" + }, + "description": "Empty output serializes no payload", + "result": {}, + "response": { + "status_code": 200, + "body": "" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Blob": { - "shape": "BlobType" - } - } - }, - "BlobType": { - "type": "blob" - } + { + "description": "Test cases for FlattenedXmlMap operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "FlattenedXmlMapResponse": { + "type": "structure", + "members": { + "myMap": { + "shape": "FooEnumMap", + "flattened": true + } + } + }, + "FooEnumMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "FooEnum" + } + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "FlattenedXmlMap", + "given": { + "name": "FlattenedXmlMap", + "http": { + "method": "POST", + "requestUri": "/FlattenedXmlMap", + "responseCode": 200 + }, + "output": { + "shape": "FlattenedXmlMapResponse" + }, + "documentation": "

Flattened maps

" + }, + "description": "Serializes flattened XML maps in responses", + "result": { + "myMap": { + "foo": "Foo", + "baz": "Baz" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n \n foo\n Foo\n \n \n baz\n Baz\n \n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Blob": "value" - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "dmFsdWU=" - } - } - ] - }, - { - "description": "Lists", - "metadata": { - "protocol": "rest-xml" + { + "description": "Test cases for FlattenedXmlMapWithXmlName operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "FlattenedXmlMapWithXmlNameResponse": { + "type": "structure", + "members": { + "myMap": { + "shape": "FlattenedXmlMapWithXmlNameInputOutputMap", + "flattened": true, + "locationName": "KVP" + } + } + }, + "FlattenedXmlMapWithXmlNameInputOutputMap": { + "type": "map", + "key": { + "shape": "String", + "locationName": "K" + }, + "value": { + "shape": "String", + "locationName": "V" + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "FlattenedXmlMapWithXmlName", + "given": { + "name": "FlattenedXmlMapWithXmlName", + "http": { + "method": "POST", + "requestUri": "/FlattenedXmlMapWithXmlName", + "responseCode": 200 + }, + "output": { + "shape": "FlattenedXmlMapWithXmlNameResponse" + }, + "documentation": "

Flattened maps with @xmlName

" + }, + "description": "Serializes flattened XML maps in responses that have xmlName on members", + "result": { + "myMap": { + "a": "A", + "b": "B" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n \n a\n A\n \n \n b\n B\n \n" + } + } + ] + }, + { + "description": "Test cases for FlattenedXmlMapWithXmlNamespace operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "FlattenedXmlMapWithXmlNamespaceOutput": { + "type": "structure", + "members": { + "myMap": { + "shape": "FlattenedXmlMapWithXmlNamespaceOutputMap", + "flattened": true, + "locationName": "KVP", + "xmlNamespace": "https://the-member.example.com" + } + } + }, + "FlattenedXmlMapWithXmlNamespaceOutputMap": { + "type": "map", + "key": { + "shape": "String", + "locationName": "K", + "xmlNamespace": "https://the-key.example.com" + }, + "value": { + "shape": "String", + "locationName": "V", + "xmlNamespace": "https://the-value.example.com" + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestXmlFlattenedXmlMapWithXmlNamespace", + "given": { + "name": "FlattenedXmlMapWithXmlNamespace", + "http": { + "method": "POST", + "requestUri": "/FlattenedXmlMapWithXmlNamespace", + "responseCode": 200 + }, + "output": { + "shape": "FlattenedXmlMapWithXmlNamespaceOutput" + }, + "documentation": "

Flattened maps with @xmlNamespace and @xmlName

" + }, + "description": "Serializes flattened XML maps in responses that have xmlNamespace and xmlName on members", + "result": { + "myMap": { + "a": "A", + "b": "B" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n \n a\n A\n \n \n b\n B\n \n" + } + } + ] + }, + { + "description": "Test cases for FractionalSeconds operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "FractionalSecondsOutput": { + "type": "structure", + "members": { + "datetime": { + "shape": "DateTime" + } + } + }, + "DateTime": { + "type": "timestamp", + "timestampFormat": "iso8601" + } + }, + "cases": [ + { + "id": "RestXmlDateTimeWithFractionalSeconds", + "given": { + "name": "FractionalSeconds", + "http": { + "method": "POST", + "requestUri": "/FractionalSeconds", + "responseCode": 200 + }, + "output": { + "shape": "FractionalSecondsOutput" + } + }, + "description": "Ensures that clients can correctly parse datetime timestamps with fractional seconds", + "result": { + "datetime": 9.46845296123E8 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n 2000-01-02T20:34:56.123Z\n\n" + } + } + ] + }, + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "GreetingWithErrorsOutput": { + "type": "structure", + "members": { + "greeting": { + "shape": "String", + "location": "header", + "locationName": "X-Greeting" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "GreetingWithErrors", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "output": { + "shape": "GreetingWithErrorsOutput" + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A BadRequest error.

Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the

", + "idempotent": true + }, + "description": "Ensures that operations with errors successfully know how to deserialize the successful response", + "result": { + "greeting": "Hello" + }, + "response": { + "status_code": 200, + "headers": { + "X-Greeting": "Hello" + }, + "body": "" + } + } + ] + }, + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "InvalidGreeting": { + "type": "structure", + "members": { + "Message": { + "shape": "String" + } + }, + "documentation": "

This error is thrown when an invalid greeting value is provided.

", + "error": { + "httpStatusCode": 400, + "senderFault": true + }, + "exception": true + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "InvalidGreetingError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A BadRequest error.

Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the

", + "idempotent": true, + "errors": [ + { + "shape": "InvalidGreeting" + } + ] + }, + "description": "Parses simple XML errors", + "errorCode": "InvalidGreeting", + "errorMessage": "Hi", + "error": { + "Message": "Hi" + }, + "response": { + "status_code": 400, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n \n Sender\n InvalidGreeting\n Hi\n setting\n \n foo-id\n\n" + } + } + ] + }, + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "ComplexError": { + "type": "structure", + "members": { + "Header": { + "shape": "String", + "location": "header", + "locationName": "X-Header" + }, + "TopLevel": { + "shape": "String" + }, + "Nested": { + "shape": "ComplexNestedErrorData" + } + }, + "documentation": "

This error is thrown when a request is invalid.

", + "error": { + "httpStatusCode": 403, + "senderFault": true + }, + "exception": true + }, + "String": { + "type": "string" + }, + "ComplexNestedErrorData": { + "type": "structure", + "members": { + "Foo": { + "shape": "String" + } + } + } + }, + "cases": [ + { + "id": "ComplexError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "

This operation has three possible return values:

  1. A successful response in the form of GreetingWithErrorsOutput
  2. An InvalidGreeting error.
  3. A BadRequest error.

Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the

", + "idempotent": true, + "errors": [ + { + "shape": "ComplexError" + } + ] + }, + "errorCode": "ComplexError", + "error": { + "Header": "Header", + "TopLevel": "Top level", + "Nested": { + "Foo": "bar" + } + }, + "response": { + "status_code": 403, + "headers": { + "Content-Type": "application/xml", + "X-Header": "Header" + }, + "body": "\n \n Sender\n ComplexError\n Hi\n Top level\n \n bar\n \n \n foo-id\n\n" + } + } + ] + }, + { + "description": "Test cases for HttpEnumPayload operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "EnumPayloadInput": { + "type": "structure", + "members": { + "payload": { + "shape": "StringEnum" + } + }, + "payload": "payload" + }, + "StringEnum": { + "type": "string", + "enum": [ + "enumvalue" + ] + } + }, + "cases": [ + { + "id": "RestXmlEnumPayloadResponse", + "given": { + "name": "HttpEnumPayload", + "http": { + "method": "POST", + "requestUri": "/EnumPayload", + "responseCode": 200 + }, + "output": { + "shape": "EnumPayloadInput" + } + }, + "result": { + "payload": "enumvalue" + }, + "response": { + "status_code": 200, + "body": "enumvalue" + } + } + ] + }, + { + "description": "Test cases for HttpPayloadTraits operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPayloadTraitsInputOutput": { + "type": "structure", + "members": { + "foo": { + "shape": "String", + "location": "header", + "locationName": "X-Foo" + }, + "blob": { + "shape": "Blob" + } + }, + "payload": "blob" + }, + "String": { + "type": "string" + }, + "Blob": { + "type": "blob" + } + }, + "cases": [ + { + "id": "HttpPayloadTraitsWithBlob", + "given": { + "name": "HttpPayloadTraits", + "http": { + "method": "POST", + "requestUri": "/HttpPayloadTraits", + "responseCode": 200 + }, + "output": { + "shape": "HttpPayloadTraitsInputOutput" + }, + "documentation": "

This example serializes a blob shape in the payload.

In this example, no XML document is synthesized because the payload is not a structure or a union type.

" + }, + "description": "Serializes a blob in the HTTP payload", + "result": { + "foo": "Foo", + "blob": "blobby blob blob" + }, + "response": { + "status_code": 200, + "headers": { + "X-Foo": "Foo" + }, + "body": "blobby blob blob" + } + }, + { + "id": "HttpPayloadTraitsWithNoBlobBody", + "given": { + "name": "HttpPayloadTraits", + "http": { + "method": "POST", + "requestUri": "/HttpPayloadTraits", + "responseCode": 200 + }, + "output": { + "shape": "HttpPayloadTraitsInputOutput" + }, + "documentation": "

This example serializes a blob shape in the payload.

In this example, no XML document is synthesized because the payload is not a structure or a union type.

" + }, + "description": "Serializes an empty blob in the HTTP payload", + "result": { + "foo": "Foo" + }, + "response": { + "status_code": 200, + "headers": { + "X-Foo": "Foo" + }, + "body": "" + } + } + ] + }, + { + "description": "Test cases for HttpPayloadWithMemberXmlName operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPayloadWithMemberXmlNameInputOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "PayloadWithXmlName", + "locationName": "Hola" + } + }, + "payload": "nested" + }, + "PayloadWithXmlName": { + "type": "structure", + "members": { + "name": { + "shape": "String" + } + }, + "locationName": "Hello" + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "HttpPayloadWithMemberXmlName", + "given": { + "name": "HttpPayloadWithMemberXmlName", + "http": { + "method": "PUT", + "requestUri": "/HttpPayloadWithMemberXmlName", + "responseCode": 200 + }, + "output": { + "shape": "HttpPayloadWithMemberXmlNameInputOutput" + }, + "documentation": "

The following example serializes a payload that uses an XML name on the member, changing the wrapper name.

", + "idempotent": true + }, + "description": "Serializes a structure in the payload using a wrapper name based on member xmlName", + "result": { + "nested": { + "name": "Phreddy" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "Phreddy" + } + } + ] + }, + { + "description": "Test cases for HttpPayloadWithStructure operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPayloadWithStructureInputOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "NestedPayload", + "locationName": "NestedPayload" + } + }, + "payload": "nested" + }, + "NestedPayload": { + "type": "structure", + "members": { + "greeting": { + "shape": "String" + }, + "name": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "HttpPayloadWithStructure", + "given": { + "name": "HttpPayloadWithStructure", + "http": { + "method": "PUT", + "requestUri": "/HttpPayloadWithStructure", + "responseCode": 200 + }, + "output": { + "shape": "HttpPayloadWithStructureInputOutput" + }, + "documentation": "

This example serializes a structure in the payload.

Note that serializing a structure changes the wrapper element name to match the targeted structure.

", + "idempotent": true + }, + "description": "Serializes a structure in the payload", + "result": { + "nested": { + "greeting": "hello", + "name": "Phreddy" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n hello\n Phreddy\n\n" + } + } + ] + }, + { + "description": "Test cases for HttpPayloadWithUnion operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPayloadWithUnionInputOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "UnionPayload", + "locationName": "nested" + } + }, + "payload": "nested" + }, + "UnionPayload": { + "type": "structure", + "members": { + "greeting": { + "shape": "String" + } + }, + "union": true + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestXmlHttpPayloadWithUnion", + "given": { + "name": "HttpPayloadWithUnion", + "http": { + "method": "PUT", + "requestUri": "/HttpPayloadWithUnion", + "responseCode": 200 + }, + "output": { + "shape": "HttpPayloadWithUnionInputOutput" + }, + "documentation": "

This example serializes a union in the payload.

", + "idempotent": true + }, + "description": "Serializes a union in the payload.", + "result": { + "nested": { + "greeting": "hello" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n hello\n" + } + }, + { + "id": "RestXmlHttpPayloadWithUnsetUnion", + "given": { + "name": "HttpPayloadWithUnion", + "http": { + "method": "PUT", + "requestUri": "/HttpPayloadWithUnion", + "responseCode": 200 + }, + "output": { + "shape": "HttpPayloadWithUnionInputOutput" + }, + "documentation": "

This example serializes a union in the payload.

", + "idempotent": true + }, + "description": "No payload is sent if the union has no value.", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Length": "0" + }, + "body": "" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "ListMember": { - "shape": "ListShape" - } - } - }, - "ListShape": { - "type": "list", - "member": { - "shape": "StringType" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for HttpPayloadWithXmlName operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPayloadWithXmlNameInputOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "PayloadWithXmlName", + "locationName": "nested" + } + }, + "payload": "nested" + }, + "PayloadWithXmlName": { + "type": "structure", + "members": { + "name": { + "shape": "String" + } + }, + "locationName": "Hello" + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "HttpPayloadWithXmlName", + "given": { + "name": "HttpPayloadWithXmlName", + "http": { + "method": "PUT", + "requestUri": "/HttpPayloadWithXmlName", + "responseCode": 200 + }, + "output": { + "shape": "HttpPayloadWithXmlNameInputOutput" + }, + "documentation": "

The following example serializes a payload that uses an XML name, changing the wrapper name.

", + "idempotent": true + }, + "description": "Serializes a structure in the payload using a wrapper name based on xmlName", + "result": { + "nested": { + "name": "Phreddy" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "Phreddy" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "ListMember": ["abc", "123"] - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "abc123" - } - } - ] - }, - { - "description": "List with custom member name", - "metadata": { - "protocol": "rest-xml" + { + "description": "Test cases for HttpPayloadWithXmlNamespace operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPayloadWithXmlNamespaceInputOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "PayloadWithXmlNamespace", + "locationName": "nested" + } + }, + "payload": "nested" + }, + "PayloadWithXmlNamespace": { + "type": "structure", + "members": { + "name": { + "shape": "String" + } + }, + "xmlNamespace": "http://foo.com" + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "HttpPayloadWithXmlNamespace", + "given": { + "name": "HttpPayloadWithXmlNamespace", + "http": { + "method": "PUT", + "requestUri": "/HttpPayloadWithXmlNamespace", + "responseCode": 200 + }, + "output": { + "shape": "HttpPayloadWithXmlNamespaceInputOutput" + }, + "documentation": "

The following example serializes a payload that uses an XML namespace.

", + "idempotent": true + }, + "description": "Serializes a structure in the payload using a wrapper with an XML namespace", + "result": { + "nested": { + "name": "Phreddy" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n Phreddy\n" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "ListMember": { - "shape": "ListShape" - } - } - }, - "ListShape": { - "type": "list", - "member": { - "shape": "StringType", - "locationName": "item" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for HttpPayloadWithXmlNamespaceAndPrefix operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPayloadWithXmlNamespaceAndPrefixInputOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "PayloadWithXmlNamespaceAndPrefix", + "locationName": "nested" + } + }, + "payload": "nested" + }, + "PayloadWithXmlNamespaceAndPrefix": { + "type": "structure", + "members": { + "name": { + "shape": "String" + } + }, + "xmlNamespace": { + "prefix": "baz", + "uri": "http://foo.com" + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "HttpPayloadWithXmlNamespaceAndPrefix", + "given": { + "name": "HttpPayloadWithXmlNamespaceAndPrefix", + "http": { + "method": "PUT", + "requestUri": "/HttpPayloadWithXmlNamespaceAndPrefix", + "responseCode": 200 + }, + "output": { + "shape": "HttpPayloadWithXmlNamespaceAndPrefixInputOutput" + }, + "documentation": "

The following example serializes a payload that uses an XML namespace.

", + "idempotent": true + }, + "description": "Serializes a structure in the payload using a wrapper with an XML namespace", + "result": { + "nested": { + "name": "Phreddy" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n Phreddy\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "ListMember": ["abc", "123"] - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "abc123" - } - } - ] - }, - { - "description": "Flattened List", - "metadata": { - "protocol": "rest-xml" + { + "description": "Test cases for HttpPrefixHeaders operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPrefixHeadersInputOutput": { + "type": "structure", + "members": { + "foo": { + "shape": "String", + "location": "header", + "locationName": "X-Foo" + }, + "fooMap": { + "shape": "FooPrefixHeaders", + "location": "headers", + "locationName": "X-Foo-" + } + } + }, + "String": { + "type": "string" + }, + "FooPrefixHeaders": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "String" + } + } + }, + "cases": [ + { + "id": "HttpPrefixHeadersArePresent", + "given": { + "name": "HttpPrefixHeaders", + "http": { + "method": "GET", + "requestUri": "/HttpPrefixHeaders", + "responseCode": 200 + }, + "output": { + "shape": "HttpPrefixHeadersInputOutput" + }, + "documentation": "

This examples adds headers to the input of a request and response by prefix.

" + }, + "description": "Adds headers by prefix", + "result": { + "foo": "Foo", + "fooMap": { + "Abc": "Abc value", + "Def": "Def value" + } + }, + "response": { + "status_code": 200, + "headers": { + "X-Foo": "Foo", + "X-Foo-Abc": "Abc value", + "X-Foo-Def": "Def value" + }, + "body": "" + } + }, + { + "id": "HttpPrefixHeadersAreNotPresent", + "given": { + "name": "HttpPrefixHeaders", + "http": { + "method": "GET", + "requestUri": "/HttpPrefixHeaders", + "responseCode": 200 + }, + "output": { + "shape": "HttpPrefixHeadersInputOutput" + }, + "documentation": "

This examples adds headers to the input of a request and response by prefix.

" + }, + "description": "No prefix headers are serialized because the value is empty", + "result": { + "foo": "Foo", + "fooMap": {} + }, + "response": { + "status_code": 200, + "headers": { + "X-Foo": "Foo" + }, + "body": "" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "ListMember": { - "shape": "StringList", - "flattened": true - } - } - }, - "StringList": { - "type": "list", - "member": { - "shape": "StringType" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for HttpResponseCode operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpResponseCodeOutput": { + "type": "structure", + "members": { + "Status": { + "shape": "Integer", + "location": "statusCode" + } + } + }, + "Integer": { + "type": "integer", + "box": true + } + }, + "cases": [ + { + "id": "RestXmlHttpResponseCode", + "given": { + "name": "HttpResponseCode", + "http": { + "method": "PUT", + "requestUri": "/HttpResponseCode", + "responseCode": 200 + }, + "output": { + "shape": "HttpResponseCodeOutput" + }, + "idempotent": true + }, + "description": "Binds the http response code to an output structure.", + "result": { + "Status": 201 + }, + "response": { + "status_code": 201, + "headers": { + "Content-Type": "application/xml" + }, + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "ListMember": ["abc", "123"] - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "abc123" - } - } - ] - }, - { - "description": "Normal map", - "metadata": { - "protocol": "rest-xml" + { + "description": "Test cases for HttpStringPayload operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "StringPayloadInput": { + "type": "structure", + "members": { + "payload": { + "shape": "String" + } + }, + "payload": "payload" + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestXmlStringPayloadResponse", + "given": { + "name": "HttpStringPayload", + "http": { + "method": "POST", + "requestUri": "/StringPayload", + "responseCode": 200 + }, + "output": { + "shape": "StringPayloadInput" + } + }, + "result": { + "payload": "rawstring" + }, + "response": { + "status_code": 200, + "body": "rawstring" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Map": { - "shape": "StringMap" - } - } - }, - "StringMap": { - "type": "map", - "key": { - "shape": "StringType" - }, - "value": { - "shape": "SingleStructure" - } - }, - "SingleStructure": { - "type": "structure", - "members": { - "foo": { - "shape": "StringType" - } - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for IgnoreQueryParamsInResponse operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "IgnoreQueryParamsInResponseOutput": { + "type": "structure", + "members": { + "baz": { + "shape": "String", + "location": "uri", + "locationName": "baz" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "IgnoreQueryParamsInResponse", + "given": { + "name": "IgnoreQueryParamsInResponse", + "http": { + "method": "GET", + "requestUri": "/IgnoreQueryParamsInResponse", + "responseCode": 200 + }, + "output": { + "shape": "IgnoreQueryParamsInResponseOutput" + }, + "documentation": "

This example ensures that query string bound request parameters are serialized in the body of responses if the structure is used in both the request and response.

" + }, + "description": "Query parameters must be ignored when serializing the output of an operation", + "result": { + "baz": "bam" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "bam" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Map": { - "qux": { - "foo": "bar" - }, - "baz": { - "foo": "bam" - } - } - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "quxbarbazbam" - } - } - ] - }, - { - "description": "Flattened map", - "metadata": { - "protocol": "rest-xml" + { + "description": "Test cases for InputAndOutputWithHeaders operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "InputAndOutputWithHeadersIO": { + "type": "structure", + "members": { + "headerString": { + "shape": "String", + "location": "header", + "locationName": "X-String" + }, + "headerByte": { + "shape": "Integer", + "location": "header", + "locationName": "X-Byte" + }, + "headerShort": { + "shape": "Integer", + "location": "header", + "locationName": "X-Short" + }, + "headerInteger": { + "shape": "Integer", + "location": "header", + "locationName": "X-Integer" + }, + "headerLong": { + "shape": "Long", + "location": "header", + "locationName": "X-Long" + }, + "headerFloat": { + "shape": "Float", + "location": "header", + "locationName": "X-Float" + }, + "headerDouble": { + "shape": "Double", + "location": "header", + "locationName": "X-Double" + }, + "headerTrueBool": { + "shape": "Boolean", + "location": "header", + "locationName": "X-Boolean1" + }, + "headerFalseBool": { + "shape": "Boolean", + "location": "header", + "locationName": "X-Boolean2" + }, + "headerStringList": { + "shape": "StringList", + "location": "header", + "locationName": "X-StringList" + }, + "headerStringSet": { + "shape": "StringSet", + "location": "header", + "locationName": "X-StringSet" + }, + "headerIntegerList": { + "shape": "IntegerList", + "location": "header", + "locationName": "X-IntegerList" + }, + "headerBooleanList": { + "shape": "BooleanList", + "location": "header", + "locationName": "X-BooleanList" + }, + "headerTimestampList": { + "shape": "TimestampList", + "location": "header", + "locationName": "X-TimestampList" + }, + "headerEnum": { + "shape": "FooEnum", + "location": "header", + "locationName": "X-Enum" + }, + "headerEnumList": { + "shape": "FooEnumList", + "location": "header", + "locationName": "X-EnumList" + } + } + }, + "String": { + "type": "string" + }, + "Integer": { + "type": "integer", + "box": true + }, + "Long": { + "type": "long", + "box": true + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringSet": { + "type": "list", + "member": { + "shape": "String" + } + }, + "IntegerList": { + "type": "list", + "member": { + "shape": "Integer" + } + }, + "BooleanList": { + "type": "list", + "member": { + "shape": "Boolean" + } + }, + "TimestampList": { + "type": "list", + "member": { + "shape": "Timestamp" + } + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "Timestamp": { + "type": "timestamp" + } + }, + "cases": [ + { + "id": "InputAndOutputWithStringHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Tests responses with string header bindings", + "result": { + "headerString": "Hello", + "headerStringList": [ + "a", + "b", + "c" + ], + "headerStringSet": [ + "a", + "b", + "c" + ] + }, + "response": { + "status_code": 200, + "headers": { + "X-String": "Hello", + "X-StringList": "a, b, c", + "X-StringSet": "a, b, c" + }, + "body": "" + } + }, + { + "id": "InputAndOutputWithNumericHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Tests responses with numeric header bindings", + "result": { + "headerByte": 1, + "headerShort": 123, + "headerInteger": 123, + "headerLong": 123, + "headerFloat": 1.1, + "headerDouble": 1.1, + "headerIntegerList": [ + 1, + 2, + 3 + ] + }, + "response": { + "status_code": 200, + "headers": { + "X-Byte": "1", + "X-Double": "1.1", + "X-Float": "1.1", + "X-Integer": "123", + "X-IntegerList": "1, 2, 3", + "X-Long": "123", + "X-Short": "123" + }, + "body": "" + } + }, + { + "id": "InputAndOutputWithBooleanHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Tests responses with boolean header bindings", + "result": { + "headerTrueBool": true, + "headerFalseBool": false, + "headerBooleanList": [ + true, + false, + true + ] + }, + "response": { + "status_code": 200, + "headers": { + "X-Boolean1": "true", + "X-Boolean2": "false", + "X-BooleanList": "true, false, true" + }, + "body": "" + } + }, + { + "id": "InputAndOutputWithTimestampHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Tests responses with timestamp header bindings", + "result": { + "headerTimestampList": [ + 1576540098, + 1576540098 + ] + }, + "response": { + "status_code": 200, + "headers": { + "X-TimestampList": "Mon, 16 Dec 2019 23:48:18 GMT, Mon, 16 Dec 2019 23:48:18 GMT" + }, + "body": "" + } + }, + { + "id": "InputAndOutputWithEnumHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Tests responses with enum header bindings", + "result": { + "headerEnum": "Foo", + "headerEnumList": [ + "Foo", + "Bar", + "Baz" + ] + }, + "response": { + "status_code": 200, + "headers": { + "X-Enum": "Foo", + "X-EnumList": "Foo, Bar, Baz" + }, + "body": "" + } + }, + { + "id": "RestXmlSupportsNaNFloatHeaderOutputs", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Supports handling NaN float header values.", + "result": { + "headerFloat": "NaN", + "headerDouble": "NaN" + }, + "response": { + "status_code": 200, + "headers": { + "X-Double": "NaN", + "X-Float": "NaN" + }, + "body": "" + } + }, + { + "id": "RestXmlSupportsInfinityFloatHeaderOutputs", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Supports handling Infinity float header values.", + "result": { + "headerFloat": "Infinity", + "headerDouble": "Infinity" + }, + "response": { + "status_code": 200, + "headers": { + "X-Double": "Infinity", + "X-Float": "Infinity" + }, + "body": "" + } + }, + { + "id": "RestXmlSupportsNegativeInfinityFloatHeaderOutputs", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Supports handling -Infinity float header values.", + "result": { + "headerFloat": "-Infinity", + "headerDouble": "-Infinity" + }, + "response": { + "status_code": 200, + "headers": { + "X-Double": "-Infinity", + "X-Float": "-Infinity" + }, + "body": "" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Map": { - "shape": "StringMap", - "flattened": true - } - } - }, - "StringMap": { - "type": "map", - "key": { - "shape": "StringType" - }, - "value": { - "shape": "StringType" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for NestedXmlMaps operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "NestedXmlMapsResponse": { + "type": "structure", + "members": { + "nestedMap": { + "shape": "NestedMap" + }, + "flatNestedMap": { + "shape": "NestedMap", + "flattened": true + } + } + }, + "NestedMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "FooEnumMap" + } + }, + "FooEnumMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "FooEnum" + } + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "NestedXmlMapResponse", + "given": { + "name": "NestedXmlMaps", + "http": { + "method": "POST", + "requestUri": "/NestedXmlMaps", + "responseCode": 200 + }, + "output": { + "shape": "NestedXmlMapsResponse" + } + }, + "description": "Tests responses with nested maps.", + "result": { + "nestedMap": { + "foo": { + "bar": "Bar" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n \n \n foo\n \n \n bar\n Bar\n \n \n \n \n" + } + }, + { + "id": "FlatNestedXmlMapResponse", + "given": { + "name": "NestedXmlMaps", + "http": { + "method": "POST", + "requestUri": "/NestedXmlMaps", + "responseCode": 200 + }, + "output": { + "shape": "NestedXmlMapsResponse" + } + }, + "description": "Tests responses with nested flat maps. Since maps can only be\nflattened when they're structure members, only the outer map is flat.", + "result": { + "flatNestedMap": { + "foo": { + "bar": "Bar" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n \n foo\n \n \n bar\n Bar\n \n \n \n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Map": { - "qux": "bar", - "baz": "bam" - } - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "quxbarbazbam" - } - } - ] - }, - { - "description": "Named map", - "metadata": { - "protocol": "rest-xml" + { + "description": "Test cases for NoInputAndNoOutput operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": {}, + "cases": [ + { + "id": "NoInputAndNoOutput", + "given": { + "name": "NoInputAndNoOutput", + "http": { + "method": "POST", + "requestUri": "/NoInputAndNoOutput", + "responseCode": 200 + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input or output. While this should be rare, code generators must support this.

" + }, + "description": "No output serializes no payload", + "result": {}, + "response": { + "status_code": 200, + "body": "" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Map": { - "shape": "StringMap" - } - } - }, - "StringMap": { - "type": "map", - "key": { - "shape": "StringType", - "locationName": "foo" - }, - "value": { - "shape": "StringType", - "locationName": "bar" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for NoInputAndOutput operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "NoInputAndOutputOutput": { + "type": "structure", + "members": {} + } + }, + "cases": [ + { + "id": "NoInputAndOutput", + "given": { + "name": "NoInputAndOutput", + "http": { + "method": "POST", + "requestUri": "/NoInputAndOutputOutput", + "responseCode": 200 + }, + "output": { + "shape": "NoInputAndOutputOutput" + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input and the output is empty. While this should be rare, code generators must support this.

" + }, + "description": "Empty output serializes no payload", + "result": {}, + "response": { + "status_code": 200, + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Map": { - "qux": "bar", - "baz": "bam" - } - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "quxbarbazbam" - } - } - ] - }, - { - "description": "XML payload", - "metadata": { - "protocol": "rest-xml" + { + "description": "Test cases for RecursiveShapes operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "RecursiveShapesResponse": { + "type": "structure", + "members": { + "nested": { + "shape": "RecursiveShapesInputOutputNested1" + } + } + }, + "RecursiveShapesInputOutputNested1": { + "type": "structure", + "members": { + "foo": { + "shape": "String" + }, + "nested": { + "shape": "RecursiveShapesInputOutputNested2" + } + } + }, + "String": { + "type": "string" + }, + "RecursiveShapesInputOutputNested2": { + "type": "structure", + "members": { + "bar": { + "shape": "String" + }, + "recursiveMember": { + "shape": "RecursiveShapesInputOutputNested1" + } + } + } + }, + "cases": [ + { + "id": "RecursiveShapes", + "given": { + "name": "RecursiveShapes", + "http": { + "method": "PUT", + "requestUri": "/RecursiveShapes", + "responseCode": 200 + }, + "output": { + "shape": "RecursiveShapesResponse" + }, + "documentation": "

Recursive shapes

", + "idempotent": true + }, + "description": "Serializes recursive structures", + "result": { + "nested": { + "foo": "Foo1", + "nested": { + "bar": "Bar1", + "recursiveMember": { + "foo": "Foo2", + "nested": { + "bar": "Bar2" + } + } + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n \n Foo1\n \n Bar1\n \n Foo2\n \n Bar2\n \n \n \n \n\n" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "payload": "Data", - "members": { - "Header": { - "shape": "StringType", - "location": "header", - "locationName": "X-Foo" - }, - "Data": { - "shape": "SingleStructure" - } - } - }, - "StringType": { - "type": "string" - }, - "SingleStructure": { - "type": "structure", - "members": { - "Foo": { - "shape": "StringType" - } - } - } + { + "description": "Test cases for SimpleScalarProperties operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "SimpleScalarPropertiesResponse": { + "type": "structure", + "members": { + "foo": { + "shape": "String", + "location": "header", + "locationName": "X-Foo" + }, + "stringValue": { + "shape": "String" + }, + "trueBooleanValue": { + "shape": "Boolean" + }, + "falseBooleanValue": { + "shape": "Boolean" + }, + "byteValue": { + "shape": "Integer" + }, + "shortValue": { + "shape": "Integer" + }, + "integerValue": { + "shape": "Integer" + }, + "longValue": { + "shape": "Long" + }, + "floatValue": { + "shape": "Float" + }, + "doubleValue": { + "shape": "Double", + "locationName": "DoubleDribble" + } + } + }, + "String": { + "type": "string" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + }, + "Long": { + "type": "long", + "box": true + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + } + }, + "cases": [ + { + "id": "SimpleScalarProperties", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "output": { + "shape": "SimpleScalarPropertiesResponse" + }, + "idempotent": true + }, + "description": "Serializes simple scalar properties", + "result": { + "foo": "Foo", + "stringValue": "string", + "trueBooleanValue": true, + "falseBooleanValue": false, + "byteValue": 1, + "shortValue": 2, + "integerValue": 3, + "longValue": 4, + "floatValue": 5.5, + "doubleValue": 6.5 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml", + "X-Foo": "Foo" + }, + "body": "\n string\n true\n false\n 1\n 2\n 3\n 4\n 5.5\n 6.5\n\n" + } + }, + { + "id": "SimpleScalarPropertiesComplexEscapes", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "output": { + "shape": "SimpleScalarPropertiesResponse" + }, + "idempotent": true + }, + "description": "Serializes string with escaping.\n\nThis validates the three escape types: literal, decimal and hexadecimal. It also validates that unescaping properly\nhandles the case where unescaping an & produces a newly formed escape sequence (this should not be re-unescaped).\n\nServers may produce different output, this test is designed different unescapes clients must handle\n", + "result": { + "foo": "Foo", + "stringValue": "escaped data: <\r\n" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml", + "X-Foo": "Foo" + }, + "body": "\n escaped data: &lt; \n\n" + } + }, + { + "id": "SimpleScalarPropertiesWithEscapedCharacter", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "output": { + "shape": "SimpleScalarPropertiesResponse" + }, + "idempotent": true + }, + "description": "Serializes string with escaping", + "result": { + "foo": "Foo", + "stringValue": "" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml", + "X-Foo": "Foo" + }, + "body": "\n <string>\n\n" + } + }, + { + "id": "SimpleScalarPropertiesWithXMLPreamble", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "output": { + "shape": "SimpleScalarPropertiesResponse" + }, + "idempotent": true + }, + "description": "Serializes simple scalar properties with xml preamble, comments and CDATA", + "result": { + "foo": "Foo", + "stringValue": "string" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml", + "X-Foo": "Foo" + }, + "body": "\n\n \n string\n \n\n" + } + }, + { + "id": "SimpleScalarPropertiesWithWhiteSpace", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "output": { + "shape": "SimpleScalarPropertiesResponse" + }, + "idempotent": true + }, + "description": "Serializes string containing white space", + "result": { + "foo": "Foo", + "stringValue": " string with white space " + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml", + "X-Foo": "Foo" + }, + "body": "\n\n string with white space \n\n" + } + }, + { + "id": "SimpleScalarPropertiesPureWhiteSpace", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "output": { + "shape": "SimpleScalarPropertiesResponse" + }, + "idempotent": true + }, + "description": "Serializes string containing white space", + "result": { + "foo": "Foo", + "stringValue": " " + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml", + "X-Foo": "Foo" + }, + "body": "\n\n \n\n" + } + }, + { + "id": "RestXmlSupportsNaNFloatOutputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "output": { + "shape": "SimpleScalarPropertiesResponse" + }, + "idempotent": true + }, + "description": "Supports handling NaN float values.", + "result": { + "floatValue": "NaN", + "doubleValue": "NaN" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n NaN\n NaN\n\n" + } + }, + { + "id": "RestXmlSupportsInfinityFloatOutputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "output": { + "shape": "SimpleScalarPropertiesResponse" + }, + "idempotent": true + }, + "description": "Supports handling Infinity float values.", + "result": { + "floatValue": "Infinity", + "doubleValue": "Infinity" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n Infinity\n Infinity\n\n" + } + }, + { + "id": "RestXmlSupportsNegativeInfinityFloatOutputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "output": { + "shape": "SimpleScalarPropertiesResponse" + }, + "idempotent": true + }, + "description": "Supports handling -Infinity float values.", + "result": { + "floatValue": "-Infinity", + "doubleValue": "-Infinity" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n -Infinity\n -Infinity\n\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Header": "baz", - "Data": { - "Foo": "abc" - } - }, - "response": { - "status_code": 200, - "headers": { - "X-Foo": "baz" - }, - "body": "abc" - } - } - ] - }, - { - "description": "Streaming payload", - "metadata": { - "protocol": "rest-xml" + { + "description": "Test cases for TimestampFormatHeaders operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "TimestampFormatHeadersIO": { + "type": "structure", + "members": { + "memberEpochSeconds": { + "shape": "SyntheticTimestamp_epoch_seconds", + "location": "header", + "locationName": "X-memberEpochSeconds" + }, + "memberHttpDate": { + "shape": "SyntheticTimestamp_http_date", + "location": "header", + "locationName": "X-memberHttpDate" + }, + "memberDateTime": { + "shape": "SyntheticTimestamp_date_time", + "location": "header", + "locationName": "X-memberDateTime" + }, + "defaultFormat": { + "shape": "Timestamp", + "location": "header", + "locationName": "X-defaultFormat" + }, + "targetEpochSeconds": { + "shape": "EpochSeconds", + "location": "header", + "locationName": "X-targetEpochSeconds" + }, + "targetHttpDate": { + "shape": "HttpDate", + "location": "header", + "locationName": "X-targetHttpDate" + }, + "targetDateTime": { + "shape": "DateTime", + "location": "header", + "locationName": "X-targetDateTime" + } + } + }, + "SyntheticTimestamp_epoch_seconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "SyntheticTimestamp_http_date": { + "type": "timestamp", + "timestampFormat": "rfc822" + }, + "SyntheticTimestamp_date_time": { + "type": "timestamp", + "timestampFormat": "iso8601" + }, + "Timestamp": { + "type": "timestamp" + }, + "EpochSeconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "HttpDate": { + "type": "timestamp", + "timestampFormat": "rfc822" + }, + "DateTime": { + "type": "timestamp", + "timestampFormat": "iso8601" + } + }, + "cases": [ + { + "id": "TimestampFormatHeaders", + "given": { + "name": "TimestampFormatHeaders", + "http": { + "method": "POST", + "requestUri": "/TimestampFormatHeaders", + "responseCode": 200 + }, + "output": { + "shape": "TimestampFormatHeadersIO" + }, + "documentation": "

The example tests how timestamp request and response headers are serialized.

" + }, + "description": "Tests how timestamp response headers are serialized", + "result": { + "memberEpochSeconds": 1576540098, + "memberHttpDate": 1576540098, + "memberDateTime": 1576540098, + "defaultFormat": 1576540098, + "targetEpochSeconds": 1576540098, + "targetHttpDate": 1576540098, + "targetDateTime": 1576540098 + }, + "response": { + "status_code": 200, + "headers": { + "X-defaultFormat": "Mon, 16 Dec 2019 23:48:18 GMT", + "X-memberDateTime": "2019-12-16T23:48:18Z", + "X-memberEpochSeconds": "1576540098", + "X-memberHttpDate": "Mon, 16 Dec 2019 23:48:18 GMT", + "X-targetDateTime": "2019-12-16T23:48:18Z", + "X-targetEpochSeconds": "1576540098", + "X-targetHttpDate": "Mon, 16 Dec 2019 23:48:18 GMT" + }, + "body": "" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "payload": "Stream", - "members": { - "Stream": { - "shape": "BlobStream" - } - } - }, - "BlobStream": { - "type": "blob" - } + { + "description": "Test cases for XmlAttributes operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlAttributesResponse": { + "type": "structure", + "members": { + "foo": { + "shape": "String" + }, + "attr": { + "shape": "String", + "locationName": "test", + "xmlAttribute": true + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "XmlAttributes", + "given": { + "name": "XmlAttributes", + "http": { + "method": "PUT", + "requestUri": "/XmlAttributes", + "responseCode": 200 + }, + "output": { + "shape": "XmlAttributesResponse" + }, + "documentation": "

This example serializes an XML attributes on synthesized document.

", + "idempotent": true + }, + "description": "Serializes simple scalar properties", + "result": { + "foo": "hi", + "attr": "test" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n hi\n\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Stream": "abc" - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "abc" - } - } - ] - }, - { - "description": "Scalar members in headers", - "metadata": { - "protocol": "rest-xml" + { + "description": "Test cases for XmlAttributesOnPayload operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlAttributesOnPayloadResponse": { + "type": "structure", + "members": { + "payload": { + "shape": "XmlAttributesPayloadResponse" + } + }, + "payload": "payload" + }, + "XmlAttributesPayloadResponse": { + "type": "structure", + "members": { + "foo": { + "shape": "String" + }, + "attr": { + "shape": "String", + "locationName": "test", + "xmlAttribute": true + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "XmlAttributesOnPayload", + "given": { + "name": "XmlAttributesOnPayload", + "http": { + "method": "PUT", + "requestUri": "/XmlAttributesOnPayload", + "responseCode": 200 + }, + "output": { + "shape": "XmlAttributesOnPayloadResponse" + }, + "documentation": "

This example serializes an XML attributes on a document targeted by httpPayload.

", + "idempotent": true + }, + "description": "Serializes simple scalar properties", + "result": { + "payload": { + "foo": "hi", + "attr": "test" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n hi\n\n" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Str": { - "locationName": "x-str", - "shape": "StringHeaderType" - }, - "Integer": { - "locationName": "x-int", - "shape": "IntegerHeaderType" - }, - "TrueBool": { - "locationName": "x-true-bool", - "shape": "BooleanHeaderType" - }, - "FalseBool": { - "locationName": "x-false-bool", - "shape": "BooleanHeaderType" - }, - "Float": { - "locationName": "x-float", - "shape": "FloatHeaderType" - }, - "Double": { - "locationName": "x-double", - "shape": "DoubleHeaderType" - }, - "Long": { - "locationName": "x-long", - "shape": "LongHeaderType" - }, - "Char": { - "locationName": "x-char", - "shape": "CharHeaderType" - }, - "Timestamp": { - "locationName": "x-timestamp", - "shape": "TimestampHeaderType" - } - } - }, - "StringHeaderType": { - "location": "header", - "type": "string" - }, - "IntegerHeaderType": { - "location": "header", - "type": "integer" - }, - "BooleanHeaderType": { - "location": "header", - "type": "boolean" - }, - "FloatHeaderType": { - "location": "header", - "type": "float" - }, - "DoubleHeaderType": { - "location": "header", - "type": "double" - }, - "LongHeaderType": { - "location": "header", - "type": "long" - }, - "CharHeaderType": { - "location": "header", - "type": "character" - }, - "TimestampHeaderType": { - "location": "header", - "type": "timestamp" - } + { + "description": "Test cases for XmlBlobs operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlBlobsResponse": { + "type": "structure", + "members": { + "data": { + "shape": "Blob" + } + } + }, + "Blob": { + "type": "blob" + } + }, + "cases": [ + { + "id": "XmlBlobs", + "given": { + "name": "XmlBlobs", + "http": { + "method": "POST", + "requestUri": "/XmlBlobs", + "responseCode": 200 + }, + "output": { + "shape": "XmlBlobsResponse" + }, + "documentation": "

Blobs are base64 encoded

" + }, + "description": "Blobs are base64 encoded", + "result": { + "data": "value" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n dmFsdWU=\n\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Str": "string", - "Integer": 1, - "TrueBool": true, - "FalseBool": false, - "Float": 1.5, - "Double": 1.5, - "Long": 100, - "Char": "a", - "Timestamp": 1422172800 - }, - "response": { - "status_code": 200, - "headers": { - "x-str": "string", - "x-int": "1", - "x-true-bool": "true", - "x-false-bool": "false", - "x-float": "1.5", - "x-double": "1.5", - "x-long": "100", - "x-char": "a", - "x-timestamp": "Sun, 25 Jan 2015 08:00:00 GMT" - }, - "body": "" - } - } - ] - }, - { - "description": "Empty string", - "metadata": { - "protocol": "rest-xml" + { + "description": "Test cases for XmlEmptyBlobs operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlEmptyBlobsResponse": { + "type": "structure", + "members": { + "data": { + "shape": "Blob" + } + } + }, + "Blob": { + "type": "blob" + } + }, + "cases": [ + { + "id": "XmlEmptyBlobs", + "given": { + "name": "XmlEmptyBlobs", + "http": { + "method": "POST", + "requestUri": "/XmlEmptyBlobs", + "responseCode": 200 + }, + "output": { + "shape": "XmlEmptyBlobsResponse" + }, + "documentation": "

Blobs are base64 encoded

" + }, + "description": "Empty blobs are deserialized as empty string", + "result": { + "data": "" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n \n\n" + } + }, + { + "id": "XmlEmptySelfClosedBlobs", + "given": { + "name": "XmlEmptyBlobs", + "http": { + "method": "POST", + "requestUri": "/XmlEmptyBlobs", + "responseCode": 200 + }, + "output": { + "shape": "XmlEmptyBlobsResponse" + }, + "documentation": "

Blobs are base64 encoded

" + }, + "description": "Empty self closed blobs are deserialized as empty string", + "result": { + "data": "" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n \n\n" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Foo": { - "shape": "StringType" - } - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for XmlEmptyLists operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlEmptyListsResponse": { + "type": "structure", + "members": { + "stringList": { + "shape": "StringList" + }, + "stringSet": { + "shape": "StringSet" + }, + "integerList": { + "shape": "IntegerList" + }, + "booleanList": { + "shape": "BooleanList" + }, + "timestampList": { + "shape": "TimestampList" + }, + "enumList": { + "shape": "FooEnumList" + }, + "intEnumList": { + "shape": "IntegerEnumList" + }, + "nestedStringList": { + "shape": "NestedStringList" + }, + "renamedListMembers": { + "shape": "RenamedListMembers", + "locationName": "renamed" + }, + "flattenedList": { + "shape": "RenamedListMembers", + "flattened": true + }, + "flattenedList2": { + "shape": "RenamedListMembers", + "flattened": true, + "locationName": "customName" + }, + "flattenedListWithMemberNamespace": { + "shape": "ListWithMemberNamespace", + "flattened": true + }, + "flattenedListWithNamespace": { + "shape": "ListWithNamespace", + "flattened": true + }, + "structureList": { + "shape": "StructureList", + "locationName": "myStructureList" + }, + "flattenedStructureList": { + "shape": "StructureList", + "flattened": true + } + } + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringSet": { + "type": "list", + "member": { + "shape": "String" + } + }, + "IntegerList": { + "type": "list", + "member": { + "shape": "Integer" + } + }, + "BooleanList": { + "type": "list", + "member": { + "shape": "Boolean" + } + }, + "TimestampList": { + "type": "list", + "member": { + "shape": "Timestamp" + } + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "IntegerEnumList": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "NestedStringList": { + "type": "list", + "member": { + "shape": "StringList" + }, + "documentation": "

A list of lists of strings.

" + }, + "RenamedListMembers": { + "type": "list", + "member": { + "shape": "String", + "locationName": "item" + } + }, + "ListWithMemberNamespace": { + "type": "list", + "member": { + "shape": "String", + "xmlNamespace": "https://xml-member.example.com" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "ListWithNamespace": { + "type": "list", + "member": { + "shape": "String" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "StructureList": { + "type": "list", + "member": { + "shape": "StructureListMember", + "locationName": "item" + } + }, + "StructureListMember": { + "type": "structure", + "members": { + "a": { + "shape": "String", + "locationName": "value" + }, + "b": { + "shape": "String", + "locationName": "other" + } + } + }, + "String": { + "type": "string" + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "Timestamp": { + "type": "timestamp" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + } + }, + "cases": [ + { + "id": "XmlEmptyLists", + "given": { + "name": "XmlEmptyLists", + "http": { + "method": "PUT", + "requestUri": "/XmlEmptyLists", + "responseCode": 200 + }, + "output": { + "shape": "XmlEmptyListsResponse" + }, + "idempotent": true + }, + "description": "Deserializes Empty XML lists", + "result": { + "stringList": [], + "stringSet": [] + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n \n \n\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Foo": "" - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "requestid" - } - } - ] - }, - { - "description": "JSON value trait", - "metadata": { - "protocol": "rest-xml" + { + "description": "Test cases for XmlEmptyMaps operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlEmptyMapsResponse": { + "type": "structure", + "members": { + "myMap": { + "shape": "XmlMapsInputOutputMap" + } + } + }, + "XmlMapsInputOutputMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "GreetingStruct" + } + }, + "GreetingStruct": { + "type": "structure", + "members": { + "hi": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "XmlEmptyMaps", + "given": { + "name": "XmlEmptyMaps", + "http": { + "method": "POST", + "requestUri": "/XmlEmptyMaps", + "responseCode": 200 + }, + "output": { + "shape": "XmlEmptyMapsResponse" + } + }, + "description": "Deserializes Empty XML maps", + "result": { + "myMap": {} + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n \n\n" + } + }, + { + "id": "XmlEmptySelfClosedMaps", + "given": { + "name": "XmlEmptyMaps", + "http": { + "method": "POST", + "requestUri": "/XmlEmptyMaps", + "responseCode": 200 + }, + "output": { + "shape": "XmlEmptyMapsResponse" + } + }, + "description": "Deserializes Empty Self-closed XML maps", + "result": { + "myMap": {} + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n \n\n" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Attr": { - "shape": "StringType", - "jsonvalue": true, - "location": "header", - "locationName": "X-Amz-Foo" - } - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for XmlEmptyStrings operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlEmptyStringsResponse": { + "type": "structure", + "members": { + "emptyString": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "XmlEmptyStrings", + "given": { + "name": "XmlEmptyStrings", + "http": { + "method": "PUT", + "requestUri": "/XmlEmptyStrings", + "responseCode": 200 + }, + "output": { + "shape": "XmlEmptyStringsResponse" + }, + "idempotent": true + }, + "description": "Deserializes xml empty strings", + "result": { + "emptyString": "" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n \n\n" + } + }, + { + "id": "XmlEmptySelfClosedStrings", + "given": { + "name": "XmlEmptyStrings", + "http": { + "method": "PUT", + "requestUri": "/XmlEmptyStrings", + "responseCode": 200 + }, + "output": { + "shape": "XmlEmptyStringsResponse" + }, + "idempotent": true + }, + "description": "Empty self closed string are deserialized as empty string", + "result": { + "emptyString": "" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n \n\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Attr": {"Foo":"Bar"} - }, - "response": { - "status_code": 200, - "headers": {"X-Amz-Foo": "eyJGb28iOiJCYXIifQ=="}, - "body": "" - } - } - ] - }, - { - "description": "Timestamp members", - "metadata": { - "protocol": "rest-xml" + { + "description": "Test cases for XmlEnums operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlEnumsResponse": { + "type": "structure", + "members": { + "fooEnum1": { + "shape": "FooEnum" + }, + "fooEnum2": { + "shape": "FooEnum" + }, + "fooEnum3": { + "shape": "FooEnum" + }, + "fooEnumList": { + "shape": "FooEnumList" + }, + "fooEnumSet": { + "shape": "FooEnumSet" + }, + "fooEnumMap": { + "shape": "FooEnumMap" + } + } + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "FooEnumSet": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "FooEnumMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "FooEnum" + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "XmlEnums", + "given": { + "name": "XmlEnums", + "http": { + "method": "PUT", + "requestUri": "/XmlEnums", + "responseCode": 200 + }, + "output": { + "shape": "XmlEnumsResponse" + }, + "documentation": "

This example serializes enums as top level properties, in lists, sets, and maps.

", + "idempotent": true + }, + "description": "Serializes simple scalar properties", + "result": { + "fooEnum1": "Foo", + "fooEnum2": "0", + "fooEnum3": "1", + "fooEnumList": [ + "Foo", + "0" + ], + "fooEnumSet": [ + "Foo", + "0" + ], + "fooEnumMap": { + "hi": "Foo", + "zero": "0" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n Foo\n 0\n 1\n \n Foo\n 0\n \n \n Foo\n 0\n \n \n \n hi\n Foo\n \n \n zero\n 0\n \n \n\n" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "TimeArg": { - "shape": "TimestampType" - }, - "TimeArgInHeader": { - "shape": "TimestampType", - "location": "header", - "locationName": "x-amz-timearg" - }, - "TimeCustom": { - "timestampFormat": "rfc822", - "shape": "TimestampType" - }, - "TimeCustomInHeader": { - "timestampFormat": "unixTimestamp", - "shape": "TimestampType", - "location": "header", - "locationName": "x-amz-timecustom" - }, - "TimeFormat": { - "shape": "TimestampFormatType" - }, - "TimeFormatInHeader": { - "shape": "TimestampFormatType", - "location": "header", - "locationName": "x-amz-timeformat" - }, - "StructMember": { - "shape": "TimeContainer" - } - } - }, - "TimeContainer": { - "type": "structure", - "members": { - "foo": { - "shape": "TimestampType" - }, - "bar": { - "shape": "TimestampFormatType" - } - } - }, - "TimestampFormatType": { - "timestampFormat": "unixTimestamp", - "type": "timestamp" - }, - "TimestampType": { - "type": "timestamp" - } + { + "description": "Test cases for XmlIntEnums operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlIntEnumsResponse": { + "type": "structure", + "members": { + "intEnum1": { + "shape": "IntegerEnum" + }, + "intEnum2": { + "shape": "IntegerEnum" + }, + "intEnum3": { + "shape": "IntegerEnum" + }, + "intEnumList": { + "shape": "IntegerEnumList" + }, + "intEnumSet": { + "shape": "IntegerEnumSet" + }, + "intEnumMap": { + "shape": "IntegerEnumMap" + } + } + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "IntegerEnumList": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "IntegerEnumSet": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "IntegerEnumMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "IntegerEnum" + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "XmlIntEnums", + "given": { + "name": "XmlIntEnums", + "http": { + "method": "PUT", + "requestUri": "/XmlIntEnums", + "responseCode": 200 + }, + "output": { + "shape": "XmlIntEnumsResponse" + }, + "documentation": "

This example serializes enums as top level properties, in lists, sets, and maps.

", + "idempotent": true + }, + "description": "Serializes simple scalar properties", + "result": { + "intEnum1": 1, + "intEnum2": 2, + "intEnum3": 3, + "intEnumList": [ + 1, + 2 + ], + "intEnumSet": [ + 1, + 2 + ], + "intEnumMap": { + "a": 1, + "b": 2 + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n 1\n 2\n 3\n \n 1\n 2\n \n \n 1\n 2\n \n \n \n a\n 1\n \n \n b\n 2\n \n \n\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "TimeArg": 1398796238, - "TimeArgInHeader": 1398796238, - "TimeCustom": 1398796238, - "TimeCustomInHeader": 1398796238, - "TimeFormat": 1398796238, - "TimeFormatInHeader": 1398796238, - "StructMember": { - "foo": 1398796238, - "bar": 1398796238 - } - }, - "response": { - "status_code": 200, - "headers": { - "x-amz-timearg": "Tue, 29 Apr 2014 18:30:38 GMT", - "x-amz-timecustom": "1398796238", - "x-amz-timeformat": "1398796238" - }, - "body": "2014-04-29T18:30:38+00:0013987962382014-04-29T18:30:38+00:00Tue, 29 Apr 2014 18:30:38 GMT1398796238requestid" - } - } - ] - }, - { - "description": "REST XML Event Stream", - "metadata": { - "protocol": "rest-xml" + { + "description": "Test cases for XmlLists operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlListsResponse": { + "type": "structure", + "members": { + "stringList": { + "shape": "StringList" + }, + "stringSet": { + "shape": "StringSet" + }, + "integerList": { + "shape": "IntegerList" + }, + "booleanList": { + "shape": "BooleanList" + }, + "timestampList": { + "shape": "TimestampList" + }, + "enumList": { + "shape": "FooEnumList" + }, + "intEnumList": { + "shape": "IntegerEnumList" + }, + "nestedStringList": { + "shape": "NestedStringList" + }, + "renamedListMembers": { + "shape": "RenamedListMembers", + "locationName": "renamed" + }, + "flattenedList": { + "shape": "RenamedListMembers", + "flattened": true + }, + "flattenedList2": { + "shape": "RenamedListMembers", + "flattened": true, + "locationName": "customName" + }, + "flattenedListWithMemberNamespace": { + "shape": "ListWithMemberNamespace", + "flattened": true + }, + "flattenedListWithNamespace": { + "shape": "ListWithNamespace", + "flattened": true + }, + "structureList": { + "shape": "StructureList", + "locationName": "myStructureList" + }, + "flattenedStructureList": { + "shape": "StructureList", + "flattened": true + } + } + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringSet": { + "type": "list", + "member": { + "shape": "String" + } + }, + "IntegerList": { + "type": "list", + "member": { + "shape": "Integer" + } + }, + "BooleanList": { + "type": "list", + "member": { + "shape": "Boolean" + } + }, + "TimestampList": { + "type": "list", + "member": { + "shape": "Timestamp" + } + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "IntegerEnumList": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "NestedStringList": { + "type": "list", + "member": { + "shape": "StringList" + }, + "documentation": "

A list of lists of strings.

" + }, + "RenamedListMembers": { + "type": "list", + "member": { + "shape": "String", + "locationName": "item" + } + }, + "ListWithMemberNamespace": { + "type": "list", + "member": { + "shape": "String", + "xmlNamespace": "https://xml-member.example.com" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "ListWithNamespace": { + "type": "list", + "member": { + "shape": "String" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "StructureList": { + "type": "list", + "member": { + "shape": "StructureListMember", + "locationName": "item" + } + }, + "StructureListMember": { + "type": "structure", + "members": { + "a": { + "shape": "String", + "locationName": "value" + }, + "b": { + "shape": "String", + "locationName": "other" + } + } + }, + "String": { + "type": "string" + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "Timestamp": { + "type": "timestamp" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + } + }, + "cases": [ + { + "id": "XmlLists", + "given": { + "name": "XmlLists", + "http": { + "method": "PUT", + "requestUri": "/XmlLists", + "responseCode": 200 + }, + "output": { + "shape": "XmlListsResponse" + }, + "documentation": "

This test case serializes XML lists for the following cases for both input and output:

  1. Normal XML lists.
  2. Normal XML sets.
  3. XML lists of lists.
  4. XML lists with @xmlName on its members
  5. Flattened XML lists.
  6. Flattened XML lists with @xmlName.
  7. Flattened XML lists with @xmlNamespace.
  8. Lists of structures.
  9. Flattened XML list of structures
", + "idempotent": true + }, + "description": "Tests for XML list serialization", + "result": { + "stringList": [ + "foo", + "bar" + ], + "stringSet": [ + "foo", + "bar" + ], + "integerList": [ + 1, + 2 + ], + "booleanList": [ + true, + false + ], + "timestampList": [ + 1398796238, + 1398796238 + ], + "enumList": [ + "Foo", + "0" + ], + "intEnumList": [ + 1, + 2 + ], + "nestedStringList": [ + [ + "foo", + "bar" + ], + [ + "baz", + "qux" + ] + ], + "renamedListMembers": [ + "foo", + "bar" + ], + "flattenedList": [ + "hi", + "bye" + ], + "flattenedList2": [ + "yep", + "nope" + ], + "flattenedListWithMemberNamespace": [ + "a", + "b" + ], + "flattenedListWithNamespace": [ + "a", + "b" + ], + "structureList": [ + { + "a": "1", + "b": "2" + }, + { + "a": "3", + "b": "4" + } + ], + "flattenedStructureList": [ + { + "a": "5", + "b": "6" + }, + { + "a": "7", + "b": "8" + } + ] + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n \n foo\n bar\n \n \n foo\n bar\n \n \n 1\n 2\n \n \n true\n false\n \n \n 2014-04-29T18:30:38Z\n 2014-04-29T18:30:38Z\n \n \n Foo\n 0\n \n \n 1\n 2\n \n \n \n foo\n bar\n \n \n baz\n qux\n \n \n \n foo\n bar\n \n hi\n bye\n yep\n nope\n a\n b\n a\n b\n \n \n 1\n 2\n \n \n 3\n 4\n \n \n \n 5\n 6\n \n \n 7\n 8\n \n\n" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Payload": {"shape": "EventStream"} - }, - "payload": "Payload" - }, - "EventStream": { - "type": "structure", - "eventstream": true, - "members": { - "TypeA": {"shape": "TypeAEvent"}, - "TypeB": {"shape": "TypeBEvent"}, - "TypeC": {"shape": "TypeCEvent"} - } - }, - "TypeAEvent": { - "type": "structure", - "event": true, - "members": { - "Payload": { - "shape": "BlobType", - "eventpayload": true - } - } - }, - "TypeBEvent": { - "type": "structure", - "event": true, - "members": { - "Details": { - "shape": "Details", - "eventpayload": true - } - } - }, - "TypeCEvent": { - "type": "structure", - "event": true, - "members": { - "Details": { - "shape": "Details", - "eventpayload": true - }, - "Boolean": { - "shape": "BooleanType", - "eventheader": true - }, - "Integer": { - "shape": "IntegerType", - "eventheader": true - }, - "Blob": { - "shape": "BlobType", - "eventheader": true - }, - "String": { - "shape": "StringType", - "eventheader": true - }, - "Timestamp": { - "shape": "TimestampType", - "eventheader": true - } - } - }, - "Details": { - "type": "structure", - "members": { - "StringField": {"shape": "StringType"}, - "IntegerField": {"shape": "IntegerType"} - } - }, - "StringType": { - "type": "string" - }, - "IntegerType": { - "type": "integer" - }, - "BooleanType": { - "type": "boolean" - }, - "TimestampType": { - "type": "timestamp" - }, - "BlobType": { - "type": "blob" - } + { + "description": "Test cases for XmlMaps operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlMapsResponse": { + "type": "structure", + "members": { + "myMap": { + "shape": "XmlMapsInputOutputMap" + } + } + }, + "XmlMapsInputOutputMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "GreetingStruct" + } + }, + "GreetingStruct": { + "type": "structure", + "members": { + "hi": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "XmlMaps", + "given": { + "name": "XmlMaps", + "http": { + "method": "POST", + "requestUri": "/XmlMaps", + "responseCode": 200 + }, + "output": { + "shape": "XmlMapsResponse" + }, + "documentation": "

The example tests basic map serialization.

" + }, + "description": "Tests for XML map serialization", + "result": { + "myMap": { + "foo": { + "hi": "there" + }, + "baz": { + "hi": "bye" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n \n \n foo\n \n there\n \n \n \n baz\n \n bye\n \n \n \n\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Payload": [ - { - "TypeA": {"Payload": "somebytes"} - }, - { - "TypeB": { - "Details": { - "StringField": "somestring", - "IntegerField": 123 - } - } - } - ] - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "AAAAbAAAAFPLgkVrDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcABVR5cGVBDTpjb250ZW50LXR5cGUHABhhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW1zb21lYnl0ZXMesj2HAAAAsAAAAEOaMMdXDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcABVR5cGVCDTpjb250ZW50LXR5cGUHAAh0ZXh0L3htbDxUeXBlQiB4bWxucz0iIj48U3RyaW5nRmllbGQ+c29tZXN0cmluZzwvU3RyaW5nRmllbGQ+PEludGVnZXJGaWVsZD4xMjM8L0ludGVnZXJGaWVsZD48L1R5cGVCPiwthPo=" - } - }, - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Payload": [ - { - "TypeC": { - "Boolean": true, - "Integer": 123, - "Blob": "someblob", - "String": "somestring", - "Timestamp": 1422172800, - "Details": { - "StringField": "somestring", - "IntegerField": 123 - } - } - } - ] - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "AAABAQAAAJBjEbY4DTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcABVR5cGVDDTpjb250ZW50LXR5cGUHAAh0ZXh0L3htbAdCb29sZWFuAAdJbnRlZ2VyBAAAAHsEQmxvYgYACHNvbWVibG9iBlN0cmluZwcACnNvbWVzdHJpbmcJVGltZXN0YW1wCAAAAUsgGsQAPERldGFpbHMgeG1sbnM9IiI+PFN0cmluZ0ZpZWxkPnNvbWVzdHJpbmc8L1N0cmluZ0ZpZWxkPjxJbnRlZ2VyRmllbGQ+MTIzPC9JbnRlZ2VyRmllbGQ+PC9EZXRhaWxzPhGUvKo=" - } - }, - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Payload": [] - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "" - } - } - ] - }, - { - "description": "Modeled exceptions", - "metadata": { - "protocol": "rest-xml" + { + "description": "Test cases for XmlMapsXmlName operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlMapsXmlNameResponse": { + "type": "structure", + "members": { + "myMap": { + "shape": "XmlMapsXmlNameInputOutputMap" + } + } + }, + "XmlMapsXmlNameInputOutputMap": { + "type": "map", + "key": { + "shape": "String", + "locationName": "Attribute" + }, + "value": { + "shape": "GreetingStruct", + "locationName": "Setting" + } + }, + "GreetingStruct": { + "type": "structure", + "members": { + "hi": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "XmlMapsXmlName", + "given": { + "name": "XmlMapsXmlName", + "http": { + "method": "POST", + "requestUri": "/XmlMapsXmlName", + "responseCode": 200 + }, + "output": { + "shape": "XmlMapsXmlNameResponse" + } + }, + "description": "Serializes XML lists", + "result": { + "myMap": { + "foo": { + "hi": "there" + }, + "baz": { + "hi": "bye" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n \n \n foo\n \n there\n \n \n \n baz\n \n bye\n \n \n \n\n" + } + } + ] }, - "shapes": { - "ExceptionShape": { - "exception": true, - "type": "structure", - "members": { - "ImaHeader": { - "shape": "HeaderShape" - }, - "ImaHeaderLocation": { - "shape": "HeaderShape", - "locationName": "X-Foo" - }, - "Status": { - "shape": "StatusShape", - "location": "statusCode" - }, - "BodyMember": { - "shape": "StringType" - }, - "Message": { - "shape": "StringType" - } - } - }, - "OtherExceptionShape": { - "exception": true, - "type": "structure", - "members": { - "BodyMember": { - "shape": "StringType" - } - } - }, - "HeaderShape": { - "type": "string", - "location": "header" - }, - "StatusShape": { - "type": "integer" - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for XmlMapWithXmlNamespace operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlMapWithXmlNamespaceResponse": { + "type": "structure", + "members": { + "myMap": { + "shape": "XmlMapWithXmlNamespaceInputOutputMap", + "locationName": "KVP", + "xmlNamespace": "https://the-member.example.com" + } + } + }, + "XmlMapWithXmlNamespaceInputOutputMap": { + "type": "map", + "key": { + "shape": "String", + "locationName": "K", + "xmlNamespace": "https://the-key.example.com" + }, + "value": { + "shape": "String", + "locationName": "V", + "xmlNamespace": "https://the-value.example.com" + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestXmlXmlMapWithXmlNamespace", + "given": { + "name": "XmlMapWithXmlNamespace", + "http": { + "method": "POST", + "requestUri": "/XmlMapWithXmlNamespace", + "responseCode": 200 + }, + "output": { + "shape": "XmlMapWithXmlNamespaceResponse" + }, + "documentation": "

Maps with @xmlNamespace and @xmlName

" + }, + "description": "Serializes XML maps in responses that have xmlNamespace and xmlName on members", + "result": { + "myMap": { + "a": "A", + "b": "B" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n \n \n a\n A\n \n \n b\n B\n \n \n" + } + } + ] }, - "cases": [ - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" - }, - "error": { - "ImaHeader": "test", - "ImaHeaderLocation": "abc", - "Status": 400, - "BodyMember": "mybody", - "Message": "mymessage" - }, - "errorCode": "ExceptionShape", - "errorMessage": "mymessage", - "response": { - "status_code": 400, - "headers": { - "ImaHeader": "test", - "X-Foo": "abc", - "X-Amzn-Requestid": "foo-id" - }, - "body": "SomeTypeExceptionShapemymessagemybody" - } - }, - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" - }, - "error": { - "BodyMember": "mybody" - }, - "errorCode": "OtherExceptionShape", - "errorMessage": "mymessage", - "response": { - "status_code": 400, - "headers": { - "ImaHeader": "test", - "X-Foo": "abc", - "X-Amzn-Requestid": "foo-id" - }, - "body": "SomeTypeOtherExceptionShapemymessagemybody" - } - }, - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" - }, - "error": {}, - "errorCode": "UndefinedShape", - "response": { - "status_code": 400, - "headers": { - "ImaHeader": "test", - "X-Foo": "abc", - "X-Amzn-Requestid": "foo-id" - }, - "body": "SomeTypeUndefinedShapemybody" - } - } - ] - }, - { - "description": "Unions", - "metadata": { - "protocol": "rest-xml" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "UnionMember": { - "shape": "UnionType" - } - } - }, - "UnionType": { - "type": "structure", - "members": { - "S":{"shape":"StringType"}, - "L": {"shape": "ListType"} - }, - "union": true - }, - "ListType": { - "type": "list", - "member": { - "shape": "StringType" - } - }, - "StringType": { - "type": "string" - } - }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "UnionMember": {"S": "string value"} - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "string value" - } - }, - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "UnionMember": {"L": ["a", "b"]} - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "ab" - } - }, - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "UnionMember": {"SDK_UNKNOWN_MEMBER": {"name": "SomeUnknownMember"}} - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "foo" - } - } - ] - }, - { - "description": "List in header", - "metadata": { - "protocol": "rest-xml" + { + "description": "Test cases for XmlNamespaces operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlNamespacesResponse": { + "type": "structure", + "members": { + "nested": { + "shape": "XmlNamespaceNested" + } + }, + "xmlNamespace": "http://foo.com" + }, + "XmlNamespaceNested": { + "type": "structure", + "members": { + "foo": { + "shape": "String", + "xmlNamespace": { + "prefix": "baz", + "uri": "http://baz.com" + } + }, + "values": { + "shape": "XmlNamespacedList", + "xmlNamespace": "http://qux.com" + } + }, + "xmlNamespace": "http://foo.com" + }, + "String": { + "type": "string" + }, + "XmlNamespacedList": { + "type": "list", + "member": { + "shape": "String", + "xmlNamespace": "http://bux.com" + } + } + }, + "cases": [ + { + "id": "XmlNamespaces", + "given": { + "name": "XmlNamespaces", + "http": { + "method": "POST", + "requestUri": "/XmlNamespaces", + "responseCode": 200 + }, + "output": { + "shape": "XmlNamespacesResponse" + } + }, + "description": "Serializes XML namespaces", + "result": { + "nested": { + "foo": "Foo", + "values": [ + "Bar", + "Baz" + ] + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n \n Foo\n \n Bar\n Baz\n \n \n\n" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "ListMember": { - "shape": "ListShape", - "location": "header", - "locationName": "x-amz-list-member" - } - } - }, - "ListShape": { - "type": "list", - "member": { - "shape": "EnumType" - } - }, - "EnumType": { - "type": "string", - "enum": ["one", "two", "three"] - } + { + "description": "Test cases for XmlTimestamps operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlTimestampsResponse": { + "type": "structure", + "members": { + "normal": { + "shape": "Timestamp" + }, + "dateTime": { + "shape": "SyntheticTimestamp_date_time" + }, + "dateTimeOnTarget": { + "shape": "DateTime" + }, + "epochSeconds": { + "shape": "SyntheticTimestamp_epoch_seconds" + }, + "epochSecondsOnTarget": { + "shape": "EpochSeconds" + }, + "httpDate": { + "shape": "SyntheticTimestamp_http_date" + }, + "httpDateOnTarget": { + "shape": "HttpDate" + } + } + }, + "Timestamp": { + "type": "timestamp" + }, + "SyntheticTimestamp_date_time": { + "type": "timestamp", + "timestampFormat": "iso8601" + }, + "DateTime": { + "type": "timestamp", + "timestampFormat": "iso8601" + }, + "SyntheticTimestamp_epoch_seconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "EpochSeconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "SyntheticTimestamp_http_date": { + "type": "timestamp", + "timestampFormat": "rfc822" + }, + "HttpDate": { + "type": "timestamp", + "timestampFormat": "rfc822" + } + }, + "cases": [ + { + "id": "XmlTimestamps", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/XmlTimestamps", + "responseCode": 200 + }, + "output": { + "shape": "XmlTimestampsResponse" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Tests how normal timestamps are serialized", + "result": { + "normal": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n 2014-04-29T18:30:38Z\n\n" + } + }, + { + "id": "XmlTimestampsWithDateTimeFormat", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/XmlTimestamps", + "responseCode": 200 + }, + "output": { + "shape": "XmlTimestampsResponse" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of date-time works like normal timestamps", + "result": { + "dateTime": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n 2014-04-29T18:30:38Z\n\n" + } + }, + { + "id": "XmlTimestampsWithDateTimeOnTargetFormat", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/XmlTimestamps", + "responseCode": 200 + }, + "output": { + "shape": "XmlTimestampsResponse" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of date-time on the target shape works like normal timestamps", + "result": { + "dateTimeOnTarget": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n 2014-04-29T18:30:38Z\n\n" + } + }, + { + "id": "XmlTimestampsWithEpochSecondsFormat", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/XmlTimestamps", + "responseCode": 200 + }, + "output": { + "shape": "XmlTimestampsResponse" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of epoch-seconds works", + "result": { + "epochSeconds": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n 1398796238\n\n" + } + }, + { + "id": "XmlTimestampsWithEpochSecondsOnTargetFormat", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/XmlTimestamps", + "responseCode": 200 + }, + "output": { + "shape": "XmlTimestampsResponse" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of epoch-seconds on the target shape works", + "result": { + "epochSecondsOnTarget": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n 1398796238\n\n" + } + }, + { + "id": "XmlTimestampsWithHttpDateFormat", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/XmlTimestamps", + "responseCode": 200 + }, + "output": { + "shape": "XmlTimestampsResponse" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of http-date works", + "result": { + "httpDate": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n Tue, 29 Apr 2014 18:30:38 GMT\n\n" + } + }, + { + "id": "XmlTimestampsWithHttpDateOnTargetFormat", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/XmlTimestamps", + "responseCode": 200 + }, + "output": { + "shape": "XmlTimestampsResponse" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of http-date on the target shape works", + "result": { + "httpDateOnTarget": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n Tue, 29 Apr 2014 18:30:38 GMT\n\n" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "ListMember": ["one", "two", "three"] - }, - "response": { - "status_code": 200, - "headers": { - "x-amz-list-member": " one,two , three " - }, - "body": "" - } - } - ] - } + { + "description": "Test cases for XmlUnions operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlUnionsResponse": { + "type": "structure", + "members": { + "unionValue": { + "shape": "XmlUnionShape" + } + } + }, + "XmlUnionShape": { + "type": "structure", + "members": { + "stringValue": { + "shape": "String" + }, + "booleanValue": { + "shape": "Boolean" + }, + "byteValue": { + "shape": "Integer" + }, + "shortValue": { + "shape": "Integer" + }, + "integerValue": { + "shape": "Integer" + }, + "longValue": { + "shape": "Long" + }, + "floatValue": { + "shape": "Float" + }, + "doubleValue": { + "shape": "Double" + }, + "unionValue": { + "shape": "XmlUnionShape" + }, + "structValue": { + "shape": "XmlNestedUnionStruct" + } + }, + "union": true + }, + "String": { + "type": "string" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + }, + "Long": { + "type": "long", + "box": true + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + }, + "XmlNestedUnionStruct": { + "type": "structure", + "members": { + "stringValue": { + "shape": "String" + }, + "booleanValue": { + "shape": "Boolean" + }, + "byteValue": { + "shape": "Integer" + }, + "shortValue": { + "shape": "Integer" + }, + "integerValue": { + "shape": "Integer" + }, + "longValue": { + "shape": "Long" + }, + "floatValue": { + "shape": "Float" + }, + "doubleValue": { + "shape": "Double" + } + } + } + }, + "cases": [ + { + "id": "XmlUnionsWithStructMember", + "given": { + "name": "XmlUnions", + "http": { + "method": "PUT", + "requestUri": "/XmlUnions", + "responseCode": 200 + }, + "output": { + "shape": "XmlUnionsResponse" + }, + "idempotent": true + }, + "description": "Serializes union struct member", + "result": { + "unionValue": { + "structValue": { + "stringValue": "string", + "booleanValue": true, + "byteValue": 1, + "shortValue": 2, + "integerValue": 3, + "longValue": 4, + "floatValue": 5.5, + "doubleValue": 6.5 + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n \n \n string\n true\n 1\n 2\n 3\n 4\n 5.5\n 6.5\n \n \n\n" + } + }, + { + "id": "XmlUnionsWithStringMember", + "given": { + "name": "XmlUnions", + "http": { + "method": "PUT", + "requestUri": "/XmlUnions", + "responseCode": 200 + }, + "output": { + "shape": "XmlUnionsResponse" + }, + "idempotent": true + }, + "description": "Serializes union string member", + "result": { + "unionValue": { + "stringValue": "some string" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n \n some string\n \n\n" + } + }, + { + "id": "XmlUnionsWithBooleanMember", + "given": { + "name": "XmlUnions", + "http": { + "method": "PUT", + "requestUri": "/XmlUnions", + "responseCode": 200 + }, + "output": { + "shape": "XmlUnionsResponse" + }, + "idempotent": true + }, + "description": "Serializes union boolean member", + "result": { + "unionValue": { + "booleanValue": true + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n \n true\n \n\n" + } + }, + { + "id": "XmlUnionsWithUnionMember", + "given": { + "name": "XmlUnions", + "http": { + "method": "PUT", + "requestUri": "/XmlUnions", + "responseCode": 200 + }, + "output": { + "shape": "XmlUnionsResponse" + }, + "idempotent": true + }, + "description": "Serializes union member", + "result": { + "unionValue": { + "unionValue": { + "booleanValue": true + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "\n \n \n true\n \n \n\n" + } + } + ] + } ] From 9a94f30f1f08553b452d68518b029d71c0036a82 Mon Sep 17 00:00:00 2001 From: jonathan343 Date: Tue, 23 Jul 2024 22:46:17 -0700 Subject: [PATCH 03/11] Add smithy generated request serialization protocol tests --- tests/unit/protocols/input/ec2.json | 1689 +++-- tests/unit/protocols/input/json.json | 3085 +++++--- tests/unit/protocols/input/json_1_0.json | 878 +++ tests/unit/protocols/input/query.json | 2535 ++++--- tests/unit/protocols/input/rest-json.json | 8019 +++++++++++++++------ tests/unit/protocols/input/rest-xml.json | 7523 ++++++++++++++----- 6 files changed, 17331 insertions(+), 6398 deletions(-) create mode 100644 tests/unit/protocols/input/json_1_0.json diff --git a/tests/unit/protocols/input/ec2.json b/tests/unit/protocols/input/ec2.json index 486766a9b4..200ac6e16a 100644 --- a/tests/unit/protocols/input/ec2.json +++ b/tests/unit/protocols/input/ec2.json @@ -1,531 +1,1218 @@ [ - { - "description": "Scalar members", - "metadata": { - "protocol": "ec2", - "apiVersion": "2014-01-01" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "Foo": { - "shape": "StringType" - }, - "Bar": { - "shape": "StringType" - } - } - }, - "StringType": { - "type": "string" - } - }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" + { + "description": "Test cases for EmptyInputAndEmptyOutput operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" }, - "params": { - "Foo": "val1", - "Bar": "val2" + "shapes": { + "EmptyInputAndEmptyOutputInput": { + "type": "structure", + "members": {} + } }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&Foo=val1&Bar=val2" - } - } - ] - }, - { - "description": "Structure with locationName and queryName applied to members", - "metadata": { - "protocol": "ec2", - "apiVersion": "2014-01-01" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "Foo": { - "shape": "StringType" - }, - "Bar": { - "shape": "StringType", - "locationName": "barLocationName" - }, - "Yuck": { - "shape": "StringType", - "locationName": "yuckLocationName", - "queryName": "yuckQueryName" - } - } - }, - "StringType": { - "type": "string" - } + "cases": [ + { + "id": "Ec2QueryEmptyInputAndEmptyOutput", + "given": { + "name": "EmptyInputAndEmptyOutput", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "EmptyInputAndEmptyOutputInput" + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response members.

While this should be rare, code generators must support this.

" + }, + "description": "Empty input serializes no extra query params", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=EmptyInputAndEmptyOutput&Version=2020-01-08", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + } + } + ] }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" + { + "description": "Test cases for EndpointOperation operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" }, - "params": { - "Foo": "val1", - "Bar": "val2", - "Yuck": "val3" - }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&Foo=val1&BarLocationName=val2&yuckQueryName=val3" - } - } - ] - }, - { - "description": "Nested structure members", - "metadata": { - "protocol": "ec2", - "apiVersion": "2014-01-01" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "StructArg": { - "shape": "StructType", - "locationName": "Struct" - } - } - }, - "StructType": { - "type": "structure", - "members": { - "ScalarArg": { - "shape": "StringType", - "locationName": "Scalar" - } - } - }, - "StringType": { - "type": "string" - } + "shapes": {}, + "cases": [ + { + "id": "Ec2QueryEndpointTrait", + "given": { + "name": "EndpointOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "endpoint": { + "hostPrefix": "foo." + } + }, + "description": "Operations can prepend to the given host if they define the\nendpoint trait.", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=EndpointOperation&Version=2020-01-08", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "host": "foo.example.com" + } + } + ], + "clientEndpoint": "https://example.com" }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" + { + "description": "Test cases for EndpointWithHostLabelOperation operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" }, - "params": { - "StructArg": { - "ScalarArg": "foo" - } + "shapes": { + "HostLabelInput": { + "type": "structure", + "required": [ + "label" + ], + "members": { + "label": { + "shape": "String", + "hostLabel": true + } + } + }, + "String": { + "type": "string" + } }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&Struct.Scalar=foo" - } - } - ] - }, - { - "description": "List types", - "metadata": { - "protocol": "ec2", - "apiVersion": "2014-01-01" + "cases": [ + { + "id": "Ec2QueryEndpointTraitWithHostLabel", + "given": { + "name": "EndpointWithHostLabelOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "HostLabelInput" + }, + "endpoint": { + "hostPrefix": "foo.{label}." + } + }, + "description": "Operations can prepend to the given host if they define the\nendpoint trait, and can use the host label trait to define\nfurther customization based on user input.", + "params": { + "label": "bar" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=EndpointWithHostLabelOperation&Version=2020-01-08&Label=bar", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "host": "foo.bar.example.com" + } + } + ], + "clientEndpoint": "https://example.com" }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "ListArg": { - "shape": "ListType" - } - } - }, - "ListType": { - "type": "list", - "member": { - "shape": "Strings" - } - }, - "Strings": { - "type": "string" - } - }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "ListArg": [ - "foo", - "bar", - "baz" - ] + { + "description": "Test cases for HostWithPathOperation operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&ListArg.1=foo&ListArg.2=bar&ListArg.3=baz" - } - } - ] - }, - { - "description": "List with location name applied to member", - "metadata": { - "protocol": "ec2", - "apiVersion": "2014-01-01" + "shapes": {}, + "cases": [ + { + "id": "Ec2QueryHostWithPath", + "given": { + "name": "HostWithPathOperation", + "http": { + "method": "POST", + "requestUri": "/" + } + }, + "description": "Custom endpoints supplied by users can have paths", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/custom/", + "body": "Action=HostWithPathOperation&Version=2020-01-08", + "host": "example.com/custom" + } + } + ], + "clientEndpoint": "https://example.com/custom" }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "ListArg": { - "shape": "ListType", - "locationName": "ListMemberName" - } - } - }, - "ListType": { - "type": "list", - "member": { - "shape": "StringType", - "LocationName": "item" - } - }, - "StringType": { - "type": "string" - } - }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" + { + "description": "Test cases for NestedStructures operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" }, - "params": { - "ListArg": [ - "a", - "b", - "c" - ] + "shapes": { + "NestedStructuresInput": { + "type": "structure", + "members": { + "Nested": { + "shape": "StructArg" + } + } + }, + "StructArg": { + "type": "structure", + "members": { + "StringArg": { + "shape": "String" + }, + "OtherArg": { + "shape": "Boolean" + }, + "RecursiveArg": { + "shape": "StructArg" + } + } + }, + "String": { + "type": "string" + }, + "Boolean": { + "type": "boolean", + "box": true + } }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&ListMemberName.1=a&ListMemberName.2=b&ListMemberName.3=c" - } - } - ] - }, - { - "description": "List with locationName and queryName", - "metadata": { - "protocol": "ec2", - "apiVersion": "2014-01-01" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "ListArg": { - "shape": "ListType", - "locationName": "ListMemberName", - "queryName": "ListQueryName" - } - } - }, - "ListType": { - "type": "list", - "member": { - "shape": "StringType", - "LocationName": "item" - } - }, - "StringType": { - "type": "string" - } + "cases": [ + { + "id": "Ec2NestedStructures", + "given": { + "name": "NestedStructures", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "NestedStructuresInput" + }, + "documentation": "

This test serializes nested and recursive structure members.

" + }, + "description": "Serializes nested structures using dots", + "params": { + "Nested": { + "StringArg": "foo", + "OtherArg": true, + "RecursiveArg": { + "StringArg": "baz" + } + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=NestedStructures&Version=2020-01-08&Nested.StringArg=foo&Nested.OtherArg=true&Nested.RecursiveArg.StringArg=baz", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + } + ] }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" + { + "description": "Test cases for NoInputAndOutput operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" }, - "params": { - "ListArg": [ - "a", - "b", - "c" - ] - }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&ListQueryName.1=a&ListQueryName.2=b&ListQueryName.3=c" - } - } - ] - }, - { - "description": "Base64 encoded Blobs", - "metadata": { - "protocol": "ec2", - "apiVersion": "2014-01-01" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "BlobArg": { - "shape": "BlobType" - } - } - }, - "BlobType": { - "type": "blob" - } + "shapes": {}, + "cases": [ + { + "id": "Ec2QueryNoInputAndOutput", + "given": { + "name": "NoInputAndOutput", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request payload or response members.

While this should be rare, code generators must support this.

" + }, + "description": "No input serializes no payload", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=NoInputAndOutput&Version=2020-01-08", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + } + } + ] }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" + { + "description": "Test cases for PutWithContentEncoding operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" }, - "params": { - "BlobArg": "foo" + "shapes": { + "PutWithContentEncodingInput": { + "type": "structure", + "members": { + "encoding": { + "shape": "String" + }, + "data": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&BlobArg=Zm9v" - } - } - ] - }, - { - "description": "Timestamp values", - "metadata": { - "protocol": "ec2", - "apiVersion": "2014-01-01" + "cases": [ + { + "id": "SDKAppliedContentEncoding_ec2Query", + "given": { + "name": "PutWithContentEncoding", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "PutWithContentEncodingInput" + }, + "requestcompression": { + "encodings": [ + "gzip" + ] + } + }, + "description": "Compression algorithm encoding is appended to the Content-Encoding header.", + "params": { + "data": "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\n" + }, + "serialized": { + "method": "POST", + "uri": "/", + "headers": { + "Content-Encoding": "gzip" + } + } + }, + { + "id": "SDKAppendsGzipAndIgnoresHttpProvidedEncoding_ec2Query", + "given": { + "name": "PutWithContentEncoding", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "PutWithContentEncodingInput" + }, + "requestcompression": { + "encodings": [ + "gzip" + ] + } + }, + "description": "Compression algorithm encoding is appended to the Content-Encoding header, and the\nuser-provided content-encoding is NOT in the Content-Encoding header since HTTP binding\ntraits are ignored in the ec2Query protocol.\n", + "params": { + "encoding": "custom", + "data": "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\n" + }, + "serialized": { + "method": "POST", + "uri": "/", + "headers": { + "Content-Encoding": "gzip" + } + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "TimeArg": { - "shape": "TimestampType" - }, - "TimeCustom": { - "timestampFormat": "unixTimestamp", - "shape": "TimestampType" - }, - "TimeFormat": { - "shape": "TimestampFormatType" - } - } - }, - "TimestampFormatType": { - "timestampFormat": "unixTimestamp", - "type": "timestamp" - }, - "TimestampType": { - "type": "timestamp" - } - }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" + { + "description": "Test cases for QueryIdempotencyTokenAutoFill operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" }, - "params": { - "TimeArg": 1422172800, - "TimeCustom": 1422172800, - "TimeFormat": 1422172800 + "shapes": { + "QueryIdempotencyTokenAutoFillInput": { + "type": "structure", + "members": { + "token": { + "shape": "String", + "idempotencyToken": true + } + } + }, + "String": { + "type": "string" + } }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&TimeArg=2015-01-25T08%3A00%3A00Z&TimeCustom=1422172800&TimeFormat=1422172800" - } - } - ] - }, - { - "description": "Idempotency token auto fill", - "metadata": { - "protocol": "ec2", - "apiVersion": "2014-01-01" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "Token": { - "shape": "StringType", - "idempotencyToken": true - } - } - }, - "StringType": { - "type": "string" - } + "cases": [ + { + "id": "Ec2ProtocolIdempotencyTokenAutoFill", + "given": { + "name": "QueryIdempotencyTokenAutoFill", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "QueryIdempotencyTokenAutoFillInput" + }, + "documentation": "

Automatically adds idempotency tokens.

" + }, + "description": "Automatically adds idempotency token when not set", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=QueryIdempotencyTokenAutoFill&Version=2020-01-08&Token=00000000-0000-4000-8000-000000000000", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "Ec2ProtocolIdempotencyTokenAutoFillIsSet", + "given": { + "name": "QueryIdempotencyTokenAutoFill", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "QueryIdempotencyTokenAutoFillInput" + }, + "documentation": "

Automatically adds idempotency tokens.

" + }, + "description": "Uses the given idempotency token as-is", + "params": { + "token": "00000000-0000-4000-8000-000000000123" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=QueryIdempotencyTokenAutoFill&Version=2020-01-08&Token=00000000-0000-4000-8000-000000000123", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + } + ] }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" + { + "description": "Test cases for QueryLists operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" }, - "params": { - "Token": "abc123" + "shapes": { + "QueryListsInput": { + "type": "structure", + "members": { + "ListArg": { + "shape": "StringList" + }, + "ComplexListArg": { + "shape": "GreetingList" + }, + "ListArgWithXmlNameMember": { + "shape": "ListWithXmlName" + }, + "ListArgWithXmlName": { + "shape": "ListWithXmlName", + "locationName": "Hi" + }, + "NestedWithList": { + "shape": "NestedStructWithList" + } + } + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "GreetingList": { + "type": "list", + "member": { + "shape": "GreetingStruct" + } + }, + "ListWithXmlName": { + "type": "list", + "member": { + "shape": "String", + "locationName": "item" + } + }, + "NestedStructWithList": { + "type": "structure", + "members": { + "ListArg": { + "shape": "StringList" + } + } + }, + "String": { + "type": "string" + }, + "GreetingStruct": { + "type": "structure", + "members": { + "hi": { + "shape": "String" + } + } + } }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&Token=abc123" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&Token=00000000-0000-4000-8000-000000000000" - } - } - ] - }, - { - "description": "Endpoint host trait", - "metadata": { - "protocol": "ec2", - "apiVersion": "2014-01-01" + "cases": [ + { + "id": "Ec2Lists", + "given": { + "name": "QueryLists", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "QueryListsInput" + }, + "documentation": "

This test serializes simple and complex lists.

" + }, + "description": "Serializes query lists. All EC2 lists are flattened.", + "params": { + "ListArg": [ + "foo", + "bar", + "baz" + ], + "ComplexListArg": [ + { + "hi": "hello" + }, + { + "hi": "hola" + } + ] + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=QueryLists&Version=2020-01-08&ListArg.1=foo&ListArg.2=bar&ListArg.3=baz&ComplexListArg.1.Hi=hello&ComplexListArg.2.Hi=hola", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + } + }, + { + "id": "Ec2EmptyQueryLists", + "given": { + "name": "QueryLists", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "QueryListsInput" + }, + "documentation": "

This test serializes simple and complex lists.

" + }, + "description": "Does not serialize empty query lists.", + "params": { + "ListArg": [] + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=QueryLists&Version=2020-01-08", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + } + }, + { + "id": "Ec2ListArgWithXmlNameMember", + "given": { + "name": "QueryLists", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "QueryListsInput" + }, + "documentation": "

This test serializes simple and complex lists.

" + }, + "description": "An xmlName trait in the member of a list has no effect on the list serialization.", + "params": { + "ListArgWithXmlNameMember": [ + "A", + "B" + ] + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=QueryLists&Version=2020-01-08&ListArgWithXmlNameMember.1=A&ListArgWithXmlNameMember.2=B", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + } + }, + { + "id": "Ec2ListMemberWithXmlName", + "given": { + "name": "QueryLists", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "QueryListsInput" + }, + "documentation": "

This test serializes simple and complex lists.

" + }, + "description": "Changes the name of the list using the xmlName trait", + "params": { + "ListArgWithXmlName": [ + "A", + "B" + ] + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=QueryLists&Version=2020-01-08&Hi.1=A&Hi.2=B", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + } + }, + { + "id": "Ec2ListNestedStructWithList", + "given": { + "name": "QueryLists", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "QueryListsInput" + }, + "documentation": "

This test serializes simple and complex lists.

" + }, + "description": "Nested structure with a list member", + "params": { + "NestedWithList": { + "ListArg": [ + "A", + "B" + ] + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=QueryLists&Version=2020-01-08&NestedWithList.ListArg.1=A&NestedWithList.ListArg.2=B", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + } + } + ] }, - "clientEndpoint": "https://service.region.amazonaws.com", - "shapes": { - "StaticInputShape": { - "type": "structure", - "members": { - "Name": { - "shape": "StringType" - } - } - }, - "MemberRefInputShape": { - "type": "structure", - "members": { - "Name": { - "shape": "StringType", - "hostLabel": true - } - } - }, - "StringType": { - "type": "string" - } - }, - "cases": [ - { - "given": { - "name": "StaticOp", - "input": { - "shape": "StaticInputShape" - }, - "endpoint":{ - "hostPrefix": "data-" - } + { + "description": "Test cases for QueryTimestamps operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" }, - "params": { - "Name": "myname" + "shapes": { + "QueryTimestampsInput": { + "type": "structure", + "members": { + "normalFormat": { + "shape": "Timestamp" + }, + "epochMember": { + "shape": "SyntheticTimestamp_epoch_seconds" + }, + "epochTarget": { + "shape": "EpochSeconds" + } + } + }, + "Timestamp": { + "type": "timestamp" + }, + "SyntheticTimestamp_epoch_seconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "EpochSeconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + } }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=StaticOp&Version=2014-01-01&Name=myname", - "host": "data-service.region.amazonaws.com" - } - }, - { - "given": { - "name": "MemberRefOp", - "input": { - "shape": "MemberRefInputShape" - }, - "endpoint":{ - "hostPrefix": "foo-{Name}." - } + "cases": [ + { + "id": "Ec2TimestampsInput", + "given": { + "name": "QueryTimestamps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "QueryTimestampsInput" + }, + "documentation": "

This test serializes timestamps.

  1. Timestamps are serialized as RFC 3339 date-time values by default.
  2. A timestampFormat trait on a member changes the format.
  3. A timestampFormat trait on the shape targeted by the member changes the format.
" + }, + "description": "Serializes timestamps", + "params": { + "normalFormat": 1422172800, + "epochMember": 1422172800, + "epochTarget": 1422172800 + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=QueryTimestamps&Version=2020-01-08&NormalFormat=2015-01-25T08%3A00%3A00Z&EpochMember=1422172800&EpochTarget=1422172800", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + } + ] + }, + { + "description": "Test cases for SimpleInputParams operation", + "metadata": { + "protocol": "ec2", + "protocols": [ + "ec2" + ], + "apiVersion": "2020-01-08" }, - "params": { - "Name": "myname" + "shapes": { + "SimpleInputParamsInput": { + "type": "structure", + "members": { + "Foo": { + "shape": "String" + }, + "Bar": { + "shape": "String" + }, + "Baz": { + "shape": "Boolean" + }, + "Bam": { + "shape": "Integer" + }, + "FloatValue": { + "shape": "Float" + }, + "Boo": { + "shape": "Double" + }, + "Qux": { + "shape": "Blob" + }, + "FooEnum": { + "shape": "FooEnum" + }, + "HasQueryName": { + "shape": "String" + }, + "HasQueryAndXmlName": { + "shape": "String", + "locationName": "hasQueryAndXmlName" + }, + "UsesXmlName": { + "shape": "String", + "locationName": "usesXmlName" + } + } + }, + "String": { + "type": "string" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + }, + "Blob": { + "type": "blob" + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + } }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=MemberRefOp&Version=2014-01-01&Name=myname", - "host": "foo-myname.service.region.amazonaws.com" - } - } - ] - } + "cases": [ + { + "id": "Ec2SimpleInputParamsStrings", + "given": { + "name": "SimpleInputParams", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleInputParamsInput" + }, + "documentation": "

This test serializes strings, numbers, and boolean values.

" + }, + "description": "Serializes strings", + "params": { + "Foo": "val1", + "Bar": "val2" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&Foo=val1&Bar=val2", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "Ec2SimpleInputParamsStringAndBooleanTrue", + "given": { + "name": "SimpleInputParams", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleInputParamsInput" + }, + "documentation": "

This test serializes strings, numbers, and boolean values.

" + }, + "description": "Serializes booleans that are true", + "params": { + "Foo": "val1", + "Baz": true + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&Foo=val1&Baz=true", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "Ec2SimpleInputParamsStringsAndBooleanFalse", + "given": { + "name": "SimpleInputParams", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleInputParamsInput" + }, + "documentation": "

This test serializes strings, numbers, and boolean values.

" + }, + "description": "Serializes booleans that are false", + "params": { + "Baz": false + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&Baz=false", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "Ec2SimpleInputParamsInteger", + "given": { + "name": "SimpleInputParams", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleInputParamsInput" + }, + "documentation": "

This test serializes strings, numbers, and boolean values.

" + }, + "description": "Serializes integers", + "params": { + "Bam": 10 + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&Bam=10", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "Ec2SimpleInputParamsFloat", + "given": { + "name": "SimpleInputParams", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleInputParamsInput" + }, + "documentation": "

This test serializes strings, numbers, and boolean values.

" + }, + "description": "Serializes floats", + "params": { + "Boo": 10.8 + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&Boo=10.8", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "Ec2SimpleInputParamsBlob", + "given": { + "name": "SimpleInputParams", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleInputParamsInput" + }, + "documentation": "

This test serializes strings, numbers, and boolean values.

" + }, + "description": "Blobs are base64 encoded in the query string", + "params": { + "Qux": "value" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&Qux=dmFsdWU%3D", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "Ec2Enums", + "given": { + "name": "SimpleInputParams", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleInputParamsInput" + }, + "documentation": "

This test serializes strings, numbers, and boolean values.

" + }, + "description": "Serializes enums in the query string", + "params": { + "FooEnum": "Foo" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&FooEnum=Foo", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "Ec2Query", + "given": { + "name": "SimpleInputParams", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleInputParamsInput" + }, + "documentation": "

This test serializes strings, numbers, and boolean values.

" + }, + "description": "Serializes query using ec2QueryName trait.", + "params": { + "HasQueryName": "Hi" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&HasQueryName=Hi", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "Ec2QueryIsPreferred", + "given": { + "name": "SimpleInputParams", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleInputParamsInput" + }, + "documentation": "

This test serializes strings, numbers, and boolean values.

" + }, + "description": "ec2QueryName trait is preferred over xmlName.", + "params": { + "HasQueryAndXmlName": "Hi" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&HasQueryAndXmlName=Hi", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "Ec2XmlNameIsUppercased", + "given": { + "name": "SimpleInputParams", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleInputParamsInput" + }, + "documentation": "

This test serializes strings, numbers, and boolean values.

" + }, + "description": "xmlName is used with the ec2 protocol, but the first character is uppercased", + "params": { + "UsesXmlName": "Hi" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&UsesXmlName=Hi", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "Ec2QuerySupportsNaNFloatInputs", + "given": { + "name": "SimpleInputParams", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleInputParamsInput" + }, + "documentation": "

This test serializes strings, numbers, and boolean values.

" + }, + "description": "Supports handling NaN float values.", + "params": { + "FloatValue": "NaN", + "Boo": "NaN" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&FloatValue=NaN&Boo=NaN", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "Ec2QuerySupportsInfinityFloatInputs", + "given": { + "name": "SimpleInputParams", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleInputParamsInput" + }, + "documentation": "

This test serializes strings, numbers, and boolean values.

" + }, + "description": "Supports handling Infinity float values.", + "params": { + "FloatValue": "Infinity", + "Boo": "Infinity" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&FloatValue=Infinity&Boo=Infinity", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "Ec2QuerySupportsNegativeInfinityFloatInputs", + "given": { + "name": "SimpleInputParams", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleInputParamsInput" + }, + "documentation": "

This test serializes strings, numbers, and boolean values.

" + }, + "description": "Supports handling -Infinity float values.", + "params": { + "FloatValue": "-Infinity", + "Boo": "-Infinity" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&FloatValue=-Infinity&Boo=-Infinity", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + } + ] + } ] diff --git a/tests/unit/protocols/input/json.json b/tests/unit/protocols/input/json.json index 5672848a90..13cd22aa18 100644 --- a/tests/unit/protocols/input/json.json +++ b/tests/unit/protocols/input/json.json @@ -1,906 +1,2257 @@ [ - { - "description": "Scalar members", - "metadata": { - "protocol": "json", - "jsonVersion": "1.1", - "targetPrefix": "com.amazonaws.foo" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "Name": { - "shape": "StringType" - } - } - }, - "StringType": { - "type": "string" - } - }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName", - "http": { - "method": "POST" - } - }, - "params": { - "Name": "myname" + { + "description": "Test cases for EmptyOperation operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "serialized": { - "body": "{\"Name\": \"myname\"}", - "headers": { - "X-Amz-Target": "com.amazonaws.foo.OperationName", - "Content-Type": "application/x-amz-json-1.1" - }, - "uri": "/" - } - } - ] - }, - { - "description": "Timestamp values", - "metadata": { - "protocol": "json", - "jsonVersion": "1.1", - "targetPrefix": "com.amazonaws.foo" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "TimeArg": { - "shape": "TimestampType" - }, - "TimeCustom": { - "timestampFormat": "rfc822", - "shape": "TimestampType" - }, - "TimeFormat": { - "shape": "TimestampFormatType" - } - } - }, - "TimestampFormatType": { - "timestampFormat": "rfc822", - "type": "timestamp" - }, - "TimestampType": { - "type": "timestamp" - } - }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "TimeArg": 1422172800, - "TimeCustom": 1422172800, - "TimeFormat": 1422172800 - }, - "serialized": { - "body": "{\"TimeArg\": 1422172800, \"TimeCustom\": \"Sun, 25 Jan 2015 08:00:00 GMT\", \"TimeFormat\": \"Sun, 25 Jan 2015 08:00:00 GMT\"}", - "headers": { - "X-Amz-Target": "com.amazonaws.foo.OperationName", - "Content-Type": "application/x-amz-json-1.1" - }, - "uri": "/" - } - } - ] - }, - { - "description": "Base64 encoded Blobs", - "metadata": { - "protocol": "json", - "jsonVersion": "1.1", - "targetPrefix": "com.amazonaws.foo" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "BlobArg": { - "shape": "BlobType" - }, - "BlobMap": { - "shape": "BlobMapType" - } - } - }, - "BlobType": { - "type": "blob" - }, - "BlobMapType": { - "type": "map", - "key": {"shape": "StringType"}, - "value": {"shape": "BlobType"} - }, - "StringType": { - "type": "string" - } + "shapes": {}, + "cases": [ + { + "id": "sends_requests_to_slash", + "given": { + "name": "EmptyOperation", + "http": { + "method": "POST", + "requestUri": "/" + } + }, + "description": "Sends requests to /", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.EmptyOperation" + } + } + }, + { + "id": "includes_x_amz_target_and_content_type", + "given": { + "name": "EmptyOperation", + "http": { + "method": "POST", + "requestUri": "/" + } + }, + "description": "Includes X-Amz-Target header and Content-Type", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.EmptyOperation" + } + } + }, + { + "id": "json_1_1_client_sends_empty_payload_for_no_input_shape", + "given": { + "name": "EmptyOperation", + "http": { + "method": "POST", + "requestUri": "/" + } + }, + "description": "Clients must always send an empty JSON object payload for\noperations with no input (that is, `{}`). While AWS service\nimplementations support requests with no payload or requests\nthat send `{}`, always sending `{}` from the client is\npreferred for forward compatibility in case input is ever\nadded to an operation.", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.EmptyOperation" + } + } + } + ] }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "BlobArg": "foo" + { + "description": "Test cases for EndpointOperation operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "serialized": { - "body": "{\"BlobArg\": \"Zm9v\"}", - "headers": { - "X-Amz-Target": "com.amazonaws.foo.OperationName", - "Content-Type": "application/x-amz-json-1.1" - }, - "uri": "/" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "BlobMap": { - "key1": "foo", - "key2": "bar" - } - }, - "serialized": { - "body": "{\"BlobMap\": {\"key1\": \"Zm9v\", \"key2\": \"YmFy\"}}", - "headers": { - "X-Amz-Target": "com.amazonaws.foo.OperationName", - "Content-Type": "application/x-amz-json-1.1" - }, - "uri": "/" - } - } - ] - }, - { - "description": "Nested blobs", - "metadata": { - "protocol": "json", - "jsonVersion": "1.1", - "targetPrefix": "com.amazonaws.foo" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "ListParam": { - "shape": "ListOfStructures" - } - } - }, - "ListOfStructures": { - "type": "list", - "member": { - "shape": "BlobType" - } - }, - "BlobType": { - "type": "blob" - } + "shapes": {}, + "cases": [ + { + "id": "AwsJson11EndpointTrait", + "given": { + "name": "EndpointOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "endpoint": { + "hostPrefix": "foo." + } + }, + "description": "Operations can prepend to the given host if they define the\nendpoint trait.", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.EndpointOperation" + }, + "host": "foo.example.com" + } + } + ], + "clientEndpoint": "https://example.com" }, - "cases": [ - { - "given": { - "http": { - "method": "POST" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" + { + "description": "Test cases for EndpointWithHostLabelOperation operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "params": { - "ListParam": ["foo", "bar"] + "shapes": { + "HostLabelInput": { + "type": "structure", + "required": [ + "label" + ], + "members": { + "label": { + "shape": "String", + "hostLabel": true + } + } + }, + "String": { + "type": "string" + } }, - "serialized": { - "body": "{\"ListParam\": [\"Zm9v\", \"YmFy\"]}", - "uri": "/", - "headers": { - "X-Amz-Target": "com.amazonaws.foo.OperationName", - "Content-Type": "application/x-amz-json-1.1" - } - } - } - ] - }, - { - "description": "Recursive shapes", - "metadata": { - "protocol": "json", - "jsonVersion": "1.1", - "targetPrefix": "com.amazonaws.foo" + "cases": [ + { + "id": "AwsJson11EndpointTraitWithHostLabel", + "given": { + "name": "EndpointWithHostLabelOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "HostLabelInput" + }, + "endpoint": { + "hostPrefix": "foo.{label}." + } + }, + "description": "Operations can prepend to the given host if they define the\nendpoint trait, and can use the host label trait to define\nfurther customization based on user input.", + "params": { + "label": "bar" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"label\": \"bar\"}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.EndpointWithHostLabelOperation" + }, + "host": "foo.bar.example.com" + } + } + ], + "clientEndpoint": "https://example.com" }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "RecursiveStruct": { - "shape": "RecursiveStructType" - } - } - }, - "RecursiveStructType": { - "type": "structure", - "members": { - "NoRecurse": { - "shape": "StringType" - }, - "RecursiveStruct": { - "shape": "RecursiveStructType" - }, - "RecursiveList": { - "shape": "RecursiveListType" - }, - "RecursiveMap": { - "shape": "RecursiveMapType" - } - } - }, - "RecursiveListType": { - "type": "list", - "member": { - "shape": "RecursiveStructType" - } - }, - "RecursiveMapType": { - "type": "map", - "key": { - "shape": "StringType" + { + "description": "Test cases for HostWithPathOperation operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "value": { - "shape": "RecursiveStructType" - } - }, - "StringType": { - "type": "string" - } + "shapes": {}, + "cases": [ + { + "id": "AwsJson11HostWithPath", + "given": { + "name": "HostWithPathOperation", + "http": { + "method": "POST", + "requestUri": "/" + } + }, + "description": "Custom endpoints supplied by users can have paths", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/custom/", + "body": "{}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.HostWithPathOperation" + }, + "host": "example.com/custom" + } + } + ], + "clientEndpoint": "https://example.com/custom" }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "RecursiveStruct": { - "NoRecurse": "foo" - } - }, - "serialized": { - "uri": "/", - "headers": { - "X-Amz-Target": "com.amazonaws.foo.OperationName", - "Content-Type": "application/x-amz-json-1.1" - }, - "body": "{\"RecursiveStruct\": {\"NoRecurse\": \"foo\"}}" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" + { + "description": "Test cases for JsonEnums operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "params": { - "RecursiveStruct": { - "RecursiveStruct": { - "NoRecurse": "foo" + "shapes": { + "JsonEnumsInputOutput": { + "type": "structure", + "members": { + "fooEnum1": { + "shape": "FooEnum" + }, + "fooEnum2": { + "shape": "FooEnum" + }, + "fooEnum3": { + "shape": "FooEnum" + }, + "fooEnumList": { + "shape": "FooEnumList" + }, + "fooEnumSet": { + "shape": "FooEnumSet" + }, + "fooEnumMap": { + "shape": "FooEnumMap" + } + } + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "FooEnumSet": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "FooEnumMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "FooEnum" + } + }, + "String": { + "type": "string" } - } }, - "serialized": { - "uri": "/", - "headers": { - "X-Amz-Target": "com.amazonaws.foo.OperationName", - "Content-Type": "application/x-amz-json-1.1" - }, - "body": "{\"RecursiveStruct\": {\"RecursiveStruct\": {\"NoRecurse\": \"foo\"}}}" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "RecursiveStruct": { - "RecursiveStruct": { - "RecursiveStruct": { - "RecursiveStruct": { - "NoRecurse": "foo" - } - } + "cases": [ + { + "id": "AwsJson11Enums", + "given": { + "name": "JsonEnums", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "JsonEnumsInputOutput" + }, + "documentation": "

This example serializes enums as top level properties, in lists, sets, and maps.

", + "idempotent": true + }, + "description": "Serializes simple scalar properties", + "params": { + "fooEnum1": "Foo", + "fooEnum2": "0", + "fooEnum3": "1", + "fooEnumList": [ + "Foo", + "0" + ], + "fooEnumSet": [ + "Foo", + "0" + ], + "fooEnumMap": { + "hi": "Foo", + "zero": "0" + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"fooEnum1\": \"Foo\",\n \"fooEnum2\": \"0\",\n \"fooEnum3\": \"1\",\n \"fooEnumList\": [\n \"Foo\",\n \"0\"\n ],\n \"fooEnumSet\": [\n \"Foo\",\n \"0\"\n ],\n \"fooEnumMap\": {\n \"hi\": \"Foo\",\n \"zero\": \"0\"\n }\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.JsonEnums" + } + } } - } - }, - "serialized": { - "uri": "/", - "headers": { - "X-Amz-Target": "com.amazonaws.foo.OperationName", - "Content-Type": "application/x-amz-json-1.1" - }, - "body": "{\"RecursiveStruct\": {\"RecursiveStruct\": {\"RecursiveStruct\": {\"RecursiveStruct\": {\"NoRecurse\": \"foo\"}}}}}" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "RecursiveStruct": { - "RecursiveList": [ - { - "NoRecurse": "foo" - }, - { - "NoRecurse": "bar" - } - ] - } - }, - "serialized": { - "uri": "/", - "headers": { - "X-Amz-Target": "com.amazonaws.foo.OperationName", - "Content-Type": "application/x-amz-json-1.1" - }, - "body": "{\"RecursiveStruct\": {\"RecursiveList\": [{\"NoRecurse\": \"foo\"}, {\"NoRecurse\": \"bar\"}]}}" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "RecursiveStruct": { - "RecursiveList": [ - { - "NoRecurse": "foo" - }, - { - "RecursiveStruct": { - "NoRecurse": "bar" - } - } - ] - } - }, - "serialized": { - "uri": "/", - "headers": { - "X-Amz-Target": "com.amazonaws.foo.OperationName", - "Content-Type": "application/x-amz-json-1.1" - }, - "body": "{\"RecursiveStruct\": {\"RecursiveList\": [{\"NoRecurse\": \"foo\"}, {\"RecursiveStruct\": {\"NoRecurse\": \"bar\"}}]}}" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" + ] + }, + { + "description": "Test cases for JsonUnions operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "params": { - "RecursiveStruct": { - "RecursiveMap": { - "foo": { - "NoRecurse": "foo" - }, - "bar": { - "NoRecurse": "bar" - } + "shapes": { + "UnionInputOutput": { + "type": "structure", + "members": { + "contents": { + "shape": "MyUnion" + } + }, + "documentation": "

A shared structure that contains a single union member.

" + }, + "MyUnion": { + "type": "structure", + "members": { + "stringValue": { + "shape": "String" + }, + "booleanValue": { + "shape": "Boolean" + }, + "numberValue": { + "shape": "Integer" + }, + "blobValue": { + "shape": "Blob" + }, + "timestampValue": { + "shape": "Timestamp" + }, + "enumValue": { + "shape": "FooEnum" + }, + "listValue": { + "shape": "StringList" + }, + "mapValue": { + "shape": "StringMap" + }, + "structureValue": { + "shape": "GreetingStruct" + } + }, + "documentation": "

A union with a representative set of types for members.

", + "union": true + }, + "String": { + "type": "string" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + }, + "Blob": { + "type": "blob" + }, + "Timestamp": { + "type": "timestamp" + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "String" + } + }, + "GreetingStruct": { + "type": "structure", + "members": { + "hi": { + "shape": "String" + } + } } - } - }, - "serialized": { - "uri": "/", - "headers": { - "X-Amz-Target": "com.amazonaws.foo.OperationName", - "Content-Type": "application/x-amz-json-1.1" - }, - "body": "{\"RecursiveStruct\": {\"RecursiveMap\": {\"foo\": {\"NoRecurse\": \"foo\"}, \"bar\": {\"NoRecurse\": \"bar\"}}}}" - } - } - ] - }, - { - "description": "Empty maps", - "metadata": { - "protocol": "json", - "jsonVersion": "1.1", - "targetPrefix": "com.amazonaws.foo" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "Map": { - "shape": "MapType" - } - } - }, - "MapType": { - "type": "map", - "key": { - "shape": "StringType" }, - "value": { - "shape": "StringType" - } - }, - "StringType": { - "type": "string" - } + "cases": [ + { + "id": "AwsJson11SerializeStringUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes a string union value", + "params": { + "contents": { + "stringValue": "foo" + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"contents\": {\n \"stringValue\": \"foo\"\n }\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.JsonUnions" + } + } + }, + { + "id": "AwsJson11SerializeBooleanUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes a boolean union value", + "params": { + "contents": { + "booleanValue": true + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"contents\": {\n \"booleanValue\": true\n }\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.JsonUnions" + } + } + }, + { + "id": "AwsJson11SerializeNumberUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes a number union value", + "params": { + "contents": { + "numberValue": 1 + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"contents\": {\n \"numberValue\": 1\n }\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.JsonUnions" + } + } + }, + { + "id": "AwsJson11SerializeBlobUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes a blob union value", + "params": { + "contents": { + "blobValue": "foo" + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"contents\": {\n \"blobValue\": \"Zm9v\"\n }\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.JsonUnions" + } + } + }, + { + "id": "AwsJson11SerializeTimestampUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes a timestamp union value", + "params": { + "contents": { + "timestampValue": 1398796238 + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"contents\": {\n \"timestampValue\": 1398796238\n }\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.JsonUnions" + } + } + }, + { + "id": "AwsJson11SerializeEnumUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes an enum union value", + "params": { + "contents": { + "enumValue": "Foo" + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"contents\": {\n \"enumValue\": \"Foo\"\n }\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.JsonUnions" + } + } + }, + { + "id": "AwsJson11SerializeListUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes a list union value", + "params": { + "contents": { + "listValue": [ + "foo", + "bar" + ] + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"contents\": {\n \"listValue\": [\"foo\", \"bar\"]\n }\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.JsonUnions" + } + } + }, + { + "id": "AwsJson11SerializeMapUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes a map union value", + "params": { + "contents": { + "mapValue": { + "foo": "bar", + "spam": "eggs" + } + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"contents\": {\n \"mapValue\": {\n \"foo\": \"bar\",\n \"spam\": \"eggs\"\n }\n }\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.JsonUnions" + } + } + }, + { + "id": "AwsJson11SerializeStructureUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes a structure union value", + "params": { + "contents": { + "structureValue": { + "hi": "hello" + } + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"contents\": {\n \"structureValue\": {\n \"hi\": \"hello\"\n }\n }\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.JsonUnions" + } + } + } + ] }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName", - "http": { - "method": "POST" - } + { + "description": "Test cases for KitchenSinkOperation operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "params": { - "Map": {} + "shapes": { + "KitchenSink": { + "type": "structure", + "members": { + "Blob": { + "shape": "Blob" + }, + "Boolean": { + "shape": "Boolean" + }, + "Double": { + "shape": "Double" + }, + "EmptyStruct": { + "shape": "EmptyStruct" + }, + "Float": { + "shape": "Float" + }, + "HttpdateTimestamp": { + "shape": "SyntheticTimestamp_http_date" + }, + "Integer": { + "shape": "Integer" + }, + "Iso8601Timestamp": { + "shape": "SyntheticTimestamp_date_time" + }, + "JsonValue": { + "shape": "JsonValue", + "jsonvalue": true + }, + "ListOfLists": { + "shape": "ListOfListOfStrings" + }, + "ListOfMapsOfStrings": { + "shape": "ListOfMapsOfStrings" + }, + "ListOfStrings": { + "shape": "ListOfStrings" + }, + "ListOfStructs": { + "shape": "ListOfStructs" + }, + "Long": { + "shape": "Long" + }, + "MapOfListsOfStrings": { + "shape": "MapOfListsOfStrings" + }, + "MapOfMaps": { + "shape": "MapOfMapOfStrings" + }, + "MapOfStrings": { + "shape": "MapOfStrings" + }, + "MapOfStructs": { + "shape": "MapOfStructs" + }, + "RecursiveList": { + "shape": "ListOfKitchenSinks" + }, + "RecursiveMap": { + "shape": "MapOfKitchenSinks" + }, + "RecursiveStruct": { + "shape": "KitchenSink" + }, + "SimpleStruct": { + "shape": "SimpleStruct" + }, + "String": { + "shape": "String" + }, + "StructWithJsonName": { + "shape": "StructWithJsonName" + }, + "Timestamp": { + "shape": "Timestamp" + }, + "UnixTimestamp": { + "shape": "SyntheticTimestamp_epoch_seconds" + } + } + }, + "Blob": { + "type": "blob" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Double": { + "type": "double", + "box": true + }, + "EmptyStruct": { + "type": "structure", + "members": {} + }, + "Float": { + "type": "float", + "box": true + }, + "SyntheticTimestamp_http_date": { + "type": "timestamp", + "timestampFormat": "rfc822" + }, + "Integer": { + "type": "integer", + "box": true + }, + "SyntheticTimestamp_date_time": { + "type": "timestamp", + "timestampFormat": "iso8601" + }, + "JsonValue": { + "type": "string" + }, + "ListOfListOfStrings": { + "type": "list", + "member": { + "shape": "ListOfStrings" + } + }, + "ListOfMapsOfStrings": { + "type": "list", + "member": { + "shape": "MapOfStrings" + } + }, + "ListOfStrings": { + "type": "list", + "member": { + "shape": "String" + } + }, + "ListOfStructs": { + "type": "list", + "member": { + "shape": "SimpleStruct" + } + }, + "Long": { + "type": "long", + "box": true + }, + "MapOfListsOfStrings": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "ListOfStrings" + } + }, + "MapOfMapOfStrings": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "MapOfStrings" + } + }, + "MapOfStrings": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "String" + } + }, + "MapOfStructs": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "SimpleStruct" + } + }, + "ListOfKitchenSinks": { + "type": "list", + "member": { + "shape": "KitchenSink" + } + }, + "MapOfKitchenSinks": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "KitchenSink" + } + }, + "SimpleStruct": { + "type": "structure", + "members": { + "Value": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + }, + "StructWithJsonName": { + "type": "structure", + "members": { + "Value": { + "shape": "String" + } + } + }, + "Timestamp": { + "type": "timestamp" + }, + "SyntheticTimestamp_epoch_seconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + } }, - "serialized": { - "body": "{\"Map\": {}}", - "headers": { - "X-Amz-Target": "com.amazonaws.foo.OperationName", - "Content-Type": "application/x-amz-json-1.1" - }, - "uri": "/" - } - } - ] - }, - { - "description": "Idempotency token auto fill", - "metadata": { - "protocol": "json", - "apiVersion": "2014-01-01", - "jsonVersion": "1.1", - "targetPrefix": "com.amazonaws.foo" - - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "Token": { - "shape": "StringType", - "idempotencyToken": true - } - } - }, - "StringType": { - "type": "string" - } + "cases": [ + { + "id": "serializes_string_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes string shapes", + "params": { + "String": "abc xyz" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"String\":\"abc xyz\"}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_string_shapes_with_jsonvalue_trait", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes string shapes with jsonvalue trait", + "params": { + "JsonValue": "{\"string\":\"value\",\"number\":1234.5,\"boolTrue\":true,\"boolFalse\":false,\"array\":[1,2,3,4],\"object\":{\"key\":\"value\"},\"null\":null}" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"JsonValue\":\"{\\\"string\\\":\\\"value\\\",\\\"number\\\":1234.5,\\\"boolTrue\\\":true,\\\"boolFalse\\\":false,\\\"array\\\":[1,2,3,4],\\\"object\\\":{\\\"key\\\":\\\"value\\\"},\\\"null\\\":null}\"}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_integer_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes integer shapes", + "params": { + "Integer": 1234 + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"Integer\":1234}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_long_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes long shapes", + "params": { + "Long": 999999999999 + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"Long\":999999999999}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_float_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes float shapes", + "params": { + "Float": 1234.5 + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"Float\":1234.5}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_double_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes double shapes", + "params": { + "Double": 1234.5 + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"Double\":1234.5}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_blob_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes blob shapes", + "params": { + "Blob": "binary-value" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"Blob\":\"YmluYXJ5LXZhbHVl\"}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_boolean_shapes_true", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes boolean shapes (true)", + "params": { + "Boolean": true + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"Boolean\":true}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_boolean_shapes_false", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes boolean shapes (false)", + "params": { + "Boolean": false + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"Boolean\":false}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_timestamp_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes timestamp shapes", + "params": { + "Timestamp": 946845296 + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"Timestamp\":946845296}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_timestamp_shapes_with_iso8601_timestampformat", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes timestamp shapes with iso8601 timestampFormat", + "params": { + "Iso8601Timestamp": 946845296 + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"Iso8601Timestamp\":\"2000-01-02T20:34:56Z\"}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_timestamp_shapes_with_httpdate_timestampformat", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes timestamp shapes with httpdate timestampFormat", + "params": { + "HttpdateTimestamp": 946845296 + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"HttpdateTimestamp\":\"Sun, 02 Jan 2000 20:34:56 GMT\"}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_timestamp_shapes_with_unixtimestamp_timestampformat", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes timestamp shapes with unixTimestamp timestampFormat", + "params": { + "UnixTimestamp": 946845296 + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"UnixTimestamp\":946845296}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_list_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes list shapes", + "params": { + "ListOfStrings": [ + "abc", + "mno", + "xyz" + ] + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"ListOfStrings\":[\"abc\",\"mno\",\"xyz\"]}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_empty_list_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes empty list shapes", + "params": { + "ListOfStrings": [] + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"ListOfStrings\":[]}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_list_of_map_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes list of map shapes", + "params": { + "ListOfMapsOfStrings": [ + { + "foo": "bar" + }, + { + "abc": "xyz" + }, + { + "red": "blue" + } + ] + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"ListOfMapsOfStrings\":[{\"foo\":\"bar\"},{\"abc\":\"xyz\"},{\"red\":\"blue\"}]}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_list_of_structure_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes list of structure shapes", + "params": { + "ListOfStructs": [ + { + "Value": "abc" + }, + { + "Value": "mno" + }, + { + "Value": "xyz" + } + ] + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"ListOfStructs\":[{\"Value\":\"abc\"},{\"Value\":\"mno\"},{\"Value\":\"xyz\"}]}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_list_of_recursive_structure_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes list of recursive structure shapes", + "params": { + "RecursiveList": [ + { + "RecursiveList": [ + { + "RecursiveList": [ + { + "Integer": 123 + } + ] + } + ] + } + ] + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"RecursiveList\":[{\"RecursiveList\":[{\"RecursiveList\":[{\"Integer\":123}]}]}]}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_map_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes map shapes", + "params": { + "MapOfStrings": { + "abc": "xyz", + "mno": "hjk" + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"MapOfStrings\":{\"abc\":\"xyz\",\"mno\":\"hjk\"}}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_empty_map_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes empty map shapes", + "params": { + "MapOfStrings": {} + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"MapOfStrings\":{}}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_map_of_list_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes map of list shapes", + "params": { + "MapOfListsOfStrings": { + "abc": [ + "abc", + "xyz" + ], + "mno": [ + "xyz", + "abc" + ] + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"MapOfListsOfStrings\":{\"abc\":[\"abc\",\"xyz\"],\"mno\":[\"xyz\",\"abc\"]}}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_map_of_structure_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes map of structure shapes", + "params": { + "MapOfStructs": { + "key1": { + "Value": "value-1" + }, + "key2": { + "Value": "value-2" + } + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"MapOfStructs\":{\"key1\":{\"Value\":\"value-1\"},\"key2\":{\"Value\":\"value-2\"}}}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_map_of_recursive_structure_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes map of recursive structure shapes", + "params": { + "RecursiveMap": { + "key1": { + "RecursiveMap": { + "key2": { + "RecursiveMap": { + "key3": { + "Boolean": false + } + } + } + } + } + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"RecursiveMap\":{\"key1\":{\"RecursiveMap\":{\"key2\":{\"RecursiveMap\":{\"key3\":{\"Boolean\":false}}}}}}}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_structure_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes structure shapes", + "params": { + "SimpleStruct": { + "Value": "abc" + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"SimpleStruct\":{\"Value\":\"abc\"}}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_structure_members_with_locationname_traits", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes structure members with locationName traits", + "params": { + "StructWithJsonName": { + "Value": "some-value" + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"StructWithJsonName\":{\"Value\":\"some-value\"}}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_empty_structure_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes empty structure shapes", + "params": { + "SimpleStruct": {} + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"SimpleStruct\":{}}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_structure_which_have_no_members", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes structure which have no members", + "params": { + "EmptyStruct": {} + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"EmptyStruct\":{}}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "serializes_recursive_structure_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "KitchenSink" + } + }, + "description": "Serializes recursive structure shapes", + "params": { + "String": "top-value", + "Boolean": false, + "RecursiveStruct": { + "String": "nested-value", + "Boolean": true, + "RecursiveList": [ + { + "String": "string-only" + }, + { + "RecursiveStruct": { + "MapOfStrings": { + "color": "red", + "size": "large" + } + } + } + ] + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"String\":\"top-value\",\"Boolean\":false,\"RecursiveStruct\":{\"String\":\"nested-value\",\"Boolean\":true,\"RecursiveList\":[{\"String\":\"string-only\"},{\"RecursiveStruct\":{\"MapOfStrings\":{\"color\":\"red\",\"size\":\"large\"}}}]}}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation" + }, + "requireHeaders": [ + "Content-Length" + ] + } + } + ] }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "http": { - "method": "POST" - }, - "name": "OperationName" - }, - "params": { - "Token": "abc123" + { + "description": "Test cases for NullOperation operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "serialized": { - "uri": "/", - "headers": {}, - "body": "{\"Token\": \"abc123\"}" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "http": { - "method": "POST" - }, - "name": "OperationName" - }, - "params": { + "shapes": { + "NullOperationInputOutput": { + "type": "structure", + "members": { + "string": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } }, - "serialized": { - "uri": "/", - "headers": {}, - "body": "{\"Token\": \"00000000-0000-4000-8000-000000000000\"}" - } - } - ] - }, - { - "description": "Endpoint host trait static prefix", - "metadata": { - "protocol": "json", - "jsonVersion": "1.1", - "targetPrefix": "com.amazonaws.foo" - }, - "clientEndpoint": "https://service.region.amazonaws.com", - "shapes": { - "StaticInputShape": { - "type": "structure", - "members": { - "Name": { - "shape": "StringType" - } - } - }, - "MemberRefInputShape": { - "type": "structure", - "members": { - "Name": { - "shape": "StringType", - "hostLabel": true - } - } - }, - "StringType": { - "type": "string" - } + "cases": [ + { + "id": "AwsJson11StructuresDontSerializeNullValues", + "given": { + "name": "NullOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "NullOperationInputOutput" + } + }, + "description": "Null structure values are dropped", + "params": { + "string": null + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.NullOperation" + } + } + } + ] }, - "cases": [ - { - "given": { - "name": "StaticOp", - "input": { - "shape": "StaticInputShape" - }, - "http": { - "method": "POST" - }, - "endpoint":{ - "hostPrefix": "data-" - } - }, - "params": { - "Name": "myname" + { + "description": "Test cases for OperationWithOptionalInputOutput operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "serialized": { - "headers": { - "X-Amz-Target": "com.amazonaws.foo.StaticOp", - "Content-Type": "application/x-amz-json-1.1" - }, - "uri": "/", - "body": "{\"Name\": \"myname\"}", - "host": "data-service.region.amazonaws.com" - } - }, - { - "given": { - "name": "MemberRefOp", - "input": { - "shape": "MemberRefInputShape" - }, - "http": { - "method": "POST" - }, - "endpoint":{ - "hostPrefix": "foo-{Name}." - } - }, - "params": { - "Name": "myname" + "shapes": { + "OperationWithOptionalInputOutputInput": { + "type": "structure", + "members": { + "Value": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } }, - "serialized": { - "headers": { - "X-Amz-Target": "com.amazonaws.foo.MemberRefOp", - "Content-Type": "application/x-amz-json-1.1" - }, - "uri": "/", - "body": "{\"Name\": \"myname\"}", - "host": "foo-myname.service.region.amazonaws.com" - } - } - ] - }, - { - "description": "Serializes document with standalone primitive type in a JSON request.", - "metadata": { - "protocol": "json", - "jsonVersion": "1.1", - "targetPrefix": "com.amazonaws.foo" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "inlineDocument": { - "shape": "DocumentType" + "cases": [ + { + "id": "can_call_operation_with_no_input_or_output", + "given": { + "name": "OperationWithOptionalInputOutput", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "OperationWithOptionalInputOutputInput" + } + }, + "description": "Can call operations with no input or output", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.OperationWithOptionalInputOutput" + } + } + }, + { + "id": "can_call_operation_with_optional_input", + "given": { + "name": "OperationWithOptionalInputOutput", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "OperationWithOptionalInputOutputInput" + } + }, + "description": "Can invoke operations with optional input", + "params": { + "Value": "Hi" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"Value\":\"Hi\"}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.OperationWithOptionalInputOutput" + } + } } - } - }, - "DocumentType": { - "type": "structure", - "document": true - } + ] }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName", - "http": { - "method": "POST" - } - }, - "params": { - "inlineDocument": "foo" - }, - "serialized": { - "headers": { - "X-Amz-Target": "com.amazonaws.foo.OperationName", - "Content-Type": "application/x-amz-json-1.1" - }, - "uri": "/", - "body": "{\"inlineDocument\": \"foo\"}" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName", - "http": { - "method": "POST" - } - }, - "params": { - "inlineDocument": 123 - }, - "serialized": { - "headers": { - "X-Amz-Target": "com.amazonaws.foo.OperationName", - "Content-Type": "application/x-amz-json-1.1" - }, - "uri": "/", - "body": "{\"inlineDocument\": 123}" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName", - "http": { - "method": "POST" - } - }, - "params": { - "inlineDocument": 1.2 - }, - "serialized": { - "headers": { - "X-Amz-Target": "com.amazonaws.foo.OperationName", - "Content-Type": "application/x-amz-json-1.1" - }, - "uri": "/", - "body": "{\"inlineDocument\": 1.2}" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName", - "http": { - "method": "POST" - } - }, - "params": { - "inlineDocument": true - }, - "serialized": { - "headers": { - "X-Amz-Target": "com.amazonaws.foo.OperationName", - "Content-Type": "application/x-amz-json-1.1" - }, - "uri": "/", - "body": "{\"inlineDocument\": true}" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName", - "http": { - "method": "POST" - } + { + "description": "Test cases for PutAndGetInlineDocuments operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "params": { - "inlineDocument": "" + "shapes": { + "PutAndGetInlineDocumentsInputOutput": { + "type": "structure", + "members": { + "inlineDocument": { + "shape": "Document" + } + } + }, + "Document": { + "type": "structure", + "members": {}, + "document": true + } }, - "serialized": { - "headers": { - "X-Amz-Target": "com.amazonaws.foo.OperationName", - "Content-Type": "application/x-amz-json-1.1" - }, - "uri": "/", - "body": "{\"inlineDocument\": \"\"}" - } - } - ] - }, - { - "description": "Serializes inline document in a JSON request.", - "metadata": { - "protocol": "json", - "jsonVersion": "1.1", - "targetPrefix": "com.amazonaws.foo" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "inlineDocument": { - "shape": "DocumentType" + "cases": [ + { + "id": "PutAndGetInlineDocumentsInput", + "given": { + "name": "PutAndGetInlineDocuments", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "PutAndGetInlineDocumentsInputOutput" + }, + "documentation": "

This example serializes an inline document as part of the payload.

" + }, + "description": "Serializes inline documents in a JSON request.", + "params": { + "inlineDocument": { + "foo": "bar" + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"inlineDocument\": {\"foo\": \"bar\"}\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.PutAndGetInlineDocuments" + }, + "requireHeaders": [ + "Content-Length" + ] + } } - } - }, - "DocumentType": { - "type": "structure", - "document": true - } + ] }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName", - "http": { - "method": "POST" - } + { + "description": "Test cases for PutWithContentEncoding operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "params": { - "inlineDocument": {"foo": "bar"} + "shapes": { + "PutWithContentEncodingInput": { + "type": "structure", + "members": { + "encoding": { + "shape": "String" + }, + "data": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } }, - "serialized": { - "headers": { - "X-Amz-Target": "com.amazonaws.foo.OperationName", - "Content-Type": "application/x-amz-json-1.1" - }, - "uri": "/", - "body": "{\"inlineDocument\": {\"foo\": \"bar\"}}" - } - } - ] - }, - { - "description": "Serializes aggregate documents in a JSON request.", - "metadata": { - "protocol": "json", - "jsonVersion": "1.1", - "targetPrefix": "com.amazonaws.foo" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "parentDocument": { - "shape": "DocumentType" + "cases": [ + { + "id": "SDKAppliedContentEncoding_awsJson1_1", + "given": { + "name": "PutWithContentEncoding", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "PutWithContentEncodingInput" + }, + "requestcompression": { + "encodings": [ + "gzip" + ] + } + }, + "description": "Compression algorithm encoding is appended to the Content-Encoding header.", + "params": { + "data": "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\n" + }, + "serialized": { + "method": "POST", + "uri": "/", + "headers": { + "Content-Encoding": "gzip" + } + } + }, + { + "id": "SDKAppendsGzipAndIgnoresHttpProvidedEncoding_awsJson1_1", + "given": { + "name": "PutWithContentEncoding", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "PutWithContentEncodingInput" + }, + "requestcompression": { + "encodings": [ + "gzip" + ] + } + }, + "description": "Compression algorithm encoding is appended to the Content-Encoding header, and the\nuser-provided content-encoding is NOT in the Content-Encoding header since HTTP binding\ntraits are ignored in the awsJson1_1 protocol.\n", + "params": { + "encoding": "custom", + "data": "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\n" + }, + "serialized": { + "method": "POST", + "uri": "/", + "headers": { + "Content-Encoding": "gzip" + } + } } - } - }, - "DocumentType": { - "type": "structure", - "document": true - } + ] }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName", - "http": { - "method": "POST" - } + { + "description": "Test cases for SimpleScalarProperties operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "params": { - "parentDocument": { - "str": "test", - "num": 123, - "float": 1.2, - "bool": true, - "null": "", - "document": {"foo": false}, - "list": ["myname", 321, 1.3, true, "", {"nested": true}, [200, ""]] - } - }, - "serialized": { - "headers": { - "X-Amz-Target": "com.amazonaws.foo.OperationName", - "Content-Type": "application/x-amz-json-1.1" - }, - "uri": "/", - "body": "{\"parentDocument\": {\"str\": \"test\", \"num\": 123, \"float\": 1.2, \"bool\": true, \"null\": \"\", \"document\": {\"foo\": false}, \"list\": [\"myname\", 321, 1.3, true, \"\", {\"nested\": true}, [200, \"\"]]}}" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName", - "http": { - "method": "POST" - } - }, - "params": { - "parentDocument": [ - "test", - 123, - 1.2, - true, - "", - {"str": "myname", "num": 321, "float": 1.3, "bool": true, "null": "", "document": {"nested": true}, "list": [200, ""]}, - ["foo", false] - ] + "shapes": { + "SimpleScalarPropertiesInputOutput": { + "type": "structure", + "members": { + "floatValue": { + "shape": "Float" + }, + "doubleValue": { + "shape": "Double" + } + } + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + } }, - "serialized": { - "headers": { - "X-Amz-Target": "com.amazonaws.foo.OperationName", - "Content-Type": "application/x-amz-json-1.1" - }, - "uri": "/", - "body": "{\"parentDocument\": [\"test\", 123, 1.2, true, \"\", {\"str\": \"myname\", \"num\": 321, \"float\": 1.3, \"bool\": true, \"null\": \"\", \"document\": {\"nested\": true}, \"list\": [200, \"\"]}, [\"foo\", false]]}" - } - } - ] - } + "cases": [ + { + "id": "AwsJson11SupportsNaNFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleScalarPropertiesInputOutput" + } + }, + "description": "Supports handling NaN float values.", + "params": { + "floatValue": "NaN", + "doubleValue": "NaN" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"floatValue\": \"NaN\",\n \"doubleValue\": \"NaN\"\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.SimpleScalarProperties" + } + } + }, + { + "id": "AwsJson11SupportsInfinityFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleScalarPropertiesInputOutput" + } + }, + "description": "Supports handling Infinity float values.", + "params": { + "floatValue": "Infinity", + "doubleValue": "Infinity" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"floatValue\": \"Infinity\",\n \"doubleValue\": \"Infinity\"\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.SimpleScalarProperties" + } + } + }, + { + "id": "AwsJson11SupportsNegativeInfinityFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleScalarPropertiesInputOutput" + } + }, + "description": "Supports handling -Infinity float values.", + "params": { + "floatValue": "-Infinity", + "doubleValue": "-Infinity" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"floatValue\": \"-Infinity\",\n \"doubleValue\": \"-Infinity\"\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.SimpleScalarProperties" + } + } + } + ] + } ] diff --git a/tests/unit/protocols/input/json_1_0.json b/tests/unit/protocols/input/json_1_0.json new file mode 100644 index 0000000000..f746c22361 --- /dev/null +++ b/tests/unit/protocols/input/json_1_0.json @@ -0,0 +1,878 @@ +[ + { + "description": "Test cases for EmptyInputAndEmptyOutput operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2020-07-14", + "jsonVersion": "1.0", + "targetPrefix": "JsonRpc10" + }, + "shapes": { + "EmptyInputAndEmptyOutputInput": { + "type": "structure", + "members": {} + } + }, + "cases": [ + { + "id": "AwsJson10EmptyInputAndEmptyOutput", + "given": { + "name": "EmptyInputAndEmptyOutput", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "EmptyInputAndEmptyOutputInput" + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response payload because the operation has an empty input and empty output structure that reuses the same shape. While this should be rare, code generators must support this.

" + }, + "description": "Clients must always send an empty object if input is modeled.", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{}", + "headers": { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.EmptyInputAndEmptyOutput" + } + } + } + ] + }, + { + "description": "Test cases for EndpointOperation operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2020-07-14", + "jsonVersion": "1.0", + "targetPrefix": "JsonRpc10" + }, + "shapes": {}, + "cases": [ + { + "id": "AwsJson10EndpointTrait", + "given": { + "name": "EndpointOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "endpoint": { + "hostPrefix": "foo." + } + }, + "description": "Operations can prepend to the given host if they define the\nendpoint trait.", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{}", + "host": "foo.example.com" + } + } + ], + "clientEndpoint": "https://example.com" + }, + { + "description": "Test cases for EndpointWithHostLabelOperation operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2020-07-14", + "jsonVersion": "1.0", + "targetPrefix": "JsonRpc10" + }, + "shapes": { + "EndpointWithHostLabelOperationInput": { + "type": "structure", + "required": [ + "label" + ], + "members": { + "label": { + "shape": "String", + "hostLabel": true + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "AwsJson10EndpointTraitWithHostLabel", + "given": { + "name": "EndpointWithHostLabelOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "EndpointWithHostLabelOperationInput" + }, + "endpoint": { + "hostPrefix": "foo.{label}." + } + }, + "description": "Operations can prepend to the given host if they define the\nendpoint trait, and can use the host label trait to define\nfurther customization based on user input.", + "params": { + "label": "bar" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\"label\": \"bar\"}", + "host": "foo.bar.example.com" + } + } + ], + "clientEndpoint": "https://example.com" + }, + { + "description": "Test cases for HostWithPathOperation operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2020-07-14", + "jsonVersion": "1.0", + "targetPrefix": "JsonRpc10" + }, + "shapes": {}, + "cases": [ + { + "id": "AwsJson10HostWithPath", + "given": { + "name": "HostWithPathOperation", + "http": { + "method": "POST", + "requestUri": "/" + } + }, + "description": "Custom endpoints supplied by users can have paths", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/custom/", + "body": "{}", + "host": "example.com/custom" + } + } + ], + "clientEndpoint": "https://example.com/custom" + }, + { + "description": "Test cases for JsonUnions operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2020-07-14", + "jsonVersion": "1.0", + "targetPrefix": "JsonRpc10" + }, + "shapes": { + "JsonUnionsInput": { + "type": "structure", + "members": { + "contents": { + "shape": "MyUnion" + } + } + }, + "MyUnion": { + "type": "structure", + "members": { + "stringValue": { + "shape": "String" + }, + "booleanValue": { + "shape": "Boolean" + }, + "numberValue": { + "shape": "Integer" + }, + "blobValue": { + "shape": "Blob" + }, + "timestampValue": { + "shape": "Timestamp" + }, + "enumValue": { + "shape": "FooEnum" + }, + "intEnumValue": { + "shape": "IntegerEnum" + }, + "listValue": { + "shape": "StringList" + }, + "mapValue": { + "shape": "StringMap" + }, + "structureValue": { + "shape": "GreetingStruct" + } + }, + "documentation": "

A union with a representative set of types for members.

", + "union": true + }, + "String": { + "type": "string" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + }, + "Blob": { + "type": "blob" + }, + "Timestamp": { + "type": "timestamp" + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "String" + } + }, + "GreetingStruct": { + "type": "structure", + "members": { + "hi": { + "shape": "String" + } + } + } + }, + "cases": [ + { + "id": "AwsJson10SerializeStringUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "JsonUnionsInput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes a string union value", + "params": { + "contents": { + "stringValue": "foo" + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"contents\": {\n \"stringValue\": \"foo\"\n }\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.JsonUnions" + } + } + }, + { + "id": "AwsJson10SerializeBooleanUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "JsonUnionsInput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes a boolean union value", + "params": { + "contents": { + "booleanValue": true + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"contents\": {\n \"booleanValue\": true\n }\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.JsonUnions" + } + } + }, + { + "id": "AwsJson10SerializeNumberUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "JsonUnionsInput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes a number union value", + "params": { + "contents": { + "numberValue": 1 + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"contents\": {\n \"numberValue\": 1\n }\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.JsonUnions" + } + } + }, + { + "id": "AwsJson10SerializeBlobUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "JsonUnionsInput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes a blob union value", + "params": { + "contents": { + "blobValue": "foo" + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"contents\": {\n \"blobValue\": \"Zm9v\"\n }\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.JsonUnions" + } + } + }, + { + "id": "AwsJson10SerializeTimestampUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "JsonUnionsInput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes a timestamp union value", + "params": { + "contents": { + "timestampValue": 1398796238 + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"contents\": {\n \"timestampValue\": 1398796238\n }\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.JsonUnions" + } + } + }, + { + "id": "AwsJson10SerializeEnumUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "JsonUnionsInput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes an enum union value", + "params": { + "contents": { + "enumValue": "Foo" + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"contents\": {\n \"enumValue\": \"Foo\"\n }\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.JsonUnions" + } + } + }, + { + "id": "AwsJson10SerializeIntEnumUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "JsonUnionsInput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes an intEnum union value", + "params": { + "contents": { + "intEnumValue": 1 + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"contents\": {\n \"intEnumValue\": 1\n }\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.JsonUnions" + } + } + }, + { + "id": "AwsJson10SerializeListUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "JsonUnionsInput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes a list union value", + "params": { + "contents": { + "listValue": [ + "foo", + "bar" + ] + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"contents\": {\n \"listValue\": [\"foo\", \"bar\"]\n }\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.JsonUnions" + } + } + }, + { + "id": "AwsJson10SerializeMapUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "JsonUnionsInput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes a map union value", + "params": { + "contents": { + "mapValue": { + "foo": "bar", + "spam": "eggs" + } + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"contents\": {\n \"mapValue\": {\n \"foo\": \"bar\",\n \"spam\": \"eggs\"\n }\n }\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.JsonUnions" + } + } + }, + { + "id": "AwsJson10SerializeStructureUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "JsonUnionsInput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes a structure union value", + "params": { + "contents": { + "structureValue": { + "hi": "hello" + } + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"contents\": {\n \"structureValue\": {\n \"hi\": \"hello\"\n }\n }\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.JsonUnions" + } + } + } + ] + }, + { + "description": "Test cases for NoInputAndNoOutput operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2020-07-14", + "jsonVersion": "1.0", + "targetPrefix": "JsonRpc10" + }, + "shapes": {}, + "cases": [ + { + "id": "AwsJson10MustAlwaysSendEmptyJsonPayload", + "given": { + "name": "NoInputAndNoOutput", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input or output. While this should be rare, code generators must support this.

" + }, + "description": "Clients must always send an empty JSON object payload for\noperations with no input (that is, `{}`). While AWS service\nimplementations support requests with no payload or requests\nthat send `{}`, always sending `{}` from the client is\npreferred for forward compatibility in case input is ever\nadded to an operation.", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{}", + "headers": { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.NoInputAndNoOutput" + } + } + } + ] + }, + { + "description": "Test cases for NoInputAndOutput operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2020-07-14", + "jsonVersion": "1.0", + "targetPrefix": "JsonRpc10" + }, + "shapes": {}, + "cases": [ + { + "id": "AwsJson10NoInputAndOutput", + "given": { + "name": "NoInputAndOutput", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input and the output is empty. While this should be rare, code generators must support this.

" + }, + "description": "A client should always send and empty JSON object payload.", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{}", + "headers": { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.NoInputAndOutput" + } + } + } + ] + }, + { + "description": "Test cases for PutWithContentEncoding operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2020-07-14", + "jsonVersion": "1.0", + "targetPrefix": "JsonRpc10" + }, + "shapes": { + "PutWithContentEncodingInput": { + "type": "structure", + "members": { + "encoding": { + "shape": "String" + }, + "data": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "SDKAppliedContentEncoding_awsJson1_0", + "given": { + "name": "PutWithContentEncoding", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "PutWithContentEncodingInput" + }, + "requestcompression": { + "encodings": [ + "gzip" + ] + } + }, + "description": "Compression algorithm encoding is appended to the Content-Encoding header.", + "params": { + "data": "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\n" + }, + "serialized": { + "method": "POST", + "uri": "/", + "headers": { + "Content-Encoding": "gzip" + } + } + }, + { + "id": "SDKAppendsGzipAndIgnoresHttpProvidedEncoding_awsJson1_0", + "given": { + "name": "PutWithContentEncoding", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "PutWithContentEncodingInput" + }, + "requestcompression": { + "encodings": [ + "gzip" + ] + } + }, + "description": "Compression algorithm encoding is appended to the Content-Encoding header, and the\nuser-provided content-encoding is NOT in the Content-Encoding header since HTTP binding\ntraits are ignored in the awsJson1_0 protocol.\n", + "params": { + "encoding": "custom", + "data": "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\n" + }, + "serialized": { + "method": "POST", + "uri": "/", + "headers": { + "Content-Encoding": "gzip" + } + } + } + ] + }, + { + "description": "Test cases for SimpleScalarProperties operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2020-07-14", + "jsonVersion": "1.0", + "targetPrefix": "JsonRpc10" + }, + "shapes": { + "SimpleScalarPropertiesInput": { + "type": "structure", + "members": { + "floatValue": { + "shape": "Float" + }, + "doubleValue": { + "shape": "Double" + } + } + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + } + }, + "cases": [ + { + "id": "AwsJson10SupportsNaNFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleScalarPropertiesInput" + } + }, + "description": "Supports handling NaN float values.", + "params": { + "floatValue": "NaN", + "doubleValue": "NaN" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"floatValue\": \"NaN\",\n \"doubleValue\": \"NaN\"\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.SimpleScalarProperties" + } + } + }, + { + "id": "AwsJson10SupportsInfinityFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleScalarPropertiesInput" + } + }, + "description": "Supports handling Infinity float values.", + "params": { + "floatValue": "Infinity", + "doubleValue": "Infinity" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"floatValue\": \"Infinity\",\n \"doubleValue\": \"Infinity\"\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.SimpleScalarProperties" + } + } + }, + { + "id": "AwsJson10SupportsNegativeInfinityFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleScalarPropertiesInput" + } + }, + "description": "Supports handling -Infinity float values.", + "params": { + "floatValue": "-Infinity", + "doubleValue": "-Infinity" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "{\n \"floatValue\": \"-Infinity\",\n \"doubleValue\": \"-Infinity\"\n}", + "headers": { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.SimpleScalarProperties" + } + } + } + ] + } +] diff --git a/tests/unit/protocols/input/query.json b/tests/unit/protocols/input/query.json index ac93e9eef6..58435cca0c 100644 --- a/tests/unit/protocols/input/query.json +++ b/tests/unit/protocols/input/query.json @@ -1,1002 +1,1611 @@ [ - { - "description": "Scalar members", - "metadata": { - "protocol": "query", - "apiVersion": "2014-01-01" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "Foo": { - "shape": "StringType" - }, - "Bar": { - "shape": "StringType" - }, - "Baz": { - "shape": "BooleanType" - } - } - }, - "StringType": { - "type": "string" - }, - "BooleanType": { - "type": "boolean" - } - }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "Foo": "val1", - "Bar": "val2" - }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&Foo=val1&Bar=val2" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "Baz": true - }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&Baz=true" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "Baz": false - }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&Baz=false" - } - } - ] - }, - { - "description": "Nested structure members", - "metadata": { - "protocol": "query", - "apiVersion": "2014-01-01" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "StructArg": { - "shape": "StructType" - } - } - }, - "StructType": { - "type": "structure", - "members": { - "ScalarArg": { - "shape": "StringType" - } - } - }, - "StringType": { - "type": "string" - } - }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "StructArg": { - "ScalarArg": "foo" - } - }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&StructArg.ScalarArg=foo" - } - } - ] - }, - { - "description": "List types", - "metadata": { - "protocol": "query", - "apiVersion": "2014-01-01" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "ListArg": { - "shape": "ListType" - } - } - }, - "ListType": { - "type": "list", - "member": { - "shape": "Strings" - } - }, - "Strings": { - "type": "string" - } - }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "ListArg": [ - "foo", - "bar", - "baz" - ] - }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&ListArg.member.1=foo&ListArg.member.2=bar&ListArg.member.3=baz" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "ListArg": [] - }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&ListArg=" - } - } - ] - }, - { - "description": "Flattened list", - "metadata": { - "protocol": "query", - "apiVersion": "2014-01-01" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "ScalarArg": { - "shape": "StringType" - }, - "ListArg": { - "shape": "ListType" - }, - "NamedListArg": { - "shape": "NamedListType" - } - } - }, - "ListType": { - "type": "list", - "member": { - "shape": "StringType" - }, - "flattened": true - }, - "NamedListType": { - "type": "list", - "member": { - "shape": "StringType", - "locationName": "Foo" - }, - "flattened": true - }, - "StringType": { - "type": "string" - } - }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "ScalarArg": "foo", - "ListArg": [ - "a", - "b", - "c" - ] - }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&ScalarArg=foo&ListArg.1=a&ListArg.2=b&ListArg.3=c" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "NamedListArg": [ - "a" - ] - }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&Foo.1=a" - } - } - ] - }, - { - "description": "Serialize flattened map type", - "metadata": { - "protocol": "query", - "apiVersion": "2014-01-01" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "MapArg": { - "shape": "StringMap" - } - } - }, - "StringMap": { - "type": "map", - "key": { - "shape": "StringType" - }, - "value": { - "shape": "StringType" - }, - "flattened": true - }, - "StringType": { - "type": "string" - } - }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "MapArg": { - "key1": "val1", - "key2": "val2" - } - }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&MapArg.1.key=key1&MapArg.1.value=val1&MapArg.2.key=key2&MapArg.2.value=val2" - } - } - ] - }, - { - "description": "Non flattened list with LocationName", - "metadata": { - "protocol": "query", - "apiVersion": "2014-01-01" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "ListArg": { - "shape": "ListType" - } - } - }, - "ListType": { - "type": "list", - "member": { - "shape": "StringType", - "locationName": "item" - } - }, - "StringType": { - "type": "string" - } - }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" + { + "description": "Test cases for EmptyInputAndEmptyOutput operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" }, - "params": { - "ListArg": [ - "a", - "b", - "c" - ] + "shapes": { + "EmptyInputAndEmptyOutputInput": { + "type": "structure", + "members": {} + } }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&ListArg.item.1=a&ListArg.item.2=b&ListArg.item.3=c" - } - } - ] - }, - { - "description": "Flattened list with LocationName", - "metadata": { - "protocol": "query", - "apiVersion": "2014-01-01" + "cases": [ + { + "id": "QueryEmptyInputAndEmptyOutput", + "given": { + "name": "EmptyInputAndEmptyOutput", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "EmptyInputAndEmptyOutputInput" + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response members.

While this should be rare, code generators must support this.

" + }, + "description": "Empty input serializes no extra query params", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=EmptyInputAndEmptyOutput&Version=2020-01-08", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "ScalarArg": { - "shape": "StringType" - }, - "ListArg": { - "shape": "ListType" - } - } - }, - "ListType": { - "type": "list", - "member": { - "shape": "StringType", - "locationName": "ListArgLocation" + { + "description": "Test cases for EndpointOperation operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" }, - "flattened": true - }, - "StringType": { - "type": "string" - } + "shapes": {}, + "cases": [ + { + "id": "AwsQueryEndpointTrait", + "given": { + "name": "EndpointOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "endpoint": { + "hostPrefix": "foo." + } + }, + "description": "Operations can prepend to the given host if they define the\nendpoint trait.", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=EndpointOperation&Version=2020-01-08", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "host": "foo.example.com" + } + } + ], + "clientEndpoint": "https://example.com" }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" + { + "description": "Test cases for EndpointWithHostLabelOperation operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" }, - "params": { - "ScalarArg": "foo", - "ListArg": [ - "a", - "b", - "c" - ] + "shapes": { + "HostLabelInput": { + "type": "structure", + "required": [ + "label" + ], + "members": { + "label": { + "shape": "String", + "hostLabel": true + } + } + }, + "String": { + "type": "string" + } }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&ScalarArg=foo&ListArgLocation.1=a&ListArgLocation.2=b&ListArgLocation.3=c" - } - } - ] - }, - { - "description": "Serialize map type", - "metadata": { - "protocol": "query", - "apiVersion": "2014-01-01" + "cases": [ + { + "id": "AwsQueryEndpointTraitWithHostLabel", + "given": { + "name": "EndpointWithHostLabelOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "HostLabelInput" + }, + "endpoint": { + "hostPrefix": "foo.{label}." + } + }, + "description": "Operations can prepend to the given host if they define the\nendpoint trait, and can use the host label trait to define\nfurther customization based on user input.", + "params": { + "label": "bar" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=EndpointWithHostLabelOperation&Version=2020-01-08&label=bar", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "host": "foo.bar.example.com" + } + } + ], + "clientEndpoint": "https://example.com" }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "MapArg": { - "shape": "StringMap" - } - } - }, - "StringMap": { - "type": "map", - "key": { - "shape": "StringType" + { + "description": "Test cases for HostWithPathOperation operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" }, - "value": { - "shape": "StringType" - } - }, - "StringType": { - "type": "string" - } + "shapes": {}, + "cases": [ + { + "id": "QueryHostWithPath", + "given": { + "name": "HostWithPathOperation", + "http": { + "method": "POST", + "requestUri": "/" + } + }, + "description": "Custom endpoints supplied by users can have paths", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/custom/", + "body": "Action=HostWithPathOperation&Version=2020-01-08", + "host": "example.com/custom" + } + } + ], + "clientEndpoint": "https://example.com/custom" }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" + { + "description": "Test cases for NestedStructures operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" }, - "params": { - "MapArg": { - "key1": "val1", - "key2": "val2" - } + "shapes": { + "NestedStructuresInput": { + "type": "structure", + "members": { + "Nested": { + "shape": "StructArg" + } + } + }, + "StructArg": { + "type": "structure", + "members": { + "StringArg": { + "shape": "String" + }, + "OtherArg": { + "shape": "Boolean" + }, + "RecursiveArg": { + "shape": "StructArg" + } + } + }, + "String": { + "type": "string" + }, + "Boolean": { + "type": "boolean", + "box": true + } }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&MapArg.entry.1.key=key1&MapArg.entry.1.value=val1&MapArg.entry.2.key=key2&MapArg.entry.2.value=val2" - } - } - ] - }, - { - "description": "Serialize map type with locationName", - "metadata": { - "protocol": "query", - "apiVersion": "2014-01-01" + "cases": [ + { + "id": "NestedStructures", + "given": { + "name": "NestedStructures", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "NestedStructuresInput" + }, + "documentation": "

This test serializes nested and recursive structure members.

" + }, + "description": "Serializes nested structures using dots", + "params": { + "Nested": { + "StringArg": "foo", + "OtherArg": true, + "RecursiveArg": { + "StringArg": "baz" + } + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=NestedStructures&Version=2020-01-08&Nested.StringArg=foo&Nested.OtherArg=true&Nested.RecursiveArg.StringArg=baz", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "MapArg": { - "shape": "StringMap" - } - } - }, - "StringMap": { - "type": "map", - "key": { - "shape": "StringType", - "locationName": "TheKey" + { + "description": "Test cases for NoInputAndNoOutput operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" }, - "value": { - "shape": "StringType", - "locationName": "TheValue" - } - }, - "StringType": { - "type": "string" - } + "shapes": {}, + "cases": [ + { + "id": "QueryNoInputAndNoOutput", + "given": { + "name": "NoInputAndNoOutput", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input or output.

While this should be rare, code generators must support this.

" + }, + "description": "No input serializes no additional query params", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=NoInputAndNoOutput&Version=2020-01-08", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + } + } + ] }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" + { + "description": "Test cases for NoInputAndOutput operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" }, - "params": { - "MapArg": { - "key1": "val1", - "key2": "val2" - } + "shapes": { + "NoInputAndOutputInput": { + "type": "structure", + "members": {} + } }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&MapArg.entry.1.TheKey=key1&MapArg.entry.1.TheValue=val1&MapArg.entry.2.TheKey=key2&MapArg.entry.2.TheValue=val2" - } - } - ] - }, - { - "description": "Base64 encoded Blobs", - "metadata": { - "protocol": "query", - "apiVersion": "2014-01-01" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "BlobArg": { - "shape": "BlobType" - } - } - }, - "BlobType": { - "type": "blob" - } + "cases": [ + { + "id": "QueryNoInputAndOutput", + "given": { + "name": "NoInputAndOutput", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "NoInputAndOutputInput" + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request payload or response members.

While this should be rare, code generators must support this.

" + }, + "description": "No input serializes no payload", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=NoInputAndOutput&Version=2020-01-08", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + } + } + ] }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" + { + "description": "Test cases for PutWithContentEncoding operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" }, - "params": { - "BlobArg": "foo" + "shapes": { + "PutWithContentEncodingInput": { + "type": "structure", + "members": { + "encoding": { + "shape": "String" + }, + "data": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&BlobArg=Zm9v" - } - } - ] - }, - { - "description": "Timestamp values", - "metadata": { - "protocol": "query", - "apiVersion": "2014-01-01" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "TimeArg": { - "shape": "TimestampType" - }, - "TimeCustom": { - "timestampFormat": "unixTimestamp", - "shape": "TimestampType" - }, - "TimeFormat": { - "shape": "TimestampFormatType" - } - } - }, - "TimestampFormatType": { - "timestampFormat": "unixTimestamp", - "type": "timestamp" - }, - "TimestampType": { - "type": "timestamp" - } + "cases": [ + { + "id": "SDKAppliedContentEncoding_awsQuery", + "given": { + "name": "PutWithContentEncoding", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "PutWithContentEncodingInput" + }, + "requestcompression": { + "encodings": [ + "gzip" + ] + } + }, + "description": "Compression algorithm encoding is appended to the Content-Encoding header.", + "params": { + "data": "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\n" + }, + "serialized": { + "method": "POST", + "uri": "/", + "headers": { + "Content-Encoding": "gzip" + } + } + }, + { + "id": "SDKAppendsGzipAndIgnoresHttpProvidedEncoding_awsQuery", + "given": { + "name": "PutWithContentEncoding", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "PutWithContentEncodingInput" + }, + "requestcompression": { + "encodings": [ + "gzip" + ] + } + }, + "description": "Compression algorithm encoding is appended to the Content-Encoding header, and the\nuser-provided content-encoding is NOT in the Content-Encoding header since HTTP binding\ntraits are ignored in the awsQuery protocol.\n", + "params": { + "encoding": "custom", + "data": "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\n" + }, + "serialized": { + "method": "POST", + "uri": "/", + "headers": { + "Content-Encoding": "gzip" + } + } + } + ] }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" + { + "description": "Test cases for QueryIdempotencyTokenAutoFill operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" }, - "params": { - "TimeArg": 1422172800, - "TimeCustom": 1422172800, - "TimeFormat": 1422172800 - }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&TimeArg=2015-01-25T08%3A00%3A00Z&TimeCustom=1422172800&TimeFormat=1422172800" - } - } - ] - }, - { - "description": "Recursive shapes", - "metadata": { - "protocol": "query", - "apiVersion": "2014-01-01" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "RecursiveStruct": { - "shape": "RecursiveStructType" - } - } - }, - "RecursiveStructType": { - "type": "structure", - "members": { - "NoRecurse": { - "shape": "StringType" - }, - "RecursiveStruct": { - "shape": "RecursiveStructType" - }, - "RecursiveList": { - "shape": "RecursiveListType" - }, - "RecursiveMap": { - "shape": "RecursiveMapType" - } - } - }, - "RecursiveListType": { - "type": "list", - "member": { - "shape": "RecursiveStructType" - } - }, - "RecursiveMapType": { - "type": "map", - "key": { - "shape": "StringType" + "shapes": { + "QueryIdempotencyTokenAutoFillInput": { + "type": "structure", + "members": { + "token": { + "shape": "String", + "idempotencyToken": true + } + } + }, + "String": { + "type": "string" + } }, - "value": { - "shape": "RecursiveStructType" - } - }, - "StringType": { - "type": "string" - } + "cases": [ + { + "id": "QueryProtocolIdempotencyTokenAutoFill", + "given": { + "name": "QueryIdempotencyTokenAutoFill", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "QueryIdempotencyTokenAutoFillInput" + }, + "documentation": "

Automatically adds idempotency tokens.

" + }, + "description": "Automatically adds idempotency token when not set", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=QueryIdempotencyTokenAutoFill&Version=2020-01-08&token=00000000-0000-4000-8000-000000000000", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "QueryProtocolIdempotencyTokenAutoFillIsSet", + "given": { + "name": "QueryIdempotencyTokenAutoFill", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "QueryIdempotencyTokenAutoFillInput" + }, + "documentation": "

Automatically adds idempotency tokens.

" + }, + "description": "Uses the given idempotency token as-is", + "params": { + "token": "00000000-0000-4000-8000-000000000123" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=QueryIdempotencyTokenAutoFill&Version=2020-01-08&token=00000000-0000-4000-8000-000000000123", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + } + ] }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "RecursiveStruct": { - "NoRecurse": "foo" - } - }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&RecursiveStruct.NoRecurse=foo" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" + { + "description": "Test cases for QueryLists operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" }, - "params": { - "RecursiveStruct": { - "RecursiveStruct": { - "NoRecurse": "foo" + "shapes": { + "QueryListsInput": { + "type": "structure", + "members": { + "ListArg": { + "shape": "StringList" + }, + "ComplexListArg": { + "shape": "GreetingList" + }, + "FlattenedListArg": { + "shape": "StringList", + "flattened": true + }, + "ListArgWithXmlNameMember": { + "shape": "ListWithXmlName" + }, + "FlattenedListArgWithXmlName": { + "shape": "ListWithXmlName", + "flattened": true, + "locationName": "Hi" + }, + "NestedWithList": { + "shape": "NestedStructWithList" + } + } + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "GreetingList": { + "type": "list", + "member": { + "shape": "GreetingStruct" + } + }, + "ListWithXmlName": { + "type": "list", + "member": { + "shape": "String", + "locationName": "item" + } + }, + "NestedStructWithList": { + "type": "structure", + "members": { + "ListArg": { + "shape": "StringList" + } + } + }, + "String": { + "type": "string" + }, + "GreetingStruct": { + "type": "structure", + "members": { + "hi": { + "shape": "String" + } + } } - } }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&RecursiveStruct.RecursiveStruct.NoRecurse=foo" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "RecursiveStruct": { - "RecursiveStruct": { - "RecursiveStruct": { - "RecursiveStruct": { - "NoRecurse": "foo" - } - } + "cases": [ + { + "id": "QueryLists", + "given": { + "name": "QueryLists", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "QueryListsInput" + }, + "documentation": "

This test serializes simple and complex lists.

" + }, + "description": "Serializes query lists", + "params": { + "ListArg": [ + "foo", + "bar", + "baz" + ], + "ComplexListArg": [ + { + "hi": "hello" + }, + { + "hi": "hola" + } + ] + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=QueryLists&Version=2020-01-08&ListArg.member.1=foo&ListArg.member.2=bar&ListArg.member.3=baz&ComplexListArg.member.1.hi=hello&ComplexListArg.member.2.hi=hola", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + } + }, + { + "id": "EmptyQueryLists", + "given": { + "name": "QueryLists", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "QueryListsInput" + }, + "documentation": "

This test serializes simple and complex lists.

" + }, + "description": "Serializes empty query lists", + "params": { + "ListArg": [] + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=QueryLists&Version=2020-01-08&ListArg=", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + } + }, + { + "id": "FlattenedQueryLists", + "given": { + "name": "QueryLists", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "QueryListsInput" + }, + "documentation": "

This test serializes simple and complex lists.

" + }, + "description": "Flattens query lists by repeating the member name and removing the member element", + "params": { + "FlattenedListArg": [ + "A", + "B" + ] + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=QueryLists&Version=2020-01-08&FlattenedListArg.1=A&FlattenedListArg.2=B", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + } + }, + { + "id": "QueryListArgWithXmlNameMember", + "given": { + "name": "QueryLists", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "QueryListsInput" + }, + "documentation": "

This test serializes simple and complex lists.

" + }, + "description": "Changes the member of lists using xmlName trait", + "params": { + "ListArgWithXmlNameMember": [ + "A", + "B" + ] + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=QueryLists&Version=2020-01-08&ListArgWithXmlNameMember.item.1=A&ListArgWithXmlNameMember.item.2=B", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + } + }, + { + "id": "QueryFlattenedListArgWithXmlName", + "given": { + "name": "QueryLists", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "QueryListsInput" + }, + "documentation": "

This test serializes simple and complex lists.

" + }, + "description": "Changes the name of flattened lists using xmlName trait on the structure member", + "params": { + "FlattenedListArgWithXmlName": [ + "A", + "B" + ] + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=QueryLists&Version=2020-01-08&Hi.1=A&Hi.2=B", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + } + }, + { + "id": "QueryNestedStructWithList", + "given": { + "name": "QueryLists", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "QueryListsInput" + }, + "documentation": "

This test serializes simple and complex lists.

" + }, + "description": "Nested structure with a list member", + "params": { + "NestedWithList": { + "ListArg": [ + "A", + "B" + ] + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=QueryLists&Version=2020-01-08&NestedWithList.ListArg.member.1=A&NestedWithList.ListArg.member.2=B", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + } } - } - }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&RecursiveStruct.RecursiveStruct.RecursiveStruct.RecursiveStruct.NoRecurse=foo" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "RecursiveStruct": { - "RecursiveList": [ - { - "NoRecurse": "foo" - }, - { - "NoRecurse": "bar" - } - ] - } - }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&RecursiveStruct.RecursiveList.member.1.NoRecurse=foo&RecursiveStruct.RecursiveList.member.2.NoRecurse=bar" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "RecursiveStruct": { - "RecursiveList": [ - { - "NoRecurse": "foo" - }, - { - "RecursiveStruct": { - "NoRecurse": "bar" - } - } - ] - } - }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&RecursiveStruct.RecursiveList.member.1.NoRecurse=foo&RecursiveStruct.RecursiveList.member.2.RecursiveStruct.NoRecurse=bar" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "name": "OperationName" + ] + }, + { + "description": "Test cases for QueryMaps operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" }, - "params": { - "RecursiveStruct": { - "RecursiveMap": { - "foo": { - "NoRecurse": "foo" - }, - "bar": { - "NoRecurse": "bar" - } + "shapes": { + "QueryMapsInput": { + "type": "structure", + "members": { + "MapArg": { + "shape": "StringMap" + }, + "RenamedMapArg": { + "shape": "StringMap", + "locationName": "Foo" + }, + "ComplexMapArg": { + "shape": "ComplexMap" + }, + "MapWithXmlMemberName": { + "shape": "MapWithXmlName" + }, + "FlattenedMap": { + "shape": "StringMap", + "flattened": true + }, + "FlattenedMapWithXmlName": { + "shape": "MapWithXmlName", + "flattened": true, + "locationName": "Hi" + }, + "MapOfLists": { + "shape": "MapOfLists" + }, + "NestedStructWithMap": { + "shape": "NestedStructWithMap" + } + } + }, + "StringMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "String" + } + }, + "ComplexMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "GreetingStruct" + } + }, + "MapWithXmlName": { + "type": "map", + "key": { + "shape": "String", + "locationName": "K" + }, + "value": { + "shape": "String", + "locationName": "V" + } + }, + "MapOfLists": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "StringList" + } + }, + "NestedStructWithMap": { + "type": "structure", + "members": { + "MapArg": { + "shape": "StringMap" + } + } + }, + "String": { + "type": "string" + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "GreetingStruct": { + "type": "structure", + "members": { + "hi": { + "shape": "String" + } + } } - } }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&RecursiveStruct.RecursiveMap.entry.1.key=foo&RecursiveStruct.RecursiveMap.entry.1.value.NoRecurse=foo&RecursiveStruct.RecursiveMap.entry.2.key=bar&RecursiveStruct.RecursiveMap.entry.2.value.NoRecurse=bar" - } - } - ] - }, - { - "description": "Idempotency token auto fill", - "metadata": { - "protocol": "query", - "apiVersion": "2014-01-01" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "Token": { - "shape": "StringType", - "idempotencyToken": true - } - } - }, - "StringType": { - "type": "string" - } + "cases": [ + { + "id": "QuerySimpleQueryMaps", + "given": { + "name": "QueryMaps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "QueryMapsInput" + }, + "documentation": "

This test serializes simple and complex maps.

" + }, + "description": "Serializes query maps", + "params": { + "MapArg": { + "bar": "Bar", + "foo": "Foo" + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=QueryMaps&Version=2020-01-08&MapArg.entry.1.key=bar&MapArg.entry.1.value=Bar&MapArg.entry.2.key=foo&MapArg.entry.2.value=Foo", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + } + }, + { + "id": "QuerySimpleQueryMapsWithXmlName", + "given": { + "name": "QueryMaps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "QueryMapsInput" + }, + "documentation": "

This test serializes simple and complex maps.

" + }, + "description": "Serializes query maps and uses xmlName", + "params": { + "RenamedMapArg": { + "foo": "Foo" + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=QueryMaps&Version=2020-01-08&Foo.entry.1.key=foo&Foo.entry.1.value=Foo", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + } + }, + { + "id": "QueryComplexQueryMaps", + "given": { + "name": "QueryMaps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "QueryMapsInput" + }, + "documentation": "

This test serializes simple and complex maps.

" + }, + "description": "Serializes complex query maps", + "params": { + "ComplexMapArg": { + "bar": { + "hi": "Bar" + }, + "foo": { + "hi": "Foo" + } + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=QueryMaps&Version=2020-01-08&ComplexMapArg.entry.1.key=bar&ComplexMapArg.entry.1.value.hi=Bar&ComplexMapArg.entry.2.key=foo&ComplexMapArg.entry.2.value.hi=Foo", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + } + }, + { + "id": "QueryEmptyQueryMaps", + "given": { + "name": "QueryMaps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "QueryMapsInput" + }, + "documentation": "

This test serializes simple and complex maps.

" + }, + "description": "Does not serialize empty query maps", + "params": { + "MapArg": {} + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=QueryMaps&Version=2020-01-08", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + } + }, + { + "id": "QueryQueryMapWithMemberXmlName", + "given": { + "name": "QueryMaps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "QueryMapsInput" + }, + "documentation": "

This test serializes simple and complex maps.

" + }, + "description": "Serializes query maps where the member has an xmlName trait", + "params": { + "MapWithXmlMemberName": { + "bar": "Bar", + "foo": "Foo" + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=QueryMaps&Version=2020-01-08&MapWithXmlMemberName.entry.1.K=bar&MapWithXmlMemberName.entry.1.V=Bar&MapWithXmlMemberName.entry.2.K=foo&MapWithXmlMemberName.entry.2.V=Foo", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + } + }, + { + "id": "QueryFlattenedQueryMaps", + "given": { + "name": "QueryMaps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "QueryMapsInput" + }, + "documentation": "

This test serializes simple and complex maps.

" + }, + "description": "Serializes flattened query maps", + "params": { + "FlattenedMap": { + "bar": "Bar", + "foo": "Foo" + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=QueryMaps&Version=2020-01-08&FlattenedMap.1.key=bar&FlattenedMap.1.value=Bar&FlattenedMap.2.key=foo&FlattenedMap.2.value=Foo", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + } + }, + { + "id": "QueryFlattenedQueryMapsWithXmlName", + "given": { + "name": "QueryMaps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "QueryMapsInput" + }, + "documentation": "

This test serializes simple and complex maps.

" + }, + "description": "Serializes flattened query maps that use an xmlName", + "params": { + "FlattenedMapWithXmlName": { + "bar": "Bar", + "foo": "Foo" + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=QueryMaps&Version=2020-01-08&Hi.1.K=bar&Hi.1.V=Bar&Hi.2.K=foo&Hi.2.V=Foo", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + } + }, + { + "id": "QueryQueryMapOfLists", + "given": { + "name": "QueryMaps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "QueryMapsInput" + }, + "documentation": "

This test serializes simple and complex maps.

" + }, + "description": "Serializes query map of lists", + "params": { + "MapOfLists": { + "bar": [ + "C", + "D" + ], + "foo": [ + "A", + "B" + ] + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=QueryMaps&Version=2020-01-08&MapOfLists.entry.1.key=bar&MapOfLists.entry.1.value.member.1=C&MapOfLists.entry.1.value.member.2=D&MapOfLists.entry.2.key=foo&MapOfLists.entry.2.value.member.1=A&MapOfLists.entry.2.value.member.2=B", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + } + }, + { + "id": "QueryNestedStructWithMap", + "given": { + "name": "QueryMaps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "QueryMapsInput" + }, + "documentation": "

This test serializes simple and complex maps.

" + }, + "description": "Serializes nested struct with map member", + "params": { + "NestedStructWithMap": { + "MapArg": { + "bar": "Bar", + "foo": "Foo" + } + } + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=QueryMaps&Version=2020-01-08&NestedStructWithMap.MapArg.entry.1.key=bar&NestedStructWithMap.MapArg.entry.1.value=Bar&NestedStructWithMap.MapArg.entry.2.key=foo&NestedStructWithMap.MapArg.entry.2.value=Foo", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + } + } + ] }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "http": { - "method": "POST" - }, - "name": "OperationName" - }, - "params": { - "Token": "abc123" + { + "description": "Test cases for QueryTimestamps operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&Token=abc123" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "http": { - "method": "POST" - }, - "name": "OperationName" - }, - "params": { + "shapes": { + "QueryTimestampsInput": { + "type": "structure", + "members": { + "normalFormat": { + "shape": "Timestamp" + }, + "epochMember": { + "shape": "SyntheticTimestamp_epoch_seconds" + }, + "epochTarget": { + "shape": "EpochSeconds" + } + } + }, + "Timestamp": { + "type": "timestamp" + }, + "SyntheticTimestamp_epoch_seconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "EpochSeconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + } }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=OperationName&Version=2014-01-01&Token=00000000-0000-4000-8000-000000000000" - } - } - ] - }, - { - "description": "Endpoint host trait", - "metadata": { - "protocol": "query", - "apiVersion": "2014-01-01" - }, - "clientEndpoint": "https://service.region.amazonaws.com", - "shapes": { - "StaticInputShape": { - "type": "structure", - "members": { - "Name": { - "shape": "StringType" - } - } - }, - "MemberRefInputShape": { - "type": "structure", - "members": { - "Name": { - "shape": "StringType", - "hostLabel": true - } - } - }, - "StringType": { - "type": "string" - } + "cases": [ + { + "id": "QueryTimestampsInput", + "given": { + "name": "QueryTimestamps", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "QueryTimestampsInput" + }, + "documentation": "

This test serializes timestamps.

  1. Timestamps are serialized as RFC 3339 date-time values by default.
  2. A timestampFormat trait on a member changes the format.
  3. A timestampFormat trait on the shape targeted by the member changes the format.
" + }, + "description": "Serializes timestamps", + "params": { + "normalFormat": 1422172800, + "epochMember": 1422172800, + "epochTarget": 1422172800 + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=QueryTimestamps&Version=2020-01-08&normalFormat=2015-01-25T08%3A00%3A00Z&epochMember=1422172800&epochTarget=1422172800", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + } + ] }, - "cases": [ - { - "given": { - "name": "StaticOp", - "input": { - "shape": "StaticInputShape" - }, - "http": { - "method": "POST" - }, - "endpoint":{ - "hostPrefix": "data-" - } + { + "description": "Test cases for SimpleInputParams operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" }, - "params": { - "Name": "myname" - }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=StaticOp&Version=2014-01-01&Name=myname", - "host": "data-service.region.amazonaws.com" - } - }, - { - "given": { - "name": "MemberRefOp", - "input": { - "shape": "MemberRefInputShape" - }, - "http": { - "method": "POST" - }, - "endpoint":{ - "hostPrefix": "foo-{Name}." - } - }, - "params": { - "Name": "myname" + "shapes": { + "SimpleInputParamsInput": { + "type": "structure", + "members": { + "Foo": { + "shape": "String" + }, + "Bar": { + "shape": "String" + }, + "Baz": { + "shape": "Boolean" + }, + "Bam": { + "shape": "Integer" + }, + "FloatValue": { + "shape": "Float" + }, + "Boo": { + "shape": "Double" + }, + "Qux": { + "shape": "Blob" + }, + "FooEnum": { + "shape": "FooEnum" + }, + "IntegerEnum": { + "shape": "IntegerEnum" + } + } + }, + "String": { + "type": "string" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + }, + "Blob": { + "type": "blob" + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "IntegerEnum": { + "type": "integer", + "box": true + } }, - "serialized": { - "uri": "/", - "headers": { - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" - }, - "body": "Action=MemberRefOp&Version=2014-01-01&Name=myname", - "host": "foo-myname.service.region.amazonaws.com" - } - } - ] - } + "cases": [ + { + "id": "QuerySimpleInputParamsStrings", + "given": { + "name": "SimpleInputParams", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleInputParamsInput" + }, + "documentation": "

This test serializes strings, numbers, and boolean values.

" + }, + "description": "Serializes strings", + "params": { + "Foo": "val1", + "Bar": "val2" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&Foo=val1&Bar=val2", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "QuerySimpleInputParamsStringAndBooleanTrue", + "given": { + "name": "SimpleInputParams", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleInputParamsInput" + }, + "documentation": "

This test serializes strings, numbers, and boolean values.

" + }, + "description": "Serializes booleans that are true", + "params": { + "Foo": "val1", + "Baz": true + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&Foo=val1&Baz=true", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "QuerySimpleInputParamsStringsAndBooleanFalse", + "given": { + "name": "SimpleInputParams", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleInputParamsInput" + }, + "documentation": "

This test serializes strings, numbers, and boolean values.

" + }, + "description": "Serializes booleans that are false", + "params": { + "Baz": false + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&Baz=false", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "QuerySimpleInputParamsInteger", + "given": { + "name": "SimpleInputParams", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleInputParamsInput" + }, + "documentation": "

This test serializes strings, numbers, and boolean values.

" + }, + "description": "Serializes integers", + "params": { + "Bam": 10 + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&Bam=10", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "QuerySimpleInputParamsFloat", + "given": { + "name": "SimpleInputParams", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleInputParamsInput" + }, + "documentation": "

This test serializes strings, numbers, and boolean values.

" + }, + "description": "Serializes floats", + "params": { + "Boo": 10.8 + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&Boo=10.8", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "QuerySimpleInputParamsBlob", + "given": { + "name": "SimpleInputParams", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleInputParamsInput" + }, + "documentation": "

This test serializes strings, numbers, and boolean values.

" + }, + "description": "Blobs are base64 encoded in the query string", + "params": { + "Qux": "value" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&Qux=dmFsdWU%3D", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "QueryEnums", + "given": { + "name": "SimpleInputParams", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleInputParamsInput" + }, + "documentation": "

This test serializes strings, numbers, and boolean values.

" + }, + "description": "Serializes enums in the query string", + "params": { + "FooEnum": "Foo" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&FooEnum=Foo", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "QueryIntEnums", + "given": { + "name": "SimpleInputParams", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleInputParamsInput" + }, + "documentation": "

This test serializes strings, numbers, and boolean values.

" + }, + "description": "Serializes intEnums in the query string", + "params": { + "IntegerEnum": 1 + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&IntegerEnum=1", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "AwsQuerySupportsNaNFloatInputs", + "given": { + "name": "SimpleInputParams", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleInputParamsInput" + }, + "documentation": "

This test serializes strings, numbers, and boolean values.

" + }, + "description": "Supports handling NaN float values.", + "params": { + "FloatValue": "NaN", + "Boo": "NaN" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&FloatValue=NaN&Boo=NaN", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "AwsQuerySupportsInfinityFloatInputs", + "given": { + "name": "SimpleInputParams", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleInputParamsInput" + }, + "documentation": "

This test serializes strings, numbers, and boolean values.

" + }, + "description": "Supports handling Infinity float values.", + "params": { + "FloatValue": "Infinity", + "Boo": "Infinity" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&FloatValue=Infinity&Boo=Infinity", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "AwsQuerySupportsNegativeInfinityFloatInputs", + "given": { + "name": "SimpleInputParams", + "http": { + "method": "POST", + "requestUri": "/" + }, + "input": { + "shape": "SimpleInputParamsInput" + }, + "documentation": "

This test serializes strings, numbers, and boolean values.

" + }, + "description": "Supports handling -Infinity float values.", + "params": { + "FloatValue": "-Infinity", + "Boo": "-Infinity" + }, + "serialized": { + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&FloatValue=-Infinity&Boo=-Infinity", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "requireHeaders": [ + "Content-Length" + ] + } + } + ] + } ] diff --git a/tests/unit/protocols/input/rest-json.json b/tests/unit/protocols/input/rest-json.json index 54f327dbd8..4e0c45c7b7 100644 --- a/tests/unit/protocols/input/rest-json.json +++ b/tests/unit/protocols/input/rest-json.json @@ -1,2194 +1,5927 @@ [ - { - "description": "No parameters", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" - }, - "shapes": {}, - "cases": [ - { - "given": { - "http": { - "method": "GET", - "requestUri": "/2014-01-01/jobs" - }, - "name": "OperationName" - }, - "serialized": { - "body": "", - "uri": "/2014-01-01/jobs", - "headers": {} - } - } - ] - }, - { - "description": "URI parameter only with no location name", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "PipelineId": { - "shape": "StringType", - "location": "uri" - } - } - }, - "StringType": { - "type": "string" - } - }, - "cases": [ - { - "given": { - "http": { - "method": "GET", - "requestUri": "/2014-01-01/jobsByPipeline/{PipelineId}" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "PipelineId": "foo" - }, - "serialized": { - "body": "", - "uri": "/2014-01-01/jobsByPipeline/foo", - "headers": {} - } - } - ] - }, - { - "description": "URI parameter only with location name", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "Foo": { - "shape": "StringType", - "location": "uri", - "locationName": "PipelineId" - } - } - }, - "StringType": { - "type": "string" - } - }, - "cases": [ - { - "given": { - "http": { - "method": "GET", - "requestUri": "/2014-01-01/jobsByPipeline/{PipelineId}" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "Foo": "bar" - }, - "serialized": { - "body": "", - "uri": "/2014-01-01/jobsByPipeline/bar", - "headers": {} - } - } - ] - }, - { - "description": "Querystring list of strings", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for AllQueryStringTypes operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "AllQueryStringTypesInput": { + "type": "structure", + "members": { + "queryString": { + "shape": "String", + "location": "querystring", + "locationName": "String" + }, + "queryStringList": { + "shape": "StringList", + "location": "querystring", + "locationName": "StringList" + }, + "queryStringSet": { + "shape": "StringSet", + "location": "querystring", + "locationName": "StringSet" + }, + "queryByte": { + "shape": "Integer", + "location": "querystring", + "locationName": "Byte" + }, + "queryShort": { + "shape": "Integer", + "location": "querystring", + "locationName": "Short" + }, + "queryInteger": { + "shape": "Integer", + "location": "querystring", + "locationName": "Integer" + }, + "queryIntegerList": { + "shape": "IntegerList", + "location": "querystring", + "locationName": "IntegerList" + }, + "queryIntegerSet": { + "shape": "IntegerSet", + "location": "querystring", + "locationName": "IntegerSet" + }, + "queryLong": { + "shape": "Long", + "location": "querystring", + "locationName": "Long" + }, + "queryFloat": { + "shape": "Float", + "location": "querystring", + "locationName": "Float" + }, + "queryDouble": { + "shape": "Double", + "location": "querystring", + "locationName": "Double" + }, + "queryDoubleList": { + "shape": "DoubleList", + "location": "querystring", + "locationName": "DoubleList" + }, + "queryBoolean": { + "shape": "Boolean", + "location": "querystring", + "locationName": "Boolean" + }, + "queryBooleanList": { + "shape": "BooleanList", + "location": "querystring", + "locationName": "BooleanList" + }, + "queryTimestamp": { + "shape": "Timestamp", + "location": "querystring", + "locationName": "Timestamp" + }, + "queryTimestampList": { + "shape": "TimestampList", + "location": "querystring", + "locationName": "TimestampList" + }, + "queryEnum": { + "shape": "FooEnum", + "location": "querystring", + "locationName": "Enum" + }, + "queryEnumList": { + "shape": "FooEnumList", + "location": "querystring", + "locationName": "EnumList" + }, + "queryIntegerEnum": { + "shape": "IntegerEnum", + "location": "querystring", + "locationName": "IntegerEnum" + }, + "queryIntegerEnumList": { + "shape": "IntegerEnumList", + "location": "querystring", + "locationName": "IntegerEnumList" + }, + "queryParamsMapOfStringList": { + "shape": "StringListMap", + "location": "querystring" + } + } + }, + "String": { + "type": "string" + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringSet": { + "type": "list", + "member": { + "shape": "String" + } + }, + "Integer": { + "type": "integer", + "box": true + }, + "IntegerList": { + "type": "list", + "member": { + "shape": "Integer" + } + }, + "IntegerSet": { + "type": "list", + "member": { + "shape": "Integer" + } + }, + "Long": { + "type": "long", + "box": true + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + }, + "DoubleList": { + "type": "list", + "member": { + "shape": "Double" + } + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "BooleanList": { + "type": "list", + "member": { + "shape": "Boolean" + } + }, + "Timestamp": { + "type": "timestamp" + }, + "TimestampList": { + "type": "list", + "member": { + "shape": "Timestamp" + } + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "IntegerEnumList": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "StringListMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "StringList" + } + } + }, + "cases": [ + { + "id": "RestJsonAllQueryStringTypes", + "given": { + "name": "AllQueryStringTypes", + "http": { + "method": "GET", + "requestUri": "/AllQueryStringTypesInput", + "responseCode": 200 + }, + "input": { + "shape": "AllQueryStringTypesInput" + }, + "documentation": "

This example uses all query string types.

" + }, + "description": "Serializes query string parameters with all supported types", + "params": { + "queryString": "Hello there", + "queryStringList": [ + "a", + "b", + "c" + ], + "queryStringSet": [ + "a", + "b", + "c" + ], + "queryByte": 1, + "queryShort": 2, + "queryInteger": 3, + "queryIntegerList": [ + 1, + 2, + 3 + ], + "queryIntegerSet": [ + 1, + 2, + 3 + ], + "queryLong": 4, + "queryFloat": 1.1, + "queryDouble": 1.1, + "queryDoubleList": [ + 1.1, + 2.1, + 3.1 + ], + "queryBoolean": true, + "queryBooleanList": [ + true, + false, + true + ], + "queryTimestamp": 1, + "queryTimestampList": [ + 1, + 2, + 3 + ], + "queryEnum": "Foo", + "queryEnumList": [ + "Foo", + "Baz", + "Bar" + ], + "queryIntegerEnum": 1, + "queryIntegerEnumList": [ + 1, + 2, + 3 + ], + "queryParamsMapOfStringList": { + "String": [ + "Hello there" + ], + "StringList": [ + "a", + "b", + "c" + ], + "StringSet": [ + "a", + "b", + "c" + ], + "Byte": [ + "1" + ], + "Short": [ + "2" + ], + "Integer": [ + "3" + ], + "IntegerList": [ + "1", + "2", + "3" + ], + "IntegerSet": [ + "1", + "2", + "3" + ], + "Long": [ + "4" + ], + "Float": [ + "1.1" + ], + "Double": [ + "1.1" + ], + "DoubleList": [ + "1.1", + "2.1", + "3.1" + ], + "Boolean": [ + "true" + ], + "BooleanList": [ + "true", + "false", + "true" + ], + "Timestamp": [ + "1970-01-01T00:00:01Z" + ], + "TimestampList": [ + "1970-01-01T00:00:01Z", + "1970-01-01T00:00:02Z", + "1970-01-01T00:00:03Z" + ], + "Enum": [ + "Foo" + ], + "EnumList": [ + "Foo", + "Baz", + "Bar" + ], + "IntegerEnum": [ + "1" + ], + "IntegerEnumList": [ + "1", + "2", + "3" + ] + } + }, + "serialized": { + "method": "GET", + "uri": "/AllQueryStringTypesInput?String=Hello%20there&StringList=a&StringList=b&StringList=c&StringSet=a&StringSet=b&StringSet=c&Byte=1&Short=2&Integer=3&IntegerList=1&IntegerList=2&IntegerList=3&IntegerSet=1&IntegerSet=2&IntegerSet=3&Long=4&Float=1.1&Double=1.1&DoubleList=1.1&DoubleList=2.1&DoubleList=3.1&Boolean=true&BooleanList=true&BooleanList=false&BooleanList=true&Timestamp=1970-01-01T00%3A00%3A01Z&TimestampList=1970-01-01T00%3A00%3A01Z&TimestampList=1970-01-01T00%3A00%3A02Z&TimestampList=1970-01-01T00%3A00%3A03Z&Enum=Foo&EnumList=Foo&EnumList=Baz&EnumList=Bar&IntegerEnum=1&IntegerEnumList=1&IntegerEnumList=2&IntegerEnumList=3", + "body": "" + } + }, + { + "id": "RestJsonQueryStringMap", + "given": { + "name": "AllQueryStringTypes", + "http": { + "method": "GET", + "requestUri": "/AllQueryStringTypesInput", + "responseCode": 200 + }, + "input": { + "shape": "AllQueryStringTypesInput" + }, + "documentation": "

This example uses all query string types.

" + }, + "description": "Handles query string maps", + "params": { + "queryParamsMapOfStringList": { + "QueryParamsStringKeyA": [ + "Foo" + ], + "QueryParamsStringKeyB": [ + "Bar" + ] + } + }, + "serialized": { + "method": "GET", + "uri": "/AllQueryStringTypesInput?QueryParamsStringKeyA=Foo&QueryParamsStringKeyB=Bar", + "body": "" + } + }, + { + "id": "RestJsonQueryStringEscaping", + "given": { + "name": "AllQueryStringTypes", + "http": { + "method": "GET", + "requestUri": "/AllQueryStringTypesInput", + "responseCode": 200 + }, + "input": { + "shape": "AllQueryStringTypesInput" + }, + "documentation": "

This example uses all query string types.

" + }, + "description": "Handles escaping all required characters in the query string.", + "params": { + "queryString": " %:/?#[]@!$&'()*+,;=😹", + "queryParamsMapOfStringList": { + "String": [ + " %:/?#[]@!$&'()*+,;=😹" + ] + } + }, + "serialized": { + "method": "GET", + "uri": "/AllQueryStringTypesInput?String=%20%25%3A%2F%3F%23%5B%5D%40%21%24%26%27%28%29%2A%2B%2C%3B%3D%F0%9F%98%B9", + "body": "" + } + }, + { + "id": "RestJsonSupportsNaNFloatQueryValues", + "given": { + "name": "AllQueryStringTypes", + "http": { + "method": "GET", + "requestUri": "/AllQueryStringTypesInput", + "responseCode": 200 + }, + "input": { + "shape": "AllQueryStringTypesInput" + }, + "documentation": "

This example uses all query string types.

" + }, + "description": "Supports handling NaN float query values.", + "params": { + "queryFloat": "NaN", + "queryDouble": "NaN", + "queryParamsMapOfStringList": { + "Float": [ + "NaN" + ], + "Double": [ + "NaN" + ] + } + }, + "serialized": { + "method": "GET", + "uri": "/AllQueryStringTypesInput?Float=NaN&Double=NaN", + "body": "" + } + }, + { + "id": "RestJsonSupportsInfinityFloatQueryValues", + "given": { + "name": "AllQueryStringTypes", + "http": { + "method": "GET", + "requestUri": "/AllQueryStringTypesInput", + "responseCode": 200 + }, + "input": { + "shape": "AllQueryStringTypesInput" + }, + "documentation": "

This example uses all query string types.

" + }, + "description": "Supports handling Infinity float query values.", + "params": { + "queryFloat": "Infinity", + "queryDouble": "Infinity", + "queryParamsMapOfStringList": { + "Float": [ + "Infinity" + ], + "Double": [ + "Infinity" + ] + } + }, + "serialized": { + "method": "GET", + "uri": "/AllQueryStringTypesInput?Float=Infinity&Double=Infinity", + "body": "" + } + }, + { + "id": "RestJsonSupportsNegativeInfinityFloatQueryValues", + "given": { + "name": "AllQueryStringTypes", + "http": { + "method": "GET", + "requestUri": "/AllQueryStringTypesInput", + "responseCode": 200 + }, + "input": { + "shape": "AllQueryStringTypesInput" + }, + "documentation": "

This example uses all query string types.

" + }, + "description": "Supports handling -Infinity float query values.", + "params": { + "queryFloat": "-Infinity", + "queryDouble": "-Infinity", + "queryParamsMapOfStringList": { + "Float": [ + "-Infinity" + ], + "Double": [ + "-Infinity" + ] + } + }, + "serialized": { + "method": "GET", + "uri": "/AllQueryStringTypesInput?Float=-Infinity&Double=-Infinity", + "body": "" + } + }, + { + "id": "RestJsonZeroAndFalseQueryValues", + "given": { + "name": "AllQueryStringTypes", + "http": { + "method": "GET", + "requestUri": "/AllQueryStringTypesInput", + "responseCode": 200 + }, + "input": { + "shape": "AllQueryStringTypesInput" + }, + "documentation": "

This example uses all query string types.

" + }, + "description": "Query values of 0 and false are serialized", + "params": { + "queryInteger": 0, + "queryBoolean": false, + "queryParamsMapOfStringList": { + "Integer": [ + "0" + ], + "Boolean": [ + "false" + ] + } + }, + "serialized": { + "method": "GET", + "uri": "/AllQueryStringTypesInput?Integer=0&Boolean=false", + "body": "" + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "Items": { - "shape": "StringList", - "location": "querystring", - "locationName": "item" - } - } - }, - "StringList": { - "type": "list", - "member": { - "shape": "String" - } - }, - "String": { - "type": "string" - } + { + "description": "Test cases for ConstantAndVariableQueryString operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "ConstantAndVariableQueryStringInput": { + "type": "structure", + "members": { + "baz": { + "shape": "String", + "location": "querystring", + "locationName": "baz" + }, + "maybeSet": { + "shape": "String", + "location": "querystring", + "locationName": "maybeSet" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonConstantAndVariableQueryStringMissingOneValue", + "given": { + "name": "ConstantAndVariableQueryString", + "http": { + "method": "GET", + "requestUri": "/ConstantAndVariableQueryString?foo=bar", + "responseCode": 200 + }, + "input": { + "shape": "ConstantAndVariableQueryStringInput" + }, + "documentation": "

This example uses fixed query string params and variable query string params. The fixed query string parameters and variable parameters must both be serialized (implementations may need to merge them together).

" + }, + "description": "Mixes constant and variable query string parameters", + "params": { + "baz": "bam" + }, + "serialized": { + "method": "GET", + "uri": "/ConstantAndVariableQueryString?foo=bar&baz=bam", + "body": "" + } + }, + { + "id": "RestJsonConstantAndVariableQueryStringAllValues", + "given": { + "name": "ConstantAndVariableQueryString", + "http": { + "method": "GET", + "requestUri": "/ConstantAndVariableQueryString?foo=bar", + "responseCode": 200 + }, + "input": { + "shape": "ConstantAndVariableQueryStringInput" + }, + "documentation": "

This example uses fixed query string params and variable query string params. The fixed query string parameters and variable parameters must both be serialized (implementations may need to merge them together).

" + }, + "description": "Mixes constant and variable query string parameters", + "params": { + "baz": "bam", + "maybeSet": "yes" + }, + "serialized": { + "method": "GET", + "uri": "/ConstantAndVariableQueryString?foo=bar&baz=bam&maybeSet=yes", + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "GET", - "requestUri": "/path" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "Items": ["value1", "value2"] - }, - "serialized": { - "body": "", - "uri": "/path?item=value1&item=value2", - "headers": {} - } - } - ] - }, - { - "description": "String to string maps in querystring", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for ConstantQueryString operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "ConstantQueryStringInput": { + "type": "structure", + "required": [ + "hello" + ], + "members": { + "hello": { + "shape": "String", + "location": "uri", + "locationName": "hello" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonConstantQueryString", + "given": { + "name": "ConstantQueryString", + "http": { + "method": "GET", + "requestUri": "/ConstantQueryString/{hello}?foo=bar&hello", + "responseCode": 200 + }, + "input": { + "shape": "ConstantQueryStringInput" + }, + "documentation": "

This example uses a constant query string parameters and a label. This simply tests that labels and query string parameters are compatible. The fixed query string parameter named "hello" should in no way conflict with the label, {hello}.

" + }, + "description": "Includes constant query string parameters", + "params": { + "hello": "hi" + }, + "serialized": { + "method": "GET", + "uri": "/ConstantQueryString/hi?foo=bar&hello", + "body": "" + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "PipelineId": { - "shape": "StringType", - "location": "uri" - }, - "QueryDoc": { - "shape": "MapStringStringType", - "location": "querystring" - } - } - }, - "MapStringStringType": { - "type": "map", - "key": { - "shape": "StringType" - }, - "value": { - "shape": "StringType" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for DocumentType operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "DocumentTypeInputOutput": { + "type": "structure", + "members": { + "stringValue": { + "shape": "String" + }, + "documentValue": { + "shape": "Document" + } + } + }, + "String": { + "type": "string" + }, + "Document": { + "type": "structure", + "members": {}, + "document": true + } + }, + "cases": [ + { + "id": "DocumentTypeInputWithObject", + "given": { + "name": "DocumentType", + "http": { + "method": "PUT", + "requestUri": "/DocumentType", + "responseCode": 200 + }, + "input": { + "shape": "DocumentTypeInputOutput" + }, + "documentation": "

This example serializes a document as part of the payload.

", + "idempotent": true + }, + "description": "Serializes document types as part of the JSON request payload with no escaping.", + "params": { + "stringValue": "string", + "documentValue": { + "foo": "bar" + } + }, + "serialized": { + "method": "PUT", + "uri": "/DocumentType", + "body": "{\n \"stringValue\": \"string\",\n \"documentValue\": {\n \"foo\": \"bar\"\n }\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "DocumentInputWithString", + "given": { + "name": "DocumentType", + "http": { + "method": "PUT", + "requestUri": "/DocumentType", + "responseCode": 200 + }, + "input": { + "shape": "DocumentTypeInputOutput" + }, + "documentation": "

This example serializes a document as part of the payload.

", + "idempotent": true + }, + "description": "Serializes document types using a string.", + "params": { + "stringValue": "string", + "documentValue": "hello" + }, + "serialized": { + "method": "PUT", + "uri": "/DocumentType", + "body": "{\n \"stringValue\": \"string\",\n \"documentValue\": \"hello\"\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "DocumentInputWithNumber", + "given": { + "name": "DocumentType", + "http": { + "method": "PUT", + "requestUri": "/DocumentType", + "responseCode": 200 + }, + "input": { + "shape": "DocumentTypeInputOutput" + }, + "documentation": "

This example serializes a document as part of the payload.

", + "idempotent": true + }, + "description": "Serializes document types using a number.", + "params": { + "stringValue": "string", + "documentValue": 10 + }, + "serialized": { + "method": "PUT", + "uri": "/DocumentType", + "body": "{\n \"stringValue\": \"string\",\n \"documentValue\": 10\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "DocumentInputWithBoolean", + "given": { + "name": "DocumentType", + "http": { + "method": "PUT", + "requestUri": "/DocumentType", + "responseCode": 200 + }, + "input": { + "shape": "DocumentTypeInputOutput" + }, + "documentation": "

This example serializes a document as part of the payload.

", + "idempotent": true + }, + "description": "Serializes document types using a boolean.", + "params": { + "stringValue": "string", + "documentValue": true + }, + "serialized": { + "method": "PUT", + "uri": "/DocumentType", + "body": "{\n \"stringValue\": \"string\",\n \"documentValue\": true\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "DocumentInputWithList", + "given": { + "name": "DocumentType", + "http": { + "method": "PUT", + "requestUri": "/DocumentType", + "responseCode": 200 + }, + "input": { + "shape": "DocumentTypeInputOutput" + }, + "documentation": "

This example serializes a document as part of the payload.

", + "idempotent": true + }, + "description": "Serializes document types using a list.", + "params": { + "stringValue": "string", + "documentValue": [ + true, + "hi", + [ + 1, + 2 + ], + { + "foo": { + "baz": [ + 3, + 4 + ] + } + } + ] + }, + "serialized": { + "method": "PUT", + "uri": "/DocumentType", + "body": "{\n \"stringValue\": \"string\",\n \"documentValue\": [\n true,\n \"hi\",\n [\n 1,\n 2\n ],\n {\n \"foo\": {\n \"baz\": [\n 3,\n 4\n ]\n }\n }\n ]\n}", + "headers": { + "Content-Type": "application/json" + } + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "GET", - "requestUri": "/2014-01-01/jobsByPipeline/{PipelineId}" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "PipelineId": "foo", - "QueryDoc": { - "bar": "baz", - "fizz": "buzz" - } - }, - "serialized": { - "body": "", - "uri": "/2014-01-01/jobsByPipeline/foo?bar=baz&fizz=buzz", - "headers": {} - } - } - ] - }, - { - "description": "String to string list maps in querystring", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for DocumentTypeAsMapValue operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "DocumentTypeAsMapValueInputOutput": { + "type": "structure", + "members": { + "docValuedMap": { + "shape": "DocumentValuedMap" + } + } + }, + "DocumentValuedMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "Document" + } + }, + "Document": { + "type": "structure", + "members": {}, + "document": true + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "DocumentTypeAsMapValueInput", + "given": { + "name": "DocumentTypeAsMapValue", + "http": { + "method": "PUT", + "requestUri": "/DocumentTypeAsMapValue", + "responseCode": 200 + }, + "input": { + "shape": "DocumentTypeAsMapValueInputOutput" + }, + "documentation": "

This example serializes documents as the value of maps.

", + "idempotent": true + }, + "description": "Serializes a map that uses documents as the value.", + "params": { + "docValuedMap": { + "foo": { + "f": 1, + "o": 2 + }, + "bar": [ + "b", + "a", + "r" + ], + "baz": "BAZ" + } + }, + "serialized": { + "method": "PUT", + "uri": "/DocumentTypeAsMapValue", + "body": "{\n \"docValuedMap\": {\n \"foo\": { \"f\": 1, \"o\": 2 },\n \"bar\": [ \"b\", \"a\", \"r\" ],\n \"baz\": \"BAZ\"\n }\n}", + "headers": { + "Content-Type": "application/json" + } + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "PipelineId": { - "shape": "StringType", - "location": "uri" - }, - "QueryDoc": { - "shape": "MapStringStringListType", - "location": "querystring" - } - } - }, - "MapStringStringListType": { - "type": "map", - "key": { - "shape": "StringType" - }, - "value": { - "shape": "StringListType" - } - }, - "StringListType": { - "type": "list", - "member": { - "shape": "StringType" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for DocumentTypeAsPayload operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "DocumentTypeAsPayloadInputOutput": { + "type": "structure", + "members": { + "documentValue": { + "shape": "Document" + } + }, + "payload": "documentValue" + }, + "Document": { + "type": "structure", + "members": {}, + "document": true + } + }, + "cases": [ + { + "id": "DocumentTypeAsPayloadInput", + "given": { + "name": "DocumentTypeAsPayload", + "http": { + "method": "PUT", + "requestUri": "/DocumentTypeAsPayload", + "responseCode": 200 + }, + "input": { + "shape": "DocumentTypeAsPayloadInputOutput" + }, + "documentation": "

This example serializes a document as the entire HTTP payload.

", + "idempotent": true + }, + "description": "Serializes a document as the target of the httpPayload trait.", + "params": { + "documentValue": { + "foo": "bar" + } + }, + "serialized": { + "method": "PUT", + "uri": "/DocumentTypeAsPayload", + "body": "{\n \"foo\": \"bar\"\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "DocumentTypeAsPayloadInputString", + "given": { + "name": "DocumentTypeAsPayload", + "http": { + "method": "PUT", + "requestUri": "/DocumentTypeAsPayload", + "responseCode": 200 + }, + "input": { + "shape": "DocumentTypeAsPayloadInputOutput" + }, + "documentation": "

This example serializes a document as the entire HTTP payload.

", + "idempotent": true + }, + "description": "Serializes a document as the target of the httpPayload trait using a string.", + "params": { + "documentValue": "hello" + }, + "serialized": { + "method": "PUT", + "uri": "/DocumentTypeAsPayload", + "body": "\"hello\"", + "headers": { + "Content-Type": "application/json" + } + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "GET", - "requestUri": "/2014-01-01/jobsByPipeline/{PipelineId}" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "PipelineId": "id", - "QueryDoc": { - "foo": ["bar", "baz"], - "fizz": ["buzz", "pop"] - } - }, - "serialized": { - "body": "", - "uri": "/2014-01-01/jobsByPipeline/id?foo=bar&foo=baz&fizz=buzz&fizz=pop", - "headers": {} - } - } - ] - }, - { - "description": "Boolean in querystring", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for EmptyInputAndEmptyOutput operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "EmptyInputAndEmptyOutputInput": { + "type": "structure", + "members": {} + } + }, + "cases": [ + { + "id": "RestJsonEmptyInputAndEmptyOutput", + "given": { + "name": "EmptyInputAndEmptyOutput", + "http": { + "method": "POST", + "requestUri": "/EmptyInputAndEmptyOutput", + "responseCode": 200 + }, + "input": { + "shape": "EmptyInputAndEmptyOutputInput" + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response payload because the operation has an empty input and empty output structure that reuses the same shape. While this should be rare, code generators must support this.

" + }, + "description": "Clients should not serialize a JSON payload when no parameters\nare given that are sent in the body. A service will tolerate\nclients that omit a payload or that send a JSON object.", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/EmptyInputAndEmptyOutput", + "body": "" + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "BoolQuery": { - "shape": "BoolType", - "location": "querystring", - "locationName": "bool-query" - } - } - }, - "BoolType": { - "type": "boolean" - } + { + "description": "Test cases for EndpointOperation operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": {}, + "cases": [ + { + "id": "RestJsonEndpointTrait", + "given": { + "name": "EndpointOperation", + "http": { + "method": "POST", + "requestUri": "/EndpointOperation", + "responseCode": 200 + }, + "endpoint": { + "hostPrefix": "foo." + } + }, + "description": "Operations can prepend to the given host if they define the\nendpoint trait.", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/EndpointOperation", + "body": "", + "host": "foo.example.com" + } + } + ], + "clientEndpoint": "https://example.com" }, - "cases": [ - { - "given": { - "http": { - "method": "GET", - "requestUri": "/path" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "BoolQuery": true - }, - "serialized": { - "body": "", - "uri": "/path?bool-query=true", - "headers": {} - } - }, - { - "given": { - "http": { - "method": "GET", - "requestUri": "/path" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "BoolQuery": false - }, - "serialized": { - "body": "", - "uri": "/path?bool-query=false", - "headers": {} - } - } - ] - }, - { - "description": "URI parameter and querystring params", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for EndpointWithHostLabelOperation operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HostLabelInput": { + "type": "structure", + "required": [ + "label" + ], + "members": { + "label": { + "shape": "String", + "hostLabel": true + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonEndpointTraitWithHostLabel", + "given": { + "name": "EndpointWithHostLabelOperation", + "http": { + "method": "POST", + "requestUri": "/EndpointWithHostLabelOperation", + "responseCode": 200 + }, + "input": { + "shape": "HostLabelInput" + }, + "endpoint": { + "hostPrefix": "foo.{label}." + } + }, + "description": "Operations can prepend to the given host if they define the\nendpoint trait, and can use the host label trait to define\nfurther customization based on user input.", + "params": { + "label": "bar" + }, + "serialized": { + "method": "POST", + "uri": "/EndpointWithHostLabelOperation", + "body": "{\"label\": \"bar\"}", + "host": "foo.bar.example.com" + } + } + ], + "clientEndpoint": "https://example.com" }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "PipelineId": { - "shape": "StringType", - "location": "uri", - "locationName": "PipelineId" - }, - "Ascending": { - "shape": "StringType", - "location": "querystring", - "locationName": "Ascending" - }, - "PageToken": { - "shape": "StringType", - "location": "querystring", - "locationName": "PageToken" - } - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for HostWithPathOperation operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": {}, + "cases": [ + { + "id": "RestJsonHostWithPath", + "given": { + "name": "HostWithPathOperation", + "http": { + "method": "GET", + "requestUri": "/HostWithPathOperation", + "responseCode": 200 + } + }, + "description": "Custom endpoints supplied by users can have paths", + "params": {}, + "serialized": { + "method": "GET", + "uri": "/custom/HostWithPathOperation", + "body": "", + "host": "example.com/custom" + } + } + ], + "clientEndpoint": "https://example.com/custom" }, - "cases": [ - { - "given": { - "http": { - "method": "GET", - "requestUri": "/2014-01-01/jobsByPipeline/{PipelineId}" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "PipelineId": "foo", - "Ascending": "true", - "PageToken": "bar" - }, - "serialized": { - "body": "", - "uri": "/2014-01-01/jobsByPipeline/foo?Ascending=true&PageToken=bar", - "headers": {} - } - } - ] - }, - { - "description": "URI parameter, querystring params and JSON body", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for HttpChecksumRequired operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpChecksumRequiredInputOutput": { + "type": "structure", + "members": { + "foo": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonHttpChecksumRequired", + "given": { + "name": "HttpChecksumRequired", + "http": { + "method": "POST", + "requestUri": "/HttpChecksumRequired", + "responseCode": 200 + }, + "input": { + "shape": "HttpChecksumRequiredInputOutput" + }, + "documentation": "

This example tests httpChecksumRequired trait

", + "httpChecksumRequired": true + }, + "description": "Adds Content-MD5 header", + "params": { + "foo": "base64 encoded md5 checksum" + }, + "serialized": { + "method": "POST", + "uri": "/HttpChecksumRequired", + "body": "{\n \"foo\":\"base64 encoded md5 checksum\"\n}\n", + "headers": { + "Content-MD5": "iB0/3YSo7maijL0IGOgA9g==", + "Content-Type": "application/json" + } + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "PipelineId": { - "shape": "StringType", - "location": "uri", - "locationName": "PipelineId" - }, - "Ascending": { - "shape": "StringType", - "location": "querystring", - "locationName": "Ascending" - }, - "PageToken": { - "shape": "StringType", - "location": "querystring", - "locationName": "PageToken" - }, - "Config": { - "shape": "StructType" - } - } - }, - "StringType": { - "type": "string" - }, - "StructType": { - "type": "structure", - "members": { - "A": { - "shape": "StringType" - }, - "B": { - "shape": "StringType" - } - } - } + { + "description": "Test cases for HttpEnumPayload operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "EnumPayloadInput": { + "type": "structure", + "members": { + "payload": { + "shape": "StringEnum" + } + }, + "payload": "payload" + }, + "StringEnum": { + "type": "string", + "enum": [ + "enumvalue" + ] + } + }, + "cases": [ + { + "id": "RestJsonEnumPayloadRequest", + "given": { + "name": "HttpEnumPayload", + "http": { + "method": "POST", + "requestUri": "/EnumPayload", + "responseCode": 200 + }, + "input": { + "shape": "EnumPayloadInput" + } + }, + "params": { + "payload": "enumvalue" + }, + "serialized": { + "method": "POST", + "uri": "/EnumPayload", + "body": "enumvalue" + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/2014-01-01/jobsByPipeline/{PipelineId}" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "PipelineId": "foo", - "Ascending": "true", - "PageToken": "bar", - "Config": { - "A": "one", - "B": "two" - } - }, - "serialized": { - "body": "{\"Config\": {\"A\": \"one\", \"B\": \"two\"}}", - "uri": "/2014-01-01/jobsByPipeline/foo?Ascending=true&PageToken=bar", - "headers": {} - } - } - ] - }, - { - "description": "URI parameter, querystring params, headers and JSON body", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for HttpPayloadTraits operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPayloadTraitsInputOutput": { + "type": "structure", + "members": { + "foo": { + "shape": "String", + "location": "header", + "locationName": "X-Foo" + }, + "blob": { + "shape": "Blob" + } + }, + "payload": "blob" + }, + "String": { + "type": "string" + }, + "Blob": { + "type": "blob" + } + }, + "cases": [ + { + "id": "RestJsonHttpPayloadTraitsWithBlob", + "given": { + "name": "HttpPayloadTraits", + "http": { + "method": "POST", + "requestUri": "/HttpPayloadTraits", + "responseCode": 200 + }, + "input": { + "shape": "HttpPayloadTraitsInputOutput" + }, + "documentation": "

This example serializes a blob shape in the payload.

In this example, no JSON document is synthesized because the payload is not a structure or a union type.

" + }, + "description": "Serializes a blob in the HTTP payload", + "params": { + "foo": "Foo", + "blob": "blobby blob blob" + }, + "serialized": { + "method": "POST", + "uri": "/HttpPayloadTraits", + "body": "blobby blob blob", + "headers": { + "Content-Type": "application/octet-stream", + "X-Foo": "Foo" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "RestJsonHttpPayloadTraitsWithNoBlobBody", + "given": { + "name": "HttpPayloadTraits", + "http": { + "method": "POST", + "requestUri": "/HttpPayloadTraits", + "responseCode": 200 + }, + "input": { + "shape": "HttpPayloadTraitsInputOutput" + }, + "documentation": "

This example serializes a blob shape in the payload.

In this example, no JSON document is synthesized because the payload is not a structure or a union type.

" + }, + "description": "Serializes an empty blob in the HTTP payload", + "params": { + "foo": "Foo" + }, + "serialized": { + "method": "POST", + "uri": "/HttpPayloadTraits", + "body": "", + "headers": { + "X-Foo": "Foo" + } + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "PipelineId": { - "shape": "StringType", - "location": "uri", - "locationName": "PipelineId" - }, - "Ascending": { - "shape": "StringType", - "location": "querystring", - "locationName": "Ascending" - }, - "Checksum": { - "shape": "StringType", - "location": "header", - "locationName": "x-amz-checksum" - }, - "PageToken": { - "shape": "StringType", - "location": "querystring", - "locationName": "PageToken" - }, - "Config": { - "shape": "StructType" - } - } - }, - "StringType": { - "type": "string" - }, - "StructType": { - "type": "structure", - "members": { - "A": { - "shape": "StringType" - }, - "B": { - "shape": "StringType" - } - } - } + { + "description": "Test cases for HttpPayloadWithStructure operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPayloadWithStructureInputOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "NestedPayload" + } + }, + "payload": "nested" + }, + "NestedPayload": { + "type": "structure", + "members": { + "greeting": { + "shape": "String" + }, + "name": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonHttpPayloadWithStructure", + "given": { + "name": "HttpPayloadWithStructure", + "http": { + "method": "PUT", + "requestUri": "/HttpPayloadWithStructure", + "responseCode": 200 + }, + "input": { + "shape": "HttpPayloadWithStructureInputOutput" + }, + "documentation": "

This example serializes a structure in the payload.

Note that serializing a structure changes the wrapper element name to match the targeted structure.

", + "idempotent": true + }, + "description": "Serializes a structure in the payload", + "params": { + "nested": { + "greeting": "hello", + "name": "Phreddy" + } + }, + "serialized": { + "method": "PUT", + "uri": "/HttpPayloadWithStructure", + "body": "{\n \"greeting\": \"hello\",\n \"name\": \"Phreddy\"\n}", + "headers": { + "Content-Type": "application/json" + }, + "requireHeaders": [ + "Content-Length" + ] + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/2014-01-01/jobsByPipeline/{PipelineId}" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "PipelineId": "foo", - "Ascending": "true", - "Checksum": "12345", - "PageToken": "bar", - "Config": { - "A": "one", - "B": "two" - } - }, - "serialized": { - "body": "{\"Config\": {\"A\": \"one\", \"B\": \"two\"}}", - "uri": "/2014-01-01/jobsByPipeline/foo?Ascending=true&PageToken=bar", - "headers": { - "x-amz-checksum": "12345" - } - } - } - ] - }, - { - "description": "Streaming payload", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for HttpPayloadWithUnion operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPayloadWithUnionInputOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "UnionPayload" + } + }, + "payload": "nested" + }, + "UnionPayload": { + "type": "structure", + "members": { + "greeting": { + "shape": "String" + } + }, + "union": true + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonHttpPayloadWithUnion", + "given": { + "name": "HttpPayloadWithUnion", + "http": { + "method": "PUT", + "requestUri": "/HttpPayloadWithUnion", + "responseCode": 200 + }, + "input": { + "shape": "HttpPayloadWithUnionInputOutput" + }, + "documentation": "

This example serializes a union in the payload.

", + "idempotent": true + }, + "description": "Serializes a union in the payload.", + "params": { + "nested": { + "greeting": "hello" + } + }, + "serialized": { + "method": "PUT", + "uri": "/HttpPayloadWithUnion", + "body": "{\n \"greeting\": \"hello\"\n}", + "headers": { + "Content-Type": "application/json" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "RestJsonHttpPayloadWithUnsetUnion", + "given": { + "name": "HttpPayloadWithUnion", + "http": { + "method": "PUT", + "requestUri": "/HttpPayloadWithUnion", + "responseCode": 200 + }, + "input": { + "shape": "HttpPayloadWithUnionInputOutput" + }, + "documentation": "

This example serializes a union in the payload.

", + "idempotent": true + }, + "description": "No payload is sent if the union has no value.", + "params": {}, + "serialized": { + "method": "PUT", + "uri": "/HttpPayloadWithUnion", + "body": "" + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "vaultName": { - "shape": "StringType", - "location": "uri", - "locationName": "vaultName" - }, - "checksum": { - "shape": "StringType", - "location": "header", - "locationName": "x-amz-sha256-tree-hash" - }, - "body": { - "shape": "Stream" - } - }, - "required": [ - "vaultName" - ], - "payload": "body" - }, - "StringType": { - "type": "string" - }, - "Stream": { - "type": "blob", - "streaming": true - } + { + "description": "Test cases for HttpPrefixHeaders operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPrefixHeadersInput": { + "type": "structure", + "members": { + "foo": { + "shape": "String", + "location": "header", + "locationName": "X-Foo" + }, + "fooMap": { + "shape": "StringMap", + "location": "headers", + "locationName": "X-Foo-" + } + } + }, + "String": { + "type": "string" + }, + "StringMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "String" + } + } + }, + "cases": [ + { + "id": "RestJsonHttpPrefixHeadersArePresent", + "given": { + "name": "HttpPrefixHeaders", + "http": { + "method": "GET", + "requestUri": "/HttpPrefixHeaders", + "responseCode": 200 + }, + "input": { + "shape": "HttpPrefixHeadersInput" + }, + "documentation": "

This examples adds headers to the input of a request and response by prefix.

" + }, + "description": "Adds headers by prefix", + "params": { + "foo": "Foo", + "fooMap": { + "Abc": "Abc value", + "Def": "Def value" + } + }, + "serialized": { + "method": "GET", + "uri": "/HttpPrefixHeaders", + "body": "", + "headers": { + "X-Foo": "Foo", + "X-Foo-Abc": "Abc value", + "X-Foo-Def": "Def value" + } + } + }, + { + "id": "RestJsonHttpPrefixHeadersAreNotPresent", + "given": { + "name": "HttpPrefixHeaders", + "http": { + "method": "GET", + "requestUri": "/HttpPrefixHeaders", + "responseCode": 200 + }, + "input": { + "shape": "HttpPrefixHeadersInput" + }, + "documentation": "

This examples adds headers to the input of a request and response by prefix.

" + }, + "description": "No prefix headers are serialized because the value is empty", + "params": { + "foo": "Foo", + "fooMap": {} + }, + "serialized": { + "method": "GET", + "uri": "/HttpPrefixHeaders", + "body": "", + "headers": { + "X-Foo": "Foo" + } + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/2014-01-01/vaults/{vaultName}/archives" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "vaultName": "name", - "checksum": "foo", - "body": "contents" - }, - "serialized": { - "body": "contents", - "uri": "/2014-01-01/vaults/name/archives", - "headers": { - "x-amz-sha256-tree-hash": "foo" - } - } - } - ] - }, - { - "description": "Serialize blobs in body", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for HttpRequestWithFloatLabels operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpRequestWithFloatLabelsInput": { + "type": "structure", + "required": [ + "float", + "double" + ], + "members": { + "float": { + "shape": "Float", + "location": "uri", + "locationName": "float" + }, + "double": { + "shape": "Double", + "location": "uri", + "locationName": "double" + } + } + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + } + }, + "cases": [ + { + "id": "RestJsonSupportsNaNFloatLabels", + "given": { + "name": "HttpRequestWithFloatLabels", + "http": { + "method": "GET", + "requestUri": "/FloatHttpLabels/{float}/{double}", + "responseCode": 200 + }, + "input": { + "shape": "HttpRequestWithFloatLabelsInput" + } + }, + "description": "Supports handling NaN float label values.", + "params": { + "float": "NaN", + "double": "NaN" + }, + "serialized": { + "method": "GET", + "uri": "/FloatHttpLabels/NaN/NaN", + "body": "" + } + }, + { + "id": "RestJsonSupportsInfinityFloatLabels", + "given": { + "name": "HttpRequestWithFloatLabels", + "http": { + "method": "GET", + "requestUri": "/FloatHttpLabels/{float}/{double}", + "responseCode": 200 + }, + "input": { + "shape": "HttpRequestWithFloatLabelsInput" + } + }, + "description": "Supports handling Infinity float label values.", + "params": { + "float": "Infinity", + "double": "Infinity" + }, + "serialized": { + "method": "GET", + "uri": "/FloatHttpLabels/Infinity/Infinity", + "body": "" + } + }, + { + "id": "RestJsonSupportsNegativeInfinityFloatLabels", + "given": { + "name": "HttpRequestWithFloatLabels", + "http": { + "method": "GET", + "requestUri": "/FloatHttpLabels/{float}/{double}", + "responseCode": 200 + }, + "input": { + "shape": "HttpRequestWithFloatLabelsInput" + } + }, + "description": "Supports handling -Infinity float label values.", + "params": { + "float": "-Infinity", + "double": "-Infinity" + }, + "serialized": { + "method": "GET", + "uri": "/FloatHttpLabels/-Infinity/-Infinity", + "body": "" + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "Foo": { - "shape": "StringType", - "location": "uri", - "locationName": "Foo" - }, - "Bar": {"shape": "BlobType"} - }, - "required": [ - "Foo" + { + "description": "Test cases for HttpRequestWithGreedyLabelInPath operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpRequestWithGreedyLabelInPathInput": { + "type": "structure", + "required": [ + "foo", + "baz" + ], + "members": { + "foo": { + "shape": "String", + "location": "uri", + "locationName": "foo" + }, + "baz": { + "shape": "String", + "location": "uri", + "locationName": "baz" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonHttpRequestWithGreedyLabelInPath", + "given": { + "name": "HttpRequestWithGreedyLabelInPath", + "http": { + "method": "GET", + "requestUri": "/HttpRequestWithGreedyLabelInPath/foo/{foo}/baz/{baz+}", + "responseCode": 200 + }, + "input": { + "shape": "HttpRequestWithGreedyLabelInPathInput" + } + }, + "description": "Serializes greedy labels and normal labels", + "params": { + "foo": "hello/escape", + "baz": "there/guy" + }, + "serialized": { + "method": "GET", + "uri": "/HttpRequestWithGreedyLabelInPath/foo/hello%2Fescape/baz/there/guy", + "body": "" + } + } ] - }, - "StringType": { - "type": "string" - }, - "BlobType": { - "type": "blob" - } }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/2014-01-01/{Foo}" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "Foo": "foo_name", - "Bar": "Blob param" - }, - "serialized": { - "body": "{\"Bar\": \"QmxvYiBwYXJhbQ==\"}", - "uri": "/2014-01-01/foo_name" - } - } - ] - }, - { - "description": "Blob payload", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for HttpRequestWithLabels operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpRequestWithLabelsInput": { + "type": "structure", + "required": [ + "string", + "short", + "integer", + "long", + "float", + "double", + "boolean", + "timestamp" + ], + "members": { + "string": { + "shape": "String", + "location": "uri", + "locationName": "string" + }, + "short": { + "shape": "Integer", + "location": "uri", + "locationName": "short" + }, + "integer": { + "shape": "Integer", + "location": "uri", + "locationName": "integer" + }, + "long": { + "shape": "Long", + "location": "uri", + "locationName": "long" + }, + "float": { + "shape": "Float", + "location": "uri", + "locationName": "float" + }, + "double": { + "shape": "Double", + "location": "uri", + "locationName": "double" + }, + "boolean": { + "shape": "Boolean", + "documentation": "

Serialized in the path as true or false.

", + "location": "uri", + "locationName": "boolean" + }, + "timestamp": { + "shape": "Timestamp", + "documentation": "

Note that this member has no format, so it's serialized as an RFC 3399 date-time.

", + "location": "uri", + "locationName": "timestamp" + } + } + }, + "String": { + "type": "string" + }, + "Integer": { + "type": "integer", + "box": true + }, + "Long": { + "type": "long", + "box": true + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Timestamp": { + "type": "timestamp" + } + }, + "cases": [ + { + "id": "RestJsonInputWithHeadersAndAllParams", + "given": { + "name": "HttpRequestWithLabels", + "http": { + "method": "GET", + "requestUri": "/HttpRequestWithLabels/{string}/{short}/{integer}/{long}/{float}/{double}/{boolean}/{timestamp}", + "responseCode": 200 + }, + "input": { + "shape": "HttpRequestWithLabelsInput" + }, + "documentation": "

The example tests how requests are serialized when there's no input payload but there are HTTP labels.

" + }, + "description": "Sends a GET request that uses URI label bindings", + "params": { + "string": "string", + "short": 1, + "integer": 2, + "long": 3, + "float": 4.1, + "double": 5.1, + "boolean": true, + "timestamp": 1576540098 + }, + "serialized": { + "method": "GET", + "uri": "/HttpRequestWithLabels/string/1/2/3/4.1/5.1/true/2019-12-16T23%3A48%3A18Z", + "body": "" + } + }, + { + "id": "RestJsonHttpRequestLabelEscaping", + "given": { + "name": "HttpRequestWithLabels", + "http": { + "method": "GET", + "requestUri": "/HttpRequestWithLabels/{string}/{short}/{integer}/{long}/{float}/{double}/{boolean}/{timestamp}", + "responseCode": 200 + }, + "input": { + "shape": "HttpRequestWithLabelsInput" + }, + "documentation": "

The example tests how requests are serialized when there's no input payload but there are HTTP labels.

" + }, + "description": "Sends a GET request that uses URI label bindings", + "params": { + "string": " %:/?#[]@!$&'()*+,;=😹", + "short": 1, + "integer": 2, + "long": 3, + "float": 4.1, + "double": 5.1, + "boolean": true, + "timestamp": 1576540098 + }, + "serialized": { + "method": "GET", + "uri": "/HttpRequestWithLabels/%20%25%3A%2F%3F%23%5B%5D%40%21%24%26%27%28%29%2A%2B%2C%3B%3D%F0%9F%98%B9/1/2/3/4.1/5.1/true/2019-12-16T23%3A48%3A18Z", + "body": "" + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "foo": { - "shape": "FooShape" - } - } - }, - "FooShape": { - "type": "blob" - } + { + "description": "Test cases for HttpRequestWithLabelsAndTimestampFormat operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpRequestWithLabelsAndTimestampFormatInput": { + "type": "structure", + "required": [ + "memberEpochSeconds", + "memberHttpDate", + "memberDateTime", + "defaultFormat", + "targetEpochSeconds", + "targetHttpDate", + "targetDateTime" + ], + "members": { + "memberEpochSeconds": { + "shape": "SyntheticTimestamp_epoch_seconds", + "location": "uri", + "locationName": "memberEpochSeconds" + }, + "memberHttpDate": { + "shape": "SyntheticTimestamp_http_date", + "location": "uri", + "locationName": "memberHttpDate" + }, + "memberDateTime": { + "shape": "SyntheticTimestamp_date_time", + "location": "uri", + "locationName": "memberDateTime" + }, + "defaultFormat": { + "shape": "Timestamp", + "location": "uri", + "locationName": "defaultFormat" + }, + "targetEpochSeconds": { + "shape": "EpochSeconds", + "location": "uri", + "locationName": "targetEpochSeconds" + }, + "targetHttpDate": { + "shape": "HttpDate", + "location": "uri", + "locationName": "targetHttpDate" + }, + "targetDateTime": { + "shape": "DateTime", + "location": "uri", + "locationName": "targetDateTime" + } + } + }, + "SyntheticTimestamp_epoch_seconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "SyntheticTimestamp_http_date": { + "type": "timestamp", + "timestampFormat": "rfc822" + }, + "SyntheticTimestamp_date_time": { + "type": "timestamp", + "timestampFormat": "iso8601" + }, + "Timestamp": { + "type": "timestamp" + }, + "EpochSeconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "HttpDate": { + "type": "timestamp", + "timestampFormat": "rfc822" + }, + "DateTime": { + "type": "timestamp", + "timestampFormat": "iso8601" + } + }, + "cases": [ + { + "id": "RestJsonHttpRequestWithLabelsAndTimestampFormat", + "given": { + "name": "HttpRequestWithLabelsAndTimestampFormat", + "http": { + "method": "GET", + "requestUri": "/HttpRequestWithLabelsAndTimestampFormat/{memberEpochSeconds}/{memberHttpDate}/{memberDateTime}/{defaultFormat}/{targetEpochSeconds}/{targetHttpDate}/{targetDateTime}", + "responseCode": 200 + }, + "input": { + "shape": "HttpRequestWithLabelsAndTimestampFormatInput" + }, + "documentation": "

The example tests how requests serialize different timestamp formats in the URI path.

" + }, + "description": "Serializes different timestamp formats in URI labels", + "params": { + "memberEpochSeconds": 1576540098, + "memberHttpDate": 1576540098, + "memberDateTime": 1576540098, + "defaultFormat": 1576540098, + "targetEpochSeconds": 1576540098, + "targetHttpDate": 1576540098, + "targetDateTime": 1576540098 + }, + "serialized": { + "method": "GET", + "uri": "/HttpRequestWithLabelsAndTimestampFormat/1576540098/Mon%2C%2016%20Dec%202019%2023%3A48%3A18%20GMT/2019-12-16T23%3A48%3A18Z/2019-12-16T23%3A48%3A18Z/1576540098/Mon%2C%2016%20Dec%202019%2023%3A48%3A18%20GMT/2019-12-16T23%3A48%3A18Z", + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/" - }, - "input": { - "shape": "InputShape", - "payload": "foo" - }, - "name": "OperationName" - }, - "params": { - "foo": "bar" - }, - "serialized": { - "method": "POST", - "body": "bar", - "uri": "/" - } - }, - { - "given": { - "http": { - "method": "POST", - "requestUri": "/" - }, - "input": { - "shape": "InputShape", - "payload": "foo" - }, - "name": "OperationName" - }, - "params": { - }, - "serialized": { - "method": "POST", - "body": "", - "uri": "/" - } - } - ] - }, - { - "description": "Structure payload", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for HttpRequestWithRegexLiteral operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpRequestWithRegexLiteralInput": { + "type": "structure", + "required": [ + "str" + ], + "members": { + "str": { + "shape": "String", + "location": "uri", + "locationName": "str" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonToleratesRegexCharsInSegments", + "given": { + "name": "HttpRequestWithRegexLiteral", + "http": { + "method": "GET", + "requestUri": "/ReDosLiteral/{str}/(a+)+", + "responseCode": 200 + }, + "input": { + "shape": "HttpRequestWithRegexLiteralInput" + } + }, + "description": "Path matching is not broken by regex expressions in literal segments", + "params": { + "str": "abc" + }, + "serialized": { + "method": "GET", + "uri": "/ReDosLiteral/abc/(a+)+", + "body": "" + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "foo": { - "shape": "FooShape" - } - } - }, - "FooShape": { - "locationName": "foo", - "type": "structure", - "members": { - "baz": { - "shape": "BazShape" - } - } - }, - "BazShape": { - "type": "string" - } + { + "description": "Test cases for HttpStringPayload operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "StringPayloadInput": { + "type": "structure", + "members": { + "payload": { + "shape": "String" + } + }, + "payload": "payload" + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonStringPayloadRequest", + "given": { + "name": "HttpStringPayload", + "http": { + "method": "POST", + "requestUri": "/StringPayload", + "responseCode": 200 + }, + "input": { + "shape": "StringPayloadInput" + } + }, + "params": { + "payload": "rawstring" + }, + "serialized": { + "method": "POST", + "uri": "/StringPayload", + "body": "rawstring" + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/" - }, - "input": { - "shape": "InputShape", - "payload": "foo" - }, - "name": "OperationName" - }, - "params": { - "foo": { - "baz": "bar" - } - }, - "serialized": { - "method": "POST", - "body": "{\"baz\": \"bar\"}", - "uri": "/" - } - }, - { - "given": { - "http": { - "method": "POST", - "requestUri": "/" - }, - "input": { - "shape": "InputShape", - "payload": "foo" - }, - "name": "OperationName" - }, - "params": {}, - "serialized": { - "method": "POST", - "body": "{}", - "uri": "/" - } - } - ] - }, - { - "description": "Omits null query params, but serializes empty strings", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for InputAndOutputWithHeaders operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "InputAndOutputWithHeadersIO": { + "type": "structure", + "members": { + "headerString": { + "shape": "String", + "location": "header", + "locationName": "X-String" + }, + "headerByte": { + "shape": "Integer", + "location": "header", + "locationName": "X-Byte" + }, + "headerShort": { + "shape": "Integer", + "location": "header", + "locationName": "X-Short" + }, + "headerInteger": { + "shape": "Integer", + "location": "header", + "locationName": "X-Integer" + }, + "headerLong": { + "shape": "Long", + "location": "header", + "locationName": "X-Long" + }, + "headerFloat": { + "shape": "Float", + "location": "header", + "locationName": "X-Float" + }, + "headerDouble": { + "shape": "Double", + "location": "header", + "locationName": "X-Double" + }, + "headerTrueBool": { + "shape": "Boolean", + "location": "header", + "locationName": "X-Boolean1" + }, + "headerFalseBool": { + "shape": "Boolean", + "location": "header", + "locationName": "X-Boolean2" + }, + "headerStringList": { + "shape": "StringList", + "location": "header", + "locationName": "X-StringList" + }, + "headerStringSet": { + "shape": "StringSet", + "location": "header", + "locationName": "X-StringSet" + }, + "headerIntegerList": { + "shape": "IntegerList", + "location": "header", + "locationName": "X-IntegerList" + }, + "headerBooleanList": { + "shape": "BooleanList", + "location": "header", + "locationName": "X-BooleanList" + }, + "headerTimestampList": { + "shape": "TimestampList", + "location": "header", + "locationName": "X-TimestampList" + }, + "headerEnum": { + "shape": "FooEnum", + "location": "header", + "locationName": "X-Enum" + }, + "headerEnumList": { + "shape": "FooEnumList", + "location": "header", + "locationName": "X-EnumList" + }, + "headerIntegerEnum": { + "shape": "IntegerEnum", + "location": "header", + "locationName": "X-IntegerEnum" + }, + "headerIntegerEnumList": { + "shape": "IntegerEnumList", + "location": "header", + "locationName": "X-IntegerEnumList" + } + } + }, + "String": { + "type": "string" + }, + "Integer": { + "type": "integer", + "box": true + }, + "Long": { + "type": "long", + "box": true + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringSet": { + "type": "list", + "member": { + "shape": "String" + } + }, + "IntegerList": { + "type": "list", + "member": { + "shape": "Integer" + } + }, + "BooleanList": { + "type": "list", + "member": { + "shape": "Boolean" + } + }, + "TimestampList": { + "type": "list", + "member": { + "shape": "Timestamp" + } + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "IntegerEnumList": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "Timestamp": { + "type": "timestamp" + } + }, + "cases": [ + { + "id": "RestJsonInputAndOutputWithStringHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "input": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Tests requests with string header bindings", + "params": { + "headerString": "Hello", + "headerStringList": [ + "a", + "b", + "c" + ], + "headerStringSet": [ + "a", + "b", + "c" + ] + }, + "serialized": { + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "body": "", + "headers": { + "X-String": "Hello", + "X-StringList": "a, b, c", + "X-StringSet": "a, b, c" + } + } + }, + { + "id": "RestJsonInputAndOutputWithQuotedStringHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "input": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Tests requests with string list header bindings that require quoting", + "params": { + "headerStringList": [ + "b,c", + "\"def\"", + "a" + ] + }, + "serialized": { + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "body": "", + "headers": { + "X-StringList": "\"b,c\", \"\\\"def\\\"\", a" + } + } + }, + { + "id": "RestJsonInputAndOutputWithNumericHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "input": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Tests requests with numeric header bindings", + "params": { + "headerByte": 1, + "headerShort": 123, + "headerInteger": 123, + "headerLong": 123, + "headerFloat": 1.1, + "headerDouble": 1.1, + "headerIntegerList": [ + 1, + 2, + 3 + ] + }, + "serialized": { + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "body": "", + "headers": { + "X-Byte": "1", + "X-Double": "1.1", + "X-Float": "1.1", + "X-Integer": "123", + "X-IntegerList": "1, 2, 3", + "X-Long": "123", + "X-Short": "123" + } + } + }, + { + "id": "RestJsonInputAndOutputWithBooleanHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "input": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Tests requests with boolean header bindings", + "params": { + "headerTrueBool": true, + "headerFalseBool": false, + "headerBooleanList": [ + true, + false, + true + ] + }, + "serialized": { + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "body": "", + "headers": { + "X-Boolean1": "true", + "X-Boolean2": "false", + "X-BooleanList": "true, false, true" + } + } + }, + { + "id": "RestJsonInputAndOutputWithTimestampHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "input": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Tests requests with timestamp header bindings", + "params": { + "headerTimestampList": [ + 1576540098, + 1576540098 + ] + }, + "serialized": { + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "body": "", + "headers": { + "X-TimestampList": "Mon, 16 Dec 2019 23:48:18 GMT, Mon, 16 Dec 2019 23:48:18 GMT" + } + } + }, + { + "id": "RestJsonInputAndOutputWithEnumHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "input": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Tests requests with enum header bindings", + "params": { + "headerEnum": "Foo", + "headerEnumList": [ + "Foo", + "Bar", + "Baz" + ] + }, + "serialized": { + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "body": "", + "headers": { + "X-Enum": "Foo", + "X-EnumList": "Foo, Bar, Baz" + } + } + }, + { + "id": "RestJsonInputAndOutputWithIntEnumHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "input": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Tests requests with intEnum header bindings", + "params": { + "headerIntegerEnum": 1, + "headerIntegerEnumList": [ + 1, + 2, + 3 + ] + }, + "serialized": { + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "body": "", + "headers": { + "X-IntegerEnum": "1", + "X-IntegerEnumList": "1, 2, 3" + } + } + }, + { + "id": "RestJsonSupportsNaNFloatHeaderInputs", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "input": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Supports handling NaN float header values.", + "params": { + "headerFloat": "NaN", + "headerDouble": "NaN" + }, + "serialized": { + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "body": "", + "headers": { + "X-Double": "NaN", + "X-Float": "NaN" + } + } + }, + { + "id": "RestJsonSupportsInfinityFloatHeaderInputs", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "input": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Supports handling Infinity float header values.", + "params": { + "headerFloat": "Infinity", + "headerDouble": "Infinity" + }, + "serialized": { + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "body": "", + "headers": { + "X-Double": "Infinity", + "X-Float": "Infinity" + } + } + }, + { + "id": "RestJsonSupportsNegativeInfinityFloatHeaderInputs", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "input": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Supports handling -Infinity float header values.", + "params": { + "headerFloat": "-Infinity", + "headerDouble": "-Infinity" + }, + "serialized": { + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "body": "", + "headers": { + "X-Double": "-Infinity", + "X-Float": "-Infinity" + } + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "foo": { - "location":"querystring", - "locationName":"param-name", - "shape": "Foo" - } - } - }, - "Foo": { - "type": "string" - } + { + "description": "Test cases for JsonBlobs operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "JsonBlobsInputOutput": { + "type": "structure", + "members": { + "data": { + "shape": "Blob" + } + } + }, + "Blob": { + "type": "blob" + } + }, + "cases": [ + { + "id": "RestJsonJsonBlobs", + "given": { + "name": "JsonBlobs", + "http": { + "method": "POST", + "requestUri": "/JsonBlobs", + "responseCode": 200 + }, + "input": { + "shape": "JsonBlobsInputOutput" + }, + "documentation": "

Blobs are base64 encoded

" + }, + "description": "Blobs are base64 encoded", + "params": { + "data": "value" + }, + "serialized": { + "method": "POST", + "uri": "/JsonBlobs", + "body": "{\n \"data\": \"dmFsdWU=\"\n}", + "headers": { + "Content-Type": "application/json" + } + } + } + ] }, - "cases": [ - { - "given": { - "name": "OperationName", - "http": { - "method": "POST", - "requestUri": "/path" - }, - "input": { "shape": "InputShape" } - }, - "params": { "foo": null }, - "serialized": { - "method": "POST", - "body": "", - "uri": "/path" - } - }, - { - "given": { - "name": "OperationName", - "http": { - "method": "POST", - "requestUri": "/path?abc=mno" - }, - "input": { "shape": "InputShape" } - }, - "params": { "foo": "" }, - "serialized": { - "method": "POST", - "body": "", - "uri": "/path?abc=mno¶m-name=" - } - } - ] - }, - { - "description": "Recursive shapes", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for JsonEnums operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "JsonEnumsInputOutput": { + "type": "structure", + "members": { + "fooEnum1": { + "shape": "FooEnum" + }, + "fooEnum2": { + "shape": "FooEnum" + }, + "fooEnum3": { + "shape": "FooEnum" + }, + "fooEnumList": { + "shape": "FooEnumList" + }, + "fooEnumSet": { + "shape": "FooEnumSet" + }, + "fooEnumMap": { + "shape": "FooEnumMap" + } + } + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "FooEnumSet": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "FooEnumMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "FooEnum" + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonJsonEnums", + "given": { + "name": "JsonEnums", + "http": { + "method": "PUT", + "requestUri": "/JsonEnums", + "responseCode": 200 + }, + "input": { + "shape": "JsonEnumsInputOutput" + }, + "documentation": "

This example serializes enums as top level properties, in lists, sets, and maps.

", + "idempotent": true + }, + "description": "Serializes simple scalar properties", + "params": { + "fooEnum1": "Foo", + "fooEnum2": "0", + "fooEnum3": "1", + "fooEnumList": [ + "Foo", + "0" + ], + "fooEnumSet": [ + "Foo", + "0" + ], + "fooEnumMap": { + "hi": "Foo", + "zero": "0" + } + }, + "serialized": { + "method": "PUT", + "uri": "/JsonEnums", + "body": "{\n \"fooEnum1\": \"Foo\",\n \"fooEnum2\": \"0\",\n \"fooEnum3\": \"1\",\n \"fooEnumList\": [\n \"Foo\",\n \"0\"\n ],\n \"fooEnumSet\": [\n \"Foo\",\n \"0\"\n ],\n \"fooEnumMap\": {\n \"hi\": \"Foo\",\n \"zero\": \"0\"\n }\n}", + "headers": { + "Content-Type": "application/json" + } + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "RecursiveStruct": { - "shape": "RecursiveStructType" - } - } - }, - "RecursiveStructType": { - "type": "structure", - "members": { - "NoRecurse": { - "shape": "StringType" - }, - "RecursiveStruct": { - "shape": "RecursiveStructType" - }, - "RecursiveList": { - "shape": "RecursiveListType" - }, - "RecursiveMap": { - "shape": "RecursiveMapType" - } - } - }, - "RecursiveListType": { - "type": "list", - "member": { - "shape": "RecursiveStructType" - } - }, - "RecursiveMapType": { - "type": "map", - "key": { - "shape": "StringType" - }, - "value": { - "shape": "RecursiveStructType" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for JsonIntEnums operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "JsonIntEnumsInputOutput": { + "type": "structure", + "members": { + "integerEnum1": { + "shape": "IntegerEnum" + }, + "integerEnum2": { + "shape": "IntegerEnum" + }, + "integerEnum3": { + "shape": "IntegerEnum" + }, + "integerEnumList": { + "shape": "IntegerEnumList" + }, + "integerEnumSet": { + "shape": "IntegerEnumSet" + }, + "integerEnumMap": { + "shape": "IntegerEnumMap" + } + } + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "IntegerEnumList": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "IntegerEnumSet": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "IntegerEnumMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "IntegerEnum" + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonJsonIntEnums", + "given": { + "name": "JsonIntEnums", + "http": { + "method": "PUT", + "requestUri": "/JsonIntEnums", + "responseCode": 200 + }, + "input": { + "shape": "JsonIntEnumsInputOutput" + }, + "documentation": "

This example serializes intEnums as top level properties, in lists, sets, and maps.

", + "idempotent": true + }, + "description": "Serializes intEnums as integers", + "params": { + "integerEnum1": 1, + "integerEnum2": 2, + "integerEnum3": 3, + "integerEnumList": [ + 1, + 2, + 3 + ], + "integerEnumSet": [ + 1, + 2 + ], + "integerEnumMap": { + "abc": 1, + "def": 2 + } + }, + "serialized": { + "method": "PUT", + "uri": "/JsonIntEnums", + "body": "{\n \"integerEnum1\": 1,\n \"integerEnum2\": 2,\n \"integerEnum3\": 3,\n \"integerEnumList\": [\n 1,\n 2,\n 3\n ],\n \"integerEnumSet\": [\n 1,\n 2\n ],\n \"integerEnumMap\": {\n \"abc\": 1,\n \"def\": 2\n }\n}", + "headers": { + "Content-Type": "application/json" + } + } + } + ] }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "http": { - "method": "POST", - "requestUri": "/path" - }, - "name": "OperationName" - }, - "params": { - "RecursiveStruct": { - "NoRecurse": "foo" - } - }, - "serialized": { - "uri": "/path" , - "headers": {}, - "body": "{\"RecursiveStruct\": {\"NoRecurse\": \"foo\"}}" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "http": { - "method": "POST", - "requestUri": "/path" - }, - "name": "OperationName" - }, - "params": { - "RecursiveStruct": { - "RecursiveStruct": { - "NoRecurse": "foo" - } - } - }, - "serialized": { - "uri": "/path", - "headers": {}, - "body": "{\"RecursiveStruct\": {\"RecursiveStruct\": {\"NoRecurse\": \"foo\"}}}" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "http": { - "method": "POST", - "requestUri": "/path" - }, - "name": "OperationName" - }, - "params": { - "RecursiveStruct": { - "RecursiveStruct": { - "RecursiveStruct": { - "RecursiveStruct": { - "NoRecurse": "foo" - } - } - } - } - }, - "serialized": { - "uri": "/path", - "headers": {}, - "body": "{\"RecursiveStruct\": {\"RecursiveStruct\": {\"RecursiveStruct\": {\"RecursiveStruct\": {\"NoRecurse\": \"foo\"}}}}}" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "http": { - "method": "POST", - "requestUri": "/path" - }, - "name": "OperationName" - }, - "params": { - "RecursiveStruct": { - "RecursiveList": [ - { - "NoRecurse": "foo" - }, - { - "NoRecurse": "bar" - } - ] - } - }, - "serialized": { - "uri": "/path", - "headers": {}, - "body": "{\"RecursiveStruct\": {\"RecursiveList\": [{\"NoRecurse\": \"foo\"}, {\"NoRecurse\": \"bar\"}]}}" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "http": { - "method": "POST", - "requestUri": "/path" - }, - "name": "OperationName" - }, - "params": { - "RecursiveStruct": { - "RecursiveList": [ - { - "NoRecurse": "foo" - }, - { - "RecursiveStruct": { - "NoRecurse": "bar" - } - } - ] - } - }, - "serialized": { - "uri": "/path", - "headers": {}, - "body": "{\"RecursiveStruct\": {\"RecursiveList\": [{\"NoRecurse\": \"foo\"}, {\"RecursiveStruct\": {\"NoRecurse\": \"bar\"}}]}}" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "http": { - "method": "POST", - "requestUri": "/path" - }, - "name": "OperationName" - }, - "params": { - "RecursiveStruct": { - "RecursiveMap": { - "foo": { - "NoRecurse": "foo" - }, - "bar": { - "NoRecurse": "bar" - } - } - } - }, - "serialized": { - "uri": "/path", - "headers": {}, - "body": "{\"RecursiveStruct\": {\"RecursiveMap\": {\"foo\": {\"NoRecurse\": \"foo\"}, \"bar\": {\"NoRecurse\": \"bar\"}}}}" - } - } - ] - }, - { - "description": "Timestamp values", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for JsonLists operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "JsonListsInputOutput": { + "type": "structure", + "members": { + "stringList": { + "shape": "StringList" + }, + "stringSet": { + "shape": "StringSet" + }, + "integerList": { + "shape": "IntegerList" + }, + "booleanList": { + "shape": "BooleanList" + }, + "timestampList": { + "shape": "TimestampList" + }, + "enumList": { + "shape": "FooEnumList" + }, + "intEnumList": { + "shape": "IntegerEnumList" + }, + "nestedStringList": { + "shape": "NestedStringList" + }, + "structureList": { + "shape": "StructureList", + "locationName": "myStructureList" + } + } + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringSet": { + "type": "list", + "member": { + "shape": "String" + } + }, + "IntegerList": { + "type": "list", + "member": { + "shape": "Integer" + } + }, + "BooleanList": { + "type": "list", + "member": { + "shape": "Boolean" + } + }, + "TimestampList": { + "type": "list", + "member": { + "shape": "Timestamp" + } + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "IntegerEnumList": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "NestedStringList": { + "type": "list", + "member": { + "shape": "StringList" + }, + "documentation": "

A list of lists of strings.

" + }, + "StructureList": { + "type": "list", + "member": { + "shape": "StructureListMember" + } + }, + "StructureListMember": { + "type": "structure", + "members": { + "a": { + "shape": "String", + "locationName": "value" + }, + "b": { + "shape": "String", + "locationName": "other" + } + } + }, + "String": { + "type": "string" + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "Timestamp": { + "type": "timestamp" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + } + }, + "cases": [ + { + "id": "RestJsonLists", + "given": { + "name": "JsonLists", + "http": { + "method": "PUT", + "requestUri": "/JsonLists", + "responseCode": 200 + }, + "input": { + "shape": "JsonListsInputOutput" + }, + "documentation": "

This test case serializes JSON lists for the following cases for both input and output:

  1. Normal JSON lists.
  2. Normal JSON sets.
  3. JSON lists of lists.
  4. Lists of structures.
", + "idempotent": true + }, + "description": "Serializes JSON lists", + "params": { + "stringList": [ + "foo", + "bar" + ], + "stringSet": [ + "foo", + "bar" + ], + "integerList": [ + 1, + 2 + ], + "booleanList": [ + true, + false + ], + "timestampList": [ + 1398796238, + 1398796238 + ], + "enumList": [ + "Foo", + "0" + ], + "intEnumList": [ + 1, + 2 + ], + "nestedStringList": [ + [ + "foo", + "bar" + ], + [ + "baz", + "qux" + ] + ], + "structureList": [ + { + "a": "1", + "b": "2" + }, + { + "a": "3", + "b": "4" + } + ] + }, + "serialized": { + "method": "PUT", + "uri": "/JsonLists", + "body": "{\n \"stringList\": [\n \"foo\",\n \"bar\"\n ],\n \"stringSet\": [\n \"foo\",\n \"bar\"\n ],\n \"integerList\": [\n 1,\n 2\n ],\n \"booleanList\": [\n true,\n false\n ],\n \"timestampList\": [\n 1398796238,\n 1398796238\n ],\n \"enumList\": [\n \"Foo\",\n \"0\"\n ],\n \"intEnumList\": [\n 1,\n 2\n ],\n \"nestedStringList\": [\n [\n \"foo\",\n \"bar\"\n ],\n [\n \"baz\",\n \"qux\"\n ]\n ],\n \"myStructureList\": [\n {\n \"value\": \"1\",\n \"other\": \"2\"\n },\n {\n \"value\": \"3\",\n \"other\": \"4\"\n }\n ]\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "RestJsonListsEmpty", + "given": { + "name": "JsonLists", + "http": { + "method": "PUT", + "requestUri": "/JsonLists", + "responseCode": 200 + }, + "input": { + "shape": "JsonListsInputOutput" + }, + "documentation": "

This test case serializes JSON lists for the following cases for both input and output:

  1. Normal JSON lists.
  2. Normal JSON sets.
  3. JSON lists of lists.
  4. Lists of structures.
", + "idempotent": true + }, + "description": "Serializes empty JSON lists", + "params": { + "stringList": [] + }, + "serialized": { + "method": "PUT", + "uri": "/JsonLists", + "body": "{\n \"stringList\": []\n}", + "headers": { + "Content-Type": "application/json" + } + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "TimeArg": { - "shape": "TimestampType" - }, - "TimeArgInHeader": { - "shape": "TimestampType", - "location": "header", - "locationName": "x-amz-timearg" - }, - "TimeArgInQuery": { - "shape": "TimestampType", - "location": "querystring", - "locationName": "TimeQuery" - }, - "TimeCustom": { - "timestampFormat": "iso8601", - "shape": "TimestampType" - }, - "TimeCustomInHeader": { - "timestampFormat": "unixTimestamp", - "shape": "TimestampType", - "location": "header", - "locationName": "x-amz-timecustom-header" - }, - "TimeCustomInQuery": { - "timestampFormat": "unixTimestamp", - "shape": "TimestampType", - "location": "querystring", - "locationName": "TimeCustomQuery" - }, - "TimeFormat": { - "shape": "TimestampFormatRfcType" - }, - "TimeFormatInHeader": { - "shape": "TimestampFormatUnixType", - "location": "header", - "locationName": "x-amz-timeformat-header" - }, - "TimeFormatInQuery": { - "shape": "TimestampFormatUnixType", - "location": "querystring", - "locationName": "TimeFormatQuery" - } - } - }, - "TimestampFormatRfcType": { - "timestampFormat": "rfc822", - "type": "timestamp" - }, - "TimestampFormatUnixType": { - "timestampFormat": "unixTimestamp", - "type": "timestamp" - }, - "TimestampType": { - "type": "timestamp" - } + { + "description": "Test cases for JsonMaps operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "JsonMapsInputOutput": { + "type": "structure", + "members": { + "denseStructMap": { + "shape": "DenseStructMap" + }, + "denseNumberMap": { + "shape": "DenseNumberMap" + }, + "denseBooleanMap": { + "shape": "DenseBooleanMap" + }, + "denseStringMap": { + "shape": "DenseStringMap" + }, + "denseSetMap": { + "shape": "DenseSetMap" + } + } + }, + "DenseStructMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "GreetingStruct" + } + }, + "DenseNumberMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "Integer" + } + }, + "DenseBooleanMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "Boolean" + } + }, + "DenseStringMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "String" + } + }, + "DenseSetMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "StringSet" + } + }, + "StringSet": { + "type": "list", + "member": { + "shape": "String" + } + }, + "String": { + "type": "string" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + }, + "GreetingStruct": { + "type": "structure", + "members": { + "hi": { + "shape": "String" + } + } + } + }, + "cases": [ + { + "id": "RestJsonJsonMaps", + "given": { + "name": "JsonMaps", + "http": { + "method": "POST", + "requestUri": "/JsonMaps", + "responseCode": 200 + }, + "input": { + "shape": "JsonMapsInputOutput" + }, + "documentation": "

The example tests basic map serialization.

" + }, + "description": "Serializes JSON maps", + "params": { + "denseStructMap": { + "foo": { + "hi": "there" + }, + "baz": { + "hi": "bye" + } + } + }, + "serialized": { + "method": "POST", + "uri": "/JsonMaps", + "body": "{\n \"denseStructMap\": {\n \"foo\": {\n \"hi\": \"there\"\n },\n \"baz\": {\n \"hi\": \"bye\"\n }\n }\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "RestJsonSerializesZeroValuesInMaps", + "given": { + "name": "JsonMaps", + "http": { + "method": "POST", + "requestUri": "/JsonMaps", + "responseCode": 200 + }, + "input": { + "shape": "JsonMapsInputOutput" + }, + "documentation": "

The example tests basic map serialization.

" + }, + "description": "Ensure that 0 and false are sent over the wire in all maps and lists", + "params": { + "denseNumberMap": { + "x": 0 + }, + "denseBooleanMap": { + "x": false + } + }, + "serialized": { + "method": "POST", + "uri": "/JsonMaps", + "body": "{\n \"denseNumberMap\": {\n \"x\": 0\n },\n \"denseBooleanMap\": {\n \"x\": false\n }\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "RestJsonSerializesDenseSetMap", + "given": { + "name": "JsonMaps", + "http": { + "method": "POST", + "requestUri": "/JsonMaps", + "responseCode": 200 + }, + "input": { + "shape": "JsonMapsInputOutput" + }, + "documentation": "

The example tests basic map serialization.

" + }, + "description": "A request that contains a dense map of sets.", + "params": { + "denseSetMap": { + "x": [], + "y": [ + "a", + "b" + ] + } + }, + "serialized": { + "method": "POST", + "uri": "/JsonMaps", + "body": "{\n \"denseSetMap\": {\n \"x\": [],\n \"y\": [\"a\", \"b\"]\n }\n}", + "headers": { + "Content-Type": "application/json" + } + } + } + ] }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "http": { - "method": "POST", - "requestUri": "/path" - }, - "name": "OperationName" - }, - "params": { - "TimeArg": 1422172800, - "TimeArgInQuery": 1422172800, - "TimeArgInHeader": 1422172800, - "TimeCustom": 1422172800, - "TimeCustomInQuery": 1422172800, - "TimeCustomInHeader": 1422172800, - "TimeFormat": 1422172800, - "TimeFormatInQuery": 1422172800, - "TimeFormatInHeader": 1422172800 - }, - "serialized": { - "uri": "/path?TimeQuery=2015-01-25T08%3A00%3A00Z&TimeCustomQuery=1422172800&TimeFormatQuery=1422172800", - "headers": { - "x-amz-timearg": "Sun, 25 Jan 2015 08:00:00 GMT", - "x-amz-timecustom-header": "1422172800", - "x-amz-timeformat-header": "1422172800" - }, - "body": "{\"TimeArg\": 1422172800, \"TimeCustom\": \"2015-01-25T08:00:00Z\", \"TimeFormat\": \"Sun, 25 Jan 2015 08:00:00 GMT\"}" - } - } - ] - }, - { - "description": "Named locations in JSON body", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for JsonTimestamps operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "JsonTimestampsInputOutput": { + "type": "structure", + "members": { + "normal": { + "shape": "Timestamp" + }, + "dateTime": { + "shape": "SyntheticTimestamp_date_time" + }, + "dateTimeOnTarget": { + "shape": "DateTime" + }, + "epochSeconds": { + "shape": "SyntheticTimestamp_epoch_seconds" + }, + "epochSecondsOnTarget": { + "shape": "EpochSeconds" + }, + "httpDate": { + "shape": "SyntheticTimestamp_http_date" + }, + "httpDateOnTarget": { + "shape": "HttpDate" + } + } + }, + "Timestamp": { + "type": "timestamp" + }, + "SyntheticTimestamp_date_time": { + "type": "timestamp", + "timestampFormat": "iso8601" + }, + "DateTime": { + "type": "timestamp", + "timestampFormat": "iso8601" + }, + "SyntheticTimestamp_epoch_seconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "EpochSeconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "SyntheticTimestamp_http_date": { + "type": "timestamp", + "timestampFormat": "rfc822" + }, + "HttpDate": { + "type": "timestamp", + "timestampFormat": "rfc822" + } + }, + "cases": [ + { + "id": "RestJsonJsonTimestamps", + "given": { + "name": "JsonTimestamps", + "http": { + "method": "POST", + "requestUri": "/JsonTimestamps", + "responseCode": 200 + }, + "input": { + "shape": "JsonTimestampsInputOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Tests how normal timestamps are serialized", + "params": { + "normal": 1398796238 + }, + "serialized": { + "method": "POST", + "uri": "/JsonTimestamps", + "body": "{\n \"normal\": 1398796238\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "RestJsonJsonTimestampsWithDateTimeFormat", + "given": { + "name": "JsonTimestamps", + "http": { + "method": "POST", + "requestUri": "/JsonTimestamps", + "responseCode": 200 + }, + "input": { + "shape": "JsonTimestampsInputOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of date-time works like normal timestamps", + "params": { + "dateTime": 1398796238 + }, + "serialized": { + "method": "POST", + "uri": "/JsonTimestamps", + "body": "{\n \"dateTime\": \"2014-04-29T18:30:38Z\"\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "RestJsonJsonTimestampsWithDateTimeOnTargetFormat", + "given": { + "name": "JsonTimestamps", + "http": { + "method": "POST", + "requestUri": "/JsonTimestamps", + "responseCode": 200 + }, + "input": { + "shape": "JsonTimestampsInputOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of date-time on the target shape works like normal timestamps", + "params": { + "dateTimeOnTarget": 1398796238 + }, + "serialized": { + "method": "POST", + "uri": "/JsonTimestamps", + "body": "{\n \"dateTimeOnTarget\": \"2014-04-29T18:30:38Z\"\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "RestJsonJsonTimestampsWithEpochSecondsFormat", + "given": { + "name": "JsonTimestamps", + "http": { + "method": "POST", + "requestUri": "/JsonTimestamps", + "responseCode": 200 + }, + "input": { + "shape": "JsonTimestampsInputOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of epoch-seconds works", + "params": { + "epochSeconds": 1398796238 + }, + "serialized": { + "method": "POST", + "uri": "/JsonTimestamps", + "body": "{\n \"epochSeconds\": 1398796238\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "RestJsonJsonTimestampsWithEpochSecondsOnTargetFormat", + "given": { + "name": "JsonTimestamps", + "http": { + "method": "POST", + "requestUri": "/JsonTimestamps", + "responseCode": 200 + }, + "input": { + "shape": "JsonTimestampsInputOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of epoch-seconds on the target shape works", + "params": { + "epochSecondsOnTarget": 1398796238 + }, + "serialized": { + "method": "POST", + "uri": "/JsonTimestamps", + "body": "{\n \"epochSecondsOnTarget\": 1398796238\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "RestJsonJsonTimestampsWithHttpDateFormat", + "given": { + "name": "JsonTimestamps", + "http": { + "method": "POST", + "requestUri": "/JsonTimestamps", + "responseCode": 200 + }, + "input": { + "shape": "JsonTimestampsInputOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of http-date works", + "params": { + "httpDate": 1398796238 + }, + "serialized": { + "method": "POST", + "uri": "/JsonTimestamps", + "body": "{\n \"httpDate\": \"Tue, 29 Apr 2014 18:30:38 GMT\"\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "RestJsonJsonTimestampsWithHttpDateOnTargetFormat", + "given": { + "name": "JsonTimestamps", + "http": { + "method": "POST", + "requestUri": "/JsonTimestamps", + "responseCode": 200 + }, + "input": { + "shape": "JsonTimestampsInputOutput" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of http-date on the target shape works", + "params": { + "httpDateOnTarget": 1398796238 + }, + "serialized": { + "method": "POST", + "uri": "/JsonTimestamps", + "body": "{\n \"httpDateOnTarget\": \"Tue, 29 Apr 2014 18:30:38 GMT\"\n}", + "headers": { + "Content-Type": "application/json" + } + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "TimeArg": { - "shape": "TimestampType", - "locationName": "timestamp_location" - } - } - }, - "TimestampType": { - "type": "timestamp" - } + { + "description": "Test cases for JsonUnions operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "UnionInputOutput": { + "type": "structure", + "members": { + "contents": { + "shape": "MyUnion" + } + }, + "documentation": "

A shared structure that contains a single union member.

" + }, + "MyUnion": { + "type": "structure", + "members": { + "stringValue": { + "shape": "String" + }, + "booleanValue": { + "shape": "Boolean" + }, + "numberValue": { + "shape": "Integer" + }, + "blobValue": { + "shape": "Blob" + }, + "timestampValue": { + "shape": "Timestamp" + }, + "enumValue": { + "shape": "FooEnum" + }, + "listValue": { + "shape": "StringList" + }, + "mapValue": { + "shape": "StringMap" + }, + "structureValue": { + "shape": "GreetingStruct" + }, + "renamedStructureValue": { + "shape": "RenamedGreeting" + } + }, + "documentation": "

A union with a representative set of types for members.

", + "union": true + }, + "String": { + "type": "string" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + }, + "Blob": { + "type": "blob" + }, + "Timestamp": { + "type": "timestamp" + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "String" + } + }, + "GreetingStruct": { + "type": "structure", + "members": { + "hi": { + "shape": "String" + } + } + }, + "RenamedGreeting": { + "type": "structure", + "members": { + "salutation": { + "shape": "String" + } + } + } + }, + "cases": [ + { + "id": "RestJsonSerializeStringUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "input": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes a string union value", + "params": { + "contents": { + "stringValue": "foo" + } + }, + "serialized": { + "method": "PUT", + "uri": "/JsonUnions", + "body": "{\n \"contents\": {\n \"stringValue\": \"foo\"\n }\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "RestJsonSerializeBooleanUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "input": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes a boolean union value", + "params": { + "contents": { + "booleanValue": true + } + }, + "serialized": { + "method": "PUT", + "uri": "/JsonUnions", + "body": "{\n \"contents\": {\n \"booleanValue\": true\n }\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "RestJsonSerializeNumberUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "input": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes a number union value", + "params": { + "contents": { + "numberValue": 1 + } + }, + "serialized": { + "method": "PUT", + "uri": "/JsonUnions", + "body": "{\n \"contents\": {\n \"numberValue\": 1\n }\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "RestJsonSerializeBlobUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "input": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes a blob union value", + "params": { + "contents": { + "blobValue": "foo" + } + }, + "serialized": { + "method": "PUT", + "uri": "/JsonUnions", + "body": "{\n \"contents\": {\n \"blobValue\": \"Zm9v\"\n }\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "RestJsonSerializeTimestampUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "input": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes a timestamp union value", + "params": { + "contents": { + "timestampValue": 1398796238 + } + }, + "serialized": { + "method": "PUT", + "uri": "/JsonUnions", + "body": "{\n \"contents\": {\n \"timestampValue\": 1398796238\n }\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "RestJsonSerializeEnumUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "input": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes an enum union value", + "params": { + "contents": { + "enumValue": "Foo" + } + }, + "serialized": { + "method": "PUT", + "uri": "/JsonUnions", + "body": "{\n \"contents\": {\n \"enumValue\": \"Foo\"\n }\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "RestJsonSerializeListUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "input": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes a list union value", + "params": { + "contents": { + "listValue": [ + "foo", + "bar" + ] + } + }, + "serialized": { + "method": "PUT", + "uri": "/JsonUnions", + "body": "{\n \"contents\": {\n \"listValue\": [\"foo\", \"bar\"]\n }\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "RestJsonSerializeMapUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "input": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes a map union value", + "params": { + "contents": { + "mapValue": { + "foo": "bar", + "spam": "eggs" + } + } + }, + "serialized": { + "method": "PUT", + "uri": "/JsonUnions", + "body": "{\n \"contents\": {\n \"mapValue\": {\n \"foo\": \"bar\",\n \"spam\": \"eggs\"\n }\n }\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "RestJsonSerializeStructureUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "input": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes a structure union value", + "params": { + "contents": { + "structureValue": { + "hi": "hello" + } + } + }, + "serialized": { + "method": "PUT", + "uri": "/JsonUnions", + "body": "{\n \"contents\": {\n \"structureValue\": {\n \"hi\": \"hello\"\n }\n }\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "RestJsonSerializeRenamedStructureUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "input": { + "shape": "UnionInputOutput" + }, + "documentation": "

This operation uses unions for inputs and outputs.

", + "idempotent": true + }, + "description": "Serializes a renamed structure union value", + "params": { + "contents": { + "renamedStructureValue": { + "salutation": "hello!" + } + } + }, + "serialized": { + "method": "PUT", + "uri": "/JsonUnions", + "body": "{\n \"contents\": {\n \"renamedStructureValue\": {\n \"salutation\": \"hello!\"\n }\n }\n}", + "headers": { + "Content-Type": "application/json" + } + } + } + ] }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "http": { - "method": "POST", - "requestUri": "/path" - }, - "name": "OperationName" - }, - "params": { - "TimeArg": 1422172800 - }, - "serialized": { - "uri": "/path", - "headers": {}, - "body": "{\"timestamp_location\": 1422172800}" - } - } - ] - }, - { - "description": "String payload", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for MediaTypeHeader operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "MediaTypeHeaderInput": { + "type": "structure", + "members": { + "json": { + "shape": "JsonValue", + "jsonvalue": true, + "location": "header", + "locationName": "X-Json" + } + } + }, + "JsonValue": { + "type": "string" + } + }, + "cases": [ + { + "id": "MediaTypeHeaderInputBase64", + "given": { + "name": "MediaTypeHeader", + "http": { + "method": "GET", + "requestUri": "/MediaTypeHeader", + "responseCode": 200 + }, + "input": { + "shape": "MediaTypeHeaderInput" + }, + "documentation": "

This example ensures that mediaType strings are base64 encoded in headers.

" + }, + "description": "Headers that target strings with a mediaType are base64 encoded", + "params": { + "json": "true" + }, + "serialized": { + "method": "GET", + "uri": "/MediaTypeHeader", + "body": "", + "headers": { + "X-Json": "dHJ1ZQ==" + } + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "foo": { - "shape": "FooShape" - } - } - }, - "FooShape": { - "type": "string" - } + { + "description": "Test cases for NoInputAndNoOutput operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": {}, + "cases": [ + { + "id": "RestJsonNoInputAndNoOutput", + "given": { + "name": "NoInputAndNoOutput", + "http": { + "method": "POST", + "requestUri": "/NoInputAndNoOutput", + "responseCode": 200 + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input or output. While this should be rare, code generators must support this.

" + }, + "description": "No input serializes no payload. When clients do not need to\nserialize any data in the payload, they should omit a payload\naltogether.", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/NoInputAndNoOutput", + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/" - }, - "input": { - "shape": "InputShape", - "payload": "foo" - }, - "name": "OperationName" - }, - "params": { - "foo": "bar" - }, - "serialized": { - "method": "POST", - "body": "bar", - "uri": "/" - } - } - ] - }, - { - "description": "Idempotency token auto fill", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for NoInputAndOutput operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": {}, + "cases": [ + { + "id": "RestJsonNoInputAndOutput", + "given": { + "name": "NoInputAndOutput", + "http": { + "method": "POST", + "requestUri": "/NoInputAndOutputOutput", + "responseCode": 200 + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input and the output is empty. While this should be rare, code generators must support this.

" + }, + "description": "No input serializes no payload. When clients do not need to\nserialize any data in the payload, they should omit a payload\naltogether.", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/NoInputAndOutputOutput", + "body": "" + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "Token": { - "shape": "StringType", - "idempotencyToken": true - } - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for NullAndEmptyHeadersClient operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "NullAndEmptyHeadersIO": { + "type": "structure", + "members": { + "a": { + "shape": "String", + "location": "header", + "locationName": "X-A" + }, + "b": { + "shape": "String", + "location": "header", + "locationName": "X-B" + }, + "c": { + "shape": "StringList", + "location": "header", + "locationName": "X-C" + } + } + }, + "String": { + "type": "string" + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + } + }, + "cases": [ + { + "id": "RestJsonNullAndEmptyHeaders", + "given": { + "name": "NullAndEmptyHeadersClient", + "http": { + "method": "GET", + "requestUri": "/NullAndEmptyHeadersClient", + "responseCode": 200 + }, + "input": { + "shape": "NullAndEmptyHeadersIO" + }, + "documentation": "

Null and empty headers are not sent over the wire.

" + }, + "description": "Do not send null values, empty strings, or empty lists over the wire in headers", + "params": { + "a": null, + "b": "", + "c": [] + }, + "serialized": { + "method": "GET", + "uri": "/NullAndEmptyHeadersClient", + "body": "", + "forbidHeaders": [ + "X-A", + "X-B", + "X-C" + ] + } + } + ] }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "http": { - "method": "POST", - "requestUri": "/path" - }, - "name": "OperationName" - }, - "params": { - "Token": "abc123" - }, - "serialized": { - "uri": "/path", - "headers": {}, - "body": "{\"Token\": \"abc123\"}" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "http": { - "method": "POST", - "requestUri": "/path" - }, - "name": "OperationName" - }, - "params": { - }, - "serialized": { - "uri": "/path", - "headers": {}, - "body": "{\"Token\": \"00000000-0000-4000-8000-000000000000\"}" - } - } - ] - }, - { - "description": "JSON value trait", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for OmitsNullSerializesEmptyString operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "OmitsNullSerializesEmptyStringInput": { + "type": "structure", + "members": { + "nullValue": { + "shape": "String", + "location": "querystring", + "locationName": "Null" + }, + "emptyString": { + "shape": "String", + "location": "querystring", + "locationName": "Empty" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonOmitsNullQuery", + "given": { + "name": "OmitsNullSerializesEmptyString", + "http": { + "method": "GET", + "requestUri": "/OmitsNullSerializesEmptyString", + "responseCode": 200 + }, + "input": { + "shape": "OmitsNullSerializesEmptyStringInput" + }, + "documentation": "

Omits null, but serializes empty string value.

" + }, + "description": "Omits null query values", + "params": { + "nullValue": null + }, + "serialized": { + "method": "GET", + "uri": "/OmitsNullSerializesEmptyString", + "body": "" + } + }, + { + "id": "RestJsonSerializesEmptyQueryValue", + "given": { + "name": "OmitsNullSerializesEmptyString", + "http": { + "method": "GET", + "requestUri": "/OmitsNullSerializesEmptyString", + "responseCode": 200 + }, + "input": { + "shape": "OmitsNullSerializesEmptyStringInput" + }, + "documentation": "

Omits null, but serializes empty string value.

" + }, + "description": "Serializes empty query strings", + "params": { + "emptyString": "" + }, + "serialized": { + "method": "GET", + "uri": "/OmitsNullSerializesEmptyString?Empty=", + "body": "" + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "Attr": { - "shape": "StringType", - "jsonvalue": true, - "location": "header", - "locationName": "X-Amz-Foo" - } - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for OmitsSerializingEmptyLists operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "OmitsSerializingEmptyListsInput": { + "type": "structure", + "members": { + "queryStringList": { + "shape": "StringList", + "location": "querystring", + "locationName": "StringList" + }, + "queryIntegerList": { + "shape": "IntegerList", + "location": "querystring", + "locationName": "IntegerList" + }, + "queryDoubleList": { + "shape": "DoubleList", + "location": "querystring", + "locationName": "DoubleList" + }, + "queryBooleanList": { + "shape": "BooleanList", + "location": "querystring", + "locationName": "BooleanList" + }, + "queryTimestampList": { + "shape": "TimestampList", + "location": "querystring", + "locationName": "TimestampList" + }, + "queryEnumList": { + "shape": "FooEnumList", + "location": "querystring", + "locationName": "EnumList" + }, + "queryIntegerEnumList": { + "shape": "IntegerEnumList", + "location": "querystring", + "locationName": "IntegerEnumList" + } + } + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "IntegerList": { + "type": "list", + "member": { + "shape": "Integer" + } + }, + "DoubleList": { + "type": "list", + "member": { + "shape": "Double" + } + }, + "BooleanList": { + "type": "list", + "member": { + "shape": "Boolean" + } + }, + "TimestampList": { + "type": "list", + "member": { + "shape": "Timestamp" + } + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "IntegerEnumList": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "Timestamp": { + "type": "timestamp" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Double": { + "type": "double", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonOmitsEmptyListQueryValues", + "given": { + "name": "OmitsSerializingEmptyLists", + "http": { + "method": "POST", + "requestUri": "/OmitsSerializingEmptyLists", + "responseCode": 200 + }, + "input": { + "shape": "OmitsSerializingEmptyListsInput" + }, + "documentation": "

Omits serializing empty lists. Because empty strings are serilized as Foo=, empty lists cannot also be serialized as Foo= and instead must be omitted.

" + }, + "description": "Supports omitting empty lists.", + "params": { + "queryStringList": [], + "queryIntegerList": [], + "queryDoubleList": [], + "queryBooleanList": [], + "queryTimestampList": [], + "queryEnumList": [], + "queryIntegerEnumList": [] + }, + "serialized": { + "method": "POST", + "uri": "/OmitsSerializingEmptyLists", + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "http": { - "method": "POST", - "requestUri": "/path" - }, - "name": "OperationName" - }, - "params": { - "Attr": {"Foo":"Bar"} - }, - "serialized": { - "uri": "/path", - "headers": {"X-Amz-Foo": "eyJGb28iOiJCYXIifQ=="}, - "body": "" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "http": { - "method": "POST", - "requestUri": "/path" - }, - "name": "OperationName" - }, - "params": { - }, - "serialized": { - "uri": "/path", - "headers": {}, - "body": "" - } - } - ] - }, - { - "description": "Endpoint host trait", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for PostUnionWithJsonName operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "PostUnionWithJsonNameInput": { + "type": "structure", + "members": { + "value": { + "shape": "UnionWithJsonName" + } + } + }, + "UnionWithJsonName": { + "type": "structure", + "members": { + "foo": { + "shape": "String", + "locationName": "FOO" + }, + "bar": { + "shape": "String" + }, + "baz": { + "shape": "String", + "locationName": "_baz" + } + }, + "union": true + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "PostUnionWithJsonNameRequest1", + "given": { + "name": "PostUnionWithJsonName", + "http": { + "method": "POST", + "requestUri": "/PostUnionWithJsonName", + "responseCode": 200 + }, + "input": { + "shape": "PostUnionWithJsonNameInput" + }, + "documentation": "

This operation defines a union that uses jsonName on some members.

" + }, + "description": "Tests that jsonName works with union members.", + "params": { + "value": { + "foo": "hi" + } + }, + "serialized": { + "method": "POST", + "uri": "/PostUnionWithJsonName", + "body": "{\n \"value\": {\n \"FOO\": \"hi\"\n }\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "PostUnionWithJsonNameRequest2", + "given": { + "name": "PostUnionWithJsonName", + "http": { + "method": "POST", + "requestUri": "/PostUnionWithJsonName", + "responseCode": 200 + }, + "input": { + "shape": "PostUnionWithJsonNameInput" + }, + "documentation": "

This operation defines a union that uses jsonName on some members.

" + }, + "description": "Tests that jsonName works with union members.", + "params": { + "value": { + "baz": "hi" + } + }, + "serialized": { + "method": "POST", + "uri": "/PostUnionWithJsonName", + "body": "{\n \"value\": {\n \"_baz\": \"hi\"\n }\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "PostUnionWithJsonNameRequest3", + "given": { + "name": "PostUnionWithJsonName", + "http": { + "method": "POST", + "requestUri": "/PostUnionWithJsonName", + "responseCode": 200 + }, + "input": { + "shape": "PostUnionWithJsonNameInput" + }, + "documentation": "

This operation defines a union that uses jsonName on some members.

" + }, + "description": "Tests that jsonName works with union members.", + "params": { + "value": { + "bar": "hi" + } + }, + "serialized": { + "method": "POST", + "uri": "/PostUnionWithJsonName", + "body": "{\n \"value\": {\n \"bar\": \"hi\"\n }\n}", + "headers": { + "Content-Type": "application/json" + } + } + } + ] }, - "clientEndpoint": "https://service.region.amazonaws.com", - "shapes": { - "StaticInputShape": { - "type": "structure", - "members": { - "Name": { - "shape": "StringType" - } - } - }, - "MemberRefInputShape": { - "type": "structure", - "members": { - "Name": { - "shape": "StringType", - "hostLabel": true - } - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for PutWithContentEncoding operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "PutWithContentEncodingInput": { + "type": "structure", + "members": { + "encoding": { + "shape": "String", + "location": "header", + "locationName": "Content-Encoding" + }, + "data": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "SDKAppliedContentEncoding_restJson1", + "given": { + "name": "PutWithContentEncoding", + "http": { + "method": "POST", + "requestUri": "/requestcompression/putcontentwithencoding", + "responseCode": 200 + }, + "input": { + "shape": "PutWithContentEncodingInput" + }, + "requestcompression": { + "encodings": [ + "gzip" + ] + } + }, + "description": "Compression algorithm encoding is appended to the Content-Encoding header.", + "params": { + "data": "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\n" + }, + "serialized": { + "method": "POST", + "uri": "/requestcompression/putcontentwithencoding", + "headers": { + "Content-Encoding": "gzip" + } + } + }, + { + "id": "SDKAppendedGzipAfterProvidedEncoding_restJson1", + "given": { + "name": "PutWithContentEncoding", + "http": { + "method": "POST", + "requestUri": "/requestcompression/putcontentwithencoding", + "responseCode": 200 + }, + "input": { + "shape": "PutWithContentEncodingInput" + }, + "requestcompression": { + "encodings": [ + "gzip" + ] + } + }, + "description": "Compression algorithm encoding is appended to the Content-Encoding header, and the\nuser-provided content-encoding is in the Content-Encoding header before the\nrequest compression encoding from the HTTP binding.\n", + "params": { + "encoding": "custom", + "data": "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\n" + }, + "serialized": { + "method": "POST", + "uri": "/requestcompression/putcontentwithencoding", + "headers": { + "Content-Encoding": "custom, gzip" + } + } + } + ] }, - "cases": [ - { - "given": { - "name": "StaticOp", - "input": { - "shape": "StaticInputShape" - }, - "http": { - "method": "POST", - "requestUri": "/path" - }, - "endpoint":{ - "hostPrefix": "data-" - } - }, - "params": { - "Name": "myname" - }, - "serialized": { - "uri": "/path", - "body": "{\"Name\": \"myname\"}", - "host": "data-service.region.amazonaws.com" - } - }, - { - "given": { - "name": "MemberRefOp", - "input": { - "shape": "MemberRefInputShape" - }, - "http": { - "method": "GET", - "requestUri": "/path" - }, - "endpoint":{ - "hostPrefix": "foo-{Name}." - } - }, - "params": { - "Name": "myname" - }, - "serialized": { - "uri": "/path", - "body": "{\"Name\": \"myname\"}", - "host": "foo-myname.service.region.amazonaws.com" - } - } - ] - }, - { - "description": "Serializes document with standalone primitive as part of the JSON request payload with no escaping.", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for QueryIdempotencyTokenAutoFill operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "QueryIdempotencyTokenAutoFillInput": { + "type": "structure", + "members": { + "token": { + "shape": "String", + "idempotencyToken": true, + "location": "querystring", + "locationName": "token" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonQueryIdempotencyTokenAutoFill", + "given": { + "name": "QueryIdempotencyTokenAutoFill", + "http": { + "method": "POST", + "requestUri": "/QueryIdempotencyTokenAutoFill", + "responseCode": 200 + }, + "input": { + "shape": "QueryIdempotencyTokenAutoFillInput" + }, + "documentation": "

Automatically adds idempotency tokens.

" + }, + "description": "Automatically adds idempotency token when not set", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/QueryIdempotencyTokenAutoFill?token=00000000-0000-4000-8000-000000000000", + "body": "" + } + }, + { + "id": "RestJsonQueryIdempotencyTokenAutoFillIsSet", + "given": { + "name": "QueryIdempotencyTokenAutoFill", + "http": { + "method": "POST", + "requestUri": "/QueryIdempotencyTokenAutoFill", + "responseCode": 200 + }, + "input": { + "shape": "QueryIdempotencyTokenAutoFillInput" + }, + "documentation": "

Automatically adds idempotency tokens.

" + }, + "description": "Uses the given idempotency token as-is", + "params": { + "token": "00000000-0000-4000-8000-000000000000" + }, + "serialized": { + "method": "POST", + "uri": "/QueryIdempotencyTokenAutoFill?token=00000000-0000-4000-8000-000000000000", + "body": "" + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "documentValue": { - "shape": "DocumentType" - } - } - }, - "DocumentType": { - "type": "structure", - "document": true - } + { + "description": "Test cases for QueryParamsAsStringListMap operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "QueryParamsAsStringListMapInput": { + "type": "structure", + "members": { + "qux": { + "shape": "String", + "location": "querystring", + "locationName": "corge" + }, + "foo": { + "shape": "StringListMap", + "location": "querystring" + } + } + }, + "String": { + "type": "string" + }, + "StringListMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "StringList" + } + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + } + }, + "cases": [ + { + "id": "RestJsonQueryParamsStringListMap", + "given": { + "name": "QueryParamsAsStringListMap", + "http": { + "method": "POST", + "requestUri": "/StringListMap", + "responseCode": 200 + }, + "input": { + "shape": "QueryParamsAsStringListMapInput" + } + }, + "description": "Serialize query params from map of list strings", + "params": { + "qux": "named", + "foo": { + "baz": [ + "bar", + "qux" + ] + } + }, + "serialized": { + "method": "POST", + "uri": "/StringListMap?corge=named&baz=bar&baz=qux", + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/InlineDocument" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "documentValue": "foo" - }, - "serialized": { - "body": "{\"documentValue\": \"foo\"}", - "uri": "/InlineDocument" - } - }, - { - "given": { - "http": { - "method": "POST", - "requestUri": "/InlineDocument" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "documentValue": 123 - }, - "serialized": { - "body": "{\"documentValue\": 123}", - "uri": "/InlineDocument" - } - }, - { - "given": { - "http": { - "method": "POST", - "requestUri": "/InlineDocument" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "documentValue": 1.2 - }, - "serialized": { - "body": "{\"documentValue\": 1.2}", - "uri": "/InlineDocument" - } - }, - { - "given": { - "http": { - "method": "POST", - "requestUri": "/InlineDocument" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "documentValue": true - }, - "serialized": { - "body": "{\"documentValue\": true}", - "uri": "/InlineDocument" - } - }, - { - "given": { - "http": { - "method": "POST", - "requestUri": "/InlineDocument" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "documentValue": "" - }, - "serialized": { - "body": "{\"documentValue\": \"\"}", - "uri": "/InlineDocument" - } - } - ] - }, - { - "description": "Serializes inline documents as part of the JSON request payload with no escaping.", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for QueryPrecedence operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "QueryPrecedenceInput": { + "type": "structure", + "members": { + "foo": { + "shape": "String", + "location": "querystring", + "locationName": "bar" + }, + "baz": { + "shape": "StringMap", + "location": "querystring" + } + } + }, + "String": { + "type": "string" + }, + "StringMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "String" + } + } + }, + "cases": [ + { + "id": "RestJsonQueryPrecedence", + "given": { + "name": "QueryPrecedence", + "http": { + "method": "POST", + "requestUri": "/Precedence", + "responseCode": 200 + }, + "input": { + "shape": "QueryPrecedenceInput" + } + }, + "description": "Prefer named query parameters when serializing", + "params": { + "foo": "named", + "baz": { + "bar": "fromMap", + "qux": "alsoFromMap" + } + }, + "serialized": { + "method": "POST", + "uri": "/Precedence?bar=named&qux=alsoFromMap", + "body": "" + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "documentValue": { - "shape": "DocumentType" - } - } - }, - "DocumentType": { - "type": "structure", - "document": true - } + { + "description": "Test cases for RecursiveShapes operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "RecursiveShapesInputOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "RecursiveShapesInputOutputNested1" + } + } + }, + "RecursiveShapesInputOutputNested1": { + "type": "structure", + "members": { + "foo": { + "shape": "String" + }, + "nested": { + "shape": "RecursiveShapesInputOutputNested2" + } + } + }, + "String": { + "type": "string" + }, + "RecursiveShapesInputOutputNested2": { + "type": "structure", + "members": { + "bar": { + "shape": "String" + }, + "recursiveMember": { + "shape": "RecursiveShapesInputOutputNested1" + } + } + } + }, + "cases": [ + { + "id": "RestJsonRecursiveShapes", + "given": { + "name": "RecursiveShapes", + "http": { + "method": "PUT", + "requestUri": "/RecursiveShapes", + "responseCode": 200 + }, + "input": { + "shape": "RecursiveShapesInputOutput" + }, + "documentation": "

Recursive shapes

", + "idempotent": true + }, + "description": "Serializes recursive structures", + "params": { + "nested": { + "foo": "Foo1", + "nested": { + "bar": "Bar1", + "recursiveMember": { + "foo": "Foo2", + "nested": { + "bar": "Bar2" + } + } + } + } + }, + "serialized": { + "method": "PUT", + "uri": "/RecursiveShapes", + "body": "{\n \"nested\": {\n \"foo\": \"Foo1\",\n \"nested\": {\n \"bar\": \"Bar1\",\n \"recursiveMember\": {\n \"foo\": \"Foo2\",\n \"nested\": {\n \"bar\": \"Bar2\"\n }\n }\n }\n }\n}", + "headers": { + "Content-Type": "application/json" + } + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/InlineDocument" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "documentValue": {"foo": "bar"} - }, - "serialized": { - "body": "{\"documentValue\": {\"foo\": \"bar\"}}", - "uri": "/InlineDocument" - } - } - ] - }, - { - "description": "Serializes aggregate documents as part of the JSON request payload with no escaping.", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for SimpleScalarProperties operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "SimpleScalarPropertiesInputOutput": { + "type": "structure", + "members": { + "foo": { + "shape": "String", + "location": "header", + "locationName": "X-Foo" + }, + "stringValue": { + "shape": "String" + }, + "trueBooleanValue": { + "shape": "Boolean" + }, + "falseBooleanValue": { + "shape": "Boolean" + }, + "byteValue": { + "shape": "Integer" + }, + "shortValue": { + "shape": "Integer" + }, + "integerValue": { + "shape": "Integer" + }, + "longValue": { + "shape": "Long" + }, + "floatValue": { + "shape": "Float" + }, + "doubleValue": { + "shape": "Double", + "locationName": "DoubleDribble" + } + } + }, + "String": { + "type": "string" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + }, + "Long": { + "type": "long", + "box": true + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + } + }, + "cases": [ + { + "id": "RestJsonSimpleScalarProperties", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "input": { + "shape": "SimpleScalarPropertiesInputOutput" + }, + "idempotent": true + }, + "description": "Serializes simple scalar properties", + "params": { + "foo": "Foo", + "stringValue": "string", + "trueBooleanValue": true, + "falseBooleanValue": false, + "byteValue": 1, + "shortValue": 2, + "integerValue": 3, + "longValue": 4, + "floatValue": 5.5, + "doubleValue": 6.5 + }, + "serialized": { + "method": "PUT", + "uri": "/SimpleScalarProperties", + "body": "{\n \"stringValue\": \"string\",\n \"trueBooleanValue\": true,\n \"falseBooleanValue\": false,\n \"byteValue\": 1,\n \"shortValue\": 2,\n \"integerValue\": 3,\n \"longValue\": 4,\n \"floatValue\": 5.5,\n \"DoubleDribble\": 6.5\n}", + "headers": { + "Content-Type": "application/json", + "X-Foo": "Foo" + } + } + }, + { + "id": "RestJsonDoesntSerializeNullStructureValues", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "input": { + "shape": "SimpleScalarPropertiesInputOutput" + }, + "idempotent": true + }, + "description": "Rest Json should not serialize null structure values", + "params": { + "stringValue": null + }, + "serialized": { + "method": "PUT", + "uri": "/SimpleScalarProperties", + "body": "{}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "RestJsonSupportsNaNFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "input": { + "shape": "SimpleScalarPropertiesInputOutput" + }, + "idempotent": true + }, + "description": "Supports handling NaN float values.", + "params": { + "floatValue": "NaN", + "doubleValue": "NaN" + }, + "serialized": { + "method": "PUT", + "uri": "/SimpleScalarProperties", + "body": "{\n \"floatValue\": \"NaN\",\n \"DoubleDribble\": \"NaN\"\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "RestJsonSupportsInfinityFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "input": { + "shape": "SimpleScalarPropertiesInputOutput" + }, + "idempotent": true + }, + "description": "Supports handling Infinity float values.", + "params": { + "floatValue": "Infinity", + "doubleValue": "Infinity" + }, + "serialized": { + "method": "PUT", + "uri": "/SimpleScalarProperties", + "body": "{\n \"floatValue\": \"Infinity\",\n \"DoubleDribble\": \"Infinity\"\n}", + "headers": { + "Content-Type": "application/json" + } + } + }, + { + "id": "RestJsonSupportsNegativeInfinityFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "input": { + "shape": "SimpleScalarPropertiesInputOutput" + }, + "idempotent": true + }, + "description": "Supports handling -Infinity float values.", + "params": { + "floatValue": "-Infinity", + "doubleValue": "-Infinity" + }, + "serialized": { + "method": "PUT", + "uri": "/SimpleScalarProperties", + "body": "{\n \"floatValue\": \"-Infinity\",\n \"DoubleDribble\": \"-Infinity\"\n}", + "headers": { + "Content-Type": "application/json" + } + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "documentValue": { - "shape": "DocumentType" - } - } - }, - "DocumentType": { - "type": "structure", - "document": true - } + { + "description": "Test cases for TestBodyStructure operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "TestBodyStructureInputOutput": { + "type": "structure", + "members": { + "testId": { + "shape": "String", + "location": "header", + "locationName": "x-amz-test-id" + }, + "testConfig": { + "shape": "TestConfig" + } + } + }, + "String": { + "type": "string" + }, + "TestConfig": { + "type": "structure", + "members": { + "timeout": { + "shape": "Integer" + } + } + }, + "Integer": { + "type": "integer", + "box": true + } + }, + "cases": [ + { + "id": "RestJsonTestBodyStructure", + "given": { + "name": "TestBodyStructure", + "http": { + "method": "POST", + "requestUri": "/body", + "responseCode": 200 + }, + "input": { + "shape": "TestBodyStructureInputOutput" + }, + "documentation": "

This example operation serializes a structure in the HTTP body.

It should ensure Content-Type: application/json is used in all requests and that an "empty" body is an empty JSON document ({}).

", + "idempotent": true + }, + "description": "Serializes a structure", + "params": { + "testConfig": { + "timeout": 10 + } + }, + "serialized": { + "method": "POST", + "uri": "/body", + "body": "{\"testConfig\":\n {\"timeout\": 10}\n}", + "headers": { + "Content-Type": "application/json" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "RestJsonHttpWithEmptyBody", + "given": { + "name": "TestBodyStructure", + "http": { + "method": "POST", + "requestUri": "/body", + "responseCode": 200 + }, + "input": { + "shape": "TestBodyStructureInputOutput" + }, + "documentation": "

This example operation serializes a structure in the HTTP body.

It should ensure Content-Type: application/json is used in all requests and that an "empty" body is an empty JSON document ({}).

", + "idempotent": true + }, + "description": "Serializes an empty structure in the body", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/body", + "body": "{}", + "headers": { + "Content-Type": "application/json" + }, + "requireHeaders": [ + "Content-Length" + ] + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/InlineDocument" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "documentValue": { - "str": "test", - "num": 123, - "float": 1.2, - "bool": true, - "null": "", - "document": {"foo": false}, - "list": ["myname", 321, 1.3, true, "", {"nested": true}, [200, ""]] - } - }, - "serialized": { - "body": "{\"documentValue\": {\"str\": \"test\", \"num\": 123, \"float\": 1.2, \"bool\": true, \"null\": \"\", \"document\": {\"foo\": false}, \"list\": [\"myname\", 321, 1.3, true, \"\", {\"nested\": true}, [200, \"\"]]}}", - "uri": "/InlineDocument" - } - }, - { - "given": { - "http": { - "method": "POST", - "requestUri": "/InlineDocument" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "documentValue": [ - "test", - 123, - 1.2, - true, - "", - {"str": "myname", "num": 321, "float": 1.3, "bool": true, "null": "", "document": {"nested": true}, "list": [200, ""]}, - ["foo", false] - ] - }, - "serialized": { - "body": "{\"documentValue\": [\"test\", 123, 1.2, true, \"\", {\"str\": \"myname\", \"num\": 321, \"float\": 1.3, \"bool\": true, \"null\": \"\", \"document\": {\"nested\": true}, \"list\": [200, \"\"]}, [\"foo\", false]]}", - "uri": "/InlineDocument" - } - } - ] - }, - { - "description": "Content-Type and JSON body", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for TestNoPayload operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "TestNoPayloadInputOutput": { + "type": "structure", + "members": { + "testId": { + "shape": "String", + "location": "header", + "locationName": "X-Amz-Test-Id" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonHttpWithNoModeledBody", + "given": { + "name": "TestNoPayload", + "http": { + "method": "GET", + "requestUri": "/no_payload", + "responseCode": 200 + }, + "input": { + "shape": "TestNoPayloadInputOutput" + }, + "documentation": "

This example operation serializes a request without an HTTP body.

These tests are to ensure we do not attach a body or related headers (Content-Length, Content-Type) to operations that semantically cannot produce an HTTP body.

" + }, + "description": "Serializes a GET request with no modeled body", + "params": {}, + "serialized": { + "method": "GET", + "uri": "/no_payload", + "body": "", + "forbidHeaders": [ + "Content-Length", + "Content-Type" + ] + } + }, + { + "id": "RestJsonHttpWithHeaderMemberNoModeledBody", + "given": { + "name": "TestNoPayload", + "http": { + "method": "GET", + "requestUri": "/no_payload", + "responseCode": 200 + }, + "input": { + "shape": "TestNoPayloadInputOutput" + }, + "documentation": "

This example operation serializes a request without an HTTP body.

These tests are to ensure we do not attach a body or related headers (Content-Length, Content-Type) to operations that semantically cannot produce an HTTP body.

" + }, + "description": "Serializes a GET request with header member but no modeled body", + "params": { + "testId": "t-12345" + }, + "serialized": { + "method": "GET", + "uri": "/no_payload", + "body": "", + "headers": { + "X-Amz-Test-Id": "t-12345" + }, + "forbidHeaders": [ + "Content-Length", + "Content-Type" + ] + } + } + ] }, - "clientEndpoint": "https://rest-json-test.amazonaws.com", - "shapes":{ - "Integer":{ - "type":"integer" - }, - "String":{"type":"string"}, - "Blob":{"type":"blob"}, - "NoPayloadRequest":{ - "type":"structure", - "required":[], - "members":{ - "testId":{ - "shape":"TestId", - "documentation":"

The unique ID for a test.

", - "location":"header", - "locationName":"x-amz-test-id" - } - }, - "documentation":"

The request structure for a no payload request.

" - }, - "TestId":{ - "type":"string", - "max":8, - "min":3, - "pattern":"t-[a-z0-9-]+" - }, - "TestConfig":{ - "type":"structure", - "required":[], - "members":{ - "timeout":{ - "shape":"Integer", - "documentation":"

Timeout in seconds

" - } - } - }, - "PayloadConfig":{ - "type":"structure", - "required":[], - "members":{ - "data":{ - "shape":"Integer", - "documentation":"

Numerical data

" - } - } - }, - "TestBodyRequest":{ - "type":"structure", - "required":[], - "members":{ - "testConfig":{ - "shape":"TestConfig", - "documentation":"

Content to post

" - }, - "testId":{ - "shape":"TestId", - "documentation":"

Optional test identifier

", - "location":"header", - "locationName":"x-amz-test-id" - } - }, - "documentation":"

The request structure for a test body request.

" - }, - "TestPayloadRequest":{ - "type":"structure", - "required":[], - "members":{ - "payloadConfig":{ - "shape":"PayloadConfig", - "documentation":"

Payload to post

" - }, - "testId":{ - "shape":"TestId", - "documentation":"

Optional test identifier

", - "location":"header", - "locationName":"x-amz-test-id" - } - }, - "documentation":"

The request structure for a payload request.

", - "payload":"payloadConfig" - }, - "TestBlobPayloadRequest":{ - "type":"structure", - "required":[], - "members":{ - "data":{ - "shape":"Blob", - "documentation":"

Blob payload to post

" - }, - "contentType":{ - "shape":"String", - "documentation":"

Optional content-type header

", - "location":"header", - "locationName":"Content-Type" - } - }, - "documentation":"

The request structure for a blob payload request.

", - "payload":"data" - } + { + "description": "Test cases for TestPayloadBlob operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "TestPayloadBlobInputOutput": { + "type": "structure", + "members": { + "contentType": { + "shape": "String", + "location": "header", + "locationName": "Content-Type" + }, + "data": { + "shape": "Blob" + } + }, + "payload": "data" + }, + "String": { + "type": "string" + }, + "Blob": { + "type": "blob" + } + }, + "cases": [ + { + "id": "RestJsonHttpWithEmptyBlobPayload", + "given": { + "name": "TestPayloadBlob", + "http": { + "method": "POST", + "requestUri": "/blob_payload", + "responseCode": 200 + }, + "input": { + "shape": "TestPayloadBlobInputOutput" + }, + "documentation": "

This example operation serializes a payload targeting a blob.

The Blob shape is not structured content and we cannot make assumptions about what data will be sent. This test ensures only a generic "Content-Type: application/octet-stream" header is used, and that we are not treating an empty body as an empty JSON document.

", + "idempotent": true + }, + "description": "Serializes a payload targeting an empty blob", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/blob_payload", + "body": "", + "headers": { + "Content-Type": "application/octet-stream" + } + } + }, + { + "id": "RestJsonTestPayloadBlob", + "given": { + "name": "TestPayloadBlob", + "http": { + "method": "POST", + "requestUri": "/blob_payload", + "responseCode": 200 + }, + "input": { + "shape": "TestPayloadBlobInputOutput" + }, + "documentation": "

This example operation serializes a payload targeting a blob.

The Blob shape is not structured content and we cannot make assumptions about what data will be sent. This test ensures only a generic "Content-Type: application/octet-stream" header is used, and that we are not treating an empty body as an empty JSON document.

", + "idempotent": true + }, + "description": "Serializes a payload targeting a blob", + "params": { + "contentType": "image/jpg", + "data": "1234" + }, + "serialized": { + "method": "POST", + "uri": "/blob_payload", + "body": "1234", + "headers": { + "Content-Type": "image/jpg" + }, + "requireHeaders": [ + "Content-Length" + ] + } + } + ] }, - "cases": [ - { - "given": { - "name": "TestBody", - "input": { - "shape": "TestBodyRequest" - }, - "http": { - "method": "POST", - "requestUri": "/body" - } - }, - "params": { - "testConfig": { - "timeout": 10 - }, - "testId": "t-12345" - }, - "serialized": { - "uri": "/body", - "body": "{\"testConfig\": {\"timeout\": 10}}", - "headers": { - "x-amz-test-id": "t-12345", - "Content-Type": "application/json" - }, - "host": "rest-json-test.amazonaws.com" - } - }, - { - "given": { - "name": "TestBodyNoParams", - "input": { - "shape": "TestBodyRequest" - }, - "http": { - "method": "POST", - "requestUri": "/body" - } - }, - "params": {}, - "serialized": { - "uri": "/body", - "body": "{}", - "headers": { - "Content-Type": "application/json" - }, - "host": "rest-json-test.amazonaws.com" - } - }, - { - "given": { - "name": "TestPayloadNoParams", - "input": { - "shape": "TestPayloadRequest" - }, - "http": { - "method": "POST", - "requestUri": "/payload" - } - }, - "params": {}, - "serialized": { - "uri": "/payload", - "body": "{}", - "headers": { - "Content-Type": "application/json" - }, - "host": "rest-json-test.amazonaws.com" - } - }, - { - "given": { - "name": "TestPayload", - "input": { - "shape": "TestPayloadRequest" - }, - "http": { - "method": "POST", - "requestUri": "/payload" - } - }, - "params": { - "payloadConfig": { - "data": 25 - }, - "testId": "t-12345" - }, - "serialized": { - "uri": "/payload", - "body": "{\"data\": 25}", - "headers": { - "x-amz-test-id": "t-12345", - "Content-Type": "application/json" - }, - "host": "rest-json-test.amazonaws.com" - } - }, - { - "given": { - "name": "TestPayloadNoBody", - "input": { - "shape": "TestPayloadRequest" - }, - "http": { - "method": "POST", - "requestUri": "/payload" - } - }, - "params": { - "testId": "t-12345" - }, - "serialized": { - "uri": "/payload", - "body": "{}", - "headers": { - "x-amz-test-id": "t-12345", - "Content-Type": "application/json" - }, - "host": "rest-json-test.amazonaws.com" - } - }, - { - "given": { - "name": "TestBlobPayload", - "input": { - "shape": "TestBlobPayloadRequest" - }, - "http": { - "method": "POST", - "requestUri": "/blob-payload" - } - }, - "params": { - "data": "1234", - "contentType": "image/jpg" - }, - "serialized": { - "uri": "/blob-payload", - "body": "1234", - "headers": { - "Content-Type": "image/jpg" - }, - "host": "rest-json-test.amazonaws.com" - } - }, - { - "given": { - "name": "TestBlobPayloadNoContentType", - "input": { - "shape": "TestBlobPayloadRequest" - }, - "http": { - "method": "POST", - "requestUri": "/blob-payload" - } - }, - "params": { - "data": "1234" - }, - "serialized": { - "uri": "/blob-payload", - "body": "1234", - "forbidHeaders": ["Content-Length"], - "host": "rest-json-test.amazonaws.com" - } - }, - { - "given": { - "name": "TestBlobPayloadNoParams", - "input": { - "shape": "TestBlobPayloadRequest" - }, - "http": { - "method": "POST", - "requestUri": "/blob-payload" - } - }, - "params": {}, - "serialized": { - "uri": "/blob-payload", - "body": "", - "headers": {}, - "forbidHeaders": [ - "Content-Type" - ], - "host": "rest-json-test.amazonaws.com" - } - }, - { - "given": { - "name": "NoPayload", - "input": { - "shape": "NoPayloadRequest" - }, - "http": { - "method": "POST", - "requestUri": "/no-payload" - } - }, - "params": {}, - "serialized": { - "uri": "/no-payload", - "body": "", - "forbidHeaders": [ - "Content-Type", - "Content-Length" - ], - "host": "rest-json-test.amazonaws.com" - } - }, - { - "given": { - "name": "NoPayloadWithHeader", - "input": { - "shape": "NoPayloadRequest" - }, - "http": { - "method": "POST", - "requestUri": "/no-payload" - } - }, - "params": { - "testId": "t-12345" - }, - "serialized": { - "uri": "/no-payload", - "body": "", - "headers": { - "x-amz-test-id": "t-12345" - }, - "forbidHeaders": [ - "Content-Type", - "Content-Length" - ], - "host": "rest-json-test.amazonaws.com" - } - }, - { - "given": { - "name": "NoPayloadGET", - "input": { - "shape": "NoPayloadRequest" - }, - "http": { - "method": "GET", - "requestUri": "/no-payload" - } - }, - "params": {}, - "serialized": { - "uri": "/no-payload", - "body": "", - "forbidHeaders": [ - "Content-Type", - "Content-Length" - ], - "host": "rest-json-test.amazonaws.com" - } - }, - { - "given": { - "name": "NoPayloadWithHeaderGET", - "input": { - "shape": "NoPayloadRequest" - }, - "http": { - "method": "GET", - "requestUri": "/no-payload" - } - }, - "params": { - "testId": "t-12345" - }, - "serialized": { - "uri": "/no-payload", - "body": "", - "headers": { - "x-amz-test-id": "t-12345" - }, - "forbidHeaders": [ - "Content-Type", - "Content-Length" - ], - "host": "rest-json-test.amazonaws.com" - } - } - ] - }, - { - "description": "List in header", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for TestPayloadStructure operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "TestPayloadStructureInputOutput": { + "type": "structure", + "members": { + "testId": { + "shape": "String", + "location": "header", + "locationName": "x-amz-test-id" + }, + "payloadConfig": { + "shape": "PayloadConfig" + } + }, + "payload": "payloadConfig" + }, + "String": { + "type": "string" + }, + "PayloadConfig": { + "type": "structure", + "members": { + "data": { + "shape": "Integer" + } + } + }, + "Integer": { + "type": "integer", + "box": true + } + }, + "cases": [ + { + "id": "RestJsonHttpWithEmptyStructurePayload", + "given": { + "name": "TestPayloadStructure", + "http": { + "method": "POST", + "requestUri": "/payload", + "responseCode": 200 + }, + "input": { + "shape": "TestPayloadStructureInputOutput" + }, + "documentation": "

This example operation serializes a payload targeting a structure.

This enforces the same requirements as TestBodyStructure but with the body specified by the @httpPayload trait.

", + "idempotent": true + }, + "description": "Serializes a payload targeting an empty structure", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/payload", + "body": "{}", + "headers": { + "Content-Type": "application/json" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "RestJsonTestPayloadStructure", + "given": { + "name": "TestPayloadStructure", + "http": { + "method": "POST", + "requestUri": "/payload", + "responseCode": 200 + }, + "input": { + "shape": "TestPayloadStructureInputOutput" + }, + "documentation": "

This example operation serializes a payload targeting a structure.

This enforces the same requirements as TestBodyStructure but with the body specified by the @httpPayload trait.

", + "idempotent": true + }, + "description": "Serializes a payload targeting a structure", + "params": { + "payloadConfig": { + "data": 25 + } + }, + "serialized": { + "method": "POST", + "uri": "/payload", + "body": "{\"data\": 25\n}", + "headers": { + "Content-Type": "application/json" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "RestJsonHttpWithHeadersButNoPayload", + "given": { + "name": "TestPayloadStructure", + "http": { + "method": "POST", + "requestUri": "/payload", + "responseCode": 200 + }, + "input": { + "shape": "TestPayloadStructureInputOutput" + }, + "documentation": "

This example operation serializes a payload targeting a structure.

This enforces the same requirements as TestBodyStructure but with the body specified by the @httpPayload trait.

", + "idempotent": true + }, + "description": "Serializes an request with header members but no payload", + "params": { + "testId": "t-12345" + }, + "serialized": { + "method": "POST", + "uri": "/payload", + "body": "{}", + "headers": { + "Content-Type": "application/json", + "X-Amz-Test-Id": "t-12345" + }, + "requireHeaders": [ + "Content-Length" + ] + } + } + ] }, - "clientEndpoint": "https://rest-json-test.amazonaws.com", - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "ListParam": { - "shape": "ListShape", - "location": "header", - "locationName": "x-amz-list-param" - } - } - }, - "ListShape": { - "type": "list", - "member": { - "shape": "EnumType" - } - }, - "EnumType": { - "type": "string", - "enum": ["one", "two", "three"] - } + { + "description": "Test cases for TimestampFormatHeaders operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "TimestampFormatHeadersIO": { + "type": "structure", + "members": { + "memberEpochSeconds": { + "shape": "SyntheticTimestamp_epoch_seconds", + "location": "header", + "locationName": "X-memberEpochSeconds" + }, + "memberHttpDate": { + "shape": "SyntheticTimestamp_http_date", + "location": "header", + "locationName": "X-memberHttpDate" + }, + "memberDateTime": { + "shape": "SyntheticTimestamp_date_time", + "location": "header", + "locationName": "X-memberDateTime" + }, + "defaultFormat": { + "shape": "Timestamp", + "location": "header", + "locationName": "X-defaultFormat" + }, + "targetEpochSeconds": { + "shape": "EpochSeconds", + "location": "header", + "locationName": "X-targetEpochSeconds" + }, + "targetHttpDate": { + "shape": "HttpDate", + "location": "header", + "locationName": "X-targetHttpDate" + }, + "targetDateTime": { + "shape": "DateTime", + "location": "header", + "locationName": "X-targetDateTime" + } + } + }, + "SyntheticTimestamp_epoch_seconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "SyntheticTimestamp_http_date": { + "type": "timestamp", + "timestampFormat": "rfc822" + }, + "SyntheticTimestamp_date_time": { + "type": "timestamp", + "timestampFormat": "iso8601" + }, + "Timestamp": { + "type": "timestamp" + }, + "EpochSeconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "HttpDate": { + "type": "timestamp", + "timestampFormat": "rfc822" + }, + "DateTime": { + "type": "timestamp", + "timestampFormat": "iso8601" + } + }, + "cases": [ + { + "id": "RestJsonTimestampFormatHeaders", + "given": { + "name": "TimestampFormatHeaders", + "http": { + "method": "POST", + "requestUri": "/TimestampFormatHeaders", + "responseCode": 200 + }, + "input": { + "shape": "TimestampFormatHeadersIO" + }, + "documentation": "

This example tests how timestamp request and response headers are serialized.

" + }, + "description": "Tests how timestamp request headers are serialized", + "params": { + "memberEpochSeconds": 1576540098, + "memberHttpDate": 1576540098, + "memberDateTime": 1576540098, + "defaultFormat": 1576540098, + "targetEpochSeconds": 1576540098, + "targetHttpDate": 1576540098, + "targetDateTime": 1576540098 + }, + "serialized": { + "method": "POST", + "uri": "/TimestampFormatHeaders", + "body": "", + "headers": { + "X-defaultFormat": "Mon, 16 Dec 2019 23:48:18 GMT", + "X-memberDateTime": "2019-12-16T23:48:18Z", + "X-memberEpochSeconds": "1576540098", + "X-memberHttpDate": "Mon, 16 Dec 2019 23:48:18 GMT", + "X-targetDateTime": "2019-12-16T23:48:18Z", + "X-targetEpochSeconds": "1576540098", + "X-targetHttpDate": "Mon, 16 Dec 2019 23:48:18 GMT" + } + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/2014-01-01/example" - }, - "input": { - "shape": "InputShape", - "locationName": "OperationRequest" - }, - "name": "OperationName" - }, - "params": { - "ListParam": [ - "one", - "two", - "three" - ] - }, - "serialized": { - "method": "POST", - "body": "", - "uri": "/2014-01-01/example", - "headers": { - "x-amz-list-param": "one,two,three" - } - } - }, - { - "given": { - "http": { - "method": "POST", - "requestUri": "/2014-01-01/example" - }, - "input": { - "shape": "InputShape", - "locationName": "OperationRequest" - }, - "name": "OperationName" - }, - "params": { - "ListParam": [] - }, - "serialized": { - "method": "POST", - "body": "", - "uri": "/2014-01-01/example", - "headers": {}, - "forbidHeaders": ["x-amz-list-param"] - } - } - ] - } + { + "description": "Test cases for UnitInputAndOutput operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": {}, + "cases": [ + { + "id": "RestJsonUnitInputAndOutput", + "given": { + "name": "UnitInputAndOutput", + "http": { + "method": "POST", + "requestUri": "/UnitInputAndOutput", + "responseCode": 200 + }, + "documentation": "

This test is similar to NoInputAndNoOutput, but uses explicit Unit types.

" + }, + "description": "A unit type input serializes no payload. When clients do not\nneed to serialize any data in the payload, they should omit\na payload altogether.", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/UnitInputAndOutput", + "body": "" + } + } + ] + } ] diff --git a/tests/unit/protocols/input/rest-xml.json b/tests/unit/protocols/input/rest-xml.json index cd5b98418e..47901eba73 100644 --- a/tests/unit/protocols/input/rest-xml.json +++ b/tests/unit/protocols/input/rest-xml.json @@ -1,1976 +1,5651 @@ [ - { - "description": "Basic XML serialization", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "Name": { - "shape": "StringType" - }, - "Description": { - "shape": "StringType" - } - } - }, - "StringType": { - "type": "string" - } - }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/2014-01-01/hostedzone" - }, - "input": { - "shape": "InputShape", - "locationName": "OperationRequest", - "xmlNamespace": {"uri": "https://foo/"} - }, - "name": "OperationName" - }, - "params": { - "Name": "foo", - "Description": "bar" - }, - "serialized": { - "method": "POST", - "body": "foobar", - "uri": "/2014-01-01/hostedzone", - "headers": {} - } - }, - { - "given": { - "http": { - "method": "PUT", - "requestUri": "/2014-01-01/hostedzone" - }, - "input": { - "shape": "InputShape", - "locationName": "OperationRequest", - "xmlNamespace": {"uri": "https://foo/"} - }, - "name": "OperationName" - }, - "params": { - "Name": "foo", - "Description": "bar" - }, - "serialized": { - "method": "PUT", - "body": "foobar", - "uri": "/2014-01-01/hostedzone", - "headers": {} - } - }, - { - "given": { - "http": { - "method": "GET", - "requestUri": "/2014-01-01/hostedzone" - }, - "name": "OperationName" - }, - "params": {}, - "serialized": { - "method": "GET", - "body": "", - "uri": "/2014-01-01/hostedzone", - "headers": {} - } - } - ] - }, - { - "description": "Serialize other scalar types", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" - }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "First": { - "shape": "BoolType" - }, - "Second": { - "shape": "BoolType" - }, - "Third": { - "shape": "FloatType" - }, - "Fourth": { - "shape": "IntegerType" - } - } - }, - "BoolType": { - "type": "boolean" - }, - "FloatType": { - "type": "float" - }, - "IntegerType": { - "type": "integer" - } - }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/2014-01-01/hostedzone" - }, - "input": { - "shape": "InputShape", - "locationName": "OperationRequest", - "xmlNamespace": {"uri": "https://foo/"} - }, - "name": "OperationName" - }, - "params": { - "First": true, - "Second": false, - "Third": 1.2, - "Fourth": 3 - }, - "serialized": { - "method": "POST", - "body": "truefalse1.23", - "uri": "/2014-01-01/hostedzone", - "headers": {} - } - } - ] - }, - { - "description": "Nested structures", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" + { + "description": "Test cases for AllQueryStringTypes operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "AllQueryStringTypesInput": { + "type": "structure", + "members": { + "queryString": { + "shape": "String", + "location": "querystring", + "locationName": "String" + }, + "queryStringList": { + "shape": "StringList", + "location": "querystring", + "locationName": "StringList" + }, + "queryStringSet": { + "shape": "StringSet", + "location": "querystring", + "locationName": "StringSet" + }, + "queryByte": { + "shape": "Integer", + "location": "querystring", + "locationName": "Byte" + }, + "queryShort": { + "shape": "Integer", + "location": "querystring", + "locationName": "Short" + }, + "queryInteger": { + "shape": "Integer", + "location": "querystring", + "locationName": "Integer" + }, + "queryIntegerList": { + "shape": "IntegerList", + "location": "querystring", + "locationName": "IntegerList" + }, + "queryIntegerSet": { + "shape": "IntegerSet", + "location": "querystring", + "locationName": "IntegerSet" + }, + "queryLong": { + "shape": "Long", + "location": "querystring", + "locationName": "Long" + }, + "queryFloat": { + "shape": "Float", + "location": "querystring", + "locationName": "Float" + }, + "queryDouble": { + "shape": "Double", + "location": "querystring", + "locationName": "Double" + }, + "queryDoubleList": { + "shape": "DoubleList", + "location": "querystring", + "locationName": "DoubleList" + }, + "queryBoolean": { + "shape": "Boolean", + "location": "querystring", + "locationName": "Boolean" + }, + "queryBooleanList": { + "shape": "BooleanList", + "location": "querystring", + "locationName": "BooleanList" + }, + "queryTimestamp": { + "shape": "Timestamp", + "location": "querystring", + "locationName": "Timestamp" + }, + "queryTimestampList": { + "shape": "TimestampList", + "location": "querystring", + "locationName": "TimestampList" + }, + "queryEnum": { + "shape": "FooEnum", + "location": "querystring", + "locationName": "Enum" + }, + "queryEnumList": { + "shape": "FooEnumList", + "location": "querystring", + "locationName": "EnumList" + }, + "queryIntegerEnum": { + "shape": "IntegerEnum", + "location": "querystring", + "locationName": "IntegerEnum" + }, + "queryIntegerEnumList": { + "shape": "IntegerEnumList", + "location": "querystring", + "locationName": "IntegerEnumList" + }, + "queryParamsMapOfStrings": { + "shape": "StringMap", + "location": "querystring" + } + } + }, + "String": { + "type": "string" + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringSet": { + "type": "list", + "member": { + "shape": "String" + } + }, + "Integer": { + "type": "integer", + "box": true + }, + "IntegerList": { + "type": "list", + "member": { + "shape": "Integer" + } + }, + "IntegerSet": { + "type": "list", + "member": { + "shape": "Integer" + } + }, + "Long": { + "type": "long", + "box": true + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + }, + "DoubleList": { + "type": "list", + "member": { + "shape": "Double" + } + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "BooleanList": { + "type": "list", + "member": { + "shape": "Boolean" + } + }, + "Timestamp": { + "type": "timestamp" + }, + "TimestampList": { + "type": "list", + "member": { + "shape": "Timestamp" + } + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "IntegerEnumList": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "StringMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "String" + } + } + }, + "cases": [ + { + "id": "AllQueryStringTypes", + "given": { + "name": "AllQueryStringTypes", + "http": { + "method": "GET", + "requestUri": "/AllQueryStringTypesInput", + "responseCode": 200 + }, + "input": { + "shape": "AllQueryStringTypesInput" + }, + "documentation": "

This example uses all query string types.

" + }, + "description": "Serializes query string parameters with all supported types", + "params": { + "queryString": "Hello there", + "queryStringList": [ + "a", + "b", + "c" + ], + "queryStringSet": [ + "a", + "b", + "c" + ], + "queryByte": 1, + "queryShort": 2, + "queryInteger": 3, + "queryIntegerList": [ + 1, + 2, + 3 + ], + "queryIntegerSet": [ + 1, + 2, + 3 + ], + "queryLong": 4, + "queryFloat": 1.1, + "queryDouble": 1.1, + "queryDoubleList": [ + 1.1, + 2.1, + 3.1 + ], + "queryBoolean": true, + "queryBooleanList": [ + true, + false, + true + ], + "queryTimestamp": 1, + "queryTimestampList": [ + 1, + 2, + 3 + ], + "queryEnum": "Foo", + "queryEnumList": [ + "Foo", + "Baz", + "Bar" + ], + "queryIntegerEnum": 1, + "queryIntegerEnumList": [ + 1, + 2 + ] + }, + "serialized": { + "method": "GET", + "uri": "/AllQueryStringTypesInput?String=Hello%20there&StringList=a&StringList=b&StringList=c&StringSet=a&StringSet=b&StringSet=c&Byte=1&Short=2&Integer=3&IntegerList=1&IntegerList=2&IntegerList=3&IntegerSet=1&IntegerSet=2&IntegerSet=3&Long=4&Float=1.1&Double=1.1&DoubleList=1.1&DoubleList=2.1&DoubleList=3.1&Boolean=true&BooleanList=true&BooleanList=false&BooleanList=true&Timestamp=1970-01-01T00%3A00%3A01Z&TimestampList=1970-01-01T00%3A00%3A01Z&TimestampList=1970-01-01T00%3A00%3A02Z&TimestampList=1970-01-01T00%3A00%3A03Z&Enum=Foo&EnumList=Foo&EnumList=Baz&EnumList=Bar&IntegerEnum=1&IntegerEnumList=1&IntegerEnumList=2", + "body": "" + } + }, + { + "id": "RestXmlQueryStringMap", + "given": { + "name": "AllQueryStringTypes", + "http": { + "method": "GET", + "requestUri": "/AllQueryStringTypesInput", + "responseCode": 200 + }, + "input": { + "shape": "AllQueryStringTypesInput" + }, + "documentation": "

This example uses all query string types.

" + }, + "description": "Handles query string maps", + "params": { + "queryParamsMapOfStrings": { + "QueryParamsStringKeyA": "Foo", + "QueryParamsStringKeyB": "Bar" + } + }, + "serialized": { + "method": "GET", + "uri": "/AllQueryStringTypesInput?QueryParamsStringKeyA=Foo&QueryParamsStringKeyB=Bar", + "body": "" + } + }, + { + "id": "RestXmlQueryStringEscaping", + "given": { + "name": "AllQueryStringTypes", + "http": { + "method": "GET", + "requestUri": "/AllQueryStringTypesInput", + "responseCode": 200 + }, + "input": { + "shape": "AllQueryStringTypesInput" + }, + "documentation": "

This example uses all query string types.

" + }, + "description": "Handles escaping all required characters in the query string.", + "params": { + "queryString": " %:/?#[]@!$&'()*+,;=😹" + }, + "serialized": { + "method": "GET", + "uri": "/AllQueryStringTypesInput?String=%20%25%3A%2F%3F%23%5B%5D%40%21%24%26%27%28%29%2A%2B%2C%3B%3D%F0%9F%98%B9", + "body": "" + } + }, + { + "id": "RestXmlSupportsNaNFloatQueryValues", + "given": { + "name": "AllQueryStringTypes", + "http": { + "method": "GET", + "requestUri": "/AllQueryStringTypesInput", + "responseCode": 200 + }, + "input": { + "shape": "AllQueryStringTypesInput" + }, + "documentation": "

This example uses all query string types.

" + }, + "description": "Supports handling NaN float query values.", + "params": { + "queryFloat": "NaN", + "queryDouble": "NaN" + }, + "serialized": { + "method": "GET", + "uri": "/AllQueryStringTypesInput?Float=NaN&Double=NaN", + "body": "" + } + }, + { + "id": "RestXmlSupportsInfinityFloatQueryValues", + "given": { + "name": "AllQueryStringTypes", + "http": { + "method": "GET", + "requestUri": "/AllQueryStringTypesInput", + "responseCode": 200 + }, + "input": { + "shape": "AllQueryStringTypesInput" + }, + "documentation": "

This example uses all query string types.

" + }, + "description": "Supports handling Infinity float query values.", + "params": { + "queryFloat": "Infinity", + "queryDouble": "Infinity" + }, + "serialized": { + "method": "GET", + "uri": "/AllQueryStringTypesInput?Float=Infinity&Double=Infinity", + "body": "" + } + }, + { + "id": "RestXmlSupportsNegativeInfinityFloatQueryValues", + "given": { + "name": "AllQueryStringTypes", + "http": { + "method": "GET", + "requestUri": "/AllQueryStringTypesInput", + "responseCode": 200 + }, + "input": { + "shape": "AllQueryStringTypesInput" + }, + "documentation": "

This example uses all query string types.

" + }, + "description": "Supports handling -Infinity float query values.", + "params": { + "queryFloat": "-Infinity", + "queryDouble": "-Infinity" + }, + "serialized": { + "method": "GET", + "uri": "/AllQueryStringTypesInput?Float=-Infinity&Double=-Infinity", + "body": "" + } + }, + { + "id": "RestXmlZeroAndFalseQueryValues", + "given": { + "name": "AllQueryStringTypes", + "http": { + "method": "GET", + "requestUri": "/AllQueryStringTypesInput", + "responseCode": 200 + }, + "input": { + "shape": "AllQueryStringTypesInput" + }, + "documentation": "

This example uses all query string types.

" + }, + "description": "Query values of 0 and false are serialized", + "params": { + "queryInteger": 0, + "queryBoolean": false + }, + "serialized": { + "method": "GET", + "uri": "/AllQueryStringTypesInput?Integer=0&Boolean=false", + "body": "" + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "SubStructure": { - "shape": "SubStructure" - }, - "Description": { - "shape": "StringType" - } - } - }, - "SubStructure": { - "type": "structure", - "members": { - "Foo": { - "shape": "StringType" - }, - "Bar": { - "shape": "StringType" - } - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for BodyWithXmlName operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "BodyWithXmlNameInputOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "PayloadWithXmlName" + } + }, + "locationName": "Ahoy" + }, + "PayloadWithXmlName": { + "type": "structure", + "members": { + "name": { + "shape": "String" + } + }, + "locationName": "Hello" + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "BodyWithXmlName", + "given": { + "name": "BodyWithXmlName", + "http": { + "method": "PUT", + "requestUri": "/BodyWithXmlName", + "responseCode": 200 + }, + "input": { + "shape": "BodyWithXmlNameInputOutput", + "locationName": "BodyWithXmlNameRequest" + }, + "documentation": "

The following example serializes a body that uses an XML name, changing the wrapper name.

", + "idempotent": true + }, + "description": "Serializes a payload using a wrapper name based on the xmlName", + "params": { + "nested": { + "name": "Phreddy" + } + }, + "serialized": { + "method": "PUT", + "uri": "/BodyWithXmlName", + "body": "Phreddy", + "headers": { + "Content-Type": "application/xml" + }, + "requireHeaders": [ + "Content-Length" + ] + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/2014-01-01/hostedzone" - }, - "input": { - "shape": "InputShape", - "locationName": "OperationRequest", - "xmlNamespace": {"uri": "https://foo/"} - }, - "name": "OperationName" - }, - "params": { - "SubStructure": { - "Foo": "a", - "Bar": "b" - }, - "Description": "baz" - }, - "serialized": { - "method": "POST", - "body": "abbaz", - "uri": "/2014-01-01/hostedzone", - "headers": {} - } - }, - { - "given": { - "http": { - "method": "POST", - "requestUri": "/2014-01-01/hostedzone" - }, - "input": { - "shape": "InputShape", - "locationName": "OperationRequest", - "xmlNamespace": {"uri": "https://foo/"} - }, - "name": "OperationName" - }, - "params": { - "SubStructure": { - "Foo": "a", - "Bar": null - }, - "Description": "baz" - }, - "serialized": { - "method": "POST", - "body": "abaz", - "uri": "/2014-01-01/hostedzone", - "headers": {} - } - } - ] - }, - { - "description": "Nested structures", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" + { + "description": "Test cases for ConstantAndVariableQueryString operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "ConstantAndVariableQueryStringInput": { + "type": "structure", + "members": { + "baz": { + "shape": "String", + "location": "querystring", + "locationName": "baz" + }, + "maybeSet": { + "shape": "String", + "location": "querystring", + "locationName": "maybeSet" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "ConstantAndVariableQueryStringMissingOneValue", + "given": { + "name": "ConstantAndVariableQueryString", + "http": { + "method": "GET", + "requestUri": "/ConstantAndVariableQueryString?foo=bar", + "responseCode": 200 + }, + "input": { + "shape": "ConstantAndVariableQueryStringInput" + }, + "documentation": "

This example uses fixed query string params and variable query string params. The fixed query string parameters and variable parameters must both be serialized (implementations may need to merge them together).

" + }, + "description": "Mixes constant and variable query string parameters", + "params": { + "baz": "bam" + }, + "serialized": { + "method": "GET", + "uri": "/ConstantAndVariableQueryString?foo=bar&baz=bam", + "body": "" + } + }, + { + "id": "ConstantAndVariableQueryStringAllValues", + "given": { + "name": "ConstantAndVariableQueryString", + "http": { + "method": "GET", + "requestUri": "/ConstantAndVariableQueryString?foo=bar", + "responseCode": 200 + }, + "input": { + "shape": "ConstantAndVariableQueryStringInput" + }, + "documentation": "

This example uses fixed query string params and variable query string params. The fixed query string parameters and variable parameters must both be serialized (implementations may need to merge them together).

" + }, + "description": "Mixes constant and variable query string parameters", + "params": { + "baz": "bam", + "maybeSet": "yes" + }, + "serialized": { + "method": "GET", + "uri": "/ConstantAndVariableQueryString?foo=bar&baz=bam&maybeSet=yes", + "body": "" + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "SubStructure": { - "shape": "SubStructure" - }, - "Description": { - "shape": "StringType" - } - } - }, - "SubStructure": { - "type": "structure", - "members": { - "Foo": { - "shape": "StringType" - }, - "Bar": { - "shape": "StringType" - } - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for ConstantQueryString operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "ConstantQueryStringInput": { + "type": "structure", + "required": [ + "hello" + ], + "members": { + "hello": { + "shape": "String", + "location": "uri", + "locationName": "hello" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "ConstantQueryString", + "given": { + "name": "ConstantQueryString", + "http": { + "method": "GET", + "requestUri": "/ConstantQueryString/{hello}?foo=bar&hello", + "responseCode": 200 + }, + "input": { + "shape": "ConstantQueryStringInput" + }, + "documentation": "

This example uses a constant query string parameters and a label. This simply tests that labels and query string parameters are compatible. The fixed query string parameter named "hello" should in no way conflict with the label, {hello}.

" + }, + "description": "Includes constant query string parameters", + "params": { + "hello": "hi" + }, + "serialized": { + "method": "GET", + "uri": "/ConstantQueryString/hi?foo=bar&hello", + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/2014-01-01/hostedzone" - }, - "input": { - "shape": "InputShape", - "locationName": "OperationRequest", - "xmlNamespace": {"uri": "https://foo/"} - }, - "name": "OperationName" - }, - "params": { - "SubStructure": {}, - "Description": "baz" - }, - "serialized": { - "method": "POST", - "body": "baz", - "uri": "/2014-01-01/hostedzone", - "headers": {} - } - } - ] - }, - { - "description": "Non flattened lists", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" + { + "description": "Test cases for EmptyInputAndEmptyOutput operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "EmptyInputAndEmptyOutputInput": { + "type": "structure", + "members": {} + } + }, + "cases": [ + { + "id": "EmptyInputAndEmptyOutput", + "given": { + "name": "EmptyInputAndEmptyOutput", + "http": { + "method": "POST", + "requestUri": "/EmptyInputAndEmptyOutput", + "responseCode": 200 + }, + "input": { + "shape": "EmptyInputAndEmptyOutputInput" + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response payload because the operation has an empty input and empty output structure that reuses the same shape. While this should be rare, code generators must support this.

" + }, + "description": "Empty input serializes no payload", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/EmptyInputAndEmptyOutput", + "body": "" + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "ListParam": { - "shape": "ListShape" - } - } - }, - "ListShape": { - "type": "list", - "member": { - "shape": "StringType" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for EndpointOperation operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": {}, + "cases": [ + { + "id": "RestXmlEndpointTrait", + "given": { + "name": "EndpointOperation", + "http": { + "method": "POST", + "requestUri": "/EndpointOperation", + "responseCode": 200 + }, + "endpoint": { + "hostPrefix": "foo." + } + }, + "description": "Operations can prepend to the given host if they define the\nendpoint trait.", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/EndpointOperation", + "body": "", + "host": "foo.example.com" + } + } + ], + "clientEndpoint": "https://example.com" }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/2014-01-01/hostedzone" - }, - "input": { - "shape": "InputShape", - "locationName": "OperationRequest", - "xmlNamespace": {"uri": "https://foo/"} - }, - "name": "OperationName" - }, - "params": { - "ListParam": [ - "one", - "two", - "three" - ] - }, - "serialized": { - "method": "POST", - "body": "onetwothree", - "uri": "/2014-01-01/hostedzone", - "headers": {} - } - } - ] - }, - { - "description": "Non flattened lists with locationName", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" + { + "description": "Test cases for EndpointWithHostLabelHeaderOperation operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HostLabelHeaderInput": { + "type": "structure", + "required": [ + "accountId" + ], + "members": { + "accountId": { + "shape": "String", + "hostLabel": true, + "location": "header", + "locationName": "X-Amz-Account-Id" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestXmlEndpointTraitWithHostLabelAndHttpBinding", + "given": { + "name": "EndpointWithHostLabelHeaderOperation", + "http": { + "method": "POST", + "requestUri": "/EndpointWithHostLabelHeaderOperation", + "responseCode": 200 + }, + "input": { + "shape": "HostLabelHeaderInput" + }, + "endpoint": { + "hostPrefix": "{accountId}." + } + }, + "description": "Operations can prepend to the given host if they define the\nendpoint trait, and can use the host label trait to define\nfurther customization based on user input. The label must also\nbe serialized in into any other location it is bound to, such\nas the body or in this case an http header.", + "params": { + "accountId": "bar" + }, + "serialized": { + "method": "POST", + "uri": "/EndpointWithHostLabelHeaderOperation", + "body": "", + "headers": { + "X-Amz-Account-Id": "bar" + }, + "host": "bar.example.com" + } + } + ], + "clientEndpoint": "https://example.com" }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "ListParam": { - "shape": "ListShape", - "locationName": "AlternateName" - } - } - }, - "ListShape": { - "type": "list", - "member": { - "shape": "StringType", - "locationName": "NotMember" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for EndpointWithHostLabelOperation operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "EndpointWithHostLabelOperationRequest": { + "type": "structure", + "required": [ + "label" + ], + "members": { + "label": { + "shape": "String", + "hostLabel": true + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestXmlEndpointTraitWithHostLabel", + "given": { + "name": "EndpointWithHostLabelOperation", + "http": { + "method": "POST", + "requestUri": "/EndpointWithHostLabelOperation", + "responseCode": 200 + }, + "input": { + "shape": "EndpointWithHostLabelOperationRequest", + "locationName": "EndpointWithHostLabelOperationRequest" + }, + "endpoint": { + "hostPrefix": "foo.{label}." + } + }, + "description": "Operations can prepend to the given host if they define the\nendpoint trait, and can use the host label trait to define\nfurther customization based on user input.", + "params": { + "label": "bar" + }, + "serialized": { + "method": "POST", + "uri": "/EndpointWithHostLabelOperation", + "body": "\n \n\n", + "host": "foo.bar.example.com" + } + } + ], + "clientEndpoint": "https://example.com" }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/2014-01-01/hostedzone" - }, - "input": { - "shape": "InputShape", - "locationName": "OperationRequest", - "xmlNamespace": {"uri": "https://foo/"} - }, - "name": "OperationName" - }, - "params": { - "ListParam": [ - "one", - "two", - "three" - ] - }, - "serialized": { - "method": "POST", - "body": "onetwothree", - "uri": "/2014-01-01/hostedzone", - "headers": {} - } - } - ] - }, - { - "description": "Flattened lists", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" + { + "description": "Test cases for FlattenedXmlMap operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "FlattenedXmlMapRequest": { + "type": "structure", + "members": { + "myMap": { + "shape": "FooEnumMap", + "flattened": true + } + } + }, + "FooEnumMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "FooEnum" + } + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "FlattenedXmlMap", + "given": { + "name": "FlattenedXmlMap", + "http": { + "method": "POST", + "requestUri": "/FlattenedXmlMap", + "responseCode": 200 + }, + "input": { + "shape": "FlattenedXmlMapRequest", + "locationName": "FlattenedXmlMapRequest" + }, + "documentation": "

Flattened maps

" + }, + "description": "Serializes flattened XML maps in requests", + "params": { + "myMap": { + "foo": "Foo", + "baz": "Baz" + } + }, + "serialized": { + "method": "POST", + "uri": "/FlattenedXmlMap", + "body": "\n \n foo\n Foo\n \n \n baz\n Baz\n \n", + "headers": { + "Content-Type": "application/xml" + } + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "ListParam": { - "shape": "ListShape" - } - } - }, - "ListShape": { - "type": "list", - "member": { - "shape": "StringType" - }, - "flattened": true - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for FlattenedXmlMapWithXmlName operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "FlattenedXmlMapWithXmlNameRequest": { + "type": "structure", + "members": { + "myMap": { + "shape": "FlattenedXmlMapWithXmlNameInputOutputMap", + "flattened": true, + "locationName": "KVP" + } + } + }, + "FlattenedXmlMapWithXmlNameInputOutputMap": { + "type": "map", + "key": { + "shape": "String", + "locationName": "K" + }, + "value": { + "shape": "String", + "locationName": "V" + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "FlattenedXmlMapWithXmlName", + "given": { + "name": "FlattenedXmlMapWithXmlName", + "http": { + "method": "POST", + "requestUri": "/FlattenedXmlMapWithXmlName", + "responseCode": 200 + }, + "input": { + "shape": "FlattenedXmlMapWithXmlNameRequest", + "locationName": "FlattenedXmlMapWithXmlNameRequest" + }, + "documentation": "

Flattened maps with @xmlName

" + }, + "description": "Serializes flattened XML maps in requests that have xmlName on members", + "params": { + "myMap": { + "a": "A", + "b": "B" + } + }, + "serialized": { + "method": "POST", + "uri": "/FlattenedXmlMapWithXmlName", + "body": "\n \n a\n A\n \n \n b\n B\n \n", + "headers": { + "Content-Type": "application/xml" + } + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/2014-01-01/hostedzone" - }, - "input": { - "shape": "InputShape", - "locationName": "OperationRequest", - "xmlNamespace": {"uri": "https://foo/"} - }, - "name": "OperationName" - }, - "params": { - "ListParam": [ - "one", - "two", - "three" - ] - }, - "serialized": { - "method": "POST", - "body": "onetwothree", - "uri": "/2014-01-01/hostedzone", - "headers": {} - } - } - ] - }, - { - "description": "Flattened lists with locationName", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" + { + "description": "Test cases for HttpEnumPayload operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "EnumPayloadInput": { + "type": "structure", + "members": { + "payload": { + "shape": "StringEnum" + } + }, + "payload": "payload" + }, + "StringEnum": { + "type": "string", + "enum": [ + "enumvalue" + ] + } + }, + "cases": [ + { + "id": "RestXmlEnumPayloadRequest", + "given": { + "name": "HttpEnumPayload", + "http": { + "method": "POST", + "requestUri": "/EnumPayload", + "responseCode": 200 + }, + "input": { + "shape": "EnumPayloadInput" + } + }, + "params": { + "payload": "enumvalue" + }, + "serialized": { + "method": "POST", + "uri": "/EnumPayload", + "body": "enumvalue" + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "ListParam": { - "shape": "ListShape", - "locationName": "item" - } - } - }, - "ListShape": { - "type": "list", - "member": { - "shape": "StringType" - }, - "flattened": true - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for HttpPayloadTraits operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPayloadTraitsInputOutput": { + "type": "structure", + "members": { + "foo": { + "shape": "String", + "location": "header", + "locationName": "X-Foo" + }, + "blob": { + "shape": "Blob" + } + }, + "payload": "blob" + }, + "String": { + "type": "string" + }, + "Blob": { + "type": "blob" + } + }, + "cases": [ + { + "id": "HttpPayloadTraitsWithBlob", + "given": { + "name": "HttpPayloadTraits", + "http": { + "method": "POST", + "requestUri": "/HttpPayloadTraits", + "responseCode": 200 + }, + "input": { + "shape": "HttpPayloadTraitsInputOutput" + }, + "documentation": "

This example serializes a blob shape in the payload.

In this example, no XML document is synthesized because the payload is not a structure or a union type.

" + }, + "description": "Serializes a blob in the HTTP payload", + "params": { + "foo": "Foo", + "blob": "blobby blob blob" + }, + "serialized": { + "method": "POST", + "uri": "/HttpPayloadTraits", + "body": "blobby blob blob", + "headers": { + "X-Foo": "Foo" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "HttpPayloadTraitsWithNoBlobBody", + "given": { + "name": "HttpPayloadTraits", + "http": { + "method": "POST", + "requestUri": "/HttpPayloadTraits", + "responseCode": 200 + }, + "input": { + "shape": "HttpPayloadTraitsInputOutput" + }, + "documentation": "

This example serializes a blob shape in the payload.

In this example, no XML document is synthesized because the payload is not a structure or a union type.

" + }, + "description": "Serializes an empty blob in the HTTP payload", + "params": { + "foo": "Foo" + }, + "serialized": { + "method": "POST", + "uri": "/HttpPayloadTraits", + "body": "", + "headers": { + "X-Foo": "Foo" + } + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/2014-01-01/hostedzone" - }, - "input": { - "shape": "InputShape", - "locationName": "OperationRequest", - "xmlNamespace": {"uri": "https://foo/"} - }, - "name": "OperationName" - }, - "params": { - "ListParam": [ - "one", - "two", - "three" - ] - }, - "serialized": { - "method": "POST", - "body": "onetwothree", - "uri": "/2014-01-01/hostedzone", - "headers": {} - } - } - ] - }, - { - "description": "List of structures", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" + { + "description": "Test cases for HttpPayloadWithMemberXmlName operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPayloadWithMemberXmlNameInputOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "PayloadWithXmlName", + "locationName": "Hola" + } + }, + "payload": "nested" + }, + "PayloadWithXmlName": { + "type": "structure", + "members": { + "name": { + "shape": "String" + } + }, + "locationName": "Hello" + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "HttpPayloadWithMemberXmlName", + "given": { + "name": "HttpPayloadWithMemberXmlName", + "http": { + "method": "PUT", + "requestUri": "/HttpPayloadWithMemberXmlName", + "responseCode": 200 + }, + "input": { + "shape": "HttpPayloadWithMemberXmlNameInputOutput" + }, + "documentation": "

The following example serializes a payload that uses an XML name on the member, changing the wrapper name.

", + "idempotent": true + }, + "description": "Serializes a structure in the payload using a wrapper name based on member xmlName", + "params": { + "nested": { + "name": "Phreddy" + } + }, + "serialized": { + "method": "PUT", + "uri": "/HttpPayloadWithMemberXmlName", + "body": "Phreddy", + "headers": { + "Content-Type": "application/xml" + }, + "requireHeaders": [ + "Content-Length" + ] + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "ListParam": { - "shape": "ListShape", - "locationName": "item" - } - } - }, - "ListShape": { - "type": "list", - "member": { - "shape": "SingleFieldStruct" - }, - "flattened": true - }, - "StringType": { - "type": "string" - }, - "SingleFieldStruct": { - "type": "structure", - "members": { - "Element": { - "shape": "StringType", - "locationName": "value" - } - } - } + { + "description": "Test cases for HttpPayloadWithStructure operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPayloadWithStructureInputOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "NestedPayload", + "locationName": "NestedPayload" + } + }, + "payload": "nested" + }, + "NestedPayload": { + "type": "structure", + "members": { + "greeting": { + "shape": "String" + }, + "name": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "HttpPayloadWithStructure", + "given": { + "name": "HttpPayloadWithStructure", + "http": { + "method": "PUT", + "requestUri": "/HttpPayloadWithStructure", + "responseCode": 200 + }, + "input": { + "shape": "HttpPayloadWithStructureInputOutput" + }, + "documentation": "

This example serializes a structure in the payload.

Note that serializing a structure changes the wrapper element name to match the targeted structure.

", + "idempotent": true + }, + "description": "Serializes a structure in the payload", + "params": { + "nested": { + "greeting": "hello", + "name": "Phreddy" + } + }, + "serialized": { + "method": "PUT", + "uri": "/HttpPayloadWithStructure", + "body": "\n hello\n Phreddy\n\n", + "headers": { + "Content-Type": "application/xml" + }, + "requireHeaders": [ + "Content-Length" + ] + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/2014-01-01/hostedzone" - }, - "input": { - "shape": "InputShape", - "locationName": "OperationRequest", - "xmlNamespace": {"uri": "https://foo/"} - }, - "name": "OperationName" - }, - "params": { - "ListParam": [ - { - "Element": "one" - }, - { - "Element": "two" - }, - { - "Element": "three" - } - ] - }, - "serialized": { - "method": "POST", - "body": "onetwothree", - "uri": "/2014-01-01/hostedzone", - "headers": {} - } - } - ] - }, - { - "description": "Blob shapes", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" + { + "description": "Test cases for HttpPayloadWithUnion operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPayloadWithUnionInputOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "UnionPayload", + "locationName": "nested" + } + }, + "payload": "nested" + }, + "UnionPayload": { + "type": "structure", + "members": { + "greeting": { + "shape": "String" + } + }, + "union": true + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestXmlHttpPayloadWithUnion", + "given": { + "name": "HttpPayloadWithUnion", + "http": { + "method": "PUT", + "requestUri": "/HttpPayloadWithUnion", + "responseCode": 200 + }, + "input": { + "shape": "HttpPayloadWithUnionInputOutput" + }, + "documentation": "

This example serializes a union in the payload.

", + "idempotent": true + }, + "description": "Serializes a union in the payload.", + "params": { + "nested": { + "greeting": "hello" + } + }, + "serialized": { + "method": "PUT", + "uri": "/HttpPayloadWithUnion", + "body": "\n hello\n", + "headers": { + "Content-Type": "application/xml" + }, + "requireHeaders": [ + "Content-Length" + ] + } + }, + { + "id": "RestXmlHttpPayloadWithUnsetUnion", + "given": { + "name": "HttpPayloadWithUnion", + "http": { + "method": "PUT", + "requestUri": "/HttpPayloadWithUnion", + "responseCode": 200 + }, + "input": { + "shape": "HttpPayloadWithUnionInputOutput" + }, + "documentation": "

This example serializes a union in the payload.

", + "idempotent": true + }, + "description": "No payload is sent if the union has no value.", + "params": {}, + "serialized": { + "method": "PUT", + "uri": "/HttpPayloadWithUnion", + "body": "" + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "StructureParam": { - "shape": "StructureShape" - } - } - }, - "StructureShape": { - "type": "structure", - "members": { - "b": { - "shape": "BShape" - } - } - }, - "BShape": { - "type": "blob" - } + { + "description": "Test cases for HttpPayloadWithXmlName operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPayloadWithXmlNameInputOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "PayloadWithXmlName", + "locationName": "nested" + } + }, + "payload": "nested" + }, + "PayloadWithXmlName": { + "type": "structure", + "members": { + "name": { + "shape": "String" + } + }, + "locationName": "Hello" + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "HttpPayloadWithXmlName", + "given": { + "name": "HttpPayloadWithXmlName", + "http": { + "method": "PUT", + "requestUri": "/HttpPayloadWithXmlName", + "responseCode": 200 + }, + "input": { + "shape": "HttpPayloadWithXmlNameInputOutput" + }, + "documentation": "

The following example serializes a payload that uses an XML name, changing the wrapper name.

", + "idempotent": true + }, + "description": "Serializes a structure in the payload using a wrapper name based on xmlName", + "params": { + "nested": { + "name": "Phreddy" + } + }, + "serialized": { + "method": "PUT", + "uri": "/HttpPayloadWithXmlName", + "body": "Phreddy", + "headers": { + "Content-Type": "application/xml" + }, + "requireHeaders": [ + "Content-Length" + ] + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/2014-01-01/hostedzone" - }, - "input": { - "shape": "InputShape", - "locationName": "OperationRequest", - "xmlNamespace": {"uri": "https://foo/"} - }, - "name": "OperationName" - }, - "params": { - "StructureParam": { - "b": "foo" - } - }, - "serialized": { - "method": "POST", - "body": "Zm9v", - "uri": "/2014-01-01/hostedzone", - "headers": {} - } - } - ] - }, - { - "description": "Timestamp shapes", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" + { + "description": "Test cases for HttpPayloadWithXmlNamespace operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPayloadWithXmlNamespaceInputOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "PayloadWithXmlNamespace", + "locationName": "nested" + } + }, + "payload": "nested" + }, + "PayloadWithXmlNamespace": { + "type": "structure", + "members": { + "name": { + "shape": "String" + } + }, + "xmlNamespace": "http://foo.com" + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "HttpPayloadWithXmlNamespace", + "given": { + "name": "HttpPayloadWithXmlNamespace", + "http": { + "method": "PUT", + "requestUri": "/HttpPayloadWithXmlNamespace", + "responseCode": 200 + }, + "input": { + "shape": "HttpPayloadWithXmlNamespaceInputOutput" + }, + "documentation": "

The following example serializes a payload that uses an XML namespace.

", + "idempotent": true + }, + "description": "Serializes a structure in the payload using a wrapper with an XML namespace", + "params": { + "nested": { + "name": "Phreddy" + } + }, + "serialized": { + "method": "PUT", + "uri": "/HttpPayloadWithXmlNamespace", + "body": "\n Phreddy\n", + "headers": { + "Content-Type": "application/xml" + }, + "requireHeaders": [ + "Content-Length" + ] + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "TimeArg": { - "shape": "TimestampType" - }, - "TimeArgInHeader": { - "shape": "TimestampType", - "location": "header", - "locationName": "x-amz-timearg" - }, - "TimeArgInQuery": { - "shape": "TimestampType", - "location": "querystring", - "locationName": "TimeQuery" - }, - "TimeCustom": { - "timestampFormat": "rfc822", - "shape": "TimestampType" - }, - "TimeCustomInHeader": { - "timestampFormat": "unixTimestamp", - "shape": "TimestampType", - "location": "header", - "locationName": "x-amz-timecustom-header" - }, - "TimeCustomInQuery": { - "timestampFormat": "unixTimestamp", - "shape": "TimestampType", - "location": "querystring", - "locationName": "TimeCustomQuery" - }, - "TimeFormat": { - "shape": "TimestampFormatRfcType" - }, - "TimeFormatInHeader": { - "shape": "TimestampFormatUnixType", - "location": "header", - "locationName": "x-amz-timeformat-header" - }, - "TimeFormatInQuery": { - "shape": "TimestampFormatUnixType", - "location": "querystring", - "locationName": "TimeFormatQuery" - } - } - }, - "TimestampFormatRfcType": { - "timestampFormat": "rfc822", - "type": "timestamp" - }, - "TimestampFormatUnixType": { - "timestampFormat": "unixTimestamp", - "type": "timestamp" - }, - "TimestampType": { - "type": "timestamp" - } + { + "description": "Test cases for HttpPayloadWithXmlNamespaceAndPrefix operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPayloadWithXmlNamespaceAndPrefixInputOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "PayloadWithXmlNamespaceAndPrefix", + "locationName": "nested" + } + }, + "payload": "nested" + }, + "PayloadWithXmlNamespaceAndPrefix": { + "type": "structure", + "members": { + "name": { + "shape": "String" + } + }, + "xmlNamespace": { + "prefix": "baz", + "uri": "http://foo.com" + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "HttpPayloadWithXmlNamespaceAndPrefix", + "given": { + "name": "HttpPayloadWithXmlNamespaceAndPrefix", + "http": { + "method": "PUT", + "requestUri": "/HttpPayloadWithXmlNamespaceAndPrefix", + "responseCode": 200 + }, + "input": { + "shape": "HttpPayloadWithXmlNamespaceAndPrefixInputOutput" + }, + "documentation": "

The following example serializes a payload that uses an XML namespace.

", + "idempotent": true + }, + "description": "Serializes a structure in the payload using a wrapper with an XML namespace", + "params": { + "nested": { + "name": "Phreddy" + } + }, + "serialized": { + "method": "PUT", + "uri": "/HttpPayloadWithXmlNamespaceAndPrefix", + "body": "\n Phreddy\n", + "headers": { + "Content-Type": "application/xml" + }, + "requireHeaders": [ + "Content-Length" + ] + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/2014-01-01/hostedzone" - }, - "input": { - "shape": "InputShape", - "locationName": "TimestampStructure", - "xmlNamespace": {"uri": "https://foo/"} - }, - "name": "OperationName" - }, - "params": { - "TimeArg": 1422172800, - "TimeArgInQuery": 1422172800, - "TimeArgInHeader": 1422172800, - "TimeCustom": 1422172800, - "TimeCustomInQuery": 1422172800, - "TimeCustomInHeader": 1422172800, - "TimeFormat": 1422172800, - "TimeFormatInQuery": 1422172800, - "TimeFormatInHeader": 1422172800 - }, - "serialized": { - "method": "POST", - "body": "2015-01-25T08:00:00ZSun, 25 Jan 2015 08:00:00 GMTSun, 25 Jan 2015 08:00:00 GMT", - "uri": "/2014-01-01/hostedzone?TimeQuery=2015-01-25T08%3A00%3A00Z&TimeCustomQuery=1422172800&TimeFormatQuery=1422172800", - "headers": { - "x-amz-timearg": "Sun, 25 Jan 2015 08:00:00 GMT", - "x-amz-timecustom-header": "1422172800", - "x-amz-timeformat-header": "1422172800" - } - } - } - ] - }, - { - "description": "Header maps", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" + { + "description": "Test cases for HttpPrefixHeaders operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPrefixHeadersInputOutput": { + "type": "structure", + "members": { + "foo": { + "shape": "String", + "location": "header", + "locationName": "X-Foo" + }, + "fooMap": { + "shape": "FooPrefixHeaders", + "location": "headers", + "locationName": "X-Foo-" + } + } + }, + "String": { + "type": "string" + }, + "FooPrefixHeaders": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "String" + } + } + }, + "cases": [ + { + "id": "HttpPrefixHeadersArePresent", + "given": { + "name": "HttpPrefixHeaders", + "http": { + "method": "GET", + "requestUri": "/HttpPrefixHeaders", + "responseCode": 200 + }, + "input": { + "shape": "HttpPrefixHeadersInputOutput" + }, + "documentation": "

This examples adds headers to the input of a request and response by prefix.

" + }, + "description": "Adds headers by prefix", + "params": { + "foo": "Foo", + "fooMap": { + "Abc": "Abc value", + "Def": "Def value" + } + }, + "serialized": { + "method": "GET", + "uri": "/HttpPrefixHeaders", + "body": "", + "headers": { + "X-Foo": "Foo", + "X-Foo-Abc": "Abc value", + "X-Foo-Def": "Def value" + } + } + }, + { + "id": "HttpPrefixHeadersAreNotPresent", + "given": { + "name": "HttpPrefixHeaders", + "http": { + "method": "GET", + "requestUri": "/HttpPrefixHeaders", + "responseCode": 200 + }, + "input": { + "shape": "HttpPrefixHeadersInputOutput" + }, + "documentation": "

This examples adds headers to the input of a request and response by prefix.

" + }, + "description": "No prefix headers are serialized because the value is empty", + "params": { + "foo": "Foo", + "fooMap": {} + }, + "serialized": { + "method": "GET", + "uri": "/HttpPrefixHeaders", + "body": "", + "headers": { + "X-Foo": "Foo" + } + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "foo": { - "shape": "FooShape" - } - } - }, - "FooShape": { - "type": "map", - "location": "headers", - "locationName": "x-foo-", - "key": { - "shape": "FooKeyValue" - }, - "value": { - "shape": "FooKeyValue" - } - }, - "FooKeyValue": { - "type": "string" - } + { + "description": "Test cases for HttpRequestWithFloatLabels operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpRequestWithFloatLabelsInput": { + "type": "structure", + "required": [ + "float", + "double" + ], + "members": { + "float": { + "shape": "Float", + "location": "uri", + "locationName": "float" + }, + "double": { + "shape": "Double", + "location": "uri", + "locationName": "double" + } + } + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + } + }, + "cases": [ + { + "id": "RestXmlSupportsNaNFloatLabels", + "given": { + "name": "HttpRequestWithFloatLabels", + "http": { + "method": "GET", + "requestUri": "/FloatHttpLabels/{float}/{double}", + "responseCode": 200 + }, + "input": { + "shape": "HttpRequestWithFloatLabelsInput" + } + }, + "description": "Supports handling NaN float label values.", + "params": { + "float": "NaN", + "double": "NaN" + }, + "serialized": { + "method": "GET", + "uri": "/FloatHttpLabels/NaN/NaN", + "body": "" + } + }, + { + "id": "RestXmlSupportsInfinityFloatLabels", + "given": { + "name": "HttpRequestWithFloatLabels", + "http": { + "method": "GET", + "requestUri": "/FloatHttpLabels/{float}/{double}", + "responseCode": 200 + }, + "input": { + "shape": "HttpRequestWithFloatLabelsInput" + } + }, + "description": "Supports handling Infinity float label values.", + "params": { + "float": "Infinity", + "double": "Infinity" + }, + "serialized": { + "method": "GET", + "uri": "/FloatHttpLabels/Infinity/Infinity", + "body": "" + } + }, + { + "id": "RestXmlSupportsNegativeInfinityFloatLabels", + "given": { + "name": "HttpRequestWithFloatLabels", + "http": { + "method": "GET", + "requestUri": "/FloatHttpLabels/{float}/{double}", + "responseCode": 200 + }, + "input": { + "shape": "HttpRequestWithFloatLabelsInput" + } + }, + "description": "Supports handling -Infinity float label values.", + "params": { + "float": "-Infinity", + "double": "-Infinity" + }, + "serialized": { + "method": "GET", + "uri": "/FloatHttpLabels/-Infinity/-Infinity", + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/" - }, - "input": { - "shape": "InputShape", - "locationName": "OperationRequest", - "xmlNamespace": {"uri": "https://foo/"} - }, - "name": "OperationName" - }, - "params": { - "foo": { - "a": "b", - "c": "d" - } - }, - "serialized": { - "method": "POST", - "body": "", - "uri": "/", - "headers": { - "x-foo-a": "b", - "x-foo-c": "d" - } - } - } - ] - }, - { - "description": "Querystring list of strings", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" + { + "description": "Test cases for HttpRequestWithGreedyLabelInPath operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpRequestWithGreedyLabelInPathInput": { + "type": "structure", + "required": [ + "foo", + "baz" + ], + "members": { + "foo": { + "shape": "String", + "location": "uri", + "locationName": "foo" + }, + "baz": { + "shape": "String", + "location": "uri", + "locationName": "baz" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "HttpRequestWithGreedyLabelInPath", + "given": { + "name": "HttpRequestWithGreedyLabelInPath", + "http": { + "method": "GET", + "requestUri": "/HttpRequestWithGreedyLabelInPath/foo/{foo}/baz/{baz+}", + "responseCode": 200 + }, + "input": { + "shape": "HttpRequestWithGreedyLabelInPathInput" + } + }, + "description": "Serializes greedy labels and normal labels", + "params": { + "foo": "hello", + "baz": "there/guy" + }, + "serialized": { + "method": "GET", + "uri": "/HttpRequestWithGreedyLabelInPath/foo/hello/baz/there/guy", + "body": "" + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "Items": { - "shape": "StringList", - "location": "querystring", - "locationName": "item" - } - } - }, - "StringList": { - "type": "list", - "member": { - "shape": "String" - } - }, - "String": { - "type": "string" - } + { + "description": "Test cases for HttpRequestWithLabels operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpRequestWithLabelsInput": { + "type": "structure", + "required": [ + "string", + "short", + "integer", + "long", + "float", + "double", + "boolean", + "timestamp" + ], + "members": { + "string": { + "shape": "String", + "location": "uri", + "locationName": "string" + }, + "short": { + "shape": "Integer", + "location": "uri", + "locationName": "short" + }, + "integer": { + "shape": "Integer", + "location": "uri", + "locationName": "integer" + }, + "long": { + "shape": "Long", + "location": "uri", + "locationName": "long" + }, + "float": { + "shape": "Float", + "location": "uri", + "locationName": "float" + }, + "double": { + "shape": "Double", + "location": "uri", + "locationName": "double" + }, + "boolean": { + "shape": "Boolean", + "documentation": "

Serialized in the path as true or false.

", + "location": "uri", + "locationName": "boolean" + }, + "timestamp": { + "shape": "Timestamp", + "documentation": "

Note that this member has no format, so it's serialized as an RFC 3399 date-time.

", + "location": "uri", + "locationName": "timestamp" + } + } + }, + "String": { + "type": "string" + }, + "Integer": { + "type": "integer", + "box": true + }, + "Long": { + "type": "long", + "box": true + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Timestamp": { + "type": "timestamp" + } + }, + "cases": [ + { + "id": "InputWithHeadersAndAllParams", + "given": { + "name": "HttpRequestWithLabels", + "http": { + "method": "GET", + "requestUri": "/HttpRequestWithLabels/{string}/{short}/{integer}/{long}/{float}/{double}/{boolean}/{timestamp}", + "responseCode": 200 + }, + "input": { + "shape": "HttpRequestWithLabelsInput" + }, + "documentation": "

The example tests how requests are serialized when there's no input payload but there are HTTP labels.

" + }, + "description": "Sends a GET request that uses URI label bindings", + "params": { + "string": "string", + "short": 1, + "integer": 2, + "long": 3, + "float": 4.1, + "double": 5.1, + "boolean": true, + "timestamp": 1576540098 + }, + "serialized": { + "method": "GET", + "uri": "/HttpRequestWithLabels/string/1/2/3/4.1/5.1/true/2019-12-16T23%3A48%3A18Z", + "body": "" + } + }, + { + "id": "HttpRequestLabelEscaping", + "given": { + "name": "HttpRequestWithLabels", + "http": { + "method": "GET", + "requestUri": "/HttpRequestWithLabels/{string}/{short}/{integer}/{long}/{float}/{double}/{boolean}/{timestamp}", + "responseCode": 200 + }, + "input": { + "shape": "HttpRequestWithLabelsInput" + }, + "documentation": "

The example tests how requests are serialized when there's no input payload but there are HTTP labels.

" + }, + "description": "Sends a GET request that uses URI label bindings", + "params": { + "string": " %:/?#[]@!$&'()*+,;=😹", + "short": 1, + "integer": 2, + "long": 3, + "float": 4.1, + "double": 5.1, + "boolean": true, + "timestamp": 1576540098 + }, + "serialized": { + "method": "GET", + "uri": "/HttpRequestWithLabels/%20%25%3A%2F%3F%23%5B%5D%40%21%24%26%27%28%29%2A%2B%2C%3B%3D%F0%9F%98%B9/1/2/3/4.1/5.1/true/2019-12-16T23%3A48%3A18Z", + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "GET", - "requestUri": "/path" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "Items": ["value1", "value2"] - }, - "serialized": { - "body": "", - "uri": "/path?item=value1&item=value2", - "headers": {} - } - } - ] - }, - { - "description": "String to string maps in querystring", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" + { + "description": "Test cases for HttpRequestWithLabelsAndTimestampFormat operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpRequestWithLabelsAndTimestampFormatInput": { + "type": "structure", + "required": [ + "memberEpochSeconds", + "memberHttpDate", + "memberDateTime", + "defaultFormat", + "targetEpochSeconds", + "targetHttpDate", + "targetDateTime" + ], + "members": { + "memberEpochSeconds": { + "shape": "SyntheticTimestamp_epoch_seconds", + "location": "uri", + "locationName": "memberEpochSeconds" + }, + "memberHttpDate": { + "shape": "SyntheticTimestamp_http_date", + "location": "uri", + "locationName": "memberHttpDate" + }, + "memberDateTime": { + "shape": "SyntheticTimestamp_date_time", + "location": "uri", + "locationName": "memberDateTime" + }, + "defaultFormat": { + "shape": "Timestamp", + "location": "uri", + "locationName": "defaultFormat" + }, + "targetEpochSeconds": { + "shape": "EpochSeconds", + "location": "uri", + "locationName": "targetEpochSeconds" + }, + "targetHttpDate": { + "shape": "HttpDate", + "location": "uri", + "locationName": "targetHttpDate" + }, + "targetDateTime": { + "shape": "DateTime", + "location": "uri", + "locationName": "targetDateTime" + } + } + }, + "SyntheticTimestamp_epoch_seconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "SyntheticTimestamp_http_date": { + "type": "timestamp", + "timestampFormat": "rfc822" + }, + "SyntheticTimestamp_date_time": { + "type": "timestamp", + "timestampFormat": "iso8601" + }, + "Timestamp": { + "type": "timestamp" + }, + "EpochSeconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "HttpDate": { + "type": "timestamp", + "timestampFormat": "rfc822" + }, + "DateTime": { + "type": "timestamp", + "timestampFormat": "iso8601" + } + }, + "cases": [ + { + "id": "HttpRequestWithLabelsAndTimestampFormat", + "given": { + "name": "HttpRequestWithLabelsAndTimestampFormat", + "http": { + "method": "GET", + "requestUri": "/HttpRequestWithLabelsAndTimestampFormat/{memberEpochSeconds}/{memberHttpDate}/{memberDateTime}/{defaultFormat}/{targetEpochSeconds}/{targetHttpDate}/{targetDateTime}", + "responseCode": 200 + }, + "input": { + "shape": "HttpRequestWithLabelsAndTimestampFormatInput" + }, + "documentation": "

The example tests how requests serialize different timestamp formats in the URI path.

" + }, + "description": "Serializes different timestamp formats in URI labels", + "params": { + "memberEpochSeconds": 1576540098, + "memberHttpDate": 1576540098, + "memberDateTime": 1576540098, + "defaultFormat": 1576540098, + "targetEpochSeconds": 1576540098, + "targetHttpDate": 1576540098, + "targetDateTime": 1576540098 + }, + "serialized": { + "method": "GET", + "uri": "/HttpRequestWithLabelsAndTimestampFormat/1576540098/Mon%2C%2016%20Dec%202019%2023%3A48%3A18%20GMT/2019-12-16T23%3A48%3A18Z/2019-12-16T23%3A48%3A18Z/1576540098/Mon%2C%2016%20Dec%202019%2023%3A48%3A18%20GMT/2019-12-16T23%3A48%3A18Z", + "body": "" + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "PipelineId": { - "shape": "StringType", - "location": "uri" - }, - "QueryDoc": { - "shape": "MapStringStringType", - "location": "querystring" - } - } - }, - "MapStringStringType": { - "type": "map", - "key": { - "shape": "StringType" - }, - "value": { - "shape": "StringType" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for HttpStringPayload operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "StringPayloadInput": { + "type": "structure", + "members": { + "payload": { + "shape": "String" + } + }, + "payload": "payload" + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestXmlStringPayloadRequest", + "given": { + "name": "HttpStringPayload", + "http": { + "method": "POST", + "requestUri": "/StringPayload", + "responseCode": 200 + }, + "input": { + "shape": "StringPayloadInput" + } + }, + "params": { + "payload": "rawstring" + }, + "serialized": { + "method": "POST", + "uri": "/StringPayload", + "body": "rawstring" + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "GET", - "requestUri": "/2014-01-01/jobsByPipeline/{PipelineId}" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "PipelineId": "foo", - "QueryDoc": { - "bar": "baz", - "fizz": "buzz" - } - }, - "serialized": { - "body": "", - "uri": "/2014-01-01/jobsByPipeline/foo?bar=baz&fizz=buzz", - "headers": {} - } - } - ] - }, - { - "description": "String to string list maps in querystring", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" + { + "description": "Test cases for InputAndOutputWithHeaders operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "InputAndOutputWithHeadersIO": { + "type": "structure", + "members": { + "headerString": { + "shape": "String", + "location": "header", + "locationName": "X-String" + }, + "headerByte": { + "shape": "Integer", + "location": "header", + "locationName": "X-Byte" + }, + "headerShort": { + "shape": "Integer", + "location": "header", + "locationName": "X-Short" + }, + "headerInteger": { + "shape": "Integer", + "location": "header", + "locationName": "X-Integer" + }, + "headerLong": { + "shape": "Long", + "location": "header", + "locationName": "X-Long" + }, + "headerFloat": { + "shape": "Float", + "location": "header", + "locationName": "X-Float" + }, + "headerDouble": { + "shape": "Double", + "location": "header", + "locationName": "X-Double" + }, + "headerTrueBool": { + "shape": "Boolean", + "location": "header", + "locationName": "X-Boolean1" + }, + "headerFalseBool": { + "shape": "Boolean", + "location": "header", + "locationName": "X-Boolean2" + }, + "headerStringList": { + "shape": "StringList", + "location": "header", + "locationName": "X-StringList" + }, + "headerStringSet": { + "shape": "StringSet", + "location": "header", + "locationName": "X-StringSet" + }, + "headerIntegerList": { + "shape": "IntegerList", + "location": "header", + "locationName": "X-IntegerList" + }, + "headerBooleanList": { + "shape": "BooleanList", + "location": "header", + "locationName": "X-BooleanList" + }, + "headerTimestampList": { + "shape": "TimestampList", + "location": "header", + "locationName": "X-TimestampList" + }, + "headerEnum": { + "shape": "FooEnum", + "location": "header", + "locationName": "X-Enum" + }, + "headerEnumList": { + "shape": "FooEnumList", + "location": "header", + "locationName": "X-EnumList" + } + } + }, + "String": { + "type": "string" + }, + "Integer": { + "type": "integer", + "box": true + }, + "Long": { + "type": "long", + "box": true + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringSet": { + "type": "list", + "member": { + "shape": "String" + } + }, + "IntegerList": { + "type": "list", + "member": { + "shape": "Integer" + } + }, + "BooleanList": { + "type": "list", + "member": { + "shape": "Boolean" + } + }, + "TimestampList": { + "type": "list", + "member": { + "shape": "Timestamp" + } + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "Timestamp": { + "type": "timestamp" + } + }, + "cases": [ + { + "id": "InputAndOutputWithStringHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "input": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Tests requests with string header bindings", + "params": { + "headerString": "Hello", + "headerStringList": [ + "a", + "b", + "c" + ], + "headerStringSet": [ + "a", + "b", + "c" + ] + }, + "serialized": { + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "body": "", + "headers": { + "X-String": "Hello", + "X-StringList": "a, b, c", + "X-StringSet": "a, b, c" + } + } + }, + { + "id": "InputAndOutputWithNumericHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "input": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Tests requests with numeric header bindings", + "params": { + "headerByte": 1, + "headerShort": 123, + "headerInteger": 123, + "headerLong": 123, + "headerFloat": 1.1, + "headerDouble": 1.1, + "headerIntegerList": [ + 1, + 2, + 3 + ] + }, + "serialized": { + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "body": "", + "headers": { + "X-Byte": "1", + "X-Double": "1.1", + "X-Float": "1.1", + "X-Integer": "123", + "X-IntegerList": "1, 2, 3", + "X-Long": "123", + "X-Short": "123" + } + } + }, + { + "id": "InputAndOutputWithBooleanHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "input": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Tests requests with boolean header bindings", + "params": { + "headerTrueBool": true, + "headerFalseBool": false, + "headerBooleanList": [ + true, + false, + true + ] + }, + "serialized": { + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "body": "", + "headers": { + "X-Boolean1": "true", + "X-Boolean2": "false", + "X-BooleanList": "true, false, true" + } + } + }, + { + "id": "InputAndOutputWithTimestampHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "input": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Tests requests with timestamp header bindings", + "params": { + "headerTimestampList": [ + 1576540098, + 1576540098 + ] + }, + "serialized": { + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "body": "", + "headers": { + "X-TimestampList": "Mon, 16 Dec 2019 23:48:18 GMT, Mon, 16 Dec 2019 23:48:18 GMT" + } + } + }, + { + "id": "InputAndOutputWithEnumHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "input": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Tests requests with enum header bindings", + "params": { + "headerEnum": "Foo", + "headerEnumList": [ + "Foo", + "Bar", + "Baz" + ] + }, + "serialized": { + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "body": "", + "headers": { + "X-Enum": "Foo", + "X-EnumList": "Foo, Bar, Baz" + } + } + }, + { + "id": "RestXmlSupportsNaNFloatHeaderInputs", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "input": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Supports handling NaN float header values.", + "params": { + "headerFloat": "NaN", + "headerDouble": "NaN" + }, + "serialized": { + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "body": "", + "headers": { + "X-Double": "NaN", + "X-Float": "NaN" + } + } + }, + { + "id": "RestXmlSupportsInfinityFloatHeaderInputs", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "input": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Supports handling Infinity float header values.", + "params": { + "headerFloat": "Infinity", + "headerDouble": "Infinity" + }, + "serialized": { + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "body": "", + "headers": { + "X-Double": "Infinity", + "X-Float": "Infinity" + } + } + }, + { + "id": "RestXmlSupportsNegativeInfinityFloatHeaderInputs", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "input": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "

The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.

" + }, + "description": "Supports handling -Infinity float header values.", + "params": { + "headerFloat": "-Infinity", + "headerDouble": "-Infinity" + }, + "serialized": { + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "body": "", + "headers": { + "X-Double": "-Infinity", + "X-Float": "-Infinity" + } + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "PipelineId": { - "shape": "StringType", - "location": "uri" - }, - "QueryDoc": { - "shape": "MapStringStringListType", - "location": "querystring" - } - } - }, - "MapStringStringListType": { - "type": "map", - "key": { - "shape": "StringType" - }, - "value": { - "shape": "StringListType" - } - }, - "StringListType": { - "type": "list", - "member": { - "shape": "StringType" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for NestedXmlMaps operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "NestedXmlMapsRequest": { + "type": "structure", + "members": { + "nestedMap": { + "shape": "NestedMap" + }, + "flatNestedMap": { + "shape": "NestedMap", + "flattened": true + } + } + }, + "NestedMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "FooEnumMap" + } + }, + "FooEnumMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "FooEnum" + } + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "NestedXmlMapRequest", + "given": { + "name": "NestedXmlMaps", + "http": { + "method": "POST", + "requestUri": "/NestedXmlMaps", + "responseCode": 200 + }, + "input": { + "shape": "NestedXmlMapsRequest", + "locationName": "NestedXmlMapsRequest" + } + }, + "description": "Tests requests with nested maps.", + "params": { + "nestedMap": { + "foo": { + "bar": "Bar" + } + } + }, + "serialized": { + "method": "POST", + "uri": "/NestedXmlMaps", + "body": "\n \n \n foo\n \n \n bar\n Bar\n \n \n \n \n", + "headers": { + "Content-Type": "application/xml" + } + } + }, + { + "id": "FlatNestedXmlMapRequest", + "given": { + "name": "NestedXmlMaps", + "http": { + "method": "POST", + "requestUri": "/NestedXmlMaps", + "responseCode": 200 + }, + "input": { + "shape": "NestedXmlMapsRequest", + "locationName": "NestedXmlMapsRequest" + } + }, + "description": "Tests requests with nested flat maps. Since maps can only be\nflattened when they're structure members, only the outer map is flat.", + "params": { + "flatNestedMap": { + "foo": { + "bar": "Bar" + } + } + }, + "serialized": { + "method": "POST", + "uri": "/NestedXmlMaps", + "body": "\n \n foo\n \n \n bar\n Bar\n \n \n \n", + "headers": { + "Content-Type": "application/xml" + } + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "GET", - "requestUri": "/2014-01-01/jobsByPipeline/{PipelineId}" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "PipelineId": "id", - "QueryDoc": { - "foo": ["bar", "baz"], - "fizz": ["buzz", "pop"] - } - }, - "serialized": { - "body": "", - "uri": "/2014-01-01/jobsByPipeline/id?foo=bar&foo=baz&fizz=buzz&fizz=pop", - "headers": {} - } - } - ] - }, - { - "description": "Boolean in querystring", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" + { + "description": "Test cases for NoInputAndNoOutput operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": {}, + "cases": [ + { + "id": "NoInputAndNoOutput", + "given": { + "name": "NoInputAndNoOutput", + "http": { + "method": "POST", + "requestUri": "/NoInputAndNoOutput", + "responseCode": 200 + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input or output. While this should be rare, code generators must support this.

" + }, + "description": "No input serializes no payload", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/NoInputAndNoOutput", + "body": "" + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "BoolQuery": { - "shape": "BoolType", - "location": "querystring", - "locationName": "bool-query" - } - } - }, - "BoolType": { - "type": "boolean" - } + { + "description": "Test cases for NoInputAndOutput operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": {}, + "cases": [ + { + "id": "NoInputAndOutput", + "given": { + "name": "NoInputAndOutput", + "http": { + "method": "POST", + "requestUri": "/NoInputAndOutputOutput", + "responseCode": 200 + }, + "documentation": "

The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input and the output is empty. While this should be rare, code generators must support this.

" + }, + "description": "No input serializes no payload", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/NoInputAndOutputOutput", + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "GET", - "requestUri": "/path" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "BoolQuery": true - }, - "serialized": { - "body": "", - "uri": "/path?bool-query=true", - "headers": {} - } - }, - { - "given": { - "http": { - "method": "GET", - "requestUri": "/path" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "BoolQuery": false - }, - "serialized": { - "body": "", - "uri": "/path?bool-query=false", - "headers": {} - } - } - ] - }, - { - "description": "String payload", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" + { + "description": "Test cases for NullAndEmptyHeadersClient operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "NullAndEmptyHeadersIO": { + "type": "structure", + "members": { + "a": { + "shape": "String", + "location": "header", + "locationName": "X-A" + }, + "b": { + "shape": "String", + "location": "header", + "locationName": "X-B" + }, + "c": { + "shape": "StringList", + "location": "header", + "locationName": "X-C" + } + } + }, + "String": { + "type": "string" + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + } + }, + "cases": [ + { + "id": "NullAndEmptyHeaders", + "given": { + "name": "NullAndEmptyHeadersClient", + "http": { + "method": "GET", + "requestUri": "/NullAndEmptyHeadersClient", + "responseCode": 200 + }, + "input": { + "shape": "NullAndEmptyHeadersIO" + }, + "documentation": "

Null and empty headers are not sent over the wire.

" + }, + "description": "Do not send null values, empty strings, or empty lists over the wire in headers", + "params": { + "a": null, + "b": "", + "c": [] + }, + "serialized": { + "method": "GET", + "uri": "/NullAndEmptyHeadersClient", + "body": "", + "forbidHeaders": [ + "X-A", + "X-B", + "X-C" + ] + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "foo": { - "shape": "FooShape" - } - }, - "payload": "foo" - }, - "FooShape": { - "type": "string" - } + { + "description": "Test cases for OmitsNullSerializesEmptyString operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "OmitsNullSerializesEmptyStringInput": { + "type": "structure", + "members": { + "nullValue": { + "shape": "String", + "location": "querystring", + "locationName": "Null" + }, + "emptyString": { + "shape": "String", + "location": "querystring", + "locationName": "Empty" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestXmlOmitsNullQuery", + "given": { + "name": "OmitsNullSerializesEmptyString", + "http": { + "method": "GET", + "requestUri": "/OmitsNullSerializesEmptyString", + "responseCode": 200 + }, + "input": { + "shape": "OmitsNullSerializesEmptyStringInput" + }, + "documentation": "

Omits null, but serializes empty string value.

" + }, + "description": "Omits null query values", + "params": { + "nullValue": null + }, + "serialized": { + "method": "GET", + "uri": "/OmitsNullSerializesEmptyString", + "body": "" + } + }, + { + "id": "RestXmlSerializesEmptyString", + "given": { + "name": "OmitsNullSerializesEmptyString", + "http": { + "method": "GET", + "requestUri": "/OmitsNullSerializesEmptyString", + "responseCode": 200 + }, + "input": { + "shape": "OmitsNullSerializesEmptyStringInput" + }, + "documentation": "

Omits null, but serializes empty string value.

" + }, + "description": "Serializes empty query strings", + "params": { + "emptyString": "" + }, + "serialized": { + "method": "GET", + "uri": "/OmitsNullSerializesEmptyString?Empty=", + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "foo": "bar" - }, - "serialized": { - "method": "POST", - "body": "bar", - "uri": "/" - } - } - ] - }, - { - "description": "Blob payload", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" + { + "description": "Test cases for PutWithContentEncoding operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "PutWithContentEncodingInput": { + "type": "structure", + "members": { + "encoding": { + "shape": "String", + "location": "header", + "locationName": "Content-Encoding" + }, + "data": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "SDKAppliedContentEncoding_restXml", + "given": { + "name": "PutWithContentEncoding", + "http": { + "method": "POST", + "requestUri": "/requestcompression/putcontentwithencoding", + "responseCode": 200 + }, + "input": { + "shape": "PutWithContentEncodingInput", + "locationName": "PutWithContentEncodingRequest" + }, + "requestcompression": { + "encodings": [ + "gzip" + ] + } + }, + "description": "Compression algorithm encoding is appended to the Content-Encoding header.", + "params": { + "data": "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\n" + }, + "serialized": { + "method": "POST", + "uri": "/requestcompression/putcontentwithencoding", + "headers": { + "Content-Encoding": "gzip" + } + } + }, + { + "id": "SDKAppendedGzipAfterProvidedEncoding_restXml", + "given": { + "name": "PutWithContentEncoding", + "http": { + "method": "POST", + "requestUri": "/requestcompression/putcontentwithencoding", + "responseCode": 200 + }, + "input": { + "shape": "PutWithContentEncodingInput", + "locationName": "PutWithContentEncodingRequest" + }, + "requestcompression": { + "encodings": [ + "gzip" + ] + } + }, + "description": "Compression algorithm encoding is appended to the Content-Encoding header, and the\nuser-provided content-encoding is in the Content-Encoding header before the\nrequest compression encoding from the HTTP binding.\n", + "params": { + "encoding": "custom", + "data": "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\n" + }, + "serialized": { + "method": "POST", + "uri": "/requestcompression/putcontentwithencoding", + "headers": { + "Content-Encoding": "custom, gzip" + } + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "foo": { - "shape": "FooShape" - } - }, - "payload": "foo" - }, - "FooShape": { - "type": "blob" - } + { + "description": "Test cases for QueryIdempotencyTokenAutoFill operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "QueryIdempotencyTokenAutoFillInput": { + "type": "structure", + "members": { + "token": { + "shape": "String", + "idempotencyToken": true, + "location": "querystring", + "locationName": "token" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "QueryIdempotencyTokenAutoFill", + "given": { + "name": "QueryIdempotencyTokenAutoFill", + "http": { + "method": "POST", + "requestUri": "/QueryIdempotencyTokenAutoFill", + "responseCode": 200 + }, + "input": { + "shape": "QueryIdempotencyTokenAutoFillInput" + }, + "documentation": "

Automatically adds idempotency tokens.

" + }, + "description": "Automatically adds idempotency token when not set", + "params": {}, + "serialized": { + "method": "POST", + "uri": "/QueryIdempotencyTokenAutoFill?token=00000000-0000-4000-8000-000000000000", + "body": "" + } + }, + { + "id": "QueryIdempotencyTokenAutoFillIsSet", + "given": { + "name": "QueryIdempotencyTokenAutoFill", + "http": { + "method": "POST", + "requestUri": "/QueryIdempotencyTokenAutoFill", + "responseCode": 200 + }, + "input": { + "shape": "QueryIdempotencyTokenAutoFillInput" + }, + "documentation": "

Automatically adds idempotency tokens.

" + }, + "description": "Uses the given idempotency token as-is", + "params": { + "token": "00000000-0000-4000-8000-000000000000" + }, + "serialized": { + "method": "POST", + "uri": "/QueryIdempotencyTokenAutoFill?token=00000000-0000-4000-8000-000000000000", + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "foo": "bar" - }, - "serialized": { - "method": "POST", - "body": "bar", - "uri": "/" - } - }, - { - "given": { - "http": { - "method": "POST", - "requestUri": "/" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - }, - "serialized": { - "method": "POST", - "body": "", - "uri": "/" - } - } - ] - }, - { - "description": "Structure payload", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" + { + "description": "Test cases for QueryParamsAsStringListMap operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "QueryParamsAsStringListMapInput": { + "type": "structure", + "members": { + "qux": { + "shape": "String", + "location": "querystring", + "locationName": "corge" + }, + "foo": { + "shape": "StringListMap", + "location": "querystring" + } + } + }, + "String": { + "type": "string" + }, + "StringListMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "StringList" + } + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + } + }, + "cases": [ + { + "id": "RestXmlQueryParamsStringListMap", + "given": { + "name": "QueryParamsAsStringListMap", + "http": { + "method": "POST", + "requestUri": "/StringListMap", + "responseCode": 200 + }, + "input": { + "shape": "QueryParamsAsStringListMapInput" + } + }, + "description": "Serialize query params from map of list strings", + "params": { + "qux": "named", + "foo": { + "baz": [ + "bar", + "qux" + ] + } + }, + "serialized": { + "method": "POST", + "uri": "/StringListMap?corge=named&baz=bar&baz=qux", + "body": "" + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "foo": { - "shape": "FooShape" - } - }, - "payload": "foo" - }, - "FooShape": { - "locationName": "foo", - "type": "structure", - "members": { - "baz": { - "shape": "BazShape" - } - } - }, - "BazShape": { - "type": "string" - } + { + "description": "Test cases for QueryPrecedence operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "QueryPrecedenceInput": { + "type": "structure", + "members": { + "foo": { + "shape": "String", + "location": "querystring", + "locationName": "bar" + }, + "baz": { + "shape": "StringMap", + "location": "querystring" + } + } + }, + "String": { + "type": "string" + }, + "StringMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "String" + } + } + }, + "cases": [ + { + "id": "RestXmlQueryPrecedence", + "given": { + "name": "QueryPrecedence", + "http": { + "method": "POST", + "requestUri": "/Precedence", + "responseCode": 200 + }, + "input": { + "shape": "QueryPrecedenceInput" + } + }, + "description": "Prefer named query parameters when serializing", + "params": { + "foo": "named", + "baz": { + "bar": "fromMap", + "qux": "alsoFromMap" + } + }, + "serialized": { + "method": "POST", + "uri": "/Precedence?bar=named&qux=alsoFromMap", + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "foo": { - "baz": "bar" - } - }, - "serialized": { - "method": "POST", - "body": "bar", - "uri": "/" - } - }, - { - "given": { - "http": { - "method": "POST", - "requestUri": "/" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": {}, - "serialized": { - "method": "POST", - "body": "", - "uri": "/" - } - }, - { - "given": { - "http": { - "method": "POST", - "requestUri": "/" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "foo": {} - }, - "serialized": { - "method": "POST", - "body": "", - "uri": "/" - } - }, - { - "given": { - "http": { - "method": "POST", - "requestUri": "/" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "foo": null - }, - "serialized": { - "method": "POST", - "body": "", - "uri": "/" - } - } - ] - }, - { - "description": "XML Attribute", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" + { + "description": "Test cases for RecursiveShapes operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "RecursiveShapesRequest": { + "type": "structure", + "members": { + "nested": { + "shape": "RecursiveShapesInputOutputNested1" + } + } + }, + "RecursiveShapesInputOutputNested1": { + "type": "structure", + "members": { + "foo": { + "shape": "String" + }, + "nested": { + "shape": "RecursiveShapesInputOutputNested2" + } + } + }, + "String": { + "type": "string" + }, + "RecursiveShapesInputOutputNested2": { + "type": "structure", + "members": { + "bar": { + "shape": "String" + }, + "recursiveMember": { + "shape": "RecursiveShapesInputOutputNested1" + } + } + } + }, + "cases": [ + { + "id": "RecursiveShapes", + "given": { + "name": "RecursiveShapes", + "http": { + "method": "PUT", + "requestUri": "/RecursiveShapes", + "responseCode": 200 + }, + "input": { + "shape": "RecursiveShapesRequest", + "locationName": "RecursiveShapesRequest" + }, + "documentation": "

Recursive shapes

", + "idempotent": true + }, + "description": "Serializes recursive structures", + "params": { + "nested": { + "foo": "Foo1", + "nested": { + "bar": "Bar1", + "recursiveMember": { + "foo": "Foo2", + "nested": { + "bar": "Bar2" + } + } + } + } + }, + "serialized": { + "method": "PUT", + "uri": "/RecursiveShapes", + "body": "\n \n Foo1\n \n Bar1\n \n Foo2\n \n Bar2\n \n \n \n \n\n", + "headers": { + "Content-Type": "application/xml" + } + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "Grant": { - "shape": "Grant" - } - }, - "payload": "Grant" - }, - "Grant": { - "type": "structure", - "locationName": "Grant", - "members": { - "Grantee": { - "shape": "Grantee" - } - } - }, - "Grantee": { - "type": "structure", - "members": { - "Type": { - "shape": "Type", - "locationName": "xsi:type", - "xmlAttribute": true - }, - "EmailAddress": { - "shape": "StringType" - } - }, - "xmlNamespace": { - "prefix": "xsi", - "uri":"http://www.w3.org/2001/XMLSchema-instance" - } - }, - "Type": { - "type": "string" - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for SimpleScalarProperties operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "SimpleScalarPropertiesRequest": { + "type": "structure", + "members": { + "foo": { + "shape": "String", + "location": "header", + "locationName": "X-Foo" + }, + "stringValue": { + "shape": "String" + }, + "trueBooleanValue": { + "shape": "Boolean" + }, + "falseBooleanValue": { + "shape": "Boolean" + }, + "byteValue": { + "shape": "Integer" + }, + "shortValue": { + "shape": "Integer" + }, + "integerValue": { + "shape": "Integer" + }, + "longValue": { + "shape": "Long" + }, + "floatValue": { + "shape": "Float" + }, + "doubleValue": { + "shape": "Double", + "locationName": "DoubleDribble" + } + } + }, + "String": { + "type": "string" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + }, + "Long": { + "type": "long", + "box": true + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + } + }, + "cases": [ + { + "id": "SimpleScalarProperties", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "input": { + "shape": "SimpleScalarPropertiesRequest", + "locationName": "SimpleScalarPropertiesRequest" + }, + "idempotent": true + }, + "description": "Serializes simple scalar properties", + "params": { + "foo": "Foo", + "stringValue": "string", + "trueBooleanValue": true, + "falseBooleanValue": false, + "byteValue": 1, + "shortValue": 2, + "integerValue": 3, + "longValue": 4, + "floatValue": 5.5, + "doubleValue": 6.5 + }, + "serialized": { + "method": "PUT", + "uri": "/SimpleScalarProperties", + "body": "\n string\n true\n false\n 1\n 2\n 3\n 4\n 5.5\n 6.5\n\n", + "headers": { + "Content-Type": "application/xml", + "X-Foo": "Foo" + } + } + }, + { + "id": "SimpleScalarPropertiesWithEscapedCharacter", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "input": { + "shape": "SimpleScalarPropertiesRequest", + "locationName": "SimpleScalarPropertiesRequest" + }, + "idempotent": true + }, + "description": "Serializes string with escaping", + "params": { + "foo": "Foo", + "stringValue": "" + }, + "serialized": { + "method": "PUT", + "uri": "/SimpleScalarProperties", + "body": "\n <string>\n\n", + "headers": { + "Content-Type": "application/xml", + "X-Foo": "Foo" + } + } + }, + { + "id": "SimpleScalarPropertiesWithWhiteSpace", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "input": { + "shape": "SimpleScalarPropertiesRequest", + "locationName": "SimpleScalarPropertiesRequest" + }, + "idempotent": true + }, + "description": "Serializes string containing white space", + "params": { + "foo": "Foo", + "stringValue": " string with white space " + }, + "serialized": { + "method": "PUT", + "uri": "/SimpleScalarProperties", + "body": "\n string with white space \n\n", + "headers": { + "Content-Type": "application/xml", + "X-Foo": "Foo" + } + } + }, + { + "id": "SimpleScalarPropertiesPureWhiteSpace", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "input": { + "shape": "SimpleScalarPropertiesRequest", + "locationName": "SimpleScalarPropertiesRequest" + }, + "idempotent": true + }, + "description": "Serializes string containing exclusively whitespace", + "params": { + "foo": "Foo", + "stringValue": " " + }, + "serialized": { + "method": "PUT", + "uri": "/SimpleScalarProperties", + "body": "\n \n\n", + "headers": { + "Content-Type": "application/xml", + "X-Foo": "Foo" + } + } + }, + { + "id": "RestXmlSupportsNaNFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "input": { + "shape": "SimpleScalarPropertiesRequest", + "locationName": "SimpleScalarPropertiesRequest" + }, + "idempotent": true + }, + "description": "Supports handling NaN float values.", + "params": { + "floatValue": "NaN", + "doubleValue": "NaN" + }, + "serialized": { + "method": "PUT", + "uri": "/SimpleScalarProperties", + "body": "\n NaN\n NaN\n\n", + "headers": { + "Content-Type": "application/xml" + } + } + }, + { + "id": "RestXmlSupportsInfinityFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "input": { + "shape": "SimpleScalarPropertiesRequest", + "locationName": "SimpleScalarPropertiesRequest" + }, + "idempotent": true + }, + "description": "Supports handling Infinity float values.", + "params": { + "floatValue": "Infinity", + "doubleValue": "Infinity" + }, + "serialized": { + "method": "PUT", + "uri": "/SimpleScalarProperties", + "body": "\n Infinity\n Infinity\n\n", + "headers": { + "Content-Type": "application/xml" + } + } + }, + { + "id": "RestXmlSupportsNegativeInfinityFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "input": { + "shape": "SimpleScalarPropertiesRequest", + "locationName": "SimpleScalarPropertiesRequest" + }, + "idempotent": true + }, + "description": "Supports handling -Infinity float values.", + "params": { + "floatValue": "-Infinity", + "doubleValue": "-Infinity" + }, + "serialized": { + "method": "PUT", + "uri": "/SimpleScalarProperties", + "body": "\n -Infinity\n -Infinity\n\n", + "headers": { + "Content-Type": "application/xml" + } + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "Grant": { - "Grantee": { - "EmailAddress": "foo@example.com", - "Type": "CanonicalUser" - } - } - }, - "serialized": { - "method": "POST", - "body": "foo@example.com", - "uri": "/" - } - } - ] - }, - { - "description": "Greedy keys", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" + { + "description": "Test cases for TimestampFormatHeaders operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "TimestampFormatHeadersIO": { + "type": "structure", + "members": { + "memberEpochSeconds": { + "shape": "SyntheticTimestamp_epoch_seconds", + "location": "header", + "locationName": "X-memberEpochSeconds" + }, + "memberHttpDate": { + "shape": "SyntheticTimestamp_http_date", + "location": "header", + "locationName": "X-memberHttpDate" + }, + "memberDateTime": { + "shape": "SyntheticTimestamp_date_time", + "location": "header", + "locationName": "X-memberDateTime" + }, + "defaultFormat": { + "shape": "Timestamp", + "location": "header", + "locationName": "X-defaultFormat" + }, + "targetEpochSeconds": { + "shape": "EpochSeconds", + "location": "header", + "locationName": "X-targetEpochSeconds" + }, + "targetHttpDate": { + "shape": "HttpDate", + "location": "header", + "locationName": "X-targetHttpDate" + }, + "targetDateTime": { + "shape": "DateTime", + "location": "header", + "locationName": "X-targetDateTime" + } + } + }, + "SyntheticTimestamp_epoch_seconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "SyntheticTimestamp_http_date": { + "type": "timestamp", + "timestampFormat": "rfc822" + }, + "SyntheticTimestamp_date_time": { + "type": "timestamp", + "timestampFormat": "iso8601" + }, + "Timestamp": { + "type": "timestamp" + }, + "EpochSeconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "HttpDate": { + "type": "timestamp", + "timestampFormat": "rfc822" + }, + "DateTime": { + "type": "timestamp", + "timestampFormat": "iso8601" + } + }, + "cases": [ + { + "id": "TimestampFormatHeaders", + "given": { + "name": "TimestampFormatHeaders", + "http": { + "method": "POST", + "requestUri": "/TimestampFormatHeaders", + "responseCode": 200 + }, + "input": { + "shape": "TimestampFormatHeadersIO" + }, + "documentation": "

The example tests how timestamp request and response headers are serialized.

" + }, + "description": "Tests how timestamp request headers are serialized", + "params": { + "memberEpochSeconds": 1576540098, + "memberHttpDate": 1576540098, + "memberDateTime": 1576540098, + "defaultFormat": 1576540098, + "targetEpochSeconds": 1576540098, + "targetHttpDate": 1576540098, + "targetDateTime": 1576540098 + }, + "serialized": { + "method": "POST", + "uri": "/TimestampFormatHeaders", + "body": "", + "headers": { + "X-defaultFormat": "Mon, 16 Dec 2019 23:48:18 GMT", + "X-memberDateTime": "2019-12-16T23:48:18Z", + "X-memberEpochSeconds": "1576540098", + "X-memberHttpDate": "Mon, 16 Dec 2019 23:48:18 GMT", + "X-targetDateTime": "2019-12-16T23:48:18Z", + "X-targetEpochSeconds": "1576540098", + "X-targetHttpDate": "Mon, 16 Dec 2019 23:48:18 GMT" + } + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "Bucket": { - "shape": "BucketShape", - "location": "uri" - }, - "Key": { - "shape": "KeyShape", - "location": "uri" - } - } - }, - "BucketShape": { - "type": "string" - }, - "KeyShape": { - "type": "string" - } + { + "description": "Test cases for XmlAttributes operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlAttributesRequest": { + "type": "structure", + "members": { + "foo": { + "shape": "String" + }, + "attr": { + "shape": "String", + "locationName": "test", + "xmlAttribute": true + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "XmlAttributes", + "given": { + "name": "XmlAttributes", + "http": { + "method": "PUT", + "requestUri": "/XmlAttributes", + "responseCode": 200 + }, + "input": { + "shape": "XmlAttributesRequest", + "locationName": "XmlAttributesRequest" + }, + "documentation": "

This example serializes an XML attributes on synthesized document.

", + "idempotent": true + }, + "description": "Serializes XML attributes on the synthesized document", + "params": { + "foo": "hi", + "attr": "test" + }, + "serialized": { + "method": "PUT", + "uri": "/XmlAttributes", + "body": "\n hi\n\n", + "headers": { + "Content-Type": "application/xml" + } + } + }, + { + "id": "XmlAttributesWithEscaping", + "given": { + "name": "XmlAttributes", + "http": { + "method": "PUT", + "requestUri": "/XmlAttributes", + "responseCode": 200 + }, + "input": { + "shape": "XmlAttributesRequest", + "locationName": "XmlAttributesRequest" + }, + "documentation": "

This example serializes an XML attributes on synthesized document.

", + "idempotent": true + }, + "description": "Serializes XML attributes with escaped characters on the synthesized document", + "params": { + "foo": "hi", + "attr": "" + }, + "serialized": { + "method": "PUT", + "uri": "/XmlAttributes", + "body": "\n hi\n\n", + "headers": { + "Content-Type": "application/xml" + } + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "GET", - "requestUri": "/{Bucket}/{Key+}" - }, - "input": { - "shape": "InputShape" - }, - "name": "OperationName" - }, - "params": { - "Key": "testing /123", - "Bucket": "my/bucket" - }, - "serialized": { - "method": "GET", - "body": "", - "uri": "/my%2Fbucket/testing%20/123" - } - } - ] - }, - { - "description": "Omits null query params, but serializes empty strings", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" + { + "description": "Test cases for XmlAttributesOnPayload operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlAttributesOnPayloadRequest": { + "type": "structure", + "members": { + "payload": { + "shape": "XmlAttributesPayloadRequest", + "locationName": "payload" + } + }, + "payload": "payload" + }, + "XmlAttributesPayloadRequest": { + "type": "structure", + "members": { + "foo": { + "shape": "String" + }, + "attr": { + "shape": "String", + "locationName": "test", + "xmlAttribute": true + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "XmlAttributesOnPayload", + "given": { + "name": "XmlAttributesOnPayload", + "http": { + "method": "PUT", + "requestUri": "/XmlAttributesOnPayload", + "responseCode": 200 + }, + "input": { + "shape": "XmlAttributesOnPayloadRequest" + }, + "documentation": "

This example serializes an XML attributes on a document targeted by httpPayload.

", + "idempotent": true + }, + "description": "Serializes XML attributes on the synthesized document", + "params": { + "payload": { + "foo": "hi", + "attr": "test" + } + }, + "serialized": { + "method": "PUT", + "uri": "/XmlAttributesOnPayload", + "body": "\n hi\n\n", + "headers": { + "Content-Type": "application/xml" + } + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "foo": { - "location":"querystring", - "locationName":"param-name", - "shape": "Foo" - } - } - }, - "Foo": { - "type": "string" - } + { + "description": "Test cases for XmlBlobs operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlBlobsRequest": { + "type": "structure", + "members": { + "data": { + "shape": "Blob" + } + } + }, + "Blob": { + "type": "blob" + } + }, + "cases": [ + { + "id": "XmlBlobs", + "given": { + "name": "XmlBlobs", + "http": { + "method": "POST", + "requestUri": "/XmlBlobs", + "responseCode": 200 + }, + "input": { + "shape": "XmlBlobsRequest", + "locationName": "XmlBlobsRequest" + }, + "documentation": "

Blobs are base64 encoded

" + }, + "description": "Blobs are base64 encoded", + "params": { + "data": "value" + }, + "serialized": { + "method": "POST", + "uri": "/XmlBlobs", + "body": "\n dmFsdWU=\n\n", + "headers": { + "Content-Type": "application/xml" + } + } + } + ] }, - "cases": [ - { - "given": { - "name": "OperationName", - "http": { - "method": "POST", - "requestUri": "/path" - }, - "input": { "shape": "InputShape" } - }, - "params": { "foo": null }, - "serialized": { - "method": "POST", - "body": "", - "uri": "/path" - } - }, - { - "given": { - "name": "OperationName", - "http": { - "method": "POST", - "requestUri": "/path?abc=mno" - }, - "input": { "shape": "InputShape" } - }, - "params": { "foo": "" }, - "serialized": { - "method": "POST", - "body": "", - "uri": "/path?abc=mno¶m-name=" - } - } - ] - }, - { - "description": "Recursive shapes", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" + { + "description": "Test cases for XmlEmptyLists operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlEmptyListsRequest": { + "type": "structure", + "members": { + "stringList": { + "shape": "StringList" + }, + "stringSet": { + "shape": "StringSet" + }, + "integerList": { + "shape": "IntegerList" + }, + "booleanList": { + "shape": "BooleanList" + }, + "timestampList": { + "shape": "TimestampList" + }, + "enumList": { + "shape": "FooEnumList" + }, + "intEnumList": { + "shape": "IntegerEnumList" + }, + "nestedStringList": { + "shape": "NestedStringList" + }, + "renamedListMembers": { + "shape": "RenamedListMembers", + "locationName": "renamed" + }, + "flattenedList": { + "shape": "RenamedListMembers", + "flattened": true + }, + "flattenedList2": { + "shape": "RenamedListMembers", + "flattened": true, + "locationName": "customName" + }, + "flattenedListWithMemberNamespace": { + "shape": "ListWithMemberNamespace", + "flattened": true + }, + "flattenedListWithNamespace": { + "shape": "ListWithNamespace", + "flattened": true + }, + "structureList": { + "shape": "StructureList", + "locationName": "myStructureList" + }, + "flattenedStructureList": { + "shape": "StructureList", + "flattened": true + } + } + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringSet": { + "type": "list", + "member": { + "shape": "String" + } + }, + "IntegerList": { + "type": "list", + "member": { + "shape": "Integer" + } + }, + "BooleanList": { + "type": "list", + "member": { + "shape": "Boolean" + } + }, + "TimestampList": { + "type": "list", + "member": { + "shape": "Timestamp" + } + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "IntegerEnumList": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "NestedStringList": { + "type": "list", + "member": { + "shape": "StringList" + }, + "documentation": "

A list of lists of strings.

" + }, + "RenamedListMembers": { + "type": "list", + "member": { + "shape": "String", + "locationName": "item" + } + }, + "ListWithMemberNamespace": { + "type": "list", + "member": { + "shape": "String", + "xmlNamespace": "https://xml-member.example.com" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "ListWithNamespace": { + "type": "list", + "member": { + "shape": "String" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "StructureList": { + "type": "list", + "member": { + "shape": "StructureListMember", + "locationName": "item" + } + }, + "StructureListMember": { + "type": "structure", + "members": { + "a": { + "shape": "String", + "locationName": "value" + }, + "b": { + "shape": "String", + "locationName": "other" + } + } + }, + "String": { + "type": "string" + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "Timestamp": { + "type": "timestamp" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + } + }, + "cases": [ + { + "id": "XmlEmptyLists", + "given": { + "name": "XmlEmptyLists", + "http": { + "method": "PUT", + "requestUri": "/XmlEmptyLists", + "responseCode": 200 + }, + "input": { + "shape": "XmlEmptyListsRequest", + "locationName": "XmlEmptyListsRequest" + }, + "idempotent": true + }, + "description": "Serializes Empty XML lists", + "params": { + "stringList": [], + "stringSet": [] + }, + "serialized": { + "method": "PUT", + "uri": "/XmlEmptyLists", + "body": "\n \n \n\n", + "headers": { + "Content-Type": "application/xml" + } + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "RecursiveStruct": { - "shape": "RecursiveStructType" - } - } - }, - "RecursiveStructType": { - "type": "structure", - "members": { - "NoRecurse": { - "shape": "StringType" - }, - "RecursiveStruct": { - "shape": "RecursiveStructType" - }, - "RecursiveList": { - "shape": "RecursiveListType" - }, - "RecursiveMap": { - "shape": "RecursiveMapType" - } - } - }, - "RecursiveListType": { - "type": "list", - "member": { - "shape": "RecursiveStructType" - } - }, - "RecursiveMapType": { - "type": "map", - "key": { - "shape": "StringType" - }, - "value": { - "shape": "RecursiveStructType" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for XmlEmptyMaps operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlEmptyMapsRequest": { + "type": "structure", + "members": { + "myMap": { + "shape": "XmlMapsInputOutputMap" + } + } + }, + "XmlMapsInputOutputMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "GreetingStruct" + } + }, + "GreetingStruct": { + "type": "structure", + "members": { + "hi": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "XmlEmptyMaps", + "given": { + "name": "XmlEmptyMaps", + "http": { + "method": "POST", + "requestUri": "/XmlEmptyMaps", + "responseCode": 200 + }, + "input": { + "shape": "XmlEmptyMapsRequest", + "locationName": "XmlEmptyMapsRequest" + } + }, + "description": "Serializes Empty XML maps", + "params": { + "myMap": {} + }, + "serialized": { + "method": "POST", + "uri": "/XmlEmptyMaps", + "body": "\n \n\n", + "headers": { + "Content-Type": "application/xml" + } + } + } + ] }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape", - "locationName": "OperationRequest", - "xmlNamespace": {"uri": "https://foo/"} - }, - "http": { - "method": "POST", - "requestUri": "/path" - }, - "name": "OperationName" - }, - "params": { - "RecursiveStruct": { - "NoRecurse": "foo" - } - }, - "serialized": { - "uri": "/path", - "body": "foo" - } - }, - { - "given": { - "input": { - "shape": "InputShape", - "locationName": "OperationRequest", - "xmlNamespace": {"uri": "https://foo/"} - }, - "http": { - "method": "POST", - "requestUri": "/path" - }, - "name": "OperationName" - }, - "params": { - "RecursiveStruct": { - "RecursiveStruct": { - "NoRecurse": "foo" - } - } - }, - "serialized": { - "uri": "/path", - "body": "foo" - } - }, - { - "given": { - "input": { - "shape": "InputShape", - "locationName": "OperationRequest", - "xmlNamespace": {"uri": "https://foo/"} - }, - "http": { - "method": "POST", - "requestUri": "/path" - }, - "name": "OperationName" - }, - "params": { - "RecursiveStruct": { - "RecursiveStruct": { - "RecursiveStruct": { - "RecursiveStruct": { - "NoRecurse": "foo" - } - } - } - } - }, - "serialized": { - "uri": "/path", - "body": "foo" - } - }, - { - "given": { - "input": { - "shape": "InputShape", - "locationName": "OperationRequest", - "xmlNamespace": {"uri": "https://foo/"} - }, - "http": { - "method": "POST", - "requestUri": "/path" - }, - "name": "OperationName" - }, - "params": { - "RecursiveStruct": { - "RecursiveList": [ - { - "NoRecurse": "foo" - }, - { - "NoRecurse": "bar" - } - ] - } - }, - "serialized": { - "uri": "/path", - "body": "foobar" - } - }, - { - "given": { - "input": { - "shape": "InputShape", - "locationName": "OperationRequest", - "xmlNamespace": {"uri": "https://foo/"} - }, - "http": { - "method": "POST", - "requestUri": "/path" - }, - "name": "OperationName" - }, - "params": { - "RecursiveStruct": { - "RecursiveList": [ - { - "NoRecurse": "foo" - }, - { - "RecursiveStruct": { - "NoRecurse": "bar" - } - } - ] - } - }, - "serialized": { - "uri": "/path", - "body": "foobar" - } - }, - { - "given": { - "input": { - "shape": "InputShape", - "locationName": "OperationRequest", - "xmlNamespace": {"uri": "https://foo/"} - }, - "http": { - "method": "POST", - "requestUri": "/path" - }, - "name": "OperationName" - }, - "params": { - "RecursiveStruct": { - "RecursiveMap": { - "foo": { - "NoRecurse": "foo" - }, - "bar": { - "NoRecurse": "bar" - } - } - } - }, - "serialized": { - "uri": "/path", - "body": "foofoobarbar" - } - } - ] - }, - { - "description": "Idempotency token auto fill", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" + { + "description": "Test cases for XmlEmptyStrings operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlEmptyStringsRequest": { + "type": "structure", + "members": { + "emptyString": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "XmlEmptyStrings", + "given": { + "name": "XmlEmptyStrings", + "http": { + "method": "PUT", + "requestUri": "/XmlEmptyStrings", + "responseCode": 200 + }, + "input": { + "shape": "XmlEmptyStringsRequest", + "locationName": "XmlEmptyStringsRequest" + }, + "idempotent": true + }, + "description": "Serializes xml empty strings", + "params": { + "emptyString": "" + }, + "serialized": { + "method": "PUT", + "uri": "/XmlEmptyStrings", + "body": "\n \n\n", + "headers": { + "Content-Type": "application/xml" + } + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "Token": { - "shape": "StringType", - "idempotencyToken": true - } - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for XmlEnums operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlEnumsRequest": { + "type": "structure", + "members": { + "fooEnum1": { + "shape": "FooEnum" + }, + "fooEnum2": { + "shape": "FooEnum" + }, + "fooEnum3": { + "shape": "FooEnum" + }, + "fooEnumList": { + "shape": "FooEnumList" + }, + "fooEnumSet": { + "shape": "FooEnumSet" + }, + "fooEnumMap": { + "shape": "FooEnumMap" + } + } + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "FooEnumSet": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "FooEnumMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "FooEnum" + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "XmlEnums", + "given": { + "name": "XmlEnums", + "http": { + "method": "PUT", + "requestUri": "/XmlEnums", + "responseCode": 200 + }, + "input": { + "shape": "XmlEnumsRequest", + "locationName": "XmlEnumsRequest" + }, + "documentation": "

This example serializes enums as top level properties, in lists, sets, and maps.

", + "idempotent": true + }, + "description": "Serializes simple scalar properties", + "params": { + "fooEnum1": "Foo", + "fooEnum2": "0", + "fooEnum3": "1", + "fooEnumList": [ + "Foo", + "0" + ], + "fooEnumSet": [ + "Foo", + "0" + ], + "fooEnumMap": { + "hi": "Foo", + "zero": "0" + } + }, + "serialized": { + "method": "PUT", + "uri": "/XmlEnums", + "body": "\n Foo\n 0\n 1\n \n Foo\n 0\n \n \n Foo\n 0\n \n \n \n hi\n Foo\n \n \n zero\n 0\n \n \n\n", + "headers": { + "Content-Type": "application/xml" + } + } + } + ] }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "http": { - "method": "POST", - "requestUri": "/path" - }, - "name": "OperationName" - }, - "params": { - "Token": "abc123" - }, - "serialized": { - "uri": "/path", - "headers": {}, - "body": "abc123" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "http": { - "method": "POST", - "requestUri": "/path" - }, - "name": "OperationName" - }, - "params": { - }, - "serialized": { - "uri": "/path", - "headers": {}, - "body": "00000000-0000-4000-8000-000000000000" - } - } - ] - }, - { - "description": "JSON value trait", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" + { + "description": "Test cases for XmlIntEnums operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlIntEnumsRequest": { + "type": "structure", + "members": { + "intEnum1": { + "shape": "IntegerEnum" + }, + "intEnum2": { + "shape": "IntegerEnum" + }, + "intEnum3": { + "shape": "IntegerEnum" + }, + "intEnumList": { + "shape": "IntegerEnumList" + }, + "intEnumSet": { + "shape": "IntegerEnumSet" + }, + "intEnumMap": { + "shape": "IntegerEnumMap" + } + } + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "IntegerEnumList": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "IntegerEnumSet": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "IntegerEnumMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "IntegerEnum" + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "XmlIntEnums", + "given": { + "name": "XmlIntEnums", + "http": { + "method": "PUT", + "requestUri": "/XmlIntEnums", + "responseCode": 200 + }, + "input": { + "shape": "XmlIntEnumsRequest", + "locationName": "XmlIntEnumsRequest" + }, + "documentation": "

This example serializes enums as top level properties, in lists, sets, and maps.

", + "idempotent": true + }, + "description": "Serializes simple scalar properties", + "params": { + "intEnum1": 1, + "intEnum2": 2, + "intEnum3": 3, + "intEnumList": [ + 1, + 2 + ], + "intEnumSet": [ + 1, + 2 + ], + "intEnumMap": { + "a": 1, + "b": 2 + } + }, + "serialized": { + "method": "PUT", + "uri": "/XmlIntEnums", + "body": "\n 1\n 2\n 3\n \n 1\n 2\n \n \n 1\n 2\n \n \n \n a\n 1\n \n \n b\n 2\n \n \n\n", + "headers": { + "Content-Type": "application/xml" + } + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "Attr": { - "shape": "StringType", - "jsonvalue": true, - "location": "header", - "locationName": "X-Amz-Foo" - } - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for XmlLists operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlListsRequest": { + "type": "structure", + "members": { + "stringList": { + "shape": "StringList" + }, + "stringSet": { + "shape": "StringSet" + }, + "integerList": { + "shape": "IntegerList" + }, + "booleanList": { + "shape": "BooleanList" + }, + "timestampList": { + "shape": "TimestampList" + }, + "enumList": { + "shape": "FooEnumList" + }, + "intEnumList": { + "shape": "IntegerEnumList" + }, + "nestedStringList": { + "shape": "NestedStringList" + }, + "renamedListMembers": { + "shape": "RenamedListMembers", + "locationName": "renamed" + }, + "flattenedList": { + "shape": "RenamedListMembers", + "flattened": true + }, + "flattenedList2": { + "shape": "RenamedListMembers", + "flattened": true, + "locationName": "customName" + }, + "flattenedListWithMemberNamespace": { + "shape": "ListWithMemberNamespace", + "flattened": true + }, + "flattenedListWithNamespace": { + "shape": "ListWithNamespace", + "flattened": true + }, + "structureList": { + "shape": "StructureList", + "locationName": "myStructureList" + }, + "flattenedStructureList": { + "shape": "StructureList", + "flattened": true + } + } + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringSet": { + "type": "list", + "member": { + "shape": "String" + } + }, + "IntegerList": { + "type": "list", + "member": { + "shape": "Integer" + } + }, + "BooleanList": { + "type": "list", + "member": { + "shape": "Boolean" + } + }, + "TimestampList": { + "type": "list", + "member": { + "shape": "Timestamp" + } + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "IntegerEnumList": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "NestedStringList": { + "type": "list", + "member": { + "shape": "StringList" + }, + "documentation": "

A list of lists of strings.

" + }, + "RenamedListMembers": { + "type": "list", + "member": { + "shape": "String", + "locationName": "item" + } + }, + "ListWithMemberNamespace": { + "type": "list", + "member": { + "shape": "String", + "xmlNamespace": "https://xml-member.example.com" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "ListWithNamespace": { + "type": "list", + "member": { + "shape": "String" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "StructureList": { + "type": "list", + "member": { + "shape": "StructureListMember", + "locationName": "item" + } + }, + "StructureListMember": { + "type": "structure", + "members": { + "a": { + "shape": "String", + "locationName": "value" + }, + "b": { + "shape": "String", + "locationName": "other" + } + } + }, + "String": { + "type": "string" + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "Timestamp": { + "type": "timestamp" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + } + }, + "cases": [ + { + "id": "XmlLists", + "given": { + "name": "XmlLists", + "http": { + "method": "PUT", + "requestUri": "/XmlLists", + "responseCode": 200 + }, + "input": { + "shape": "XmlListsRequest", + "locationName": "XmlListsRequest" + }, + "documentation": "

This test case serializes XML lists for the following cases for both input and output:

  1. Normal XML lists.
  2. Normal XML sets.
  3. XML lists of lists.
  4. XML lists with @xmlName on its members
  5. Flattened XML lists.
  6. Flattened XML lists with @xmlName.
  7. Flattened XML lists with @xmlNamespace.
  8. Lists of structures.
  9. Flattened XML list of structures
", + "idempotent": true + }, + "description": "Tests for XML list serialization", + "params": { + "stringList": [ + "foo", + "bar" + ], + "stringSet": [ + "foo", + "bar" + ], + "integerList": [ + 1, + 2 + ], + "booleanList": [ + true, + false + ], + "timestampList": [ + 1398796238, + 1398796238 + ], + "enumList": [ + "Foo", + "0" + ], + "intEnumList": [ + 1, + 2 + ], + "nestedStringList": [ + [ + "foo", + "bar" + ], + [ + "baz", + "qux" + ] + ], + "renamedListMembers": [ + "foo", + "bar" + ], + "flattenedList": [ + "hi", + "bye" + ], + "flattenedList2": [ + "yep", + "nope" + ], + "structureList": [ + { + "a": "1", + "b": "2" + }, + { + "a": "3", + "b": "4" + } + ], + "flattenedStructureList": [ + { + "a": "5", + "b": "6" + }, + { + "a": "7", + "b": "8" + } + ] + }, + "serialized": { + "method": "PUT", + "uri": "/XmlLists", + "body": "\n \n foo\n bar\n \n \n foo\n bar\n \n \n 1\n 2\n \n \n true\n false\n \n \n 2014-04-29T18:30:38Z\n 2014-04-29T18:30:38Z\n \n \n Foo\n 0\n \n \n 1\n 2\n \n \n \n foo\n bar\n \n \n baz\n qux\n \n \n \n foo\n bar\n \n hi\n bye\n yep\n nope\n \n \n 1\n 2\n \n \n 3\n 4\n \n \n \n 5\n 6\n \n \n 7\n 8\n \n\n", + "headers": { + "Content-Type": "application/xml" + } + } + } + ] }, - "cases": [ - { - "given": { - "input": { - "shape": "InputShape" - }, - "http": { - "method": "POST", - "requestUri": "/path" - }, - "name": "OperationName" - }, - "params": { - "Attr": {"Foo":"Bar"} - }, - "serialized": { - "uri": "/path", - "headers": {"X-Amz-Foo": "eyJGb28iOiJCYXIifQ=="}, - "body": "" - } - }, - { - "given": { - "input": { - "shape": "InputShape" - }, - "http": { - "method": "POST", - "requestUri": "/path" - }, - "name": "OperationName" - }, - "params": { - }, - "serialized": { - "uri": "/path", - "headers": {}, - "body": "" - } - } - ] - }, - { - "description": "Endpoint host trait", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" + { + "description": "Test cases for XmlMaps operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlMapsRequest": { + "type": "structure", + "members": { + "myMap": { + "shape": "XmlMapsInputOutputMap" + } + } + }, + "XmlMapsInputOutputMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "GreetingStruct" + } + }, + "GreetingStruct": { + "type": "structure", + "members": { + "hi": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "XmlMaps", + "given": { + "name": "XmlMaps", + "http": { + "method": "POST", + "requestUri": "/XmlMaps", + "responseCode": 200 + }, + "input": { + "shape": "XmlMapsRequest", + "locationName": "XmlMapsRequest" + }, + "documentation": "

The example tests basic map serialization.

" + }, + "description": "Tests for XML map serialization", + "params": { + "myMap": { + "foo": { + "hi": "there" + }, + "baz": { + "hi": "bye" + } + } + }, + "serialized": { + "method": "POST", + "uri": "/XmlMaps", + "body": "\n \n \n foo\n \n there\n \n \n \n baz\n \n bye\n \n \n \n\n", + "headers": { + "Content-Type": "application/xml" + } + } + } + ] + }, + { + "description": "Test cases for XmlMapsXmlName operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlMapsXmlNameRequest": { + "type": "structure", + "members": { + "myMap": { + "shape": "XmlMapsXmlNameInputOutputMap" + } + } + }, + "XmlMapsXmlNameInputOutputMap": { + "type": "map", + "key": { + "shape": "String", + "locationName": "Attribute" + }, + "value": { + "shape": "GreetingStruct", + "locationName": "Setting" + } + }, + "GreetingStruct": { + "type": "structure", + "members": { + "hi": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "XmlMapsXmlName", + "given": { + "name": "XmlMapsXmlName", + "http": { + "method": "POST", + "requestUri": "/XmlMapsXmlName", + "responseCode": 200 + }, + "input": { + "shape": "XmlMapsXmlNameRequest", + "locationName": "XmlMapsXmlNameRequest" + } + }, + "description": "Serializes XML maps that have xmlName on members", + "params": { + "myMap": { + "foo": { + "hi": "there" + }, + "baz": { + "hi": "bye" + } + } + }, + "serialized": { + "method": "POST", + "uri": "/XmlMapsXmlName", + "body": "\n \n \n foo\n \n there\n \n \n \n baz\n \n bye\n \n \n \n\n", + "headers": { + "Content-Type": "application/xml" + } + } + } + ] }, - "clientEndpoint": "https://service.region.amazonaws.com", - "shapes": { - "StaticInputShape": { - "type": "structure", - "members": { - "Name": { - "shape": "StringType" - } - } - }, - "MemberRefInputShape": { - "type": "structure", - "members": { - "Name": { - "shape": "StringType", - "hostLabel": true - } - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for XmlMapWithXmlNamespace operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlMapWithXmlNamespaceRequest": { + "type": "structure", + "members": { + "myMap": { + "shape": "XmlMapWithXmlNamespaceInputOutputMap", + "locationName": "KVP", + "xmlNamespace": "https://the-member.example.com" + } + } + }, + "XmlMapWithXmlNamespaceInputOutputMap": { + "type": "map", + "key": { + "shape": "String", + "locationName": "K", + "xmlNamespace": "https://the-key.example.com" + }, + "value": { + "shape": "String", + "locationName": "V", + "xmlNamespace": "https://the-value.example.com" + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestXmlXmlMapWithXmlNamespace", + "given": { + "name": "XmlMapWithXmlNamespace", + "http": { + "method": "POST", + "requestUri": "/XmlMapWithXmlNamespace", + "responseCode": 200 + }, + "input": { + "shape": "XmlMapWithXmlNamespaceRequest", + "locationName": "XmlMapWithXmlNamespaceRequest" + }, + "documentation": "

Maps with @xmlNamespace and @xmlName

" + }, + "description": "Serializes XML maps in requests that have xmlNamespace and xmlName on members", + "params": { + "myMap": { + "a": "A", + "b": "B" + } + }, + "serialized": { + "method": "POST", + "uri": "/XmlMapWithXmlNamespace", + "body": "\n \n \n a\n A\n \n \n b\n B\n \n \n", + "headers": { + "Content-Type": "application/xml" + } + } + } + ] }, - "cases": [ - { - "given": { - "name": "StaticOp", - "input": { - "shape": "StaticInputShape", - "locationName": "StaticOpRequest" - }, - "http": { - "method": "POST", - "requestUri": "/path" - }, - "endpoint":{ - "hostPrefix": "data-" - } - }, - "params": { - "Name": "myname" - }, - "serialized": { - "uri": "/path", - "body": "myname", - "host": "data-service.region.amazonaws.com" - } - }, - { - "given": { - "name": "MemberRefOp", - "input": { - "shape": "MemberRefInputShape", - "locationName": "MemberRefOpRequest" - }, - "http": { - "method": "GET", - "requestUri": "/path" - }, - "endpoint":{ - "hostPrefix": "foo-{Name}." - } - }, - "params": { - "Name": "myname" - }, - "serialized": { - "uri": "/path", - "body": "myname", - "host": "foo-myname.service.region.amazonaws.com" - } - } - ] - }, - { - "description": "List in header", - "metadata": { - "protocol": "rest-xml", - "apiVersion": "2014-01-01" + { + "description": "Test cases for XmlNamespaces operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlNamespacesRequest": { + "type": "structure", + "members": { + "nested": { + "shape": "XmlNamespaceNested" + } + }, + "xmlNamespace": "http://foo.com" + }, + "XmlNamespaceNested": { + "type": "structure", + "members": { + "foo": { + "shape": "String", + "xmlNamespace": { + "prefix": "baz", + "uri": "http://baz.com" + } + }, + "values": { + "shape": "XmlNamespacedList", + "xmlNamespace": "http://qux.com" + } + }, + "xmlNamespace": "http://foo.com" + }, + "String": { + "type": "string" + }, + "XmlNamespacedList": { + "type": "list", + "member": { + "shape": "String", + "xmlNamespace": "http://bux.com" + } + } + }, + "cases": [ + { + "id": "XmlNamespaces", + "given": { + "name": "XmlNamespaces", + "http": { + "method": "POST", + "requestUri": "/XmlNamespaces", + "responseCode": 200 + }, + "input": { + "shape": "XmlNamespacesRequest", + "locationName": "XmlNamespacesRequest" + } + }, + "description": "Serializes XML namespaces", + "params": { + "nested": { + "foo": "Foo", + "values": [ + "Bar", + "Baz" + ] + } + }, + "serialized": { + "method": "POST", + "uri": "/XmlNamespaces", + "body": "\n \n Foo\n \n Bar\n Baz\n \n \n\n", + "headers": { + "Content-Type": "application/xml" + } + } + } + ] }, - "shapes": { - "InputShape": { - "type": "structure", - "members": { - "ListParam": { - "shape": "ListShape", - "location": "header", - "locationName": "x-amz-list-param" - } - } - }, - "ListShape": { - "type": "list", - "member": { - "shape": "EnumType" - } - }, - "EnumType": { - "type": "string", - "enum": ["one", "two", "three"] - } + { + "description": "Test cases for XmlTimestamps operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlTimestampsRequest": { + "type": "structure", + "members": { + "normal": { + "shape": "Timestamp" + }, + "dateTime": { + "shape": "SyntheticTimestamp_date_time" + }, + "dateTimeOnTarget": { + "shape": "DateTime" + }, + "epochSeconds": { + "shape": "SyntheticTimestamp_epoch_seconds" + }, + "epochSecondsOnTarget": { + "shape": "EpochSeconds" + }, + "httpDate": { + "shape": "SyntheticTimestamp_http_date" + }, + "httpDateOnTarget": { + "shape": "HttpDate" + } + } + }, + "Timestamp": { + "type": "timestamp" + }, + "SyntheticTimestamp_date_time": { + "type": "timestamp", + "timestampFormat": "iso8601" + }, + "DateTime": { + "type": "timestamp", + "timestampFormat": "iso8601" + }, + "SyntheticTimestamp_epoch_seconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "EpochSeconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "SyntheticTimestamp_http_date": { + "type": "timestamp", + "timestampFormat": "rfc822" + }, + "HttpDate": { + "type": "timestamp", + "timestampFormat": "rfc822" + } + }, + "cases": [ + { + "id": "XmlTimestamps", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/XmlTimestamps", + "responseCode": 200 + }, + "input": { + "shape": "XmlTimestampsRequest", + "locationName": "XmlTimestampsRequest" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Tests how normal timestamps are serialized", + "params": { + "normal": 1398796238 + }, + "serialized": { + "method": "POST", + "uri": "/XmlTimestamps", + "body": "\n 2014-04-29T18:30:38Z\n\n", + "headers": { + "Content-Type": "application/xml" + } + } + }, + { + "id": "XmlTimestampsWithDateTimeFormat", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/XmlTimestamps", + "responseCode": 200 + }, + "input": { + "shape": "XmlTimestampsRequest", + "locationName": "XmlTimestampsRequest" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of date-time works like normal timestamps", + "params": { + "dateTime": 1398796238 + }, + "serialized": { + "method": "POST", + "uri": "/XmlTimestamps", + "body": "\n 2014-04-29T18:30:38Z\n\n", + "headers": { + "Content-Type": "application/xml" + } + } + }, + { + "id": "XmlTimestampsWithDateTimeOnTargetFormat", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/XmlTimestamps", + "responseCode": 200 + }, + "input": { + "shape": "XmlTimestampsRequest", + "locationName": "XmlTimestampsRequest" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of date-time on the target shape works like normal timestamps", + "params": { + "dateTimeOnTarget": 1398796238 + }, + "serialized": { + "method": "POST", + "uri": "/XmlTimestamps", + "body": "\n 2014-04-29T18:30:38Z\n\n", + "headers": { + "Content-Type": "application/xml" + } + } + }, + { + "id": "XmlTimestampsWithEpochSecondsFormat", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/XmlTimestamps", + "responseCode": 200 + }, + "input": { + "shape": "XmlTimestampsRequest", + "locationName": "XmlTimestampsRequest" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of epoch-seconds works", + "params": { + "epochSeconds": 1398796238 + }, + "serialized": { + "method": "POST", + "uri": "/XmlTimestamps", + "body": "\n 1398796238\n\n", + "headers": { + "Content-Type": "application/xml" + } + } + }, + { + "id": "XmlTimestampsWithEpochSecondsOnTargetFormat", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/XmlTimestamps", + "responseCode": 200 + }, + "input": { + "shape": "XmlTimestampsRequest", + "locationName": "XmlTimestampsRequest" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of epoch-seconds on the target shape works", + "params": { + "epochSecondsOnTarget": 1398796238 + }, + "serialized": { + "method": "POST", + "uri": "/XmlTimestamps", + "body": "\n 1398796238\n\n", + "headers": { + "Content-Type": "application/xml" + } + } + }, + { + "id": "XmlTimestampsWithHttpDateFormat", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/XmlTimestamps", + "responseCode": 200 + }, + "input": { + "shape": "XmlTimestampsRequest", + "locationName": "XmlTimestampsRequest" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of http-date works", + "params": { + "httpDate": 1398796238 + }, + "serialized": { + "method": "POST", + "uri": "/XmlTimestamps", + "body": "\n Tue, 29 Apr 2014 18:30:38 GMT\n\n", + "headers": { + "Content-Type": "application/xml" + } + } + }, + { + "id": "XmlTimestampsWithHttpDateOnTargetFormat", + "given": { + "name": "XmlTimestamps", + "http": { + "method": "POST", + "requestUri": "/XmlTimestamps", + "responseCode": 200 + }, + "input": { + "shape": "XmlTimestampsRequest", + "locationName": "XmlTimestampsRequest" + }, + "documentation": "

This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.

" + }, + "description": "Ensures that the timestampFormat of http-date on the target shape works", + "params": { + "httpDateOnTarget": 1398796238 + }, + "serialized": { + "method": "POST", + "uri": "/XmlTimestamps", + "body": "\n Tue, 29 Apr 2014 18:30:38 GMT\n\n", + "headers": { + "Content-Type": "application/xml" + } + } + } + ] }, - "cases": [ - { - "given": { - "http": { - "method": "POST", - "requestUri": "/2014-01-01/example" - }, - "input": { - "shape": "InputShape", - "locationName": "OperationRequest", - "xmlNamespace": {"uri": "https://foo/"} - }, - "name": "OperationName" - }, - "params": { - "ListParam": [ - "one", - "two", - "three" - ] - }, - "serialized": { - "method": "POST", - "body": "", - "uri": "/2014-01-01/example", - "headers": { - "x-amz-list-param": "one,two,three" - } - } - }, - { - "given": { - "http": { - "method": "POST", - "requestUri": "/2014-01-01/example" - }, - "input": { - "shape": "InputShape", - "locationName": "OperationRequest", - "xmlNamespace": {"uri": "https://foo/"} - }, - "name": "OperationName" - }, - "params": { - "ListParam": [] - }, - "serialized": { - "method": "POST", - "body": "", - "uri": "/2014-01-01/example", - "headers": {}, - "forbidHeaders": ["x-amz-list-param"] - } - } - ] - } + { + "description": "Test cases for XmlUnions operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlUnionsRequest": { + "type": "structure", + "members": { + "unionValue": { + "shape": "XmlUnionShape" + } + } + }, + "XmlUnionShape": { + "type": "structure", + "members": { + "stringValue": { + "shape": "String" + }, + "booleanValue": { + "shape": "Boolean" + }, + "byteValue": { + "shape": "Integer" + }, + "shortValue": { + "shape": "Integer" + }, + "integerValue": { + "shape": "Integer" + }, + "longValue": { + "shape": "Long" + }, + "floatValue": { + "shape": "Float" + }, + "doubleValue": { + "shape": "Double" + }, + "unionValue": { + "shape": "XmlUnionShape" + }, + "structValue": { + "shape": "XmlNestedUnionStruct" + } + }, + "union": true + }, + "String": { + "type": "string" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + }, + "Long": { + "type": "long", + "box": true + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + }, + "XmlNestedUnionStruct": { + "type": "structure", + "members": { + "stringValue": { + "shape": "String" + }, + "booleanValue": { + "shape": "Boolean" + }, + "byteValue": { + "shape": "Integer" + }, + "shortValue": { + "shape": "Integer" + }, + "integerValue": { + "shape": "Integer" + }, + "longValue": { + "shape": "Long" + }, + "floatValue": { + "shape": "Float" + }, + "doubleValue": { + "shape": "Double" + } + } + } + }, + "cases": [ + { + "id": "XmlUnionsWithStructMember", + "given": { + "name": "XmlUnions", + "http": { + "method": "PUT", + "requestUri": "/XmlUnions", + "responseCode": 200 + }, + "input": { + "shape": "XmlUnionsRequest", + "locationName": "XmlUnionsRequest" + }, + "idempotent": true + }, + "description": "Serializes union struct member", + "params": { + "unionValue": { + "structValue": { + "stringValue": "string", + "booleanValue": true, + "byteValue": 1, + "shortValue": 2, + "integerValue": 3, + "longValue": 4, + "floatValue": 5.5, + "doubleValue": 6.5 + } + } + }, + "serialized": { + "method": "PUT", + "uri": "/XmlUnions", + "body": "\n \n \n string\n true\n 1\n 2\n 3\n 4\n 5.5\n 6.5\n \n \n\n", + "headers": { + "Content-Type": "application/xml" + } + } + }, + { + "id": "XmlUnionsWithStringMember", + "given": { + "name": "XmlUnions", + "http": { + "method": "PUT", + "requestUri": "/XmlUnions", + "responseCode": 200 + }, + "input": { + "shape": "XmlUnionsRequest", + "locationName": "XmlUnionsRequest" + }, + "idempotent": true + }, + "description": "serialize union string member", + "params": { + "unionValue": { + "stringValue": "some string" + } + }, + "serialized": { + "method": "PUT", + "uri": "/XmlUnions", + "body": "\n \n some string\n \n\n", + "headers": { + "Content-Type": "application/xml" + } + } + }, + { + "id": "XmlUnionsWithBooleanMember", + "given": { + "name": "XmlUnions", + "http": { + "method": "PUT", + "requestUri": "/XmlUnions", + "responseCode": 200 + }, + "input": { + "shape": "XmlUnionsRequest", + "locationName": "XmlUnionsRequest" + }, + "idempotent": true + }, + "description": "Serializes union boolean member", + "params": { + "unionValue": { + "booleanValue": true + } + }, + "serialized": { + "method": "PUT", + "uri": "/XmlUnions", + "body": "\n \n true\n \n\n", + "headers": { + "Content-Type": "application/xml" + } + } + }, + { + "id": "XmlUnionsWithUnionMember", + "given": { + "name": "XmlUnions", + "http": { + "method": "PUT", + "requestUri": "/XmlUnions", + "responseCode": 200 + }, + "input": { + "shape": "XmlUnionsRequest", + "locationName": "XmlUnionsRequest" + }, + "idempotent": true + }, + "description": "Serializes union member", + "params": { + "unionValue": { + "unionValue": { + "booleanValue": true + } + } + }, + "serialized": { + "method": "PUT", + "uri": "/XmlUnions", + "body": "\n \n \n true\n \n \n\n", + "headers": { + "Content-Type": "application/xml" + } + } + } + ] + } ] From 0559d2e522721ef907b8de646f754a1953f706a3 Mon Sep 17 00:00:00 2001 From: jonathan343 Date: Tue, 23 Jul 2024 22:48:32 -0700 Subject: [PATCH 04/11] Resolve a majority of the response parsing test cases. --- botocore/parsers.py | 115 +++++++++++++++++++++++------------ tests/unit/test_protocols.py | 73 +++++++++++++++------- 2 files changed, 126 insertions(+), 62 deletions(-) diff --git a/botocore/parsers.py b/botocore/parsers.py index 0c7a34f218..c214262234 100644 --- a/botocore/parsers.py +++ b/botocore/parsers.py @@ -201,6 +201,10 @@ class ResponseParser: DEFAULT_ENCODING = 'utf-8' EVENT_STREAM_PARSER_CLS = None + # This is a list of known values for the "location" key in the + # serialization dict. The location key tells us where in the response + # to parse the value. + KNOWN_LOCATIONS = ['statusCode', 'header', 'headers'] def __init__(self, timestamp_parser=None, blob_parser=None): if timestamp_parser is None: @@ -363,7 +367,11 @@ def _has_unknown_tagged_union_member(self, shape, value): ) raise ResponseParserError(error_msg % shape.name) tag = self._get_first_key(cleaned_value) - if tag not in shape.members: + serialized_member_names = [ + shape.members[member].serialization.get('name', member) + for member in shape.members + ] + if tag not in serialized_member_names: msg = ( "Received a tagged union response with member " "unknown to client: %s. Please upgrade SDK for full " @@ -427,11 +435,13 @@ def _handle_structure(self, shape, node): return self._handle_unknown_tagged_union_member(tag) for member_name in members: member_shape = members[member_name] + location = member_shape.serialization.get('location') if ( - 'location' in member_shape.serialization + location + and location in self.KNOWN_LOCATIONS or member_shape.serialization.get('eventheader') ): - # All members with locations have already been handled, + # All members with know locations have already been handled, # so we don't need to parse these members. continue xml_name = self._member_key_name(member_shape, member_name) @@ -460,20 +470,7 @@ def _get_error_root(self, original_root): return original_root def _member_key_name(self, shape, member_name): - # This method is needed because we have to special case flattened list - # with a serialization name. If this is the case we use the - # locationName from the list's member shape as the key name for the - # surrounding structure. - if shape.type_name == 'list' and shape.serialization.get('flattened'): - list_member_serialized_name = shape.member.serialization.get( - 'name' - ) - if list_member_serialized_name is not None: - return list_member_serialized_name - serialized_name = shape.serialization.get('name') - if serialized_name is not None: - return serialized_name - return member_name + return shape.serialization.get('name', member_name) def _build_name_to_xml_node(self, parent_node): # If the parent node is actually a list. We should not be trying @@ -574,6 +571,8 @@ def _do_modeled_error_parse(self, response, shape): return self._parse_body_as_xml(response, shape, inject_metadata=False) def _do_parse(self, response, shape): + if not response.get('body'): + return {} return self._parse_body_as_xml(response, shape, inject_metadata=True) def _parse_body_as_xml(self, response, shape, inject_metadata=True): @@ -586,6 +585,16 @@ def _parse_body_as_xml(self, response, shape, inject_metadata=True): start = self._find_result_wrapped_shape( shape.serialization['resultWrapper'], root ) + else: + operation_name = response.get("context", {}).get( + "operation_name", "" + ) + inferred_wrapper_name = operation_name + "Result" + inferred_wrapper = self._find_result_wrapped_shape( + inferred_wrapper_name, root + ) + if inferred_wrapper is not None: + start = inferred_wrapper parsed = self._parse_shape(shape, start) if inject_metadata: self._inject_response_metadata(root, parsed) @@ -593,7 +602,7 @@ def _parse_body_as_xml(self, response, shape, inject_metadata=True): def _find_result_wrapped_shape(self, element_name, xml_root_node): mapping = self._build_name_to_xml_node(xml_root_node) - return mapping[element_name] + return mapping.get(element_name) def _inject_response_metadata(self, node, inject_into): mapping = self._build_name_to_xml_node(node) @@ -704,11 +713,19 @@ def _do_error_parse(self, response, shape): code = body.get('__type', response_code and str(response_code)) if code is not None: + # The "Code" value can come from either a response + # header or a value in the JSON body. + if 'x-amzn-errortype' in response['headers']: + code = response['headers']['x-amzn-errortype'] + elif 'code' in body or 'Code' in body: + code = body.get('code', body.get('Code', '')) # code has a couple forms as well: # * "com.aws.dynamodb.vAPI#ProvisionedThroughputExceededException" # * "ResourceNotFoundException" + if ':' in code: + code = code.split(':', 1)[0] if '#' in code: - code = code.rsplit('#', 1)[1] + code = code.split('#', 1)[1] if 'x-amzn-query-error' in headers: code = self._do_query_compatible_error_parse( code, headers, error @@ -743,7 +760,16 @@ def _parse_body_as_json(self, body_contents): return {} body = body_contents.decode(self.DEFAULT_ENCODING) try: - original_parsed = json.loads(body) + # Function to remove null values from a JSON object. + def remove_nulls(obj): + if isinstance(obj, dict): + return {k: v for k, v in obj.items() if v is not None} + elif isinstance(obj, list): + return [v for v in obj if v is not None] + else: + return obj + + original_parsed = json.loads(body, object_hook=remove_nulls) return original_parsed except ValueError: # if the body cannot be parsed, include @@ -953,7 +979,7 @@ def _parse_non_payload_attrs( for name in member_shapes: member_shape = member_shapes[name] location = member_shape.serialization.get('location') - if location is None: + if location is None or location not in self.KNOWN_LOCATIONS: continue elif location == 'statusCode': final_parsed[name] = self._parse_shape( @@ -994,14 +1020,28 @@ def _handle_string(self, shape, value): parsed = value if is_json_value_header(shape): decoded = base64.b64decode(value).decode(self.DEFAULT_ENCODING) - parsed = json.loads(decoded) + parsed = json.dumps(json.loads(decoded)) return parsed + def _handle_list_header(self, node): + # TODO: Clean up and consider timestamps. + TOKEN_PATTERN = r'[!#$%&\'*+\-.^_`|~\w]+' + QUOTED_STRING_PATTERN = r'"(?:[^"\\]|\\.)*"' + PATTERN = rf'({QUOTED_STRING_PATTERN}|{TOKEN_PATTERN})' + matches = re.findall(PATTERN, node) + parsed_values = [] + for match in matches: + if match.startswith('"') and match.endswith('"'): + parsed_values.append(match[1:-1].replace('\\"', '"')) + else: + parsed_values.append(match) + return parsed_values + def _handle_list(self, shape, node): location = shape.serialization.get('location') if location == 'header' and not isinstance(node, list): # List in headers may be a comma separated string as per RFC7230 - node = [e.strip() for e in node.split(',')] + node = self._handle_list_header(node) return super()._handle_list(shape, node) @@ -1011,28 +1051,23 @@ class RestJSONParser(BaseRestParser, BaseJSONParser): def _initial_body_parse(self, body_contents): return self._parse_body_as_json(body_contents) - def _do_error_parse(self, response, shape): - error = super()._do_error_parse(response, shape) - self._inject_error_code(error, response) - return error - - def _inject_error_code(self, error, response): - # The "Code" value can come from either a response - # header or a value in the JSON body. - body = self._initial_body_parse(response['body']) - if 'x-amzn-errortype' in response['headers']: - code = response['headers']['x-amzn-errortype'] - # Could be: - # x-amzn-errortype: ValidationException: - code = code.split(':')[0] - error['Error']['Code'] = code - elif 'code' in body or 'Code' in body: - error['Error']['Code'] = body.get('code', body.get('Code', '')) + def _handle_boolean(self, shape, value): + # It's possible to receive a boolean as a string + if isinstance(value, str): + if value == 'true': + return True + else: + return False + return value def _handle_integer(self, shape, value): return int(value) + def _handle_float(self, shape, value): + return float(value) + _handle_long = _handle_integer + _handle_double = _handle_float class RestXMLParser(BaseRestParser, BaseXMLResponseParser): diff --git a/tests/unit/test_protocols.py b/tests/unit/test_protocols.py index 3bf84c9935..2d77c7519e 100644 --- a/tests/unit/test_protocols.py +++ b/tests/unit/test_protocols.py @@ -54,7 +54,6 @@ import copy import os from base64 import b64decode -from calendar import timegm from enum import Enum import pytest @@ -181,7 +180,7 @@ def stream(self): ) def test_output_compliance(json_description, case, basename): service_description = copy.deepcopy(json_description) - operation_name = case.get('name', 'OperationName') + operation_name = case.get('given', {}).get('name', 'OperationName') service_description['operations'] = { operation_name: case, } @@ -194,11 +193,17 @@ def test_output_compliance(json_description, case, basename): ) # We load the json as utf-8, but the response parser is at the # botocore boundary, so it expects to work with bytes. - body_bytes = case['response']['body'].encode('utf-8') - case['response']['body'] = body_bytes + # If a test case doesn't define a response body, set it to `None`. + if 'body' in case['response']: + body_bytes = case['response']['body'].encode('utf-8') + case['response']['body'] = body_bytes + else: + case['response']['body'] = None # We need the headers to be case insensitive - headers = HeadersDict(case['response']['headers']) - case['response']['headers'] = headers + # If a test case doesn't define response headers, set it to an empty `HeadersDict`. + case['response']['headers'] = HeadersDict( + case['response'].get('headers', {}) + ) # If this is an event stream fake the raw streamed response if operation_model.has_event_stream_output: case['response']['body'] = MockRawResponse(body_bytes) @@ -206,7 +211,8 @@ def test_output_compliance(json_description, case, basename): output_shape = operation_model.output_shape parsed = parser.parse(case['response'], output_shape) try: - error_shape = model.shape_for(parsed['Error']['Code']) + error_code = parsed.get("Error", {}).get("Code") + error_shape = model.shape_for_error_code(error_code) except NoShapeFoundError: error_shape = None if error_shape is not None: @@ -279,24 +285,47 @@ def _fixup_parsed_result(parsed): for key in error_keys: if key not in ['Code', 'Message']: del parsed['Error'][key] + # 5. Special float types. In the protocol test suite, certain special float + # types are represented as strings: "Infinity", "-Infinity", and "NaN". + # However, we parse these values as actual floats types, so we need to convert + # them back to their string representation. + parsed = _convert_special_floats_to_string(parsed) return parsed -def _convert_bytes_to_str(parsed): - if isinstance(parsed, dict): - new_dict = {} - for key, value in parsed.items(): - new_dict[key] = _convert_bytes_to_str(value) - return new_dict - elif isinstance(parsed, bytes): - return parsed.decode('utf-8') - elif isinstance(parsed, list): - new_list = [] - for item in parsed: - new_list.append(_convert_bytes_to_str(item)) - return new_list +def _convert(obj, conversion_funcs): + if isinstance(obj, dict): + return {k: _convert(v, conversion_funcs) for k, v in obj.items()} + elif isinstance(obj, list): + return [_convert(item, conversion_funcs) for item in obj] else: - return parsed + for conv_type, conv_func in conversion_funcs: + if isinstance(obj, conv_type): + return conv_func(obj) + return obj + + +def _bytes_to_str(value): + if isinstance(value, bytes): + return value.decode('utf-8') + return value + + +def _convert_bytes_to_str(parsed): + return _convert(parsed, [(bytes, _bytes_to_str)]) + + +def _special_floats_to_str(value): + if isinstance(value, float): + if value in [float('Infinity'), float('-Infinity')] or math.isnan( + value + ): + return json.dumps(value) + return value + + +def _convert_special_floats_to_string(parsed): + return _convert(parsed, [(float, _special_floats_to_str)]) def _compliance_timestamp_parser(value): @@ -304,7 +333,7 @@ def _compliance_timestamp_parser(value): # Convert from our time zone to UTC datetime = datetime.astimezone(tzutc()) # Convert to epoch. - return int(timegm(datetime.timetuple())) + return datetime.timestamp() def _output_failure_message( From 772fd81f0b73d9ab0f8e512372ee21f041bb65e4 Mon Sep 17 00:00:00 2001 From: jonathan343 Date: Sat, 27 Jul 2024 16:46:30 -0700 Subject: [PATCH 05/11] Update test_input_compliance to support new protocol tests --- tests/unit/test_protocols.py | 41 +++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/tests/unit/test_protocols.py b/tests/unit/test_protocols.py index 2d77c7519e..b5c5ffd031 100644 --- a/tests/unit/test_protocols.py +++ b/tests/unit/test_protocols.py @@ -52,7 +52,9 @@ """ import copy +import math import os +import xml.etree.ElementTree as ET from base64 import b64decode from enum import Enum @@ -97,7 +99,9 @@ 'rest-json': RestJSONParser, 'rest-xml': RestXMLParser, } -PROTOCOL_TEST_BLACKLIST = ['Idempotency token auto fill'] +PROTOCOL_TEST_BLACKLIST = [ + "Test cases for QueryIdempotencyTokenAutoFill operation", +] class TestType(Enum): @@ -129,7 +133,7 @@ def _compliance_tests(test_type=None): def test_input_compliance(json_description, case, basename): service_description = copy.deepcopy(json_description) service_description['operations'] = { - case.get('name', 'OperationName'): case, + case.get('given', {}).get('name', 'OperationName'): case, } model = ServiceModel(service_description) protocol_type = model.metadata['protocol'] @@ -145,7 +149,7 @@ def test_input_compliance(json_description, case, basename): client_endpoint = service_description.get('clientEndpoint') try: _assert_request_body_is_bytes(request['body']) - _assert_requests_equal(request, case['serialized']) + _assert_requests_equal(request, case['serialized'], protocol_type) _assert_endpoints_equal(request, case['serialized'], client_endpoint) except AssertionError as e: _input_failure_message(protocol_type, case, request, e) @@ -423,11 +427,32 @@ def _serialize_request_description(request_dict): request_dict['url_path'] += f'&{encoded}' -def _assert_requests_equal(actual, expected): - assert_equal( - actual['body'], expected.get('body', '').encode('utf-8'), 'Body value' - ) +def _assert_requests_equal(actual, expected, protocol_type): + expected_body = expected.get('body', '').encode('utf-8') + actual_body = actual['body'] + # The expected bodies in our consumed protocol tests have extra + # whitespace and newlines that need to handled. We need to normalize + # the expected and actual response bodies before evaluating equivalence. + try: + if protocol_type in ['json', 'rest-json']: + assert_equal( + json.loads(actual_body), + json.loads(expected_body), + 'Body value', + ) + elif protocol_type in ['rest-xml']: + tree1 = ET.canonicalize(actual_body, strip_text=True) + tree2 = ET.canonicalize(expected_body, strip_text=True) + assert_equal(tree1, tree2, 'Body value') + else: + assert_equal(actual_body, expected_body, 'Body value') + except (json.JSONDecodeError, ET.ParseError): + assert_equal(actual_body, expected_body, 'Body value') + actual_headers = HeadersDict(actual['headers']) + if protocol_type in ['query', 'ec2']: + if expected.get('headers', {}).get('Content-Type'): + expected['headers']['Content-Type'] += '; charset=utf-8' expected_headers = HeadersDict(expected.get('headers', {})) excluded_headers = expected.get('forbidHeaders', []) _assert_expected_headers_in_request( @@ -460,7 +485,7 @@ def _walk_files(): def _load_cases(full_path): - # During developement, you can set the BOTOCORE_TEST_ID + # During development, you can set the BOTOCORE_TEST_ID # to run a specific test suite or even a specific test case. # The format is BOTOCORE_TEST_ID=suite_id:test_id or # BOTOCORE_TEST_ID=suite_id From 6d5502329282c096daf8e20477b9533be8758251 Mon Sep 17 00:00:00 2001 From: jonathan343 Date: Mon, 29 Jul 2024 10:43:16 -0700 Subject: [PATCH 06/11] Resolve a majority of the request serialization test cases. --- botocore/serialize.py | 121 ++++++++++++++++++++++++++++++++---------- 1 file changed, 92 insertions(+), 29 deletions(-) diff --git a/botocore/serialize.py b/botocore/serialize.py index 82ed58d09a..8bb33f7d75 100644 --- a/botocore/serialize.py +++ b/botocore/serialize.py @@ -180,7 +180,11 @@ def _expand_host_prefix(self, parameters, operation_model): return None host_prefix_expression = operation_endpoint['hostPrefix'] - input_members = operation_model.input_shape.members + input_members = ( + operation_model.input_shape.members + if operation_model.input_shape + else {} + ) host_labels = [ member for member, shape in input_members.items() @@ -203,6 +207,9 @@ def _expand_host_prefix(self, parameters, operation_model): ) return host_prefix_expression.format(**format_kwargs) + def _is_shape_flattened(self, shape): + return shape.serialization.get('flattened') + class QuerySerializer(Serializer): TIMESTAMP_FORMAT = 'iso8601' @@ -249,6 +256,9 @@ def _serialize(self, serialized, value, shape, prefix=''): def _serialize_type_structure(self, serialized, value, shape, prefix=''): members = shape.members for key, value in value.items(): + if value is None: + # Don't serialize any parameter with a None value. + continue member_shape = members[key] member_prefix = self._get_serialized_name(member_shape, key) if prefix: @@ -262,10 +272,6 @@ def _serialize_type_list(self, serialized, value, shape, prefix=''): return if self._is_shape_flattened(shape): list_prefix = prefix - if shape.member.serialization.get('name'): - name = self._get_serialized_name(shape.member, default_name='') - # Replace '.Original' with '.{name}'. - list_prefix = '.'.join(prefix.split('.')[:-1] + [name]) else: list_name = shape.member.serialization.get('name', 'member') list_prefix = f'{prefix}.{list_name}' @@ -308,9 +314,6 @@ def _serialize_type_boolean(self, serialized, value, shape, prefix=''): def _default_serialize(self, serialized, value, shape, prefix=''): serialized[prefix] = value - def _is_shape_flattened(self, shape): - return shape.serialization.get('flattened') - class EC2Serializer(QuerySerializer): """EC2 specific customizations to the query protocol serializers. @@ -324,7 +327,7 @@ class EC2Serializer(QuerySerializer): def _get_serialized_name(self, shape, default_name): # Returns the serialized name for the shape if it exists. - # Otherwise it will return the passed in default_name. + # Otherwise it will return the passed in capitalized default_name. if 'queryName' in shape.serialization: return shape.serialization['queryName'] elif 'name' in shape.serialization: @@ -394,6 +397,9 @@ def _serialize_type_structure(self, serialized, value, shape, key): serialized = new_serialized members = shape.members for member_key, member_value in value.items(): + if member_value is None: + # Don't serialize any parameter with a None value. + continue member_shape = members[member_key] if 'name' in member_shape.serialization: member_key = member_shape.serialization['name'] @@ -442,6 +448,7 @@ class BaseRestSerializer(Serializer): """ + URI_TIMESTAMP_FORMAT = 'iso8601' QUERY_STRING_TIMESTAMP_FORMAT = 'iso8601' HEADER_TIMESTAMP_FORMAT = 'rfc822' # This is a list of known values for the "location" key in the @@ -570,6 +577,19 @@ def _serialize_content_type(self, serialized, shape, shape_members): """ pass + def _handle_streaming_payload_content_type( + self, serialized, shape, shape_members + ): + """Set Content-Type header for streaming payload member types.""" + payload = shape.serialization.get('payload') + if self._has_streaming_payload(payload, shape_members): + if shape_members[payload].type_name == 'string': + serialized['headers']['Content-Type'] = 'text/plain' + elif shape_members[payload].type_name == 'blob': + serialized['headers']['Content-Type'] = ( + 'application/octet-stream' + ) + def _requires_empty_body(self, shape): """ Some protocols require a specific body to represent an empty @@ -600,7 +620,19 @@ def _partition_parameters( location = member.serialization.get('location') key_name = member.serialization.get('name', param_name) if location == 'uri': - partitioned['uri_path_kwargs'][key_name] = param_value + if isinstance(param_value, bool): + bool_str = str(param_value).lower() + partitioned['uri_path_kwargs'][key_name] = bool_str + elif member.type_name == 'timestamp': + timestamp_format = member.serialization.get( + 'timestampFormat', self.URI_TIMESTAMP_FORMAT + ) + timestamp = self._convert_timestamp_to_str( + param_value, timestamp_format + ) + partitioned['uri_path_kwargs'][key_name] = timestamp + else: + partitioned['uri_path_kwargs'][key_name] = param_value elif location == 'querystring': if isinstance(param_value, dict): partitioned['query_string_kwargs'].update(param_value) @@ -619,8 +651,8 @@ def _partition_parameters( partitioned['query_string_kwargs'][key_name] = param_value elif location == 'header': shape = shape_members[param_name] - if not param_value and shape.type_name == 'list': - # Empty lists should not be set on the headers + if not param_value and shape.type_name in ['list', 'string']: + # Empty lists and strings should not be set on the headers return value = self._convert_header_value(shape, param_value) partitioned['headers'][key_name] = str(value) @@ -685,10 +717,9 @@ def _requires_empty_body(self, shape): def _serialize_content_type(self, serialized, shape, shape_members): """Set Content-Type to application/json for all structured bodies.""" - payload = shape.serialization.get('payload') - if self._has_streaming_payload(payload, shape_members): - # Don't apply content-type to streaming bodies - return + self._handle_streaming_payload_content_type( + serialized, shape, shape_members + ) has_body = serialized['body'] != b'' has_content_type = has_header('Content-Type', serialized['headers']) @@ -722,12 +753,7 @@ def _serialize(self, shape, params, xmlnode, name): def _serialize_type_structure(self, xmlnode, params, shape, name): structure_node = ElementTree.SubElement(xmlnode, name) - if 'xmlNamespace' in shape.serialization: - namespace_metadata = shape.serialization['xmlNamespace'] - attribute_name = 'xmlns' - if namespace_metadata.get('prefix'): - attribute_name += f":{namespace_metadata['prefix']}" - structure_node.attrib[attribute_name] = namespace_metadata['uri'] + self._add_xml_namespace(shape, structure_node) for key, value in params.items(): member_shape = shape.members[key] member_name = member_shape.serialization.get('name', key) @@ -753,6 +779,7 @@ def _serialize_type_list(self, xmlnode, params, shape, name): else: element_name = member_shape.serialization.get('name', 'member') list_node = ElementTree.SubElement(xmlnode, name) + self._add_xml_namespace(shape, list_node) for item in params: self._serialize(member_shape, item, list_node, element_name) @@ -765,16 +792,22 @@ def _serialize_type_map(self, xmlnode, params, shape, name): # val1 # # - node = ElementTree.SubElement(xmlnode, name) - # TODO: handle flattened maps. + if not self._is_shape_flattened(shape): + node = ElementTree.SubElement(xmlnode, name) + self._add_xml_namespace(shape, node) + for key, value in params.items(): - entry_node = ElementTree.SubElement(node, 'entry') + sub_node = ( + ElementTree.SubElement(xmlnode, name) + if self._is_shape_flattened(shape) + else ElementTree.SubElement(node, 'entry') + ) key_name = self._get_serialized_name(shape.key, default_name='key') val_name = self._get_serialized_name( shape.value, default_name='value' ) - self._serialize(shape.key, key, entry_node, key_name) - self._serialize(shape.value, value, entry_node, val_name) + self._serialize(shape.key, key, sub_node, key_name) + self._serialize(shape.value, value, sub_node, val_name) def _serialize_type_boolean(self, xmlnode, params, shape, name): # For scalar types, the 'params' attr is actually just a scalar @@ -786,20 +819,50 @@ def _serialize_type_boolean(self, xmlnode, params, shape, name): else: str_value = 'false' node.text = str_value + self._add_xml_namespace(shape, node) def _serialize_type_blob(self, xmlnode, params, shape, name): node = ElementTree.SubElement(xmlnode, name) node.text = self._get_base64(params) + self._add_xml_namespace(shape, node) def _serialize_type_timestamp(self, xmlnode, params, shape, name): node = ElementTree.SubElement(xmlnode, name) - node.text = self._convert_timestamp_to_str( - params, shape.serialization.get('timestampFormat') + node.text = str( + self._convert_timestamp_to_str( + params, shape.serialization.get('timestampFormat') + ) ) + self._add_xml_namespace(shape, node) def _default_serialize(self, xmlnode, params, shape, name): node = ElementTree.SubElement(xmlnode, name) node.text = str(params) + self._add_xml_namespace(shape, node) + + def _serialize_content_type(self, serialized, shape, shape_members): + """Set Content-Type to application/xml for all structured bodies.""" + self._handle_streaming_payload_content_type( + serialized, shape, shape_members + ) + + has_body = serialized['body'] != b'' + has_content_type = has_header('Content-Type', serialized['headers']) + if has_body and not has_content_type: + serialized['headers']['Content-Type'] = 'application/xml' + + def _add_xml_namespace(self, shape, structure_node): + if 'xmlNamespace' in shape.serialization: + namespace_metadata = shape.serialization['xmlNamespace'] + attribute_name = 'xmlns' + if isinstance(namespace_metadata, dict): + if namespace_metadata.get('prefix'): + attribute_name += f":{namespace_metadata['prefix']}" + structure_node.attrib[attribute_name] = namespace_metadata[ + 'uri' + ] + elif isinstance(namespace_metadata, str): + structure_node.attrib[attribute_name] = namespace_metadata SERIALIZERS = { From 7db1cf332a4a55bdc9bd5fe331c92556b406bfbf Mon Sep 17 00:00:00 2001 From: jonathan343 Date: Tue, 30 Jul 2024 07:35:16 -0700 Subject: [PATCH 07/11] Fix more input serialization issues. --- botocore/serialize.py | 140 ++++++++++++++++++++++------------- tests/unit/test_protocols.py | 3 + 2 files changed, 90 insertions(+), 53 deletions(-) diff --git a/botocore/serialize.py b/botocore/serialize.py index 8bb33f7d75..a7474957f5 100644 --- a/botocore/serialize.py +++ b/botocore/serialize.py @@ -462,6 +462,11 @@ def serialize_to_request(self, parameters, operation_model): 'method', self.DEFAULT_METHOD ) shape = operation_model.input_shape + + host_prefix = self._expand_host_prefix(parameters, operation_model) + if host_prefix is not None: + serialized['host_prefix'] = host_prefix + if shape is None: serialized['url_path'] = operation_model.http['requestUri'] return serialized @@ -509,10 +514,6 @@ def serialize_to_request(self, parameters, operation_model): ) self._serialize_content_type(serialized, shape, shape_members) - host_prefix = self._expand_host_prefix(parameters, operation_model) - if host_prefix is not None: - serialized['host_prefix'] = host_prefix - return serialized def _render_uri_template(self, uri_template, params): @@ -577,19 +578,6 @@ def _serialize_content_type(self, serialized, shape, shape_members): """ pass - def _handle_streaming_payload_content_type( - self, serialized, shape, shape_members - ): - """Set Content-Type header for streaming payload member types.""" - payload = shape.serialization.get('payload') - if self._has_streaming_payload(payload, shape_members): - if shape_members[payload].type_name == 'string': - serialized['headers']['Content-Type'] = 'text/plain' - elif shape_members[payload].type_name == 'blob': - serialized['headers']['Content-Type'] = ( - 'application/octet-stream' - ) - def _requires_empty_body(self, shape): """ Some protocols require a specific body to represent an empty @@ -635,27 +623,26 @@ def _partition_parameters( partitioned['uri_path_kwargs'][key_name] = param_value elif location == 'querystring': if isinstance(param_value, dict): - partitioned['query_string_kwargs'].update(param_value) - elif isinstance(param_value, bool): - bool_str = str(param_value).lower() - partitioned['query_string_kwargs'][key_name] = bool_str - elif member.type_name == 'timestamp': - timestamp_format = member.serialization.get( - 'timestampFormat', self.QUERY_STRING_TIMESTAMP_FORMAT - ) - timestamp = self._convert_timestamp_to_str( - param_value, timestamp_format - ) - partitioned['query_string_kwargs'][key_name] = timestamp + # Add only new query string key/value pairs. + # Named query parameters should take precedence. + for key, value in param_value.items(): + partitioned['query_string_kwargs'].setdefault(key, value) + elif member.type_name == 'list': + new_param = [ + self._get_query_string_value(value, member.member) + for value in param_value + ] + partitioned['query_string_kwargs'][key_name] = new_param else: - partitioned['query_string_kwargs'][key_name] = param_value + new_param = self._get_query_string_value(param_value, member) + partitioned['query_string_kwargs'][key_name] = new_param elif location == 'header': shape = shape_members[param_name] if not param_value and shape.type_name in ['list', 'string']: # Empty lists and strings should not be set on the headers return value = self._convert_header_value(shape, param_value) - partitioned['headers'][key_name] = str(value) + partitioned['headers'][key_name] = value elif location == 'headers': # 'headers' is a bit of an oddball. The ``key_name`` # is actually really a prefix for the header names: @@ -670,6 +657,19 @@ def _partition_parameters( else: partitioned['body_kwargs'][param_name] = param_value + def _get_query_string_value(self, param_value, member): + if isinstance(param_value, bool): + return str(param_value).lower() + elif member.type_name == 'timestamp': + timestamp_format = member.serialization.get( + 'timestampFormat', self.QUERY_STRING_TIMESTAMP_FORMAT + ) + return self._convert_timestamp_to_str( + param_value, timestamp_format + ) + else: + return param_value + def _do_serialize_header_map(self, header_prefix, headers, user_input): for key, val in user_input.items(): full_key = header_prefix + key @@ -679,24 +679,41 @@ def _serialize_body_params(self, params, shape): raise NotImplementedError('_serialize_body_params') def _convert_header_value(self, shape, value): - if shape.type_name == 'timestamp': + if isinstance(value, bool): + return str(value).lower() + elif shape.type_name == 'timestamp': datetime_obj = parse_to_aware_datetime(value) timestamp = calendar.timegm(datetime_obj.utctimetuple()) timestamp_format = shape.serialization.get( 'timestampFormat', self.HEADER_TIMESTAMP_FORMAT ) - return self._convert_timestamp_to_str(timestamp, timestamp_format) + return str( + self._convert_timestamp_to_str(timestamp, timestamp_format) + ) elif shape.type_name == 'list': - converted_value = [ - self._convert_header_value(shape.member, v) - for v in value - if v is not None - ] - return ",".join(converted_value) + if shape.member.type_name == "string": + converted_value = [ + self._escape_header_list_string(v) + for v in value + if v is not None + ] + else: + converted_value = [ + self._convert_header_value(shape.member, v) + for v in value + if v is not None + ] + return ", ".join(converted_value) elif is_json_value_header(shape): # Serialize with no spaces after separators to save space in # the header. return self._get_base64(json.dumps(value, separators=(',', ':'))) + else: + return str(value) + + def _escape_header_list_string(self, value): + if '"' in value or ',' in value: + return '"' + value.replace('"', '\\"') + '"' else: return value @@ -717,18 +734,29 @@ def _requires_empty_body(self, shape): def _serialize_content_type(self, serialized, shape, shape_members): """Set Content-Type to application/json for all structured bodies.""" - self._handle_streaming_payload_content_type( - serialized, shape, shape_members - ) - - has_body = serialized['body'] != b'' has_content_type = has_header('Content-Type', serialized['headers']) - if has_body and not has_content_type: - serialized['headers']['Content-Type'] = 'application/json' + if has_content_type: + return + payload = shape.serialization.get('payload') + if self._has_streaming_payload(payload, shape_members): + if shape_members[payload].type_name == 'string': + serialized['headers']['Content-Type'] = 'text/plain' + elif shape_members[payload].type_name == 'blob': + serialized['headers']['Content-Type'] = ( + 'application/octet-stream' + ) + else: + if serialized['body'] != b'': + serialized['headers']['Content-Type'] = 'application/json' def _serialize_body_params(self, params, shape): serialized_body = self.MAP_TYPE() self._serialize(serialized_body, params, shape) + # Handle document types as a payload + if list(serialized_body.keys()) == [None] and shape.metadata.get( + 'document' + ): + serialized_body = serialized_body[None] return json.dumps(serialized_body).encode(self.DEFAULT_ENCODING) @@ -842,14 +870,20 @@ def _default_serialize(self, xmlnode, params, shape, name): def _serialize_content_type(self, serialized, shape, shape_members): """Set Content-Type to application/xml for all structured bodies.""" - self._handle_streaming_payload_content_type( - serialized, shape, shape_members - ) - - has_body = serialized['body'] != b'' has_content_type = has_header('Content-Type', serialized['headers']) - if has_body and not has_content_type: - serialized['headers']['Content-Type'] = 'application/xml' + if has_content_type: + return + payload = shape.serialization.get('payload') + if self._has_streaming_payload(payload, shape_members): + if shape_members[payload].type_name == 'string': + serialized['headers']['Content-Type'] = 'text/plain' + elif shape_members[payload].type_name == 'blob': + serialized['headers']['Content-Type'] = ( + 'application/octet-stream' + ) + else: + if serialized['body'] != b'': + serialized['headers']['Content-Type'] = 'application/xml' def _add_xml_namespace(self, shape, structure_node): if 'xmlNamespace' in shape.serialization: diff --git a/tests/unit/test_protocols.py b/tests/unit/test_protocols.py index b5c5ffd031..dd8f338dda 100644 --- a/tests/unit/test_protocols.py +++ b/tests/unit/test_protocols.py @@ -100,7 +100,10 @@ 'rest-xml': RestXMLParser, } PROTOCOL_TEST_BLACKLIST = [ + # These cases test functionality outside the serializers and parsers. "Test cases for QueryIdempotencyTokenAutoFill operation", + "Test cases for PutWithContentEncoding operation", + "Test cases for HttpChecksumRequired operation", ] From 752465c3da2f19deca736a9508cc69756238beb3 Mon Sep 17 00:00:00 2001 From: jonathan343 Date: Thu, 15 Aug 2024 14:44:47 -0700 Subject: [PATCH 08/11] Partially address PR feedback. --- botocore/parsers.py | 25 +++++++++++-------------- botocore/serialize.py | 5 ++++- tests/unit/test_protocols.py | 11 ++++------- 3 files changed, 19 insertions(+), 22 deletions(-) diff --git a/botocore/parsers.py b/botocore/parsers.py index c214262234..f74140cf09 100644 --- a/botocore/parsers.py +++ b/botocore/parsers.py @@ -124,6 +124,7 @@ from botocore.compat import ETree, XMLParseError from botocore.eventstream import EventStream, NoInitialResponseError from botocore.utils import ( + ensure_boolean, is_json_value_header, lowercase_dict, merge_dicts, @@ -204,7 +205,7 @@ class ResponseParser: # This is a list of known values for the "location" key in the # serialization dict. The location key tells us where in the response # to parse the value. - KNOWN_LOCATIONS = ['statusCode', 'header', 'headers'] + KNOWN_LOCATIONS = ('statusCode', 'header', 'headers') def __init__(self, timestamp_parser=None, blob_parser=None): if timestamp_parser is None: @@ -437,11 +438,10 @@ def _handle_structure(self, shape, node): member_shape = members[member_name] location = member_shape.serialization.get('location') if ( - location - and location in self.KNOWN_LOCATIONS + location in self.KNOWN_LOCATIONS or member_shape.serialization.get('eventheader') ): - # All members with know locations have already been handled, + # All members with known locations have already been handled, # so we don't need to parse these members. continue xml_name = self._member_key_name(member_shape, member_name) @@ -551,6 +551,8 @@ def _handle_blob(self, shape, text): class QueryParser(BaseXMLResponseParser): + ROOT_NODE_SUFFIX = 'Result' + def _do_error_parse(self, response, shape): xml_contents = response['body'] root = self._parse_xml_string_to_dom(xml_contents) @@ -589,9 +591,8 @@ def _parse_body_as_xml(self, response, shape, inject_metadata=True): operation_name = response.get("context", {}).get( "operation_name", "" ) - inferred_wrapper_name = operation_name + "Result" inferred_wrapper = self._find_result_wrapped_shape( - inferred_wrapper_name, root + f"{operation_name}{self.ROOT_NODE_SUFFIX}", root ) if inferred_wrapper is not None: start = inferred_wrapper @@ -615,6 +616,8 @@ def _inject_response_metadata(self, node, inject_into): class EC2QueryParser(QueryParser): + ROOT_NODE_SUFFIX = 'Response' + def _inject_response_metadata(self, node, inject_into): mapping = self._build_name_to_xml_node(node) child_node = mapping.get('requestId') @@ -979,7 +982,7 @@ def _parse_non_payload_attrs( for name in member_shapes: member_shape = member_shapes[name] location = member_shape.serialization.get('location') - if location is None or location not in self.KNOWN_LOCATIONS: + if location is None: continue elif location == 'statusCode': final_parsed[name] = self._parse_shape( @@ -1052,13 +1055,7 @@ def _initial_body_parse(self, body_contents): return self._parse_body_as_json(body_contents) def _handle_boolean(self, shape, value): - # It's possible to receive a boolean as a string - if isinstance(value, str): - if value == 'true': - return True - else: - return False - return value + return ensure_boolean(value) def _handle_integer(self, shape, value): return int(value) diff --git a/botocore/serialize.py b/botocore/serialize.py index a7474957f5..bdc9525b34 100644 --- a/botocore/serialize.py +++ b/botocore/serialize.py @@ -559,7 +559,10 @@ def _serialize_payload( body_params, shape_members[payload_member] ) else: - serialized['body'] = self._serialize_empty_body() + if shape_members[payload_member].is_tagged_union: + serialized['body'] = b'' + else: + serialized['body'] = self._serialize_empty_body() elif partitioned['body_kwargs']: serialized['body'] = self._serialize_body_params( partitioned['body_kwargs'], shape diff --git a/tests/unit/test_protocols.py b/tests/unit/test_protocols.py index dd8f338dda..501c27b509 100644 --- a/tests/unit/test_protocols.py +++ b/tests/unit/test_protocols.py @@ -52,7 +52,6 @@ """ import copy -import math import os import xml.etree.ElementTree as ET from base64 import b64decode @@ -99,12 +98,12 @@ 'rest-json': RestJSONParser, 'rest-xml': RestXMLParser, } -PROTOCOL_TEST_BLACKLIST = [ +PROTOCOL_TEST_BLOCKLIST = ( # These cases test functionality outside the serializers and parsers. "Test cases for QueryIdempotencyTokenAutoFill operation", "Test cases for PutWithContentEncoding operation", "Test cases for HttpChecksumRequired operation", -] +) class TestType(Enum): @@ -122,7 +121,7 @@ def _compliance_tests(test_type=None): for full_path in _walk_files(): if full_path.endswith('.json'): for model, case, basename in _load_cases(full_path): - if model.get('description') in PROTOCOL_TEST_BLACKLIST: + if model.get('description') in PROTOCOL_TEST_BLOCKLIST: continue if 'params' in case and inp: yield model, case, basename @@ -324,9 +323,7 @@ def _convert_bytes_to_str(parsed): def _special_floats_to_str(value): if isinstance(value, float): - if value in [float('Infinity'), float('-Infinity')] or math.isnan( - value - ): + if value in [float('Infinity'), float('-Infinity')] or value != value: return json.dumps(value) return value From 35aeaf6d43c983fa697f6e9441c7bd2061ab4c33 Mon Sep 17 00:00:00 2001 From: jonathan343 Date: Mon, 19 Aug 2024 15:26:22 -0700 Subject: [PATCH 09/11] Implement granular protocol tests ignore list. --- .../protocols/protocol-tests-ignore-list.json | 100 ++++++++++++++++++ tests/unit/test_protocols.py | 72 +++++++++++-- 2 files changed, 164 insertions(+), 8 deletions(-) create mode 100644 tests/unit/protocols/protocol-tests-ignore-list.json diff --git a/tests/unit/protocols/protocol-tests-ignore-list.json b/tests/unit/protocols/protocol-tests-ignore-list.json new file mode 100644 index 0000000000..562e73f013 --- /dev/null +++ b/tests/unit/protocols/protocol-tests-ignore-list.json @@ -0,0 +1,100 @@ +{ + "general": { + "input": { + "suites": [ + "Test cases for PutWithContentEncoding operation", + "Test cases for QueryIdempotencyTokenAutoFill operation", + "Test cases for HostWithPathOperation operation" + ] + } + }, + "protocols": { + "ec2" : { + "input" : { + "cases": [ + "Ec2QueryEndpointTraitWithHostLabel", + "Ec2Lists", + "Ec2TimestampsInput" + ] + }, + "output": { + "cases": [ + "Ec2ComplexError" + ] + } + }, + "query" : { + "output": { + "cases": [ + "QueryEmptyInputAndEmptyOutput", + "QueryCustomizedError", + "QueryComplexError", + "QueryNoInputAndNoOutput", + "QueryNoInputAndOutput" + ] + } + }, + "json" : { + "input" : { + "cases": [ + "sends_requests_to_slash", + "includes_x_amz_target_and_content_type" + ] + }, + "output" : { + "cases": [ + "AwsJson11FooErrorUsingXAmznErrorTypeWithUriAndNamespace", + "AwsJson11FooErrorUsingXAmznErrorTypeWithUri" + ] + } + }, + "json_1_0" : { + "output" : { + "cases": [ + "AwsJson10FooErrorUsingXAmznErrorType", + "AwsJson10FooErrorUsingXAmznErrorTypeWithUri", + "AwsJson10FooErrorUsingXAmznErrorTypeWithUriAndNamespace" + ] + } + }, + "rest-json" : { + "input" : { + "cases": [ + "MediaTypeHeaderInputBase64", + "RestJsonHttpChecksumRequired" + ] + }, + "output" : { + "cases": [ + "RestJsonFooErrorUsingXAmznErrorType", + "RestJsonFooErrorUsingXAmznErrorTypeWithUri", + "RestJsonFooErrorUsingXAmznErrorTypeWithUriAndNamespace", + "RestJsonHttpPayloadTraitsWithNoBlobBody", + "RestJsonHttpPayloadWithUnsetUnion", + "RestJsonInputAndOutputWithTimestampHeaders" + ] + } + }, + "rest-xml": { + "input": { + "cases": [ + "BodyWithXmlName", + "RestXmlHttpPayloadWithUnion", + "HttpPayloadWithXmlName", + "HttpPayloadWithXmlNamespace", + "HttpPayloadWithXmlNamespaceAndPrefix", + "XmlAttributesOnPayload" + ] + }, + "output": { + "cases": [ + "InputAndOutputWithTimestampHeaders", + "RestXmlHttpPayloadWithUnsetUnion", + "HttpPayloadTraitsWithNoBlobBody", + "ComplexError", + "BodyWithXmlName" + ] + } + } + } +} diff --git a/tests/unit/test_protocols.py b/tests/unit/test_protocols.py index 501c27b509..4d2ac9caea 100644 --- a/tests/unit/test_protocols.py +++ b/tests/unit/test_protocols.py @@ -98,12 +98,10 @@ 'rest-json': RestJSONParser, 'rest-xml': RestXMLParser, } -PROTOCOL_TEST_BLOCKLIST = ( - # These cases test functionality outside the serializers and parsers. - "Test cases for QueryIdempotencyTokenAutoFill operation", - "Test cases for PutWithContentEncoding operation", - "Test cases for HttpChecksumRequired operation", -) +IGNORE_LIST_FILENAME = "protocol-tests-ignore-list.json" +PROTOCOL_TEST_IGNORE_LIST_PATH = os.path.join(TEST_DIR, IGNORE_LIST_FILENAME) +with open(PROTOCOL_TEST_IGNORE_LIST_PATH) as f: + PROTOCOL_TEST_IGNORE_LIST = json.load(f) class TestType(Enum): @@ -121,7 +119,13 @@ def _compliance_tests(test_type=None): for full_path in _walk_files(): if full_path.endswith('.json'): for model, case, basename in _load_cases(full_path): - if model.get('description') in PROTOCOL_TEST_BLOCKLIST: + protocol = basename.replace('.json', '') + if _should_ignore_test( + protocol, + "input" if inp else "output", + model['description'], + case['id'], + ): continue if 'params' in case and inp: yield model, case, basename @@ -431,7 +435,7 @@ def _assert_requests_equal(actual, expected, protocol_type): expected_body = expected.get('body', '').encode('utf-8') actual_body = actual['body'] # The expected bodies in our consumed protocol tests have extra - # whitespace and newlines that need to handled. We need to normalize + # whitespace and newlines that need to be handled. We need to normalize # the expected and actual response bodies before evaluating equivalence. try: if protocol_type in ['json', 'rest-json']: @@ -481,6 +485,8 @@ def _walk_files(): else: for root, _, filenames in os.walk(TEST_DIR): for filename in filenames: + if filename == IGNORE_LIST_FILENAME: + continue yield os.path.join(root, filename) @@ -525,3 +531,53 @@ def _get_suite_test_id(): "integers." ) return suite_id, test_id + + +def _should_ignore_test(protocol, test_type, suite, case): + """ + Determines if a protocol test should be ignored. + + This function checks the following, in order: + 1. General test suites to ignore across all protocols. + 2. General test cases to ignore across all protocols. + 3. Protocol-specific test suites to ignore + 4. Protocol-specific test cases to ignore + + :type protocol: str + :param protocol: The protocol name as represented by its corresponding + protocol test file name (without the .json extension). + + :type test_type: str + :param test_type: The protocol test type ("input" or "output"). + + :type suite: str + :param suite: The "description" attribute of a protocol test suite. + + :type case: str + :param case: The "id" attribute of a specific protocol test case. + + :return: True if the protocol test should be ignored, False otherwise. + :rtype: bool + """ + general_ignore_list = PROTOCOL_TEST_IGNORE_LIST['general'] + general_suites_to_ignore = general_ignore_list.get(test_type, {}).get( + 'suites', [] + ) + general_cases_to_ignore = general_ignore_list.get(test_type, {}).get( + 'cases', [] + ) + if suite in general_suites_to_ignore or case in general_cases_to_ignore: + return True + + protocol_ignore_list = PROTOCOL_TEST_IGNORE_LIST['protocols'].get( + protocol, {} + ) + protocol_suites_to_ignore = protocol_ignore_list.get(test_type, {}).get( + 'suites', [] + ) + protocol_cases_to_ignore = protocol_ignore_list.get(test_type, {}).get( + 'cases', [] + ) + return ( + suite in protocol_suites_to_ignore or case in protocol_cases_to_ignore + ) From 6afd16202d699fbe0592b51da6488488a27d573b Mon Sep 17 00:00:00 2001 From: jonathan343 Date: Wed, 21 Aug 2024 15:59:53 -0700 Subject: [PATCH 10/11] Clean up and more CR feedback. --- botocore/parsers.py | 16 +-- .../protocols/protocol-tests-ignore-list.json | 9 +- tests/unit/test_protocols.py | 108 ++++++++++-------- 3 files changed, 65 insertions(+), 68 deletions(-) diff --git a/botocore/parsers.py b/botocore/parsers.py index f74140cf09..0af710fd9a 100644 --- a/botocore/parsers.py +++ b/botocore/parsers.py @@ -361,6 +361,9 @@ def _has_unknown_tagged_union_member(self, shape, value): if shape.is_tagged_union: cleaned_value = value.copy() cleaned_value.pop("__type", None) + cleaned_value = { + k: v for k, v in cleaned_value.items() if v is not None + } if len(cleaned_value) != 1: error_msg = ( "Invalid service response: %s must have one and only " @@ -573,8 +576,6 @@ def _do_modeled_error_parse(self, response, shape): return self._parse_body_as_xml(response, shape, inject_metadata=False) def _do_parse(self, response, shape): - if not response.get('body'): - return {} return self._parse_body_as_xml(response, shape, inject_metadata=True) def _parse_body_as_xml(self, response, shape, inject_metadata=True): @@ -763,16 +764,7 @@ def _parse_body_as_json(self, body_contents): return {} body = body_contents.decode(self.DEFAULT_ENCODING) try: - # Function to remove null values from a JSON object. - def remove_nulls(obj): - if isinstance(obj, dict): - return {k: v for k, v in obj.items() if v is not None} - elif isinstance(obj, list): - return [v for v in obj if v is not None] - else: - return obj - - original_parsed = json.loads(body, object_hook=remove_nulls) + original_parsed = json.loads(body) return original_parsed except ValueError: # if the body cannot be parsed, include diff --git a/tests/unit/protocols/protocol-tests-ignore-list.json b/tests/unit/protocols/protocol-tests-ignore-list.json index 562e73f013..fcb8177a2a 100644 --- a/tests/unit/protocols/protocol-tests-ignore-list.json +++ b/tests/unit/protocols/protocol-tests-ignore-list.json @@ -35,12 +35,6 @@ } }, "json" : { - "input" : { - "cases": [ - "sends_requests_to_slash", - "includes_x_amz_target_and_content_type" - ] - }, "output" : { "cases": [ "AwsJson11FooErrorUsingXAmznErrorTypeWithUriAndNamespace", @@ -71,7 +65,8 @@ "RestJsonFooErrorUsingXAmznErrorTypeWithUriAndNamespace", "RestJsonHttpPayloadTraitsWithNoBlobBody", "RestJsonHttpPayloadWithUnsetUnion", - "RestJsonInputAndOutputWithTimestampHeaders" + "RestJsonInputAndOutputWithTimestampHeaders", + "RestJsonDeserializesDenseSetMapAndSkipsNull" ] } }, diff --git a/tests/unit/test_protocols.py b/tests/unit/test_protocols.py index 4d2ac9caea..18c6043353 100644 --- a/tests/unit/test_protocols.py +++ b/tests/unit/test_protocols.py @@ -432,42 +432,63 @@ def _serialize_request_description(request_dict): def _assert_requests_equal(actual, expected, protocol_type): - expected_body = expected.get('body', '').encode('utf-8') - actual_body = actual['body'] - # The expected bodies in our consumed protocol tests have extra - # whitespace and newlines that need to be handled. We need to normalize - # the expected and actual response bodies before evaluating equivalence. - try: - if protocol_type in ['json', 'rest-json']: - assert_equal( - json.loads(actual_body), - json.loads(expected_body), - 'Body value', - ) - elif protocol_type in ['rest-xml']: - tree1 = ET.canonicalize(actual_body, strip_text=True) - tree2 = ET.canonicalize(expected_body, strip_text=True) - assert_equal(tree1, tree2, 'Body value') - else: - assert_equal(actual_body, expected_body, 'Body value') - except (json.JSONDecodeError, ET.ParseError): - assert_equal(actual_body, expected_body, 'Body value') + if 'body' in expected: + expected_body = expected['body'].encode('utf-8') + actual_body = actual['body'] + _assert_request_body(actual_body, expected_body, protocol_type) actual_headers = HeadersDict(actual['headers']) - if protocol_type in ['query', 'ec2']: - if expected.get('headers', {}).get('Content-Type'): - expected['headers']['Content-Type'] += '; charset=utf-8' expected_headers = HeadersDict(expected.get('headers', {})) excluded_headers = expected.get('forbidHeaders', []) _assert_expected_headers_in_request( - actual_headers, expected_headers, excluded_headers + actual_headers, expected_headers, excluded_headers, protocol_type ) assert_equal(actual['url_path'], expected.get('uri', ''), "URI") if 'method' in expected: assert_equal(actual['method'], expected['method'], "Method") -def _assert_expected_headers_in_request(actual, expected, excluded_headers): +def _assert_request_body(actual, expected, protocol_type): + """ + Asserts the equivalence of actual and expected request bodies based + on protocol type. + + The expected bodies in our consumed protocol tests have extra + whitespace and newlines that need to be handled. We need to normalize + the expected and actual response bodies before evaluating equivalence. + """ + if protocol_type in ['json', 'rest-json']: + _assert_json_bodies(actual, expected, protocol_type) + elif protocol_type == 'rest-xml': + _assert_xml_bodies(actual, expected) + else: + assert_equal(actual, expected, 'Body value') + + +def _assert_json_bodies(actual, expected, protocol_type): + try: + assert_equal(json.loads(actual), json.loads(expected), 'Body value') + except json.JSONDecodeError as e: + if protocol_type == 'json': + raise e + assert_equal(actual, expected, 'Body value') + + +def _assert_xml_bodies(actual, expected): + try: + tree1 = ET.canonicalize(actual, strip_text=True) + tree2 = ET.canonicalize(expected, strip_text=True) + assert_equal(tree1, tree2, 'Body value') + except ET.ParseError: + assert_equal(actual, expected, 'Body value') + + +def _assert_expected_headers_in_request( + actual, expected, excluded_headers, protocol_type +): + if protocol_type in ['query', 'ec2']: + if expected.get('Content-Type'): + expected['Content-Type'] += '; charset=utf-8' for header, value in expected.items(): assert header in actual assert actual[header] == value @@ -537,12 +558,6 @@ def _should_ignore_test(protocol, test_type, suite, case): """ Determines if a protocol test should be ignored. - This function checks the following, in order: - 1. General test suites to ignore across all protocols. - 2. General test cases to ignore across all protocols. - 3. Protocol-specific test suites to ignore - 4. Protocol-specific test cases to ignore - :type protocol: str :param protocol: The protocol name as represented by its corresponding protocol test file name (without the .json extension). @@ -559,25 +574,20 @@ def _should_ignore_test(protocol, test_type, suite, case): :return: True if the protocol test should be ignored, False otherwise. :rtype: bool """ - general_ignore_list = PROTOCOL_TEST_IGNORE_LIST['general'] - general_suites_to_ignore = general_ignore_list.get(test_type, {}).get( - 'suites', [] - ) - general_cases_to_ignore = general_ignore_list.get(test_type, {}).get( - 'cases', [] + ignore_list = PROTOCOL_TEST_IGNORE_LIST.get('general', {}).get( + test_type, {} ) - if suite in general_suites_to_ignore or case in general_cases_to_ignore: + ignore_suites = ignore_list.get('suites', []) + ignore_cases = ignore_list.get('cases', []) + + if suite in ignore_suites or case in ignore_cases: return True - protocol_ignore_list = PROTOCOL_TEST_IGNORE_LIST['protocols'].get( - protocol, {} - ) - protocol_suites_to_ignore = protocol_ignore_list.get(test_type, {}).get( - 'suites', [] - ) - protocol_cases_to_ignore = protocol_ignore_list.get(test_type, {}).get( - 'cases', [] - ) - return ( - suite in protocol_suites_to_ignore or case in protocol_cases_to_ignore + protocol_ignore_list = ( + PROTOCOL_TEST_IGNORE_LIST.get('protocols', {}) + .get(protocol, {}) + .get(test_type, {}) ) + protocol_ignore_suites = protocol_ignore_list.get('suites', []) + protocol_ignore_cases = protocol_ignore_list.get('cases', []) + return suite in protocol_ignore_suites or case in protocol_ignore_cases From 2ec3a189bd3c899b9aff3288f2321ba3362f8357 Mon Sep 17 00:00:00 2001 From: jonathan343 Date: Thu, 22 Aug 2024 12:26:43 -0700 Subject: [PATCH 11/11] Use UTF-8 by default on windows to match the expected output from Smithy. --- tests/unit/test_protocols.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/unit/test_protocols.py b/tests/unit/test_protocols.py index 18c6043353..ece3e51ae3 100644 --- a/tests/unit/test_protocols.py +++ b/tests/unit/test_protocols.py @@ -517,7 +517,9 @@ def _load_cases(full_path): # The format is BOTOCORE_TEST_ID=suite_id:test_id or # BOTOCORE_TEST_ID=suite_id suite_id, test_id = _get_suite_test_id() - all_test_data = json.load(open(full_path), object_pairs_hook=OrderedDict) + all_test_data = json.load( + open(full_path, encoding='utf-8'), object_pairs_hook=OrderedDict + ) basename = os.path.basename(full_path) for i, test_data in enumerate(all_test_data): if suite_id is not None and i != suite_id: