Improving readability of OSTF results in system-tests output.

Create function pretty_log which makes log in table format.
Use this function instead of json.dumps() in fuel_web_client.py

Change-Id: I299ec5f26c888d18bbf525c075cb391beeff1950
Closes-Bug: #1506506
This commit is contained in:
vgorin 2015-10-15 19:38:43 +03:00
parent e2e9b4b73c
commit 9e1d5f38d5
2 changed files with 70 additions and 20 deletions

View File

@ -576,3 +576,51 @@ class runlimit(object):
class TimeoutException(Exception):
pass
def pretty_log(src, indent=0, invert=False):
""" Make log more readable and awesome
The main application is using instead of json.dumps().
:param src: dictionary with data, list of dicts
can be also used for strings or lists of strings,
but it makes no sense.
Note: Indent for list by default is +3. If you want to call
pretty_log for list , call it with indent=-3 for 0,
indent=-3+1 for 1 and etc.
:param indent: int
:param invert: Swaps first and second columns. Can be used ONLY
with one levels dictionary
:return: formatted string with result, can be used in log
"""
result = ''
templates = ["\n{indent}{item:{len}}{value}" if not invert else
"\n{indent}{value:{len}}{item}",
"\n{indent}{item}:",
'\n{indent}{value}']
if isinstance(src, dict):
max_len = len(max(src.values() if invert else src.keys(),
key=lambda x: len(str(x))))
for key, value in src.iteritems():
if (isinstance(value, dict) and value) or \
isinstance(value, list):
result += templates[1].format(indent=' ' * indent, item=key)
result += pretty_log(value, indent + 3)
else:
result += templates[0].format(indent=' ' * indent,
item=key,
value=str(value),
len=max_len + 5)
elif isinstance(src, list):
for el in src:
if (isinstance(el, dict) and el) or isinstance(el, list):
res = pretty_log(el, indent + 3)
else:
res = templates[2].format(indent=' ' * (indent + 3),
value=str(el))
result += res[:indent + 2] + '-' + res[indent + 3:]
return result

View File

@ -12,7 +12,6 @@
# License for the specific language governing permissions and limitations
# under the License.
import json
import re
import time
import traceback
@ -48,6 +47,7 @@ from fuelweb_test.helpers.security import SecurityChecks
from fuelweb_test.helpers.utils import run_on_remote
from fuelweb_test.helpers.utils import node_freemem
from fuelweb_test.helpers.utils import get_node_hiera_roles
from fuelweb_test.helpers.utils import pretty_log
from fuelweb_test import logger
from fuelweb_test import logwrap
from fuelweb_test.models.nailgun_client import NailgunClient
@ -181,8 +181,9 @@ class FuelWebClient(object):
"""Wait for OSTF tests to finish, check that the tests specified
in [tests_must_be_passed] are passed"""
logger.info('Assert OSTF tests are passed at cluster #%s: %s',
cluster_id, json.dumps(tests_must_be_passed, indent=1))
logger.info('Assert OSTF tests are passed at cluster #{0}: {1}'.format(
cluster_id, pretty_log(tests_must_be_passed, indent=1)))
set_result_list = self._ostf_test_wait(cluster_id, timeout)
tests_pass_count = 0
tests_count = len(tests_must_be_passed)
@ -202,8 +203,8 @@ class FuelWebClient(object):
assert_true(tests_pass_count == tests_count,
'The following tests have not succeeded, while they '
'must have passed: %s' % json.dumps(fail_details,
indent=1))
'must have passed: {}'.format(pretty_log(fail_details,
indent=1)))
@logwrap
def assert_ostf_run(self, cluster_id, should_fail=0, failed_test_name=None,
@ -212,9 +213,10 @@ class FuelWebClient(object):
If [failed_test_name] tests are expected, ensure that these tests
are not passed"""
logger.info('Assert OSTF run at cluster #%s. '
'Should fail %s tests named %s',
cluster_id, should_fail, failed_test_name)
logger.info('Assert OSTF run at cluster #{0}. '
'Should fail {1} tests named {2}'.format(cluster_id,
should_fail,
failed_test_name))
set_result_list = self._ostf_test_wait(cluster_id, timeout)
failed_tests_res = []
failed = 0
@ -243,8 +245,8 @@ class FuelWebClient(object):
for test in set_result['tests']
if test['status'] not in ['success', 'disabled', 'skipped']]
logger.info('OSTF test statuses are : {0}'
.format(json.dumps(test_result, indent=1)))
logger.info('OSTF test statuses are :\n{}\n'.format(
pretty_log(test_result, indent=1)))
if failed_test_name:
for test_name in failed_test_name:
@ -258,7 +260,7 @@ class FuelWebClient(object):
' {1} tests. Names of failed tests: {2}'
.format(failed,
should_fail,
json.dumps(failed_tests_res,
pretty_log(failed_tests_res,
indent=1)))
def assert_release_state(self, release_name, state='available'):
@ -440,8 +442,8 @@ class FuelWebClient(object):
cluster_id = self.client.get_cluster_id(name)
logger.info('The cluster id is %s', cluster_id)
logger.info('Set cluster settings to %s',
json.dumps(settings, indent=1))
logger.info('Set cluster settings to {}'.format(
pretty_log(settings, indent=1)))
attributes = self.client.get_cluster_attributes(cluster_id)
for option in settings:
@ -990,7 +992,7 @@ class FuelWebClient(object):
tests_res.append({test['name']: test['status']})
logger.info('OSTF test statuses are : {0}'
.format(json.dumps(tests_res, indent=1)))
.format(pretty_log(tests_res, indent=1)))
return tests_res
@logwrap
@ -1010,8 +1012,8 @@ class FuelWebClient(object):
@logwrap
def task_wait(self, task, timeout, interval=5):
logger.info('Wait for task %s seconds: %s',
timeout, json.dumps(task, indent=1))
logger.info('Wait for task {0} seconds: {1}'.format(
timeout, pretty_log(task, indent=1)))
start = time.time()
try:
wait(
@ -1026,9 +1028,9 @@ class FuelWebClient(object):
"was exceeded: ".format(task=task["name"], timeout=timeout))
took = time.time() - start
task = self.client.get_task(task['id'])
logger.info('Task finished. Took %d seconds. %s',
logger.info('Task finished. Took {0} seconds. {1}'.format(
took,
json.dumps(task, indent=1))
pretty_log(task, indent=1)))
return task
@logwrap
@ -1706,8 +1708,8 @@ class FuelWebClient(object):
return failed_count
def get_nailgun_version(self):
logger.info("ISO version: %s" % json.dumps(
self.client.get_api_version(), indent=1))
logger.info("ISO version: {}".format(pretty_log(
self.client.get_api_version(), indent=1)))
@logwrap
def run_ceph_task(self, cluster_id, offline_nodes):