Split wait condition handle into separate files

Move OS::Heat::*Handle resource to
/resources/openstack/wait_condition_handle.py and move
AWS::CloudFormation::WaitConditionHandle resource to
/resources/aws/wait_condition_handle.py.

Change-Id: I2f7d34058356d381ffbf4f580316c9593492402c
Implements: blueprint decouple-aws-os-resources
This commit is contained in:
huangtianhua 2014-12-05 10:36:56 +08:00
parent c2bf586880
commit 7588fdbb26
8 changed files with 301 additions and 256 deletions

View File

@ -16,8 +16,8 @@ from heat.common import identifier
from heat.engine import attributes from heat.engine import attributes
from heat.engine import constraints from heat.engine import constraints
from heat.engine import properties from heat.engine import properties
from heat.engine.resources.aws import wait_condition_handle as aws_wch
from heat.engine.resources.openstack import wait_condition as heat_wc from heat.engine.resources.openstack import wait_condition as heat_wc
from heat.engine.resources import wait_condition as wc_base
from heat.engine import support from heat.engine import support
@ -92,7 +92,7 @@ class WaitCondition(heat_wc.HeatWaitCondition):
raise ValueError(_("WaitCondition invalid Handle %s") % raise ValueError(_("WaitCondition invalid Handle %s") %
handle_id.resource_name) handle_id.resource_name)
if not isinstance(self.stack[handle_id.resource_name], if not isinstance(self.stack[handle_id.resource_name],
wc_base.WaitConditionHandle): aws_wch.WaitConditionHandle):
raise ValueError(_("WaitCondition invalid Handle %s") % raise ValueError(_("WaitCondition invalid Handle %s") %
handle_id.resource_name) handle_id.resource_name)

View File

@ -0,0 +1,75 @@
#
# 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.
import six
from heat.engine.resources import wait_condition as wc_base
from heat.engine import signal_responder
from heat.engine import support
class WaitConditionHandle(wc_base.BaseWaitConditionHandle):
'''
the main point of this class is to :
have no dependencies (so the instance can reference it)
generate a unique url (to be returned in the reference)
then the cfn-signal will use this url to post to and
WaitCondition will poll it to see if has been written to.
'''
support_status = support.SupportStatus(version='2014.1')
METADATA_KEYS = (
DATA, REASON, STATUS, UNIQUE_ID
) = (
'Data', 'Reason', 'Status', 'UniqueId'
)
def handle_create(self):
super(WaitConditionHandle, self).handle_create()
self.resource_id_set(self._get_user_id())
def FnGetRefId(self):
'''
Override the default resource FnGetRefId so we return the signed URL
'''
if self.resource_id:
wc = signal_responder.WAITCONDITION
return six.text_type(self._get_signed_url(signal_type=wc))
else:
return six.text_type(self.name)
def metadata_update(self, new_metadata=None):
"""DEPRECATED. Should use handle_signal instead."""
self.handle_signal(details=new_metadata)
def handle_signal(self, details=None):
'''
Validate and update the resource metadata
metadata must use the following format:
{
"Status" : "Status (must be SUCCESS or FAILURE)",
"UniqueId" : "Some ID, should be unique for Count>1",
"Data" : "Arbitrary Data",
"Reason" : "Reason String"
}
'''
if details is None:
return
return super(WaitConditionHandle, self).handle_signal(details)
def resource_mapping():
return {
'AWS::CloudFormation::WaitConditionHandle': WaitConditionHandle,
}

View File

