]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
Convert Stack to separate action/status
authorSteven Hardy <shardy@redhat.com>
Tue, 18 Jun 2013 17:07:57 +0000 (18:07 +0100)
committerSteven Hardy <shardy@redhat.com>
Wed, 19 Jun 2013 15:10:51 +0000 (16:10 +0100)
Next and hopefully final step in decoupling action/status

This adjusts the Stack DB columns, model and class to be consistent with
Event/Resource, and split action/status.  This also modifies the both
APIs to join the action/status to avoid changing the API

Change-Id: Ifbdf254c62cad271b775b88de5b873f4e0b6d736

17 files changed:
heat/api/cfn/v1/stacks.py
heat/api/openstack/v1/stacks.py
heat/db/sqlalchemy/migrate_repo/versions/020_stack_action.py [new file with mode: 0644]
heat/db/sqlalchemy/models.py
heat/engine/api.py
heat/engine/parser.py
heat/engine/stack_resource.py
heat/engine/watchrule.py
heat/rpc/api.py
heat/tests/test_api_cfn_v1.py
heat/tests/test_api_openstack_v1.py
heat/tests/test_engine_service.py
heat/tests/test_metadata_refresh.py
heat/tests/test_nested_stack.py
heat/tests/test_parser.py
heat/tests/test_vpc.py
heat/tests/test_watch.py

index 21966d05f01630ef1854965611981f98d9e22407..b0f66055463492b4e496161125ed1651411e4694 100644 (file)
@@ -125,13 +125,16 @@ class StackController(object):
                 engine_api.STACK_UPDATED_TIME: 'LastUpdatedTime',
                 engine_api.STACK_ID: 'StackId',
                 engine_api.STACK_NAME: 'StackName',
-                engine_api.STACK_STATUS: 'StackStatus',
                 engine_api.STACK_STATUS_DATA: 'StackStatusReason',
                 engine_api.STACK_TMPL_DESCRIPTION: 'TemplateDescription',
             }
 
             result = api_utils.reformat_dict_keys(keymap, s)
 
+            action = s[engine_api.STACK_ACTION]
+            status = s[engine_api.STACK_STATUS]
+            result['StackStatus'] = '_'.join((action, status))
+
             # AWS docs indicate DeletionTime is ommitted for current stacks
             # This is still TODO(unknown) in the engine, we don't keep data for
             # stacks after they are deleted
@@ -195,13 +198,16 @@ class StackController(object):
                 engine_api.STACK_PARAMETERS: 'Parameters',
                 engine_api.STACK_ID: 'StackId',
                 engine_api.STACK_NAME: 'StackName',
-                engine_api.STACK_STATUS: 'StackStatus',
                 engine_api.STACK_STATUS_DATA: 'StackStatusReason',
                 engine_api.STACK_TIMEOUT: 'TimeoutInMinutes',
             }
 
             result = api_utils.reformat_dict_keys(keymap, s)
 
+            action = s[engine_api.STACK_ACTION]
+            status = s[engine_api.STACK_STATUS]
+            result['StackStatus'] = '_'.join((action, status))
+
             # Reformat outputs, these are handled separately as they are
             # only present in the engine output for a completely created
             # stack
index 6e7f897defd381a65ffb05c2867d5dd2a25dff81..a2ef92a8b97daaac2a0e071d4170dae4d7808600 100644 (file)
@@ -147,6 +147,14 @@ def format_stack(req, stack, keys=[]):
         if key == engine_api.STACK_ID:
             yield ('id', value['stack_id'])
             yield ('links', [util.make_link(req, value)])
+        elif key == engine_api.STACK_ACTION:
+            return
+        elif (key == engine_api.STACK_STATUS and
+              engine_api.STACK_ACTION in stack):
+            # 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((stack[engine_api.STACK_ACTION], value)))
         else:
             # TODO(zaneb): ensure parameters can be formatted for XML
             #elif key == engine_api.STACK_PARAMETERS:
diff --git a/heat/db/sqlalchemy/migrate_repo/versions/020_stack_action.py b/heat/db/sqlalchemy/migrate_repo/versions/020_stack_action.py
new file mode 100644 (file)
index 0000000..b919a38
--- /dev/null
@@ -0,0 +1,37 @@
+# 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
+
+    stack = Table('stack', meta, autoload=True)
+    # Align with action/status now used in the event/resource tables
+    Column('action', String(length=255,
+                            convert_unicode=False,
+                            assert_unicode=None,
+                            unicode_error=None,
+                            _warn_on_bytestring=False)).create(stack)
+
+
+def downgrade(migrate_engine):
+    meta = MetaData()
+    meta.bind = migrate_engine
+
+    stack = Table('stack', meta, autoload=True)
+    stack.c.action.drop()
index bffe24cbe1111b1ed52b2de356d144b39a5fbc8d..a239774d2e935bd61c51a08093a11af512d0822d 100644 (file)
@@ -155,6 +155,7 @@ class Stack(BASE, HeatBase):
     raw_template = relationship(RawTemplate, backref=backref('stack'))
     username = Column(String)
     tenant = Column(String)
+    action = Column('action', String)
     status = Column('status', String)
     status_reason = Column('status_reason', String)
     parameters = Column('parameters', Json)
index ad338b712693329b5253820c197c5a07fa0ee3b0..449395ba40ea550ebd8ed82529a864611e91b44e 100644 (file)
@@ -76,15 +76,16 @@ def format_stack(stack):
         STACK_PARAMETERS: stack.parameters.map(str),
         STACK_DESCRIPTION: stack.t[template.DESCRIPTION],
         STACK_TMPL_DESCRIPTION: stack.t[template.DESCRIPTION],
