Port API to Python 3

* test_make_flat_dict(): only use one dictionary key. On Python 3,
  the hash function is now randomized by default and so dictionary
  keys are returned in a random order.
* Replace "not cmp(a, b) == 0" with "a != b"
* test_common: replace range(n) with list(range(n)) to get a list on
  Python 3. On Python 3, range() now returns an iterator.
* Replace dict.items()[0] with list(dict.items()[0]). On Python 3,
  dict.items() now returns a view which is not indexable.
* VolumeTypesController.index(): replace dict.values() with
  list(dict.values()) to get a list on Python 3.
* test_xmlutil: use byte strings for XML
* test_extensions: use byte strings for HTTP body
* Add the following tests to tests-py3.txt:

  - cinder.tests.unit.api.test_common
  - cinder.tests.unit.api.test_extensions
  - cinder.tests.unit.api.test_versions
  - cinder.tests.unit.api.test_xmlutil

Partial-Implements: blueprint cinder-python3
Change-Id: I40c28f6b6a1cf72ce13774755153c8691b4d621b
This commit is contained in:
Victor Stinner 2015-10-07 18:12:48 +02:00
parent 166e0bb625
commit ad65824806
7 changed files with 25 additions and 22 deletions

View File

@ -42,7 +42,7 @@ class VolumeTypeExtraSpecTemplate(xmlutil.TemplateBuilder):
def extraspec_sel(obj, do_raise=False): def extraspec_sel(obj, do_raise=False):
# Have to extract the key and value for later use... # Have to extract the key and value for later use...
key, value = obj.items()[0] key, value = list(obj.items())[0]
return dict(key=key, value=value) return dict(key=key, value=value)
root = xmlutil.TemplateElement(tagname, selector=extraspec_sel) root = xmlutil.TemplateElement(tagname, selector=extraspec_sel)

View File

@ -56,7 +56,8 @@ class VolumeTypesController(wsgi.Controller):
def index(self, req): def index(self, req):
"""Returns the list of volume types.""" """Returns the list of volume types."""
context = req.environ['cinder.context'] context = req.environ['cinder.context']
vol_types = volume_types.get_all_types(context).values() vol_types = volume_types.get_all_types(context)
vol_types = list(vol_types.values())
req.cache_resource(vol_types, name='types') req.cache_resource(vol_types, name='types')
return self._view_builder.index(req, vol_types) return self._view_builder.index(req, vol_types)

View File

@ -400,7 +400,7 @@ class TemplateElement(object):
tmpInsertPos = parent.find(tagnameList[i]) tmpInsertPos = parent.find(tagnameList[i])
if tmpInsertPos is None: if tmpInsertPos is None:
break break
elif not cmp(parent.attrib, tmpattrib) == 0: elif parent.attrib != tmpattrib:
break break
parent = tmpInsertPos parent = tmpInsertPos
insertIndex = i + 1 insertIndex = i + 1

View File

@ -44,10 +44,10 @@ class LimiterTest(test.TestCase):
def setUp(self): def setUp(self):
"""Run before each test.""" """Run before each test."""
super(LimiterTest, self).setUp() super(LimiterTest, self).setUp()
self.tiny = range(1) self.tiny = list(range(1))
self.small = range(10) self.small = list(range(10))
self.medium = range(1000) self.medium = list(range(1000))
self.large = range(10000) self.large = list(range(10000))
def test_limiter_offset_zero(self): def test_limiter_offset_zero(self):
"""Test offset key works with 0.""" """Test offset key works with 0."""
@ -126,7 +126,7 @@ class LimiterTest(test.TestCase):
def test_limiter_limit_and_offset(self): def test_limiter_limit_and_offset(self):
"""Test request with both limit and offset.""" """Test request with both limit and offset."""
items = range(2000) items = list(range(2000))
req = webob.Request.blank('/?offset=1&limit=3') req = webob.Request.blank('/?offset=1&limit=3')
self.assertEqual(items[1:4], common.limited(items, req)) self.assertEqual(items[1:4], common.limited(items, req))
req = webob.Request.blank('/?offset=3&limit=0') req = webob.Request.blank('/?offset=3&limit=0')
@ -138,7 +138,7 @@ class LimiterTest(test.TestCase):
def test_limiter_custom_max_limit(self): def test_limiter_custom_max_limit(self):
"""Test a max_limit other than 1000.""" """Test a max_limit other than 1000."""
items = range(2000) items = list(range(2000))
req = webob.Request.blank('/?offset=1&limit=3') req = webob.Request.blank('/?offset=1&limit=3')
self.assertEqual( self.assertEqual(
items[1:4], common.limited(items, req, max_limit=2000)) items[1:4], common.limited(items, req, max_limit=2000))