@ -0,0 +1,157 @@
#
# 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.
import uuid
from heat.common.i18n import _
from heat.engine import attributes
from heat.engine import resource
from heat.engine.resources.aws import wait_condition_handle as aws_wch
from heat.engine.resources import wait_condition as wc_base
from heat.engine import support
class HeatWaitConditionHandle(wc_base.BaseWaitConditionHandle):
support_status = support.SupportStatus(version='2014.2')
METADATA_KEYS = (
DATA, REASON, STATUS, UNIQUE_ID
) = (
'data', 'reason', 'status', 'id'
)
ATTRIBUTES = (
TOKEN,
ENDPOINT,
CURL_CLI,
) = (
'token',
'endpoint',
'curl_cli',
)
attributes_schema = {
TOKEN: attributes.Schema(
_('Token for stack-user which can be used for signalling handle'),
cache_mode=attributes.Schema.CACHE_NONE
),
ENDPOINT: attributes.Schema(
_('Endpoint/url which can be used for signalling handle'),
cache_mode=attributes.Schema.CACHE_NONE
),
CURL_CLI: attributes.Schema(
_('Convenience attribute, provides curl CLI command '
'prefix, which can be used for signalling handle completion or '
'failure. You can signal success by adding '
'--data-binary \'{"status": "SUCCESS"}\' '
', or signal failure by adding '
'--data-binary \'{"status": "FAILURE"}\''),
cache_mode=attributes.Schema.CACHE_NONE
),
}
def handle_create(self):
password = uuid.uuid4().hex
self.data_set('password', password, True)
self._create_user()
self.resource_id_set(self._get_user_id())
# FIXME(shardy): The assumption here is that token expiry > timeout
# but we probably need a check here to fail fast if that's not true
# Also need to implement an update property, such that the handle
# can be replaced on update which will replace the token
token = self._user_token()
self.data_set('token', token, True)
self.data_set('endpoint', '%s/signal' % self._get_resource_endpoint())
def _get_resource_endpoint(self):
# Get the endpoint from stack.clients then replace the context
# project_id with the path to the resource (which includes the
# context project_id), then replace the context project with
# the one needed for signalling from the stack_user_project
heat_client_plugin = self.stack.clients.client_plugin('heat')
endpoint = heat_client_plugin.get_heat_url()
rsrc_ep = endpoint.replace(self.context.tenant_id,
self.identifier().url_path())
return rsrc_ep.replace(self.context.tenant_id,
self.stack.stack_user_project_id)
def handle_delete(self):
self._delete_user()
@property
def password(self):
return self.data().get('password')
def _resolve_attribute(self, key):
if self.resource_id:
if key == self.TOKEN:
return self.data().get('token')
elif key == self.ENDPOINT:
return self.data().get('endpoint')
elif key == self.CURL_CLI:
# Construct curl command for template-author convenience
return ('curl -i -X POST '
'-H \'X-Auth-Token: %(token)s\' '
'-H \'Content-Type: application/json\' '
'-H \'Accept: application/json\' '
'%(endpoint)s' %
dict(token=self.data().get('token'),
endpoint=self.data().get('endpoint')))
def handle_signal(self, details=None):
'''
Validate and update the resource metadata.
metadata is not mandatory, but if passed it must use the following
format:
{
"status" : "Status (must be SUCCESS or FAILURE)",
"data" : "Arbitrary data",
"reason" : "Reason string"
}
Optionally "id" may also be specified, but if missing the index
of the signal received will be used.
'''
rsrc_metadata = self.metadata_get(refresh=True)
signal_num = len(rsrc_metadata) + 1
reason = 'Signal %s received' % signal_num
# Tolerate missing values, default to success
metadata = details or {}
metadata.setdefault(self.REASON, reason)
metadata.setdefault(self.DATA, None)
metadata.setdefault(self.UNIQUE_ID, signal_num)
metadata.setdefault(self.STATUS, self.STATUS_SUCCESS)
return super(HeatWaitConditionHandle, self).handle_signal(metadata)
class UpdateWaitConditionHandle(aws_wch.WaitConditionHandle):
'''
This works identically to a regular WaitConditionHandle, except that
on update it clears all signals received and changes the handle. Using
this handle means that you must setup the signal senders to send their
signals again any time the update handle changes. This allows us to roll
out new configurations and be confident that they are rolled out once
UPDATE COMPLETE is reached.
'''
support_status = support.SupportStatus(version='2014.1')
def update(self, after, before=None, prev_resource=None):
raise resource.UpdateReplace(self.name)
def resource_mapping():
return {
'OS::Heat::WaitConditionHandle': HeatWaitConditionHandle,
'OS::Heat::UpdateWaitConditionHandle': UpdateWaitConditionHandle,
}

View File