-        STACK_STATUS: stack.state,
-        STACK_STATUS_DATA: stack.state_description,
+        STACK_ACTION: stack.action or '',
+        STACK_STATUS: stack.status or '',
+        STACK_STATUS_DATA: stack.status_reason,
         STACK_CAPABILITIES: [],   # TODO Not implemented yet
         STACK_DISABLE_ROLLBACK: stack.disable_rollback,
         STACK_TIMEOUT: stack.timeout_mins,
     }
 
     # only show the outputs on a completely created or updated stack
-    if stack.state in (stack.CREATE_COMPLETE, stack.UPDATE_COMPLETE):
+    if (stack.action != stack.DELETE and stack.status == stack.COMPLETE):
         info[STACK_OUTPUTS] = format_stack_outputs(stack, stack.outputs)
 
     return info
index f51246a94538e1feaf24004c7e444572c6f153a4..92ded0210d48a19fcba4af53c49db4b15f67c21e 100644 (file)
@@ -44,21 +44,8 @@ class Stack(object):
     ACTIONS = (CREATE, DELETE, UPDATE, ROLLBACK
                ) = ('CREATE', 'DELETE', 'UPDATE', 'ROLLBACK')
 
-    CREATE_IN_PROGRESS = 'CREATE_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_COMPLETE = 'UPDATE_COMPLETE'
-    UPDATE_FAILED = 'UPDATE_FAILED'
-
-    ROLLBACK_IN_PROGRESS = 'ROLLBACK_IN_PROGRESS'
-    ROLLBACK_COMPLETE = 'ROLLBACK_COMPLETE'
-    ROLLBACK_FAILED = 'ROLLBACK_FAILED'
+    STATUSES = (IN_PROGRESS, FAILED, COMPLETE
+                ) = ('IN_PROGRESS', 'FAILED', 'COMPLETE')
 
     created_time = timestamp.Timestamp(db_api.stack_get, 'created_at')
     updated_time = timestamp.Timestamp(db_api.stack_get, 'updated_at')
@@ -66,8 +53,9 @@ class Stack(object):
     _zones = None
 
     def __init__(self, context, stack_name, tmpl, env=None,
-                 stack_id=None, state=None, state_description='',
-                 timeout_mins=60, resolve_data=True, disable_rollback=True):
+                 stack_id=None, action=None, status=None,
+                 status_reason='', timeout_mins=60, resolve_data=True,
+                 disable_rollback=True):
         '''
         Initialise from a context, name, Template object and (optionally)
         Environment object. The database ID may also be initialised, if the
@@ -85,8 +73,9 @@ class Stack(object):
         self.clients = Clients(context)
         self.t = tmpl
         self.name = stack_name
-        self.state = state
-        self.state_description = state_description
+        self.action = action
+        self.status = status
+        self.status_reason = status_reason
         self.timeout_mins = timeout_mins
         self.disable_rollback = disable_rollback
 
@@ -145,8 +134,8 @@ class Stack(object):
         template = Template.load(context, stack.raw_template_id)
         env = environment.Environment(stack.parameters)
         stack = cls(context, stack.name, template, env,
-                    stack.id, stack.status, stack.status_reason, stack.timeout,
-                    resolve_data, stack.disable_rollback)
+                    stack.id, stack.action, stack.status, stack.status_reason,
+                    stack.timeout, resolve_data, stack.disable_rollback)
 
         return stack
 
@@ -165,8 +154,9 @@ class Stack(object):
             'user_creds_id': new_creds.id,
             'username': self.context.username,
             'tenant': self.context.tenant_id,
-            'status': self.state,
-            'status_reason': self.state_description,
+            'action': self.action,
+            'status': self.status,
+            'status_reason': self.status_reason,
             'timeout': self.timeout_mins,
             'disable_rollback': self.disable_rollback,
         }
@@ -254,18 +244,31 @@ class Stack(object):
             if result:
                 raise StackValidationFailed(message=result)
 
-    def state_set(self, new_status, reason):
+    def state_set(self, action, status, reason):
         '''Update the stack state in the database.'''
-        self.state = new_status
-        self.state_description = reason
+        if action not in self.ACTIONS:
+            raise ValueError("Invalid action %s" % action)
+
+        if status not in self.STATUSES:
+            raise ValueError("Invalid status %s" % status)
+
+        self.action = action
+        self.status = status
+        self.status_reason = reason
 
         if self.id is None:
             return
 
         stack = db_api.stack_get(self.context, self.id)
-        stack.update_and_save({'status': new_status,
+        stack.update_and_save({'action': action,
+                               'status': status,
                                'status_reason': reason})
 
+    @property
+    def state(self):
+        '''Returns state, tuple of action, status.'''
+        return (self.action, self.status)
+
     def timeout_secs(self):
         '''
         Return the stack creation timeout in seconds, or None if no timeout
@@ -288,9 +291,9 @@ class Stack(object):
         '''
         A task to create the stack and all of the resources.
         '''
-        self.state_set(self.CREATE_IN_PROGRESS, 'Stack creation started')
+        self.state_set(self.CREATE, self.IN_PROGRESS, 'Stack creation started')
 
-        stack_status = self.CREATE_COMPLETE
+        stack_status = self.COMPLETE
         reason = 'Stack successfully created'
         res = None
 
@@ -303,15 +306,15 @@ class Stack(object):
         try:
             yield create_task()
         except exception.ResourceFailure as ex:
-            stack_status = self.CREATE_FAILED
+            stack_status = self.FAILED
             reason = 'Resource failed: %s' % str(ex)
         except scheduler.Timeout:
-            stack_status = self.CREATE_FAILED
+            stack_status = self.FAILED
             reason = 'Timed out'
 
-        self.state_set(stack_status, reason)
+        self.state_set(self.CREATE, stack_status, reason)
 
-        if stack_status == self.CREATE_FAILED and not self.disable_rollback:
+        if stack_status == self.FAILED and not self.disable_rollback:
             self.delete(action=self.ROLLBACK)
 
     def update(self, newstack, action=UPDATE):
