From 228daeb878d65e9df2213ead656910ae033f9042 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 15 Feb 2016 16:51:20 +0100 Subject: [PATCH] Port netapp dataontap driver to Python 3 With this change, all unit tests on volume drivers pass on Python 3. Changes: * Replace a/b with a//b to get an integer on Python 3. * Replace map(...) and filter(...) with a list-comprehension to get a list on Python 3. * Replace dict.keys() with list(dict.keys()) to get a list on Python 3. * Replace (str, int, float, long) with six.integer_types + (str, float): long type was removed from Python 3. * decode_base32_to_hex(): on Python 3, decode encode_hex_to_base32() to return a Unicode string. * convert_es_fmt_to_uuid(): encode/decode on Python 3 to pass the right types to base64.b32decode() (bytes) and uuid.UUID() (Unicode). * fakes.py: Change type of XML document from Unicode to bytes: add b prefix to literal strings (b'...'). * Replace range(a, b) with list(range(a, b)) to get a list on Python 3. * tests-py3.txt: add cinder.tests.unit.volume.drivers, all volume drivers tests now pass on Python 3. Partial-Implements: blueprint cinder-python3 Change-Id: Iee609f72bbbef3789fa5e970d209047a113d005c --- .../drivers/netapp/dataontap/client/fakes.py | 6 +++--- .../drivers/netapp/dataontap/client/test_api.py | 2 +- .../dataontap/performance/test_perf_7mode.py | 9 +++++---- .../dataontap/performance/test_perf_cmode.py | 8 ++++---- .../drivers/netapp/dataontap/test_nfs_7mode.py | 4 ++-- .../drivers/netapp/dataontap/test_nfs_cmode.py | 4 ++-- .../drivers/netapp/eseries/test_host_mapper.py | 2 +- .../drivers/netapp/dataontap/client/api.py | 4 ++-- cinder/volume/drivers/netapp/eseries/client.py | 11 ++++------- cinder/volume/drivers/netapp/eseries/utils.py | 16 ++++++++++++---- tests-py3.txt | 5 +---- 11 files changed, 37 insertions(+), 34 deletions(-) diff --git a/cinder/tests/unit/volume/drivers/netapp/dataontap/client/fakes.py b/cinder/tests/unit/volume/drivers/netapp/dataontap/client/fakes.py index b21858fd7..cec69d9f7 100644 --- a/cinder/tests/unit/volume/drivers/netapp/dataontap/client/fakes.py +++ b/cinder/tests/unit/volume/drivers/netapp/dataontap/client/fakes.py @@ -20,7 +20,7 @@ from six.moves import urllib import cinder.volume.drivers.netapp.dataontap.client.api as netapp_api -FAKE_VOL_XML = """ +FAKE_VOL_XML = b""" open123 online 0 @@ -30,12 +30,12 @@ FAKE_VOL_XML = """ false """ -FAKE_XML1 = """\ +FAKE_XML1 = b"""\ abc\ abc\ """ -FAKE_XML2 = """somecontent""" +FAKE_XML2 = b"""somecontent""" FAKE_NA_ELEMENT = netapp_api.NaElement(etree.XML(FAKE_VOL_XML)) diff --git a/cinder/tests/unit/volume/drivers/netapp/dataontap/client/test_api.py b/cinder/tests/unit/volume/drivers/netapp/dataontap/client/test_api.py index f577c9cea..44ebe3ca1 100644 --- a/cinder/tests/unit/volume/drivers/netapp/dataontap/client/test_api.py +++ b/cinder/tests/unit/volume/drivers/netapp/dataontap/client/test_api.py @@ -468,7 +468,7 @@ class NetAppApiInvokeTests(test.TestCase): api_name = zapi_fakes.FAKE_API_NAME invoke_generator = netapp_api.invoke_api(na_server, api_name) - self.assertRaises(exception.InvalidInput, invoke_generator.next) + self.assertRaises(exception.InvalidInput, next, invoke_generator) @ddt.data({'params': {'na_server': zapi_fakes.FAKE_NA_SERVER, 'api_name': zapi_fakes.FAKE_API_NAME}}, diff --git a/cinder/tests/unit/volume/drivers/netapp/dataontap/performance/test_perf_7mode.py b/cinder/tests/unit/volume/drivers/netapp/dataontap/performance/test_perf_7mode.py index 71a04d958..4e363f546 100644 --- a/cinder/tests/unit/volume/drivers/netapp/dataontap/performance/test_perf_7mode.py +++ b/cinder/tests/unit/volume/drivers/netapp/dataontap/performance/test_perf_7mode.py @@ -87,7 +87,7 @@ class Performance7modeLibraryTestCase(test.TestCase): def test_update_performance_cache(self): - self.perf_library.performance_counters = range(11, 21) + self.perf_library.performance_counters = list(range(11, 21)) mock_get_node_utilization_counters = self.mock_object( self.perf_library, '_get_node_utilization_counters', @@ -98,7 +98,8 @@ class Performance7modeLibraryTestCase(test.TestCase): self.perf_library.update_performance_cache() - self.assertEqual(range(12, 22), self.perf_library.performance_counters) + self.assertEqual(list(range(12, 22)), + self.perf_library.performance_counters) self.assertEqual(25, self.perf_library.utilization) mock_get_node_utilization_counters.assert_called_once_with() mock_get_node_utilization.assert_called_once_with(12, 21, fake.NODE) @@ -120,7 +121,7 @@ class Performance7modeLibraryTestCase(test.TestCase): def test_update_performance_cache_counters_unavailable(self): - self.perf_library.performance_counters = range(11, 21) + self.perf_library.performance_counters = list(range(11, 21)) self.perf_library.utilization = 55.0 mock_get_node_utilization_counters = self.mock_object( @@ -132,7 +133,7 @@ class Performance7modeLibraryTestCase(test.TestCase): self.perf_library.update_performance_cache() - self.assertEqual(range(11, 21), + self.assertEqual(list(range(11, 21)), self.perf_library.performance_counters) self.assertEqual(55.0, self.perf_library.utilization) mock_get_node_utilization_counters.assert_called_once_with() diff --git a/cinder/tests/unit/volume/drivers/netapp/dataontap/performance/test_perf_cmode.py b/cinder/tests/unit/volume/drivers/netapp/dataontap/performance/test_perf_cmode.py index 12446764f..78e5db932 100644 --- a/cinder/tests/unit/volume/drivers/netapp/dataontap/performance/test_perf_cmode.py +++ b/cinder/tests/unit/volume/drivers/netapp/dataontap/performance/test_perf_cmode.py @@ -142,8 +142,8 @@ class PerformanceCmodeLibraryTestCase(test.TestCase): def test_update_performance_cache(self): self.perf_library.performance_counters = { - 'node1': range(11, 21), - 'node2': range(21, 31), + 'node1': list(range(11, 21)), + 'node2': list(range(21, 31)), } mock_get_aggregates_for_pools = self.mock_object( self.perf_library, '_get_aggregates_for_pools', @@ -162,8 +162,8 @@ class PerformanceCmodeLibraryTestCase(test.TestCase): self.perf_library.update_performance_cache(self.fake_volumes) expected_performance_counters = { - 'node1': range(12, 22), - 'node2': range(22, 32), + 'node1': list(range(12, 22)), + 'node2': list(range(22, 32)), } self.assertEqual(expected_performance_counters, self.perf_library.performance_counters) diff --git a/cinder/tests/unit/volume/drivers/netapp/dataontap/test_nfs_7mode.py b/cinder/tests/unit/volume/drivers/netapp/dataontap/test_nfs_7mode.py index c463d5b8d..c2e92d9cc 100644 --- a/cinder/tests/unit/volume/drivers/netapp/dataontap/test_nfs_7mode.py +++ b/cinder/tests/unit/volume/drivers/netapp/dataontap/test_nfs_7mode.py @@ -64,9 +64,9 @@ class NetApp7modeNfsDriverTestCase(test.TestCase): thick = not nfs_sparsed_volumes total_capacity_gb = na_utils.round_down( - fake.TOTAL_BYTES / units.Gi, '0.01') + fake.TOTAL_BYTES // units.Gi, '0.01') free_capacity_gb = na_utils.round_down( - fake.AVAILABLE_BYTES / units.Gi, '0.01') + fake.AVAILABLE_BYTES // units.Gi, '0.01') provisioned_capacity_gb = total_capacity_gb - free_capacity_gb capacity = { 'reserved_percentage': fake.RESERVED_PERCENTAGE, diff --git a/cinder/tests/unit/volume/drivers/netapp/dataontap/test_nfs_cmode.py b/cinder/tests/unit/volume/drivers/netapp/dataontap/test_nfs_cmode.py index 4f3d43b79..0aac910a9 100644 --- a/cinder/tests/unit/volume/drivers/netapp/dataontap/test_nfs_cmode.py +++ b/cinder/tests/unit/volume/drivers/netapp/dataontap/test_nfs_cmode.py @@ -122,9 +122,9 @@ class NetAppCmodeNfsDriverTestCase(test.TestCase): thick = not thin and not nfs_sparsed_volumes total_capacity_gb = na_utils.round_down( - fake.TOTAL_BYTES / units.Gi, '0.01') + fake.TOTAL_BYTES // units.Gi, '0.01') free_capacity_gb = na_utils.round_down( - fake.AVAILABLE_BYTES / units.Gi, '0.01') + fake.AVAILABLE_BYTES // units.Gi, '0.01') provisioned_capacity_gb = total_capacity_gb - free_capacity_gb capacity = { 'reserved_percentage': fake.RESERVED_PERCENTAGE, diff --git a/cinder/tests/unit/volume/drivers/netapp/eseries/test_host_mapper.py b/cinder/tests/unit/volume/drivers/netapp/eseries/test_host_mapper.py index 3e7f07d1a..314923dc1 100644 --- a/cinder/tests/unit/volume/drivers/netapp/eseries/test_host_mapper.py +++ b/cinder/tests/unit/volume/drivers/netapp/eseries/test_host_mapper.py @@ -41,7 +41,7 @@ def get_fake_volume(): FAKE_MAPPINGS = [{u'lun': 1}] -FAKE_USED_UP_MAPPINGS = map(lambda n: {u'lun': n}, range(256)) +FAKE_USED_UP_MAPPINGS = [{u'lun': n} for n in range(256)] FAKE_USED_UP_LUN_ID_DICT = {n: 1 for n in range(256)} diff --git a/cinder/volume/drivers/netapp/dataontap/client/api.py b/cinder/volume/drivers/netapp/dataontap/client/api.py index e8847bda4..4d729f99e 100644 --- a/cinder/volume/drivers/netapp/dataontap/client/api.py +++ b/cinder/volume/drivers/netapp/dataontap/client/api.py @@ -390,7 +390,7 @@ class NaElement(object): def get_attr_names(self): """Returns the list of attribute names.""" attributes = self._element.attrib or {} - return attributes.keys() + return list(attributes.keys()) def add_new_child(self, name, content, convert=False): """Add child with tag name and context. @@ -466,7 +466,7 @@ class NaElement(object): child = NaElement(key) child.add_child_elem(value) self.add_child_elem(child) - elif isinstance(value, (str, int, float, long)): + elif isinstance(value, six.integer_types + (str, float)): self.add_new_child(key, six.text_type(value)) elif isinstance(value, (list, tuple, dict)): child = NaElement(key) diff --git a/cinder/volume/drivers/netapp/eseries/client.py b/cinder/volume/drivers/netapp/eseries/client.py index e9c8f0b09..49dcc5e66 100644 --- a/cinder/volume/drivers/netapp/eseries/client.py +++ b/cinder/volume/drivers/netapp/eseries/client.py @@ -488,21 +488,18 @@ class RestClient(WebserviceClient): def get_volume_mappings_for_volume(self, volume): """Gets all host mappings for given volume from array.""" mappings = self.get_volume_mappings() or [] - host_maps = filter(lambda x: x.get('volumeRef') == volume['volumeRef'], - mappings) - return host_maps + return [x for x in mappings + if x.get('volumeRef') == volume['volumeRef']] def get_volume_mappings_for_host(self, host_ref): """Gets all volume mappings for given host from array.""" mappings = self.get_volume_mappings() or [] - host_maps = filter(lambda x: x.get('mapRef') == host_ref, mappings) - return host_maps + return [x for x in mappings if x.get('mapRef') == host_ref] def get_volume_mappings_for_host_group(self, hg_ref): """Gets all volume mappings for given host group from array.""" mappings = self.get_volume_mappings() or [] - hg_maps = filter(lambda x: x.get('mapRef') == hg_ref, mappings) - return hg_maps + return [x for x in mappings if x.get('mapRef') == hg_ref] def create_volume_mapping(self, object_id, target_id, lun): """Creates volume mapping on array.""" diff --git a/cinder/volume/drivers/netapp/eseries/utils.py b/cinder/volume/drivers/netapp/eseries/utils.py index c99fb0f88..0c699c2cf 100644 --- a/cinder/volume/drivers/netapp/eseries/utils.py +++ b/cinder/volume/drivers/netapp/eseries/utils.py @@ -47,12 +47,20 @@ def decode_base32_to_hex(base32_string): def convert_uuid_to_es_fmt(uuid_str): """Converts uuid to e-series compatible name format.""" uuid_base32 = encode_hex_to_base32(uuid.UUID(six.text_type(uuid_str)).hex) - return str(uuid_base32.strip(b'=')) + es_label = uuid_base32.strip(b'=') + if six.PY3: + es_label = es_label.decode('ascii') + return es_label def convert_es_fmt_to_uuid(es_label): """Converts e-series name format to uuid.""" - if es_label.startswith('tmp-'): + if isinstance(es_label, six.text_type): + es_label = es_label.encode('utf-8') + if es_label.startswith(b'tmp-'): es_label = es_label[4:] - es_label_b32 = es_label.ljust(32, '=') - return uuid.UUID(binascii.hexlify(base64.b32decode(es_label_b32))) + es_label = es_label.ljust(32, b'=') + es_label = binascii.hexlify(base64.b32decode(es_label)) + if six.PY3: + es_label = es_label.decode('ascii') + return uuid.UUID(es_label) diff --git a/tests-py3.txt b/tests-py3.txt index d2372030c..6f93ebbd4 100644 --- a/tests-py3.txt +++ b/tests-py3.txt @@ -145,10 +145,7 @@ cinder.tests.unit.test_volume_utils cinder.tests.unit.test_vzstorage cinder.tests.unit.test_xio cinder.tests.unit.test_zfssa -cinder.tests.unit.volume.drivers.emc.scaleio -cinder.tests.unit.volume.drivers.netapp.eseries.test_library -cinder.tests.unit.volume.drivers.test_fujitsu -cinder.tests.unit.volume.drivers.test_hgst +cinder.tests.unit.volume.drivers cinder.tests.unit.volume.flows.test_create_volume_flow cinder.tests.unit.windows.test_smbfs cinder.tests.unit.windows.test_vhdutils -- 2.45.2