@ -11,19 +11,11 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import six
import uuid
from heat.common import exception from heat.common import exception
from heat.common.i18n import _ from heat.common.i18n import _
from heat.common.i18n import _LE from heat.common.i18n import _LE
from heat.common.i18n import _LW from heat.common.i18n import _LW
from heat.engine import attributes
from heat.engine import resource
from heat.engine import signal_responder from heat.engine import signal_responder
from heat.engine import support
from heat.openstack.common import log as logging from heat.openstack.common import log as logging
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -96,186 +88,6 @@ class BaseWaitConditionHandle(signal_responder.SignalResponder):
if v[self.STATUS] == status] if v[self.STATUS] == status]
class HeatWaitConditionHandle(BaseWaitConditionHandle):
support_status = support.SupportStatus(version='2014.2')
METADATA_KEYS = (
DATA, REASON, STATUS, UNIQUE_ID
) = (
'data', 'reason', 'status', 'id'
)
ATTRIBUTES = (
TOKEN,
ENDPOINT,
CURL_CLI,
) = (
'token',
'endpoint',
'curl_cli',
)
attributes_schema = {
TOKEN: attributes.Schema(
_('Token for stack-user which can be used for signalling handle'),
cache_mode=attributes.Schema.CACHE_NONE
),
ENDPOINT: attributes.Schema(
_('Endpoint/url which can be used for signalling handle'),
cache_mode=attributes.Schema.CACHE_NONE
),
CURL_CLI: attributes.Schema(
_('Convenience attribute, provides curl CLI command '
'prefix, which can be used for signalling handle completion or '
'failure. You can signal success by adding '
'--data-binary \'{"status": "SUCCESS"}\' '
', or signal failure by adding '
'--data-binary \'{"status": "FAILURE"}\''),
cache_mode=attributes.Schema.CACHE_NONE
),
}
def handle_create(self):
password = uuid.uuid4().hex
self.data_set('password', password, True)
self._create_user()
self.resource_id_set(self._get_user_id())
# FIXME(shardy): The assumption here is that token expiry > timeout
# but we probably need a check here to fail fast if that's not true
# Also need to implement an update property, such that the handle
# can be replaced on update which will replace the token
token = self._user_token()
self.data_set('token', token, True)
self.data_set('endpoint', '%s/signal' % self._get_resource_endpoint())
def _get_resource_endpoint(self):
# Get the endpoint from stack.clients then replace the context
# project_id with the path to the resource (which includes the
# context project_id), then replace the context project with
# the one needed for signalling from the stack_user_project
heat_client_plugin = self.stack.clients.client_plugin('heat')
endpoint = heat_client_plugin.get_heat_url()
rsrc_ep = endpoint.replace(self.context.tenant_id,
self.identifier().url_path())
return rsrc_ep.replace(self.context.tenant_id,
self.stack.stack_user_project_id)
def handle_delete(self):
self._delete_user()
@property
def password(self):
return self.data().get('password')
def _resolve_attribute(self, key):
if self.resource_id:
if key == self.TOKEN:
return self.data().get('token')
elif key == self.ENDPOINT:
return self.data().get('endpoint')
elif key == self.CURL_CLI:
# Construct curl command for template-author convenience
return ('curl -i -X POST '
'-H \'X-Auth-Token: %(token)s\' '
'-H \'Content-Type: application/json\' '
'-H \'Accept: application/json\' '
'%(endpoint)s' %
dict(token=self.data().get('token'),
endpoint=self.data().get('endpoint')))
def handle_signal(self, details=None):
'''
Validate and update the resource metadata.
metadata is not mandatory, but if passed it must use the following
format:
{
"status" : "Status (must be SUCCESS or FAILURE)",
"data" : "Arbitrary data",
"reason" : "Reason string"
}
Optionally "id" may also be specified, but if missing the index
of the signal received will be used.
'''
rsrc_metadata = self.metadata_get(refresh=True)
signal_num = len(rsrc_metadata) + 1
reason = 'Signal %s received' % signal_num
# Tolerate missing values, default to success
metadata = details or {}
metadata.setdefault(self.REASON, reason)
metadata.setdefault(self.DATA, None)
metadata.setdefault(self.UNIQUE_ID, signal_num)
metadata.setdefault(self.STATUS, self.STATUS_SUCCESS)
return super(HeatWaitConditionHandle, self).handle_signal(metadata)
class WaitConditionHandle(BaseWaitConditionHandle):
'''
the main point of this class is to :
have no dependencies (so the instance can reference it)
generate a unique url (to be returned in the reference)
then the cfn-signal will use this url to post to and
WaitCondition will poll it to see if has been written to.
'''
support_status = support.SupportStatus(version='2014.1')
METADATA_KEYS = (
DATA, REASON, STATUS, UNIQUE_ID
) = (
'Data', 'Reason', 'Status', 'UniqueId'
)
def handle_create(self):
super(WaitConditionHandle, self).handle_create()
self.resource_id_set(self._get_user_id())
def FnGetRefId(self):
'''
Override the default resource FnGetRefId so we return the signed URL
'''
if self.resource_id:
wc = signal_responder.WAITCONDITION
return six.text_type(self._get_signed_url(signal_type=wc))
else:
return six.text_type(self.name)
def metadata_update(self, new_metadata=None):
"""DEPRECATED. Should use handle_signal instead."""
self.handle_signal(details=new_metadata)
def handle_signal(self, details=None):
'''
Validate and update the resource metadata
metadata must use the following format:
{
"Status" : "Status (must be SUCCESS or FAILURE)",
"UniqueId" : "Some ID, should be unique for Count>1",
"Data" : "Arbitrary Data",
"Reason" : "Reason String"
}
'''
if details is None:
return
return super(WaitConditionHandle, self).handle_signal(details)
class UpdateWaitConditionHandle(WaitConditionHandle):
'''
This works identically to a regular WaitConditionHandle, except that
on update it clears all signals received and changes the handle. Using
this handle means that you must setup the signal senders to send their
signals again any time the update handle changes. This allows us to roll
out new configurations and be confident that they are rolled out once
UPDATE COMPLETE is reached.
'''
support_status = support.SupportStatus(version='2014.1')
def update(self, after, before=None, prev_resource=None):
raise resource.UpdateReplace(self.name)
class WaitConditionFailure(exception.Error): class WaitConditionFailure(exception.Error):
def __init__(self, wait_condition, handle): def __init__(self, wait_condition, handle):
reasons = handle.get_status_reason(handle.STATUS_FAILURE) reasons = handle.get_status_reason(handle.STATUS_FAILURE)
@ -293,11 +105,3 @@ class WaitConditionTimeout(exception.Error):
else: else:
message = (_('%(len)d of %(count)d received') % vals) message = (_('%(len)d of %(count)d received') % vals)
super(WaitConditionTimeout, self).__init__(message) super(WaitConditionTimeout, self).__init__(message)
def resource_mapping():
return {
'OS::Heat::WaitConditionHandle': HeatWaitConditionHandle,
'AWS::CloudFormation::WaitConditionHandle': WaitConditionHandle,
'OS::Heat::UpdateWaitConditionHandle': UpdateWaitConditionHandle,
}