@@ -328,27 +331,21 @@ class Stack(object):
         '''
         if action not in (self.UPDATE, self.ROLLBACK):
             logger.error("Unexpected action %s passed to update!" % action)
-            self.state_set(self.UPDATE_FAILED, "Invalid action %s" % action)
+            self.state_set(self.UPDATE, self.FAILED,
+                           "Invalid action %s" % action)
             return
 
-        if self.state not in (self.CREATE_COMPLETE, self.UPDATE_COMPLETE,
-                              self.ROLLBACK_COMPLETE):
+        if self.status != self.COMPLETE:
             if (action == self.ROLLBACK and
-                    self.state == self.UPDATE_IN_PROGRESS):
+                    self.state == (self.UPDATE, self.IN_PROGRESS)):
                 logger.debug("Starting update rollback for %s" % self.name)
             else:
-                if action == self.UPDATE:
-                    self.state_set(self.UPDATE_FAILED,
-                                   'State invalid for update')
-                else:
-                    self.state_set(self.ROLLBACK_FAILED,
-                                   'State invalid for rollback')
+                self.state_set(action, self.FAILED,
+                               'State invalid for %s' % action)
                 return
 
-        if action == self.UPDATE:
-            self.state_set(self.UPDATE_IN_PROGRESS, 'Stack update started')
-        else:
-            self.state_set(self.ROLLBACK_IN_PROGRESS, 'Stack rollback started')
+        self.state_set(self.UPDATE, self.IN_PROGRESS,
+                       'Stack %s started' % action)
 
         # cache all the resources runtime data.
         for r in self:
@@ -416,15 +413,14 @@ class Stack(object):
                                         (res.name, self.name))
 
                 if action == self.UPDATE:
-                    stack_status = self.UPDATE_COMPLETE
                     reason = 'Stack successfully updated'
                 else:
-                    stack_status = self.ROLLBACK_COMPLETE
                     reason = 'Stack rollback completed'
+                stack_status = self.COMPLETE
 
             except eventlet.Timeout as t:
                 if t is tmo:
-                    stack_status = self.UPDATE_FAILED
+                    stack_status = self.FAILED
                     reason = 'Timed out waiting for %s' % str(res)
                 else:
                     # not my timeout
@@ -432,21 +428,17 @@ class Stack(object):
             except exception.ResourceFailure as e:
                 reason = str(e) or "Error : %s" % type(e)
 
+                stack_status = self.FAILED
                 if action == self.UPDATE:
-                    stack_status = self.UPDATE_FAILED
                     # If rollback is enabled, we do another update, with the
                     # existing template, so we roll back to the original state
-                    if self.disable_rollback:
-                        stack_status = self.UPDATE_FAILED
-                    else:
+                    if not self.disable_rollback:
                         oldstack = Stack(self.context, self.name, self.t,
                                          self.env)
                         self.update(oldstack, action=self.ROLLBACK)
                         return
-                else:
-                    stack_status = self.ROLLBACK_FAILED
 
-            self.state_set(stack_status, reason)
+            self.state_set(action, stack_status, reason)
 
             # flip the template & environment to the newstack values
             # Note we do this on success and failure, so the current
@@ -466,15 +458,14 @@ class Stack(object):
         create, which amount to the same thing, but the states are recorded
         differently.
         '''
-        if action == self.DELETE:
-            self.state_set(self.DELETE_IN_PROGRESS, 'Stack deletion started')
-        elif action == self.ROLLBACK:
-            self.state_set(self.ROLLBACK_IN_PROGRESS, 'Stack rollback started')
-        else:
+        if action not in (self.DELETE, self.ROLLBACK):
             logger.error("Unexpected action %s passed to delete!" % action)
-            self.state_set(self.DELETE_FAILED, "Invalid action %s" % action)
+            self.state_set(self.DELETE, self.FAILED,
+                           "Invalid action %s" % action)
             return
 
+        self.state_set(action, self.IN_PROGRESS, 'Stack %s started' % action)
+
         failures = []
         for res in reversed(self):
             try:
@@ -485,17 +476,10 @@ class Stack(object):
                 failures.append(str(res))
 
         if failures:
-            if action == self.DELETE:
-                self.state_set(self.DELETE_FAILED,
-                               'Failed to delete ' + ', '.join(failures))
-            elif action == self.ROLLBACK:
-                self.state_set(self.ROLLBACK_FAILED,
-                               'Failed to rollback ' + ', '.join(failures))
+            self.state_set(action, self.FAILED,
+                           'Failed to %s : %s' % (action, ', '.join(failures)))
         else:
-            if action == self.DELETE:
-                self.state_set(self.DELETE_COMPLETE, 'Deleted successfully')
-            elif action == self.ROLLBACK:
-                self.state_set(self.ROLLBACK_COMPLETE, 'Rollback completed')
+            self.state_set(action, self.COMPLETE, '%s completed' % action)
             db_api.stack_delete(self.context, self.id)
             self.id = None
 
index 1bab2627a873566e3f321dc15a88c9a0d76de866..170234b73bb39621cd55951160f726b7d39ea04a 100644 (file)
@@ -73,7 +73,8 @@ class StackResource(resource.Resource):
     def check_create_complete(self, stack_creator):
         done = stack_creator.step()
         if done:
-            if self._nested.state != self._nested.CREATE_COMPLETE:
+            if self._nested.state != (self._nested.CREATE,
+                                      self._nested.COMPLETE):
                 raise exception.Error(self._nested.state_description)
 
         return done
index 26b6aa212adb2611152f7491bfa19eb8c592e9f0..e6db474b66cf9e06ceea4a50b337aeccc98e9ab7 100644 (file)
@@ -235,9 +235,9 @@ class WatchRule(object):
                         new_state)
         else:
             s = db_api.stack_get(self.context, self.stack_id)
