def test_response_metadata_parsed_for_ec2(self): parser = parsers.EC2QueryParser() response = ('<OperationNameResponse>' ' <Str>myname</Str>' ' <requestId>request-id</requestId>' '</OperationNameResponse>').encode('utf-8') output_shape = model.StructureShape( 'OutputShape', { 'type': 'structure', 'members': { 'Str': { 'shape': 'StringType', } } }, model.ShapeResolver({'StringType': { 'type': 'string' }})) parsed = parser.parse( { 'headers': {}, 'body': response, 'status_code': 200 }, output_shape) # Note that the response metadata is normalized to match the query # protocol, even though this is not how it appears in the output. self.assertEqual( parsed, { 'Str': 'myname', 'ResponseMetadata': { 'RequestId': 'request-id', 'HTTPStatusCode': 200, 'HTTPHeaders': {} } })
def test_shape_list(self): shapes = { 'mfaDeviceListType': { "type": "list", "member": { "shape": "MFADevice" }, }, 'MFADevice': { 'type': 'structure', 'members': { 'UserName': { 'shape': 'userNameType' } } }, 'userNameType': { 'type': 'string' } } resolver = model.ShapeResolver(shapes) shape = resolver.get_shape_by_name('mfaDeviceListType') self.assertEqual(shape.member.type_name, 'structure') self.assertEqual(shape.member.name, 'MFADevice') self.assertEqual(list(shape.member.members), ['UserName'])
def test_metadata_always_exists_for_ec2(self): # ResponseMetadata is used for more than just the request id. It # should always get populated, even if the request doesn't seem to # have an id. parser = parsers.EC2QueryParser() response = ('<OperationNameResponse>' ' <Str>myname</Str>' '</OperationNameResponse>').encode('utf-8') output_shape = model.StructureShape( 'OutputShape', { 'type': 'structure', 'members': { 'Str': { 'shape': 'StringType', } } }, model.ShapeResolver({'StringType': { 'type': 'string' }})) parsed = parser.parse( { 'headers': {}, 'body': response, 'status_code': 200 }, output_shape) expected = { 'Str': 'myname', 'ResponseMetadata': { 'HTTPStatusCode': 200, 'HTTPHeaders': {} } } self.assertEqual(parsed, expected)
def test_shape_type_structure(self): shapes = { 'ChangePasswordRequest': { 'type': 'structure', 'members': { 'OldPassword': { 'shape': 'passwordType' }, 'NewPassword': { 'shape': 'passwordType' }, } }, 'passwordType': { "type": "string", } } resolver = model.ShapeResolver(shapes) shape = resolver.get_shape_by_name('ChangePasswordRequest') self.assertEqual(shape.type_name, 'structure') self.assertEqual(shape.name, 'ChangePasswordRequest') self.assertEqual(list(sorted(shape.members)), ['NewPassword', 'OldPassword']) self.assertEqual(shape.members['OldPassword'].name, 'passwordType') self.assertEqual(shape.members['OldPassword'].type_name, 'string')
def test_shape_metadata(self): shapes = { 'ChangePasswordRequest': { 'type': 'structure', 'required': ['OldPassword', 'NewPassword'], 'members': { 'OldPassword': { 'shape': 'passwordType' }, 'NewPassword': { 'shape': 'passwordType' }, } }, 'passwordType': { "type": "string", "min": 1, "max": 128, "sensitive": True } } resolver = model.ShapeResolver(shapes) shape = resolver.get_shape_by_name('ChangePasswordRequest') self.assertEqual(shape.metadata['required'], ['OldPassword', 'NewPassword']) member = shape.members['OldPassword'] self.assertEqual(member.metadata['min'], 1) self.assertEqual(member.metadata['max'], 128) self.assertEqual(member.metadata['sensitive'], True)
def test_serialization_cache(self): shape_map = { 'Foo': { 'type': 'structure', 'members': { 'Baz': { 'shape': 'StringType', 'locationName': 'other' }, } }, "StringType": { "type": "string" } } resolver = model.ShapeResolver(shape_map) shape = resolver.resolve_shape_ref({ 'shape': 'StringType', 'locationName': 'other' }) self.assertEqual(shape.serialization['name'], 'other') # serialization is computed on demand, and a cache is kept. # This is just verifying that trying to access serialization again # gives the same result. We don't actually care that it's cached, # we just care that the cache doesn't mess with correctness. self.assertEqual(shape.serialization['name'], 'other')
def test_response_no_initial_event_stream(self): parser = parsers.JSONParser() output_shape = model.StructureShape( 'OutputShape', { 'type': 'structure', 'members': { 'Payload': { 'shape': 'Payload' } } }, model.ShapeResolver({ 'Payload': { 'type': 'structure', 'members': [], 'eventstream': True } })) with self.assertRaises(parsers.ResponseParserError): response_dict = { 'status_code': 200, 'headers': {}, 'body': RawResponse(b''), 'context': { 'operation_name': 'TestOperation' } } parser.parse(response_dict, output_shape)
def test_resolve_shape_references_with_member_traits(self): shape_map = { 'Foo': { 'type': 'structure', 'members': { 'Bar': { 'shape': 'StringType' }, 'Baz': { 'shape': 'StringType', 'locationName': 'other' }, } }, "StringType": { "type": "string" } } resolver = model.ShapeResolver(shape_map) shape = resolver.resolve_shape_ref({ 'shape': 'StringType', 'locationName': 'other' }) self.assertEqual(shape.serialization['name'], 'other') self.assertEqual(shape.name, 'StringType')
def test_response_metadata_on_rest_json_response(self): parser = parsers.RestJSONParser() response = b'{"Str": "mystring"}' headers = {'x-amzn-requestid': 'request-id'} output_shape = model.StructureShape( 'OutputShape', { 'type': 'structure', 'members': { 'Str': { 'shape': 'StringType', } } }, model.ShapeResolver({'StringType': { 'type': 'string' }})) parsed = parser.parse( { 'body': response, 'headers': headers, 'status_code': 200 }, output_shape) # Note that the response metadata is normalized to match the query # protocol, even though this is not how it appears in the output. self.assertEqual( parsed, { 'Str': 'mystring', 'ResponseMetadata': { 'RequestId': 'request-id', 'HTTPStatusCode': 200, 'HTTPHeaders': headers } })
def test_metadata_always_exists_on_rest_json_response(self): # ResponseMetadata is used for more than just the request id. It # should always get populated, even if the request doesn't seem to # have an id. parser = parsers.RestJSONParser() response = b'{"Str": "mystring"}' headers = {} output_shape = model.StructureShape( 'OutputShape', { 'type': 'structure', 'members': { 'Str': { 'shape': 'StringType', } } }, model.ShapeResolver({'StringType': { 'type': 'string' }})) parsed = parser.parse( { 'body': response, 'headers': headers, 'status_code': 200 }, output_shape) expected = { 'Str': 'mystring', 'ResponseMetadata': { 'HTTPStatusCode': 200, 'HTTPHeaders': headers } } self.assertEqual(parsed, expected)
def test_shape_name_in_repr(self): shapes = { 'StringType': { 'type': 'string', } } resolver = model.ShapeResolver(shapes) self.assertIn('StringType', repr(resolver.get_shape_by_name('StringType')))
def test_exception_error_code(self): shapes = { 'FooException': { 'exception': True, 'type': 'structure', 'members': {} } } # Test without explicit error code resolver = model.ShapeResolver(shapes) shape = resolver.get_shape_by_name('FooException') self.assertTrue(shape.metadata['exception']) self.assertEqual(shape.error_code, 'FooException') # Test with explicit error code shapes['FooException']['error'] = {'code': 'ExceptionCode'} resolver = model.ShapeResolver(shapes) shape = resolver.get_shape_by_name('FooException') self.assertTrue(shape.metadata['exception']) self.assertEqual(shape.error_code, 'ExceptionCode')
def create_arbitary_output_shape(self): output_shape = model.StructureShape( 'OutputShape', { 'type': 'structure', 'members': { 'Str': { 'shape': 'StringType', } } }, model.ShapeResolver({'StringType': { 'type': 'string' }})) return output_shape
def test_shape_overrides(self): shape_map = { "StringType": { "type": "string", "documentation": "Original documentation" } } resolver = model.ShapeResolver(shape_map) shape = resolver.get_shape_by_name('StringType') self.assertEqual(shape.documentation, 'Original documentation') shape = resolver.resolve_shape_ref({ 'shape': 'StringType', 'documentation': 'override' }) self.assertEqual(shape.documentation, 'override')
def test_response_metadata_parsed_for_query_service(self): parser = parsers.QueryParser() response = ( '<OperationNameResponse>' ' <OperationNameResult><Str>myname</Str></OperationNameResult>' ' <ResponseMetadata>' ' <RequestId>request-id</RequestId>' ' </ResponseMetadata>' '</OperationNameResponse>').encode('utf-8') output_shape = model.StructureShape( 'OutputShape', { 'type': 'structure', 'resultWrapper': 'OperationNameResult', 'members': { 'Str': { 'shape': 'StringType', }, 'Num': { 'shape': 'IntegerType', } } }, model.ShapeResolver({ 'StringType': { 'type': 'string', }, 'IntegerType': { 'type': 'integer', } })) parsed = parser.parse( { 'body': response, 'headers': {}, 'status_code': 200 }, output_shape) self.assertEqual( parsed, { 'Str': 'myname', 'ResponseMetadata': { 'RequestId': 'request-id', 'HTTPStatusCode': 200, 'HTTPHeaders': {} } })
def test_resolve_shape_reference(self): shape_map = { 'Foo': { 'type': 'structure', 'members': { 'Bar': { 'shape': 'StringType' }, 'Baz': { 'shape': 'StringType' }, } }, "StringType": { "type": "string" } } resolver = model.ShapeResolver(shape_map) shape = resolver.resolve_shape_ref({'shape': 'StringType'}) self.assertEqual(shape.name, 'StringType') self.assertEqual(shape.type_name, 'string')
def test_bad_shape_ref(self): # This is an example of a denormalized model, # which should raise an exception. shapes = { 'Struct': { 'type': 'structure', 'members': { 'A': { 'type': 'string' }, 'B': { 'type': 'string' }, } } } resolver = model.ShapeResolver(shapes) with self.assertRaises(model.InvalidShapeReferenceError): struct = resolver.get_shape_by_name('Struct') # Resolving the members will fail because # the 'A' and 'B' members are not shape refs. struct.members
def setUp(self): self.shapes = { 'SetQueueAttributes': { 'type': 'structure', 'members': { 'MapExample': { 'shape': 'StrToStrMap', 'locationName': 'Attribute' }, } }, 'SetQueueAttributes2': { 'type': 'structure', 'members': { 'MapExample': { 'shape': 'StrToStrMap', 'locationName': 'Attribute2' }, } }, 'StrToStrMap': { 'type': 'map', 'key': { 'shape': 'StringType', 'locationName': 'Name' }, 'value': { 'shape': 'StringType', 'locationName': 'Value' }, 'flattened': True, 'name': 'NotAttribute', }, 'StringType': { 'type': 'string' } } self.shape_resolver = model.ShapeResolver(self.shapes)
def test_error_shape_metadata(self): shapes = { 'ResourceNotFoundException': { 'type': 'structure', 'members': { 'message': { 'shape': 'ErrorMessage', } }, 'exception': True, 'retryable': { 'throttling': True } } } resolver = model.ShapeResolver(shapes) shape = resolver.get_shape_by_name('ResourceNotFoundException') self.assertEqual(shape.metadata, { 'exception': True, 'retryable': { 'throttling': True } })
def test_shape_does_not_exist(self): resolver = model.ShapeResolver({}) with self.assertRaises(model.NoShapeFoundError): resolver.get_shape_by_name('NoExistShape')
def setUp(self): self.parser = parsers.EventStreamXMLParser() self.output_shape = model.StructureShape( 'EventStream', { 'eventstream': True, 'type': 'structure', 'members': { 'EventA': { 'shape': 'EventAStructure' }, 'EventB': { 'shape': 'EventBStructure' }, 'EventC': { 'shape': 'EventCStructure' }, 'EventD': { 'shape': 'EventDStructure' }, 'EventException': { 'shape': 'ExceptionShape' }, } }, model.ShapeResolver({ 'EventAStructure': { 'event': True, 'type': 'structure', 'members': { 'Stats': { 'shape': 'StatsStructure', 'eventpayload': True }, 'Header': { 'shape': 'IntShape', 'eventheader': True } } }, 'EventBStructure': { 'event': True, 'type': 'structure', 'members': { 'Body': { 'shape': 'BlobShape', 'eventpayload': True } } }, 'EventCStructure': { 'event': True, 'type': 'structure', 'members': { 'Body': { 'shape': 'StringShape', 'eventpayload': True } } }, 'EventDStructure': { 'event': True, 'type': 'structure', 'members': { 'StringField': { 'shape': 'StringShape' }, 'IntField': { 'shape': 'IntShape' }, 'Header': { 'shape': 'IntShape', 'eventheader': True } } }, 'StatsStructure': { 'type': 'structure', 'members': { 'StringField': { 'shape': 'StringShape' }, 'IntField': { 'shape': 'IntShape' } } }, 'BlobShape': { 'type': 'blob' }, 'StringShape': { 'type': 'string' }, 'IntShape': { 'type': 'integer' }, 'ExceptionShape': { 'exception': True, 'type': 'structure', 'members': { 'message': { 'shape': 'StringShape' } } }, }))
def test_missing_type_key(self): shapes = {'UnknownType': {'NotTheTypeKey': 'someUnknownType'}} resolver = model.ShapeResolver(shapes) with self.assertRaises(model.InvalidShapeError): resolver.get_shape_by_name('UnknownType')