Port WSGI tests to Python 3
* Replace dict.keys()[0] with list(data.keys())[0]. On Python 3, dict.keys() now returns a view which is not indexable. * Skip SSL tests on Python 3. Tests hang for an unknown reason, they must be fixed later. * Fix unit tests: HTTP body type is bytes, not Unicode. * Debug.print_generator(): on Python 3, write into sys.stdout.buffer instead of sys.stdout, because HTTP body type is bytes not Unicode. * ResponseObject: encode serializer output to UTF-8 if it's Unicode. * tox.ini: add the following tests to Python 3.4 - cinder.tests.unit.api.openstack.test_wsgi - cinder.tests.unit.wsgi Note: Ignore pylint error E1101 on sys.stdout.buffer. pylint on Python 2 complains that the buffer attribute doesn't exist, whereas the code is only executed on Python 3 and the attribute exists on Python 3. Related-Bug: #1505103 Partial-Implements: blueprint cinder-python3 Change-Id: I0db0e04010e41be71192a2e4db13829114ad6eef
This commit is contained in:
parent
7fb767f2d6
commit
d7dddd19da
@ -425,7 +425,7 @@ class XMLDictSerializer(DictSerializer):
|
||||
|
||||
def default(self, data):
|
||||
# We expect data to contain a single key which is the XML root.
|
||||
root_key = data.keys()[0]
|
||||
root_key = list(data.keys())[0]
|
||||
doc = minidom.Document()
|
||||
node = self._to_xml_node(doc, self.metadata, root_key, data[root_key])
|
||||
|
||||
@ -678,7 +678,10 @@ class ResponseObject(object):
|
||||
response.headers[hdr] = value
|
||||
response.headers['Content-Type'] = content_type
|
||||
if self.obj is not None:
|
||||
response.body = serializer.serialize(self.obj)
|
||||
body = serializer.serialize(self.obj)
|
||||
if isinstance(body, six.text_type):
|
||||
body = body.encode('utf-8')
|
||||
response.body = body
|
||||
|
||||
return response
|
||||
|
||||
@ -710,7 +713,7 @@ def action_peek_json(body):
|
||||
raise exception.MalformedRequestBody(reason=msg)
|
||||
|
||||
# Return the action and the decoded body...
|
||||
return decoded.keys()[0]
|
||||
return list(decoded.keys())[0]
|
||||
|
||||
|
||||
def action_peek_xml(body):
|
||||
|
@ -23,13 +23,13 @@ from cinder.tests.unit.api import fakes
|
||||
class RequestTest(test.TestCase):
|
||||
def test_content_type_missing(self):
|
||||
request = wsgi.Request.blank('/tests/123', method='POST')
|
||||
request.body = "<body />"
|
||||
request.body = b"<body />"
|
||||
self.assertIsNone(request.get_content_type())
|
||||
|
||||
def test_content_type_unsupported(self):
|
||||
request = wsgi.Request.blank('/tests/123', method='POST')
|
||||
request.headers["Content-Type"] = "text/html"
|
||||
request.body = "asdf<br />"
|
||||
request.body = b"asdf<br />"
|
||||
self.assertRaises(exception.InvalidContentType,
|
||||
request.get_content_type)
|
||||
|
||||
@ -206,10 +206,10 @@ class DictSerializerTest(test.TestCase):
|
||||
class XMLDictSerializerTest(test.TestCase):
|
||||
def test_xml(self):
|
||||
input_dict = dict(servers=dict(a=(2, 3)))
|
||||
expected_xml = '<serversxmlns="asdf"><a>(2,3)</a></servers>'
|
||||
expected_xml = b'<serversxmlns="asdf"><a>(2,3)</a></servers>'
|
||||
serializer = wsgi.XMLDictSerializer(xmlns="asdf")
|
||||
result = serializer.serialize(input_dict)
|
||||
result = result.replace('\n', '').replace(' ', '')
|
||||
result = result.replace(b'\n', b'').replace(b' ', b'')
|
||||
self.assertEqual(expected_xml, result)
|
||||
|
||||
|
||||
@ -317,7 +317,7 @@ class ResourceTest(test.TestCase):
|
||||
req = webob.Request.blank('/tests')
|
||||
app = fakes.TestRouter(Controller())
|
||||
response = req.get_response(app)
|
||||
self.assertEqual('off', response.body)
|
||||
self.assertEqual(b'off', response.body)
|
||||
self.assertEqual(200, response.status_int)
|
||||
|
||||
def test_resource_not_authorized(self):
|
||||
@ -443,7 +443,7 @@ class ResourceTest(test.TestCase):
|
||||
|
||||
request = wsgi.Request.blank('/', method='POST')
|
||||
request.headers['Content-Type'] = 'application/none'
|
||||
request.body = 'foo'
|
||||
request.body = b'foo'
|
||||
|
||||
content_type, body = resource.get_body(request)
|
||||
self.assertIsNone(content_type)
|
||||
@ -458,7 +458,7 @@ class ResourceTest(test.TestCase):
|
||||
resource = wsgi.Resource(controller)
|
||||
|
||||
request = wsgi.Request.blank('/', method='POST')
|
||||
request.body = 'foo'
|
||||
request.body = b'foo'
|
||||
|
||||
content_type, body = resource.get_body(request)
|
||||
self.assertIsNone(content_type)
|
||||
@ -474,7 +474,7 @@ class ResourceTest(test.TestCase):
|
||||
|
||||
request = wsgi.Request.blank('/', method='POST')
|
||||
request.headers['Content-Type'] = 'application/json'
|
||||
request.body = ''
|
||||
request.body = b''
|
||||
|
||||
content_type, body = resource.get_body(request)
|
||||
self.assertIsNone(content_type)
|
||||
@ -490,11 +490,11 @@ class ResourceTest(test.TestCase):
|
||||
|
||||
request = wsgi.Request.blank('/', method='POST')
|
||||
request.headers['Content-Type'] = 'application/json'
|
||||
request.body = 'foo'
|
||||
request.body = b'foo'
|
||||
|
||||
content_type, body = resource.get_body(request)
|
||||
self.assertEqual('application/json', content_type)
|
||||
self.assertEqual('foo', body)
|
||||
self.assertEqual(b'foo', body)
|
||||
|
||||
def test_deserialize_badtype(self):
|
||||
class Controller(object):
|
||||
@ -952,7 +952,7 @@ class ResponseObjectTest(test.TestCase):
|
||||
self.assertEqual('header1', response.headers['X-header1'])
|
||||
self.assertEqual('header2', response.headers['X-header2'])
|
||||
self.assertEqual(202, response.status_int)
|
||||
self.assertEqual(mtype, response.body)
|
||||
self.assertEqual(mtype, response.body.decode('utf-8'))
|
||||
|
||||
|
||||
class ValidBodyTest(test.TestCase):
|
||||
|
@ -205,6 +205,7 @@ class TestWSGIServer(test.TestCase):
|
||||
self.assertFalse(buf)
|
||||
server.stop()
|
||||
|
||||
@testtools.skipIf(six.PY3, "bug/1505103: test hangs on Python 3")
|
||||
def test_app_using_ssl(self):
|
||||
CONF.set_default("ssl_cert_file",
|
||||
os.path.join(TEST_VAR_DIR, 'certificate.crt'))
|
||||
@ -229,6 +230,7 @@ class TestWSGIServer(test.TestCase):
|
||||
|
||||
@testtools.skipIf(not _ipv6_configured(),
|
||||
"Test requires an IPV6 configured interface")
|
||||
@testtools.skipIf(six.PY3, "bug/1505103: test hangs on Python 3")
|
||||
def test_app_using_ipv6_and_ssl(self):
|
||||
CONF.set_default("ssl_cert_file",
|
||||
os.path.join(TEST_VAR_DIR, 'certificate.crt'))
|
||||
|
@ -39,12 +39,13 @@ class Test(test.TestCase):
|
||||
|
||||
def __call__(self, environ, start_response):
|
||||
start_response("200", [("X-Test", "checking")])
|
||||
return ['Test result']
|
||||
return [b'Test result']
|
||||
|
||||
with mock.patch('sys.stdout', new=six.StringIO()):
|
||||
with mock.patch('sys.stdout', new=six.StringIO()) as mock_stdout:
|
||||
mock_stdout.buffer = six.BytesIO()
|
||||
application = wsgi.Debug(Application())
|
||||
result = webob.Request.blank('/').get_response(application)
|
||||
self.assertEqual("Test result", result.body)
|
||||
self.assertEqual(b"Test result", result.body)
|
||||
|
||||
def test_router(self):
|
||||
|
||||
@ -53,7 +54,7 @@ class Test(test.TestCase):
|
||||
|
||||
def __call__(self, environ, start_response):
|
||||
start_response("200", [])
|
||||
return ['Router result']
|
||||
return [b'Router result']
|
||||
|
||||
class Router(wsgi.Router):
|
||||
"""Test router."""
|
||||
@ -64,6 +65,6 @@ class Test(test.TestCase):
|
||||
super(Router, self).__init__(mapper)
|
||||
|
||||
result = webob.Request.blank('/test').get_response(Router())
|
||||
self.assertEqual("Router result", result.body)
|
||||
self.assertEqual(b"Router result", result.body)
|
||||
result = webob.Request.blank('/bad').get_response(Router())
|
||||
self.assertNotEqual("Router result", result.body)
|
||||
self.assertNotEqual(b"Router result", result.body)
|
||||
|
@ -20,6 +20,7 @@ from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
from paste import deploy
|
||||
import routes.middleware
|
||||
import six
|
||||
import webob.dec
|
||||
import webob.exc
|
||||
|
||||
@ -193,8 +194,13 @@ class Debug(Middleware):
|
||||
"""Iterator that prints the contents of a wrapper string."""
|
||||
print(('*' * 40) + ' BODY') # noqa
|
||||
for part in app_iter:
|
||||
sys.stdout.write(part)
|
||||
sys.stdout.flush()
|
||||
if six.PY3:
|
||||
sys.stdout.flush()
|
||||
sys.stdout.buffer.write(part) # pylint: disable=E1101
|
||||
sys.stdout.buffer.flush() # pylint: disable=E1101
|
||||
else:
|
||||
sys.stdout.write(part)
|
||||
sys.stdout.flush()
|
||||
yield part
|
||||
print() # noqa
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
cinder.tests.unit.api.openstack.test_wsgi
|
||||
cinder.tests.unit.image.test_cache
|
||||
cinder.tests.unit.image.test_glance
|
||||
cinder.tests.unit.keymgr.test_mock_key_mgr
|
||||
@ -106,3 +107,4 @@ cinder.tests.unit.windows.test_vhdutils
|
||||
cinder.tests.unit.windows.test_windows
|
||||
cinder.tests.unit.windows.test_windows_remotefs
|
||||
cinder.tests.unit.windows.test_windows_utils
|
||||
cinder.tests.unit.wsgi
|
||||
|
Loading…
x
Reference in New Issue
Block a user