-            if s and s.status in (parser.Stack.CREATE_COMPLETE,
-                                  parser.Stack.UPDATE_COMPLETE):
-                stack = parser.Stack.load(self.context, stack=s)
+            stack = parser.Stack.load(self.context, stack=s)
+            if (stack.action != stack.DELETE
+                    and stack.status == stack.COMPLETE):
                 for a in self.rule[self.ACTION_MAP[new_state]]:
                     actions.append(stack[a].alarm)
             else:
index 20d7d30e54530aae4243d8bee3a2221ee2e78c9e..f9dbacecc882f614c8bb3c6568b23037b44ce97c 100644 (file)
@@ -25,7 +25,7 @@ STACK_KEYS = (
     STACK_CREATION_TIME, STACK_UPDATED_TIME, STACK_DELETION_TIME,
     STACK_NOTIFICATION_TOPICS,
     STACK_DESCRIPTION, STACK_TMPL_DESCRIPTION,
-    STACK_PARAMETERS, STACK_OUTPUTS,
+    STACK_PARAMETERS, STACK_OUTPUTS, STACK_ACTION,
     STACK_STATUS, STACK_STATUS_DATA, STACK_CAPABILITIES,
     STACK_DISABLE_ROLLBACK, STACK_TIMEOUT,
 ) = (
@@ -33,7 +33,7 @@ STACK_KEYS = (
     'creation_time', 'updated_time', 'deletion_time',
     'notification_topics',
     'description', 'template_description',
-    'parameters', 'outputs',
+    'parameters', 'outputs', 'stack_action',
     'stack_status', 'stack_status_reason', 'capabilities',
     'disable_rollback', 'timeout_mins'
 )
index cf00633c48236e4fdda943e17eb0a9359a9492db..ba2307e6b0c15d40d1708ad6079a30e022c2a6c4 100644 (file)
@@ -122,7 +122,8 @@ class CfnStackControllerTest(HeatTestCase):
                         u'stack_status_reason': u'Stack successfully created',
                         u'creation_time': u'2012-07-09T09:12:45Z',
                         u'stack_name': u'wordpress',
-                        u'stack_status': u'CREATE_COMPLETE'}]
+                        u'stack_action': u'CREATE',
+                        u'stack_status': u'COMPLETE'}]
         self.m.StubOutWithMock(rpc, 'call')
         rpc.call(dummy_req.context, self.topic,
                  {'namespace': None,
@@ -220,7 +221,8 @@ class CfnStackControllerTest(HeatTestCase):
                        u'creation_time': u'2012-07-09T09:12:45Z',
                        u'stack_name': u'wordpress',
                        u'notification_topics': [],
-                       u'stack_status': u'CREATE_COMPLETE',
+                       u'stack_action': u'CREATE',
+                       u'stack_status': u'COMPLETE',
                        u'description': u'blah',
                        u'disable_rollback': 'true',
                        u'timeout_mins':60,
@@ -309,7 +311,8 @@ class CfnStackControllerTest(HeatTestCase):
                         u'creation_time': u'2012-07-09T09:12:45Z',
                         u'stack_name': u'wordpress',
                         u'notification_topics': [],
-                        u'stack_status': u'CREATE_COMPLETE',
+                        u'stack_action': u'CREATE',
+                        u'stack_status': u'COMPLETE',
                         u'description': u'blah',
                         u'disable_rollback': 'true',
                         u'timeout_mins':60,
index cb3366113297b5d6f71ed35ccfd368fe7f505bac..2d8232f3772a67c0506f5f01c8c8fd101dc9b77e 100644 (file)
@@ -267,7 +267,8 @@ class StackControllerTest(ControllerTest, HeatTestCase):
                 u'stack_status_reason': u'Stack successfully created',
                 u'creation_time': u'2012-07-09T09:12:45Z',
                 u'stack_name': identity.stack_name,
-                u'stack_status': u'CREATE_COMPLETE',
+                u'stack_action': u'CREATE',
+                u'stack_status': u'COMPLETE',
                 u'parameters': {},
                 u'outputs': [],
                 u'notification_topics': [],
@@ -604,7 +605,8 @@ class StackControllerTest(ControllerTest, HeatTestCase):
                 u'creation_time': u'2012-07-09T09:12:45Z',
                 u'stack_name': identity.stack_name,
                 u'notification_topics': [],
-                u'stack_status': u'CREATE_COMPLETE',
+                u'stack_action': u'CREATE',
+                u'stack_status': u'COMPLETE',
                 u'description': u'blah',
                 u'disable_rollback': True,
                 u'timeout_mins':60,
index 55018db675d2d3e40781b41cc84077ed9acd48a3..c1a4123b0de28042ec1f54c90afdca8bc6f469e6 100644 (file)
@@ -220,8 +220,10 @@ class stackCreateTest(HeatTestCase):
 
         rsrc = stack.resources['WebServer']
         self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
+        self.assertEqual((stack.DELETE, stack.COMPLETE), rsrc.state)
         self.assertEqual(db_api.stack_get(ctx, stack_id), None)
-        self.assertEqual(db_s.status, 'DELETE_COMPLETE')
+        self.assertEqual(db_s.action, 'DELETE')
+        self.assertEqual(db_s.status, 'COMPLETE')
 
 
 class stackServiceCreateUpdateDeleteTest(HeatTestCase):
index bb9edbbb315fe0f73eb2dd101bccd43469371842..39458d35b094c36e90a4849381a94d0e72e9027c 100644 (file)
@@ -174,7 +174,8 @@ class MetadataRefreshTest(HeatTestCase):
         self.m.ReplayAll()
         self.stack.create()
 
-        self.assertEqual(self.stack.state, self.stack.CREATE_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (self.stack.CREATE, self.stack.COMPLETE))
 
         s1 = self.stack.resources['S1']
         s2 = self.stack.resources['S2']
@@ -267,7 +268,8 @@ class WaitCondMetadataUpdateTest(HeatTestCase):
         self.m.ReplayAll()
         self.stack.create()
 
-        self.assertEqual(self.stack.state, self.stack.CREATE_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (self.stack.CREATE, self.stack.COMPLETE))
 
         self.assertEqual(watch.FnGetAtt('Data'), '{"123": "foo"}')
         self.assertEqual(inst.metadata['test'], '{"123": "foo"}')
index 77d90386ed05d94cc945457e0fdeefc85dd6a7b3..5945b2ffcddea35ce6f0f382f435d1b6d80ba067 100644 (file)
@@ -55,7 +55,7 @@ Outputs:
         t = template_format.parse(template)
         stack = self.parse_stack(t)
         stack.create()
-        self.assertEqual(stack.state, stack.CREATE_COMPLETE)
+        self.assertEqual(stack.state, (stack.CREATE, stack.COMPLETE))
         return stack
 
     def parse_stack(self, t):
index d0637077139ca03677a431b118ade099e3f50094..f323766f9d16be41d33ee8aefa911294a0a4b591 100644 (file)
@@ -462,22 +462,40 @@ class StackTest(HeatTestCase):
 
     def test_state_defaults(self):
         stack = parser.Stack(None, 'test_stack', parser.Template({}))
-        self.assertEqual(stack.state, None)
-        self.assertEqual(stack.state_description, '')
+        self.assertEqual(stack.state, (None, None))
+        self.assertEqual(stack.status_reason, '')
 
     def test_state(self):
         stack = parser.Stack(None, 'test_stack', parser.Template({}),
-                             state='foo')
-        self.assertEqual(stack.state, 'foo')
-        stack.state_set('bar', '')
-        self.assertEqual(stack.state, 'bar')
-
-    def test_state_description(self):
+                             action=parser.Stack.CREATE,
+                             status=parser.Stack.IN_PROGRESS)
+        self.assertEqual(stack.state,
+                         (parser.Stack.CREATE, parser.Stack.IN_PROGRESS))
+        stack.state_set(parser.Stack.CREATE, parser.Stack.COMPLETE, 'test')
+        self.assertEqual(stack.state,
+                         (parser.Stack.CREATE, parser.Stack.COMPLETE))
+        stack.state_set(parser.Stack.DELETE, parser.Stack.COMPLETE, 'test')
+        self.assertEqual(stack.state,
+                         (parser.Stack.DELETE, parser.Stack.COMPLETE))
+
+    def test_state_bad(self):
+        stack = parser.Stack(None, 'test_stack', parser.Template({}),
+                             action=parser.Stack.CREATE,
+                             status=parser.Stack.IN_PROGRESS)
+        self.assertEqual(stack.state,
+                         (parser.Stack.CREATE, parser.Stack.IN_PROGRESS))
+        self.assertRaises(ValueError, stack.state_set,
+                          'baad', parser.Stack.COMPLETE, 'test')
+        self.assertRaises(ValueError, stack.state_set,
+                          parser.Stack.CREATE, 'oops', 'test')
+
+    def test_status_reason(self):
         stack = parser.Stack(None, 'test_stack', parser.Template({}),
-                             state_description='quux')
-        self.assertEqual(stack.state_description, 'quux')
-        stack.state_set('blarg', 'wibble')
-        self.assertEqual(stack.state_description, 'wibble')
+                             status_reason='quux')
+        self.assertEqual(stack.status_reason, 'quux')
+        stack.state_set(parser.Stack.CREATE, parser.Stack.IN_PROGRESS,
+                        'wibble')
+        self.assertEqual(stack.status_reason, 'wibble')
 
     def test_load_nonexistant_id(self):
         self.assertRaises(exception.NotFound, parser.Stack.load,
@@ -542,7 +560,7 @@ class StackTest(HeatTestCase):
         self.assertEqual(self.stack.updated_time, None)
         self.stack.store()
         stored_time = self.stack.updated_time
-        self.stack.state_set(self.stack.CREATE_IN_PROGRESS, 'testing')
+        self.stack.state_set(self.stack.CREATE, self.stack.IN_PROGRESS, 'test')
         self.assertNotEqual(self.stack.updated_time, None)
         self.assertNotEqual(self.stack.updated_time, stored_time)
 
@@ -559,7 +577,8 @@ class StackTest(HeatTestCase):
 
         db_s = db_api.stack_get(self.ctx, stack_id)
         self.assertEqual(db_s, None)
-        self.assertEqual(self.stack.state, self.stack.DELETE_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.DELETE, parser.Stack.COMPLETE))
 
     @stack_delete_after
     def test_delete_rollback(self):
