[ui] Add count of messages to commit configdocs CLI
The list of validations returned from commit configdocs can be long and sometimes lose sight of errors. This change adds a summary count of the severity level of messages returned at the bottom of the output so as to clue the user into what might be closer to the top. Change-Id: I2a8921b22977b8ceab0afb1341b195c12dc49c67
This commit is contained in:
parent
89840303b1
commit
a51e30f0a2
shipyard_client
tests/unit/control
@ -61,12 +61,21 @@ def cli_format_status_handler(response, is_error=False):
|
||||
resp_j = response.json()
|
||||
resp = formatted.format(resp_j.get('message', 'Not specified'),
|
||||
resp_j.get('reason', 'Not specified'))
|
||||
# lvl_counts must have a matching number of values as the
|
||||
# _LEVEL_KEYS below + 1 for sentinel.
|
||||
lvl_counts = [0, 0, 0, 0]
|
||||
if resp_j.get('details'):
|
||||
mlist = resp_j['details'].get('messageList', [])
|
||||
for message in sorted(mlist,
|
||||
key=lambda m: _lvl_key(
|
||||
m.get('level'),
|
||||
m.get('error', False))):
|
||||
# Decorate messages with level number and sortkey
|
||||
for message in mlist:
|
||||
message['lnum'], message['sortkey'] = _lvl_key(
|
||||
message.get('level'),
|
||||
message.get('error', False)
|
||||
)
|
||||
# Sort and formulate the messages
|
||||
for message in sorted(mlist, key=lambda m: m['sortkey']):
|
||||
lnum = message['lnum']
|
||||
lvl_counts[lnum] = lvl_counts[lnum] + 1
|
||||
if message.get('kind') == 'ValidationMessage':
|
||||
resp = resp + _format_validation_message(message)
|
||||
else:
|
||||
@ -76,6 +85,11 @@ def cli_format_status_handler(response, is_error=False):
|
||||
_INDENT,
|
||||
message['source']
|
||||
)
|
||||
# Append a count summary
|
||||
resp = resp + ("\n\n#### Errors: {},"
|
||||
" Warnings: {},"
|
||||
" Infos: {},"
|
||||
" Other: {} ####".format(*lvl_counts))
|
||||
return resp
|
||||
else:
|
||||
return ''
|
||||
@ -92,14 +106,18 @@ _LEVEL_KEYS = {
|
||||
1: ['warn', 'warning'],
|
||||
2: ['info', 'debug'],
|
||||
}
|
||||
_SENTINEL_LEVEL = "999"
|
||||
_SENTINEL_SORT_KEY = "3none"
|
||||
_SENTINEL_LEVEL = 3
|
||||
|
||||
|
||||
def _lvl_key(level_name, error):
|
||||
"""Generate a level key value
|
||||
"""Generate a level key value and sort key
|
||||
|
||||
Returns a value to support sort order based on lvls dict.
|
||||
The result is that like-level items are sorted together.
|
||||
The level number provides sameness for levels that are named differently
|
||||
but are the same level for our purposes. The sort key retains the original
|
||||
provided level so that like named items still sort together.
|
||||
"""
|
||||
if level_name is None:
|
||||
if (error):
|
||||
@ -111,8 +129,8 @@ def _lvl_key(level_name, error):
|
||||
|
||||
for key, val_list in _LEVEL_KEYS.items():
|
||||
if level_name in val_list:
|
||||
return '{}{}'.format(key, level_name)
|
||||
return _SENTINEL_LEVEL
|
||||
return key, '{}{}'.format(key, level_name)
|
||||
return _SENTINEL_LEVEL, _SENTINEL_SORT_KEY
|
||||
|
||||
|
||||
def _format_validation_message(message):
|
||||
|
@ -60,7 +60,6 @@ def test_cli_format_error_handler_no_messages():
|
||||
resp = MagicMock()
|
||||
resp.json = MagicMock(return_value=json.loads(resp_val))
|
||||
output = format_utils.cli_format_error_handler(resp)
|
||||
print(output)
|
||||
assert "Error: Unauthenticated" in output
|
||||
assert "Reason: Credentials are not established" in output
|
||||
|
||||
@ -208,7 +207,74 @@ Reason: Validation
|
||||
Document: schema/schema/v1 - someyaml
|
||||
Source: format-o-matic
|
||||
- Info: Basic info
|
||||
Source: Armadadock"""
|
||||
Source: Armadadock
|
||||
|
||||
#### Errors: 4, Warnings: 0, Infos: 2, Other: 0 ####"""
|
||||
resp = MagicMock()
|
||||
resp.json = MagicMock(return_value=json.loads(resp_val))
|
||||
output = format_utils.cli_format_status_handler(resp, is_error=True)
|
||||
assert output == expected
|
||||
|
||||
|
||||
def test_cli_format_status_handler_messages_empty():
|
||||
"""Tests the generic handler for shipyard status response if passed
|
||||
a response with no message in the detail to ensure the empty case works.
|
||||
"""
|
||||
resp_val = """
|
||||
{
|
||||
"apiVersion": "v1.0",
|
||||
"status": "Failure",
|
||||
"metadata": {},
|
||||
"message": "Component Validation Failed",
|
||||
"code": 400,
|
||||
"details": {
|
||||
"errorCount": 0,
|
||||
"messageList": []
|
||||
},
|
||||
"kind": "Status",
|
||||
"reason": "Validation"
|
||||
}
|
||||
"""
|
||||
expected = """Error: Component Validation Failed
|
||||
Reason: Validation
|
||||
|
||||
#### Errors: 0, Warnings: 0, Infos: 0, Other: 0 ####"""
|
||||
resp = MagicMock()
|
||||
resp.json = MagicMock(return_value=json.loads(resp_val))
|
||||
output = format_utils.cli_format_status_handler(resp, is_error=True)
|
||||
assert output == expected
|
||||
|
||||
|
||||
def test_cli_format_status_handler_messages_invalid_levels():
|
||||
"""Tests the generic handler for shipyard status response if passed
|
||||
a response with no message in the detail to ensure the empty case works.
|
||||
"""
|
||||
resp_val = """
|
||||
{
|
||||
"apiVersion": "v1.0",
|
||||
"status": "Failure",
|
||||
"metadata": {},
|
||||
"message": "Component Validation Failed",
|
||||
"code": 400,
|
||||
"details": {
|
||||
"errorCount": 0,
|
||||
"messageList": [
|
||||
{ "message": "It is broken",
|
||||
"level": "Broken",
|
||||
"kind": "ValidationMessage"
|
||||
}
|
||||
]
|
||||
},
|
||||
"kind": "Status",
|
||||
"reason": "Validation"
|
||||
}
|
||||
"""
|
||||
expected = """Error: Component Validation Failed
|
||||
Reason: Validation
|
||||
- Broken: None
|
||||
Message: It is broken
|
||||
|
||||
#### Errors: 0, Warnings: 0, Infos: 0, Other: 1 ####"""
|
||||
resp = MagicMock()
|
||||
resp.json = MagicMock(return_value=json.loads(resp_val))
|
||||
output = format_utils.cli_format_status_handler(resp, is_error=True)
|
||||
|
@ -39,7 +39,6 @@ def test_add_role():
|
||||
def test_add_roles():
|
||||
'''test add_roles'''
|
||||
ctx = ShipyardRequestContext()
|
||||
print(ctx.roles)
|
||||
test_roles = ['Waiter', 'Host', 'Chef']
|
||||
ctx.add_roles(test_roles)
|
||||
assert ['Chef', 'Host', 'Waiter', 'anyone'] == sorted(ctx.roles)
|
||||
|
Loading…
x
Reference in New Issue
Block a user