Fix the wait condition's reading of the metadata.

the db was caching the object, so we need to 'expire'
it to make sure we are getting live data.

Change-Id: I1108daccc96f3dcfa33fda968ea30d83e03aad2d
Signed-off-by: Angus Salkeld <asalkeld@redhat.com>
This commit is contained in:
Angus Salkeld 2012-06-21 20:10:53 +10:00
parent 477baee868
commit c44746d8d5
4 changed files with 140 additions and 7 deletions

View File

@ -61,6 +61,22 @@ class HeatBase(object):
else:
raise
def expire(self, session=None):
"""Expire this object ()."""
if not session:
session = Session.object_session(self)
if not session:
session = get_session()
session.expire(self)
def refresh(self, session=None):
"""Refresh this object."""
if not session:
session = Session.object_session(self)
if not session:
session = get_session()
session.refresh(self)
def delete(self, session=None):
"""Delete this object."""
self.deleted = True

View File

@ -492,6 +492,7 @@ class EngineManager(manager.Manager):
"""
s = db_api.stack_get_by_name(None, stack_name)
if not s:
logger.warn("Stack not found %s." % (stack_name))
return ['stack', None]
r = db_api.resource_get_by_name_and_stack(None, resource_id, s.id)

View File

@ -78,6 +78,7 @@ class WaitCondition(Resource):
status = 'WAITING'
reason = ''
res = None
sleep_time = 1
try:
while status == 'WAITING':
try:
@ -85,21 +86,28 @@ class WaitCondition(Resource):
res_name,
self.stack.id)
except Exception as ex:
logger.exception('resource %s not found' % res_name)
if 'not found' in ex:
# it has been deleted
status = 'DELETED'
else:
pass
if res and res.rsrc_metadata:
metadata = res.rsrc_metadata
if metadata:
status = metadata.get('Status', 'WAITING')
reason = metadata.get('Reason', 'Reason not provided')
logger.debug('got %s' % json.dumps(metadata))
if res:
if res.rsrc_metadata:
meta = res.rsrc_metadata
status = meta.get('Status',
'WAITING')
reason = meta.get('Reason',
'Reason not provided')
logger.debug('got %s' % json.dumps(res.rsrc_metadata))
if status == 'WAITING':
logger.debug('Waiting some more for the Metadata[Status]')
eventlet.sleep(30)
eventlet.sleep(sleep_time)
sleep_time = min(sleep_time * 2, self.timeout / 4)
if res:
res.expire()
except eventlet.Timeout, t:
if t is not tmo:
# not my timeout

View File

@ -0,0 +1,108 @@
from datetime import datetime
import eventlet
import json
import logging
import os
import sys
import nose
import unittest
import mox
from nose.plugins.attrib import attr
from nose import with_setup
import heat.db as db_api
from heat.engine import parser
logger = logging.getLogger('test_waitcondition')
test_template_waitcondition = '''
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "Just a WaitCondition.",
"Parameters" : {},
"Resources" : {
"WaitHandle" : {
"Type" : "AWS::CloudFormation::WaitConditionHandle"
},
"WaitForTheHandle" : {
"Type" : "AWS::CloudFormation::WaitCondition",
"Properties" : {
"Handle" : {"Ref" : "WaitHandle"},
"Timeout" : "5"
}
}
}
}
'''
@attr(tag=['unit', 'resource'])
@attr(speed='slow')
class stacksTest(unittest.TestCase):
def setUp(self):
self.m = mox.Mox()
self.greenpool = eventlet.GreenPool()
def tearDown(self):
self.m.UnsetStubs()
def create_stack(self, stack_name, temp, params):
stack = parser.Stack(None, stack_name, temp, 0, params)
rt = {}
rt['template'] = temp
rt['StackName'] = stack_name
new_rt = db_api.raw_template_create(None, rt)
ct = {'username': 'fred',
'password': 'mentions_fruit'}
new_creds = db_api.user_creds_create(ct)
s = {}
s['name'] = stack_name
s['raw_template_id'] = new_rt.id
s['user_creds_id'] = new_creds.id
s['username'] = ct['username']
new_s = db_api.stack_create(None, s)
stack.id = new_s.id
pt = {}
pt['template'] = stack.t
pt['raw_template_id'] = new_rt.id
new_pt = db_api.parsed_template_create(None, pt)
stack.parsed_template_id = new_pt.id
return stack
def test_post_success_to_handle(self):
params = {}
t = json.loads(test_template_waitcondition)
stack = self.create_stack('test_stack', t, params)
self.m.ReplayAll()
self.greenpool.spawn_n(stack.create)
eventlet.sleep(1)
assert(stack.resources['WaitForTheHandle'].state == 'IN_PROGRESS')
r = db_api.resource_get_by_name_and_stack(None, 'WaitHandle',
stack.id)
assert(r.name == 'WaitHandle')
metadata = {"Status": "SUCCESS",
"Reason": "woot toot",
"Data": "Application has completed configuration.",
"UniqueId": "00000"}
r.update_and_save({'rsrc_metadata': metadata})
eventlet.sleep(2)
logger.debug('state %s' % stack.resources['WaitForTheHandle'].state)
assert(stack.resources['WaitForTheHandle'].state == 'CREATE_COMPLETE')
self.greenpool.waitall()
# allows testing of the test directly
if __name__ == '__main__':
sys.argv.append(__file__)
nose.main()