@@ -574,7 +593,8 @@ class StackTest(HeatTestCase):
 
         db_s = db_api.stack_get(self.ctx, stack_id)
         self.assertEqual(db_s, None)
-        self.assertEqual(self.stack.state, self.stack.ROLLBACK_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.ROLLBACK, parser.Stack.COMPLETE))
 
     @stack_delete_after
     def test_delete_badaction(self):
@@ -589,16 +609,20 @@ class StackTest(HeatTestCase):
 
         db_s = db_api.stack_get(self.ctx, stack_id)
         self.assertNotEqual(db_s, None)
-        self.assertEqual(self.stack.state, self.stack.DELETE_FAILED)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.DELETE, parser.Stack.FAILED))
 
     @stack_delete_after
     def test_update_badstate(self):
         self.stack = parser.Stack(self.ctx, 'test_stack', parser.Template({}),
-                                  state=parser.Stack.CREATE_FAILED)
+                                  action=parser.Stack.CREATE,
+                                  status=parser.Stack.FAILED)
         stack_id = self.stack.store()
-        self.assertEqual(self.stack.state, parser.Stack.CREATE_FAILED)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.CREATE, parser.Stack.FAILED))
         self.stack.update({})
-        self.assertEqual(self.stack.state, parser.Stack.UPDATE_FAILED)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.UPDATE, parser.Stack.FAILED))
 
     @stack_delete_after
     def test_resource_by_refid(self):
