diff --git a/heat/engine/resource.py b/heat/engine/resource.py index 49bf056aa0..8d640e8665 100644 --- a/heat/engine/resource.py +++ b/heat/engine/resource.py @@ -39,6 +39,7 @@ from heat.engine import rsrc_defn from heat.engine import scheduler from heat.engine import support from heat.openstack.common import log as logging +from heat.rpc import client as rpc_client cfg.CONF.import_opt('action_retry_limit', 'heat.common.config') @@ -177,11 +178,18 @@ class Resource(object): self._stored_properties_data = None self.created_time = None self.updated_time = None + self._rpc_client = None resource = stack.db_resource_get(name) if resource: self._load_data(resource) + def rpc_client(self): + '''Return a client for making engine RPC calls.''' + if not self._rpc_client: + self._rpc_client = rpc_client.EngineClient() + return self._rpc_client + def _load_data(self, resource): '''Load the resource state from its DB representation.''' self.resource_id = resource.nova_instance diff --git a/heat/engine/resources/server.py b/heat/engine/resources/server.py index f84d0d4dd0..ec0a7b0b0a 100644 --- a/heat/engine/resources/server.py +++ b/heat/engine/resources/server.py @@ -30,6 +30,7 @@ from heat.engine import stack_user from heat.engine import support from heat.openstack.common import log as logging from heat.openstack.common import uuidutils +from heat.rpc import api as rpc_api cfg.CONF.import_opt('instance_user', 'heat.common.config') @@ -469,6 +470,14 @@ class Server(stack_user.StackUser): return self.properties.get( self.SOFTWARE_CONFIG_TRANSPORT) == self.POLL_TEMP_URL + def get_software_config(self, ud_content): + try: + sc = self.rpc_client().show_software_config( + self.context, ud_content) + return sc[rpc_api.SOFTWARE_CONFIG_CONFIG] + except exception.NotFound: + return ud_content + def handle_create(self): security_groups = self.properties.get(self.SECURITY_GROUPS) @@ -477,11 +486,7 @@ class Server(stack_user.StackUser): if self.user_data_software_config() or self.user_data_raw(): if uuidutils.is_uuid_like(ud_content): # attempt to load the userdata from software config - try: - ud_content = self.heat().software_configs.get( - ud_content).config - except Exception as ex: - self.client_plugin('heat').ignore_not_found(ex) + ud_content = self.get_software_config(ud_content) metadata = self.metadata_get(True) or {} diff --git a/heat/engine/resources/software_config/cloud_config.py b/heat/engine/resources/software_config/cloud_config.py index c2dfac4747..0a928f4d14 100644 --- a/heat/engine/resources/software_config/cloud_config.py +++ b/heat/engine/resources/software_config/cloud_config.py @@ -17,6 +17,7 @@ from heat.common.template_format import yaml_dumper from heat.engine import properties from heat.engine.resources.software_config import software_config from heat.engine import support +from heat.rpc import api as rpc_api class CloudConfig(software_config.SoftwareConfig): @@ -54,8 +55,8 @@ class CloudConfig(software_config.SoftwareConfig): cloud_config = yaml.dump(self.properties.get( self.CLOUD_CONFIG), Dumper=yaml_dumper) props[self.CONFIG] = '#cloud-config\n%s' % cloud_config - sc = self.heat().software_configs.create(**props) - self.resource_id_set(sc.id) + sc = self.rpc_client().create_software_config(self.context, **props) + self.resource_id_set(sc[rpc_api.SOFTWARE_CONFIG_ID]) def resource_mapping(): diff --git a/heat/engine/resources/software_config/multi_part.py b/heat/engine/resources/software_config/multi_part.py index 00567689d5..97be34dbb8 100644 --- a/heat/engine/resources/software_config/multi_part.py +++ b/heat/engine/resources/software_config/multi_part.py @@ -16,11 +16,13 @@ from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText import os +from heat.common import exception from heat.common.i18n import _ from heat.engine import constraints from heat.engine import properties from heat.engine.resources.software_config import software_config from heat.engine import support +from heat.rpc import api as rpc_api class MultipartMime(software_config.SoftwareConfig): @@ -95,8 +97,8 @@ class MultipartMime(software_config.SoftwareConfig): def handle_create(self): props = {self.NAME: self.physical_resource_name()} props[self.CONFIG] = self.get_message() - sc = self.heat().software_configs.create(**props) - self.resource_id_set(sc.id) + sc = self.rpc_client().create_software_config(self.context, **props) + self.resource_id_set(sc[rpc_api.SOFTWARE_CONFIG_ID]) def get_message(self): if self.message: @@ -107,10 +109,14 @@ class MultipartMime(software_config.SoftwareConfig): config = item.get(self.CONFIG) part_type = item.get(self.TYPE, self.TEXT) part = config + try: - part = self.heat().software_configs.get(config).config - except Exception as ex: - self.client_plugin().ignore_not_found(ex) + sc = self.rpc_client().show_software_config( + self.context, self.resource_id) + except exception.NotFound: + pass + else: + part = sc[rpc_api.SOFTWARE_CONFIG_CONFIG] if part_type == self.MULTIPART: self._append_multiparts(subparts, part) diff --git a/heat/engine/resources/software_config/software_component.py b/heat/engine/resources/software_config/software_component.py index c4ff977018..40a7d8da6b 100644 --- a/heat/engine/resources/software_config/software_component.py +++ b/heat/engine/resources/software_config/software_component.py @@ -18,6 +18,7 @@ from heat.engine import properties from heat.engine import resource from heat.engine.resources.software_config import software_config as sc from heat.engine import support +from heat.rpc import api as rpc_api class SoftwareComponent(sc.SoftwareConfig): @@ -116,8 +117,8 @@ class SoftwareComponent(sc.SoftwareConfig): # set 'group' to enable component processing by in-instance hook props[self.GROUP] = 'component' - sc = self.heat().software_configs.create(**props) - self.resource_id_set(sc.id) + sc = self.rpc_client().create_software_config(self.context, **props) + self.resource_id_set(sc[rpc_api.SOFTWARE_CONFIG_ID]) def _resolve_attribute(self, name): ''' @@ -129,14 +130,13 @@ class SoftwareComponent(sc.SoftwareConfig): ''' if name == self.CONFIGS_ATTR and self.resource_id: try: - config = self.heat().software_configs.get(self.resource_id).\ - config + sc = self.rpc_client().show_software_config( + self.context, self.resource_id) # configs list is stored in 'config' property of parent class # (see handle_create) - return config.get(self.CONFIGS) - except Exception as ex: - if self.client_plugin().is_not_found(ex): - return None + return sc[rpc_api.SOFTWARE_CONFIG_CONFIG].get(self.CONFIGS) + except exception.NotFound: + return None def validate(self): '''Validate SoftwareComponent properties consistency.''' diff --git a/heat/engine/resources/software_config/software_config.py b/heat/engine/resources/software_config/software_config.py index dff8960f8f..1ea7f830bf 100644 --- a/heat/engine/resources/software_config/software_config.py +++ b/heat/engine/resources/software_config/software_config.py @@ -11,6 +11,7 @@ # License for the specific language governing permissions and limitations # under the License. +from heat.common import exception from heat.common.i18n import _ from heat.engine import attributes from heat.engine import constraints @@ -18,6 +19,7 @@ from heat.engine import properties from heat.engine import resource from heat.engine import support from heat.openstack.common import log as logging +from heat.rpc import api as rpc_api LOG = logging.getLogger(__name__) @@ -152,14 +154,12 @@ class SoftwareConfig(resource.Resource): ), } - default_client_name = 'heat' - def handle_create(self): props = dict(self.properties) props[self.NAME] = self.physical_resource_name() - sc = self.heat().software_configs.create(**props) - self.resource_id_set(sc.id) + sc = self.rpc_client().create_software_config(self.context, **props) + self.resource_id_set(sc[rpc_api.SOFTWARE_CONFIG_ID]) def handle_delete(self): @@ -167,9 +167,10 @@ class SoftwareConfig(resource.Resource): return try: - self.heat().software_configs.delete(self.resource_id) - except Exception as ex: - self.client_plugin().ignore_not_found(ex) + self.rpc_client().delete_software_config( + self.context, self.resource_id) + except exception.NotFound: + pass def _resolve_attribute(self, name): ''' @@ -178,11 +179,11 @@ class SoftwareConfig(resource.Resource): ''' if name == self.CONFIG_ATTR and self.resource_id: try: - return self.heat().software_configs.get( - self.resource_id).config - except Exception as ex: - if self.client_plugin().is_not_found(ex): - return None + sc = self.rpc_client().show_software_config( + self.context, self.resource_id) + return sc[rpc_api.SOFTWARE_CONFIG_CONFIG] + except exception.NotFound: + return None def resource_mapping(): diff --git a/heat/engine/resources/software_config/software_deployment.py b/heat/engine/resources/software_config/software_deployment.py index 1873ba6374..a49ab6bb4b 100644 --- a/heat/engine/resources/software_config/software_deployment.py +++ b/heat/engine/resources/software_config/software_deployment.py @@ -26,6 +26,7 @@ from heat.engine.resources.software_config import software_config as sc from heat.engine import signal_responder from heat.engine import support from heat.openstack.common import log as logging +from heat.rpc import api as rpc_api LOG = logging.getLogger(__name__) @@ -194,23 +195,26 @@ class SoftwareDeployment(signal_responder.SignalResponder): def _delete_derived_config(self, derived_config_id): try: - self.heat().software_configs.delete(derived_config_id) - except Exception as ex: - self.client_plugin().ignore_not_found(ex) + self.rpc_client().delete_software_config( + self.context, derived_config_id) + except exception.NotFound: + pass def _get_derived_config(self, action, source_config): derived_params = self._build_derived_config_params( - action, source_config.to_dict()) - derived_config = self.heat().software_configs.create(**derived_params) - return derived_config.id + action, source_config) + derived_config = self.rpc_client().create_software_config( + self.context, **derived_params) + return derived_config[rpc_api.SOFTWARE_CONFIG_ID] def _handle_action(self, action): config_id = self.properties.get(self.CONFIG) - config = self.heat().software_configs.get(config_id) + config = self.rpc_client().show_software_config( + self.context, config_id) if action not in self.properties[self.DEPLOY_ACTIONS]\ - and not config.group == 'component': + and not config[rpc_api.SOFTWARE_CONFIG_GROUP] == 'component': return props = self._build_properties( @@ -430,7 +434,8 @@ class SoftwareDeployment(signal_responder.SignalResponder): def handle_signal(self, details): sd = self.heat().software_deployments.get(self.resource_id) - sc = self.heat().software_configs.get(self.properties[self.CONFIG]) + sc = self.rpc_client().show_software_config( + self.context, self.properties[self.CONFIG]) if not sd.status == self.IN_PROGRESS: # output values are only expected when in an IN_PROGRESS state return @@ -450,7 +455,7 @@ class SoftwareDeployment(signal_responder.SignalResponder): else: event_reason = 'deployment succeeded' - for output in sc.outputs or []: + for output in sc[rpc_api.SOFTWARE_CONFIG_OUTPUTS] or []: out_key = output['name'] if out_key in details: ov[out_key] = details[out_key] @@ -486,8 +491,10 @@ class SoftwareDeployment(signal_responder.SignalResponder): # Since there is no value for this key yet, check the output schemas # to find out if the key is valid - sc = self.heat().software_configs.get(self.properties[self.CONFIG]) - output_keys = [output['name'] for output in sc.outputs] + sc = self.rpc_client().show_software_config( + self.context, self.properties[self.CONFIG]) + outputs = sc[rpc_api.SOFTWARE_CONFIG_OUTPUTS] or [] + output_keys = [output['name'] for output in outputs] if key not in output_keys and key not in self.ATTRIBUTES: raise exception.InvalidTemplateAttribute(resource=self.name, key=key) diff --git a/heat/tests/test_cloud_config.py b/heat/tests/test_cloud_config.py index 5164158423..0f6eb529e8 100644 --- a/heat/tests/test_cloud_config.py +++ b/heat/tests/test_cloud_config.py @@ -38,9 +38,8 @@ class CloudConfigTest(common.HeatTestCase): 'Properties': self.properties }}})) self.config = self.stack['config_mysql'] - heat = mock.MagicMock() - self.config.heat = heat - self.software_configs = heat.return_value.software_configs + self.rpc_client = mock.MagicMock() + self.config._rpc_client = self.rpc_client def test_resource_mapping(self): mapping = cc.resource_mapping() @@ -50,11 +49,10 @@ class CloudConfigTest(common.HeatTestCase): self.assertIsInstance(self.config, cc.CloudConfig) def test_handle_create(self): - sc = mock.MagicMock() config_id = 'c8a19429-7fde-47ea-a42f-40045488226c' - sc.id = config_id - self.software_configs.create.return_value = sc + value = {'id': config_id} + self.rpc_client.create_software_config.return_value = value self.config.handle_create() self.assertEqual(config_id, self.config.resource_id) - kwargs = self.software_configs.create.call_args[1] + kwargs = self.rpc_client.create_software_config.call_args[1] self.assertEqual('#cloud-config\n{foo: bar}\n', kwargs['config']) diff --git a/heat/tests/test_multi_part.py b/heat/tests/test_multi_part.py index efde788916..f7ee02c06f 100644 --- a/heat/tests/test_multi_part.py +++ b/heat/tests/test_multi_part.py @@ -13,9 +13,9 @@ import email -import heatclient.exc as exc import mock +from heat.common import exception as exc from heat.engine import parser from heat.engine.resources.software_config import multi_part as mp from heat.engine import template @@ -43,9 +43,8 @@ class MultipartMimeTest(common.HeatTestCase): 'parts': parts }}}})) self.config = stack['config_mysql'] - heat = mock.MagicMock() - self.config.heat = heat - self.software_configs = heat.return_value.software_configs + self.rpc_client = mock.MagicMock() + self.config._rpc_client = self.rpc_client def test_resource_mapping(self): mapping = mp.resource_mapping() @@ -55,13 +54,12 @@ class MultipartMimeTest(common.HeatTestCase): self.assertIsInstance(self.config, mp.MultipartMime) def test_handle_create(self): - sc = mock.MagicMock() config_id = 'c8a19429-7fde-47ea-a42f-40045488226c' - sc.id = config_id - self.software_configs.create.return_value = sc + sc = {'id': config_id} + self.rpc_client.create_software_config.return_value = sc self.config.handle_create() self.assertEqual(config_id, self.config.resource_id) - args = self.software_configs.create.call_args[1] + args = self.rpc_client.create_software_config.call_args[1] self.assertEqual(self.config.message, args['config']) def test_get_message_not_none(self): @@ -82,7 +80,9 @@ class MultipartMimeTest(common.HeatTestCase): 'type': 'text' }] self.init_config(parts=parts) - self.software_configs.get.return_value.config = '#!/bin/bash' + self.rpc_client.show_software_config.return_value = { + 'config': '#!/bin/bash' + } result = self.config.get_message() message = email.message_from_string(result) self.assertTrue(message.is_multipart()) @@ -96,7 +96,7 @@ class MultipartMimeTest(common.HeatTestCase): 'type': 'text' }] self.init_config(parts=parts) - self.software_configs.get.side_effect = exc.HTTPNotFound() + self.rpc_client.show_software_config.side_effect = exc.NotFound() result = self.config.get_message() message = email.message_from_string(result) self.assertTrue(message.is_multipart()) @@ -111,7 +111,9 @@ class MultipartMimeTest(common.HeatTestCase): 'filename': '/opt/stack/configure.d/55-heat-config' }] self.init_config(parts=parts) - self.software_configs.get.return_value.config = '#!/bin/bash' + self.rpc_client.show_software_config.return_value = { + 'config': '#!/bin/bash' + } result = self.config.get_message() message = email.message_from_string(result) self.assertTrue(message.is_multipart()) @@ -138,7 +140,11 @@ class MultipartMimeTest(common.HeatTestCase): 'type': 'multipart' }] self.init_config(parts=parts) - self.software_configs.get.return_value.config = multipart + + self.rpc_client.show_software_config.return_value = { + 'config': multipart + } + result = self.config.get_message() message = email.message_from_string(result) self.assertTrue(message.is_multipart()) @@ -155,7 +161,9 @@ class MultipartMimeTest(common.HeatTestCase): {'config': '9cab10ef-16ce-4be9-8b25-a67b7313eddb', 'type': 'text'}] self.init_config(parts=parts) - self.software_configs.get.return_value.config = '#!/bin/bash' + self.rpc_client.show_software_config.return_value = { + 'config': '#!/bin/bash' + } result = self.config.get_message() message = email.message_from_string(result) self.assertTrue(message.is_multipart()) diff --git a/heat/tests/test_server.py b/heat/tests/test_server.py index 7d8081730d..646fcc83be 100644 --- a/heat/tests/test_server.py +++ b/heat/tests/test_server.py @@ -26,7 +26,6 @@ from heat.common.i18n import _ from heat.common import template_format from heat.db import api as db_api from heat.engine.clients.os import glance -from heat.engine.clients.os import heat_plugin from heat.engine.clients.os import nova from heat.engine.clients.os import swift from heat.engine import environment @@ -531,12 +530,11 @@ class ServersTest(common.HeatTestCase): server = servers.Server('WebServer', resource_defns['WebServer'], stack) - self.m.StubOutWithMock(heat_plugin.HeatClientPlugin, '_create') - heat_client = mock.Mock() - heat_plugin.HeatClientPlugin._create().AndReturn(heat_client) - sc = mock.Mock() - sc.config = 'wordpress from config' - heat_client.software_configs.get.return_value = sc + self.rpc_client = mock.MagicMock() + server._rpc_client = self.rpc_client + + sc = {'config': 'wordpress from config'} + self.rpc_client.show_software_config.return_value = sc self.m.StubOutWithMock(nova.NovaClientPlugin, '_create') nova.NovaClientPlugin._create().AndReturn(self.fc) @@ -572,11 +570,10 @@ class ServersTest(common.HeatTestCase): server = servers.Server('WebServer', resource_defns['WebServer'], stack) - self.m.StubOutWithMock(heat_plugin.HeatClientPlugin, '_create') - heat_client = mock.Mock() - heat_plugin.HeatClientPlugin._create().AndReturn(heat_client) - heat_client.software_configs.get.side_effect = \ - heat_plugin.exc.HTTPNotFound() + self.rpc_client = mock.MagicMock() + server._rpc_client = self.rpc_client + + self.rpc_client.show_software_config.side_effect = exception.NotFound self.m.StubOutWithMock(nova.NovaClientPlugin, '_create') nova.NovaClientPlugin._create().AndReturn(self.fc) diff --git a/heat/tests/test_software_component.py b/heat/tests/test_software_component.py index 7bf4154cd5..1b6d072cfe 100644 --- a/heat/tests/test_software_component.py +++ b/heat/tests/test_software_component.py @@ -14,14 +14,13 @@ import mock import six -from heat.common import exception +from heat.common import exception as exc from heat.common import template_format from heat.engine.resources.software_config import software_component as sc from heat.engine import stack from heat.engine import template from heat.tests import common from heat.tests import utils -from heatclient.exc import HTTPNotFound class SoftwareComponentTest(common.HeatTestCase): @@ -58,11 +57,8 @@ class SoftwareComponentTest(common.HeatTestCase): self.ctx, 'software_component_test_stack', template.Template(self.template)) self.component = self.stack['mysql_component'] - heat = mock.MagicMock() - self.heatclient = mock.MagicMock() - self.component.heat = heat - heat.return_value = self.heatclient - self.software_configs = self.heatclient.software_configs + self.rpc_client = mock.MagicMock() + self.component._rpc_client = self.rpc_client def test_resource_mapping(self): mapping = sc.resource_mapping() @@ -72,10 +68,9 @@ class SoftwareComponentTest(common.HeatTestCase): self.assertIsInstance(self.component, sc.SoftwareComponent) def test_handle_create(self): - value = mock.MagicMock() config_id = 'c8a19429-7fde-47ea-a42f-40045488226c' - value.id = config_id - self.software_configs.create.return_value = value + value = {'id': config_id} + self.rpc_client.create_software_config.return_value = value self.component.handle_create() self.assertEqual(config_id, self.component.resource_id) @@ -84,9 +79,9 @@ class SoftwareComponentTest(common.HeatTestCase): self.assertIsNone(self.component.handle_delete()) config_id = 'c8a19429-7fde-47ea-a42f-40045488226c' self.component.resource_id = config_id - self.software_configs.delete.return_value = None + self.rpc_client.delete_software_config.return_value = None self.assertIsNone(self.component.handle_delete()) - self.software_configs.delete.side_effect = HTTPNotFound() + self.rpc_client.delete_software_config.side_effect = exc.NotFound self.assertIsNone(self.component.handle_delete()) def test_resolve_attribute(self): @@ -94,14 +89,13 @@ class SoftwareComponentTest(common.HeatTestCase): self.component.resource_id = None self.assertIsNone(self.component._resolve_attribute('configs')) self.component.resource_id = 'c8a19429-7fde-47ea-a42f-40045488226c' - value = mock.MagicMock() configs = self.\ template['resources']['mysql_component']['properties']['configs'] # configs list is stored in 'config' property of SoftwareConfig - value.config = {'configs': configs} - self.software_configs.get.return_value = value + value = {'config': {'configs': configs}} + self.rpc_client.show_software_config.return_value = value self.assertEqual(configs, self.component._resolve_attribute('configs')) - self.software_configs.get.side_effect = HTTPNotFound() + self.rpc_client.show_software_config.side_effect = exc.NotFound self.assertIsNone(self.component._resolve_attribute('configs')) @@ -160,7 +154,7 @@ class SoftwareComponentValidationTest(common.HeatTestCase): echo CREATE $foo tool: script ''', - err=exception.StackValidationFailed, + err=exc.StackValidationFailed, err_msg='Unknown Property config') ), ( @@ -172,7 +166,7 @@ class SoftwareComponentValidationTest(common.HeatTestCase): inputs: - name: foo ''', - err=exception.StackValidationFailed, + err=exc.StackValidationFailed, err_msg='Property configs not assigned') ), # do not test until bug #1350840 @@ -199,7 +193,7 @@ class SoftwareComponentValidationTest(common.HeatTestCase): config: #!/bin/bash tool: script ''', - err=exception.StackValidationFailed, + err=exc.StackValidationFailed, err_msg='is not a list') ), ( @@ -213,7 +207,7 @@ class SoftwareComponentValidationTest(common.HeatTestCase): config: #!/bin/bash tool: script ''', - err=exception.StackValidationFailed, + err=exc.StackValidationFailed, err_msg='actions length (0) is out of range ' '(min: 1, max: None)') ), @@ -231,7 +225,7 @@ class SoftwareComponentValidationTest(common.HeatTestCase): config: #!/bin/bash tool: script ''', - err=exception.StackValidationFailed, + err=exc.StackValidationFailed, err_msg='Defining more than one configuration for the same ' 'action in SoftwareComponent "component" is not ' 'allowed.') @@ -250,7 +244,7 @@ class SoftwareComponentValidationTest(common.HeatTestCase): config: #!/bin/bash tool: script ''', - err=exception.StackValidationFailed, + err=exc.StackValidationFailed, err_msg='Defining more than one configuration for the same ' 'action in SoftwareComponent "component" is not ' 'allowed.') @@ -272,11 +266,7 @@ class SoftwareComponentValidationTest(common.HeatTestCase): self.ctx, 'software_component_test_stack', template.Template(self.template)) self.component = self.stack['component'] - heat = mock.MagicMock() - self.heatclient = mock.MagicMock() - self.component.heat = heat - heat.return_value = self.heatclient - self.software_configs = self.heatclient.software_configs + self.component._rpc_client = mock.MagicMock() def test_properties_schema(self): if self.err: diff --git a/heat/tests/test_software_config.py b/heat/tests/test_software_config.py index 3e6a9effd2..b2a62a3819 100644 --- a/heat/tests/test_software_config.py +++ b/heat/tests/test_software_config.py @@ -11,9 +11,9 @@ # License for the specific language governing permissions and limitations # under the License. -from heatclient.exc import HTTPNotFound import mock +from heat.common import exception as exc from heat.engine import parser from heat.engine.resources.software_config import software_config as sc from heat.engine import template @@ -43,11 +43,8 @@ class SoftwareConfigTest(common.HeatTestCase): 'Properties': self.properties }}})) self.config = self.stack['config_mysql'] - heat = mock.MagicMock() - self.heatclient = mock.MagicMock() - self.config.heat = heat - heat.return_value = self.heatclient - self.software_configs = self.heatclient.software_configs + self.rpc_client = mock.MagicMock() + self.config._rpc_client = self.rpc_client def test_resource_mapping(self): mapping = sc.resource_mapping() @@ -57,10 +54,9 @@ class SoftwareConfigTest(common.HeatTestCase): self.assertIsInstance(self.config, sc.SoftwareConfig) def test_handle_create(self): - value = mock.MagicMock() config_id = 'c8a19429-7fde-47ea-a42f-40045488226c' - value.id = config_id - self.software_configs.create.return_value = value + value = {'id': config_id} + self.rpc_client.create_software_config.return_value = value self.config.handle_create() self.assertEqual(config_id, self.config.resource_id) @@ -69,9 +65,9 @@ class SoftwareConfigTest(common.HeatTestCase): self.assertIsNone(self.config.handle_delete()) config_id = 'c8a19429-7fde-47ea-a42f-40045488226c' self.config.resource_id = config_id - self.software_configs.delete.return_value = None + self.rpc_client.delete_software_config.return_value = None self.assertIsNone(self.config.handle_delete()) - self.software_configs.delete.side_effect = HTTPNotFound() + self.rpc_client.delete_software_config.side_effect = exc.NotFound self.assertIsNone(self.config.handle_delete()) def test_resolve_attribute(self): @@ -79,10 +75,9 @@ class SoftwareConfigTest(common.HeatTestCase): self.config.resource_id = None self.assertIsNone(self.config._resolve_attribute('config')) self.config.resource_id = 'c8a19429-7fde-47ea-a42f-40045488226c' - value = mock.MagicMock() - value.config = '#!/bin/bash' - self.software_configs.get.return_value = value + value = {'config': '#!/bin/bash'} + self.rpc_client.show_software_config.return_value = value self.assertEqual( '#!/bin/bash', self.config._resolve_attribute('config')) - self.software_configs.get.side_effect = HTTPNotFound() + self.rpc_client.show_software_config.side_effect = exc.NotFound self.assertEqual(None, self.config._resolve_attribute('config')) diff --git a/heat/tests/test_software_deployment.py b/heat/tests/test_software_deployment.py index 11db5081be..ba9b3a14da 100644 --- a/heat/tests/test_software_deployment.py +++ b/heat/tests/test_software_deployment.py @@ -17,7 +17,7 @@ import copy import mock import six -from heat.common import exception +from heat.common import exception as exc from heat.common.i18n import _ from heat.engine import parser from heat.engine.resources.software_config import software_deployment as sd @@ -117,10 +117,13 @@ class SoftwareDeploymentTest(common.HeatTestCase): get_signed_url.return_value = 'http://192.0.2.2/signed_url' self.deployment = self.stack['deployment_mysql'] + + self.rpc_client = mock.MagicMock() + self.deployment._rpc_client = self.rpc_client + heat = mock.MagicMock() self.deployment.heat = heat self.deployments = heat.return_value.software_deployments - self.software_configs = heat.return_value.software_configs def test_validate(self): template = dict(self.template_with_server) @@ -138,7 +141,7 @@ class SoftwareDeploymentTest(common.HeatTestCase): props['user_data_format'] = 'RAW' self._create_stack(template) sd = self.deployment - err = self.assertRaises(exception.StackValidationFailed, sd.validate) + err = self.assertRaises(exc.StackValidationFailed, sd.validate) self.assertEqual("Resource server's property " "user_data_format should be set to " "SOFTWARE_CONFIG since there are " @@ -149,7 +152,6 @@ class SoftwareDeploymentTest(common.HeatTestCase): self.assertIsInstance(self.deployment, sd.SoftwareDeployment) def mock_software_config(self): - sc = mock.MagicMock() config = { 'id': '48e8ade1-9196-42d5-89a2-f709fde42632', 'group': 'Test::Group', @@ -167,14 +169,10 @@ class SoftwareDeploymentTest(common.HeatTestCase): }], 'outputs': [], } - sc.to_dict.return_value = config - sc.group = 'Test::Group' - sc.config = config['config'] - self.software_configs.get.return_value = sc - return sc + self.rpc_client.show_software_config.return_value = config + return config def mock_software_component(self): - sc = mock.MagicMock() config = { 'id': '48e8ade1-9196-42d5-89a2-f709fde42632', 'group': 'component', @@ -220,16 +218,12 @@ class SoftwareDeploymentTest(common.HeatTestCase): }], 'outputs': [], } - sc.to_dict.return_value = config - sc.group = 'component' - sc.config = config['config'] - self.software_configs.get.return_value = sc - return sc + self.rpc_client.show_software_config.return_value = config + return config def mock_derived_software_config(self): - sc = mock.MagicMock() - sc.id = '9966c8e7-bc9c-42de-aa7d-f2447a952cb2' - self.software_configs.create.return_value = sc + sc = {'id': '9966c8e7-bc9c-42de-aa7d-f2447a952cb2'} + self.rpc_client.create_software_config.return_value = sc return sc def mock_deployment(self): @@ -290,11 +284,11 @@ class SoftwareDeploymentTest(common.HeatTestCase): }], 'options': {}, 'outputs': [] - }, self.software_configs.create.call_args[1]) + }, self.rpc_client.create_software_config.call_args[1]) self.assertEqual( {'action': 'CREATE', - 'config_id': derived_sc.id, + 'config_id': derived_sc['id'], 'server_id': '9f1f0e00-05d2-4ca5-8602-95021f19c9d0', 'stack_user_project_id': '65728b74-cfe7-4f17-9c15-11d4f686e591', 'status': 'COMPLETE', @@ -381,11 +375,11 @@ class SoftwareDeploymentTest(common.HeatTestCase): }], 'options': {}, 'outputs': [] - }, self.software_configs.create.call_args[1]) + }, self.rpc_client.create_software_config.call_args[1]) self.assertEqual( {'action': 'CREATE', - 'config_id': derived_sc.id, + 'config_id': derived_sc['id'], 'server_id': '9f1f0e00-05d2-4ca5-8602-95021f19c9d0', 'stack_user_project_id': '65728b74-cfe7-4f17-9c15-11d4f686e591', 'status': 'COMPLETE', @@ -404,7 +398,7 @@ class SoftwareDeploymentTest(common.HeatTestCase): args = self.deployments.create.call_args[1] self.assertEqual( {'action': 'CREATE', - 'config_id': derived_sc.id, + 'config_id': derived_sc['id'], 'server_id': '9f1f0e00-05d2-4ca5-8602-95021f19c9d0', 'stack_user_project_id': '65728b74-cfe7-4f17-9c15-11d4f686e591', 'status': 'IN_PROGRESS', @@ -449,7 +443,7 @@ class SoftwareDeploymentTest(common.HeatTestCase): sd.status = self.deployment.FAILED sd.status_reason = 'something wrong' err = self.assertRaises( - exception.Error, self.deployment.check_create_complete, sd) + exc.Error, self.deployment.check_create_complete, sd) self.assertEqual( 'Deployment to server failed: something wrong', six.text_type(err)) @@ -479,7 +473,7 @@ class SoftwareDeploymentTest(common.HeatTestCase): args = sd.update.call_args[1] self.assertEqual({ 'action': 'DELETE', - 'config_id': derived_sc.id, + 'config_id': derived_sc['id'], 'server_id': '9f1f0e00-05d2-4ca5-8602-95021f19c9d0', 'stack_user_project_id': '65728b74-cfe7-4f17-9c15-11d4f686e591', 'status': 'IN_PROGRESS', @@ -499,14 +493,15 @@ class SoftwareDeploymentTest(common.HeatTestCase): self.mock_software_config() derived_sc = self.mock_derived_software_config() sd = self.mock_deployment() - sd.config_id = derived_sc.id + sd.config_id = derived_sc['id'] self.deployments.get.return_value = sd sd.delete.side_effect = HTTPNotFound() - self.software_configs.delete.side_effect = HTTPNotFound() + self.rpc_client.delete_software_config.side_effect = exc.NotFound self.assertIsNone(self.deployment.handle_delete()) self.assertEqual( - (derived_sc.id,), self.software_configs.delete.call_args[0]) + (self.ctx, derived_sc['id']), + self.rpc_client.delete_software_config.call_args[0]) def test_handle_delete_none(self): self._create_stack(self.template) @@ -539,13 +534,14 @@ class SoftwareDeploymentTest(common.HeatTestCase): self.deployment.handle_update( json_snippet=snippet, tmpl_diff=None, prop_diff=prop_diff) self.assertEqual( - (config_id,), self.software_configs.get.call_args[0]) + (self.ctx, config_id), + self.rpc_client.show_software_config.call_args[0]) args = self.deployments.get.call_args[0] self.assertEqual(1, len(args)) self.assertIn(sd.id, args) args = sd.update.call_args[1] - self.assertEqual(derived_sc.id, args['config_id']) + self.assertEqual(derived_sc['id'], args['config_id']) def test_handle_suspend_resume(self): self._create_stack(self.template_delete_suspend_resume) @@ -564,7 +560,7 @@ class SoftwareDeploymentTest(common.HeatTestCase): args = sd.update.call_args[1] self.assertEqual({ 'action': 'SUSPEND', - 'config_id': derived_sc.id, + 'config_id': derived_sc['id'], 'server_id': '9f1f0e00-05d2-4ca5-8602-95021f19c9d0', 'stack_user_project_id': '65728b74-cfe7-4f17-9c15-11d4f686e591', 'status': 'IN_PROGRESS', @@ -583,7 +579,7 @@ class SoftwareDeploymentTest(common.HeatTestCase): args = sd.update.call_args[1] self.assertEqual({ 'action': 'RESUME', - 'config_id': derived_sc.id, + 'config_id': derived_sc['id'], 'server_id': '9f1f0e00-05d2-4ca5-8602-95021f19c9d0', 'stack_user_project_id': '65728b74-cfe7-4f17-9c15-11d4f686e591', 'status': 'IN_PROGRESS', @@ -599,16 +595,18 @@ class SoftwareDeploymentTest(common.HeatTestCase): def test_handle_signal_ok_zero(self): self._create_stack(self.template) sd = mock.MagicMock() - sc = mock.MagicMock() - sc.outputs = [{'name': 'foo'}, - {'name': 'foo2'}, - {'name': 'failed', - 'error_output': True}] + sc = { + 'outputs': [ + {'name': 'foo'}, + {'name': 'foo2'}, + {'name': 'failed', 'error_output': True} + ] + } sd.output_values = {} sd.status = self.deployment.IN_PROGRESS sd.update.return_value = None self.deployments.get.return_value = sd - self.software_configs.get.return_value = sc + self.rpc_client.show_software_config.return_value = sc details = { 'foo': 'bar', 'deploy_status_code': 0 @@ -630,16 +628,18 @@ class SoftwareDeploymentTest(common.HeatTestCase): def test_handle_signal_ok_str_zero(self): self._create_stack(self.template) sd = mock.MagicMock() - sc = mock.MagicMock() - sc.outputs = [{'name': 'foo'}, - {'name': 'foo2'}, - {'name': 'failed', - 'error_output': True}] + sc = { + 'outputs': [ + {'name': 'foo'}, + {'name': 'foo2'}, + {'name': 'failed', 'error_output': True} + ] + } sd.output_values = {} sd.status = self.deployment.IN_PROGRESS sd.update.return_value = None self.deployments.get.return_value = sd - self.software_configs.get.return_value = sc + self.rpc_client.show_software_config.return_value = sc details = { 'foo': 'bar', 'deploy_status_code': '0' @@ -661,16 +661,18 @@ class SoftwareDeploymentTest(common.HeatTestCase): def test_handle_signal_failed(self): self._create_stack(self.template) sd = mock.MagicMock() - sc = mock.MagicMock() - sc.outputs = [{'name': 'foo'}, - {'name': 'foo2'}, - {'name': 'failed', - 'error_output': True}] + sc = { + 'outputs': [ + {'name': 'foo'}, + {'name': 'foo2'}, + {'name': 'failed', 'error_output': True} + ] + } sd.output_values = {} sd.status = self.deployment.IN_PROGRESS sd.update.return_value = None self.deployments.get.return_value = sd - self.software_configs.get.return_value = sc + self.rpc_client.show_software_config.return_value = sc details = {'failed': 'no enough memory found.'} ret = self.deployment.handle_signal(details) self.assertEqual('deployment failed', ret) @@ -760,7 +762,7 @@ class SoftwareDeploymentTest(common.HeatTestCase): sd.outputs = [] sd.output_values = {'foo': 'bar'} err = self.assertRaises( - exception.InvalidTemplateAttribute, + exc.InvalidTemplateAttribute, self.deployment.FnGetAtt, 'foo2') self.assertEqual( 'The Referenced Attribute (deployment_mysql foo2) is incorrect.', diff --git a/heat/tests/test_structured_config.py b/heat/tests/test_structured_config.py index 87e6e2d033..c0645b1436 100644 --- a/heat/tests/test_structured_config.py +++ b/heat/tests/test_structured_config.py @@ -44,9 +44,8 @@ class StructuredConfigTestJSON(common.HeatTestCase): self.ctx, 'software_config_test_stack', template.Template(self.template)) self.config = self.stack['config_mysql'] - heat = mock.MagicMock() - self.config.heat = heat - self.software_configs = heat.return_value.software_configs + self.rpc_client = mock.MagicMock() + self.config._rpc_client = self.rpc_client def test_resource_mapping(self): mapping = sc.resource_mapping() @@ -60,13 +59,12 @@ class StructuredConfigTestJSON(common.HeatTestCase): self.assertIsInstance(self.config, sc.StructuredConfig) def test_handle_create(self): - stc = mock.MagicMock() config_id = 'c8a19429-7fde-47ea-a42f-40045488226c' - stc.id = config_id - self.software_configs.create.return_value = stc + value = {'id': config_id} + self.rpc_client.create_software_config.return_value = value self.config.handle_create() self.assertEqual(config_id, self.config.resource_id) - kwargs = self.software_configs.create.call_args[1] + kwargs = self.rpc_client.create_software_config.call_args[1] self.assertEqual(self.stored_config, kwargs['config'])