From 7ef1344d0a978950035a17ec3fd8746dd57a2392 Mon Sep 17 00:00:00 2001 From: Steven Hardy Date: Fri, 14 Jun 2013 11:02:09 +0100 Subject: [PATCH] Convert Resource to separate action/status Next step in decoupling action/status This adjusts the Resource DB columns, model and class to be consistent with Event, and split action/status. This also modifies the both APIs to join the action/status to avoid changing the API (we can't change the CFN one anyway and it's desirable to avoid breaking compatibility with the ReST API, or needing a version bump for this simple change) Change-Id: I02b56eb14045a058e67b9764d386530d555c339e --- heat/api/cfn/v1/stacks.py | 25 +++-- heat/api/openstack/v1/events.py | 12 ++- heat/api/openstack/v1/resources.py | 12 ++- .../versions/019_resource_action_status.py | 42 ++++++++ heat/db/sqlalchemy/models.py | 5 +- heat/engine/api.py | 5 +- heat/engine/parser.py | 11 +- heat/engine/resource.py | 102 ++++++++++-------- heat/engine/resources/autoscaling.py | 4 +- heat/engine/resources/volume.py | 4 +- heat/engine/template.py | 8 +- heat/tests/test_api_cfn_v1.py | 73 ++----------- heat/tests/test_api_openstack_v1.py | 23 ++-- heat/tests/test_autoscaling.py | 5 +- heat/tests/test_cw_alarm.py | 3 +- heat/tests/test_dbinstance.py | 2 +- heat/tests/test_eip.py | 5 +- heat/tests/test_engine_service.py | 7 +- heat/tests/test_instance.py | 6 +- heat/tests/test_instance_group.py | 4 +- heat/tests/test_loadbalancer.py | 2 +- heat/tests/test_metadata_refresh.py | 2 +- heat/tests/test_parser.py | 34 +++--- heat/tests/test_quantum.py | 42 ++++---- heat/tests/test_resource.py | 69 ++++++++---- heat/tests/test_s3.py | 4 +- heat/tests/test_security_group.py | 6 +- heat/tests/test_swift.py | 4 +- heat/tests/test_user.py | 41 ++++--- heat/tests/test_volume.py | 12 +-- heat/tests/test_vpc.py | 10 +- heat/tests/test_waitcondition.py | 30 +++--- 32 files changed, 331 insertions(+), 283 deletions(-) create mode 100644 heat/db/sqlalchemy/migrate_repo/versions/019_resource_action_status.py diff --git a/heat/api/cfn/v1/stacks.py b/heat/api/cfn/v1/stacks.py index 7d7a27f3..21966d05 100644 --- a/heat/api/cfn/v1/stacks.py +++ b/heat/api/cfn/v1/stacks.py @@ -460,7 +460,6 @@ class StackController(object): engine_api.EVENT_RES_NAME: 'LogicalResourceId', engine_api.EVENT_RES_PHYSICAL_ID: 'PhysicalResourceId', engine_api.EVENT_RES_PROPERTIES: 'ResourceProperties', - engine_api.EVENT_RES_STATUS: 'ResourceStatus', engine_api.EVENT_RES_STATUS_DATA: 'ResourceStatusReason', engine_api.EVENT_RES_TYPE: 'ResourceType', engine_api.EVENT_STACK_ID: 'StackId', @@ -471,10 +470,7 @@ class StackController(object): result = api_utils.reformat_dict_keys(keymap, e) action = e[engine_api.EVENT_RES_ACTION] status = e[engine_api.EVENT_RES_STATUS] - if action and status: - result['ResourceStatus'] = '_'.join((action, status)) - else: - result['ResourceStatus'] = status + result['ResourceStatus'] = '_'.join((action, status)) result['ResourceProperties'] = json.dumps(result[ 'ResourceProperties']) @@ -493,6 +489,12 @@ class StackController(object): return api_utils.format_response('DescribeStackEvents', {'StackEvents': result}) + @staticmethod + def _resource_status(res): + action = res[engine_api.RES_ACTION] + status = res[engine_api.RES_STATUS] + return '_'.join((action, status)) + def describe_stack_resource(self, req): """ Implements the DescribeStackResource API action @@ -510,7 +512,6 @@ class StackController(object): engine_api.RES_NAME: 'LogicalResourceId', engine_api.RES_METADATA: 'Metadata', engine_api.RES_PHYSICAL_ID: 'PhysicalResourceId', - engine_api.RES_STATUS: 'ResourceStatus', engine_api.RES_STATUS_DATA: 'ResourceStatusReason', engine_api.RES_TYPE: 'ResourceType', engine_api.RES_STACK_ID: 'StackId', @@ -519,6 +520,8 @@ class StackController(object): result = api_utils.reformat_dict_keys(keymap, r) + result['ResourceStatus'] = self._resource_status(r) + return self._id_format(result) con = req.context @@ -564,7 +567,6 @@ class StackController(object): engine_api.RES_DESCRIPTION: 'Description', engine_api.RES_NAME: 'LogicalResourceId', engine_api.RES_PHYSICAL_ID: 'PhysicalResourceId', - engine_api.RES_STATUS: 'ResourceStatus', engine_api.RES_STATUS_DATA: 'ResourceStatusReason', engine_api.RES_TYPE: 'ResourceType', engine_api.RES_STACK_ID: 'StackId', @@ -574,6 +576,8 @@ class StackController(object): result = api_utils.reformat_dict_keys(keymap, r) + result['ResourceStatus'] = self._resource_status(r) + return self._id_format(result) con = req.context @@ -618,12 +622,15 @@ class StackController(object): engine_api.RES_UPDATED_TIME: 'LastUpdatedTimestamp', engine_api.RES_NAME: 'LogicalResourceId', engine_api.RES_PHYSICAL_ID: 'PhysicalResourceId', - engine_api.RES_STATUS: 'ResourceStatus', engine_api.RES_STATUS_DATA: 'ResourceStatusReason', engine_api.RES_TYPE: 'ResourceType', } - return api_utils.reformat_dict_keys(keymap, r) + result = api_utils.reformat_dict_keys(keymap, r) + + result['ResourceStatus'] = self._resource_status(r) + + return result con = req.context diff --git a/heat/api/openstack/v1/events.py b/heat/api/openstack/v1/events.py index 651b2e14..eab9e52b 100644 --- a/heat/api/openstack/v1/events.py +++ b/heat/api/openstack/v1/events.py @@ -29,7 +29,6 @@ summary_keys = [ engine_api.EVENT_ID, engine_api.EVENT_TIMESTAMP, engine_api.EVENT_RES_NAME, - engine_api.EVENT_RES_ACTION, engine_api.EVENT_RES_STATUS, engine_api.EVENT_RES_STATUS_DATA, engine_api.EVENT_RES_PHYSICAL_ID, @@ -51,9 +50,16 @@ def format_event(req, event, keys=None): 'resource'), util.make_link(req, identity.stack(), 'stack')]) - elif (key == engine_api.EVENT_STACK_ID or - key == engine_api.EVENT_STACK_NAME): + elif key in (engine_api.EVENT_STACK_ID, engine_api.EVENT_STACK_NAME, + engine_api.EVENT_RES_ACTION): return + elif (key == engine_api.EVENT_RES_STATUS and + engine_api.EVENT_RES_ACTION in event): + # To avoid breaking API compatibility, we join RES_ACTION + # and RES_STATUS, so the API format doesn't expose the + # internal split of state into action/status + yield (key, '_'.join((event[engine_api.EVENT_RES_ACTION], value))) + else: yield (key, value) diff --git a/heat/api/openstack/v1/resources.py b/heat/api/openstack/v1/resources.py index ca31516f..e5b65b60 100644 --- a/heat/api/openstack/v1/resources.py +++ b/heat/api/openstack/v1/resources.py @@ -23,7 +23,7 @@ from heat.rpc import client as rpc_client import heat.openstack.common.rpc.common as rpc_common -def format_resource(req, stack, keys=[]): +def format_resource(req, res, keys=[]): include_key = lambda k: k in keys if keys else True def transform(key, value): @@ -35,15 +35,21 @@ def format_resource(req, stack, keys=[]): yield ('links', [util.make_link(req, identity), util.make_link(req, identity.stack(), 'stack')]) elif (key == engine_api.RES_STACK_NAME or - key == engine_api.RES_STACK_ID): + key == engine_api.RES_STACK_ID or + key == engine_api.RES_ACTION): return elif (key == engine_api.RES_METADATA): return + elif (key == engine_api.RES_STATUS and engine_api.RES_ACTION in res): + # To avoid breaking API compatibility, we join RES_ACTION + # and RES_STATUS, so the API format doesn't expose the + # internal split of state into action/status + yield (key, '_'.join((res[engine_api.RES_ACTION], value))) else: yield (key, value) return dict(itertools.chain.from_iterable( - transform(k, v) for k, v in stack.items())) + transform(k, v) for k, v in res.items())) class ResourceController(object): diff --git a/heat/db/sqlalchemy/migrate_repo/versions/019_resource_action_status.py b/heat/db/sqlalchemy/migrate_repo/versions/019_resource_action_status.py new file mode 100644 index 00000000..857b9a84 --- /dev/null +++ b/heat/db/sqlalchemy/migrate_repo/versions/019_resource_action_status.py @@ -0,0 +1,42 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from sqlalchemy import * +from migrate import * + + +def upgrade(migrate_engine): + meta = MetaData() + meta.bind = migrate_engine + + resource = Table('resource', meta, autoload=True) + # Align the current state/state_description with the + # action/status now used in the event table + Column('action', String(length=255, + convert_unicode=False, + assert_unicode=None, + unicode_error=None, + _warn_on_bytestring=False)).create(resource) + resource.c.state.alter(name='status') + resource.c.state_description.alter(name='status_reason') + + +def downgrade(migrate_engine): + meta = MetaData() + meta.bind = migrate_engine + + resource = Table('resource', meta, autoload=True) + resource.c.status.drop() + resource.c.status.alter(name='state') + resource.c.status_reason.alter(name='state_description') diff --git a/heat/db/sqlalchemy/models.py b/heat/db/sqlalchemy/models.py index cda85c36..bffe24cb 100644 --- a/heat/db/sqlalchemy/models.py +++ b/heat/db/sqlalchemy/models.py @@ -212,10 +212,11 @@ class Resource(BASE, HeatBase): __tablename__ = 'resource' id = Column(String, primary_key=True, default=uuidutils.generate_uuid) - state = Column('state', String) + action = Column('action', String) + status = Column('status', String) name = Column('name', String, nullable=False) nova_instance = Column('nova_instance', String) - state_description = Column('state_description', String) + status_reason = Column('status_reason', String) # odd name as "metadata" is reserved rsrc_metadata = Column('rsrc_metadata', Json) diff --git a/heat/engine/api.py b/heat/engine/api.py index bf9ddd74..ad338b71 100644 --- a/heat/engine/api.py +++ b/heat/engine/api.py @@ -101,8 +101,9 @@ def format_stack_resource(resource, detail=True): RES_NAME: resource.name, RES_PHYSICAL_ID: resource.resource_id or '', RES_METADATA: resource.metadata, - RES_STATUS: resource.state, - RES_STATUS_DATA: resource.state_description, + RES_ACTION: resource.action or '', + RES_STATUS: resource.status or '', + RES_STATUS_DATA: resource.status_reason, RES_TYPE: resource.t['Type'], RES_ID: dict(resource.identifier()), RES_STACK_ID: dict(resource.stack.identifier()), diff --git a/heat/engine/parser.py b/heat/engine/parser.py index 974b8eb1..61083a6f 100644 --- a/heat/engine/parser.py +++ b/heat/engine/parser.py @@ -231,10 +231,10 @@ class Stack(object): ''' for r in self.resources.values(): if r.state in ( - r.CREATE_IN_PROGRESS, - r.CREATE_COMPLETE, - r.UPDATE_IN_PROGRESS, - r.UPDATE_COMPLETE) and r.FnGetRefId() == refid: + (r.CREATE, r.IN_PROGRESS), + (r.CREATE, r.COMPLETE), + (r.UPDATE, r.IN_PROGRESS), + (r.UPDATE, r.COMPLETE)) and r.FnGetRefId() == refid: return r def validate(self): @@ -528,7 +528,8 @@ class Stack(object): logger.exception('create') failed = True else: - res.state_set(res.CREATE_FAILED, 'Resource restart aborted') + res.state_set(res.CREATE, res.FAILED, + 'Resource restart aborted') # TODO(asalkeld) if any of this fails we Should # restart the whole stack diff --git a/heat/engine/resource.py b/heat/engine/resource.py index cc5f560f..f4da3972 100644 --- a/heat/engine/resource.py +++ b/heat/engine/resource.py @@ -96,16 +96,11 @@ class Metadata(object): class Resource(object): - # Status strings - CREATE_IN_PROGRESS = 'IN_PROGRESS' - CREATE_FAILED = 'CREATE_FAILED' - CREATE_COMPLETE = 'CREATE_COMPLETE' - DELETE_IN_PROGRESS = 'DELETE_IN_PROGRESS' - DELETE_FAILED = 'DELETE_FAILED' - DELETE_COMPLETE = 'DELETE_COMPLETE' - UPDATE_IN_PROGRESS = 'UPDATE_IN_PROGRESS' - UPDATE_FAILED = 'UPDATE_FAILED' - UPDATE_COMPLETE = 'UPDATE_COMPLETE' + ACTIONS = (CREATE, DELETE, UPDATE, ROLLBACK + ) = ('CREATE', 'DELETE', 'UPDATE', 'ROLLBACK') + + STATUSES = (IN_PROGRESS, FAILED, COMPLETE + ) = ('IN_PROGRESS', 'FAILED', 'COMPLETE') # If True, this resource must be created before it can be referenced. strict_dependency = True @@ -153,13 +148,15 @@ class Resource(object): name, stack.id) if resource: self.resource_id = resource.nova_instance - self.state = resource.state - self.state_description = resource.state_description + self.action = resource.action + self.status = resource.status + self.status_reason = resource.status_reason self.id = resource.id else: self.resource_id = None - self.state = None - self.state_description = '' + self.action = None + self.status = None + self.status_reason = '' self.id = None def __eq__(self, other): @@ -314,7 +311,7 @@ class Resource(object): Create the resource. Subclasses should provide a handle_create() method to customise creation. ''' - assert self.state is None, 'Resource create requested in invalid state' + assert None in (self.action, self.status), 'invalid state for create' logger.info('creating %s' % str(self)) @@ -329,7 +326,7 @@ class Resource(object): self.name) try: self.properties.validate() - self.state_set(self.CREATE_IN_PROGRESS) + self.state_set(self.CREATE, self.IN_PROGRESS) create_data = None if callable(getattr(self, 'handle_create', None)): create_data = self.handle_create() @@ -339,16 +336,17 @@ class Resource(object): except Exception as ex: logger.exception('create %s', str(self)) failure = exception.ResourceFailure(ex) - self.state_set(self.CREATE_FAILED, str(failure)) + self.state_set(self.CREATE, self.FAILED, str(failure)) raise failure except: with excutils.save_and_reraise_exception(): try: - self.state_set(self.CREATE_FAILED, 'Creation aborted') + self.state_set(self.CREATE, self.FAILED, + 'Creation aborted') except Exception: logger.exception('Error marking resource as failed') else: - self.state_set(self.CREATE_COMPLETE) + self.state_set(self.CREATE, self.COMPLETE) def check_create_complete(self, create_data): ''' @@ -367,14 +365,15 @@ class Resource(object): ''' assert json_snippet is not None, 'Must specify update json snippet' - if self.state in (self.CREATE_IN_PROGRESS, self.UPDATE_IN_PROGRESS): + if (self.action, self.status) in ((self.CREATE, self.IN_PROGRESS), + (self.UPDATE, self.IN_PROGRESS)): raise exception.ResourceFailure(Exception( 'Resource update already requested')) logger.info('updating %s' % str(self)) try: - self.state_set(self.UPDATE_IN_PROGRESS) + self.state_set(self.UPDATE, self.IN_PROGRESS) properties = Properties(self.properties_schema, json_snippet.get('Properties', {}), self.stack.resolve_runtime_data, @@ -390,11 +389,11 @@ class Resource(object): except Exception as ex: logger.exception('update %s : %s' % (str(self), str(ex))) failure = exception.ResourceFailure(ex) - self.state_set(self.UPDATE_FAILED, str(failure)) + self.state_set(self.UPDATE, self.FAILED, str(failure)) raise failure else: self.t = self.stack.resolve_static_data(json_snippet) - self.state_set(self.UPDATE_COMPLETE) + self.state_set(self.UPDATE, self.COMPLETE) def physical_resource_name(self): return '%s-%s' % (self.stack.name, self.name) @@ -421,12 +420,12 @@ class Resource(object): Delete the resource. Subclasses should provide a handle_delete() method to customise deletion. ''' - if self.state == self.DELETE_COMPLETE: + if (self.action, self.status) == (self.DELETE, self.COMPLETE): return - if self.state == self.DELETE_IN_PROGRESS: + if (self.action, self.status) == (self.DELETE, self.IN_PROGRESS): raise exception.Error('Resource deletion already in progress') # No need to delete if the resource has never been created - if self.state is None: + if self.action is None: return initial_state = self.state @@ -434,7 +433,7 @@ class Resource(object): logger.info('deleting %s' % str(self)) try: - self.state_set(self.DELETE_IN_PROGRESS) + self.state_set(self.DELETE, self.IN_PROGRESS) deletion_policy = self.t.get('DeletionPolicy', 'Delete') if deletion_policy == 'Delete': @@ -446,16 +445,17 @@ class Resource(object): except Exception as ex: logger.exception('Delete %s', str(self)) failure = exception.ResourceFailure(ex) - self.state_set(self.DELETE_FAILED, str(failure)) + self.state_set(self.DELETE, self.FAILED, str(failure)) raise failure except: with excutils.save_and_reraise_exception(): try: - self.state_set(self.DELETE_FAILED, 'Deletion aborted') + self.state_set(self.DELETE, self.FAILED, + 'Deletion aborted') except Exception: logger.exception('Error marking resource deletion failed') else: - self.state_set(self.DELETE_COMPLETE) + self.state_set(self.DELETE, self.COMPLETE) def destroy(self): ''' @@ -487,7 +487,9 @@ class Resource(object): def _store(self): '''Create the resource in the database.''' try: - rs = {'state': self.state, + rs = {'action': self.action, + 'status': self.status, + 'status_reason': self.status_reason, 'stack_id': self.stack.id, 'nova_instance': self.resource_id, 'name': self.name, @@ -502,10 +504,10 @@ class Resource(object): except Exception as ex: logger.error('DB error %s' % str(ex)) - def _add_event(self, new_state, reason): + def _add_event(self, action, status, reason): '''Add a state change event to the database.''' ev = event.Event(self.context, self.stack, self, - None, new_state, reason, + action, status, reason, self.resource_id, self.properties) try: @@ -513,15 +515,17 @@ class Resource(object): except Exception as ex: logger.error('DB error %s' % str(ex)) - def _store_or_update(self, new_state, reason): - self.state = new_state - self.state_description = reason + def _store_or_update(self, action, status, reason): + self.action = action + self.status = status + self.status_reason = reason if self.id is not None: try: rs = db_api.resource_get(self.context, self.id) - rs.update_and_save({'state': self.state, - 'state_description': reason, + rs.update_and_save({'action': self.action, + 'status': self.status, + 'status_reason': reason, 'nova_instance': self.resource_id}) self.stack.updated_time = datetime.utcnow() @@ -531,15 +535,27 @@ class Resource(object): # store resource in DB on transition to CREATE_IN_PROGRESS # all other transistions (other than to DELETE_COMPLETE) # should be handled by the update_and_save above.. - elif new_state == self.CREATE_IN_PROGRESS: + elif (action, status) == (self.CREATE, self.IN_PROGRESS): self._store() - def state_set(self, new_state, reason="state changed"): - old_state = self.state - self._store_or_update(new_state, reason) + def state_set(self, action, status, reason="state changed"): + if action not in self.ACTIONS: + raise ValueError("Invalid action %s" % action) + + if status not in self.STATUSES: + raise ValueError("Invalid status %s" % status) + + old_state = (self.action, self.status) + new_state = (action, status) + self._store_or_update(action, status, reason) if new_state != old_state: - self._add_event(new_state, reason) + self._add_event(action, status, reason) + + @property + def state(self): + '''Returns state, tuple of action, status.''' + return (self.action, self.status) def FnGetRefId(self): ''' diff --git a/heat/engine/resources/autoscaling.py b/heat/engine/resources/autoscaling.py index e2bb89a1..a582fd5a 100644 --- a/heat/engine/resources/autoscaling.py +++ b/heat/engine/resources/autoscaling.py @@ -119,8 +119,8 @@ class InstanceGroup(resource.Resource): template, which causes problems for event handling since we can't look up the resources via parser.Stack ''' - def state_set(self, new_state, reason="state changed"): - self._store_or_update(new_state, reason) + def state_set(self, action, status, reason="state changed"): + self._store_or_update(action, status, reason) conf = self.properties['LaunchConfigurationName'] instance_definition = self.stack.t['Resources'][conf] diff --git a/heat/engine/resources/volume.py b/heat/engine/resources/volume.py index 66a78deb..dcbdb6a3 100644 --- a/heat/engine/resources/volume.py +++ b/heat/engine/resources/volume.py @@ -107,8 +107,8 @@ class Volume(resource.Resource): if volume_backups is not None: def handle_snapshot_delete(self, state): - backup = state not in (self.CREATE_FAILED, - self.UPDATE_FAILED) + backup = state not in ((self.CREATE, self.FAILED), + (self.UPDATE, self.FAILED)) return self._delete(backup=backup) def handle_delete(self): diff --git a/heat/engine/template.py b/heat/engine/template.py index 77ca03f2..59207505 100644 --- a/heat/engine/template.py +++ b/heat/engine/template.py @@ -157,10 +157,10 @@ class Template(collections.Mapping): try: r = resources[resource] if r.state in ( - r.CREATE_IN_PROGRESS, - r.CREATE_COMPLETE, - r.UPDATE_IN_PROGRESS, - r.UPDATE_COMPLETE): + (r.CREATE, r.IN_PROGRESS), + (r.CREATE, r.COMPLETE), + (r.UPDATE, r.IN_PROGRESS), + (r.UPDATE, r.COMPLETE)): return r.FnGetAtt(att) except KeyError: raise exception.InvalidTemplateAttribute(resource=resource, diff --git a/heat/tests/test_api_cfn_v1.py b/heat/tests/test_api_cfn_v1.py index 2040854d..cf00633c 100644 --- a/heat/tests/test_api_cfn_v1.py +++ b/heat/tests/test_api_cfn_v1.py @@ -997,67 +997,6 @@ class CfnStackControllerTest(HeatTestCase): self.assertEqual(response, expected) self.m.VerifyAll() - def test_events_list_onlystatus(self): - # Format a dummy request - stack_name = "wordpress" - identity = dict(identifier.HeatIdentifier('t', stack_name, '6')) - params = {'Action': 'DescribeStackEvents', 'StackName': stack_name} - dummy_req = self._dummy_GET_request(params) - - # Stub out the RPC call to the engine with a pre-canned response - engine_resp = [{u'stack_name': u'wordpress', - u'event_time': u'2012-07-23T13:05:39Z', - u'stack_identity': {u'tenant': u't', - u'stack_name': u'wordpress', - u'stack_id': u'6', - u'path': u''}, - u'logical_resource_id': u'WikiDatabase', - u'resource_status_reason': u'state changed', - u'event_identity': - {u'tenant': u't', - u'stack_name': u'wordpress', - u'stack_id': u'6', - u'path': u'/resources/WikiDatabase/events/42'}, - u'resource_action': None, - u'resource_status': u'TEST_IN_PROGRESS', - u'physical_resource_id': None, - u'resource_properties': {u'UserData': u'blah'}, - u'resource_type': u'AWS::EC2::Instance'}] - - self.m.StubOutWithMock(rpc, 'call') - rpc.call(dummy_req.context, self.topic, - {'namespace': None, - 'method': 'identify_stack', - 'args': {'stack_name': stack_name}, - 'version': self.api_version}, None).AndReturn(identity) - rpc.call(dummy_req.context, self.topic, - {'namespace': None, - 'method': 'list_events', - 'args': {'stack_identity': identity}, - 'version': self.api_version}, None).AndReturn(engine_resp) - - self.m.ReplayAll() - - response = self.controller.events_list(dummy_req) - - expected = {'DescribeStackEventsResponse': - {'DescribeStackEventsResult': - {'StackEvents': - [{'EventId': u'42', - 'StackId': u'arn:openstack:heat::t:stacks/wordpress/6', - 'ResourceStatus': u'TEST_IN_PROGRESS', - 'ResourceType': u'AWS::EC2::Instance', - 'Timestamp': u'2012-07-23T13:05:39Z', - 'StackName': u'wordpress', - 'ResourceProperties': - json.dumps({u'UserData': u'blah'}), - 'PhysicalResourceId': None, - 'ResourceStatusReason': u'state changed', - 'LogicalResourceId': u'WikiDatabase'}]}}} - - self.assertEqual(response, expected) - self.m.VerifyAll() - def test_events_list_err_rpcerr(self): stack_name = "wordpress" identity = dict(identifier.HeatIdentifier('t', stack_name, '6')) @@ -1133,7 +1072,8 @@ class CfnStackControllerTest(HeatTestCase): u'stack_name': u'wordpress', u'stack_id': u'6', u'path': u''}, - u'resource_status': u'CREATE_COMPLETE', + u'resource_action': u'CREATE', + u'resource_status': u'COMPLETE', u'physical_resource_id': u'a3455d8c-9f88-404d-a85b-5315293e67de', u'resource_type': u'AWS::EC2::Instance', @@ -1261,7 +1201,8 @@ class CfnStackControllerTest(HeatTestCase): u'stack_name': u'wordpress', u'stack_id': u'6', u'path': u''}, - u'resource_status': u'CREATE_COMPLETE', + u'resource_action': u'CREATE', + u'resource_status': u'COMPLETE', u'physical_resource_id': u'a3455d8c-9f88-404d-a85b-5315293e67de', u'resource_type': u'AWS::EC2::Instance', @@ -1353,7 +1294,8 @@ class CfnStackControllerTest(HeatTestCase): u'stack_name': u'wordpress', u'stack_id': u'6', u'path': u''}, - u'resource_status': u'CREATE_COMPLETE', + u'resource_action': u'CREATE', + u'resource_status': u'COMPLETE', u'physical_resource_id': u'a3455d8c-9f88-404d-a85b-5315293e67de', u'resource_type': u'AWS::EC2::Instance', @@ -1461,7 +1403,8 @@ class CfnStackControllerTest(HeatTestCase): u'stack_name': u'wordpress', u'stack_id': u'6', u'path': u''}, - u'resource_status': u'CREATE_COMPLETE', + u'resource_action': u'CREATE', + u'resource_status': u'COMPLETE', u'physical_resource_id': u'a3455d8c-9f88-404d-a85b-5315293e67de', u'resource_type': u'AWS::EC2::Instance'}] diff --git a/heat/tests/test_api_openstack_v1.py b/heat/tests/test_api_openstack_v1.py index b1e35b03..b4745e0e 100644 --- a/heat/tests/test_api_openstack_v1.py +++ b/heat/tests/test_api_openstack_v1.py @@ -950,7 +950,8 @@ class ResourceControllerTest(ControllerTest, HeatTestCase): u'resource_status_reason': None, u'updated_time': u'2012-07-23T13:06:00Z', u'stack_identity': stack_identity, - u'resource_status': u'CREATE_COMPLETE', + u'resource_action': u'CREATE', + u'resource_status': u'COMPLETE', u'physical_resource_id': u'a3455d8c-9f88-404d-a85b-5315293e67de', u'resource_type': u'AWS::EC2::Instance', @@ -1024,7 +1025,8 @@ class ResourceControllerTest(ControllerTest, HeatTestCase): u'resource_status_reason': None, u'updated_time': u'2012-07-23T13:06:00Z', u'stack_identity': dict(stack_identity), - u'resource_status': u'CREATE_COMPLETE', + u'resource_action': u'CREATE', + u'resource_status': u'COMPLETE', u'physical_resource_id': u'a3455d8c-9f88-404d-a85b-5315293e67de', u'resource_type': u'AWS::EC2::Instance', @@ -1163,7 +1165,8 @@ class ResourceControllerTest(ControllerTest, HeatTestCase): u'resource_status_reason': None, u'updated_time': u'2012-07-23T13:06:00Z', u'stack_identity': dict(stack_identity), - u'resource_status': u'CREATE_COMPLETE', + u'resource_action': u'CREATE', + u'resource_status': u'COMPLETE', u'physical_resource_id': u'a3455d8c-9f88-404d-a85b-5315293e67de', u'resource_type': u'AWS::EC2::Instance', @@ -1281,6 +1284,7 @@ class EventControllerTest(ControllerTest, HeatTestCase): u'logical_resource_id': res_name, u'resource_status_reason': u'state changed', u'event_identity': dict(ev_identity), + u'resource_action': u'CREATE', u'resource_status': u'IN_PROGRESS', u'physical_resource_id': None, u'resource_properties': {u'UserData': u'blah'}, @@ -1293,6 +1297,7 @@ class EventControllerTest(ControllerTest, HeatTestCase): u'logical_resource_id': 'SomeOtherResource', u'resource_status_reason': u'state changed', u'event_identity': dict(ev_identity), + u'resource_action': u'CREATE', u'resource_status': u'IN_PROGRESS', u'physical_resource_id': None, u'resource_properties': {u'UserData': u'blah'}, @@ -1325,7 +1330,7 @@ class EventControllerTest(ControllerTest, HeatTestCase): u'logical_resource_id': res_name, u'resource_status_reason': u'state changed', u'event_time': u'2012-07-23T13:05:39Z', - u'resource_status': u'IN_PROGRESS', + u'resource_status': u'CREATE_IN_PROGRESS', u'physical_resource_id': None, } ] @@ -1354,6 +1359,7 @@ class EventControllerTest(ControllerTest, HeatTestCase): u'logical_resource_id': res_name, u'resource_status_reason': u'state changed', u'event_identity': dict(ev_identity), + u'resource_action': u'CREATE', u'resource_status': u'IN_PROGRESS', u'physical_resource_id': None, u'resource_properties': {u'UserData': u'blah'}, @@ -1385,7 +1391,7 @@ class EventControllerTest(ControllerTest, HeatTestCase): u'logical_resource_id': res_name, u'resource_status_reason': u'state changed', u'event_time': u'2012-07-23T13:05:39Z', - u'resource_status': u'IN_PROGRESS', + u'resource_status': u'CREATE_IN_PROGRESS', u'physical_resource_id': None, } ] @@ -1437,6 +1443,7 @@ class EventControllerTest(ControllerTest, HeatTestCase): u'logical_resource_id': 'SomeOtherResource', u'resource_status_reason': u'state changed', u'event_identity': dict(ev_identity), + u'resource_action': u'CREATE', u'resource_status': u'IN_PROGRESS', u'physical_resource_id': None, u'resource_properties': {u'UserData': u'blah'}, @@ -1483,6 +1490,7 @@ class EventControllerTest(ControllerTest, HeatTestCase): u'logical_resource_id': res_name, u'resource_status_reason': u'state changed', u'event_identity': dict(ev1_identity), + u'resource_action': u'CREATE', u'resource_status': u'IN_PROGRESS', u'physical_resource_id': None, u'resource_properties': {u'UserData': u'blah'}, @@ -1495,7 +1503,8 @@ class EventControllerTest(ControllerTest, HeatTestCase): u'logical_resource_id': res_name, u'resource_status_reason': u'state changed', u'event_identity': dict(ev_identity), - u'resource_status': u'CREATE_COMPLETE', + u'resource_action': u'CREATE', + u'resource_status': u'COMPLETE', u'physical_resource_id': u'a3455d8c-9f88-404d-a85b-5315293e67de', u'resource_properties': {u'UserData': u'blah'}, @@ -1560,6 +1569,7 @@ class EventControllerTest(ControllerTest, HeatTestCase): u'logical_resource_id': res_name, u'resource_status_reason': u'state changed', u'event_identity': dict(ev_identity), + u'resource_action': u'CREATE', u'resource_status': u'IN_PROGRESS', u'physical_resource_id': None, u'resource_properties': {u'UserData': u'blah'}, @@ -1604,6 +1614,7 @@ class EventControllerTest(ControllerTest, HeatTestCase): u'logical_resource_id': 'SomeOtherResourceName', u'resource_status_reason': u'state changed', u'event_identity': dict(ev_identity), + u'resource_action': u'CREATE', u'resource_status': u'IN_PROGRESS', u'physical_resource_id': None, u'resource_properties': {u'UserData': u'blah'}, diff --git a/heat/tests/test_autoscaling.py b/heat/tests/test_autoscaling.py index 16f31cf8..86e4b6aa 100644 --- a/heat/tests/test_autoscaling.py +++ b/heat/tests/test_autoscaling.py @@ -101,7 +101,7 @@ class AutoScalingTest(HeatTestCase): stack) self.assertEqual(None, rsrc.validate()) scheduler.TaskRunner(rsrc.create)() - self.assertEqual(asc.AutoScalingGroup.CREATE_COMPLETE, rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) return rsrc def create_scaling_policy(self, t, stack, resource_name): @@ -111,8 +111,7 @@ class AutoScalingTest(HeatTestCase): self.assertEqual(None, rsrc.validate()) scheduler.TaskRunner(rsrc.create)() - self.assertEqual(asc.ScalingPolicy.CREATE_COMPLETE, - rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) return rsrc def _stub_create(self, num): diff --git a/heat/tests/test_cw_alarm.py b/heat/tests/test_cw_alarm.py index a06f7901..caa341e5 100644 --- a/heat/tests/test_cw_alarm.py +++ b/heat/tests/test_cw_alarm.py @@ -61,8 +61,7 @@ class CloudWatchAlarmTest(HeatTestCase): stack) self.assertEqual(None, rsrc.validate()) scheduler.TaskRunner(rsrc.create)() - self.assertEqual(cloud_watch.CloudWatchAlarm.CREATE_COMPLETE, - rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) return rsrc def test_mem_alarm_high_update_no_replace(self): diff --git a/heat/tests/test_dbinstance.py b/heat/tests/test_dbinstance.py index 1b516673..1a8eaeb7 100644 --- a/heat/tests/test_dbinstance.py +++ b/heat/tests/test_dbinstance.py @@ -67,7 +67,7 @@ class DBInstanceTest(HeatTestCase): stack) self.assertEqual(None, resource.validate()) scheduler.TaskRunner(resource.create)() - self.assertEqual(dbi.DBInstance.CREATE_COMPLETE, resource.state) + self.assertEqual((resource.CREATE, resource.COMPLETE), resource.state) return resource def test_dbinstance(self): diff --git a/heat/tests/test_eip.py b/heat/tests/test_eip.py index 6a810d8b..a710a5a7 100644 --- a/heat/tests/test_eip.py +++ b/heat/tests/test_eip.py @@ -62,7 +62,7 @@ class EIPTest(HeatTestCase): stack) self.assertEqual(None, rsrc.validate()) scheduler.TaskRunner(rsrc.create)() - self.assertEqual(eip.ElasticIp.CREATE_COMPLETE, rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) return rsrc def create_association(self, t, stack, resource_name): @@ -71,8 +71,7 @@ class EIPTest(HeatTestCase): stack) self.assertEqual(None, rsrc.validate()) scheduler.TaskRunner(rsrc.create)() - self.assertEqual(eip.ElasticIpAssociation.CREATE_COMPLETE, - rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) return rsrc def test_eip(self): diff --git a/heat/tests/test_engine_service.py b/heat/tests/test_engine_service.py index f6c42e7d..a6b52d8e 100644 --- a/heat/tests/test_engine_service.py +++ b/heat/tests/test_engine_service.py @@ -219,7 +219,8 @@ class stackCreateTest(HeatTestCase): mox.Replay(get) stack.delete() - self.assertEqual(stack.resources['WebServer'].state, 'DELETE_COMPLETE') + rsrc = stack.resources['WebServer'] + self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state) self.assertEqual(db_api.stack_get(ctx, stack_id), None) self.assertEqual(db_s.status, 'DELETE_COMPLETE') @@ -557,9 +558,9 @@ class stackServiceTest(HeatTestCase): self.assertEqual(ev['resource_properties']['InstanceType'], 'm1.large') - self.assertTrue('resource_action' in ev) + self.assertEqual(ev['resource_action'], 'CREATE') self.assertTrue(ev['resource_status'] in ('IN_PROGRESS', - 'CREATE_COMPLETE')) + 'COMPLETE')) self.assertTrue('resource_status_reason' in ev) self.assertEqual(ev['resource_status_reason'], 'state changed') diff --git a/heat/tests/test_instance.py b/heat/tests/test_instance.py index db1c35c2..e9e63fd6 100644 --- a/heat/tests/test_instance.py +++ b/heat/tests/test_instance.py @@ -239,7 +239,7 @@ class instancesTest(HeatTestCase): instance.delete() self.assertTrue(instance.resource_id is None) - self.assertEqual(instance.state, instance.DELETE_COMPLETE) + self.assertEqual(instance.state, (instance.DELETE, instance.COMPLETE)) self.m.VerifyAll() def test_instance_update_metadata(self): @@ -285,7 +285,7 @@ class instancesTest(HeatTestCase): self.m.ReplayAll() scheduler.TaskRunner(instance.create)() - self.assertEqual(instance.state, instance.CREATE_COMPLETE) + self.assertEqual(instance.state, (instance.CREATE, instance.COMPLETE)) def test_instance_status_hard_reboot(self): self._test_instance_status_not_build_active('HARD_REBOOT') @@ -337,7 +337,7 @@ class instancesTest(HeatTestCase): self.m.ReplayAll() scheduler.TaskRunner(instance.create)() - self.assertEqual(instance.state, instance.CREATE_COMPLETE) + self.assertEqual(instance.state, (instance.CREATE, instance.COMPLETE)) self.m.VerifyAll() diff --git a/heat/tests/test_instance_group.py b/heat/tests/test_instance_group.py index e643cbfc..fc140001 100644 --- a/heat/tests/test_instance_group.py +++ b/heat/tests/test_instance_group.py @@ -80,7 +80,7 @@ class InstanceGroupTest(HeatTestCase): stack) self.assertEqual(None, rsrc.validate()) scheduler.TaskRunner(rsrc.create)() - self.assertEqual(asc.InstanceGroup.CREATE_COMPLETE, rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) return rsrc def test_instance_group(self): @@ -120,7 +120,7 @@ class InstanceGroupTest(HeatTestCase): create = scheduler.TaskRunner(rsrc.create) self.assertRaises(exception.ResourceFailure, create) - self.assertEqual(asc.InstanceGroup.CREATE_FAILED, rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state) self.m.VerifyAll() diff --git a/heat/tests/test_loadbalancer.py b/heat/tests/test_loadbalancer.py index a0907ccd..87286782 100644 --- a/heat/tests/test_loadbalancer.py +++ b/heat/tests/test_loadbalancer.py @@ -94,7 +94,7 @@ class LoadBalancerTest(HeatTestCase): stack) self.assertEqual(None, rsrc.validate()) scheduler.TaskRunner(rsrc.create)() - self.assertEqual(lb.LoadBalancer.CREATE_COMPLETE, rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) return rsrc def test_loadbalancer(self): diff --git a/heat/tests/test_metadata_refresh.py b/heat/tests/test_metadata_refresh.py index 17811032..a44d45f6 100644 --- a/heat/tests/test_metadata_refresh.py +++ b/heat/tests/test_metadata_refresh.py @@ -179,7 +179,7 @@ class MetadataRefreshTest(HeatTestCase): s2 = self.stack.resources['S2'] files = s1.metadata['AWS::CloudFormation::Init']['config']['files'] cont = files['/tmp/random_file']['content'] - self.assertEqual(s2.CREATE_COMPLETE, s2.state) + self.assertEqual((s2.CREATE, s2.COMPLETE), s2.state) self.assertEqual(cont, 's2-ip=1.2.3.5') s1.metadata_update() diff --git a/heat/tests/test_parser.py b/heat/tests/test_parser.py index d628d576..3a57eaf3 100644 --- a/heat/tests/test_parser.py +++ b/heat/tests/test_parser.py @@ -597,13 +597,12 @@ class StackTest(HeatTestCase): self.assertNotEqual(None, resource) self.assertEqual(rsrc, self.stack.resource_by_refid('aaaa')) - rsrc.state = rsrc.DELETE_IN_PROGRESS + rsrc.state_set(rsrc.DELETE, rsrc.IN_PROGRESS) try: self.assertEqual(None, self.stack.resource_by_refid('aaaa')) - self.assertEqual(None, self.stack.resource_by_refid('bbbb')) finally: - rsrc.state = rsrc.CREATE_COMPLETE + rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE) @stack_delete_after def test_update_add(self): @@ -1285,21 +1284,18 @@ class StackTest(HeatTestCase): rsrc.resource_id_set('aaaa') self.assertEqual('AResource', rsrc.FnGetAtt('foo')) - for state in ( - rsrc.CREATE_IN_PROGRESS, - rsrc.CREATE_COMPLETE, - rsrc.UPDATE_IN_PROGRESS, - rsrc.UPDATE_COMPLETE): - rsrc.state = state + for action, status in ( + (rsrc.CREATE, rsrc.IN_PROGRESS), + (rsrc.CREATE, rsrc.COMPLETE), + (rsrc.UPDATE, rsrc.IN_PROGRESS), + (rsrc.UPDATE, rsrc.COMPLETE)): + rsrc.state_set(action, status) self.assertEqual('AResource', self.stack.output('TestOutput')) - for state in ( - rsrc.CREATE_FAILED, - rsrc.DELETE_IN_PROGRESS, - rsrc.DELETE_FAILED, - rsrc.DELETE_COMPLETE, - rsrc.UPDATE_FAILED, - None): - rsrc.state = state + for action, status in ( + (rsrc.CREATE, rsrc.FAILED), + (rsrc.DELETE, rsrc.IN_PROGRESS), + (rsrc.DELETE, rsrc.FAILED), + (rsrc.DELETE, rsrc.COMPLETE), + (rsrc.UPDATE, rsrc.FAILED)): + rsrc.state_set(action, status) self.assertEqual(None, self.stack.output('TestOutput')) - - rsrc.state = rsrc.CREATE_COMPLETE diff --git a/heat/tests/test_quantum.py b/heat/tests/test_quantum.py index fd841201..c0d46d4e 100644 --- a/heat/tests/test_quantum.py +++ b/heat/tests/test_quantum.py @@ -23,8 +23,6 @@ from heat.engine import resource from heat.engine import scheduler from heat.engine.resources.quantum import net from heat.engine.resources.quantum import subnet -from heat.engine.resources.quantum import floatingip -from heat.engine.resources.quantum import port from heat.engine.resources.quantum import router from heat.engine.resources.quantum.quantum import QuantumResource as qr from heat.openstack.common.importutils import try_import @@ -203,7 +201,7 @@ class QuantumNetTest(HeatTestCase): def create_net(self, t, stack, resource_name): rsrc = net.Net('test_net', t['Resources'][resource_name], stack) scheduler.TaskRunner(rsrc.create)() - self.assertEqual(net.Net.CREATE_COMPLETE, rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) return rsrc def test_net(self): @@ -293,7 +291,7 @@ class QuantumNetTest(HeatTestCase): rsrc.handle_update, {}, {}, {}) rsrc.delete() - rsrc.state_set(rsrc.CREATE_COMPLETE, 'to delete again') + rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again') rsrc.delete() self.m.VerifyAll() @@ -312,7 +310,7 @@ class QuantumSubnetTest(HeatTestCase): rsrc = subnet.Subnet('test_subnet', t['Resources'][resource_name], stack) scheduler.TaskRunner(rsrc.create)() - self.assertEqual(subnet.Subnet.CREATE_COMPLETE, rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) return rsrc def test_subnet(self): @@ -390,7 +388,7 @@ class QuantumSubnetTest(HeatTestCase): rsrc.handle_update, {}, {}, {}) self.assertEqual(rsrc.delete(), None) - rsrc.state_set(rsrc.CREATE_COMPLETE, 'to delete again') + rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again') self.assertEqual(rsrc.delete(), None) self.m.VerifyAll() @@ -412,7 +410,7 @@ class QuantumRouterTest(HeatTestCase): def create_router(self, t, stack, resource_name): rsrc = router.Router('router', t['Resources'][resource_name], stack) scheduler.TaskRunner(rsrc.create)() - self.assertEqual(router.Router.CREATE_COMPLETE, rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) return rsrc def create_router_interface(self, t, stack, resource_name, properties={}): @@ -422,8 +420,7 @@ class QuantumRouterTest(HeatTestCase): t['Resources'][resource_name], stack) scheduler.TaskRunner(rsrc.create)() - self.assertEqual( - router.RouterInterface.CREATE_COMPLETE, rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) return rsrc def create_gateway_router(self, t, stack, resource_name, properties={}): @@ -433,7 +430,7 @@ class QuantumRouterTest(HeatTestCase): t['Resources'][resource_name], stack) scheduler.TaskRunner(rsrc.create)() - self.assertEqual(router.RouterGateway.CREATE_COMPLETE, rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) return rsrc def test_router(self): @@ -521,7 +518,7 @@ class QuantumRouterTest(HeatTestCase): rsrc.handle_update, {}, {}, {}) self.assertEqual(rsrc.delete(), None) - rsrc.state_set(rsrc.CREATE_COMPLETE, 'to delete again') + rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again') self.assertEqual(rsrc.delete(), None) self.m.VerifyAll() @@ -549,7 +546,7 @@ class QuantumRouterTest(HeatTestCase): }) self.assertEqual(rsrc.delete(), None) - rsrc.state_set(rsrc.CREATE_COMPLETE, 'to delete again') + rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again') self.assertEqual(rsrc.delete(), None) self.m.VerifyAll() @@ -575,7 +572,7 @@ class QuantumRouterTest(HeatTestCase): }) self.assertEqual(rsrc.delete(), None) - rsrc.state_set(rsrc.CREATE_COMPLETE, 'to delete again') + rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again') self.assertEqual(rsrc.delete(), None) self.m.VerifyAll() @@ -626,7 +623,7 @@ class QuantumFloatingIPTest(HeatTestCase): fip = stack['floating_ip'] scheduler.TaskRunner(fip.create)() - self.assertEqual(floatingip.FloatingIP.CREATE_COMPLETE, fip.state) + self.assertEqual((fip.CREATE, fip.COMPLETE), fip.state) fip.validate() fip_id = fip.FnGetRefId() @@ -645,7 +642,7 @@ class QuantumFloatingIPTest(HeatTestCase): self.assertRaises(resource.UpdateReplace, fip.handle_update, {}, {}, {}) self.assertEqual(fip.delete(), None) - fip.state_set(fip.CREATE_COMPLETE, 'to delete again') + fip.state_set(fip.CREATE, fip.COMPLETE, 'to delete again') self.assertEqual(fip.delete(), None) self.m.VerifyAll() @@ -693,7 +690,7 @@ class QuantumFloatingIPTest(HeatTestCase): p = stack['port_floating'] scheduler.TaskRunner(p.create)() - self.assertEqual(port.Port.CREATE_COMPLETE, p.state) + self.assertEqual((p.CREATE, p.COMPLETE), p.state) p.validate() port_id = p.FnGetRefId() @@ -786,16 +783,15 @@ class QuantumFloatingIPTest(HeatTestCase): fip = stack['floating_ip'] scheduler.TaskRunner(fip.create)() - self.assertEqual(floatingip.FloatingIP.CREATE_COMPLETE, fip.state) + self.assertEqual((fip.CREATE, fip.COMPLETE), fip.state) p = stack['port_floating'] scheduler.TaskRunner(p.create)() - self.assertEqual(port.Port.CREATE_COMPLETE, p.state) + self.assertEqual((p.CREATE, p.COMPLETE), p.state) fipa = stack['floating_ip_assoc'] scheduler.TaskRunner(fipa.create)() - self.assertEqual(floatingip.FloatingIPAssociation.CREATE_COMPLETE, - fipa.state) + self.assertEqual((fipa.CREATE, fipa.COMPLETE), fipa.state) fipa.validate() @@ -810,9 +806,9 @@ class QuantumFloatingIPTest(HeatTestCase): self.assertEqual(p.delete(), None) self.assertEqual(fip.delete(), None) - fipa.state_set(fipa.CREATE_COMPLETE, 'to delete again') - fip.state_set(fip.CREATE_COMPLETE, 'to delete again') - p.state_set(p.CREATE_COMPLETE, 'to delete again') + fipa.state_set(fipa.CREATE, fipa.COMPLETE, 'to delete again') + fip.state_set(fip.CREATE, fip.COMPLETE, 'to delete again') + p.state_set(p.CREATE, p.COMPLETE, 'to delete again') self.assertEqual(fipa.delete(), None) self.assertEqual(p.delete(), None) diff --git a/heat/tests/test_resource.py b/heat/tests/test_resource.py index edc7efd3..3dc2853b 100644 --- a/heat/tests/test_resource.py +++ b/heat/tests/test_resource.py @@ -19,6 +19,7 @@ from heat.engine import parser from heat.engine import resource from heat.engine import scheduler from heat.openstack.common import uuidutils +import heat.db.api as db_api from heat.tests import generic_resource as generic_rsrc from heat.tests.common import HeatTestCase @@ -55,20 +56,24 @@ class ResourceTest(HeatTestCase): def test_state_defaults(self): tmpl = {'Type': 'Foo'} res = generic_rsrc.GenericResource('test_res_def', tmpl, self.stack) - self.assertEqual(res.state, None) - self.assertEqual(res.state_description, '') + self.assertEqual(res.state, (None, None)) + self.assertEqual(res.status_reason, '') - def test_state(self): + def test_state_set(self): tmpl = {'Type': 'Foo'} res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack) - res.state_set('bar') - self.assertEqual(res.state, 'bar') + res.state_set(res.CREATE, res.COMPLETE, 'wibble') + self.assertEqual(res.action, res.CREATE) + self.assertEqual(res.status, res.COMPLETE) + self.assertEqual(res.state, (res.CREATE, res.COMPLETE)) + self.assertEqual(res.status_reason, 'wibble') - def test_state_description(self): + def test_state_set_invalid(self): tmpl = {'Type': 'Foo'} res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack) - res.state_set('blarg', 'wibble') - self.assertEqual(res.state_description, 'wibble') + self.assertRaises(ValueError, res.state_set, 'foo', 'bla') + self.assertRaises(ValueError, res.state_set, 'foo', res.COMPLETE) + self.assertRaises(ValueError, res.state_set, res.CREATE, 'bla') def test_type(self): tmpl = {'Type': 'Foo'} @@ -87,10 +92,32 @@ class ResourceTest(HeatTestCase): res = generic_rsrc.GenericResource('test_res_upd', tmpl, self.stack) res._store() stored_time = res.updated_time - res.state_set(res.CREATE_IN_PROGRESS, 'testing') + res.state_set(res.CREATE, res.IN_PROGRESS, 'testing') self.assertNotEqual(res.updated_time, None) self.assertNotEqual(res.updated_time, stored_time) + def test_store_or_update(self): + tmpl = {'Type': 'Foo'} + res = generic_rsrc.GenericResource('test_res_upd', tmpl, self.stack) + res._store_or_update(res.CREATE, res.IN_PROGRESS, 'test_store') + self.assertNotEqual(None, res.id) + self.assertEqual(res.action, res.CREATE) + self.assertEqual(res.status, res.IN_PROGRESS) + self.assertEqual(res.status_reason, 'test_store') + + db_res = r = db_api.resource_get(None, res.id) + self.assertEqual(db_res.action, res.CREATE) + self.assertEqual(db_res.status, res.IN_PROGRESS) + self.assertEqual(db_res.status_reason, 'test_store') + + res._store_or_update(res.CREATE, res.COMPLETE, 'test_update') + self.assertEqual(res.action, res.CREATE) + self.assertEqual(res.status, res.COMPLETE) + self.assertEqual(res.status_reason, 'test_update') + self.assertEqual(db_res.action, res.CREATE) + self.assertEqual(db_res.status, res.COMPLETE) + self.assertEqual(db_res.status_reason, 'test_update') + def test_parsed_template(self): tmpl = { 'Type': 'Foo', @@ -225,7 +252,7 @@ class ResourceTest(HeatTestCase): tmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'abc'}} res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack) scheduler.TaskRunner(res.create)() - self.assertEqual(res.CREATE_COMPLETE, res.state) + self.assertEqual((res.CREATE, res.COMPLETE), res.state) def test_create_fail_missing_req_prop(self): # patch in a dummy property schema for GenericResource @@ -239,7 +266,7 @@ class ResourceTest(HeatTestCase): estr = 'Property error : test_resource: Property Foo not assigned' create = scheduler.TaskRunner(res.create) self.assertRaises(exception.ResourceFailure, create) - self.assertEqual(res.CREATE_FAILED, res.state) + self.assertEqual((res.CREATE, res.FAILED), res.state) def test_create_fail_prop_typo(self): # patch in a dummy property schema for GenericResource @@ -253,7 +280,7 @@ class ResourceTest(HeatTestCase): estr = 'Property error : test_resource: Property Foo not assigned' create = scheduler.TaskRunner(res.create) self.assertRaises(exception.ResourceFailure, create) - self.assertEqual(res.CREATE_FAILED, res.state) + self.assertEqual((res.CREATE, res.FAILED), res.state) def test_update_ok(self): # patch in a dummy property schema for GenericResource @@ -265,7 +292,7 @@ class ResourceTest(HeatTestCase): res.update_allowed_keys = ('Properties',) res.update_allowed_properties = ('Foo',) scheduler.TaskRunner(res.create)() - self.assertEqual(res.CREATE_COMPLETE, res.state) + self.assertEqual((res.CREATE, res.COMPLETE), res.state) utmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'xyz'}} tmpl_diff = {'Properties': {'Foo': 'xyz'}} @@ -276,7 +303,7 @@ class ResourceTest(HeatTestCase): self.m.ReplayAll() self.assertEqual(None, res.update(utmpl)) - self.assertEqual(res.UPDATE_COMPLETE, res.state) + self.assertEqual((res.UPDATE, res.COMPLETE), res.state) self.m.VerifyAll() def test_update_replace(self): @@ -289,7 +316,7 @@ class ResourceTest(HeatTestCase): res.update_allowed_keys = ('Properties',) res.update_allowed_properties = ('Foo',) scheduler.TaskRunner(res.create)() - self.assertEqual(res.CREATE_COMPLETE, res.state) + self.assertEqual((res.CREATE, res.COMPLETE), res.state) utmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'xyz'}} self.m.StubOutWithMock(generic_rsrc.GenericResource, 'handle_update') @@ -312,12 +339,12 @@ class ResourceTest(HeatTestCase): res.update_allowed_keys = ('Properties',) res.update_allowed_properties = ('Foo',) scheduler.TaskRunner(res.create)() - self.assertEqual(res.CREATE_COMPLETE, res.state) + self.assertEqual((res.CREATE, res.COMPLETE), res.state) utmpl = {'Type': 'GenericResourceType', 'Properties': {}} self.assertRaises(exception.ResourceFailure, res.update, utmpl) - self.assertEqual(res.UPDATE_FAILED, res.state) + self.assertEqual((res.UPDATE, res.FAILED), res.state) def test_update_fail_prop_typo(self): # patch in a dummy property schema for GenericResource @@ -329,12 +356,12 @@ class ResourceTest(HeatTestCase): res.update_allowed_keys = ('Properties',) res.update_allowed_properties = ('Foo',) scheduler.TaskRunner(res.create)() - self.assertEqual(res.CREATE_COMPLETE, res.state) + self.assertEqual((res.CREATE, res.COMPLETE), res.state) utmpl = {'Type': 'GenericResourceType', 'Properties': {'Food': 'xyz'}} self.assertRaises(exception.ResourceFailure, res.update, utmpl) - self.assertEqual(res.UPDATE_FAILED, res.state) + self.assertEqual((res.UPDATE, res.FAILED), res.state) def test_update_not_implemented(self): # patch in a dummy property schema for GenericResource @@ -346,7 +373,7 @@ class ResourceTest(HeatTestCase): res.update_allowed_keys = ('Properties',) res.update_allowed_properties = ('Foo',) scheduler.TaskRunner(res.create)() - self.assertEqual(res.CREATE_COMPLETE, res.state) + self.assertEqual((res.CREATE, res.COMPLETE), res.state) utmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'xyz'}} tmpl_diff = {'Properties': {'Foo': 'xyz'}} @@ -356,7 +383,7 @@ class ResourceTest(HeatTestCase): ).AndRaise(NotImplemented) self.m.ReplayAll() self.assertRaises(exception.ResourceFailure, res.update, utmpl) - self.assertEqual(res.UPDATE_FAILED, res.state) + self.assertEqual((res.UPDATE, res.FAILED), res.state) self.m.VerifyAll() diff --git a/heat/tests/test_s3.py b/heat/tests/test_s3.py index 3f08a9eb..5fa6351c 100644 --- a/heat/tests/test_s3.py +++ b/heat/tests/test_s3.py @@ -74,7 +74,7 @@ class s3Test(HeatTestCase): t['Resources'][resource_name], stack) scheduler.TaskRunner(rsrc.create)() - self.assertEqual(s3.S3Bucket.CREATE_COMPLETE, rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) return rsrc def test_create_container_name(self): @@ -231,7 +231,7 @@ class s3Test(HeatTestCase): rsrc = self.create_resource(t, stack, 'S3Bucket') # if delete_container is called, mox verify will succeed rsrc.delete() - self.assertEqual(rsrc.DELETE_COMPLETE, rsrc.state) + self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state) try: self.m.VerifyAll() diff --git a/heat/tests/test_security_group.py b/heat/tests/test_security_group.py index 8c27d421..e6e03e6b 100644 --- a/heat/tests/test_security_group.py +++ b/heat/tests/test_security_group.py @@ -123,7 +123,7 @@ Resources: def assertResourceState(self, rsrc, ref_id, metadata={}): self.assertEqual(None, rsrc.validate()) - self.assertEqual(rsrc.CREATE_COMPLETE, rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) self.assertEqual(ref_id, rsrc.FnGetRefId()) self.assertEqual(metadata, dict(rsrc.metadata)) @@ -272,7 +272,7 @@ Resources: self.assertEqual(None, sg.delete()) - sg.state_set(sg.CREATE_COMPLETE, 'to delete again') + sg.state_set(sg.CREATE, sg.COMPLETE, 'to delete again') sg.resource_id = 2 stack.delete() @@ -534,7 +534,7 @@ Resources: self.assertEqual(None, sg.delete()) - sg.state_set(sg.CREATE_COMPLETE, 'to delete again') + sg.state_set(sg.CREATE, sg.COMPLETE, 'to delete again') sg.resource_id = 'aaaa' stack.delete() diff --git a/heat/tests/test_swift.py b/heat/tests/test_swift.py index 1ad87ca3..1df2009c 100644 --- a/heat/tests/test_swift.py +++ b/heat/tests/test_swift.py @@ -75,7 +75,7 @@ class swiftTest(HeatTestCase): t['Resources'][resource_name], stack) scheduler.TaskRunner(rsrc.create)() - self.assertEqual(swift.SwiftContainer.CREATE_COMPLETE, rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) return rsrc def test_create_container_name(self): @@ -251,7 +251,7 @@ class swiftTest(HeatTestCase): rsrc = self.create_resource(t, stack, 'SwiftContainer') # if delete_container is called, mox verify will succeed rsrc.delete() - self.assertEqual(rsrc.DELETE_COMPLETE, rsrc.state) + self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state) try: self.m.VerifyAll() diff --git a/heat/tests/test_user.py b/heat/tests/test_user.py index 21b630d6..7cef102d 100644 --- a/heat/tests/test_user.py +++ b/heat/tests/test_user.py @@ -107,7 +107,7 @@ class UserTest(UserPolicyTestCase): stack) self.assertEqual(None, rsrc.validate()) scheduler.TaskRunner(rsrc.create)() - self.assertEqual(user.User.CREATE_COMPLETE, rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) return rsrc def test_user(self): @@ -125,26 +125,26 @@ class UserTest(UserPolicyTestCase): self.assertEqual(utils.PhysName('test_stack', 'CfnUser'), rsrc.FnGetRefId()) - self.assertEqual('CREATE_COMPLETE', rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) self.assertRaises(resource.UpdateReplace, rsrc.handle_update, {}, {}, {}) rsrc.resource_id = None self.assertEqual(None, rsrc.delete()) - self.assertEqual('DELETE_COMPLETE', rsrc.state) + self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state) rsrc.resource_id = self.fc.access - rsrc.state_set('CREATE_COMPLETE') - self.assertEqual('CREATE_COMPLETE', rsrc.state) + rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) self.assertEqual(None, rsrc.delete()) - self.assertEqual('DELETE_COMPLETE', rsrc.state) + self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state) - rsrc.state_set('CREATE_COMPLETE') - self.assertEqual('CREATE_COMPLETE', rsrc.state) + rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) self.assertEqual(None, rsrc.delete()) - self.assertEqual('DELETE_COMPLETE', rsrc.state) + self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state) self.m.VerifyAll() def test_user_validate_policies(self): @@ -161,7 +161,7 @@ class UserTest(UserPolicyTestCase): self.assertEqual(self.fc.user_id, rsrc.resource_id) self.assertEqual(utils.PhysName('test_stack', 'CfnUser'), rsrc.FnGetRefId()) - self.assertEqual('CREATE_COMPLETE', rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) self.assertEqual([u'WebServerAccessPolicy'], rsrc.properties['Policies']) @@ -222,7 +222,7 @@ class UserTest(UserPolicyTestCase): self.assertEqual(self.fc.user_id, rsrc.resource_id) self.assertEqual(utils.PhysName('test_stack', 'CfnUser'), rsrc.FnGetRefId()) - self.assertEqual('CREATE_COMPLETE', rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) self.assertTrue(rsrc.access_allowed('a_resource')) self.assertFalse(rsrc.access_allowed('b_resource')) @@ -248,7 +248,7 @@ class UserTest(UserPolicyTestCase): self.assertEqual(self.fc.user_id, rsrc.resource_id) self.assertEqual(utils.PhysName('test_stack', 'CfnUser'), rsrc.FnGetRefId()) - self.assertEqual('CREATE_COMPLETE', rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) self.assertTrue(rsrc.access_allowed('a_resource')) self.assertFalse(rsrc.access_allowed('b_resource')) @@ -263,15 +263,14 @@ class AccessKeyTest(UserPolicyTestCase): stack) self.assertEqual(None, rsrc.validate()) scheduler.TaskRunner(rsrc.create)() - self.assertEqual(user.AccessKey.CREATE_COMPLETE, - rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) return rsrc def create_user(self, t, stack, resource_name): rsrc = stack[resource_name] self.assertEqual(None, rsrc.validate()) scheduler.TaskRunner(rsrc.create)() - self.assertEqual(rsrc.CREATE_COMPLETE, rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) return rsrc def test_access_key(self): @@ -321,14 +320,13 @@ class AccessKeyTest(UserPolicyTestCase): self.create_user(t, stack, 'CfnUser') rsrc = self.create_access_key(t, stack, 'HostKeys') - self.assertEqual(rsrc.CREATE_COMPLETE, rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) self.m.StubOutWithMock(self.fc, 'delete_ec2_keypair') NotFound = keystoneclient.exceptions.NotFound self.fc.delete_ec2_keypair(self.fc.user_id, rsrc.resource_id).AndRaise(NotFound('Gone')) self.m.ReplayAll() - self.assertEqual(None, rsrc.delete()) self.m.VerifyAll() @@ -347,11 +345,10 @@ class AccessKeyTest(UserPolicyTestCase): stack) create = scheduler.TaskRunner(rsrc.create) self.assertRaises(exception.ResourceFailure, create) - self.assertEqual(user.AccessKey.CREATE_FAILED, - rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state) self.assertEqual(None, rsrc.delete()) - self.assertEqual(user.AccessKey.DELETE_COMPLETE, rsrc.state) + self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state) self.m.VerifyAll() @@ -367,7 +364,7 @@ class AccessPolicyTest(UserPolicyTestCase): t['Resources'][resource_name], stack) scheduler.TaskRunner(rsrc.create)() - self.assertEqual(user.User.CREATE_COMPLETE, rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) def test_accesspolicy_create_ok_empty(self): t = template_format.parse(user_policy_template) @@ -379,7 +376,7 @@ class AccessPolicyTest(UserPolicyTestCase): t['Resources'][resource_name], stack) scheduler.TaskRunner(rsrc.create)() - self.assertEqual(user.User.CREATE_COMPLETE, rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) def test_accesspolicy_create_err_notfound(self): t = template_format.parse(user_policy_template) diff --git a/heat/tests/test_volume.py b/heat/tests/test_volume.py index d52dc621..d53f4e0b 100644 --- a/heat/tests/test_volume.py +++ b/heat/tests/test_volume.py @@ -93,7 +93,7 @@ class VolumeTest(HeatTestCase): rsrc = vol.Volume(resource_name, data, stack) self.assertEqual(rsrc.validate(), None) scheduler.TaskRunner(rsrc.create)() - self.assertEqual(rsrc.state, vol.Volume.CREATE_COMPLETE) + self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE)) return rsrc def create_attachment(self, t, stack, resource_name): @@ -102,7 +102,7 @@ class VolumeTest(HeatTestCase): stack) self.assertEqual(rsrc.validate(), None) scheduler.TaskRunner(rsrc.create)() - self.assertEqual(rsrc.state, vol.VolumeAttachment.CREATE_COMPLETE) + self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE)) return rsrc def test_volume(self): @@ -143,7 +143,7 @@ class VolumeTest(HeatTestCase): self.assertEqual(rsrc.destroy(), None) # Test when volume already deleted - rsrc.state = rsrc.CREATE_COMPLETE + rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE) self.assertEqual(rsrc.destroy(), None) self.m.VerifyAll() @@ -530,7 +530,7 @@ class VolumeTest(HeatTestCase): stack) self.assertEqual(rsrc.validate(), None) scheduler.TaskRunner(rsrc.create)() - self.assertEqual(rsrc.state, vol.Volume.CREATE_COMPLETE) + self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE)) self.assertEqual(fv.status, 'available') self.m.VerifyAll() @@ -561,7 +561,7 @@ class VolumeTest(HeatTestCase): stack) self.assertEqual(rsrc.validate(), None) scheduler.TaskRunner(rsrc.create)() - self.assertEqual(rsrc.state, vol.Volume.CREATE_COMPLETE) + self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE)) self.assertEqual(fv.status, 'available') self.m.VerifyAll() @@ -668,7 +668,7 @@ class VolumeTest(HeatTestCase): stack) self.assertEqual(rsrc.validate(), None) scheduler.TaskRunner(rsrc.create)() - self.assertEqual(rsrc.state, vol.VolumeAttachment.CREATE_COMPLETE) + self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE)) self.assertRaises(resource.UpdateReplace, rsrc.handle_update, {}, {}, {}) diff --git a/heat/tests/test_vpc.py b/heat/tests/test_vpc.py index 41193b64..ecbabb81 100644 --- a/heat/tests/test_vpc.py +++ b/heat/tests/test_vpc.py @@ -218,7 +218,7 @@ class VPCTestBase(HeatTestCase): def assertResourceState(self, rsrc, ref_id, metadata={}): self.assertEqual(None, rsrc.validate()) - self.assertEqual(rsrc.CREATE_COMPLETE, rsrc.state) + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) self.assertEqual(ref_id, rsrc.FnGetRefId()) self.assertEqual(metadata, dict(rsrc.metadata)) @@ -301,7 +301,7 @@ Resources: self.assertEqual('moon', rsrc.FnGetAtt('AvailabilityZone')) self.assertEqual(None, rsrc.delete()) - rsrc.state_set(rsrc.CREATE_COMPLETE, 'to delete again') + rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again') self.assertEqual(None, rsrc.delete()) self.assertEqual(None, stack['the_vpc'].delete()) self.m.VerifyAll() @@ -512,9 +512,9 @@ Resources: stack = self.create_stack(self.test_template_error_no_ref) try: self.assertEqual(stack.CREATE_FAILED, stack.state) - self.assertEqual(stack['the_nic'].CREATE_FAILED, - stack['the_nic'].state) - reason = stack['the_nic'].state_description + rsrc = stack['the_nic'] + self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state) + reason = rsrc.status_reason self.assertTrue(reason.startswith('InvalidTemplateAttribute:')) finally: stack.delete() diff --git a/heat/tests/test_waitcondition.py b/heat/tests/test_waitcondition.py index 54414cf4..05b14974 100644 --- a/heat/tests/test_waitcondition.py +++ b/heat/tests/test_waitcondition.py @@ -153,7 +153,7 @@ class WaitConditionTest(HeatTestCase): rsrc = self.stack.resources['WaitForTheHandle'] self.assertEqual(rsrc.state, - 'CREATE_COMPLETE') + (rsrc.CREATE, rsrc.COMPLETE)) r = db_api.resource_get_by_name_and_stack(None, 'WaitHandle', self.stack.id) @@ -174,8 +174,8 @@ class WaitConditionTest(HeatTestCase): self.stack.create() rsrc = self.stack.resources['WaitForTheHandle'] - self.assertEqual(rsrc.state, rsrc.CREATE_FAILED) - reason = rsrc.state_description + self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.FAILED)) + reason = rsrc.status_reason self.assertTrue(reason.startswith('WaitConditionFailure:')) r = db_api.resource_get_by_name_and_stack(None, 'WaitHandle', @@ -201,7 +201,7 @@ class WaitConditionTest(HeatTestCase): rsrc = self.stack.resources['WaitForTheHandle'] self.assertEqual(rsrc.state, - 'CREATE_COMPLETE') + (rsrc.CREATE, rsrc.COMPLETE)) r = db_api.resource_get_by_name_and_stack(None, 'WaitHandle', self.stack.id) @@ -222,8 +222,8 @@ class WaitConditionTest(HeatTestCase): self.stack.create() rsrc = self.stack.resources['WaitForTheHandle'] - self.assertEqual(rsrc.state, rsrc.CREATE_FAILED) - reason = rsrc.state_description + self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.FAILED)) + reason = rsrc.status_reason self.assertTrue(reason.startswith('WaitConditionFailure:')) r = db_api.resource_get_by_name_and_stack(None, 'WaitHandle', @@ -259,8 +259,8 @@ class WaitConditionTest(HeatTestCase): rsrc = self.stack.resources['WaitForTheHandle'] - self.assertEqual(rsrc.state, rsrc.CREATE_FAILED) - reason = rsrc.state_description + self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.FAILED)) + reason = rsrc.status_reason self.assertTrue(reason.startswith('WaitConditionTimeout:')) self.assertRaises(resource.UpdateReplace, @@ -276,13 +276,13 @@ class WaitConditionTest(HeatTestCase): self.stack.create() rsrc = self.stack.resources['WaitForTheHandle'] - self.assertEqual(rsrc.state, 'CREATE_COMPLETE') + self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE)) wc_att = rsrc.FnGetAtt('Data') self.assertEqual(wc_att, unicode({})) handle = self.stack.resources['WaitHandle'] - self.assertEqual(handle.state, 'CREATE_COMPLETE') + self.assertEqual(handle.state, (rsrc.CREATE, rsrc.COMPLETE)) test_metadata = {'Data': 'foo', 'Reason': 'bar', 'Status': 'SUCCESS', 'UniqueId': '123'} @@ -435,7 +435,7 @@ class WaitConditionHandleTest(HeatTestCase): rsrc = self.stack.resources['WaitHandle'] rsrc.created_time = created_time - self.assertEqual(rsrc.state, 'CREATE_COMPLETE') + self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE)) expected_url = "".join([ 'http://127.0.0.1:8000/v1/waitcondition/', @@ -458,7 +458,7 @@ class WaitConditionHandleTest(HeatTestCase): @stack_delete_after def test_metadata_update(self): rsrc = self.stack.resources['WaitHandle'] - self.assertEqual(rsrc.state, 'CREATE_COMPLETE') + self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE)) test_metadata = {'Data': 'foo', 'Reason': 'bar', 'Status': 'SUCCESS', 'UniqueId': '123'} @@ -472,7 +472,7 @@ class WaitConditionHandleTest(HeatTestCase): @stack_delete_after def test_metadata_update_invalid(self): rsrc = self.stack.resources['WaitHandle'] - self.assertEqual(rsrc.state, 'CREATE_COMPLETE') + self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE)) # metadata_update should raise a ValueError if the metadata # is missing any of the expected keys @@ -515,7 +515,7 @@ class WaitConditionHandleTest(HeatTestCase): @stack_delete_after def test_get_status(self): rsrc = self.stack.resources['WaitHandle'] - self.assertEqual(rsrc.state, 'CREATE_COMPLETE') + self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE)) # UnsetStubs, don't want get_status stubbed anymore.. self.m.VerifyAll() @@ -541,7 +541,7 @@ class WaitConditionHandleTest(HeatTestCase): @stack_delete_after def test_get_status_reason(self): rsrc = self.stack.resources['WaitHandle'] - self.assertEqual(rsrc.state, 'CREATE_COMPLETE') + self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE)) test_metadata = {'Data': 'foo', 'Reason': 'bar', 'Status': 'SUCCESS', 'UniqueId': '123'} -- 2.45.2