Port EMC scaleio to Python 3

* Import urllib modules using six.moves.urllib
* MockHTTPSResponse: encode HTTP body to UTF-8 if it's Unicode,
  replace six.string_types with (bytes, six.text_type).
* _id_to_base64(): catch also binascii.Error when calling
  b16decode(); encode name to UTF-8 before calling b64encode();
  decode b64encode() from ASCII on Python 3 to get Unicode.
* tox.ini: add cinder.tests.unit.volume.drivers.emc.scaleio
  to Python 3.4

Partial-Implements: blueprint cinder-python3
Change-Id: I93353d48f80971528f47c9291cd04e198632dd0b
This commit is contained in:
Victor Stinner 2015-10-07 17:57:00 +02:00
parent a37618f55b
commit c4f8f885d4
10 changed files with 50 additions and 36 deletions

View File

@ -99,18 +99,20 @@ class MockHTTPSResponse(requests.Response):
def __init__(self, content, status_code=200):
super(MockHTTPSResponse, self).__init__()
if isinstance(content, six.text_type):
content = content.encode('utf-8')
self._content = content
self.status_code = status_code
def json(self, **kwargs):
if isinstance(self._content, six.string_types):
if isinstance(self._content, (bytes, six.text_type)):
return super(MockHTTPSResponse, self).json(**kwargs)
return self._content
@property
def text(self):
if not isinstance(self._content, six.string_types):
if not isinstance(self._content, (bytes, six.text_type)):
return json.dumps(self._content)
return super(MockHTTPSResponse, self).text

View File