View File

@ -26,9 +26,9 @@ from heat.engine.clients.os import nova
from heat.engine import function from heat.engine import function
from heat.engine.notification import stack as notification from heat.engine.notification import stack as notification
from heat.engine import parser from heat.engine import parser
from heat.engine.resources.aws import wait_condition_handle as aws_wch
from heat.engine.resources import instance from heat.engine.resources import instance
from heat.engine.resources import loadbalancer as lb from heat.engine.resources import loadbalancer as lb
from heat.engine.resources import wait_condition as wc
from heat.tests import common from heat.tests import common
from heat.tests import utils from heat.tests import utils
from heat.tests.v1_1 import fakes as fakes_v1_1 from heat.tests.v1_1 import fakes as fakes_v1_1
@ -216,8 +216,8 @@ class AutoScalingGroupTest(common.HeatTestCase):
parser.Stack.validate().MultipleTimes() parser.Stack.validate().MultipleTimes()
def _stub_lb_create(self): def _stub_lb_create(self):
self.m.StubOutWithMock(wc.WaitConditionHandle, 'get_status') self.m.StubOutWithMock(aws_wch.WaitConditionHandle, 'get_status')
wc.WaitConditionHandle.get_status().AndReturn(['SUCCESS']) aws_wch.WaitConditionHandle.get_status().AndReturn(['SUCCESS'])
def _stub_lb_reload(self, num=1, setup=True): def _stub_lb_reload(self, num=1, setup=True):
if setup: if setup:

