From da0da4c1afc00dd2732b678b09fc2d826137a44d Mon Sep 17 00:00:00 2001 From: rabi Date: Thu, 25 Aug 2016 11:01:24 +0530 Subject: Add parameter_merge_startegies section This adds parameter_merge_strategies section to environment. This also adds the missing section parameter_encrypted_names. We use a server side module and a client side module that have deviated over a period of time. This patch syncs them. We probably should move these to a library and use use them for both server and client in the future. Change-Id: I9b20a7cedd416b6d8b788a30f66e472b85babf4a Blueprint: environment-merging --- heatclient/common/environment_format.py | 16 +++++++++++----- heatclient/tests/unit/test_environment_format.py | 18 +++++++++++++++++- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/heatclient/common/environment_format.py b/heatclient/common/environment_format.py index 6870b79..8f2c4ea 100644 --- a/heatclient/common/environment_format.py +++ b/heatclient/common/environment_format.py @@ -17,9 +17,13 @@ from heatclient.openstack.common._i18n import _ SECTIONS = ( - PARAMETER_DEFAULTS, PARAMETERS, RESOURCE_REGISTRY, EVENT_SINKS + PARAMETER_DEFAULTS, PARAMETERS, RESOURCE_REGISTRY, + ENCRYPTED_PARAM_NAMES, EVENT_SINKS, + PARAMETER_MERGE_STRATEGIES ) = ( - 'parameter_defaults', 'parameters', 'resource_registry', 'event_sinks' + 'parameter_defaults', 'parameters', 'resource_registry', + 'encrypted_param_names', 'event_sinks', + 'parameter_merge_strategies' ) @@ -55,7 +59,9 @@ def parse(env_str): def default_for_missing(env): """Checks a parsed environment for missing sections.""" - for param in SECTIONS: - if param not in env: - env[param] = {} + if param not in env and param != PARAMETER_MERGE_STRATEGIES: + if param in (ENCRYPTED_PARAM_NAMES, EVENT_SINKS): + env[param] = [] + else: + env[param] = {} diff --git a/heatclient/tests/unit/test_environment_format.py b/heatclient/tests/unit/test_environment_format.py index d0614b2..905c910 100644 --- a/heatclient/tests/unit/test_environment_format.py +++ b/heatclient/tests/unit/test_environment_format.py @@ -27,15 +27,31 @@ class YamlEnvironmentTest(testtools.TestCase): yaml1 = '' yaml2 = ''' parameter_defaults: {} +encrypted_param_names: [] parameters: {} resource_registry: {} -event_sinks: {} +event_sinks: [] ''' tpl1 = environment_format.parse(yaml1) environment_format.default_for_missing(tpl1) tpl2 = environment_format.parse(yaml2) self.assertEqual(tpl2, tpl1) + def test_param_valid_strategy_section(self): + yaml1 = '' + yaml2 = ''' +parameters: {} +encrypted_param_names: [] +parameter_defaults: {} +parameter_merge_strategies: {} +event_sinks: [] +resource_registry: {} +''' + tpl1 = environment_format.parse(yaml1) + environment_format.default_for_missing(tpl1) + tpl2 = environment_format.parse(yaml2) + self.assertNotEqual(tpl1, tpl2) + def test_wrong_sections(self): env = ''' parameters: {} -- cgit v1.2.1 From 4f3e7cd99e1d8906a9f4e43a91161beb8af96bc3 Mon Sep 17 00:00:00 2001 From: shizhihui Date: Mon, 1 Aug 2016 10:53:49 +0800 Subject: Trivial:Standardize the output format of 'help' in shell.py Change-Id: Ie6c03d56ab2f0aa14bc96028fd548e80987beeb1 --- heatclient/v1/shell.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/heatclient/v1/shell.py b/heatclient/v1/shell.py index cfc942a..f54b793 100644 --- a/heatclient/v1/shell.py +++ b/heatclient/v1/shell.py @@ -419,7 +419,7 @@ def do_action_check(hc, args): @utils.arg('id', metavar='', help=_('Name or ID of stack to describe.')) @utils.arg('--no-resolve-outputs', action="store_true", - help='Do not resolve outputs of the stack.') + help=_('Do not resolve outputs of the stack.')) def do_stack_show(hc, args): '''Describe the stack.''' show_deprecated('heat stack-show', 'openstack stack show') @@ -464,10 +464,10 @@ def do_stack_show(hc, args): 'updated.') % {'true': strutils.TRUE_STRINGS, 'false': strutils.FALSE_STRINGS}) @utils.arg('-y', '--dry-run', default=False, action="store_true", - help='Do not actually perform the stack update, but show what ' - 'would be changed') + help=_('Do not actually perform the stack update, but show what ' + 'would be changed')) @utils.arg('-n', '--show-nested', default=False, action="store_true", - help='Show nested stacks when performing --dry-run') + help=_('Show nested stacks when performing --dry-run')) @utils.arg('-P', '--parameters', metavar='', help=_('Parameter values used to create the stack. ' 'This can be specified multiple times, or once with ' -- cgit v1.2.1 From 2ac87cbc3d218dd9816daca388c861b5a784ed3d Mon Sep 17 00:00:00 2001 From: bhagyashris Date: Fri, 26 Aug 2016 16:29:52 +0530 Subject: Replace functions 'Dict.get' and 'del' with 'Dict.pop' Refactoring code: Making 'kwargs' dict to use single instruction: pop() rather than two instructions: get() and del, giving the codes a format that carries through. TrivialFix Change-Id: I2b2221e92495beb88be8feb76adbc4d756a180f2 --- heatclient/openstack/common/apiclient/client.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/heatclient/openstack/common/apiclient/client.py b/heatclient/openstack/common/apiclient/client.py index 24c6e73..8733772 100644 --- a/heatclient/openstack/common/apiclient/client.py +++ b/heatclient/openstack/common/apiclient/client.py @@ -145,13 +145,10 @@ class HTTPClient(object): resp.text) def serialize(self, kwargs): - if kwargs.get('json') is not None: + json_data = kwargs.pop('json', None) + if json_data is not None: kwargs['headers']['Content-Type'] = 'application/json' - kwargs['data'] = json.dumps(kwargs['json']) - try: - del kwargs['json'] - except KeyError: - pass + kwargs['data'] = json.dumps(json_data) def get_timings(self): return self.times -- cgit v1.2.1 From f5bf3e755d9b4194114a3acd50466069fb622a3f Mon Sep 17 00:00:00 2001 From: shizhihui Date: Fri, 5 Aug 2016 17:09:03 +0800 Subject: Import mox in __init__.py We can initialize the 'mox' of module mox3 in __init__.py, then in these files that have modified, we only have 'import mox' other than 'from mox3 import mox', which can make the code smaller and clear. Change-Id: Ic09597a7205eed47bd3cff03d1e7bc78744e52d4 --- heatclient/openstack/common/apiclient/base.py | 4 ++-- heatclient/tests/unit/__init__.py | 5 +++++ heatclient/tests/unit/test_common_http.py | 2 +- heatclient/tests/unit/test_events.py | 2 +- heatclient/tests/unit/test_resources.py | 2 +- heatclient/tests/unit/test_shell.py | 2 +- heatclient/tests/unit/test_template_utils.py | 2 +- 7 files changed, 12 insertions(+), 7 deletions(-) diff --git a/heatclient/openstack/common/apiclient/base.py b/heatclient/openstack/common/apiclient/base.py index 0a99ab2..3e68528 100644 --- a/heatclient/openstack/common/apiclient/base.py +++ b/heatclient/openstack/common/apiclient/base.py @@ -286,7 +286,7 @@ class CrudManager(BaseManager): {}, {}]}`). - `key`: Usually a singular noun by convention (e.g. `entity`); used to refer to an individual member of the collection. - + """ collection_key = None key = None @@ -446,7 +446,7 @@ class Resource(object): This is pretty much just a bag for attributes. """ - + HUMAN_ID = False NAME_ATTR = 'name' diff --git a/heatclient/tests/unit/__init__.py b/heatclient/tests/unit/__init__.py index e69de29..b1967c8 100644 --- a/heatclient/tests/unit/__init__.py +++ b/heatclient/tests/unit/__init__.py @@ -0,0 +1,5 @@ +import sys + +from mox3 import mox + +sys.modules['mox'] = mox diff --git a/heatclient/tests/unit/test_common_http.py b/heatclient/tests/unit/test_common_http.py index 3636585..9ccc24a 100644 --- a/heatclient/tests/unit/test_common_http.py +++ b/heatclient/tests/unit/test_common_http.py @@ -18,7 +18,7 @@ import socket from keystoneauth1 import adapter import mock -from mox3 import mox +import mox from oslo_serialization import jsonutils import requests import six diff --git a/heatclient/tests/unit/test_events.py b/heatclient/tests/unit/test_events.py index 584f713..f6071a5 100644 --- a/heatclient/tests/unit/test_events.py +++ b/heatclient/tests/unit/test_events.py @@ -13,7 +13,7 @@ # under the License. import mock -from mox3 import mox +import mox import testtools from heatclient.common import utils diff --git a/heatclient/tests/unit/test_resources.py b/heatclient/tests/unit/test_resources.py index d5200e3..b3c5c30 100644 --- a/heatclient/tests/unit/test_resources.py +++ b/heatclient/tests/unit/test_resources.py @@ -12,7 +12,7 @@ # License for the specific language governing permissions and limitations # under the License. -from mox3 import mox +import mox from six.moves.urllib import parse import testtools diff --git a/heatclient/tests/unit/test_shell.py b/heatclient/tests/unit/test_shell.py index 7071363..f88f7fc 100644 --- a/heatclient/tests/unit/test_shell.py +++ b/heatclient/tests/unit/test_shell.py @@ -19,7 +19,7 @@ import uuid import fixtures from keystoneauth1 import fixture as keystone_fixture import mock -from mox3 import mox +import mox from oslo_serialization import jsonutils from oslo_utils import encodeutils from oslotest import mockpatch diff --git a/heatclient/tests/unit/test_template_utils.py b/heatclient/tests/unit/test_template_utils.py index 6440af2..881470e 100644 --- a/heatclient/tests/unit/test_template_utils.py +++ b/heatclient/tests/unit/test_template_utils.py @@ -15,7 +15,7 @@ import base64 import json import tempfile -from mox3 import mox +import mox import six from six.moves.urllib import error from six.moves.urllib import request -- cgit v1.2.1 From 7e869ca818a8189ef6fe06c6c82cab284a624597 Mon Sep 17 00:00:00 2001 From: Bin Zhou Date: Fri, 2 Sep 2016 11:56:37 +0800 Subject: Modify use of assertTrue(A in B) developers should use assertIn(A, B) instead of assertTrue(A in B ). TrivialFix Change-Id: Ia4dd3aedf338e967b379739aa80d7fbd6bfcd15e --- heatclient/tests/unit/osc/v1/test_template.py | 2 +- heatclient/tests/unit/test_template_utils.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/heatclient/tests/unit/osc/v1/test_template.py b/heatclient/tests/unit/osc/v1/test_template.py index c69637d..895f628 100644 --- a/heatclient/tests/unit/osc/v1/test_template.py +++ b/heatclient/tests/unit/osc/v1/test_template.py @@ -117,7 +117,7 @@ class TestTemplateValidate(TestTemplate): self.assertEqual(1, self.stack_client.validate.call_count) args = self.stack_client.validate.call_args[1] self.assertEqual(args.get('environment'), {'parameters': {}}) - self.assertTrue(self.env_path in args.get('environment_files')[0]) + self.assertIn(self.env_path, args.get('environment_files')[0]) self.assertEqual([], columns) self.assertEqual([], data) diff --git a/heatclient/tests/unit/test_template_utils.py b/heatclient/tests/unit/test_template_utils.py index 6440af2..d1734b3 100644 --- a/heatclient/tests/unit/test_template_utils.py +++ b/heatclient/tests/unit/test_template_utils.py @@ -411,7 +411,7 @@ class ShellEnvironmentTest(testtools.TestCase): files['file:///home/b/a.yaml']) self.assertEqual(['file:///home/my/dir/env1.yaml'], env_file_list) - self.assertTrue('file:///home/my/dir/env1.yaml' in files) + self.assertIn('file:///home/my/dir/env1.yaml', files) self.assertEqual(expected_env, json.loads(files['file:///home/my/dir/env1.yaml'])) -- cgit v1.2.1 From 80eecf92c9e13f92e3311e22774f4b35981dfeaf Mon Sep 17 00:00:00 2001 From: Cao Xuan Hoang Date: Mon, 5 Sep 2016 09:58:29 +0700 Subject: Clean imports in code This patch set modifies lines which are importing objects instead of modules. As per openstack import guide lines, user should import modules in a file not objects. http://docs.openstack.org/developer/hacking/#imports Change-Id: I9b7c8c7e37ee9861a63489f5b8fd611f2d31946e --- heatclient/common/deployment_utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/heatclient/common/deployment_utils.py b/heatclient/common/deployment_utils.py index adb1769..ee209dc 100644 --- a/heatclient/common/deployment_utils.py +++ b/heatclient/common/deployment_utils.py @@ -20,13 +20,13 @@ from swiftclient import utils as swiftclient_utils from heatclient import exc from heatclient.openstack.common._i18n import _ -from heatclient.v1.software_configs import SoftwareConfig +from heatclient.v1 import software_configs def build_derived_config_params(action, source, name, input_values, server_id, signal_transport, signal_id=None): - if isinstance(source, SoftwareConfig): + if isinstance(source, software_configs.SoftwareConfig): source = source.to_dict() input_values = input_values or {} inputs = copy.deepcopy(source.get('inputs')) or [] -- cgit v1.2.1 From b28d8c610147b2830930da532d6b42233d8cd468 Mon Sep 17 00:00:00 2001 From: Steve Baker Date: Fri, 2 Sep 2016 05:13:29 +0000 Subject: Show resource name path in event log formatter The resource name path was introduced in the 'openstack stack failures' command and is a user-friendly way of referring to a deeply nested resource. This change modifies the event log formatter to build and display the resource name path for each event based only off data in previous events. For building the full resource path, and omitting ugly stack names from the resource path, the following heat change is needed Ib8feb7752bd5736785d142216312bb35629b3601. However the output is still improved slightly when running against an older heat which does not have this change. Change-Id: I86b687fc516da215a6baeef8b365a520d12a8ab1 Closes-Bug: #1619415 --- heatclient/common/event_utils.py | 3 +- heatclient/common/utils.py | 72 +++++++++++++++++- heatclient/osc/v1/event.py | 4 +- heatclient/tests/unit/test_utils.py | 142 ++++++++++++++++++++++++++++++++++++ 4 files changed, 217 insertions(+), 4 deletions(-) diff --git a/heatclient/common/event_utils.py b/heatclient/common/event_utils.py index 6acbbd6..c0bc42e 100644 --- a/heatclient/common/event_utils.py +++ b/heatclient/common/event_utils.py @@ -179,6 +179,7 @@ def poll_for_events(hc, stack_name, action=None, poll_period=5, marker=None, msg_template = _("\n Stack %(name)s %(status)s \n") if not out: out = sys.stdout + event_log_context = utils.EventLogContext() while True: events = get_events(hc, stack_id=stack_name, nested_depth=nested_depth, event_args={'sort_dir': 'asc', @@ -190,7 +191,7 @@ def poll_for_events(hc, stack_name, action=None, poll_period=5, marker=None, no_event_polls = 0 # set marker to last event that was received. marker = getattr(events[-1], 'id', None) - events_log = utils.event_log_formatter(events) + events_log = utils.event_log_formatter(events, event_log_context) out.write(events_log) out.write('\n') diff --git a/heatclient/common/utils.py b/heatclient/common/utils.py index a36ab38..f2b20f1 100644 --- a/heatclient/common/utils.py +++ b/heatclient/common/utils.py @@ -97,16 +97,84 @@ def print_dict(d, formatters=None): print(pt.get_string(sortby='Property')) -def event_log_formatter(events): +class EventLogContext(object): + + def __init__(self): + # key is a stack id or the name of the nested stack, value is a tuple + # of the parent stack id, and the name of the resource in the parent + # stack + self.id_to_res_info = {} + + def prepend_paths(self, resource_path, stack_id): + if stack_id not in self.id_to_res_info: + return + stack_id, res_name = self.id_to_res_info.get(stack_id) + if res_name in self.id_to_res_info: + # do a double lookup to skip the ugly stack name that doesn't + # correspond to an actual resource name + n_stack_id, res_name = self.id_to_res_info.get(res_name) + resource_path.insert(0, res_name) + self.prepend_paths(resource_path, n_stack_id) + elif res_name: + resource_path.insert(0, res_name) + + def build_resource_name(self, event): + res_name = getattr(event, 'resource_name') + + # Contribute this event to self.id_to_res_info to assist with + # future calls to build_resource_name + + def get_stack_id(): + for l in getattr(event, 'links', []): + if l.get('rel') == 'stack': + if 'href' not in l: + return None + stack_link = l['href'] + return stack_link.split('/')[-1] + + stack_id = get_stack_id() + if not stack_id: + return res_name + phys_id = getattr(event, 'physical_resource_id') + status = getattr(event, 'resource_status') + + is_stack_event = stack_id == phys_id + if is_stack_event: + # this is an event for a stack + self.id_to_res_info[stack_id] = (stack_id, res_name) + elif phys_id and status == 'CREATE_IN_PROGRESS': + # this might be an event for a resource which creates a stack + self.id_to_res_info[phys_id] = (stack_id, res_name) + + # Now build this resource path based on previous calls to + # build_resource_name + resource_path = [] + if res_name and not is_stack_event: + resource_path.append(res_name) + self.prepend_paths(resource_path, stack_id) + + return '.'.join(resource_path) + + +def event_log_formatter(events, event_log_context=None): """Return the events in log format.""" event_log = [] log_format = ("%(event_time)s " "[%(rsrc_name)s]: %(rsrc_status)s %(rsrc_status_reason)s") + + # It is preferable for a context to be passed in, but there might be enough + # events in this call to build a better resource name, so create a context + # anyway + if event_log_context is None: + event_log_context = EventLogContext() + for event in events: + rsrc_name = event_log_context.build_resource_name(event) + event_time = getattr(event, 'event_time', '') log = log_format % { 'event_time': event_time.replace('T', ' '), - 'rsrc_name': getattr(event, 'resource_name', ''), + 'rsrc_name': rsrc_name, 'rsrc_status': getattr(event, 'resource_status', ''), 'rsrc_status_reason': getattr(event, 'resource_status_reason', '') } diff --git a/heatclient/osc/v1/event.py b/heatclient/osc/v1/event.py index 870726c..4c6e4e0 100644 --- a/heatclient/osc/v1/event.py +++ b/heatclient/osc/v1/event.py @@ -177,6 +177,7 @@ class ListEvent(command.Lister): marker = parsed_args.marker try: + event_log_context = heat_utils.EventLogContext() while True: events = event_utils.get_events( client, @@ -186,7 +187,8 @@ class ListEvent(command.Lister): marker=marker) if events: marker = getattr(events[-1], 'id', None) - events_log = heat_utils.event_log_formatter(events) + events_log = heat_utils.event_log_formatter( + events, event_log_context) self.app.stdout.write(events_log) self.app.stdout.write('\n') time.sleep(5) diff --git a/heatclient/tests/unit/test_utils.py b/heatclient/tests/unit/test_utils.py index a58dc22..3491816 100644 --- a/heatclient/tests/unit/test_utils.py +++ b/heatclient/tests/unit/test_utils.py @@ -191,6 +191,148 @@ class ShellTest(testtools.TestCase): self.assertEqual(expected, utils.event_log_formatter(events_list)) self.assertEqual('', utils.event_log_formatter([])) + def test_event_log_formatter_resource_path_old_heat(self): + + events = [{ + 'resource_name': 'nested', + 'event_time': '2016-09-05T04:10:24Z', + 'links': [{ + 'href': 'http://192.0.2.1:8004/v1/t/stacks/' + 'nested/1bed5d4d-41d6-4451-b274-c073ebee375d', + 'rel': 'stack' + }], + 'logical_resource_id': 'nested', + 'resource_status': 'CREATE_IN_PROGRESS', + 'resource_status_reason': 'Stack CREATE started', + 'physical_resource_id': '1bed5d4d-41d6-4451-b274-c073ebee375d', + }, { + 'resource_name': 'rg1', + 'event_time': '2016-09-05T04:10:24Z', + 'links': [{ + 'href': 'http://192.0.2.1:8004/v1/t/stacks/' + 'nested/1bed5d4d-41d6-4451-b274-c073ebee375d', + 'rel': 'stack' + }], + 'logical_resource_id': 'rg1', + 'resource_status': 'CREATE_IN_PROGRESS', + 'resource_status_reason': 'state changed', + 'physical_resource_id': None, # note the None from old heat + 'id': '375c49ae-cefb-4fb3-8f4d-1d5f1b9e3e5d' + }, { + 'resource_name': 'nested-rg1-m4zxcs4pra6t', + 'event_time': '2016-09-05T04:10:24Z', + 'links': [{ + 'href': 'http://192.0.2.1:8004/v1/t/stacks/' + 'nested-rg1-m4zxcs4pra6t/' + '3400bbad-a825-4226-ac23-c607846420db', + 'rel': 'stack' + }], + 'logical_resource_id': 'nested-rg1-m4zxcs4pra6t', + 'resource_status': 'CREATE_IN_PROGRESS', + 'resource_status_reason': 'Stack CREATE started', + 'physical_resource_id': '3400bbad-a825-4226-ac23-c607846420db', + 'id': '7e521c84-cd35-4f4c-b0de-962bd3cc40a8' + }, { + 'resource_name': '1', + 'event_time': '2016-09-05T04:10:24Z', + 'links': [{ + 'href': 'http://192.0.2.1:8004/v1/t/stacks/' + 'nested-rg1-m4zxcs4pra6t/' + '3400bbad-a825-4226-ac23-c607846420db', + 'rel': 'stack' + }], + 'logical_resource_id': '1', + 'resource_status': 'CREATE_IN_PROGRESS', + 'resource_status_reason': 'state changed', + 'physical_resource_id': None, # note the None from old heat + 'id': 'c6186c16-94ef-4214-a11a-7e3cc8a17f82' + }] + + events_list = [hc_res.Resource(manager=None, info=event) + for event in events] + + expected = '''\ +2016-09-05 04:10:24Z [nested]: \ +CREATE_IN_PROGRESS Stack CREATE started +2016-09-05 04:10:24Z [nested.rg1]: \ +CREATE_IN_PROGRESS state changed +2016-09-05 04:10:24Z [nested-rg1-m4zxcs4pra6t]: \ +CREATE_IN_PROGRESS Stack CREATE started +2016-09-05 04:10:24Z [nested-rg1-m4zxcs4pra6t.1]: \ +CREATE_IN_PROGRESS state changed''' + self.assertEqual(expected, utils.event_log_formatter(events_list)) + + def test_event_log_formatter_resource_path(self): + + events = [{ + 'resource_name': 'nested', + 'event_time': '2016-09-05T04:10:24Z', + 'links': [{ + 'href': 'http://192.0.2.1:8004/v1/t/stacks/' + 'nested/1bed5d4d-41d6-4451-b274-c073ebee375d', + 'rel': 'stack' + }], + 'logical_resource_id': 'nested', + 'resource_status': 'CREATE_IN_PROGRESS', + 'resource_status_reason': 'Stack CREATE started', + 'physical_resource_id': '1bed5d4d-41d6-4451-b274-c073ebee375d', + }, { + 'resource_name': 'rg1', + 'event_time': '2016-09-05T04:10:24Z', + 'links': [{ + 'href': 'http://192.0.2.1:8004/v1/t/stacks/' + 'nested/1bed5d4d-41d6-4451-b274-c073ebee375d', + 'rel': 'stack' + }], + 'logical_resource_id': 'rg1', + 'resource_status': 'CREATE_IN_PROGRESS', + 'resource_status_reason': 'state changed', + 'physical_resource_id': 'nested-rg1-m4zxcs4pra6t', + 'id': '375c49ae-cefb-4fb3-8f4d-1d5f1b9e3e5d' + }, { + 'resource_name': 'nested-rg1-m4zxcs4pra6t', + 'event_time': '2016-09-05T04:10:24Z', + 'links': [{ + 'href': 'http://192.0.2.1:8004/v1/t/stacks/' + 'nested-rg1-m4zxcs4pra6t/' + '3400bbad-a825-4226-ac23-c607846420db', + 'rel': 'stack' + }], + 'logical_resource_id': 'nested-rg1-m4zxcs4pra6t', + 'resource_status': 'CREATE_IN_PROGRESS', + 'resource_status_reason': 'Stack CREATE started', + 'physical_resource_id': '3400bbad-a825-4226-ac23-c607846420db', + 'id': '7e521c84-cd35-4f4c-b0de-962bd3cc40a8' + }, { + 'resource_name': '1', + 'event_time': '2016-09-05T04:10:24Z', + 'links': [{ + 'href': 'http://192.0.2.1:8004/v1/t/stacks/' + 'nested-rg1-m4zxcs4pra6t/' + '3400bbad-a825-4226-ac23-c607846420db', + 'rel': 'stack' + }], + 'logical_resource_id': '1', + 'resource_status': 'CREATE_IN_PROGRESS', + 'resource_status_reason': 'state changed', + 'physical_resource_id': 'nested-rg1-m4zxcs4pra6t-1-z6sgpq54n6e7', + 'id': 'c6186c16-94ef-4214-a11a-7e3cc8a17f82' + }] + + events_list = [hc_res.Resource(manager=None, info=event) + for event in events] + + expected = '''\ +2016-09-05 04:10:24Z [nested]: \ +CREATE_IN_PROGRESS Stack CREATE started +2016-09-05 04:10:24Z [nested.rg1]: \ +CREATE_IN_PROGRESS state changed +2016-09-05 04:10:24Z [nested.rg1]: \ +CREATE_IN_PROGRESS Stack CREATE started +2016-09-05 04:10:24Z [nested.rg1.1]: \ +CREATE_IN_PROGRESS state changed''' + self.assertEqual(expected, utils.event_log_formatter(events_list)) + class ShellTestParameterFiles(testtools.TestCase): -- cgit v1.2.1 From 00a757eea109f5e21d7cd85ad2f09cdb9ddae94f Mon Sep 17 00:00:00 2001 From: Sharat Sharma Date: Thu, 8 Sep 2016 17:15:40 +0530 Subject: Update .gitreview for stable/newton Change-Id: I52d22733291453372c7173feb95c788b478cd19f --- .gitreview | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitreview b/.gitreview index 054320a..77ea7bb 100644 --- a/.gitreview +++ b/.gitreview @@ -2,3 +2,4 @@ host=review.openstack.org port=29418 project=openstack/python-heatclient.git +defaultbranch=stable/newton -- cgit v1.2.1