@@ -608,7 +632,8 @@ class StackTest(HeatTestCase):
                                   template.Template(tmpl))
         self.stack.store()
         self.stack.create()
-        self.assertEqual(self.stack.state, parser.Stack.CREATE_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.CREATE, parser.Stack.COMPLETE))
         self.assertTrue('AResource' in self.stack)
         rsrc = self.stack['AResource']
         rsrc.resource_id_set('aaaa')
@@ -630,7 +655,8 @@ class StackTest(HeatTestCase):
                                   template.Template(tmpl))
         self.stack.store()
         self.stack.create()
-        self.assertEqual(self.stack.state, parser.Stack.CREATE_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.CREATE, parser.Stack.COMPLETE))
 
         tmpl2 = {'Resources': {
                  'AResource': {'Type': 'GenericResourceType'},
@@ -638,7 +664,8 @@ class StackTest(HeatTestCase):
         updated_stack = parser.Stack(self.ctx, 'updated_stack',
                                      template.Template(tmpl2))
         self.stack.update(updated_stack)
-        self.assertEqual(self.stack.state, parser.Stack.UPDATE_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.UPDATE, parser.Stack.COMPLETE))
         self.assertTrue('BResource' in self.stack)
 
     @stack_delete_after
@@ -651,14 +678,16 @@ class StackTest(HeatTestCase):
                                   template.Template(tmpl))
         self.stack.store()
         self.stack.create()
-        self.assertEqual(self.stack.state, parser.Stack.CREATE_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.CREATE, parser.Stack.COMPLETE))
 
         tmpl2 = {'Resources': {'AResource': {'Type': 'GenericResourceType'}}}
 
         updated_stack = parser.Stack(self.ctx, 'updated_stack',
                                      template.Template(tmpl2))
         self.stack.update(updated_stack)
-        self.assertEqual(self.stack.state, parser.Stack.UPDATE_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.UPDATE, parser.Stack.COMPLETE))
         self.assertFalse('BResource' in self.stack)
 
     @stack_delete_after
@@ -670,7 +699,8 @@ class StackTest(HeatTestCase):
                                   template.Template(tmpl))
         self.stack.store()
         self.stack.create()
-        self.assertEqual(self.stack.state, parser.Stack.CREATE_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.CREATE, parser.Stack.COMPLETE))
 
         tmpl2 = {'Description': 'BTemplate',
                  'Resources': {'AResource': {'Type': 'GenericResourceType'}}}
@@ -678,7 +708,8 @@ class StackTest(HeatTestCase):
         updated_stack = parser.Stack(self.ctx, 'updated_stack',
                                      template.Template(tmpl2))
         self.stack.update(updated_stack)
-        self.assertEqual(self.stack.state, parser.Stack.UPDATE_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.UPDATE, parser.Stack.COMPLETE))
         self.assertEqual(self.stack.t[template.DESCRIPTION], 'BTemplate')
 
     @stack_delete_after
@@ -694,7 +725,8 @@ class StackTest(HeatTestCase):
                                   template.Template(tmpl))
         self.stack.store()
         self.stack.create()
-        self.assertEqual(self.stack.state, parser.Stack.CREATE_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.CREATE, parser.Stack.COMPLETE))
 
         tmpl2 = {'Resources': {'AResource': {'Type': 'GenericResourceType',
                                              'Properties': {'Foo': 'xyz'}}}}
@@ -708,7 +740,8 @@ class StackTest(HeatTestCase):
         self.m.ReplayAll()
 
         self.stack.update(updated_stack)
-        self.assertEqual(self.stack.state, parser.Stack.UPDATE_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.UPDATE, parser.Stack.COMPLETE))
         self.assertEqual(self.stack['AResource'].properties['Foo'], 'xyz')
         self.m.VerifyAll()
 
@@ -726,7 +759,8 @@ class StackTest(HeatTestCase):
                                   disable_rollback=True)
         self.stack.store()
         self.stack.create()
-        self.assertEqual(self.stack.state, parser.Stack.CREATE_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.CREATE, parser.Stack.COMPLETE))
 
         res = self.stack['AResource']
         res.update_allowed_keys = ('Properties',)
@@ -748,7 +782,8 @@ class StackTest(HeatTestCase):
         self.m.ReplayAll()
 
         self.stack.update(updated_stack)
-        self.assertEqual(self.stack.state, parser.Stack.UPDATE_FAILED)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.UPDATE, parser.Stack.FAILED))
         self.m.VerifyAll()
 
     @stack_delete_after
@@ -765,7 +800,8 @@ class StackTest(HeatTestCase):
                                   disable_rollback=True)
         self.stack.store()
         self.stack.create()
-        self.assertEqual(self.stack.state, parser.Stack.CREATE_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.CREATE, parser.Stack.COMPLETE))
 
         tmpl2 = {'Resources': {'AResource': {'Type': 'GenericResourceType',
                                              'Properties': {'Foo': 'xyz'}}}}
@@ -784,7 +820,8 @@ class StackTest(HeatTestCase):
         self.m.ReplayAll()
 
         self.stack.update(updated_stack)
-        self.assertEqual(self.stack.state, parser.Stack.UPDATE_FAILED)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.UPDATE, parser.Stack.FAILED))
         self.m.VerifyAll()
         # Unset here so destroy() is not stubbed for stack.delete cleanup
         self.m.UnsetStubs()
@@ -803,7 +840,8 @@ class StackTest(HeatTestCase):
                                   disable_rollback=True)
         self.stack.store()
         self.stack.create()
-        self.assertEqual(self.stack.state, parser.Stack.CREATE_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.CREATE, parser.Stack.COMPLETE))
 
         tmpl2 = {'Resources': {'AResource': {'Type': 'GenericResourceType',
                                              'Properties': {'Foo': 'xyz'}}}}
