200 lines
7.0 KiB
Python
200 lines
7.0 KiB
Python
# Copyright 2014 OpenStack Foundation
|
|
# All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
|
|
from unittest import mock
|
|
|
|
import glance_store as store
|
|
from oslo_config import cfg
|
|
from taskflow.patterns import linear_flow
|
|
|
|
import glance.async_
|
|
from glance.async_.flows import api_image_import
|
|
import glance.tests.utils as test_utils
|
|
|
|
CONF = cfg.CONF
|
|
|
|
|
|
class TestTaskExecutor(test_utils.BaseTestCase):
|
|
|
|
def setUp(self):
|
|
super(TestTaskExecutor, self).setUp()
|
|
self.context = mock.Mock()
|
|
self.task_repo = mock.Mock()
|
|
self.image_repo = mock.Mock()
|
|
self.image_factory = mock.Mock()
|
|
self.executor = glance.async_.TaskExecutor(self.context,
|
|
self.task_repo,
|
|
self.image_repo,
|
|
self.image_factory)
|
|
|
|
def test_begin_processing(self):
|
|
# setup
|
|
task_id = mock.ANY
|
|
task_type = mock.ANY
|
|
task = mock.Mock()
|
|
|
|
with mock.patch.object(
|
|
glance.async_.TaskExecutor,
|
|
'_run') as mock_run:
|
|
self.task_repo.get.return_value = task
|
|
self.executor.begin_processing(task_id)
|
|
|
|
# assert the call
|
|
mock_run.assert_called_once_with(task_id, task_type)
|
|
|
|
|
|
class TestImportTaskFlow(test_utils.BaseTestCase):
|
|
|
|
def setUp(self):
|
|
super(TestImportTaskFlow, self).setUp()
|
|
store.register_opts(CONF)
|
|
self.config(default_store='file',
|
|
stores=['file', 'http'],
|
|
filesystem_store_datadir=self.test_dir,
|
|
group="glance_store")
|
|
self.config(enabled_import_methods=[
|
|
'glance-direct', 'web-download', 'copy-image'])
|
|
self.config(node_staging_uri='file:///tmp/staging')
|
|
store.create_stores(CONF)
|
|
self.base_flow = ['ConfigureStaging', 'ImportToStore',
|
|
'DeleteFromFS', 'VerifyImageState',
|
|
'CompleteTask']
|
|
self.import_plugins = ['Convert_Image',
|
|
'Decompress_Image',
|
|
'InjectMetadataProperties']
|
|
|
|
def _get_flow(self, import_req=None):
|
|
inputs = {
|
|
'task_id': mock.MagicMock(),
|
|
'task_type': mock.MagicMock(),
|
|
'task_repo': mock.MagicMock(),
|
|
'image_repo': mock.MagicMock(),
|
|
'image_id': mock.MagicMock(),
|
|
'import_req': import_req or mock.MagicMock()
|
|
}
|
|
flow = api_image_import.get_flow(**inputs)
|
|
return flow
|
|
|
|
def _get_flow_tasks(self, flow):
|
|
flow_comp = []
|
|
for c, p in flow.iter_nodes():
|
|
if isinstance(c, linear_flow.Flow):
|
|
flow_comp += self._get_flow_tasks(c)
|
|
else:
|
|
name = str(c).split('-')
|
|
if len(name) > 1:
|
|
flow_comp.append(name[1])
|
|
return flow_comp
|
|
|
|
def test_get_default_flow(self):
|
|
# This test will ensure that without import plugins
|
|
# and without internal plugins flow builds with the
|
|
# base_flow components
|
|
flow = self._get_flow()
|
|
|
|
flow_comp = self._get_flow_tasks(flow)
|
|
# assert flow has 5 tasks
|
|
self.assertEqual(5, len(flow_comp))
|
|
for c in self.base_flow:
|
|
self.assertIn(c, flow_comp)
|
|
|
|
def test_get_flow_web_download_enabled(self):
|
|
# This test will ensure that without import plugins
|
|
# and with web-download plugin flow builds with
|
|
# base_flow components and '_WebDownload'
|
|
import_req = {
|
|
'method': {
|
|
'name': 'web-download',
|
|
'uri': 'http://cloud.foo/image.qcow2'
|
|
}
|
|
}
|
|
|
|
flow = self._get_flow(import_req=import_req)
|
|
|
|
flow_comp = self._get_flow_tasks(flow)
|
|
# assert flow has 6 tasks
|
|
self.assertEqual(6, len(flow_comp))
|
|
for c in self.base_flow:
|
|
self.assertIn(c, flow_comp)
|
|
self.assertIn('WebDownload', flow_comp)
|
|
|
|
@mock.patch.object(store, 'get_store_from_store_identifier')
|
|
def test_get_flow_copy_image_enabled(self, mock_store):
|
|
# This test will ensure that without import plugins
|
|
# and with copy-image plugin flow builds with
|
|
# base_flow components and '_CopyImage'
|
|
import_req = {
|
|
'method': {
|
|
'name': 'copy-image',
|
|
'stores': ['fake-store']
|
|
}
|
|
}
|
|
|
|
mock_store.return_value = mock.Mock()
|
|
flow = self._get_flow(import_req=import_req)
|
|
|
|
flow_comp = self._get_flow_tasks(flow)
|
|
# assert flow has 6 tasks
|
|
self.assertEqual(6, len(flow_comp))
|
|
for c in self.base_flow:
|
|
self.assertIn(c, flow_comp)
|
|
self.assertIn('CopyImage', flow_comp)
|
|
|
|
def test_get_flow_with_all_plugins_enabled(self):
|
|
# This test will ensure that flow includes import plugins
|
|
# and base flow
|
|
self.config(image_import_plugins=['image_conversion',
|
|
'image_decompression',
|
|
'inject_image_metadata'],
|
|
group='image_import_opts')
|
|
|
|
flow = self._get_flow()
|
|
|
|
flow_comp = self._get_flow_tasks(flow)
|
|
# assert flow has 8 tasks (base_flow + plugins)
|
|
self.assertEqual(8, len(flow_comp))
|
|
for c in self.base_flow:
|
|
self.assertIn(c, flow_comp)
|
|
for c in self.import_plugins:
|
|
self.assertIn(c, flow_comp)
|
|
|
|
@mock.patch.object(store, 'get_store_from_store_identifier')
|
|
def test_get_flow_copy_image_not_includes_import_plugins(
|
|
self, mock_store):
|
|
# This test will ensure that flow does not includes import
|
|
# plugins as import method is copy image
|
|
self.config(image_import_plugins=['image_conversion',
|
|
'image_decompression',
|
|
'inject_image_metadata'],
|
|
group='image_import_opts')
|
|
|
|
mock_store.return_value = mock.Mock()
|
|
import_req = {
|
|
'method': {
|
|
'name': 'copy-image',
|
|
'stores': ['fake-store']
|
|
}
|
|
}
|
|
|
|
flow = self._get_flow(import_req=import_req)
|
|
|
|
flow_comp = self._get_flow_tasks(flow)
|
|
# assert flow has 6 tasks
|
|
self.assertEqual(6, len(flow_comp))
|
|
for c in self.base_flow:
|
|
self.assertIn(c, flow_comp)
|
|
self.assertIn('CopyImage', flow_comp)
|