From 0f152eb66153e16d4d8aba0f8afebaab046aea35 Mon Sep 17 00:00:00 2001 From: dineshbhor Date: Tue, 21 Jun 2016 20:11:13 +0530 Subject: [PATCH] [PY3] byte/string conversions and enable PY3 test * The dict.items()[0] will raise a TypeError in PY3, as dict.items() doesn't return a list any more in PY3 but a view of list. * Webob response body should be bytes not strings so used oslo_utils.encodeutils.safe_decode to decode it. Partially implements blueprint: goal-python35 Co-Authored-By: ChangBo Guo(gcb) Change-Id: I38d416923bc0cec0ca98c4494dd1e06cd49671cf --- nova/api/openstack/compute/volumes.py | 2 +- nova/api/openstack/wsgi.py | 4 +++- nova/tests/unit/api/openstack/compute/test_api.py | 4 +++- nova/tests/unit/api/openstack/compute/test_volumes.py | 7 +++++-- nova/tests/unit/api/openstack/test_wsgi.py | 6 +++--- nova/tests/unit/matchers.py | 6 ++++++ tests-py3.txt | 1 - 7 files changed, 21 insertions(+), 9 deletions(-) diff --git a/nova/api/openstack/compute/volumes.py b/nova/api/openstack/compute/volumes.py index db8855bbcfb4..05cdccdc43ec 100644 --- a/nova/api/openstack/compute/volumes.py +++ b/nova/api/openstack/compute/volumes.py @@ -70,7 +70,7 @@ def _translate_volume_summary_view(context, vol): # 'mountpoint': '/dev/sda/ # } # } - attachment = vol['attachments'].items()[0] + attachment = list(vol['attachments'].items())[0] d['attachments'] = [_translate_attachment_detail_view(vol['id'], attachment[0], attachment[1].get('mountpoint'))] diff --git a/nova/api/openstack/wsgi.py b/nova/api/openstack/wsgi.py index 8c476824eba5..4925501fa39b 100644 --- a/nova/api/openstack/wsgi.py +++ b/nova/api/openstack/wsgi.py @@ -19,6 +19,7 @@ import functools import microversion_parse from oslo_log import log as logging from oslo_serialization import jsonutils +from oslo_utils import encodeutils from oslo_utils import strutils import six import webob @@ -692,7 +693,8 @@ class Resource(wsgi.Application): if hasattr(response, 'headers'): for hdr, val in list(response.headers.items()): # Headers must be utf-8 strings - response.headers[hdr] = utils.utf8(val) + response.headers[hdr] = encodeutils.safe_decode( + utils.utf8(val)) if not request.api_version_request.is_null(): response.headers[API_VERSION_REQUEST_HEADER] = \ diff --git a/nova/tests/unit/api/openstack/compute/test_api.py b/nova/tests/unit/api/openstack/compute/test_api.py index 35ef48837de1..683edc947252 100644 --- a/nova/tests/unit/api/openstack/compute/test_api.py +++ b/nova/tests/unit/api/openstack/compute/test_api.py @@ -14,6 +14,7 @@ # under the License. from oslo_serialization import jsonutils +from oslo_utils import encodeutils import six import webob.dec import webob.exc @@ -69,7 +70,8 @@ class APITest(test.NoDBTestCase): # Consider changing `api.openstack.wsgi.Resource._process_stack` # to encode header values in ASCII rather than UTF-8. # https://tools.ietf.org/html/rfc7230#section-3.2.4 - self.assertEqual(res.headers.get('Content-Type').decode(), ctype) + content_type = res.headers.get('Content-Type') + self.assertEqual(ctype, encodeutils.safe_decode(content_type)) jsonutils.loads(res.body) diff --git a/nova/tests/unit/api/openstack/compute/test_volumes.py b/nova/tests/unit/api/openstack/compute/test_volumes.py index a2e1f3d8f370..4231017587c2 100644 --- a/nova/tests/unit/api/openstack/compute/test_volumes.py +++ b/nova/tests/unit/api/openstack/compute/test_volumes.py @@ -18,6 +18,7 @@ import datetime import mock from oslo_serialization import jsonutils +from oslo_utils import encodeutils from six.moves import urllib import webob from webob import exc @@ -319,7 +320,8 @@ class VolumeApiTestV21(test.NoDBTestCase): req = fakes.HTTPRequest.blank(self.url_prefix + '/os-volumes/456') resp = req.get_response(self.app) self.assertEqual(404, resp.status_int) - self.assertIn('Volume 456 could not be found.', resp.body) + self.assertIn('Volume 456 could not be found.', + encodeutils.safe_decode(resp.body)) def test_volume_delete(self): req = fakes.HTTPRequest.blank(self.url_prefix + '/os-volumes/123') @@ -334,7 +336,8 @@ class VolumeApiTestV21(test.NoDBTestCase): req.method = 'DELETE' resp = req.get_response(self.app) self.assertEqual(404, resp.status_int) - self.assertIn('Volume 456 could not be found.', resp.body) + self.assertIn('Volume 456 could not be found.', + encodeutils.safe_decode(resp.body)) class VolumeAttachTestsV21(test.NoDBTestCase): diff --git a/nova/tests/unit/api/openstack/test_wsgi.py b/nova/tests/unit/api/openstack/test_wsgi.py index 56f54a3c0152..e02fe9a6bf04 100644 --- a/nova/tests/unit/api/openstack/test_wsgi.py +++ b/nova/tests/unit/api/openstack/test_wsgi.py @@ -867,9 +867,9 @@ class ResourceTest(MicroversionedTest): for val in six.itervalues(response.headers): # All headers must be utf8 self.assertThat(val, matchers.EncodedByUTF8()) - self.assertEqual(b'1', response.headers['x-header1']) - self.assertEqual(b'header2', response.headers['x-header2']) - self.assertEqual(b'header3', response.headers['x-header3']) + self.assertEqual('1', response.headers['x-header1']) + self.assertEqual('header2', response.headers['x-header2']) + self.assertEqual('header3', response.headers['x-header3']) def test_resource_valid_utf8_body(self): class Controller(object): diff --git a/nova/tests/unit/matchers.py b/nova/tests/unit/matchers.py index e3729fd3c2fc..c2df5e414996 100644 --- a/nova/tests/unit/matchers.py +++ b/nova/tests/unit/matchers.py @@ -547,6 +547,12 @@ class EncodedByUTF8(object): except UnicodeDecodeError: return testtools.matchers.Mismatch( "%s is not encoded in UTF-8." % obj) + elif isinstance(obj, six.text_type): + try: + obj.encode("utf-8", "strict") + except UnicodeDecodeError: + return testtools.matchers.Mismatch( + "%s cannot be encoded in UTF-8." % obj) else: reason = ("Type of '%(obj)s' is '%(obj_type)s', " "should be '%(correct_type)s'." diff --git a/tests-py3.txt b/tests-py3.txt index 540247a46483..57f322c99ee4 100644 --- a/tests-py3.txt +++ b/tests-py3.txt @@ -29,7 +29,6 @@ nova.tests.unit.api.openstack.compute.test_user_data.ServersControllerCreateTest nova.tests.unit.api.openstack.compute.test_versions.VersionsTestV21 nova.tests.unit.api.openstack.compute.test_versions.VersionsTestV21WithV2CompatibleWrapper nova.tests.unit.api.openstack.compute.test_volumes.BootFromVolumeTest -nova.tests.unit.api.openstack.compute.test_volumes.VolumeApiTestV21 nova.tests.unit.api.test_compute_req_id.RequestIdTest nova.tests.unit.compute.test_compute.ComputeAPITestCase.test_create_with_base64_user_data nova.tests.unit.compute.test_compute_cells.CellsComputeAPITestCase.test_create_with_base64_user_data