@@ -821,7 +859,8 @@ class StackTest(HeatTestCase):
         self.m.ReplayAll()
 
         self.stack.update(updated_stack)
-        self.assertEqual(self.stack.state, parser.Stack.UPDATE_FAILED)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.UPDATE, parser.Stack.FAILED))
         self.m.VerifyAll()
 
     @stack_delete_after
@@ -832,7 +871,8 @@ class StackTest(HeatTestCase):
                                   template.Template(tmpl))
         self.stack.store()
         self.stack.create()
-        self.assertEqual(self.stack.state, parser.Stack.CREATE_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.CREATE, parser.Stack.COMPLETE))
 
         tmpl2 = {'Resources': {
                  'AResource': {'Type': 'GenericResourceType'},
@@ -846,7 +886,8 @@ class StackTest(HeatTestCase):
         self.m.ReplayAll()
 
         self.stack.update(updated_stack)
-        self.assertEqual(self.stack.state, parser.Stack.UPDATE_FAILED)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.UPDATE, parser.Stack.FAILED))
         self.assertTrue('BResource' in self.stack)
 
         # Reload the stack from the DB and prove that it contains the failed
@@ -869,7 +910,8 @@ class StackTest(HeatTestCase):
                                   disable_rollback=False)
         self.stack.store()
         self.stack.create()
-        self.assertEqual(self.stack.state, parser.Stack.CREATE_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.CREATE, parser.Stack.COMPLETE))
 
         tmpl2 = {'Resources': {'AResource': {'Type': 'GenericResourceType',
                                              'Properties': {'Foo': 'xyz'}}}}
@@ -889,7 +931,8 @@ class StackTest(HeatTestCase):
         self.m.ReplayAll()
 
         self.stack.update(updated_stack)
-        self.assertEqual(self.stack.state, parser.Stack.ROLLBACK_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.ROLLBACK, parser.Stack.COMPLETE))
         self.assertEqual(self.stack['AResource'].properties['Foo'], 'abc')
         self.m.VerifyAll()
 
@@ -907,7 +950,8 @@ class StackTest(HeatTestCase):
                                   disable_rollback=False)
         self.stack.store()
         self.stack.create()
-        self.assertEqual(self.stack.state, parser.Stack.CREATE_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.CREATE, parser.Stack.COMPLETE))
 
         tmpl2 = {'Resources': {'AResource': {'Type': 'GenericResourceType',
                                              'Properties': {'Foo': 'xyz'}}}}
@@ -927,7 +971,8 @@ class StackTest(HeatTestCase):
         self.m.ReplayAll()
 
         self.stack.update(updated_stack)
-        self.assertEqual(self.stack.state, parser.Stack.ROLLBACK_FAILED)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.ROLLBACK, parser.Stack.FAILED))
         self.m.VerifyAll()
 
     @stack_delete_after
@@ -939,7 +984,8 @@ class StackTest(HeatTestCase):
                                   disable_rollback=False)
         self.stack.store()
         self.stack.create()
-        self.assertEqual(self.stack.state, parser.Stack.CREATE_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.CREATE, parser.Stack.COMPLETE))
 
         tmpl2 = {'Resources': {
                  'AResource': {'Type': 'GenericResourceType'},
@@ -955,7 +1001,8 @@ class StackTest(HeatTestCase):
         self.m.ReplayAll()
 
         self.stack.update(updated_stack)
-        self.assertEqual(self.stack.state, parser.Stack.ROLLBACK_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.ROLLBACK, parser.Stack.COMPLETE))
         self.assertFalse('BResource' in self.stack)
         self.m.VerifyAll()
 
@@ -970,7 +1017,8 @@ class StackTest(HeatTestCase):
                                   disable_rollback=False)
         self.stack.store()
         self.stack.create()
-        self.assertEqual(self.stack.state, parser.Stack.CREATE_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.CREATE, parser.Stack.COMPLETE))
 
         tmpl2 = {'Resources': {'AResource': {'Type': 'GenericResourceType'}}}
 
@@ -984,7 +1032,8 @@ class StackTest(HeatTestCase):
         self.m.ReplayAll()
 
         self.stack.update(updated_stack)
-        self.assertEqual(self.stack.state, parser.Stack.ROLLBACK_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.ROLLBACK, parser.Stack.COMPLETE))
         self.assertTrue('BResource' in self.stack)
         self.m.VerifyAll()
         # Unset here so delete() is not stubbed for stack.delete cleanup
@@ -1023,7 +1072,8 @@ class StackTest(HeatTestCase):
         self.stack.store()
         self.stack.create()
         self.m.VerifyAll()
-        self.assertEqual(self.stack.state, parser.Stack.CREATE_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.CREATE, parser.Stack.COMPLETE))
         self.assertEqual(self.stack['AResource'].properties['Foo'], 'abc')
         self.assertEqual(self.stack['BResource'].properties['Foo'],
                          'AResource')
@@ -1042,7 +1092,8 @@ class StackTest(HeatTestCase):
         updated_stack = parser.Stack(self.ctx, 'updated_stack',
                                      template.Template(tmpl2))
         self.stack.update(updated_stack)
-        self.assertEqual(self.stack.state, parser.Stack.UPDATE_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.UPDATE, parser.Stack.COMPLETE))
         self.assertEqual(self.stack['AResource'].properties['Foo'], 'smelly')
         self.assertEqual(self.stack['BResource'].properties['Foo'], 'inst-007')
         self.m.VerifyAll()
@@ -1082,7 +1133,8 @@ class StackTest(HeatTestCase):
         self.stack.create()
         self.m.VerifyAll()
 
-        self.assertEqual(self.stack.state, parser.Stack.CREATE_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.CREATE, parser.Stack.COMPLETE))
         self.assertEqual(self.stack['AResource'].properties['Foo'], 'abc')
         self.assertEqual(self.stack['BResource'].properties['Foo'],
                          'AResource')
