Python 3 compatibility

This commit introduces compatibility with python 3.

Closes-Bug: 1449772
Change-Id: I9d65b527fd317046c79310bc79d191de3e2111d5
This commit is contained in:
Ramakrishnan G
2015-05-07 16:52:26 +00:00
parent 653f63bc07
commit 0a4f6d605e
8 changed files with 70 additions and 50 deletions

View File

@@ -32,7 +32,7 @@ RAID_10_ADM = '10ADM'
RAID_LEVEL_INPUT_TO_HPSSA_MAPPING = {RAID_50: '50', RAID_60: '60'}
RAID_LEVEL_HPSSA_TO_INPUT_MAPPING = {
v: k for k, v in RAID_LEVEL_INPUT_TO_HPSSA_MAPPING.iteritems()}
v: k for k, v in RAID_LEVEL_INPUT_TO_HPSSA_MAPPING.items()}
INTERFACE_TYPE_MAP = {'SCSI': INTERFACE_TYPE_SCSI,
'SAS': INTERFACE_TYPE_SAS,

View File

@@ -111,7 +111,7 @@ def _convert_to_dict(stdout):
"""
lines = stdout.split("\n")
lines = filter(None, lines)
lines = list(filter(None, lines))
info_dict, j = _get_dict(lines, 0, 0)
return info_dict
@@ -231,7 +231,7 @@ class Server(object):
raid_info = _convert_to_dict(config)
self.controllers = []
for key, value in raid_info.iteritems():
for key, value in raid_info.items():
self.controllers.append(Controller(key, value, self))
self.last_updated = time.time()
@@ -313,7 +313,7 @@ class Controller(object):
self.raid_arrays = []
unassigned_drives = properties.get('unassigned', dict())
for key, value in unassigned_drives.iteritems():
for key, value in unassigned_drives.items():
self.unassigned_physical_drives.append(PhysicalDrive(key,
value,
self))
@@ -485,8 +485,9 @@ class LogicalDrive(object):
# It requires space to be stripped.
size = self.properties['Size'].replace(' ', '')
try:
self.size_gb = (strutils.string_to_bytes(size, return_int=True) /
(1024*1024*1024))
self.size_gb = int(strutils.string_to_bytes(size,
return_int=True) /
(1024*1024*1024))
except ValueError:
msg = ("hpssacli returned unknown size '%(size)s' for logical "
"disk '%(logical_disk)s' of RAID array '%(array)s' in "
@@ -545,8 +546,9 @@ class PhysicalDrive:
# (like 500MB, 25GB) unit of storage space to bytes (Integer value).
# It requires space to be stripped.
try:
self.size_gb = (strutils.string_to_bytes(size, return_int=True) /
(1024*1024*1024))
self.size_gb = int(strutils.string_to_bytes(size,
return_int=True) /
(1024*1024*1024))
except ValueError:
msg = ("hpssacli returned unknown size '%(size)s' for physical "
"disk '%(physical_disk)s' of controller "

View File

@@ -18,11 +18,12 @@ over RIBCL scripting language
"""
import re
import urllib2
import xml.etree.ElementTree as etree
from oslo_utils import strutils
import six
from six.moves.urllib import error as urllib_error
from six.moves.urllib import request
from proliantutils import exception
from proliantutils.ilo import common
@@ -69,10 +70,11 @@ class RIBCLOperations(operations.IloOperations):
urlstr = 'https://%s/ribcl' % (self.host)
xml = self._serialize_xml(root)
try:
req = urllib2.Request(url=urlstr, data=xml)
req = request.Request(url=urlstr, data=xml.encode('ascii'))
req.add_header("Content-length", len(xml))
data = urllib2.urlopen(req).read()
except (ValueError, urllib2.URLError, urllib2.HTTPError) as e:
data = request.urlopen(req).read()
except (ValueError, urllib_error.URLError,
urllib_error.HTTPError) as e:
raise exception.IloConnectionError(e)
return data
@@ -119,9 +121,19 @@ class RIBCLOperations(operations.IloOperations):
:param root: root of the dynamic xml.
"""
if hasattr(etree, 'tostringlist'):
xml = '\r\n'.join(etree.tostringlist(root)) + '\r\n'
if six.PY3:
xml_content_list = [
x.decode("utf-8") for x in etree.tostringlist(root)]
else:
xml_content_list = etree.tostringlist(root)
xml = '\r\n'.join(xml_content_list) + '\r\n'
else:
xml = etree.tostring(root) + '\r\n'
if six.PY3:
xml_content = etree.tostring(root).decode("utf-8")
else:
xml_content = etree.tostring(root)
xml = xml_content + '\r\n'
return xml
def _parse_output(self, xml_response):
@@ -518,9 +530,10 @@ class RIBCLOperations(operations.IloOperations):
"""Request host info from the server."""
urlstr = 'http://%s/xmldata?item=all' % (self.host)
try:
req = urllib2.Request(url=urlstr)
xml = urllib2.urlopen(req).read()
except (ValueError, urllib2.URLError, urllib2.HTTPError) as e:
req = request.Request(url=urlstr)
xml = request.urlopen(req).read()
except (ValueError, urllib_error.URLError,
urllib_error.HTTPError) as e:
raise IloConnectionError(e)
return xml
@@ -751,7 +764,7 @@ class RIBCLOperations(operations.IloOperations):
memory_bytes = (
strutils.string_to_bytes(
memsize.replace(' ', ''), return_int=True))
memory_mb = memory_bytes / (1024 * 1024)
memory_mb = int(memory_bytes / (1024 * 1024))
total_memory_size = total_memory_size + memory_mb
return total_memory_size
@@ -812,7 +825,7 @@ class RIBCLOperations(operations.IloOperations):
capacity = val['VALUE']
local_bytes = (strutils.string_to_bytes(
capacity.replace(' ', ''), return_int=True))
local_gb = local_bytes / (1024 * 1024 * 1024)
local_gb = int(local_bytes / (1024 * 1024 * 1024))
if minimum >= local_gb or minimum == 0:
minimum = local_gb
return minimum

View File

@@ -17,10 +17,11 @@ __author__ = 'HP'
import base64
import gzip
import hashlib
import httplib
import json
import StringIO
import urlparse
import six
from six.moves import http_client
from six.moves.urllib import parse as urlparse
from proliantutils import exception
from proliantutils.ilo import common
@@ -54,16 +55,20 @@ class RISOperations(operations.IloOperations):
# Use self.login/self.password and Basic Auth
if self.login is not None and self.password is not None:
hr = "BASIC " + base64.b64encode(self.login + ":" + self.password)
auth_data = self.login + ":" + self.password
hr = "BASIC " + base64.b64encode(
auth_data.encode('ascii')).decode("utf-8")
request_headers['Authorization'] = hr
redir_count = 5
while redir_count:
conn = None
if url.scheme == 'https':
conn = httplib.HTTPSConnection(host=url.netloc, strict=True)
conn = http_client.HTTPSConnection(host=url.netloc,
strict=True)
elif url.scheme == 'http':
conn = httplib.HTTPConnection(host=url.netloc, strict=True)
conn = http_client.HTTPConnection(host=url.netloc,
strict=True)
try:
conn.request(operation, url.path, headers=request_headers,
@@ -98,14 +103,14 @@ class RISOperations(operations.IloOperations):
response = dict()
try:
if body:
response = json.loads(body.decode('utf-8'))
except ValueError:
response = json.loads(body)
except (ValueError, TypeError):
# if it doesn't decode as json
# NOTE: resources may return gzipped content
# try to decode as gzip (we should check the headers for
# Content-Encoding=gzip)
try:
gzipper = gzip.GzipFile(fileobj=StringIO.StringIO(body))
gzipper = gzip.GzipFile(fileobj=six.BytesIO(body))
uncompressed_string = gzipper.read().decode('UTF-8')
response = json.loads(uncompressed_string)
except Exception as e:

View File

@@ -50,8 +50,8 @@ class ServerTest(testtools.TestCase):
self.assertEqual(sorted(physical_drives_expected),
sorted(physical_drives_found))
physical_drive = filter(lambda x: x.id == '5I:1:1',
controller.unassigned_physical_drives)[0]
physical_drive = list(filter(lambda x: x.id == '5I:1:1',
controller.unassigned_physical_drives))[0]
self.assertEqual(controller, physical_drive.parent)
self.assertEqual(500, physical_drive.size_gb)
self.assertEqual(constants.INTERFACE_TYPE_SAS,
@@ -86,14 +86,14 @@ class ServerTest(testtools.TestCase):
self.assertIsInstance(logical_drive.properties, dict)
# Assertion on physical drives of array
physical_drive = filter(lambda x: x.id == '5I:1:1',
array.physical_drives)[0]
physical_drive = list(filter(lambda x: x.id == '5I:1:1',
array.physical_drives))[0]
self.assertEqual(array, physical_drive.parent)
self.assertEqual(500, physical_drive.size_gb)
# Assertion on physical drives of controller
physical_drive = filter(lambda x: x.id == '5I:1:3',
controller.unassigned_physical_drives)[0]
physical_drive = list(filter(lambda x: x.id == '5I:1:3',
controller.unassigned_physical_drives))[0]
self.assertEqual(controller, physical_drive.parent)
self.assertEqual(400, physical_drive.size_gb)
@@ -303,13 +303,13 @@ class ControllerTest(testtools.TestCase):
controller = server.controllers[0]
array = controller.raid_arrays[0]
physical_drive = filter(lambda x: x.id == '5I:1:1',
array.physical_drives)[0]
physical_drive = list(filter(lambda x: x.id == '5I:1:1',
array.physical_drives))[0]
self.assertEqual(physical_drive,
controller.get_physical_drive_by_id('5I:1:1'))
physical_drive = filter(lambda x: x.id == '5I:1:3',
controller.unassigned_physical_drives)[0]
physical_drive = list(filter(lambda x: x.id == '5I:1:3',
controller.unassigned_physical_drives))[0]
self.assertEqual(physical_drive,
controller.get_physical_drive_by_id('5I:1:3'))

View File

@@ -19,11 +19,11 @@ import json
import unittest
import mock
import ribcl_sample_outputs as constants
from proliantutils import exception
from proliantutils.ilo import common
from proliantutils.ilo import ribcl
from proliantutils.tests.ilo import ribcl_sample_outputs as constants
class IloRibclTestCase(unittest.TestCase):

View File

@@ -16,10 +16,10 @@
"""Test class for RIS Module."""
import base64
import httplib
import json
import mock
from six.moves import http_client
import testtools
from proliantutils import exception
@@ -326,7 +326,7 @@ class TestRISOperationsPrivateMethods(testtools.TestCase):
result = self.client._validate_uefi_boot_mode()
self.assertFalse(result)
@mock.patch.object(httplib, 'HTTPSConnection')
@mock.patch.object(http_client, 'HTTPSConnection')
def test__rest_op_okay(self, https_con_mock):
connection_mock_obj = mock.MagicMock()
response_mock_obj = mock.MagicMock(status=200)
@@ -354,7 +354,7 @@ class TestRISOperationsPrivateMethods(testtools.TestCase):
headers={'Authorization': 'BASIC YWRtaW46QWRtaW4='},
body="null")
@mock.patch.object(httplib, 'HTTPSConnection')
@mock.patch.object(http_client, 'HTTPSConnection')
def test__rest_op_request_error(self, https_con_mock):
connection_mock_obj = mock.MagicMock()
https_con_mock.return_value = connection_mock_obj
@@ -365,7 +365,7 @@ class TestRISOperationsPrivateMethods(testtools.TestCase):
https_con_mock.assert_called_once_with(host='1.2.3.4', strict=True)
self.assertIn("boom", str(exc))
@mock.patch.object(httplib, 'HTTPSConnection')
@mock.patch.object(http_client, 'HTTPSConnection')
def test__rest_op_get_response_error(self, https_con_mock):
connection_mock_obj = mock.MagicMock()
https_con_mock.return_value = connection_mock_obj
@@ -380,7 +380,7 @@ class TestRISOperationsPrivateMethods(testtools.TestCase):
body="null")
self.assertIn("boom", str(exc))
@mock.patch.object(httplib, 'HTTPSConnection')
@mock.patch.object(http_client, 'HTTPSConnection')
def test__rest_op_response_read_error(self, https_con_mock):
connection_mock_obj = mock.MagicMock()
response_mock_obj = mock.MagicMock(status=200)
@@ -392,7 +392,7 @@ class TestRISOperationsPrivateMethods(testtools.TestCase):
'GET', '/v1/foo', None, None)
self.assertIn("boom", str(exc))
@mock.patch.object(httplib, 'HTTPSConnection')
@mock.patch.object(http_client, 'HTTPSConnection')
def test__rest_op_continous_redirection(self, https_con_mock):
connection_mock_obj = mock.MagicMock()
response_mock_obj = mock.MagicMock(status=301)
@@ -418,8 +418,8 @@ class TestRISOperationsPrivateMethods(testtools.TestCase):
self.assertEqual(5, connection_mock_obj.request.call_count)
self.assertIn('https://1.2.3.4/v1/foo', str(exc))
@mock.patch.object(httplib, 'HTTPConnection')
@mock.patch.object(httplib, 'HTTPSConnection')
@mock.patch.object(http_client, 'HTTPConnection')
@mock.patch.object(http_client, 'HTTPSConnection')
def test__rest_op_one_redirection(self, https_con_mock,
http_con_mock):
connection_mock_obj = mock.MagicMock()
@@ -454,7 +454,7 @@ class TestRISOperationsPrivateMethods(testtools.TestCase):
self.assertTrue(response_mock_obj1.read.called)
self.assertTrue(response_mock_obj2.read.called)
@mock.patch.object(httplib, 'HTTPSConnection')
@mock.patch.object(http_client, 'HTTPSConnection')
def test__rest_op_response_decode_error(self, https_con_mock):
connection_mock_obj = mock.MagicMock()
response_mock_obj = mock.MagicMock(status=200)
@@ -477,7 +477,7 @@ class TestRISOperationsPrivateMethods(testtools.TestCase):
headers={'Authorization': 'BASIC YWRtaW46QWRtaW4='},
body="null")
@mock.patch.object(httplib, 'HTTPSConnection')
@mock.patch.object(http_client, 'HTTPSConnection')
def test__rest_op_response_gzipped_response(self, https_con_mock):
connection_mock_obj = mock.MagicMock()
response_mock_obj = mock.MagicMock(status=200)

View File

@@ -1,5 +1,5 @@
[tox]
envlist = py27,pep8
envlist = py27,pep8,py34
[testenv]
usedevelop = True