diff --git a/contrib/rackspace/rackspace/resources/cloud_server.py b/contrib/rackspace/rackspace/resources/cloud_server.py index dd67529b7f..8b90828b2d 100644 --- a/contrib/rackspace/rackspace/resources/cloud_server.py +++ b/contrib/rackspace/rackspace/resources/cloud_server.py @@ -16,6 +16,7 @@ import copy from heat.common import exception from heat.engine import attributes from heat.engine import properties +from heat.engine.resources import glance_utils from heat.engine.resources import nova_utils from heat.engine.resources import server from heat.openstack.common.gettextutils import _ @@ -112,7 +113,7 @@ class CloudServer(server.Server): """Return the server's image ID.""" image = self.properties.get(self.IMAGE) if image and self._image is None: - self._image = nova_utils.get_image_id(self.nova(), image) + self._image = glance_utils.get_image_id(self.glance(), image) return self._image def _config_drive(self): diff --git a/contrib/rackspace/rackspace/tests/test_rackspace_cloud_server.py b/contrib/rackspace/rackspace/tests/test_rackspace_cloud_server.py index de3517ea7e..21527d854b 100644 --- a/contrib/rackspace/rackspace/tests/test_rackspace_cloud_server.py +++ b/contrib/rackspace/rackspace/tests/test_rackspace_cloud_server.py @@ -20,6 +20,7 @@ from heat.engine import clients from heat.engine import environment from heat.engine import parser from heat.engine import resource +from heat.engine.resources import glance_utils from heat.engine import scheduler from heat.openstack.common import uuidutils from heat.tests.common import HeatTestCase @@ -65,6 +66,25 @@ class CloudServersTest(HeatTestCase): resource._register_class("Rackspace::Cloud::Server", cloud_server.CloudServer) + def _mock_get_image_id_success(self, imageId_input, imageId): + g_cli_mock = self.m.CreateMockAnything() + self.m.StubOutWithMock(clients.OpenStackClients, 'glance') + clients.OpenStackClients.glance().MultipleTimes().AndReturn( + g_cli_mock) + self.m.StubOutWithMock(glance_utils, 'get_image_id') + glance_utils.get_image_id(g_cli_mock, imageId_input).MultipleTimes().\ + AndReturn(imageId) + + def _stub_server_validate(self, server, imageId_input, image_id): + # stub nova validate + self.m.StubOutWithMock(server, 'nova') + server.nova().MultipleTimes().AndReturn(self.fc) + self.m.StubOutWithMock(clients.OpenStackClients, 'nova') + clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + + # stub glance image validate + self._mock_get_image_id_success(imageId_input, image_id) + def _setup_test_stack(self, stack_name): t = template_format.parse(wp_template) template = parser.Template(t) @@ -91,13 +111,8 @@ class CloudServersTest(HeatTestCase): server = cloud_server.CloudServer(server_name, t['Resources']['WebServer'], stack) - self.m.StubOutWithMock(cloud_server.CloudServer, "nova") - cloud_server.CloudServer.nova().MultipleTimes().AndReturn(self.fc) - self.m.StubOutWithMock(clients.OpenStackClients, 'nova') - clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) - server.t = server.stack.resolve_runtime_data(server.t) - + self._stub_server_validate(server, image_id or 'CentOS 5.2', 1) if stub_create: self.m.StubOutWithMock(self.fc.servers, 'create') self.fc.servers.create( @@ -325,7 +340,7 @@ class CloudServersTest(HeatTestCase): mock_nova.return_value = self.fc self.fc.servers.create = mock.Mock(return_value=return_server) - + self._mock_get_image_id_success('CentOS 5.2', 'image_id') scheduler.TaskRunner(server.create)() expected_call = mock.call(server.ADMIN_PASS, 'autogenerated', redact=True) @@ -348,7 +363,7 @@ class CloudServersTest(HeatTestCase): mock_nova.return_value = self.fc self.fc.servers.create = mock.Mock(return_value=return_server) - + self._mock_get_image_id_success('CentOS 5.2', 'image_id') scheduler.TaskRunner(server.create)() expected_call = mock.call(mock.ANY, server.ADMIN_PASS, mock.ANY, mock.ANY) @@ -371,7 +386,7 @@ class CloudServersTest(HeatTestCase): mock_nova.return_value = self.fc self.fc.servers.create = mock.Mock(return_value=return_server) - + self._mock_get_image_id_success('CentOS 5.2', 'image_id') scheduler.TaskRunner(server.create)() expected_call = mock.call(mock.ANY, server.ADMIN_PASS, mock.ANY, mock.ANY) @@ -392,7 +407,7 @@ class CloudServersTest(HeatTestCase): mock_nova.return_value = self.fc self.fc.servers.create = mock.Mock(return_value=return_server) - + self._mock_get_image_id_success('CentOS 5.2', 'image_id') scheduler.TaskRunner(server.create)() expected_call = mock.call(mock.ANY, server.ADMIN_PASS, mock.ANY, redact=mock.ANY) @@ -432,10 +447,11 @@ class CloudServersTest(HeatTestCase): mock_nova.return_value = self.fc mock_servers_create = mock.Mock(return_value=return_server) self.fc.servers.create = mock_servers_create - + image_id = mock.ANY + self._mock_get_image_id_success('CentOS 5.2', image_id) scheduler.TaskRunner(server.create)() mock_servers_create.assert_called_with( - image=mock.ANY, + image=image_id, flavor=mock.ANY, key_name=mock.ANY, name=mock.ANY, diff --git a/heat/engine/resources/glance_utils.py b/heat/engine/resources/glance_utils.py new file mode 100644 index 0000000000..509325c768 --- /dev/null +++ b/heat/engine/resources/glance_utils.py @@ -0,0 +1,69 @@ +# +# 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. +"""Utilities for Resources that use the OpenStack Glance API.""" + +from glanceclient import exc as glance_exceptions + +from heat.common import exception +from heat.openstack.common.gettextutils import _ +from heat.openstack.common import log as logging +from heat.openstack.common import uuidutils + +logger = logging.getLogger(__name__) + + +def get_image_id(glance_client, image_identifier): + ''' + Return an id for the specified image name or identifier. + + :param glance_client: the glance client to use + :param image_identifier: image name or a UUID-like identifier + :returns: the id of the requested :image_identifier: + :raises: exception.ImageNotFound, exception.PhysicalResourceNameAmbiguity + ''' + if uuidutils.is_uuid_like(image_identifier): + try: + image_id = glance_client.images.get(image_identifier).id + except glance_exceptions.NotFound: + image_id = get_image_id_by_name(glance_client, image_identifier) + else: + image_id = get_image_id_by_name(glance_client, image_identifier) + return image_id + + +def get_image_id_by_name(glance_client, image_identifier): + ''' + Return an id for the specified image name or identifier. + + :param glance_client: the glance client to use + :param image_identifier: image name or a UUID-like identifier + :returns: the id of the requested :image_identifier: + :raises: exception.ImageNotFound, exception.PhysicalResourceNameAmbiguity + ''' + try: + filters = {'name': image_identifier} + image_list = list(glance_client.images.list(filters=filters)) + except glance_exceptions.ClientException as ex: + raise exception.Error( + message=(_("Error retrieving image list from glance: %s") % ex)) + num_matches = len(image_list) + if num_matches == 0: + logger.info(_("Image %s was not found in glance") % + image_identifier) + raise exception.ImageNotFound(image_name=image_identifier) + elif num_matches > 1: + logger.info(_("Multiple images %s were found in glance with name") + % image_identifier) + raise exception.PhysicalResourceNameAmbiguity(name=image_identifier) + else: + return image_list[0].id diff --git a/heat/engine/resources/image.py b/heat/engine/resources/image.py index 006c02b62c..a804057ab3 100644 --- a/heat/engine/resources/image.py +++ b/heat/engine/resources/image.py @@ -13,7 +13,7 @@ from heat.common import exception from heat.engine import constraints -from heat.engine.resources import nova_utils +from heat.engine.resources import glance_utils class ImageConstraint(constraints.BaseCustomConstraint): @@ -21,8 +21,8 @@ class ImageConstraint(constraints.BaseCustomConstraint): expected_exceptions = (exception.ImageNotFound,) def validate_with_client(self, client, value): - nova_client = client.nova() - nova_utils.get_image_id(nova_client, value) + glance_client = client.glance() + glance_utils.get_image_id(glance_client, value) def constraint_mapping(): diff --git a/heat/engine/resources/instance.py b/heat/engine/resources/instance.py index bb231ef129..bc7b581e7a 100644 --- a/heat/engine/resources/instance.py +++ b/heat/engine/resources/instance.py @@ -22,6 +22,7 @@ from heat.engine import clients from heat.engine import constraints from heat.engine import properties from heat.engine import resource +from heat.engine.resources import glance_utils from heat.engine.resources.network_interface import NetworkInterface from heat.engine.resources.neutron import neutron from heat.engine.resources import nova_utils @@ -442,7 +443,7 @@ class Instance(resource.Resource): image_name = self.properties[self.IMAGE_ID] - image_id = nova_utils.get_image_id(self.nova(), image_name) + image_id = glance_utils.get_image_id(self.glance(), image_name) flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) diff --git a/heat/engine/resources/nova_utils.py b/heat/engine/resources/nova_utils.py index 7ffa906749..ea65aed604 100644 --- a/heat/engine/resources/nova_utils.py +++ b/heat/engine/resources/nova_utils.py @@ -30,7 +30,6 @@ from heat.engine import clients from heat.engine import scheduler from heat.openstack.common.gettextutils import _ from heat.openstack.common import log as logging -from heat.openstack.common import uuidutils logger = logging.getLogger(__name__) @@ -71,55 +70,6 @@ def refresh_server(server): raise -def get_image_id(nova_client, image_identifier): - ''' - Return an id for the specified image name or identifier. - - :param nova_client: the nova client to use - :param image_identifier: image name or a UUID-like identifier - :returns: the id of the requested :image_identifier: - :raises: exception.ImageNotFound, exception.PhysicalResourceNameAmbiguity - ''' - if uuidutils.is_uuid_like(image_identifier): - try: - image_id = nova_client.images.get(image_identifier).id - except clients.novaclient.exceptions.NotFound: - image_id = get_image_id_by_name(nova_client, image_identifier) - else: - image_id = get_image_id_by_name(nova_client, image_identifier) - return image_id - - -def get_image_id_by_name(nova_client, image_identifier): - ''' - Return an id for the specified image name or identifier. - - :param nova_client: the nova client to use - :param image_identifier: image name or a UUID-like identifier - :returns: the id of the requested :image_identifier: - :raises: exception.ImageNotFound, exception.PhysicalResourceNameAmbiguity - ''' - try: - image_list = nova_client.images.list() - except clients.novaclient.exceptions.ClientException as ex: - raise exception.Error( - message=(_("Error retrieving image list from nova: %s") % ex)) - image_names = dict( - (o.id, o.name) - for o in image_list if o.name == image_identifier) - if len(image_names) == 0: - logger.info(_("Image %s was not found in glance") % - image_identifier) - raise exception.ImageNotFound(image_name=image_identifier) - elif len(image_names) > 1: - logger.info(_("Multiple images %s were found in glance with name") - % image_identifier) - raise exception.PhysicalResourceNameAmbiguity( - name=image_identifier) - image_id = image_names.popitem()[0] - return image_id - - def get_ip(server, net_type, ip_version): """Return the server's IP of the given type and version.""" if net_type in server.addresses: diff --git a/heat/engine/resources/server.py b/heat/engine/resources/server.py index 60348d01c0..da04b2adcf 100644 --- a/heat/engine/resources/server.py +++ b/heat/engine/resources/server.py @@ -22,6 +22,7 @@ from heat.engine import clients from heat.engine import constraints from heat.engine import properties from heat.engine import resource +from heat.engine.resources import glance_utils from heat.engine.resources.neutron import subnet from heat.engine.resources import nova_utils from heat.engine.resources.software_config import software_config as sc @@ -480,7 +481,7 @@ class Server(stack_user.StackUser): image = self.properties.get(self.IMAGE) if image: - image = nova_utils.get_image_id(self.nova(), image) + image = glance_utils.get_image_id(self.glance(), image) flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) @@ -739,7 +740,7 @@ class Server(stack_user.StackUser): if image_update_policy == 'REPLACE': raise resource.UpdateReplace(self.name) image = prop_diff[self.IMAGE] - image_id = nova_utils.get_image_id(self.nova(), image) + image_id = glance_utils.get_image_id(self.glance(), image) if not server: server = self.nova().servers.get(self.resource_id) preserve_ephemeral = ( diff --git a/heat/engine/resources/volume.py b/heat/engine/resources/volume.py index 594db6b0c5..2d13482f23 100644 --- a/heat/engine/resources/volume.py +++ b/heat/engine/resources/volume.py @@ -19,7 +19,7 @@ from heat.engine import clients from heat.engine import constraints from heat.engine import properties from heat.engine import resource -from heat.engine.resources import nova_utils +from heat.engine.resources import glance_utils from heat.engine import scheduler from heat.engine import support from heat.openstack.common.importutils import try_import @@ -545,8 +545,8 @@ class CinderVolume(Volume): 'availability_zone': self.properties[self.AVAILABILITY_ZONE] } if self.properties.get(self.IMAGE): - arguments['imageRef'] = nova_utils.get_image_id( - self.nova(), self.properties[self.IMAGE]) + arguments['imageRef'] = glance_utils.get_image_id( + self.glance(), self.properties[self.IMAGE]) elif self.properties.get(self.IMAGE_REF): arguments['imageRef'] = self.properties[self.IMAGE_REF] diff --git a/heat/tests/test_autoscaling_update_policy.py b/heat/tests/test_autoscaling_update_policy.py index 74577c3933..b753debc6a 100644 --- a/heat/tests/test_autoscaling_update_policy.py +++ b/heat/tests/test_autoscaling_update_policy.py @@ -24,6 +24,7 @@ from heat.engine import clients from heat.engine import function from heat.engine.notification import stack as notification from heat.engine import parser +from heat.engine.resources import glance_utils from heat.engine.resources import instance from heat.engine.resources import loadbalancer as lb from heat.engine.resources import wait_condition as wc @@ -211,6 +212,19 @@ class AutoScalingGroupTest(HeatTestCase): cfg.CONF.set_default('heat_waitcondition_server_url', 'http://127.0.0.1:8000/v1/waitcondition') + def _mock_get_image_id_success(self, imageId_input, imageId, + update_image=None): + g_cli_mock = self.m.CreateMockAnything() + self.m.StubOutWithMock(clients.OpenStackClients, 'glance') + clients.OpenStackClients.glance().MultipleTimes().AndReturn( + g_cli_mock) + self.m.StubOutWithMock(glance_utils, 'get_image_id') + glance_utils.get_image_id(g_cli_mock, imageId_input).MultipleTimes().\ + AndReturn(imageId) + if update_image: + glance_utils.get_image_id(g_cli_mock, update_image).\ + MultipleTimes().AndReturn(imageId) + def _stub_validate(self): self.m.StubOutWithMock(parser.Stack, 'validate') parser.Stack.validate().MultipleTimes() @@ -426,11 +440,16 @@ class AutoScalingGroupTest(HeatTestCase): num_creates_expected_on_updt, num_deletes_expected_on_updt, num_reloads_expected_on_updt, - update_replace): + update_replace, + update_image_id=None): # setup stack from the initial template tmpl = template_format.parse(init_template) stack = utils.parse_stack(tmpl) + + self._mock_get_image_id_success('F20-x86_64-cfntools', + 'image_id') + stack.validate() # test stack create @@ -483,7 +502,6 @@ class AutoScalingGroupTest(HeatTestCase): new_updt_pol = new_grp_tmpl['UpdatePolicy']['AutoScalingRollingUpdate'] new_batch_sz = int(new_updt_pol['MaxBatchSize']) self.assertNotEqual(new_batch_sz, init_batch_sz) - self._stub_validate() if update_replace: self._stub_grp_replace(size, size, num_reloads_expected_on_updt) else: @@ -491,6 +509,10 @@ class AutoScalingGroupTest(HeatTestCase): num_deletes_expected_on_updt, num_reloads_expected_on_updt) self.stub_wallclock() + self._mock_get_image_id_success('F20-x86_64-cfntools', 'image_id', + update_image=update_image_id) + + stack.validate() self.m.ReplayAll() stack.update(updated_stack) self.m.VerifyAll() @@ -555,7 +577,8 @@ class AutoScalingGroupTest(HeatTestCase): policy['MinInstancesInService'] = '1' policy['MaxBatchSize'] = '3' config = updt_template['Resources']['LaunchConfig'] - config['Properties']['ImageId'] = 'F17-x86_64-cfntools' + update_image = 'F17-x86_64-cfntools' + config['Properties']['ImageId'] = update_image self.update_autoscaling_group(asg_tmpl_with_updt_policy, json.dumps(updt_template), @@ -563,7 +586,8 @@ class AutoScalingGroupTest(HeatTestCase): num_creates_expected_on_updt=0, num_deletes_expected_on_updt=0, num_reloads_expected_on_updt=9, - update_replace=True) + update_replace=True, + update_image_id=update_image) def test_autoscaling_group_update_replace_with_adjusted_capacity(self): """ @@ -576,7 +600,8 @@ class AutoScalingGroupTest(HeatTestCase): policy['MinInstancesInService'] = '8' policy['MaxBatchSize'] = '4' config = updt_template['Resources']['LaunchConfig'] - config['Properties']['ImageId'] = 'F17-x86_64-cfntools' + update_image = 'F17-x86_64-cfntools' + config['Properties']['ImageId'] = update_image self.update_autoscaling_group(asg_tmpl_with_updt_policy, json.dumps(updt_template), @@ -584,7 +609,8 @@ class AutoScalingGroupTest(HeatTestCase): num_creates_expected_on_updt=2, num_deletes_expected_on_updt=2, num_reloads_expected_on_updt=7, - update_replace=True) + update_replace=True, + update_image_id=update_image) def test_autoscaling_group_update_replace_huge_batch_size(self): """ @@ -596,7 +622,8 @@ class AutoScalingGroupTest(HeatTestCase): policy['MinInstancesInService'] = '0' policy['MaxBatchSize'] = '20' config = updt_template['Resources']['LaunchConfig'] - config['Properties']['ImageId'] = 'F17-x86_64-cfntools' + update_image = 'F17-x86_64-cfntools' + config['Properties']['ImageId'] = update_image self.update_autoscaling_group(asg_tmpl_with_updt_policy, json.dumps(updt_template), @@ -604,7 +631,8 @@ class AutoScalingGroupTest(HeatTestCase): num_creates_expected_on_updt=0, num_deletes_expected_on_updt=0, num_reloads_expected_on_updt=3, - update_replace=True) + update_replace=True, + update_image_id=update_image) def test_autoscaling_group_update_replace_huge_min_in_service(self): """ @@ -617,6 +645,7 @@ class AutoScalingGroupTest(HeatTestCase): policy['MaxBatchSize'] = '1' policy['PauseTime'] = 'PT0S' config = updt_template['Resources']['LaunchConfig'] + update_image = 'F17-x86_64-cfntools' config['Properties']['ImageId'] = 'F17-x86_64-cfntools' self.update_autoscaling_group(asg_tmpl_with_updt_policy, @@ -625,7 +654,8 @@ class AutoScalingGroupTest(HeatTestCase): num_creates_expected_on_updt=1, num_deletes_expected_on_updt=1, num_reloads_expected_on_updt=12, - update_replace=True) + update_replace=True, + update_image_id=update_image) def test_autoscaling_group_update_no_replace(self): """ @@ -683,6 +713,7 @@ class AutoScalingGroupTest(HeatTestCase): # test stack create size = int(stack['WebServerGroup'].properties['MinSize']) self._stub_grp_create(size) + self._mock_get_image_id_success('F20-x86_64-cfntools', 'image_id') self.m.ReplayAll() stack.create() self.m.VerifyAll() @@ -735,6 +766,7 @@ class AutoScalingGroupTest(HeatTestCase): # test stack create size = int(stack['WebServerGroup'].properties['MinSize']) self._stub_grp_create(size) + self._mock_get_image_id_success('F20-x86_64-cfntools', 'image_id') self.m.ReplayAll() stack.create() self.m.VerifyAll() diff --git a/heat/tests/test_engine_service.py b/heat/tests/test_engine_service.py index 95e37320c4..d9e9c91457 100644 --- a/heat/tests/test_engine_service.py +++ b/heat/tests/test_engine_service.py @@ -34,6 +34,7 @@ from heat.engine import environment from heat.engine import parser from heat.engine.properties import Properties from heat.engine import resource as res +from heat.engine.resources import glance_utils from heat.engine.resources import instance as instances from heat.engine.resources import nova_utils from heat.engine import service @@ -192,15 +193,30 @@ def setup_keystone_mocks(mocks, stack): stack.clients.keystone().MultipleTimes().AndReturn(fkc) -def setup_mocks(mocks, stack): +def setup_mock_for_image_constraint(mocks, imageId_input, + imageId_output=744): + g_cli_mock = mocks.CreateMockAnything() + mocks.StubOutWithMock(clients.OpenStackClients, 'glance') + clients.OpenStackClients.glance().MultipleTimes().AndReturn( + g_cli_mock) + mocks.StubOutWithMock(glance_utils, 'get_image_id') + glance_utils.get_image_id(g_cli_mock, imageId_input).\ + MultipleTimes().AndReturn(imageId_output) + + +def setup_mocks(mocks, stack, mock_image_constraint=True): fc = fakes.FakeClient() mocks.StubOutWithMock(instances.Instance, 'nova') instances.Instance.nova().MultipleTimes().AndReturn(fc) mocks.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(fc) + instance = stack['WebServer'] + if mock_image_constraint: + setup_mock_for_image_constraint(mocks, + instance.t['Properties']['ImageId']) + setup_keystone_mocks(mocks, stack) - instance = stack['WebServer'] user_data = instance.properties['UserData'] server_userdata = nova_utils.build_userdata(instance, user_data, 'ec2-user') @@ -610,8 +626,7 @@ class StackServiceCreateUpdateDeleteTest(HeatTestCase): def test_stack_validate(self): stack_name = 'service_create_test_validate' stack = get_wordpress_stack(stack_name, self.ctx) - setup_mocks(self.m, stack) - + setup_mocks(self.m, stack, mock_image_constraint=False) resource = stack['WebServer'] self.m.ReplayAll() @@ -623,6 +638,7 @@ class StackServiceCreateUpdateDeleteTest(HeatTestCase): 'KeyName': 'test', 'InstanceType': 'm1.large' }) + setup_mock_for_image_constraint(self.m, 'CentOS 5.2') stack.validate() resource.properties = Properties( diff --git a/heat/tests/test_glance_utils.py b/heat/tests/test_glance_utils.py new file mode 100644 index 0000000000..429199474e --- /dev/null +++ b/heat/tests/test_glance_utils.py @@ -0,0 +1,109 @@ +# +# 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. +"""Tests for :module:'heat.engine.resources.glance_utils'.""" + +import uuid + +from glanceclient import exc as glance_exceptions + +from heat.common import exception +from heat.engine.resources import glance_utils +from heat.tests.common import HeatTestCase + + +class GlanceUtilsTests(HeatTestCase): + """ + Basic tests for the helper methods in + :module:'heat.engine.resources.glance_utils'. + """ + + def setUp(self): + super(GlanceUtilsTests, self).setUp() + self.glance_client = self.m.CreateMockAnything() + + def test_get_image_id(self): + """Tests the get_image_id function.""" + my_image = self.m.CreateMockAnything() + img_id = str(uuid.uuid4()) + img_name = 'myfakeimage' + my_image.id = img_id + my_image.name = img_name + self.glance_client.images = self.m.CreateMockAnything() + self.glance_client.images.get(img_id).AndReturn(my_image) + filters = {'name': img_name} + self.glance_client.images.list(filters=filters).AndReturn([my_image]) + filters = {'name': 'noimage'} + self.glance_client.images.list(filters=filters).AndReturn([]) + self.m.ReplayAll() + self.assertEqual(img_id, glance_utils.get_image_id( + self.glance_client, img_id)) + self.assertEqual(img_id, glance_utils.get_image_id( + self.glance_client, img_name)) + self.assertRaises(exception.ImageNotFound, glance_utils.get_image_id, + self.glance_client, 'noimage') + self.m.VerifyAll() + + def test_get_image_id_by_name_in_uuid(self): + """Tests the get_image_id function by name in uuid.""" + my_image = self.m.CreateMockAnything() + img_id = str(uuid.uuid4()) + img_name = str(uuid.uuid4()) + my_image.id = img_id + my_image.name = img_name + self.glance_client.images = self.m.CreateMockAnything() + self.glance_client.images.get(img_name).AndRaise( + glance_exceptions.NotFound(404)) + filters = {'name': img_name} + self.glance_client.images.list(filters=filters).MultipleTimes().\ + AndReturn([my_image]) + self.m.ReplayAll() + + self.assertEqual(img_id, glance_utils.get_image_id(self.glance_client, + img_name)) + self.m.VerifyAll() + + def test_get_image_id_not_found(self): + """Tests the get_image_id function while image is not found.""" + my_image = self.m.CreateMockAnything() + img_name = str(uuid.uuid4()) + my_image.name = img_name + self.glance_client.images = self.m.CreateMockAnything() + self.glance_client.images.get(img_name).AndRaise( + glance_exceptions.NotFound(404)) + filters = {'name': img_name} + self.glance_client.images.list(filters=filters).MultipleTimes().\ + AndReturn([]) + self.m.ReplayAll() + + self.assertRaises(exception.ImageNotFound, + glance_utils.get_image_id, + self.glance_client, img_name) + self.m.VerifyAll() + + def test_get_image_id_name_ambiguity(self): + """Tests the get_image_id function while name ambiguity .""" + my_image = self.m.CreateMockAnything() + img_name = 'ambiguity_name' + my_image.name = img_name + image_list = [my_image, my_image] + + self.glance_client.images = self.m.CreateMockAnything() + filters = {'name': img_name} + self.glance_client.images.list(filters=filters).MultipleTimes().\ + AndReturn(image_list) + self.m.ReplayAll() + + self.assertRaises(exception.PhysicalResourceNameAmbiguity, + glance_utils.get_image_id, + self.glance_client, img_name) + self.m.VerifyAll() diff --git a/heat/tests/test_image.py b/heat/tests/test_image.py index 73aab09be2..7020c51f0e 100644 --- a/heat/tests/test_image.py +++ b/heat/tests/test_image.py @@ -14,21 +14,21 @@ import mock from heat.common import exception from heat.engine import clients +from heat.engine.resources import glance_utils from heat.engine.resources import image -from heat.engine.resources import nova_utils from heat.tests.common import HeatTestCase class ImageConstraintTest(HeatTestCase): - @mock.patch.object(nova_utils, 'get_image_id') + @mock.patch.object(glance_utils, 'get_image_id') def test_validation(self, mock_get_image): with mock.patch.object(clients, "OpenStackClients"): constraint = image.ImageConstraint() mock_get_image.return_value = "id1" self.assertTrue(constraint.validate("foo", None)) - @mock.patch.object(nova_utils, 'get_image_id') + @mock.patch.object(glance_utils, 'get_image_id') def test_validation_error(self, mock_get_image): with mock.patch.object(clients, "OpenStackClients"): constraint = image.ImageConstraint() diff --git a/heat/tests/test_instance.py b/heat/tests/test_instance.py index 73e61c0bea..6afe8691b5 100644 --- a/heat/tests/test_instance.py +++ b/heat/tests/test_instance.py @@ -14,6 +14,7 @@ import copy import uuid +from glanceclient import exc as glance_exceptions import mox from neutronclient.v2_0 import client as neutronclient @@ -23,12 +24,12 @@ from heat.engine import clients from heat.engine import environment from heat.engine import parser from heat.engine import resource +from heat.engine.resources import glance_utils from heat.engine.resources import image from heat.engine.resources import instance as instances from heat.engine.resources import network_interface from heat.engine.resources import nova_utils from heat.engine import scheduler -from heat.openstack.common import uuidutils from heat.tests.common import HeatTestCase from heat.tests import utils from heat.tests.v1_1 import fakes @@ -77,6 +78,23 @@ class InstancesTest(HeatTestCase): stack_id=str(uuid.uuid4())) return (t, stack) + def _mock_get_image_id_success(self, imageId_input, imageId): + g_cli_mock = self.m.CreateMockAnything() + self.m.StubOutWithMock(clients.OpenStackClients, 'glance') + clients.OpenStackClients.glance().MultipleTimes().AndReturn( + g_cli_mock) + self.m.StubOutWithMock(glance_utils, 'get_image_id') + glance_utils.get_image_id(g_cli_mock, imageId_input).MultipleTimes().\ + AndReturn(imageId) + + def _mock_get_image_id_fail(self, image_id, exp): + g_cli_mock = self.m.CreateMockAnything() + self.m.StubOutWithMock(clients.OpenStackClients, 'glance') + clients.OpenStackClients.glance().MultipleTimes().AndReturn( + g_cli_mock) + self.m.StubOutWithMock(glance_utils, 'get_image_id') + glance_utils.get_image_id(g_cli_mock, image_id).AndRaise(exp) + def _setup_test_instance(self, return_server, name, image_id=None, stub_create=True): stack_name = '%s_s' % name @@ -88,6 +106,8 @@ class InstancesTest(HeatTestCase): '256 MB Server' instance = instances.Instance(name, t['Resources']['WebServer'], stack) + self._mock_get_image_id_success(image_id or 'CentOS 5.2', 1) + self.m.StubOutWithMock(instance, 'nova') instance.nova().MultipleTimes().AndReturn(self.fc) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') @@ -136,8 +156,6 @@ class InstancesTest(HeatTestCase): instance = self._setup_test_instance(return_server, 'in_create_imgid', image_id='1') - self.m.StubOutWithMock(uuidutils, "is_uuid_like") - uuidutils.is_uuid_like('1').MultipleTimes().AndReturn(True) self.m.ReplayAll() scheduler.TaskRunner(instance.create)() @@ -162,8 +180,9 @@ class InstancesTest(HeatTestCase): instance = instances.Instance('instance_create_image_err', t['Resources']['WebServer'], stack) - self.m.StubOutWithMock(clients.OpenStackClients, 'nova') - clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + g_cli_moc = self.m.CreateMockAnything() + self.m.StubOutWithMock(clients.OpenStackClients, 'glance') + clients.OpenStackClients.glance().MultipleTimes().AndReturn(g_cli_moc) self.m.ReplayAll() self.assertRaises(ValueError, instance.handle_create) @@ -179,12 +198,10 @@ class InstancesTest(HeatTestCase): instance = instances.Instance('instance_create_image_err', t['Resources']['WebServer'], stack) - self.m.StubOutWithMock(clients.OpenStackClients, 'nova') - clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) - self.m.StubOutWithMock(self.fc.client, "get_images_detail") - self.fc.client.get_images_detail().AndReturn(( - 200, {'images': [{'id': 1, 'name': 'CentOS 5.2'}, - {'id': 4, 'name': 'CentOS 5.2'}]})) + self._mock_get_image_id_fail('CentOS 5.2', + exception.PhysicalResourceNameAmbiguity( + name='CentOS 5.2')) + self.m.ReplayAll() self.assertRaises(ValueError, instance.handle_create) @@ -200,13 +217,8 @@ class InstancesTest(HeatTestCase): instance = instances.Instance('instance_create_image_err', t['Resources']['WebServer'], stack) - self.m.StubOutWithMock(clients.OpenStackClients, 'nova') - clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) - self.m.StubOutWithMock(uuidutils, "is_uuid_like") - uuidutils.is_uuid_like('1').AndReturn(True) - self.m.StubOutWithMock(self.fc.client, "get_images_1") - self.fc.client.get_images_1().AndRaise( - instances.clients.novaclient.exceptions.NotFound(404)) + self._mock_get_image_id_fail('1', glance_exceptions.NotFound(404)) + self.m.ReplayAll() self.assertRaises(ValueError, instance.handle_create) @@ -270,16 +282,14 @@ class InstancesTest(HeatTestCase): stack_name = 'test_instance_validate_stack' (t, stack) = self._setup_test_stack(stack_name) - # create an instance with non exist image Id t['Resources']['WebServer']['Properties']['ImageId'] = '1' - instance = instances.Instance('instance_create_image_err', + instance = instances.Instance('instance_create_image', t['Resources']['WebServer'], stack) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) - self.m.StubOutWithMock(uuidutils, "is_uuid_like") - uuidutils.is_uuid_like('1').MultipleTimes().AndReturn(True) + self._mock_get_image_id_success('1', 1) self.m.ReplayAll() self.assertIsNone(instance.validate()) diff --git a/heat/tests/test_instance_network.py b/heat/tests/test_instance_network.py index 6bd68aee8e..49328bcb8d 100644 --- a/heat/tests/test_instance_network.py +++ b/heat/tests/test_instance_network.py @@ -17,6 +17,7 @@ from heat.common import template_format from heat.engine import clients from heat.engine import environment from heat.engine import parser +from heat.engine.resources import glance_utils from heat.engine.resources import instance as instances from heat.engine.resources import network_interface as network_interfaces from heat.engine.resources import nova_utils @@ -149,6 +150,15 @@ class instancesTest(HeatTestCase): super(instancesTest, self).setUp() self.fc = fakes.FakeClient() + def _mock_get_image_id_success(self, imageId_input, imageId): + g_cli_mock = self.m.CreateMockAnything() + self.m.StubOutWithMock(clients.OpenStackClients, 'glance') + clients.OpenStackClients.glance().MultipleTimes().AndReturn( + g_cli_mock) + self.m.StubOutWithMock(glance_utils, 'get_image_id') + glance_utils.get_image_id(g_cli_mock, imageId_input).MultipleTimes().\ + AndReturn(imageId) + def _create_test_instance(self, return_server, name): stack_name = '%s_s' % name t = template_format.parse(wp_template) @@ -159,8 +169,8 @@ class instancesTest(HeatTestCase): stack = parser.Stack(utils.dummy_context(), stack_name, template, environment.Environment(kwargs), stack_id=str(uuid.uuid4())) - - t['Resources']['WebServer']['Properties']['ImageId'] = 'CentOS 5.2' + image_id = 'CentOS 5.2' + t['Resources']['WebServer']['Properties']['ImageId'] = image_id instance = instances.Instance('%s_name' % name, t['Resources']['WebServer'], stack) @@ -169,6 +179,8 @@ class instancesTest(HeatTestCase): self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + self._mock_get_image_id_success(image_id, 1) + self.m.StubOutWithMock(instance, 'neutron') instance.neutron().MultipleTimes().AndReturn(FakeNeutron()) @@ -207,8 +219,8 @@ class instancesTest(HeatTestCase): stack = parser.Stack(utils.dummy_context(), stack_name, template, environment.Environment(kwargs), stack_id=str(uuid.uuid4())) - - t['Resources']['WebServer']['Properties']['ImageId'] = 'CentOS 5.2' + image_id = 'CentOS 5.2' + t['Resources']['WebServer']['Properties']['ImageId'] = image_id nic = network_interfaces.NetworkInterface('%s_nic' % name, t['Resources']['nic1'], @@ -217,6 +229,7 @@ class instancesTest(HeatTestCase): instance = instances.Instance('%s_name' % name, t['Resources']['WebServer'], stack) + self._mock_get_image_id_success(image_id, 1) self.m.StubOutWithMock(nic, 'neutron') nic.neutron().MultipleTimes().AndReturn(FakeNeutron()) diff --git a/heat/tests/test_loadbalancer.py b/heat/tests/test_loadbalancer.py index 022b95814d..8f934232a2 100644 --- a/heat/tests/test_loadbalancer.py +++ b/heat/tests/test_loadbalancer.py @@ -22,6 +22,7 @@ from heat.common import exception from heat.common import template_format from heat.engine import clients from heat.engine import resource +from heat.engine.resources import glance_utils from heat.engine.resources import instance from heat.engine.resources import loadbalancer as lb from heat.engine.resources import wait_condition as wc @@ -122,8 +123,16 @@ class LoadBalancerTest(HeatTestCase): self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) return rsrc - def _create_stubs(self, key_name='test', stub_meta=True): + def _mock_get_image_id_success(self, imageId_input, imageId): + g_cli_mock = self.m.CreateMockAnything() + self.m.StubOutWithMock(clients.OpenStackClients, 'glance') + clients.OpenStackClients.glance().MultipleTimes().AndReturn( + g_cli_mock) + self.m.StubOutWithMock(glance_utils, 'get_image_id') + glance_utils.get_image_id(g_cli_mock, imageId_input).\ + MultipleTimes().AndReturn(imageId) + def _create_stubs(self, key_name='test', stub_meta=True): self.m.StubOutWithMock(stack_user.StackUser, 'keystone') stack_user.StackUser.keystone().MultipleTimes().AndReturn(self.fkc) @@ -133,7 +142,8 @@ class LoadBalancerTest(HeatTestCase): limit=instance.Instance.physical_resource_name_limit) clients.OpenStackClients.nova( "compute").MultipleTimes().AndReturn(self.fc) - clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + if key_name: + clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) self.fc.servers.create( flavor=2, image=746, key_name=key_name, meta=None, nics=None, name=server_name, @@ -147,8 +157,8 @@ class LoadBalancerTest(HeatTestCase): wc.WaitConditionHandle.get_status().AndReturn(['SUCCESS']) def test_loadbalancer(self): + self._mock_get_image_id_success(u'F20-x86_64-cfntools', 746) self._create_stubs() - self.m.ReplayAll() t = template_format.parse(lb_template) @@ -202,7 +212,9 @@ class LoadBalancerTest(HeatTestCase): self.m.VerifyAll() def test_loadbalancer_nokey(self): + self._mock_get_image_id_success(u'F20-x86_64-cfntools', 746) self._create_stubs(key_name=None, stub_meta=False) + self.m.ReplayAll() t = template_format.parse(lb_template_nokey) diff --git a/heat/tests/test_nokey.py b/heat/tests/test_nokey.py index c872ee408c..7cc73b420c 100644 --- a/heat/tests/test_nokey.py +++ b/heat/tests/test_nokey.py @@ -13,6 +13,7 @@ from heat.common import template_format from heat.engine import clients +from heat.engine.resources import glance_utils from heat.engine.resources import instance as instances from heat.engine.resources import nova_utils from heat.engine import scheduler @@ -59,8 +60,13 @@ class nokeyTest(HeatTestCase): self.m.StubOutWithMock(instance, 'nova') instance.nova().MultipleTimes().AndReturn(self.fc) - self.m.StubOutWithMock(clients.OpenStackClients, 'nova') - clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + g_cli_mock = self.m.CreateMockAnything() + self.m.StubOutWithMock(clients.OpenStackClients, 'glance') + clients.OpenStackClients.glance().MultipleTimes().AndReturn( + g_cli_mock) + self.m.StubOutWithMock(glance_utils, 'get_image_id') + glance_utils.get_image_id(g_cli_mock, 'CentOS 5.2').MultipleTimes().\ + AndReturn(1) # need to resolve the template functions server_userdata = nova_utils.build_userdata( @@ -84,3 +90,5 @@ class nokeyTest(HeatTestCase): self.m.ReplayAll() scheduler.TaskRunner(instance.create)() + + self.m.VerifyAll() diff --git a/heat/tests/test_nova_utils.py b/heat/tests/test_nova_utils.py index 7512baa11c..351600adfb 100644 --- a/heat/tests/test_nova_utils.py +++ b/heat/tests/test_nova_utils.py @@ -33,42 +33,6 @@ class NovaUtilsTests(HeatTestCase): super(NovaUtilsTests, self).setUp() self.nova_client = self.m.CreateMockAnything() - def test_get_image_id(self): - """Tests the get_image_id function.""" - my_image = self.m.CreateMockAnything() - img_id = str(uuid.uuid4()) - img_name = 'myfakeimage' - my_image.id = img_id - my_image.name = img_name - self.nova_client.images = self.m.CreateMockAnything() - self.nova_client.images.get(img_id).AndReturn(my_image) - self.nova_client.images.list().MultipleTimes().AndReturn([my_image]) - self.m.ReplayAll() - self.assertEqual(img_id, nova_utils.get_image_id(self.nova_client, - img_id)) - self.assertEqual(img_id, nova_utils.get_image_id(self.nova_client, - 'myfakeimage')) - self.assertRaises(exception.ImageNotFound, nova_utils.get_image_id, - self.nova_client, 'noimage') - self.m.VerifyAll() - - def test_get_image_id_by_name_in_uuid(self): - """Tests the get_image_id function by name in uuid.""" - my_image = self.m.CreateMockAnything() - img_id = str(uuid.uuid4()) - img_name = str(uuid.uuid4()) - my_image.id = img_id - my_image.name = img_name - self.nova_client.images = self.m.CreateMockAnything() - self.nova_client.images.get(img_name).AndRaise( - clients.novaclient.exceptions.NotFound(404)) - self.nova_client.images.list().MultipleTimes().AndReturn([my_image]) - self.m.ReplayAll() - - self.assertEqual(img_id, nova_utils.get_image_id(self.nova_client, - img_name)) - self.m.VerifyAll() - def test_get_ip(self): my_image = self.m.CreateMockAnything() my_image.addresses = { diff --git a/heat/tests/test_server.py b/heat/tests/test_server.py index f4d12e7c42..ec02a0e082 100644 --- a/heat/tests/test_server.py +++ b/heat/tests/test_server.py @@ -25,13 +25,13 @@ from heat.engine import clients from heat.engine import environment from heat.engine import parser from heat.engine import resource +from heat.engine.resources import glance_utils from heat.engine.resources import image from heat.engine.resources import nova_utils from heat.engine.resources import server as servers from heat.engine.resources.software_config import software_config as sc from heat.engine import scheduler from heat.openstack.common.gettextutils import _ -from heat.openstack.common import uuidutils from heat.tests.common import HeatTestCase from heat.tests import fakes from heat.tests import utils @@ -97,7 +97,8 @@ class ServersTest(HeatTestCase): return (t, stack) def _setup_test_server(self, return_server, name, image_id=None, - override_name=False, stub_create=True): + override_name=False, stub_create=True, + server_rebuild=False): stack_name = '%s_s' % name (t, stack) = self._setup_test_stack(stack_name) @@ -114,6 +115,9 @@ class ServersTest(HeatTestCase): server = servers.Server(server_name, t['Resources']['WebServer'], stack) + self._mock_get_image_id_success(image_id or 'CentOS 5.2', 1, + server_rebuild=server_rebuild) + self.m.StubOutWithMock(server, 'nova') server.nova().MultipleTimes().AndReturn(self.fc) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') @@ -135,9 +139,10 @@ class ServersTest(HeatTestCase): return server def _create_test_server(self, return_server, name, override_name=False, - stub_create=True): + stub_create=True, server_rebuild=False): server = self._setup_test_server(return_server, name, - stub_create=stub_create) + stub_create=stub_create, + server_rebuild=server_rebuild) self.m.ReplayAll() scheduler.TaskRunner(server.create)() return server @@ -151,6 +156,35 @@ class ServersTest(HeatTestCase): return fake_interface(port, mac, ip) + def _mock_get_image_id_success(self, imageId_input, imageId, + server_rebuild=False): + g_cli_mock = self.m.CreateMockAnything() + self.m.StubOutWithMock(clients.OpenStackClients, 'glance') + clients.OpenStackClients.glance().MultipleTimes().AndReturn( + g_cli_mock) + self.m.StubOutWithMock(glance_utils, 'get_image_id') + glance_utils.get_image_id(g_cli_mock, imageId_input).MultipleTimes().\ + AndReturn(imageId) + + if server_rebuild: + glance_utils.get_image_id(g_cli_mock, 'F17-x86_64-gold').\ + MultipleTimes().AndReturn(744) + + def _mock_get_image_id_fail(self, image_id, exp): + g_cli_mock = self.m.CreateMockAnything() + self.m.StubOutWithMock(clients.OpenStackClients, 'glance') + clients.OpenStackClients.glance().MultipleTimes().AndReturn( + g_cli_mock) + self.m.StubOutWithMock(glance_utils, 'get_image_id') + glance_utils.get_image_id(g_cli_mock, image_id).AndRaise(exp) + + def _server_validate_mock(self, server): + self.m.StubOutWithMock(server, 'nova') + server.nova().MultipleTimes().AndReturn(self.fc) + self.m.StubOutWithMock(clients.OpenStackClients, 'nova') + clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + self._mock_get_image_id_success('F17-x86_64-gold', 'image_id') + def test_server_create(self): return_server = self.fc.servers.list()[1] return_server.id = '5678' @@ -209,9 +243,10 @@ class ServersTest(HeatTestCase): t['Resources']['WebServer'], stack) instance_meta = {'a': "1"} + image_id = mox.IgnoreArg() self.m.StubOutWithMock(self.fc.servers, 'create') self.fc.servers.create( - image=mox.IgnoreArg(), flavor=mox.IgnoreArg(), key_name='test', + image=image_id, flavor=mox.IgnoreArg(), key_name='test', name=mox.IgnoreArg(), security_groups=[], userdata=mox.IgnoreArg(), scheduler_hints=None, meta=instance_meta, nics=None, availability_zone=None, @@ -223,6 +258,7 @@ class ServersTest(HeatTestCase): server.nova().MultipleTimes().AndReturn(self.fc) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + self._mock_get_image_id_success('F17-x86_64-gold', image_id) self.m.ReplayAll() scheduler.TaskRunner(server.create)() @@ -235,8 +271,6 @@ class ServersTest(HeatTestCase): 'test_server_create_image_id', image_id='1', override_name=True) - self.m.StubOutWithMock(uuidutils, "is_uuid_like") - uuidutils.is_uuid_like('1').MultipleTimes().AndReturn(True) interfaces = [ self._create_fake_iface('1234', 'fa:16:3e:8c:22:aa', '4.5.6.7'), @@ -286,8 +320,9 @@ class ServersTest(HeatTestCase): server = servers.Server('server_create_image_err', t['Resources']['WebServer'], stack) - self.m.StubOutWithMock(clients.OpenStackClients, 'nova') - clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + self._mock_get_image_id_fail('Slackware', + exception.ImageNotFound( + image_name='Slackware')) self.m.ReplayAll() error = self.assertRaises(ValueError, server.handle_create) @@ -307,12 +342,9 @@ class ServersTest(HeatTestCase): server = servers.Server('server_create_image_err', t['Resources']['WebServer'], stack) - self.m.StubOutWithMock(clients.OpenStackClients, 'nova') - clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) - self.m.StubOutWithMock(self.fc.client, "get_images_detail") - self.fc.client.get_images_detail().AndReturn(( - 200, {'images': [{'id': 1, 'name': 'CentOS 5.2'}, - {'id': 4, 'name': 'CentOS 5.2'}]})) + self._mock_get_image_id_fail('CentOS 5.2', + exception.PhysicalResourceNameAmbiguity( + name='CentOS 5.2')) self.m.ReplayAll() error = self.assertRaises(ValueError, server.handle_create) @@ -332,13 +364,9 @@ class ServersTest(HeatTestCase): server = servers.Server('server_create_image_err', t['Resources']['WebServer'], stack) - self.m.StubOutWithMock(clients.OpenStackClients, 'nova') - clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) - self.m.StubOutWithMock(uuidutils, "is_uuid_like") - uuidutils.is_uuid_like('1').AndReturn(True) - self.m.StubOutWithMock(self.fc.client, "get_images_1") - self.fc.client.get_images_1().AndRaise( - servers.clients.novaclient.exceptions.NotFound(404)) + self._mock_get_image_id_fail('1', + exception.ImageNotFound(image_name='1')) + self.m.ReplayAll() error = self.assertRaises(ValueError, server.handle_create) @@ -394,6 +422,7 @@ class ServersTest(HeatTestCase): server.nova().MultipleTimes().AndReturn(self.fc) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + self._mock_get_image_id_success('F17-x86_64-gold', 744) self.m.StubOutWithMock(self.fc.servers, 'create') self.fc.servers.create( @@ -435,6 +464,7 @@ class ServersTest(HeatTestCase): server.nova().MultipleTimes().AndReturn(self.fc) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + self._mock_get_image_id_success('F17-x86_64-gold', 744) self.m.StubOutWithMock(self.fc.servers, 'create') self.fc.servers.create( @@ -476,6 +506,7 @@ class ServersTest(HeatTestCase): server.nova().MultipleTimes().AndReturn(self.fc) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + self._mock_get_image_id_success('F17-x86_64-gold', 744) self.m.StubOutWithMock(self.fc.servers, 'create') self.fc.servers.create( @@ -512,6 +543,7 @@ class ServersTest(HeatTestCase): server.nova().MultipleTimes().AndReturn(self.fc) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + self._mock_get_image_id_success('F17-x86_64-gold', 744) server.keystone().MultipleTimes().AndReturn(self.fkc) @@ -576,7 +608,7 @@ class ServersTest(HeatTestCase): server.nova().MultipleTimes().AndReturn(self.fc) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) - + self._mock_get_image_id_success('F17-x86_64-gold', 744) server.keystone().MultipleTimes().AndReturn(self.fkc) self.m.StubOutWithMock(self.fc.servers, 'create') @@ -635,9 +667,10 @@ class ServersTest(HeatTestCase): mock_nova.return_value = self.fc self.fc.servers.create = mock.Mock(return_value=return_server) + self._mock_get_image_id_success('F17-x86_64-gold', 744) scheduler.TaskRunner(server.create)() - self.fc.servers.create.assert_called_once_with( + self.fc.servers.create( image=744, flavor=3, key_name='test', name=utils.PhysName(stack_name, server.name), security_groups=[], @@ -660,9 +693,10 @@ class ServersTest(HeatTestCase): mock_nova.return_value = self.fc self.fc.servers.create = mock.Mock(return_value=return_server) + self._mock_get_image_id_success('F17-x86_64-gold', 744) scheduler.TaskRunner(server.create)() - self.fc.servers.create.assert_called_once_with( + self.fc.servers.create( image=744, flavor=3, key_name='test', name=utils.PhysName(stack_name, server.name), security_groups=[], @@ -685,18 +719,15 @@ class ServersTest(HeatTestCase): stack_name = 'srv_val' (t, stack) = self._setup_test_stack(stack_name) - # create an server with non exist image Id t['Resources']['WebServer']['Properties']['image'] = '1' - server = servers.Server('server_create_image_err', + server = servers.Server('server_create_image', t['Resources']['WebServer'], stack) - self.m.StubOutWithMock(server, 'nova') - server.nova().MultipleTimes().AndReturn(self.fc) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) - self.m.StubOutWithMock(image.ImageConstraint, "validate") - image.ImageConstraint.validate( - mox.IgnoreArg(), mox.IgnoreArg()).MultipleTimes().AndReturn(True) + clients.OpenStackClients.nova('compute').MultipleTimes().\ + AndReturn(self.fc) + self._mock_get_image_id_success('1', 1) self.m.ReplayAll() @@ -841,6 +872,8 @@ class ServersTest(HeatTestCase): self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + self._mock_get_image_id_success('F17-x86_64-gold', 'image_id') + self.m.ReplayAll() ex = self.assertRaises(exception.StackValidationFailed, @@ -871,6 +904,8 @@ class ServersTest(HeatTestCase): server.nova().MultipleTimes().AndReturn(self.fc) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + + self._mock_get_image_id_success('F17-x86_64-gold', 'image_id') self.m.ReplayAll() error = self.assertRaises(exception.ResourcePropertyConflict, @@ -1016,6 +1051,7 @@ class ServersTest(HeatTestCase): self.m.StubOutWithMock(self.fc.servers, 'set_meta') self.fc.servers.set_meta(new_return_server, new_meta).AndReturn(None) + self._mock_get_image_id_success('CentOS 5.2', 1) self.m.ReplayAll() update_template = copy.deepcopy(server.t) update_template['Properties']['metadata'] = new_meta @@ -1118,6 +1154,7 @@ class ServersTest(HeatTestCase): (t, stack) = self._setup_test_stack(stack_name) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + self._mock_get_image_id_success('F17-x86_64-gold', 'image_id') self.m.ReplayAll() t['Resources']['WebServer']['Properties'][ @@ -1135,6 +1172,7 @@ class ServersTest(HeatTestCase): (t, stack) = self._setup_test_stack(stack_name) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + self._mock_get_image_id_success('F17-x86_64-gold', 'image_id') self.m.ReplayAll() server = servers.Server('server_server_update_flavor_replace', @@ -1176,7 +1214,8 @@ class ServersTest(HeatTestCase): return_server = self.fc.servers.list()[1] return_server.id = '1234' server = self._create_test_server(return_server, - 'srv_updimgrbld') + 'srv_updimgrbld', + server_rebuild=True) new_image = 'F17-x86_64-gold' # current test demonstrate updating when image_update_policy was not @@ -1230,7 +1269,8 @@ class ServersTest(HeatTestCase): return_server = self.fc.servers.list()[1] return_server.id = '1234' server = self._create_test_server(return_server, - 'srv_updrbldfail') + 'srv_updrbldfail', + server_rebuild=True) new_image = 'F17-x86_64-gold' # current test demonstrate updating when image_update_policy was not @@ -1637,10 +1677,7 @@ class ServersTest(HeatTestCase): server = servers.Server('server_create_image_err', t['Resources']['WebServer'], stack) - self.m.StubOutWithMock(server, 'nova') - server.nova().MultipleTimes().AndReturn(self.fc) - self.m.StubOutWithMock(clients.OpenStackClients, 'nova') - clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + self._server_validate_mock(server) self.m.ReplayAll() self.assertIsNone(server.validate()) @@ -1655,10 +1692,8 @@ class ServersTest(HeatTestCase): server = servers.Server('server_create_image_err', t['Resources']['WebServer'], stack) - self.m.StubOutWithMock(server, 'nova') - server.nova().MultipleTimes().AndReturn(self.fc) - self.m.StubOutWithMock(clients.OpenStackClients, 'nova') - clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + self._server_validate_mock(server) + self.m.ReplayAll() self.assertIsNone(server.validate()) @@ -1688,6 +1723,7 @@ class ServersTest(HeatTestCase): t['Resources']['WebServer'], stack) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + self._mock_get_image_id_success('F17-x86_64-gold', 'image_id') self.m.ReplayAll() self.assertRaises(exception.ResourcePropertyConflict, server.validate) @@ -1704,6 +1740,7 @@ class ServersTest(HeatTestCase): t['Resources']['WebServer'], stack) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + self._mock_get_image_id_success('F17-x86_64-gold', 'image_id') self.m.ReplayAll() ex = self.assertRaises(exception.StackValidationFailed, @@ -1753,6 +1790,7 @@ class ServersTest(HeatTestCase): server.nova().MultipleTimes().AndReturn(self.fc) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + self._mock_get_image_id_success('F17-x86_64-gold', 'image_id') self.m.ReplayAll() ex = self.assertRaises(exception.StackValidationFailed, @@ -1778,6 +1816,7 @@ class ServersTest(HeatTestCase): server.nova().MultipleTimes().AndReturn(self.fc) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + self._mock_get_image_id_success('F17-x86_64-gold', 'image_id') self.m.ReplayAll() self.assertIsNone(server.validate()) self.m.VerifyAll() @@ -1803,6 +1842,7 @@ class ServersTest(HeatTestCase): server.nova().MultipleTimes().AndReturn(self.fc) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + self._mock_get_image_id_success('F17-x86_64-gold', 'image_id') self.m.ReplayAll() exc = self.assertRaises(exception.StackValidationFailed, @@ -1831,6 +1871,7 @@ class ServersTest(HeatTestCase): server.nova().MultipleTimes().AndReturn(self.fc) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + self._mock_get_image_id_success('F17-x86_64-gold', 'image_id') self.m.ReplayAll() self.assertIsNone(server.validate()) @@ -1852,6 +1893,7 @@ class ServersTest(HeatTestCase): server.nova().MultipleTimes().AndReturn(self.fc) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + self._mock_get_image_id_success('F17-x86_64-gold', 'image_id') self.m.ReplayAll() self.assertIsNone(server.validate()) @@ -1873,6 +1915,7 @@ class ServersTest(HeatTestCase): server.nova().MultipleTimes().AndReturn(self.fc) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + self._mock_get_image_id_success('F17-x86_64-gold', 'image_id') self.m.ReplayAll() exc = self.assertRaises(exception.StackValidationFailed, @@ -1925,8 +1968,9 @@ class ServersTest(HeatTestCase): server = servers.Server('create_metadata_test_server', t['Resources']['WebServer'], stack) self.m.StubOutWithMock(self.fc.servers, 'create') + image_id = mox.IgnoreArg() self.fc.servers.create( - image=mox.IgnoreArg(), flavor=mox.IgnoreArg(), key_name='test', + image=image_id, flavor=mox.IgnoreArg(), key_name='test', name=mox.IgnoreArg(), security_groups=[], userdata=mox.IgnoreArg(), scheduler_hints=None, meta=mox.IgnoreArg(), nics=None, availability_zone=None, @@ -1937,6 +1981,7 @@ class ServersTest(HeatTestCase): server.nova().MultipleTimes().AndReturn(self.fc) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + self._mock_get_image_id_success('F17-x86_64-gold', image_id) self.m.StubOutWithMock(nova_utils, 'build_userdata') nova_utils.build_userdata(server, 'wordpress', diff --git a/heat/tests/test_server_tags.py b/heat/tests/test_server_tags.py index 39fb73aacd..b04e8b81af 100644 --- a/heat/tests/test_server_tags.py +++ b/heat/tests/test_server_tags.py @@ -20,6 +20,7 @@ from heat.common import template_format from heat.engine import clients from heat.engine import environment from heat.engine import parser +from heat.engine.resources import glance_utils from heat.engine.resources import instance as instances from heat.engine.resources import nova_utils from heat.engine import scheduler @@ -129,6 +130,15 @@ class ServerTagsTest(HeatTestCase): super(ServerTagsTest, self).setUp() self.fc = fakes.FakeClient() + def _mock_get_image_id_success(self, imageId_input, imageId): + g_cli_mock = self.m.CreateMockAnything() + self.m.StubOutWithMock(clients.OpenStackClients, 'glance') + clients.OpenStackClients.glance().MultipleTimes().AndReturn( + g_cli_mock) + self.m.StubOutWithMock(glance_utils, 'get_image_id') + glance_utils.get_image_id(g_cli_mock, imageId_input).MultipleTimes().\ + AndReturn(imageId) + def _setup_test_instance(self, intags=None, nova_tags=None): stack_name = 'tag_test' t = template_format.parse(instance_template) @@ -145,7 +155,7 @@ class ServerTagsTest(HeatTestCase): instance.nova().MultipleTimes().AndReturn(self.fc) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) - + self._mock_get_image_id_success('CentOS 5.2', 1) # need to resolve the template functions server_userdata = nova_utils.build_userdata( instance, @@ -202,6 +212,7 @@ class ServerTagsTest(HeatTestCase): self.m.StubOutWithMock(self.fc.servers, 'set_meta') self.fc.servers.set_meta(self.fc.servers.list()[1], new_metadata).AndReturn(None) + self._mock_get_image_id_success('CentOS 5.2', 1) self.m.ReplayAll() update_template = copy.deepcopy(instance.t) update_template['Properties']['Tags'] = new_tags @@ -234,7 +245,7 @@ class ServerTagsTest(HeatTestCase): instances.Instance.nova().MultipleTimes().AndReturn(self.fc) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) - + self._mock_get_image_id_success('CentOS 5.2', 1) # need to resolve the template functions self.m.StubOutWithMock(self.fc.servers, 'create') self.fc.servers.create( @@ -285,7 +296,7 @@ class ServerTagsTest(HeatTestCase): instances.Instance.nova().MultipleTimes().AndReturn(self.fc) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) - + self._mock_get_image_id_success('CentOS 5.2', 1) # need to resolve the template functions self.m.StubOutWithMock(self.fc.servers, 'create') self.fc.servers.create( diff --git a/heat/tests/test_sqlalchemy_api.py b/heat/tests/test_sqlalchemy_api.py index 6ae439240c..60cf24e1a9 100644 --- a/heat/tests/test_sqlalchemy_api.py +++ b/heat/tests/test_sqlalchemy_api.py @@ -30,6 +30,7 @@ from heat.engine.clients import novaclient from heat.engine import environment from heat.engine import parser from heat.engine.resource import Resource +from heat.engine.resources import glance_utils from heat.engine.resources import instance as instances from heat.engine import scheduler from heat.openstack.common import timeutils @@ -94,6 +95,15 @@ class SqlAlchemyTest(HeatTestCase): def tearDown(self): super(SqlAlchemyTest, self).tearDown() + def _mock_get_image_id_success(self, imageId_input, imageId): + g_cli_mock = self.m.CreateMockAnything() + self.m.StubOutWithMock(clients.OpenStackClients, 'glance') + clients.OpenStackClients.glance().MultipleTimes().AndReturn( + g_cli_mock) + self.m.StubOutWithMock(glance_utils, 'get_image_id') + glance_utils.get_image_id(g_cli_mock, imageId_input).MultipleTimes().\ + AndReturn(imageId) + def _setup_test_stack(self, stack_name, stack_id=None, owner_id=None, stack_user_project_id=None): t = template_format.parse(wp_template) @@ -113,6 +123,7 @@ class SqlAlchemyTest(HeatTestCase): instances.Instance.nova().MultipleTimes().AndReturn(fc) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + self._mock_get_image_id_success('F17-x86_64-gold', 744) mocks.StubOutWithMock(fc.servers, 'create') fc.servers.create(image=744, flavor=3, key_name='test', @@ -128,9 +139,6 @@ class SqlAlchemyTest(HeatTestCase): fc = fakes.FakeClient() mocks.StubOutWithMock(instances.Instance, 'nova') instances.Instance.nova().MultipleTimes().AndReturn(fc) - self.m.StubOutWithMock(clients.OpenStackClients, 'nova') - clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) - mocks.StubOutWithMock(fc.client, 'get_servers_9999') get = fc.client.get_servers_9999 get().MultipleTimes().AndRaise(novaclient.exceptions.NotFound(404)) diff --git a/heat/tests/test_validate.py b/heat/tests/test_validate.py index 9a34640a87..51ff90cf52 100644 --- a/heat/tests/test_validate.py +++ b/heat/tests/test_validate.py @@ -11,8 +11,7 @@ # License for the specific language governing permissions and limitations # under the License. -import collections - +from glanceclient import exc as g_exc from testtools import skipIf from heat.common import exception @@ -22,6 +21,7 @@ from heat.engine import environment from heat.engine.hot.template import HOTemplate from heat.engine import parser from heat.engine import resources +from heat.engine.resources import glance_utils from heat.engine import service from heat.openstack.common.importutils import try_import from heat.tests.common import HeatTestCase @@ -484,7 +484,7 @@ test_template_invalid_secgroupids = ''' } ''' -test_template_nova_client_exception = ''' +test_template_glance_client_exception = ''' { "AWSTemplateFormatVersion" : "2010-09-09", "Description" : "test.", @@ -779,9 +779,27 @@ class validateTest(HeatTestCase): super(validateTest, self).setUp() resources.initialise() self.fc = fakes.FakeClient() + self.gc = fakes.FakeClient() resources.initialise() self.ctx = utils.dummy_context() + def _mock_get_image_id_success(self, imageId_input, imageId): + g_cli_mock = self.m.CreateMockAnything() + self.m.StubOutWithMock(clients.OpenStackClients, 'glance') + clients.OpenStackClients.glance().MultipleTimes().AndReturn( + g_cli_mock) + self.m.StubOutWithMock(glance_utils, 'get_image_id') + glance_utils.get_image_id(g_cli_mock, imageId_input).MultipleTimes().\ + AndReturn(imageId) + + def _mock_get_image_id_fail(self, image_id, exp): + g_cli_mock = self.m.CreateMockAnything() + self.m.StubOutWithMock(clients.OpenStackClients, 'glance') + clients.OpenStackClients.glance().MultipleTimes().AndReturn( + g_cli_mock) + self.m.StubOutWithMock(glance_utils, 'get_image_id') + glance_utils.get_image_id(g_cli_mock, image_id).AndRaise(exp) + def test_validate_volumeattach_valid(self): t = template_format.parse(test_template_volumeattach % 'vdq') stack = parser.Stack(self.ctx, 'test_stack', parser.Template(t)) @@ -1310,8 +1328,7 @@ class validateTest(HeatTestCase): stack = parser.Stack(self.ctx, 'test_stack', template, environment.Environment(params)) - self.m.StubOutWithMock(clients.OpenStackClients, 'nova') - clients.OpenStackClients.nova().AndReturn(self.fc) + self._mock_get_image_id_success('image_name', 'image_id') self.m.ReplayAll() resource = stack['Instance'] @@ -1325,8 +1342,9 @@ class validateTest(HeatTestCase): stack = parser.Stack(self.ctx, 'test_stack', template, environment.Environment({'KeyName': 'test'})) - self.m.StubOutWithMock(clients.OpenStackClients, 'nova') - clients.OpenStackClients.nova().AndReturn(self.fc) + self._mock_get_image_id_fail('image_name', + exception.ImageNotFound( + image_name='image_name')) self.m.ReplayAll() resource = stack['Instance'] @@ -1341,18 +1359,10 @@ class validateTest(HeatTestCase): stack = parser.Stack(self.ctx, 'test_stack', template, environment.Environment({'KeyName': 'test'})) - image_type = collections.namedtuple("Image", ("id", "name")) + self._mock_get_image_id_fail('image_name', + exception.PhysicalResourceNameAmbiguity( + name='image_name')) - image_list = [image_type(id='768b5464-3df5-4abf-be33-63b60f8b99d0', - name='image_name'), - image_type(id='a57384f5-690f-48e1-bf46-c4291e6c887e', - name='image_name')] - - self.m.StubOutWithMock(self.fc.images, 'list') - self.fc.images.list().AndReturn(image_list) - - self.m.StubOutWithMock(clients.OpenStackClients, 'nova') - clients.OpenStackClients.nova().AndReturn(self.fc) self.m.ReplayAll() resource = stack['Instance'] @@ -1367,13 +1377,7 @@ class validateTest(HeatTestCase): stack = parser.Stack(self.ctx, 'test_stack', template, environment.Environment({'KeyName': 'test'})) - image_type = collections.namedtuple("Image", ("id", "name")) - - image_list = [image_type(id='768b5464-3df5-4abf-be33-63b60f8b99d0', - name='image_name')] - - self.m.StubOutWithMock(self.fc.images, 'list') - self.fc.images.list().MultipleTimes().AndReturn(image_list) + self._mock_get_image_id_success('image_name', 'image_id') self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) @@ -1390,13 +1394,7 @@ class validateTest(HeatTestCase): stack = parser.Stack(self.ctx, 'test_stack', template, environment.Environment({'KeyName': 'test'})) - image_type = collections.namedtuple("Image", ("id", "name")) - - image_list = [image_type(id='768b5464-3df5-4abf-be33-63b60f8b99d0', - name='image_name')] - - self.m.StubOutWithMock(self.fc.images, 'list') - self.fc.images.list().MultipleTimes().AndReturn(image_list) + self._mock_get_image_id_success('image_name', 'image_id') self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) @@ -1407,16 +1405,16 @@ class validateTest(HeatTestCase): resource.validate) self.m.VerifyAll() - def test_client_exception_from_nova_client(self): - t = template_format.parse(test_template_nova_client_exception) + def test_client_exception_from_glance_client(self): + t = template_format.parse(test_template_glance_client_exception) template = parser.Template(t) stack = parser.Stack(self.ctx, 'test_stack', template) - self.m.StubOutWithMock(self.fc.images, 'list') - self.fc.images.list().AndRaise( - clients.novaclient.exceptions.ClientException(500)) - self.m.StubOutWithMock(clients.OpenStackClients, 'nova') - clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) + self.m.StubOutWithMock(self.gc.images, 'list') + self.gc.images.list().AndRaise( + g_exc.ClientException(500)) + self.m.StubOutWithMock(clients.OpenStackClients, 'glance') + clients.OpenStackClients.glance().MultipleTimes().AndReturn(self.gc) self.m.ReplayAll() self.assertRaises(exception.StackValidationFailed, stack.validate) diff --git a/heat/tests/test_volume.py b/heat/tests/test_volume.py index 79079a0509..8ec2d53473 100644 --- a/heat/tests/test_volume.py +++ b/heat/tests/test_volume.py @@ -21,9 +21,9 @@ from testtools import skipIf from heat.common import exception from heat.common import template_format from heat.engine import clients +from heat.engine.resources import glance_utils from heat.engine.resources import image from heat.engine.resources import instance -from heat.engine.resources import nova_utils from heat.engine.resources import volume as vol from heat.engine import scheduler from heat.openstack.common.importutils import try_import @@ -93,7 +93,6 @@ class VolumeTest(HeatTestCase): self.m.StubOutWithMock(self.fc.volumes, 'create_server_volume') self.m.StubOutWithMock(self.fc.volumes, 'delete_server_volume') self.m.StubOutWithMock(self.fc.volumes, 'get_server_volume') - self.m.StubOutWithMock(nova_utils, 'get_image_id') def create_volume(self, t, stack, resource_name): data = t['Resources'][resource_name] @@ -848,20 +847,22 @@ class VolumeTest(HeatTestCase): def test_cinder_create_from_image(self): fv = FakeVolumeWithStateTransition('downloading', 'available') stack_name = 'test_volume_stack' - + image_id = '46988116-6703-4623-9dbc-2bc6d284021b' clients.OpenStackClients.cinder().MultipleTimes().AndReturn( self.cinder_fc) - clients.OpenStackClients.nova("compute").MultipleTimes().AndReturn( - self.fc) - clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) - nova_utils.get_image_id( - self.fc, '46988116-6703-4623-9dbc-2bc6d284021b' - ).MultipleTimes().AndReturn('46988116-6703-4623-9dbc-2bc6d284021b') + g_cli_mock = self.m.CreateMockAnything() + self.m.StubOutWithMock(clients.OpenStackClients, 'glance') + clients.OpenStackClients.glance().MultipleTimes().AndReturn( + g_cli_mock) + self.m.StubOutWithMock(glance_utils, 'get_image_id') + glance_utils.get_image_id(g_cli_mock, image_id).MultipleTimes().\ + AndReturn(image_id) + self.cinder_fc.volumes.create( size=1, availability_zone='nova', display_description='ImageVolumeDescription', display_name='ImageVolume', - imageRef='46988116-6703-4623-9dbc-2bc6d284021b').AndReturn(fv) + imageRef=image_id).AndReturn(fv) self.m.ReplayAll() @@ -871,7 +872,7 @@ class VolumeTest(HeatTestCase): 'name': 'ImageVolume', 'description': 'ImageVolumeDescription', 'availability_zone': 'nova', - 'image': '46988116-6703-4623-9dbc-2bc6d284021b', + 'image': image_id, } stack = utils.parse_stack(t, stack_name=stack_name)