View File

@ -24,9 +24,9 @@ from heat.common import template_format
from heat.engine.clients.os import glance from heat.engine.clients.os import glance
from heat.engine.clients.os import nova from heat.engine.clients.os import nova
from heat.engine import resource from heat.engine import resource
from heat.engine.resources.aws import wait_condition_handle as aws_wch
from heat.engine.resources import instance from heat.engine.resources import instance
from heat.engine.resources import loadbalancer as lb from heat.engine.resources import loadbalancer as lb
from heat.engine.resources import wait_condition as wc
from heat.engine import rsrc_defn from heat.engine import rsrc_defn
from heat.engine import scheduler from heat.engine import scheduler
from heat.tests import common from heat.tests import common
@ -144,8 +144,8 @@ class LoadBalancerTest(common.HeatTestCase):
if stub_meta: if stub_meta:
resource.Resource.metadata_set(mox.IgnoreArg()).AndReturn(None) resource.Resource.metadata_set(mox.IgnoreArg()).AndReturn(None)
self.m.StubOutWithMock(wc.WaitConditionHandle, 'get_status') self.m.StubOutWithMock(aws_wch.WaitConditionHandle, 'get_status')
wc.WaitConditionHandle.get_status().AndReturn(['SUCCESS']) aws_wch.WaitConditionHandle.get_status().AndReturn(['SUCCESS'])
def test_loadbalancer(self): def test_loadbalancer(self):
self._mock_get_image_id_success(u'F20-x86_64-cfntools', 746) self._mock_get_image_id_success(u'F20-x86_64-cfntools', 746)

View File

@ -19,9 +19,9 @@ from heat.common import identifier
from heat.common import template_format from heat.common import template_format
from heat.engine import environment from heat.engine import environment
from heat.engine import parser from heat.engine import parser
from heat.engine.resources.aws import wait_condition_handle as aws_wch
from heat.engine.resources import instance from heat.engine.resources import instance
from heat.engine.resources import server from heat.engine.resources import server
from heat.engine.resources import wait_condition as wc
from heat.engine import scheduler from heat.engine import scheduler
from heat.engine import service from heat.engine import service
from heat.tests import common from heat.tests import common
@ -238,8 +238,8 @@ class WaitCondMetadataUpdateTest(common.HeatTestCase):
id = identifier.ResourceIdentifier('test_tenant_id', stack.name, id = identifier.ResourceIdentifier('test_tenant_id', stack.name,
stack.id, '', 'WH') stack.id, '', 'WH')
self.m.StubOutWithMock(wc.WaitConditionHandle, 'identifier') self.m.StubOutWithMock(aws_wch.WaitConditionHandle, 'identifier')
wc.WaitConditionHandle.identifier().MultipleTimes().AndReturn(id) aws_wch.WaitConditionHandle.identifier().MultipleTimes().AndReturn(id)
self.m.StubOutWithMock(scheduler.TaskRunner, '_sleep') self.m.StubOutWithMock(scheduler.TaskRunner, '_sleep')
return stack return stack

View File

