2015-11-24 12:34:53 +01:00
|
|
|
"""Additional tests for request serialization.
|
|
|
|
|
|
|
|
While there are compliance tests in tests/unit/protocols where
|
|
|
|
the majority of the request serialization/response parsing is tested,
|
|
|
|
this test module contains additional tests that go above and beyond the
|
|
|
|
spec. This can happen for a number of reasons:
|
|
|
|
|
|
|
|
* We are testing python specific behavior that doesn't make sense as a
|
|
|
|
compliance test.
|
|
|
|
* We are testing behavior that is not strictly part of the spec. These
|
|
|
|
may result in a a coverage gap that would otherwise be untested.
|
|
|
|
|
|
|
|
"""
|
|
|
|
import base64
|
|
|
|
import datetime
|
2022-05-26 00:10:07 +02:00
|
|
|
import json
|
|
|
|
|
2015-11-24 12:34:53 +01:00
|
|
|
import dateutil.tz
|
|
|
|
|
|
|
|
from botocore import serialize
|
|
|
|
from botocore.compat import six
|
2016-10-11 02:22:54 +02:00
|
|
|
from botocore.exceptions import ParamValidationError
|
2022-05-26 00:10:07 +02:00
|
|
|
from botocore.model import ServiceModel
|
|
|
|
from tests import unittest
|
2015-11-24 12:34:53 +01:00
|
|
|
|
|
|
|
|
|
|
|
class BaseModelWithBlob(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
|
|
self.model = {
|
|
|
|
'metadata': {'protocol': 'query', 'apiVersion': '2014-01-01'},
|
|
|
|
'documentation': '',
|
|
|
|
'operations': {
|
|
|
|
'TestOperation': {
|
|
|
|
'name': 'TestOperation',
|
|
|
|
'http': {
|
|
|
|
'method': 'POST',
|
|
|
|
'requestUri': '/',
|
|
|
|
},
|
|
|
|
'input': {'shape': 'InputShape'},
|
|
|
|
}
|
|
|
|
},
|
|
|
|
'shapes': {
|
|
|
|
'InputShape': {
|
|
|
|
'type': 'structure',
|
|
|
|
'members': {
|
|
|
|
'Blob': {'shape': 'BlobType'},
|
2022-05-26 00:10:07 +02:00
|
|
|
},
|
2015-11-24 12:34:53 +01:00
|
|
|
},
|
|
|
|
'BlobType': {
|
|
|
|
'type': 'blob',
|
2022-05-26 00:10:07 +02:00
|
|
|
},
|
|
|
|
},
|
2015-11-24 12:34:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
def serialize_to_request(self, input_params):
|
|
|
|
service_model = ServiceModel(self.model)
|
|
|
|
request_serializer = serialize.create_serializer(
|
2022-05-26 00:10:07 +02:00
|
|
|
service_model.metadata['protocol']
|
|
|
|
)
|
2015-11-24 12:34:53 +01:00
|
|
|
return request_serializer.serialize_to_request(
|
2022-05-26 00:10:07 +02:00
|
|
|
input_params, service_model.operation_model('TestOperation')
|
|
|
|
)
|
2015-11-24 12:34:53 +01:00
|
|
|
|
|
|
|
def assert_serialized_blob_equals(self, request, blob_bytes):
|
|
|
|
# This method handles all the details of the base64 decoding.
|
|
|
|
encoded = base64.b64encode(blob_bytes)
|
|
|
|
# Now the serializers actually have the base64 encoded contents
|
|
|
|
# as str types so we need to decode back. We know that this is
|
|
|
|
# ascii so it's safe to use the ascii encoding.
|
|
|
|
expected = encoded.decode('ascii')
|
|
|
|
self.assertEqual(request['body']['Blob'], expected)
|
|
|
|
|
|
|
|
|
|
|
|
class TestBinaryTypes(BaseModelWithBlob):
|
|
|
|
def test_blob_accepts_bytes_type(self):
|
|
|
|
body = b'bytes body'
|
|
|
|
request = self.serialize_to_request(input_params={'Blob': body})
|
2022-05-26 00:10:07 +02:00
|
|
|
self.assert_serialized_blob_equals(request, blob_bytes=body)
|
2015-11-24 12:34:53 +01:00
|
|
|
|
|
|
|
def test_blob_accepts_str_type(self):
|
2022-05-26 00:10:07 +02:00
|
|
|
body = 'ascii text'
|
2015-11-24 12:34:53 +01:00
|
|
|
request = self.serialize_to_request(input_params={'Blob': body})
|
|
|
|
self.assert_serialized_blob_equals(
|
2022-05-26 00:10:07 +02:00
|
|
|
request, blob_bytes=body.encode('ascii')
|
|
|
|
)
|
2015-11-24 12:34:53 +01:00
|
|
|
|
|
|
|
def test_blob_handles_unicode_chars(self):
|
2022-05-26 00:10:07 +02:00
|
|
|
body = '\u2713'
|
2015-11-24 12:34:53 +01:00
|
|
|
request = self.serialize_to_request(input_params={'Blob': body})
|
|
|
|
self.assert_serialized_blob_equals(
|
2022-05-26 00:10:07 +02:00
|
|
|
request, blob_bytes=body.encode('utf-8')
|
|
|
|
)
|
2015-11-24 12:34:53 +01:00
|
|
|
|
|
|
|
|
|
|
|
class TestBinaryTypesJSON(BaseModelWithBlob):
|
|
|
|
def setUp(self):
|
2022-05-26 00:10:07 +02:00
|
|
|
super().setUp()
|
2015-11-24 12:34:53 +01:00
|
|
|
self.model['metadata'] = {
|
|
|
|
'protocol': 'json',
|
|
|
|
'apiVersion': '2014-01-01',
|
|
|
|
'jsonVersion': '1.1',
|
|
|
|
'targetPrefix': 'foo',
|
|
|
|
}
|
|
|
|
|
|
|
|
def test_blob_accepts_bytes_type(self):
|
|
|
|
body = b'bytes body'
|
|
|
|
request = self.serialize_to_request(input_params={'Blob': body})
|
|
|
|
serialized_blob = json.loads(request['body'].decode('utf-8'))['Blob']
|
|
|
|
self.assertEqual(
|
2022-05-26 00:10:07 +02:00
|
|
|
base64.b64encode(body).decode('ascii'), serialized_blob
|
|
|
|
)
|
2015-11-24 12:34:53 +01:00
|
|
|
|
|
|
|
|
|
|
|
class TestBinaryTypesWithRestXML(BaseModelWithBlob):
|
|
|
|
def setUp(self):
|
2022-05-26 00:10:07 +02:00
|
|
|
super().setUp()
|
2015-11-24 12:34:53 +01:00
|
|
|
self.model['metadata'] = {
|
|
|
|
'protocol': 'rest-xml',
|
|
|
|
'apiVersion': '2014-01-01',
|
|
|
|
}
|
|
|
|
self.model['operations']['TestOperation']['input'] = {
|
|
|
|
'shape': 'InputShape',
|
|
|
|
'locationName': 'OperationRequest',
|
|
|
|
'payload': 'Blob',
|
|
|
|
}
|
|
|
|
|
|
|
|
def test_blob_serialization_with_file_like_object(self):
|
|
|
|
body = six.BytesIO(b'foobar')
|
|
|
|
request = self.serialize_to_request(input_params={'Blob': body})
|
|
|
|
self.assertEqual(request['body'], body)
|
|
|
|
|
|
|
|
def test_blob_serialization_when_payload_is_unicode(self):
|
|
|
|
# When the body is a text type, we should encode the
|
|
|
|
# text to bytes.
|
2022-05-26 00:10:07 +02:00
|
|
|
body = '\u2713'
|
2015-11-24 12:34:53 +01:00
|
|
|
request = self.serialize_to_request(input_params={'Blob': body})
|
|
|
|
self.assertEqual(request['body'], body.encode('utf-8'))
|
|
|
|
|
|
|
|
def test_blob_serialization_when_payload_is_bytes(self):
|
|
|
|
body = b'bytes body'
|
|
|
|
request = self.serialize_to_request(input_params={'Blob': body})
|
|
|
|
self.assertEqual(request['body'], body)
|
|
|
|
|
|
|
|
|
|
|
|
class TestTimestampHeadersWithRestXML(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
|
|
self.model = {
|
|
|
|
'metadata': {'protocol': 'rest-xml', 'apiVersion': '2014-01-01'},
|
|
|
|
'documentation': '',
|
|
|
|
'operations': {
|
|
|
|
'TestOperation': {
|
|
|
|
'name': 'TestOperation',
|
|
|
|
'http': {
|
|
|
|
'method': 'POST',
|
|
|
|
'requestUri': '/',
|
|
|
|
},
|
|
|
|
'input': {'shape': 'InputShape'},
|
|
|
|
}
|
|
|
|
},
|
|
|
|
'shapes': {
|
|
|
|
'InputShape': {
|
|
|
|
'type': 'structure',
|
|
|
|
'members': {
|
|
|
|
'TimestampHeader': {
|
|
|
|
'shape': 'TimestampType',
|
|
|
|
'location': 'header',
|
2022-05-26 00:10:07 +02:00
|
|
|
'locationName': 'x-timestamp',
|
2015-11-24 12:34:53 +01:00
|
|
|
},
|
2022-05-26 00:10:07 +02:00
|
|
|
},
|
2015-11-24 12:34:53 +01:00
|
|
|
},
|
|
|
|
'TimestampType': {
|
|
|
|
'type': 'timestamp',
|
2022-05-26 00:10:07 +02:00
|
|
|
},
|
|
|
|
},
|
2015-11-24 12:34:53 +01:00
|
|
|
}
|
|
|
|
self.service_model = ServiceModel(self.model)
|
|
|
|
|
|
|
|
def serialize_to_request(self, input_params):
|
|
|
|
request_serializer = serialize.create_serializer(
|
2022-05-26 00:10:07 +02:00
|
|
|
self.service_model.metadata['protocol']
|
|
|
|
)
|
2015-11-24 12:34:53 +01:00
|
|
|
return request_serializer.serialize_to_request(
|
2022-05-26 00:10:07 +02:00
|
|
|
input_params, self.service_model.operation_model('TestOperation')
|
|
|
|
)
|
2015-11-24 12:34:53 +01:00
|
|
|
|
|
|
|
def test_accepts_datetime_object(self):
|
|
|
|
request = self.serialize_to_request(
|
2022-05-26 00:10:07 +02:00
|
|
|
{
|
|
|
|
'TimestampHeader': datetime.datetime(
|
|
|
|
2014, 1, 1, 12, 12, 12, tzinfo=dateutil.tz.tzutc()
|
|
|
|
)
|
|
|
|
}
|
|
|
|
)
|
|
|
|
self.assertEqual(
|
|
|
|
request['headers']['x-timestamp'], 'Wed, 01 Jan 2014 12:12:12 GMT'
|
|
|
|
)
|
2015-11-24 12:34:53 +01:00
|
|
|
|
|
|
|
def test_accepts_iso_8601_format(self):
|
|
|
|
request = self.serialize_to_request(
|
2022-05-26 00:10:07 +02:00
|
|
|
{'TimestampHeader': '2014-01-01T12:12:12+00:00'}
|
|
|
|
)
|
|
|
|
self.assertEqual(
|
|
|
|
request['headers']['x-timestamp'], 'Wed, 01 Jan 2014 12:12:12 GMT'
|
|
|
|
)
|
2015-11-24 12:34:53 +01:00
|
|
|
|
|
|
|
def test_accepts_iso_8601_format_non_utc(self):
|
|
|
|
request = self.serialize_to_request(
|
2022-05-26 00:10:07 +02:00
|
|
|
{'TimestampHeader': '2014-01-01T07:12:12-05:00'}
|
|
|
|
)
|
|
|
|
self.assertEqual(
|
|
|
|
request['headers']['x-timestamp'], 'Wed, 01 Jan 2014 12:12:12 GMT'
|
|
|
|
)
|
2015-11-24 12:34:53 +01:00
|
|
|
|
|
|
|
def test_accepts_rfc_822_format(self):
|
|
|
|
request = self.serialize_to_request(
|
2022-05-26 00:10:07 +02:00
|
|
|
{'TimestampHeader': 'Wed, 01 Jan 2014 12:12:12 GMT'}
|
|
|
|
)
|
|
|
|
self.assertEqual(
|
|
|
|
request['headers']['x-timestamp'], 'Wed, 01 Jan 2014 12:12:12 GMT'
|
|
|
|
)
|
2015-11-24 12:34:53 +01:00
|
|
|
|
|
|
|
def test_accepts_unix_timestamp_integer(self):
|
2022-05-26 00:10:07 +02:00
|
|
|
request = self.serialize_to_request({'TimestampHeader': 1388578332})
|
|
|
|
self.assertEqual(
|
|
|
|
request['headers']['x-timestamp'], 'Wed, 01 Jan 2014 12:12:12 GMT'
|
|
|
|
)
|
2015-11-24 12:34:53 +01:00
|
|
|
|
|
|
|
|
|
|
|
class TestTimestamps(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
|
|
self.model = {
|
|
|
|
'metadata': {'protocol': 'query', 'apiVersion': '2014-01-01'},
|
|
|
|
'documentation': '',
|
|
|
|
'operations': {
|
|
|
|
'TestOperation': {
|
|
|
|
'name': 'TestOperation',
|
|
|
|
'http': {
|
|
|
|
'method': 'POST',
|
|
|
|
'requestUri': '/',
|
|
|
|
},
|
|
|
|
'input': {'shape': 'InputShape'},
|
|
|
|
}
|
|
|
|
},
|
|
|
|
'shapes': {
|
|
|
|
'InputShape': {
|
|
|
|
'type': 'structure',
|
|
|
|
'members': {
|
|
|
|
'Timestamp': {'shape': 'TimestampType'},
|
2022-05-26 00:10:07 +02:00
|
|
|
},
|
2015-11-24 12:34:53 +01:00
|
|
|
},
|
|
|
|
'TimestampType': {
|
|
|
|
'type': 'timestamp',
|
2022-05-26 00:10:07 +02:00
|
|
|
},
|
|
|
|
},
|
2015-11-24 12:34:53 +01:00
|
|
|
}
|
|
|
|
self.service_model = ServiceModel(self.model)
|
|
|
|
|
|
|
|
def serialize_to_request(self, input_params):
|
|
|
|
request_serializer = serialize.create_serializer(
|
2022-05-26 00:10:07 +02:00
|
|
|
self.service_model.metadata['protocol']
|
|
|
|
)
|
2015-11-24 12:34:53 +01:00
|
|
|
return request_serializer.serialize_to_request(
|
2022-05-26 00:10:07 +02:00
|
|
|
input_params, self.service_model.operation_model('TestOperation')
|
|
|
|
)
|
2015-11-24 12:34:53 +01:00
|
|
|
|
|
|
|
def test_accepts_datetime_object(self):
|
|
|
|
request = self.serialize_to_request(
|
2022-05-26 00:10:07 +02:00
|
|
|
{
|
|
|
|
'Timestamp': datetime.datetime(
|
|
|
|
2014, 1, 1, 12, 12, 12, tzinfo=dateutil.tz.tzutc()
|
|
|
|
)
|
|
|
|
}
|
|
|
|
)
|
2015-11-24 12:34:53 +01:00
|
|
|
self.assertEqual(request['body']['Timestamp'], '2014-01-01T12:12:12Z')
|
|
|
|
|
|
|
|
def test_accepts_naive_datetime_object(self):
|
|
|
|
request = self.serialize_to_request(
|
2022-05-26 00:10:07 +02:00
|
|
|
{'Timestamp': datetime.datetime(2014, 1, 1, 12, 12, 12)}
|
|
|
|
)
|
2015-11-24 12:34:53 +01:00
|
|
|
self.assertEqual(request['body']['Timestamp'], '2014-01-01T12:12:12Z')
|
|
|
|
|
|
|
|
def test_accepts_iso_8601_format(self):
|
2016-10-11 02:22:54 +02:00
|
|
|
request = self.serialize_to_request(
|
2022-05-26 00:10:07 +02:00
|
|
|
{'Timestamp': '2014-01-01T12:12:12Z'}
|
|
|
|
)
|
2015-11-24 12:34:53 +01:00
|
|
|
self.assertEqual(request['body']['Timestamp'], '2014-01-01T12:12:12Z')
|
|
|
|
|
|
|
|
def test_accepts_timestamp_without_tz_info(self):
|
|
|
|
# If a timezone/utc is not specified, assume they meant
|
|
|
|
# UTC. This is also the previous behavior from older versions
|
|
|
|
# of botocore so we want to make sure we preserve this behavior.
|
2016-10-11 02:22:54 +02:00
|
|
|
request = self.serialize_to_request(
|
2022-05-26 00:10:07 +02:00
|
|
|
{'Timestamp': '2014-01-01T12:12:12'}
|
|
|
|
)
|
2015-11-24 12:34:53 +01:00
|
|
|
self.assertEqual(request['body']['Timestamp'], '2014-01-01T12:12:12Z')
|
|
|
|
|
|
|
|
def test_microsecond_timestamp_without_tz_info(self):
|
|
|
|
request = self.serialize_to_request(
|
2022-05-26 00:10:07 +02:00
|
|
|
{'Timestamp': '2014-01-01T12:12:12.123456'}
|
|
|
|
)
|
|
|
|
self.assertEqual(
|
|
|
|
request['body']['Timestamp'], '2014-01-01T12:12:12.123456Z'
|
|
|
|
)
|
2015-11-24 12:34:53 +01:00
|
|
|
|
|
|
|
|
|
|
|
class TestJSONTimestampSerialization(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
|
|
self.model = {
|
2022-05-26 00:10:07 +02:00
|
|
|
'metadata': {
|
|
|
|
'protocol': 'json',
|
|
|
|
'apiVersion': '2014-01-01',
|
|
|
|
'jsonVersion': '1.1',
|
|
|
|
'targetPrefix': 'foo',
|
|
|
|
},
|
2015-11-24 12:34:53 +01:00
|
|
|
'documentation': '',
|
|
|
|
'operations': {
|
|
|
|
'TestOperation': {
|
|
|
|
'name': 'TestOperation',
|
|
|
|
'http': {
|
|
|
|
'method': 'POST',
|
|
|
|
'requestUri': '/',
|
|
|
|
},
|
|
|
|
'input': {'shape': 'InputShape'},
|
|
|
|
}
|
|
|
|
},
|
|
|
|
'shapes': {
|
|
|
|
'InputShape': {
|
|
|
|
'type': 'structure',
|
|
|
|
'members': {
|
|
|
|
'Timestamp': {'shape': 'TimestampType'},
|
2022-05-26 00:10:07 +02:00
|
|
|
},
|
2015-11-24 12:34:53 +01:00
|
|
|
},
|
|
|
|
'TimestampType': {
|
|
|
|
'type': 'timestamp',
|
2022-05-26 00:10:07 +02:00
|
|
|
},
|
|
|
|
},
|
2015-11-24 12:34:53 +01:00
|
|
|
}
|
|
|
|
self.service_model = ServiceModel(self.model)
|
|
|
|
|
|
|
|
def serialize_to_request(self, input_params):
|
|
|
|
request_serializer = serialize.create_serializer(
|
2022-05-26 00:10:07 +02:00
|
|
|
self.service_model.metadata['protocol']
|
|
|
|
)
|
2015-11-24 12:34:53 +01:00
|
|
|
return request_serializer.serialize_to_request(
|
2022-05-26 00:10:07 +02:00
|
|
|
input_params, self.service_model.operation_model('TestOperation')
|
|
|
|
)
|
2015-11-24 12:34:53 +01:00
|
|
|
|
|
|
|
def test_accepts_iso_8601_format(self):
|
2022-05-26 00:10:07 +02:00
|
|
|
body = json.loads(
|
|
|
|
self.serialize_to_request({'Timestamp': '1970-01-01T00:00:00'})[
|
|
|
|
'body'
|
|
|
|
].decode('utf-8')
|
|
|
|
)
|
2015-11-24 12:34:53 +01:00
|
|
|
self.assertEqual(body['Timestamp'], 0)
|
|
|
|
|
|
|
|
def test_accepts_epoch(self):
|
2022-05-26 00:10:07 +02:00
|
|
|
body = json.loads(
|
|
|
|
self.serialize_to_request({'Timestamp': '0'})['body'].decode(
|
|
|
|
'utf-8'
|
|
|
|
)
|
|
|
|
)
|
2015-11-24 12:34:53 +01:00
|
|
|
self.assertEqual(body['Timestamp'], 0)
|
|
|
|
# Can also be an integer 0.
|
2022-05-26 00:10:07 +02:00
|
|
|
body = json.loads(
|
|
|
|
self.serialize_to_request({'Timestamp': 0})['body'].decode('utf-8')
|
|
|
|
)
|
2015-11-24 12:34:53 +01:00
|
|
|
self.assertEqual(body['Timestamp'], 0)
|
|
|
|
|
|
|
|
def test_accepts_partial_iso_format(self):
|
2022-05-26 00:10:07 +02:00
|
|
|
body = json.loads(
|
|
|
|
self.serialize_to_request({'Timestamp': '1970-01-01'})[
|
|
|
|
'body'
|
|
|
|
].decode('utf-8')
|
|
|
|
)
|
2015-11-24 12:34:53 +01:00
|
|
|
self.assertEqual(body['Timestamp'], 0)
|
2016-10-11 02:22:54 +02:00
|
|
|
|
|
|
|
|
|
|
|
class TestInstanceCreation(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
|
|
self.model = {
|
|
|
|
'metadata': {'protocol': 'query', 'apiVersion': '2014-01-01'},
|
|
|
|
'documentation': '',
|
|
|
|
'operations': {
|
|
|
|
'TestOperation': {
|
|
|
|
'name': 'TestOperation',
|
|
|
|
'http': {
|
|
|
|
'method': 'POST',
|
|
|
|
'requestUri': '/',
|
|
|
|
},
|
|
|
|
'input': {'shape': 'InputShape'},
|
|
|
|
}
|
|
|
|
},
|
|
|
|
'shapes': {
|
|
|
|
'InputShape': {
|
|
|
|
'type': 'structure',
|
|
|
|
'members': {
|
|
|
|
'Timestamp': {'shape': 'StringTestType'},
|
2022-05-26 00:10:07 +02:00
|
|
|
},
|
2016-10-11 02:22:54 +02:00
|
|
|
},
|
2022-05-26 00:10:07 +02:00
|
|
|
'StringTestType': {'type': 'string', 'min': 15},
|
|
|
|
},
|
2016-10-11 02:22:54 +02:00
|
|
|
}
|
|
|
|
self.service_model = ServiceModel(self.model)
|
|
|
|
|
|
|
|
def assert_serialize_valid_parameter(self, request_serializer):
|
|
|
|
valid_string = 'valid_string_with_min_15_chars'
|
|
|
|
request = request_serializer.serialize_to_request(
|
|
|
|
{'Timestamp': valid_string},
|
2022-05-26 00:10:07 +02:00
|
|
|
self.service_model.operation_model('TestOperation'),
|
|
|
|
)
|
2016-10-11 02:22:54 +02:00
|
|
|
|
|
|
|
self.assertEqual(request['body']['Timestamp'], valid_string)
|
|
|
|
|
|
|
|
def assert_serialize_invalid_parameter(self, request_serializer):
|
|
|
|
invalid_string = 'short string'
|
|
|
|
request = request_serializer.serialize_to_request(
|
|
|
|
{'Timestamp': invalid_string},
|
2022-05-26 00:10:07 +02:00
|
|
|
self.service_model.operation_model('TestOperation'),
|
|
|
|
)
|
2016-10-11 02:22:54 +02:00
|
|
|
|
|
|
|
self.assertEqual(request['body']['Timestamp'], invalid_string)
|
|
|
|
|
|
|
|
def test_instantiate_without_validation(self):
|
|
|
|
request_serializer = serialize.create_serializer(
|
2022-05-26 00:10:07 +02:00
|
|
|
self.service_model.metadata['protocol'], False
|
|
|
|
)
|
2016-10-11 02:22:54 +02:00
|
|
|
|
|
|
|
try:
|
|
|
|
self.assert_serialize_valid_parameter(request_serializer)
|
|
|
|
except ParamValidationError as e:
|
|
|
|
self.fail(
|
2021-11-03 18:14:15 +01:00
|
|
|
"Shouldn't fail serializing valid parameter without "
|
|
|
|
"validation: {}".format(e)
|
|
|
|
)
|
2016-10-11 02:22:54 +02:00
|
|
|
|
|
|
|
try:
|
|
|
|
self.assert_serialize_invalid_parameter(request_serializer)
|
|
|
|
except ParamValidationError as e:
|
|
|
|
self.fail(
|
2021-11-03 18:14:15 +01:00
|
|
|
"Shouldn't fail serializing invalid parameter without "
|
|
|
|
"validation: {}".format(e)
|
|
|
|
)
|
2016-10-11 02:22:54 +02:00
|
|
|
|
|
|
|
def test_instantiate_with_validation(self):
|
|
|
|
request_serializer = serialize.create_serializer(
|
2022-05-26 00:10:07 +02:00
|
|
|
self.service_model.metadata['protocol'], True
|
|
|
|
)
|
2016-10-11 02:22:54 +02:00
|
|
|
try:
|
|
|
|
self.assert_serialize_valid_parameter(request_serializer)
|
|
|
|
except ParamValidationError as e:
|
|
|
|
self.fail(
|
2021-11-03 18:14:15 +01:00
|
|
|
"Shouldn't fail serializing invalid parameter without "
|
|
|
|
"validation: {}".format(e)
|
|
|
|
)
|
2016-10-11 02:22:54 +02:00
|
|
|
|
|
|
|
with self.assertRaises(ParamValidationError):
|
|
|
|
self.assert_serialize_invalid_parameter(request_serializer)
|
|
|
|
|
|
|
|
|
|
|
|
class TestHeaderSerialization(BaseModelWithBlob):
|
|
|
|
def setUp(self):
|
|
|
|
self.model = {
|
|
|
|
'metadata': {'protocol': 'rest-xml', 'apiVersion': '2014-01-01'},
|
|
|
|
'documentation': '',
|
|
|
|
'operations': {
|
|
|
|
'TestOperation': {
|
|
|
|
'name': 'TestOperation',
|
|
|
|
'http': {
|
|
|
|
'method': 'POST',
|
|
|
|
'requestUri': '/',
|
|
|
|
},
|
|
|
|
'input': {'shape': 'InputShape'},
|
|
|
|
}
|
|
|
|
},
|
|
|
|
'shapes': {
|
|
|
|
'InputShape': {
|
|
|
|
'type': 'structure',
|
|
|
|
'members': {
|
|
|
|
'ContentLength': {
|
|
|
|
'shape': 'Integer',
|
|
|
|
'location': 'header',
|
2022-05-26 00:10:07 +02:00
|
|
|
'locationName': 'Content-Length',
|
2016-10-11 02:22:54 +02:00
|
|
|
},
|
2022-05-26 00:10:07 +02:00
|
|
|
},
|
2016-10-11 02:22:54 +02:00
|
|
|
},
|
2022-05-26 00:10:07 +02:00
|
|
|
'Integer': {'type': 'integer'},
|
|
|
|
},
|
2016-10-11 02:22:54 +02:00
|
|
|
}
|
|
|
|
self.service_model = ServiceModel(self.model)
|
|
|
|
|
|
|
|
def test_always_serialized_as_str(self):
|
|
|
|
request = self.serialize_to_request({'ContentLength': 100})
|
|
|
|
self.assertEqual(request['headers']['Content-Length'], '100')
|
|
|
|
|
|
|
|
|
|
|
|
class TestRestXMLUnicodeSerialization(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
|
|
self.model = {
|
|
|
|
'metadata': {'protocol': 'rest-xml', 'apiVersion': '2014-01-01'},
|
|
|
|
'documentation': '',
|
|
|
|
'operations': {
|
|
|
|
'TestOperation': {
|
|
|
|
'name': 'TestOperation',
|
|
|
|
'http': {
|
|
|
|
'method': 'POST',
|
|
|
|
'requestUri': '/',
|
|
|
|
},
|
|
|
|
'input': {'shape': 'InputShape'},
|
|
|
|
}
|
|
|
|
},
|
|
|
|
'shapes': {
|
|
|
|
'InputShape': {
|
|
|
|
'type': 'structure',
|
|
|
|
'members': {
|
2022-05-26 00:10:07 +02:00
|
|
|
'Foo': {'shape': 'FooShape', 'locationName': 'Foo'},
|
2016-10-11 02:22:54 +02:00
|
|
|
},
|
2022-05-26 00:10:07 +02:00
|
|
|
'payload': 'Foo',
|
2016-10-11 02:22:54 +02:00
|
|
|
},
|
|
|
|
'FooShape': {
|
|
|
|
'type': 'list',
|
2022-05-26 00:10:07 +02:00
|
|
|
'member': {'shape': 'StringShape'},
|
2016-10-11 02:22:54 +02:00
|
|
|
},
|
|
|
|
'StringShape': {
|
|
|
|
'type': 'string',
|
2022-05-26 00:10:07 +02:00
|
|
|
},
|
|
|
|
},
|
2016-10-11 02:22:54 +02:00
|
|
|
}
|
|
|
|
self.service_model = ServiceModel(self.model)
|
|
|
|
|
|
|
|
def serialize_to_request(self, input_params):
|
|
|
|
request_serializer = serialize.create_serializer(
|
2022-05-26 00:10:07 +02:00
|
|
|
self.service_model.metadata['protocol']
|
|
|
|
)
|
2016-10-11 02:22:54 +02:00
|
|
|
return request_serializer.serialize_to_request(
|
2022-05-26 00:10:07 +02:00
|
|
|
input_params, self.service_model.operation_model('TestOperation')
|
|
|
|
)
|
2016-10-11 02:22:54 +02:00
|
|
|
|
|
|
|
def test_restxml_serializes_unicode(self):
|
2022-05-26 00:10:07 +02:00
|
|
|
params = {'Foo': ['\u65e5\u672c\u8a9e\u3067\u304a\uff4b']}
|
2016-10-11 02:22:54 +02:00
|
|
|
try:
|
|
|
|
self.serialize_to_request(params)
|
|
|
|
except UnicodeEncodeError:
|
|
|
|
self.fail("RestXML serializer failed to serialize unicode text.")
|