Example #1
0
 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)
Example #2
0
 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)
Example #3
0
 def test_recursive_shape(self):
     shapes = {
         'InputStructure': {
             'type': 'structure',
             'members': {
                 'A': {
                     'shape': 'RecursiveShape'
                 }
             }
         },
         'RecursiveShape': {
             'type': 'structure',
             'members': {
                 'B': {
                     'shape': 'StringType'
                 },
                 'C': {
                     'shape': 'RecursiveShape'
                 },
             }
         },
         'StringType': {
             'type': 'string'
         }
     }
     shape = model.StructureShape(
         shape_name='InputStructure',
         shape_model=shapes['InputStructure'],
         shape_resolver=model.ShapeResolver(shape_map=shapes))
     self.assertIn('recursive', detect_shape_structure(shape))
Example #4
0
 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')
Example #5
0
 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': {}
             }
         })
Example #6
0
 def test_can_document_recursive_struct(self):
     # It's a little more work to set up a recursive
     # shape because DenormalizedStructureBuilder cannot handle
     # recursion.
     struct_shape = {
         'type': 'structure',
         'members': OrderedDict([
             ('Recurse', {'shape': 'SubShape'}),
             ('Scalar', {'shape': 'String'}),
         ]),
     }
     shapes = {
         'Top': struct_shape,
         'String': {'type': 'string'},
         'SubShape': {
             'type': 'structure',
             'members': OrderedDict([
                 ('SubRecurse', {'shape': 'Top'}),
                 ('Scalar', {'shape': 'String'}),
             ]),
         }
     }
     m = model.StructureShape(
         shape_name='Top',
         shape_model=struct_shape,
         shape_resolver=model.ShapeResolver(shapes))
     argument = mock.Mock()
     argument.argument_model = m
     argument.name = 'foo'
     argument.cli_name = '--foo'
     generated_example = self.get_generated_example_for(argument)
     self.assertIn(
         'Recurse={SubRecurse={( ... recursive ... ),Scalar=string},'
         'Scalar=string},Scalar=string',
         generated_example)
Example #7
0
 def test_list_of_structures_with_triple_dots(self):
     list_shape = {
         'type': 'list',
         'member': {
             'shape': 'StructShape'
         },
     }
     shapes = {
         'Top': list_shape,
         'String': {
             'type': 'string'
         },
         'StructShape': {
             'type':
             'structure',
             'members':
             OrderedDict([
                 ('A', {
                     'shape': 'String'
                 }),
                 ('B', {
                     'shape': 'String'
                 }),
             ])
         }
     }
     m = model.ListShape(shape_name='Top',
                         shape_model=list_shape,
                         shape_resolver=model.ShapeResolver(shapes))
     argument = mock.Mock()
     argument.argument_model = m
     argument.name = 'foo'
     argument.cli_name = '--foo'
     generated_example = self.get_generated_example_for(argument)
     self.assertIn('A=string,B=string ...', generated_example)
Example #8
0
 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)
Example #9
0
 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')
Example #10
0
 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')
Example #11
0
 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)
Example #12
0
 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)
Example #13
0
 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'])
Example #14
0
 def test_list_of_structures_with_triple_dots(self):
     list_shape = {
         'type': 'list',
         'member': {
             'shape': 'StructShape'
         },
     }
     shapes = {
         'Top': list_shape,
         'String': {
             'type': 'string'
         },
         'StructShape': {
             'type':
             'structure',
             'members':
             OrderedDict([
                 ('A', {
                     'shape': 'String'
                 }),
                 ('B', {
                     'shape': 'String'
                 }),
             ])
         }
     }
     m = model.ListShape(shape_name='Top',
                         shape_model=list_shape,
                         shape_resolver=model.ShapeResolver(shapes))
     generated_example = self.shorthand_documenter.generate_shorthand_example(
         '--foo', m)
     self.assertIn('A=string,B=string ...', generated_example)
Example #15
0
 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
             }
         })
Example #16
0
 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')
Example #17
0
 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')))
Example #18
0
 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')
Example #19
0
def create_argument_model_from_schema(schema):
    # Given a JSON schems (described in schema.py), convert it
    # to a shape object from `botocore.model.Shape` that can be
    # used as the argument_model for the Argument classes below.
    transformer = SchemaTransformer()
    shapes_map = transformer.transform(schema)
    shape_resolver = model.ShapeResolver(shapes_map)
    # The SchemaTransformer guarantees that the top level shape
    # will always be named 'InputShape'.
    arg_shape = shape_resolver.get_shape_by_name('InputShape')
    return arg_shape
Example #20
0
 def setUp(self):
     self.error_shape = model.StructureShape(
         'ErrorShape', {
             'type': 'structure',
             'exception': True,
             'members': {
                 'ModeledField': {
                     'shape': 'StringType',
                 }
             }
         }, model.ShapeResolver({'StringType': {
             'type': 'string'
         }}))
Example #21
0
 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
Example #22
0
    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')
Example #23
0
 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')
Example #24
0
 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': {}
             }
         })
Example #25
0
 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
Example #26
0
 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}}
     )
Example #27
0
 def test_shape_does_not_exist(self):
     resolver = model.ShapeResolver({})
     with self.assertRaises(model.NoShapeFoundError):
         resolver.get_shape_by_name('NoExistShape')
 def get_shape(self):
     loader = loaders.Loader()
     service_data = loader.load_service_model(SERVICE, 'service-2')
     shape_resolver = model.ShapeResolver(service_data.get('shapes', {}))
     operation_data = service_data['operations'][OPERATION]
     return shape_resolver.resolve_shape_ref(operation_data['output'])
Example #29
0
 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'
                 },
             }
         },
         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'
             }
         }))