From: Cedric Brandily Date: Wed, 22 Jul 2015 22:28:35 +0000 (+0200) Subject: Python 3: encode unicode response bodies X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=07d3d6966394e2a354fa5bd7ba52959cf76cc81e;p=openstack-build%2Fneutron-build.git Python 3: encode unicode response bodies WebOb disallows in py3K to set webob.Response.body to a unicode object, we should encode unicode bodies in such case. Change-Id: Ie0dc57fbe3ed9b19dac2e958de14387bc4c1a260 Blueprint: neutron-python3 --- diff --git a/neutron/agent/metadata/namespace_proxy.py b/neutron/agent/metadata/namespace_proxy.py index d68cb2493..5cdde8c67 100644 --- a/neutron/agent/metadata/namespace_proxy.py +++ b/neutron/agent/metadata/namespace_proxy.py @@ -92,7 +92,7 @@ class NetworkMetadataProxyHandler(object): response = webob.Response() response.status = resp.status response.headers['Content-Type'] = resp['content-type'] - response.body = content + response.body = wsgi.encode_body(content) return response elif resp.status == 400: return webob.exc.HTTPBadRequest() diff --git a/neutron/tests/unit/api/test_extensions.py b/neutron/tests/unit/api/test_extensions.py index 19b9858da..53c107ebb 100644 --- a/neutron/tests/unit/api/test_extensions.py +++ b/neutron/tests/unit/api/test_extensions.py @@ -418,7 +418,7 @@ class RequestExtensionTest(base.BaseTestCase): def extend_response_data(req, res): data = jsonutils.loads(res.body) data['FOXNSOX:extended_key'] = req.GET.get('extended_key') - res.body = jsonutils.dumps(data) + res.body = jsonutils.dumps(data).encode('utf-8') return res app = self._setup_app_with_request_handler(extend_response_data, 'GET') @@ -444,7 +444,7 @@ class RequestExtensionTest(base.BaseTestCase): def _update_handler(req, res): data = jsonutils.loads(res.body) data['uneditable'] = req.params['uneditable'] - res.body = jsonutils.dumps(data) + res.body = jsonutils.dumps(data).encode('utf-8') return res base_app = webtest.TestApp(setup_base_app(self)) diff --git a/neutron/tests/unit/extensions/foxinsocks.py b/neutron/tests/unit/extensions/foxinsocks.py index 39d2bd829..88908a490 100644 --- a/neutron/tests/unit/extensions/foxinsocks.py +++ b/neutron/tests/unit/extensions/foxinsocks.py @@ -77,7 +77,7 @@ class Foxinsocks(object): # You can use content type header to test for XML. data = jsonutils.loads(res.body) data['FOXNSOX:googoose'] = req.GET.get('chewing') - res.body = jsonutils.dumps(data) + res.body = jsonutils.dumps(data).encode('utf-8') return res req_ext1 = extensions.RequestExtension('GET', '/dummy_resources/:(id)', @@ -89,7 +89,7 @@ class Foxinsocks(object): # You can use content type header to test for XML. data = jsonutils.loads(res.body) data['FOXNSOX:big_bands'] = 'Pig Bands!' - res.body = jsonutils.dumps(data) + res.body = jsonutils.dumps(data).encode('utf-8') return res req_ext2 = extensions.RequestExtension('GET', '/dummy_resources/:(id)', diff --git a/neutron/tests/unit/test_wsgi.py b/neutron/tests/unit/test_wsgi.py index b64e03937..ebb231afa 100644 --- a/neutron/tests/unit/test_wsgi.py +++ b/neutron/tests/unit/test_wsgi.py @@ -217,7 +217,7 @@ class SerializerTest(base.BaseTestCase): serializer = wsgi.Serializer() result = serializer.serialize(input_data, content_type) - self.assertEqual('{"servers": ["test=pass"]}', result) + self.assertEqual(b'{"servers": ["test=pass"]}', result) def test_deserialize_raise_bad_request(self): """Test serialize verifies that exception is raises.""" @@ -308,7 +308,7 @@ class ResponseSerializerTest(testtools.TestCase): class JSONSerializer(object): def serialize(self, data, action='default'): - return 'pew_json' + return b'pew_json' class HeadersSerializer(object): def serialize(self, response, data, action): @@ -342,7 +342,7 @@ class ResponseSerializerTest(testtools.TestCase): response = self.serializer.serialize({}, 'application/json') self.assertEqual('application/json', response.headers['Content-Type']) - self.assertEqual('pew_json', response.body) + self.assertEqual(b'pew_json', response.body) self.assertEqual(404, response.status_int) def test_serialize_response_None(self): @@ -350,7 +350,7 @@ class ResponseSerializerTest(testtools.TestCase): None, 'application/json') self.assertEqual('application/json', response.headers['Content-Type']) - self.assertEqual('', response.body) + self.assertEqual(b'', response.body) self.assertEqual(404, response.status_int) @@ -488,28 +488,28 @@ class JSONDictSerializerTest(base.BaseTestCase): def test_json(self): input_dict = dict(servers=dict(a=(2, 3))) - expected_json = '{"servers":{"a":[2,3]}}' + expected_json = b'{"servers":{"a":[2,3]}}' serializer = wsgi.JSONDictSerializer() result = serializer.serialize(input_dict) - result = result.replace('\n', '').replace(' ', '') + result = result.replace(b'\n', b'').replace(b' ', b'') self.assertEqual(expected_json, result) def test_json_with_utf8(self): input_dict = dict(servers=dict(a=(2, '\xe7\xbd\x91\xe7\xbb\x9c'))) - expected_json = '{"servers":{"a":[2,"\\u7f51\\u7edc"]}}' + expected_json = b'{"servers":{"a":[2,"\\u7f51\\u7edc"]}}' serializer = wsgi.JSONDictSerializer() result = serializer.serialize(input_dict) - result = result.replace('\n', '').replace(' ', '') + result = result.replace(b'\n', b'').replace(b' ', b'') self.assertEqual(expected_json, result) def test_json_with_unicode(self): input_dict = dict(servers=dict(a=(2, u'\u7f51\u7edc'))) - expected_json = '{"servers":{"a":[2,"\\u7f51\\u7edc"]}}' + expected_json = b'{"servers":{"a":[2,"\\u7f51\\u7edc"]}}' serializer = wsgi.JSONDictSerializer() result = serializer.serialize(input_dict) - result = result.replace('\n', '').replace(' ', '') + result = result.replace(b'\n', b'').replace(b' ', b'') self.assertEqual(expected_json, result) diff --git a/neutron/wsgi.py b/neutron/wsgi.py index dd71a9b90..674b2b8b4 100644 --- a/neutron/wsgi.py +++ b/neutron/wsgi.py @@ -93,6 +93,16 @@ CONF.register_opts(socket_opts) LOG = logging.getLogger(__name__) +def encode_body(body): + """Encode unicode body. + + WebOb requires to encode unicode body used to update response body. + """ + if isinstance(body, six.text_type): + return body.encode('utf-8') + return body + + class WorkerService(common_service.ServiceBase): """Wraps a worker to be handled by ProcessLauncher""" def __init__(self, service, application): @@ -427,7 +437,7 @@ class JSONDictSerializer(DictSerializer): def default(self, data): def sanitizer(obj): return six.text_type(obj) - return jsonutils.dumps(data, default=sanitizer) + return encode_body(jsonutils.dumps(data, default=sanitizer)) class ResponseHeaderSerializer(ActionDispatcher): diff --git a/tox.ini b/tox.ini index f5094b0cc..65d3c68df 100644 --- a/tox.ini +++ b/tox.ini @@ -116,6 +116,7 @@ commands = python -m testtools.run \ neutron.tests.unit.plugins.ml2.drivers.openvswitch.agent.openflow.ovs_ofctl.test_br_tun \ neutron.tests.unit.plugins.ml2.drivers.openvswitch.agent.test_agent_scheduler \ neutron.tests.unit.plugins.brocade.test_brocade_db \ + neutron.tests.unit.plugins.brocade.test_brocade_plugin \ neutron.tests.unit.plugins.brocade.test_brocade_vlan \ neutron.tests.unit.plugins.oneconvergence.test_nvsd_agent \ neutron.tests.unit.plugins.oneconvergence.test_plugin_helper \ @@ -153,6 +154,7 @@ commands = python -m testtools.run \ neutron.tests.unit.plugins.cisco.test_network_db \ neutron.tests.unit.scheduler.test_l3_agent_scheduler \ neutron.tests.unit.scheduler.test_dhcp_agent_scheduler \ + neutron.tests.unit.db.test_allowedaddresspairs_db \ neutron.tests.unit.db.test_ipam_backend_mixin \ neutron.tests.unit.db.test_l3_dvr_db \ neutron.tests.unit.db.test_l3_hamode_db \ @@ -187,6 +189,7 @@ commands = python -m testtools.run \ neutron.tests.unit.agent.l3.test_dvr_fip_ns \ neutron.tests.unit.agent.ovsdb.native.test_helpers \ neutron.tests.unit.agent.common.test_config \ + neutron.tests.unit.agent.common.test_ovs_lib \ neutron.tests.unit.agent.common.test_polling \ neutron.tests.unit.agent.common.test_utils \ neutron.tests.unit.agent.linux.test_ip_lib \ @@ -214,8 +217,14 @@ commands = python -m testtools.run \ neutron.tests.unit.test_auth \ neutron.tests.unit.test_policy \ neutron.tests.unit.extensions.v2attributes \ + neutron.tests.unit.extensions.test_address_scope \ + neutron.tests.unit.extensions.test_agent \ + neutron.tests.unit.extensions.test_external_net \ + neutron.tests.unit.extensions.test_flavors \ neutron.tests.unit.extensions.test_l3_ext_gw_mode \ neutron.tests.unit.extensions.test_extra_dhcp_opt \ + neutron.tests.unit.extensions.test_netmtu \ + neutron.tests.unit.extensions.test_vlantransparent \ neutron.tests.unit.extensions.extendedattribute \ neutron.tests.unit.extensions.base \ neutron.tests.unit.extensions.foxinsocks \