Merge "Add convenience function for events over websocket"

This commit is contained in:
Jenkins 2016-12-27 04:15:02 +00:00 committed by Gerrit Code Review
commit 87b03ceac6
3 changed files with 71 additions and 2 deletions

View File

@ -18,6 +18,7 @@ import time
from heatclient._i18n import _
from heatclient.common import utils
import heatclient.exc as exc
from heatclient.v1 import events as events_mod
def get_hook_events(hc, stack_id, event_args, nested_depth=0,
@ -216,3 +217,27 @@ def poll_for_events(hc, stack_name, action=None, poll_period=5, marker=None,
no_event_polls = 0
time.sleep(poll_period)
def wait_for_events(ws, stack_name, out=None):
"""Receive events over the passed websocket and wait for final status."""
msg_template = _("\n Stack %(name)s %(status)s \n")
if not out:
out = sys.stdout
event_log_context = utils.EventLogContext()
while True:
data = ws.recv()['body']
event = events_mod.Event(None, data['payload'], True)
# Keep compatibility with the HTTP API
event.event_time = data['timestamp']
event.resource_status = '%s_%s' % (event.resource_action,
event.resource_status)
events_log = utils.event_log_formatter([event], event_log_context)
out.write(events_log)
out.write('\n')
if data['payload']['resource_name'] == stack_name:
stack_status = data['payload']['resource_status']
if stack_status in ('COMPLETE', 'FAILED'):
msg = msg_template % dict(
name=stack_name, status=event.resource_status)
return '%s_%s' % (event.resource_action, stack_status), msg

View File

@ -208,6 +208,8 @@ class EventLogContext(object):
# future calls to build_resource_name
def get_stack_id():
if getattr(event, 'stack_id', None) is not None:
return event.stack_id
for l in getattr(event, 'links', []):
if l.get('rel') == 'stack':
if 'href' not in l:
@ -218,8 +220,8 @@ class EventLogContext(object):
stack_id = get_stack_id()
if not stack_id:
return res_name
phys_id = getattr(event, 'physical_resource_id')
status = getattr(event, 'resource_status')
phys_id = getattr(event, 'physical_resource_id', None)
status = getattr(event, 'resource_status', None)
is_stack_event = stack_id == phys_id
if is_stack_event:

View File

@ -18,6 +18,15 @@ from heatclient.v1 import events as hc_ev
from heatclient.v1 import resources as hc_res
class FakeWebSocket(object):
def __init__(self, events):
self.events = events
def recv(self):
return self.events.pop(0)
class ShellTestEventUtils(testtools.TestCase):
@staticmethod
def _mock_resource(resource_id, nested_id=None):
@ -245,3 +254,36 @@ class ShellTestEventUtils(testtools.TestCase):
mock_client, 'astack', action='CREATE', poll_period=0)
self.assertEqual('CREATE_FAILED', stack_status)
self.assertEqual('\n Stack astack CREATE_FAILED \n', msg)
def test_wait_for_events(self):
ws = FakeWebSocket([
{'body': {
'timestamp': '2014-01-06T16:14:26Z',
'payload': {'resource_action': 'CREATE',
'resource_status': 'COMPLETE',
'resource_name': 'mystack',
'physical_resource_id': 'stackid1',
'stack_id': 'stackid1'}}}])
stack_status, msg = event_utils.wait_for_events(ws, 'mystack')
self.assertEqual('CREATE_COMPLETE', stack_status)
self.assertEqual('\n Stack mystack CREATE_COMPLETE \n', msg)
def test_wait_for_events_failed(self):
ws = FakeWebSocket([
{'body': {
'timestamp': '2014-01-06T16:14:23Z',
'payload': {'resource_action': 'CREATE',
'resource_status': 'IN_PROGRESS',
'resource_name': 'mystack',
'physical_resource_id': 'stackid1',
'stack_id': 'stackid1'}}},
{'body': {
'timestamp': '2014-01-06T16:14:26Z',
'payload': {'resource_action': 'CREATE',
'resource_status': 'FAILED',
'resource_name': 'mystack',
'physical_resource_id': 'stackid1',
'stack_id': 'stackid1'}}}])
stack_status, msg = event_utils.wait_for_events(ws, 'mystack')
self.assertEqual('CREATE_FAILED', stack_status)
self.assertEqual('\n Stack mystack CREATE_FAILED \n', msg)