@ -14,7 +14,8 @@
# under the License.
import json
import urllib
from six.moves import urllib
from cinder import context
from cinder import exception
@ -36,8 +37,8 @@ class TestCreateClonedVolume(scaleio.TestScaleIODriver):
self.src_volume = fake_volume.fake_volume_obj(
ctx, **{'provider_id': 'pid001'})
self.src_volume_name_2x_enc = urllib.quote(
urllib.quote(
self.src_volume_name_2x_enc = urllib.parse.quote(
urllib.parse.quote(
self.driver._id_to_base64(self.src_volume.id)
)
)
@ -51,8 +52,8 @@ class TestCreateClonedVolume(scaleio.TestScaleIODriver):
ctx, **self.new_volume_extras
)
self.new_volume_name_2x_enc = urllib.quote(
urllib.quote(
self.new_volume_name_2x_enc = urllib.parse.quote(
urllib.parse.quote(
self.driver._id_to_base64(self.new_volume.id)
)
)

View File

@ -13,7 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import json
import urllib
from six.moves import urllib
from cinder import context
from cinder import db
@ -46,11 +47,12 @@ class TestCreateSnapShot(scaleio.TestScaleIODriver):
self.mock_object(db, 'volume_get', self.return_fake_volume)
self.volume_name_2x_enc = urllib.quote(
urllib.quote(self.driver._id_to_base64(self.snapshot.volume_id))
snap_vol_id = self.snapshot.volume_id
self.volume_name_2x_enc = urllib.parse.quote(
urllib.parse.quote(self.driver._id_to_base64(snap_vol_id))
)
self.snapshot_name_2x_enc = urllib.quote(
urllib.quote(self.driver._id_to_base64(self.snapshot.id))
self.snapshot_name_2x_enc = urllib.parse.quote(
urllib.parse.quote(self.driver._id_to_base64(self.snapshot.id))
)
self.snapshot_reply = json.dumps(

View File

@ -13,7 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import json
import urllib
from six.moves import urllib
from cinder import context
from cinder import exception
@ -35,12 +36,12 @@ class TestCreateVolumeFromSnapShot(scaleio.TestScaleIODriver):
ctx = context.RequestContext('fake', 'fake', auth_token=True)
self.snapshot = fake_snapshot.fake_snapshot_obj(ctx)
self.snapshot_name_2x_enc = urllib.quote(
urllib.quote(self.driver._id_to_base64(self.snapshot.id))
self.snapshot_name_2x_enc = urllib.parse.quote(
urllib.parse.quote(self.driver._id_to_base64(self.snapshot.id))
)
self.volume = fake_volume.fake_volume_obj(ctx)
self.volume_name_2x_enc = urllib.quote(
urllib.quote(self.driver._id_to_base64(self.volume.id))
self.volume_name_2x_enc = urllib.parse.quote(
urllib.parse.quote(self.driver._id_to_base64(self.volume.id))
)
self.snapshot_reply = json.dumps(

View File

@ -12,7 +12,7 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import urllib
from six.moves import urllib
from cinder import context
from cinder import exception
@ -34,8 +34,8 @@ class TestDeleteSnapShot(scaleio.TestScaleIODriver):
self.snapshot = fake_snapshot_obj(
ctx, **{'provider_id': 'snap_1'})
self.snapshot_name_2x_enc = urllib.quote(
urllib.quote(
self.snapshot_name_2x_enc = urllib.parse.quote(
urllib.parse.quote(
self.driver._id_to_base64(self.snapshot.id)
)
)

View File

@ -12,7 +12,7 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import urllib
from six.moves import urllib
from cinder import context
from cinder import exception
@ -34,8 +34,8 @@ class TestDeleteVolume(scaleio.TestScaleIODriver):
self.volume = fake_volume.fake_volume_obj(
ctx, **{'provider_id': 'pid_1'})
self.volume_name_2x_enc = urllib.quote(
urllib.quote(self.driver._id_to_base64(self.volume.id))
self.volume_name_2x_enc = urllib.parse.quote(
urllib.parse.quote(self.driver._id_to_base64(self.volume.id))
)
self.HTTPS_MOCK_RESPONSES = {

View File

@ -12,7 +12,7 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import urllib
from six.moves import urllib
from cinder import context
from cinder import exception
@ -42,8 +42,8 @@ class TestExtendVolume(scaleio.TestScaleIODriver):
self.volume = fake_volume_obj(ctx, **{'id': 'fake_volume',
'provider_id': 'pid_1'})
self.volume_name_2x_enc = urllib.quote(
urllib.quote(self.driver._id_to_base64(self.volume.id))
self.volume_name_2x_enc = urllib.parse.quote(
urllib.parse.quote(self.driver._id_to_base64(self.volume.id))
)
self.HTTPS_MOCK_RESPONSES = {

View File

@ -12,7 +12,7 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import urllib
from six.moves import urllib
from cinder import exception
from cinder.tests.unit.volume.drivers.emc import scaleio
@ -30,8 +30,8 @@ class TestMisc(scaleio.TestScaleIODriver):
"""
super(TestMisc, self).setUp()
self.domain_name_enc = urllib.quote(self.DOMAIN_NAME)
self.pool_name_enc = urllib.quote(self.POOL_NAME)
self.domain_name_enc = urllib.parse.quote(self.DOMAIN_NAME)
self.pool_name_enc = urllib.parse.quote(self.POOL_NAME)
self.HTTPS_MOCK_RESPONSES = {
self.RESPONSE_MODE.Valid: {

View File

@ -17,6 +17,7 @@ Driver for EMC ScaleIO based on ScaleIO remote CLI.
"""
import base64
import binascii
import json
from os_brick.initiator import connector
@ -25,7 +26,7 @@ from oslo_log import log as logging
from oslo_utils import units
import requests
import six
import urllib
from six.moves import urllib
from cinder import context
from cinder import exception
@ -250,9 +251,14 @@ class ScaleIODriver(driver.VolumeDriver):
name = six.text_type(id).replace("-", "")
try:
name = base64.b16decode(name.upper())
except TypeError:
except (TypeError, binascii.Error):
pass
encoded_name = base64.b64encode(name)
encoded_name = name
if isinstance(encoded_name, six.text_type):
encoded_name = encoded_name.encode('utf-8')
encoded_name = base64.b64encode(encoded_name)
if six.PY3:
encoded_name = encoded_name.decode('ascii')
LOG.debug(
"Converted id %(id)s to scaleio name %(name)s.",
{'id': id, 'name': encoded_name})
@ -307,7 +313,8 @@ class ScaleIODriver(driver.VolumeDriver):
" protection domain id.")
raise exception.VolumeBackendAPIException(data=msg)
encoded_domain_name = urllib.quote(self.protection_domain_name, '')
domain_name = self.protection_domain_name
encoded_domain_name = urllib.parse.quote(domain_name, '')
req_vars = {'server_ip': self.server_ip,
'server_port': self.server_port,
'encoded_domain_name': encoded_domain_name}
@ -341,7 +348,7 @@ class ScaleIODriver(driver.VolumeDriver):
pool_name = self.storage_pool_name
pool_id = self.storage_pool_id
if pool_name:
encoded_domain_name = urllib.quote(pool_name, '')
encoded_domain_name = urllib.parse.quote(pool_name, '')
req_vars = {'server_ip': self.server_ip,
'server_port': self.server_port,
'domain_id': domain_id,
@ -702,7 +709,7 @@ class ScaleIODriver(driver.VolumeDriver):
{'domain': domain_name,
'pool': pool_name})
# Get domain id from name.
encoded_domain_name = urllib.quote(domain_name, '')
encoded_domain_name = urllib.parse.quote(domain_name, '')
req_vars = {'server_ip': self.server_ip,
'server_port': self.server_port,
'encoded_domain_name': encoded_domain_name}
@ -738,7 +745,7 @@ class ScaleIODriver(driver.VolumeDriver):
LOG.info(_LI("Domain id is %s."), domain_id)
# Get pool id from name.
encoded_pool_name = urllib.quote(pool_name, '')
encoded_pool_name = urllib.parse.quote(pool_name, '')
req_vars = {'server_ip': self.server_ip,
'server_port': self.server_port,
'domain_id': domain_id,

View File

@ -91,6 +91,7 @@ cinder.tests.unit.test_volume_transfer
cinder.tests.unit.test_volume_types
cinder.tests.unit.test_volume_types_extra_specs
cinder.tests.unit.test_volume_utils
cinder.tests.unit.volume.drivers.emc.scaleio
cinder.tests.unit.volume.flows.test_create_volume_flow
cinder.tests.unit.windows.test_smbfs
cinder.tests.unit.windows.test_vhdutils