View File

@ -200,12 +200,12 @@ class ExtensionControllerIdFormatTest(test.TestCase):
def test_id_with_xml_format(self): def test_id_with_xml_format(self):
result = self._bounce_id('foo.xml') result = self._bounce_id('foo.xml')
self.assertEqual('foo', result) self.assertEqual(b'foo', result)
def test_id_with_json_format(self): def test_id_with_json_format(self):
result = self._bounce_id('foo.json') result = self._bounce_id('foo.json')
self.assertEqual('foo', result) self.assertEqual(b'foo', result)
def test_id_with_bad_format(self): def test_id_with_bad_format(self):
result = self._bounce_id('foo.bad') result = self._bounce_id('foo.bad')
self.assertEqual('foo.bad', result) self.assertEqual(b'foo.bad', result)

View File

@ -656,14 +656,12 @@ class TemplateTest(test.TestCase):
selector='scope0:scope1:scope2:key3') selector='scope0:scope1:scope2:key3')
key3.text = xmlutil.Selector() key3.text = xmlutil.Selector()
serializer = xmlutil.MasterTemplate(root, 1) serializer = xmlutil.MasterTemplate(root, 1)
xml_list = [] expected_xml = (b"<?xmlversion='1.0'encoding='UTF-8'?><test>"
xml_list.append("<?xmlversion='1.0'encoding='UTF-8'?><test>") b"<scope0><key1>Value1</key1><scope1>"
xml_list.append("<scope0><key1>Value1</key1><scope1>") b"<key2>Value2</key2><scope2><key3>Value3</key3>"
xml_list.append("<key2>Value2</key2><scope2><key3>Value3</key3>") b"</scope2></scope1></scope0></test>")
xml_list.append("</scope2></scope1></scope0></test>")
expected_xml = ''.join(xml_list)
result = serializer.serialize(obj) result = serializer.serialize(obj)
result = result.replace('\n', '').replace(' ', '') result = result.replace(b'\n', b'').replace(b' ', b'')
self.assertEqual(expected_xml, result) self.assertEqual(expected_xml, result)
@ -728,9 +726,9 @@ class TemplateBuilderTest(test.TestCase):
class MiscellaneousXMLUtilTests(test.TestCase): class MiscellaneousXMLUtilTests(test.TestCase):
def test_make_flat_dict(self): def test_make_flat_dict(self):
expected_xml = ("<?xml version='1.0' encoding='UTF-8'?>\n" expected_xml = (b"<?xml version='1.0' encoding='UTF-8'?>\n"
'<wrapper><a>foo</a><b>bar</b></wrapper>') b'<wrapper><a>foo</a></wrapper>')
root = xmlutil.make_flat_dict('wrapper') root = xmlutil.make_flat_dict('wrapper')
tmpl = xmlutil.MasterTemplate(root, 1) tmpl = xmlutil.MasterTemplate(root, 1)
result = tmpl.serialize(dict(wrapper=dict(a='foo', b='bar'))) result = tmpl.serialize(dict(wrapper=dict(a='foo')))
self.assertEqual(expected_xml, result) self.assertEqual(expected_xml, result)

View File

@ -1,4 +1,8 @@
cinder.tests.unit.api.openstack.test_wsgi cinder.tests.unit.api.openstack.test_wsgi
cinder.tests.unit.api.test_common
cinder.tests.unit.api.test_extensions
cinder.tests.unit.api.test_versions
cinder.tests.unit.api.test_xmlutil
cinder.tests.unit.image.test_cache cinder.tests.unit.image.test_cache
cinder.tests.unit.image.test_glance cinder.tests.unit.image.test_glance
cinder.tests.unit.keymgr.test_mock_key_mgr cinder.tests.unit.keymgr.test_mock_key_mgr