@ -28,6 +28,8 @@ from heat.engine.clients.os import heat_plugin
from heat.engine import environment from heat.engine import environment
from heat.engine import parser from heat.engine import parser
from heat.engine import resource from heat.engine import resource
from heat.engine.resources.aws import wait_condition_handle as aws_wch
from heat.engine.resources.openstack import wait_condition_handle as heat_wch
from heat.engine.resources import wait_condition as wc from heat.engine.resources import wait_condition as wc
from heat.engine import rsrc_defn from heat.engine import rsrc_defn
from heat.engine import scheduler from heat.engine import scheduler
@ -161,20 +163,21 @@ class WaitConditionTest(common.HeatTestCase):
if stub: if stub:
id = identifier.ResourceIdentifier('test_tenant', stack.name, id = identifier.ResourceIdentifier('test_tenant', stack.name,
stack.id, '', 'WaitHandle') stack.id, '', 'WaitHandle')
self.m.StubOutWithMock(wc.WaitConditionHandle, 'identifier') self.m.StubOutWithMock(aws_wch.WaitConditionHandle, 'identifier')
wc.WaitConditionHandle.identifier().MultipleTimes().AndReturn(id) aws_wch.WaitConditionHandle.identifier().\
MultipleTimes().AndReturn(id)
if stub_status: if stub_status:
self.m.StubOutWithMock(wc.WaitConditionHandle, self.m.StubOutWithMock(aws_wch.WaitConditionHandle,
'get_status') 'get_status')
return stack return stack
def test_post_success_to_handle(self): def test_post_success_to_handle(self):
self.stack = self.create_stack() self.stack = self.create_stack()
wc.WaitConditionHandle.get_status().AndReturn([]) aws_wch.WaitConditionHandle.get_status().AndReturn([])
wc.WaitConditionHandle.get_status().AndReturn([]) aws_wch.WaitConditionHandle.get_status().AndReturn([])
wc.WaitConditionHandle.get_status().AndReturn(['SUCCESS']) aws_wch.WaitConditionHandle.get_status().AndReturn(['SUCCESS'])
self.m.ReplayAll() self.m.ReplayAll()
@ -191,9 +194,9 @@ class WaitConditionTest(common.HeatTestCase):
def test_post_failure_to_handle(self): def test_post_failure_to_handle(self):
self.stack = self.create_stack() self.stack = self.create_stack()
wc.WaitConditionHandle.get_status().AndReturn([]) aws_wch.WaitConditionHandle.get_status().AndReturn([])
wc.WaitConditionHandle.get_status().AndReturn([]) aws_wch.WaitConditionHandle.get_status().AndReturn([])
wc.WaitConditionHandle.get_status().AndReturn(['FAILURE']) aws_wch.WaitConditionHandle.get_status().AndReturn(['FAILURE'])
self.m.ReplayAll() self.m.ReplayAll()
@ -211,11 +214,13 @@ class WaitConditionTest(common.HeatTestCase):
def test_post_success_to_handle_count(self): def test_post_success_to_handle_count(self):
self.stack = self.create_stack(template=test_template_wc_count) self.stack = self.create_stack(template=test_template_wc_count)
wc.WaitConditionHandle.get_status().AndReturn([]) aws_wch.WaitConditionHandle.get_status().AndReturn([])
wc.WaitConditionHandle.get_status().AndReturn(['SUCCESS']) aws_wch.WaitConditionHandle.get_status().AndReturn(['SUCCESS'])
wc.WaitConditionHandle.get_status().AndReturn(['SUCCESS', 'SUCCESS']) aws_wch.WaitConditionHandle.get_status().AndReturn(['SUCCESS',
wc.WaitConditionHandle.get_status().AndReturn(['SUCCESS', 'SUCCESS', 'SUCCESS'])
'SUCCESS']) aws_wch.WaitConditionHandle.get_status().AndReturn(['SUCCESS',
'SUCCESS',
'SUCCESS'])
self.m.ReplayAll() self.m.ReplayAll()
@ -232,9 +237,10 @@ class WaitConditionTest(common.HeatTestCase):
def test_post_failure_to_handle_count(self): def test_post_failure_to_handle_count(self):
self.stack = self.create_stack(template=test_template_wc_count) self.stack = self.create_stack(template=test_template_wc_count)
wc.WaitConditionHandle.get_status().AndReturn([]) aws_wch.WaitConditionHandle.get_status().AndReturn([])
wc.WaitConditionHandle.get_status().AndReturn(['SUCCESS']) aws_wch.WaitConditionHandle.get_status().AndReturn(['SUCCESS'])
wc.WaitConditionHandle.get_status().AndReturn(['SUCCESS', 'FAILURE']) aws_wch.WaitConditionHandle.get_status().AndReturn(['SUCCESS',
'FAILURE'])
self.m.ReplayAll() self.m.ReplayAll()
@ -264,9 +270,9 @@ class WaitConditionTest(common.HeatTestCase):
scheduler.wallclock().AndReturn(st) scheduler.wallclock().AndReturn(st)
scheduler.wallclock().AndReturn(st + 0.001) scheduler.wallclock().AndReturn(st + 0.001)
scheduler.wallclock().AndReturn(st + 0.1) scheduler.wallclock().AndReturn(st + 0.1)
wc.WaitConditionHandle.get_status().AndReturn([]) aws_wch.WaitConditionHandle.get_status().AndReturn([])
scheduler.wallclock().AndReturn(st + 4.1) scheduler.wallclock().AndReturn(st + 4.1)
wc.WaitConditionHandle.get_status().AndReturn([]) aws_wch.WaitConditionHandle.get_status().AndReturn([])
scheduler.wallclock().AndReturn(st + 5.1) scheduler.wallclock().AndReturn(st + 5.1)
self.m.ReplayAll() self.m.ReplayAll()
@ -283,7 +289,7 @@ class WaitConditionTest(common.HeatTestCase):
def test_FnGetAtt(self): def test_FnGetAtt(self):
self.stack = self.create_stack() self.stack = self.create_stack()
wc.WaitConditionHandle.get_status().AndReturn(['SUCCESS']) aws_wch.WaitConditionHandle.get_status().AndReturn(['SUCCESS'])
self.m.ReplayAll() self.m.ReplayAll()
self.stack.create() self.stack.create()
@ -428,13 +434,13 @@ class WaitConditionHandleTest(common.HeatTestCase):
self.stack_id = stack.id self.stack_id = stack.id
# Stub waitcondition status so all goes CREATE_COMPLETE # Stub waitcondition status so all goes CREATE_COMPLETE
self.m.StubOutWithMock(wc.WaitConditionHandle, 'get_status') self.m.StubOutWithMock(aws_wch.WaitConditionHandle, 'get_status')
wc.WaitConditionHandle.get_status().AndReturn(['SUCCESS']) aws_wch.WaitConditionHandle.get_status().AndReturn(['SUCCESS'])
id = identifier.ResourceIdentifier('test_tenant', stack.name, id = identifier.ResourceIdentifier('test_tenant', stack.name,
stack.id, '', 'WaitHandle') stack.id, '', 'WaitHandle')
self.m.StubOutWithMock(wc.WaitConditionHandle, 'identifier') self.m.StubOutWithMock(aws_wch.WaitConditionHandle, 'identifier')
wc.WaitConditionHandle.identifier().MultipleTimes().AndReturn(id) aws_wch.WaitConditionHandle.identifier().MultipleTimes().AndReturn(id)
self.m.ReplayAll() self.m.ReplayAll()
stack.create() stack.create()
@ -602,12 +608,14 @@ class WaitConditionUpdateTest(common.HeatTestCase):
with utils.UUIDStub(self.stack_id): with utils.UUIDStub(self.stack_id):
stack.store() stack.store()
self.m.StubOutWithMock(wc.WaitConditionHandle, 'get_status') self.m.StubOutWithMock(aws_wch.WaitConditionHandle, 'get_status')
wc.WaitConditionHandle.get_status().AndReturn([]) aws_wch.WaitConditionHandle.get_status().AndReturn([])
wc.WaitConditionHandle.get_status().AndReturn(['SUCCESS']) aws_wch.WaitConditionHandle.get_status().AndReturn(['SUCCESS'])
wc.WaitConditionHandle.get_status().AndReturn(['SUCCESS', 'SUCCESS']) aws_wch.WaitConditionHandle.get_status().AndReturn(['SUCCESS',
wc.WaitConditionHandle.get_status().AndReturn(['SUCCESS', 'SUCCESS', 'SUCCESS'])
'SUCCESS']) aws_wch.WaitConditionHandle.get_status().AndReturn(['SUCCESS',
'SUCCESS',
'SUCCESS'])
return stack return stack
@ -796,24 +804,25 @@ class HeatWaitConditionTest(common.HeatTestCase):
if stub: if stub:
id = identifier.ResourceIdentifier('test_tenant', stack.name, id = identifier.ResourceIdentifier('test_tenant', stack.name,
stack.id, '', 'wait_handle') stack.id, '', 'wait_handle')
self.m.StubOutWithMock(wc.HeatWaitConditionHandle, 'identifier') self.m.StubOutWithMock(heat_wch.HeatWaitConditionHandle,
wc.HeatWaitConditionHandle.identifier().MultipleTimes().AndReturn( 'identifier')
id) heat_wch.HeatWaitConditionHandle.\
identifier().MultipleTimes().AndReturn(id)
if stub_status: if stub_status:
self.m.StubOutWithMock(wc.HeatWaitConditionHandle, self.m.StubOutWithMock(heat_wch.HeatWaitConditionHandle,
'get_status') 'get_status')
return stack return stack
def test_post_complete_to_handle(self): def test_post_complete_to_handle(self):
self.stack = self.create_stack() self.stack = self.create_stack()
wc.HeatWaitConditionHandle.get_status().AndReturn(['SUCCESS']) heat_wch.HeatWaitConditionHandle.get_status().AndReturn(['SUCCESS'])
wc.HeatWaitConditionHandle.get_status().AndReturn(['SUCCESS', heat_wch.HeatWaitConditionHandle.get_status().AndReturn(['SUCCESS',
'SUCCESS']) 'SUCCESS'])
wc.HeatWaitConditionHandle.get_status().AndReturn(['SUCCESS', heat_wch.HeatWaitConditionHandle.get_status().AndReturn(['SUCCESS',
'SUCCESS', 'SUCCESS',
'SUCCESS']) 'SUCCESS'])
self.m.ReplayAll() self.m.ReplayAll()
@ -830,12 +839,12 @@ class HeatWaitConditionTest(common.HeatTestCase):
def test_post_failed_to_handle(self): def test_post_failed_to_handle(self):
self.stack = self.create_stack() self.stack = self.create_stack()
wc.HeatWaitConditionHandle.get_status().AndReturn(['SUCCESS']) heat_wch.HeatWaitConditionHandle.get_status().AndReturn(['SUCCESS'])
wc.HeatWaitConditionHandle.get_status().AndReturn(['SUCCESS', heat_wch.HeatWaitConditionHandle.get_status().AndReturn(['SUCCESS',
'SUCCESS']) 'SUCCESS'])
wc.HeatWaitConditionHandle.get_status().AndReturn(['SUCCESS', heat_wch.HeatWaitConditionHandle.get_status().AndReturn(['SUCCESS',
'SUCCESS', 'SUCCESS',
'FAILURE']) 'FAILURE'])
self.m.ReplayAll() self.m.ReplayAll()
@ -866,9 +875,9 @@ class HeatWaitConditionTest(common.HeatTestCase):
scheduler.wallclock().AndReturn(st) scheduler.wallclock().AndReturn(st)
scheduler.wallclock().AndReturn(st + 0.001) scheduler.wallclock().AndReturn(st + 0.001)
scheduler.wallclock().AndReturn(st + 0.1) scheduler.wallclock().AndReturn(st + 0.1)
wc.HeatWaitConditionHandle.get_status().AndReturn([]) heat_wch.HeatWaitConditionHandle.get_status().AndReturn([])
scheduler.wallclock().AndReturn(st + 4.1) scheduler.wallclock().AndReturn(st + 4.1)
wc.HeatWaitConditionHandle.get_status().AndReturn([]) heat_wch.HeatWaitConditionHandle.get_status().AndReturn([])
scheduler.wallclock().AndReturn(st + 5.1) scheduler.wallclock().AndReturn(st + 5.1)
self.m.ReplayAll() self.m.ReplayAll()
@ -886,7 +895,7 @@ class HeatWaitConditionTest(common.HeatTestCase):
def _create_heat_wc_and_handle(self): def _create_heat_wc_and_handle(self):
self.stack = self.create_stack( self.stack = self.create_stack(
template=test_template_heat_waitcondition) template=test_template_heat_waitcondition)
wc.HeatWaitConditionHandle.get_status().AndReturn(['SUCCESS']) heat_wch.HeatWaitConditionHandle.get_status().AndReturn(['SUCCESS'])
self.m.ReplayAll() self.m.ReplayAll()
self.stack.create() self.stack.create()