@@ -1110,7 +1162,8 @@ class StackTest(HeatTestCase):
                                      template.Template(tmpl2),
                                      disable_rollback=False)
         self.stack.update(updated_stack)
-        self.assertEqual(self.stack.state, parser.Stack.ROLLBACK_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.ROLLBACK, parser.Stack.COMPLETE))
         self.assertEqual(self.stack['AResource'].properties['Foo'], 'abc')
 
         self.m.VerifyAll()
@@ -1150,7 +1203,8 @@ class StackTest(HeatTestCase):
         self.stack.create()
         self.m.VerifyAll()
 
-        self.assertEqual(self.stack.state, parser.Stack.CREATE_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.CREATE, parser.Stack.COMPLETE))
         self.assertEqual(self.stack['AResource'].properties['Foo'], 'abc')
         self.assertEqual(self.stack['BResource'].properties['Foo'],
                          'AResource')
@@ -1166,19 +1220,19 @@ class StackTest(HeatTestCase):
             'AResource')
         generic_rsrc.GenericResource.FnGetRefId().AndReturn(
             'inst-007')
-        # self.state_set(self.UPDATE_IN_PROGRESS)
+        # self.state_set(self.UPDATE, self.IN_PROGRESS)
         generic_rsrc.GenericResource.FnGetRefId().AndReturn(
             'inst-007')
-        # self.state_set(self.DELETE_IN_PROGRESS)
+        # self.state_set(self.DELETE, self.IN_PROGRESS)
         generic_rsrc.GenericResource.FnGetRefId().AndReturn(
             'inst-007')
-        # self.state_set(self.DELETE_COMPLETE)
+        # self.state_set(self.DELETE, self.COMPLETE)
         generic_rsrc.GenericResource.FnGetRefId().AndReturn(
             'inst-007')
         # self.properties.validate()
         generic_rsrc.GenericResource.FnGetRefId().AndReturn(
             'inst-007')
-        # self.state_set(self.CREATE_IN_PROGRESS)
+        # self.state_set(self.CREATE, self.IN_PROGRESS)
         generic_rsrc.GenericResource.FnGetRefId().AndReturn(
             'inst-007')
 
@@ -1191,10 +1245,10 @@ class StackTest(HeatTestCase):
         # resource.UpdateReplace because we've not specified the modified
         # key/property in update_allowed_keys/update_allowed_properties
 
-        # self.state_set(self.DELETE_IN_PROGRESS)
+        # self.state_set(self.DELETE, self.IN_PROGRESS)
         generic_rsrc.GenericResource.FnGetRefId().AndReturn(
             'inst-007')
-        # self.state_set(self.DELETE_IN_PROGRESS)
+        # self.state_set(self.DELETE, self.IN_PROGRESS)
         generic_rsrc.GenericResource.FnGetRefId().AndReturn(
             'inst-007')
 
@@ -1211,7 +1265,8 @@ class StackTest(HeatTestCase):
                                      template.Template(tmpl2),
                                      disable_rollback=False)
         self.stack.update(updated_stack)
-        self.assertEqual(self.stack.state, parser.Stack.ROLLBACK_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.ROLLBACK, parser.Stack.COMPLETE))
         self.assertEqual(self.stack['AResource'].properties['Foo'], 'abc')
 
         self.m.VerifyAll()
@@ -1236,8 +1291,9 @@ class StackTest(HeatTestCase):
 
         stack.create()
 
-        self.assertEqual(stack.state, stack.CREATE_FAILED)
-        self.assertEqual(stack.state_description, 'Timed out')
+        self.assertEqual(stack.state,
+                         (parser.Stack.CREATE, parser.Stack.FAILED))
+        self.assertEqual(stack.status_reason, 'Timed out')
 
         self.m.VerifyAll()
 
@@ -1296,7 +1352,8 @@ class StackTest(HeatTestCase):
                                   template.Template(tmpl))
         self.stack.store()
         self.stack.create()
-        self.assertEqual(self.stack.state, parser.Stack.CREATE_COMPLETE)
+        self.assertEqual(self.stack.state,
+                         (parser.Stack.CREATE, parser.Stack.COMPLETE))
         self.assertTrue('AResource' in self.stack)
         rsrc = self.stack['AResource']
         rsrc.resource_id_set('aaaa')
index 5244ac8e830e0f5187b564af252a826aa12e8768..83695516d538e737ee2e9bd078108ad18575de18 100644 (file)
@@ -460,7 +460,7 @@ Resources:
 
         stack = self.create_stack(self.test_template)
         try:
-            self.assertEqual(stack.CREATE_COMPLETE, stack.state)
+            self.assertEqual((stack.CREATE, stack.COMPLETE), stack.state)
             rsrc = stack['the_nic']
             self.assertResourceState(rsrc, 'dddd')
 
@@ -510,7 +510,7 @@ Resources:
 
         stack = self.create_stack(self.test_template_error_no_ref)
         try:
-            self.assertEqual(stack.CREATE_FAILED, stack.state)
+            self.assertEqual((stack.CREATE, stack.FAILED), stack.state)
             rsrc = stack['the_nic']
             self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
             reason = rsrc.status_reason
index 46453dcec711c0f1dc8baee5a91b2b3fae98056f..5066cd081d041e39f2511254a5ae243ac85ce83f 100644 (file)
@@ -53,7 +53,8 @@ class WatchRuleTest(HeatTestCase):
         tmpl = parser.Template(empty_tmpl)
         stack_name = 'dummystack'
         dummy_stack = parser.Stack(ctx, stack_name, tmpl)
-        dummy_stack.state_set(dummy_stack.CREATE_COMPLETE, 'Testing')
+        dummy_stack.state_set(dummy_stack.CREATE, dummy_stack.COMPLETE,
+                              'Testing')
         dummy_stack.store()
 
         cls.stack_id = dummy_stack.id