diff --git a/test/functional/combine_logs.py b/test/functional/combine_logs.py --- a/test/functional/combine_logs.py +++ b/test/functional/combine_logs.py @@ -12,6 +12,7 @@ import heapq import itertools import os +import pathlib import re import sys import tempfile @@ -60,9 +61,22 @@ print("Opening latest test directory: {}".format(testdir), file=sys.stderr) + colors = defaultdict(lambda: '') + if args.color: + colors["test"] = "\033[0;36m" # CYAN + colors["node0"] = "\033[0;34m" # BLUE + colors["node1"] = "\033[0;32m" # GREEN + colors["node2"] = "\033[0;31m" # RED + colors["node3"] = "\033[0;33m" # YELLOW + colors["reset"] = "\033[0m" # Reset font color + log_events = read_logs(testdir) - print_logs(log_events, color=args.color, html=args.html) + if args.html: + print_logs_html(log_events) + else: + print_logs_plain(log_events, colors) + print_node_warnings(testdir, colors) def read_logs(tmp_dir): @@ -93,6 +107,29 @@ return heapq.merge(*[get_log_events(source, f) for source, f in files]) +def print_node_warnings(tmp_dir, colors): + """Print nodes' errors and warnings""" + + warnings = [] + for stream in ['stdout', 'stderr']: + for i in itertools.count(): + folder = "{}/node{}/{}".format(tmp_dir, i, stream) + if not os.path.isdir(folder): + break + for (_, _, fns) in os.walk(folder): + for fn in fns: + warning = pathlib.Path( + '{}/{}'.format(folder, fn)).read_text().strip() + if warning: + warnings.append(("node{} {}".format(i, stream), + warning)) + + print() + for w in warnings: + print("{} {} {} {}".format(colors[w[0].split()[0]], + w[0], w[1], colors["reset"])) + + def find_latest_test_dir(): """Returns the latest tmpfile test directory prefix.""" tmpdir = tempfile.gettempdir() @@ -153,36 +190,30 @@ logfile), file=sys.stderr) -def print_logs(log_events, color=False, html=False): - """Renders the iterator of log events into text or html.""" - if not html: - colors = defaultdict(lambda: '') - if color: - colors["test"] = "\033[0;36m" # CYAN - colors["node0"] = "\033[0;34m" # BLUE - colors["node1"] = "\033[0;32m" # GREEN - colors["node2"] = "\033[0;31m" # RED - colors["node3"] = "\033[0;33m" # YELLOW - colors["reset"] = "\033[0m" # Reset font color - - for event in log_events: - lines = event.event.splitlines() - print("{0} {1: <5} {2} {3}".format( - colors[event.source.rstrip()], event.source, lines[0], colors["reset"])) - if len(lines) > 1: - for line in lines[1:]: - print("{0}{1}{2}".format( - colors[event.source.rstrip()], line, colors["reset"])) +def print_logs_plain(log_events, colors): + """Renders the iterator of log events into text.""" + for event in log_events: + lines = event.event.splitlines() + print("{0} {1: <5} {2} {3}".format(colors[event.source.rstrip()], + event.source, lines[0], + colors["reset"])) + if len(lines) > 1: + for line in lines[1:]: + print("{0}{1}{2}".format( + colors[event.source.rstrip()], line, colors["reset"])) - else: - try: - import jinja2 - except ImportError: - print("jinja2 not found. Try `pip install jinja2`") - sys.exit(1) - print(jinja2.Environment(loader=jinja2.FileSystemLoader('./')) - .get_template('combined_log_template.html') - .render(title="Combined Logs from testcase", log_events=[event._asdict() for event in log_events])) + +def print_logs_html(log_events): + """Renders the iterator of log events into html.""" + try: + import jinja2 + except ImportError: + print("jinja2 not found. Try `pip install jinja2`") + sys.exit(1) + print(jinja2.Environment(loader=jinja2.FileSystemLoader('./')) + .get_template('combined_log_template.html') + .render(title="Combined Logs from testcase", + log_events=[event._asdict() for event in log_events])) if __name__ == '__main__':