Port async tests to Python 3

* Replace exc.message with six.text_type(exc). The message attribute
  of exceptions was removed in Python 3.
* set_image_data(): replace "isinstance(data_iter, file)" with
  "hasattr(data_iter, 'close')". The file type is gone in Python 3,
  use duck-typing instead to check for the close() method.
* Use bytes instead of Unicode strings for image content. Replace
  cStringIO() with BytesIO().
* Fix data iterator: use a list of strings instead of a string.
* tox.ini: add the following tests to Python 3.4

  - glance.tests.unit.async.flows.test_convert
  - glance.tests.unit.async.flows.test_import
  - glance.tests.unit.async.flows.test_introspect
  - glance.tests.unit.async.test_taskflow_executor

Change-Id: I885e11c0da1a264456fdeb2bff54dcfd3acfd193
This commit is contained in:
Victor Stinner 2015-10-05 16:49:11 +02:00
parent 06a08c6cd6
commit 47e2ce98a0
6 changed files with 22 additions and 15 deletions

View File

@ -19,6 +19,7 @@ import futurist
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import excutils
import six
from stevedore import driver
from taskflow import engines
from taskflow.listeners import logging as llistener
@ -127,7 +128,7 @@ class TaskExecutor(glance.async.TaskExecutor):
except Exception as exc:
with excutils.save_and_reraise_exception():
LOG.error(_LE('Failed to execute task %(task_id)s: %(exc)s') %
{'task_id': task_id, 'exc': exc.message})
{'task_id': task_id, 'exc': six.text_type(exc)})
# TODO(sabari): Check for specific exceptions and update the
# task failure message.
task.fail(_('Task failed due to Internal Error'))

View File

@ -14,6 +14,7 @@
# under the License.
from oslo_log import log as logging
import six
from taskflow import task
from glance import i18n
@ -61,6 +62,6 @@ class OptionalTask(task.Task):
except Exception as exc:
msg = (_LW("An optional task has failed, "
"the failure was: %s") %
exc.message)
six.text_type(exc))
LOG.warn(msg)
return wrapper

View File

@ -163,5 +163,5 @@ def set_image_data(image, uri, task_id):
" %(image_data)s"), {"image_data": uri,
"task_id": task_id})
finally:
if isinstance(data_iter, file):
if hasattr(data_iter, 'close'):
data_iter.close()

View File

@ -147,7 +147,7 @@ class TestImportTask(test_utils.BaseTestCase):
return ("", None)
with mock.patch.object(script_utils, 'get_image_data_iter') as dmock:
dmock.return_value = six.BytesIO("TEST_IMAGE")
dmock.return_value = six.BytesIO(b"TEST_IMAGE")
with mock.patch.object(processutils, 'execute') as exc_mock:
exc_mock.side_effect = fake_execute

View File

@ -20,7 +20,7 @@ import os
import glance_store
from oslo_concurrency import processutils as putils
from oslo_config import cfg
from six.moves import cStringIO
import six
from six.moves import urllib
from taskflow import task
from taskflow.types import failure
@ -108,7 +108,7 @@ class TestImportTask(test_utils.BaseTestCase):
img_factory.new_image.side_effect = create_image
with mock.patch.object(script_utils, 'get_image_data_iter') as dmock:
dmock.return_value = cStringIO("TEST_IMAGE")
dmock.return_value = six.BytesIO(b"TEST_IMAGE")
with mock.patch.object(putils, 'trycmd') as tmock:
tmock.return_value = (json.dumps({
@ -149,7 +149,7 @@ class TestImportTask(test_utils.BaseTestCase):
img_factory.new_image.side_effect = create_image
with mock.patch.object(script_utils, 'get_image_data_iter') as dmock:
dmock.return_value = cStringIO("TEST_IMAGE")
dmock.return_value = six.BytesIO(b"TEST_IMAGE")
with mock.patch.object(import_flow._ImportToFS, 'execute') as emk:
executor.begin_processing(self.task.task_id)
@ -220,7 +220,7 @@ class TestImportTask(test_utils.BaseTestCase):
img_factory.new_image.side_effect = create_image
with mock.patch.object(script_utils, 'get_image_data_iter') as dmock:
dmock.return_value = cStringIO("TEST_IMAGE")
dmock.return_value = six.BytesIO(b"TEST_IMAGE")
with mock.patch.object(putils, 'trycmd') as tmock:
tmock.return_value = (json.dumps({
@ -269,7 +269,7 @@ class TestImportTask(test_utils.BaseTestCase):
img_factory.new_image.side_effect = create_image
with mock.patch.object(script_utils, 'get_image_data_iter') as dmock:
dmock.return_value = cStringIO("TEST_IMAGE")
dmock.return_value = six.BytesIO(b"TEST_IMAGE")
with mock.patch.object(putils, 'trycmd') as tmock:
tmock.return_value = (json.dumps({
@ -319,8 +319,8 @@ class TestImportTask(test_utils.BaseTestCase):
img_factory.new_image.side_effect = create_image
with mock.patch.object(urllib.request, 'urlopen') as umock:
content = "TEST_IMAGE"
umock.return_value = cStringIO(content)
content = b"TEST_IMAGE"
umock.return_value = six.BytesIO(content)
with mock.patch.object(import_flow, "_get_import_flows") as imock:
imock.return_value = (x for x in [])
@ -332,7 +332,7 @@ class TestImportTask(test_utils.BaseTestCase):
self.assertTrue(os.path.exists(image_path))
self.assertEqual(1, umock.call_count)
with open(image_path) as ifile:
with open(image_path, 'rb') as ifile:
self.assertEqual(content, ifile.read())
def test_create_image(self):
@ -376,7 +376,8 @@ class TestImportTask(test_utils.BaseTestCase):
'http://example.com/image.qcow2')
with mock.patch.object(script_utils, 'get_image_data_iter') as dmock:
dmock.return_value = "test"
content = b"test"
dmock.return_value = [content]
with mock.patch.object(putils, 'trycmd') as tmock:
tmock.return_value = (json.dumps({
@ -387,7 +388,7 @@ class TestImportTask(test_utils.BaseTestCase):
path = import_fs.execute(image_id)
reader, size = glance_store.get_from_backend(path)
self.assertEqual(4, size)
self.assertEqual(dmock.return_value, "".join(reader))
self.assertEqual(content, b"".join(reader))
image_path = os.path.join(self.work_dir, image_id)
tmp_image_path = os.path.join(self.work_dir, image_path)
@ -397,7 +398,7 @@ class TestImportTask(test_utils.BaseTestCase):
delete_fs = import_flow._DeleteFromFS(self.task.task_id,
self.task_type)
data = "test"
data = [b"test"]
store = glance_store.get_store_from_scheme('file')
path = glance_store.store_add_to_backend(mock.sentinel.image_id, data,

View File

@ -22,7 +22,11 @@ commands =
glance.tests.unit.api.test_cmd_cache_manage \
glance.tests.unit.api.test_common \
glance.tests.unit.api.test_property_protections \
glance.tests.unit.async.flows.test_convert \
glance.tests.unit.async.flows.test_import \
glance.tests.unit.async.flows.test_introspect \
glance.tests.unit.async.test_async \
glance.tests.unit.async.test_taskflow_executor \
glance.tests.unit.common.test_client \
glance.tests.unit.common.test_config \
glance.tests.unit.common.test_exception \