X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=sidebyside;f=test%2Fpy%2Fmultiplexed_log.py;h=f23d5dec68cd3b8c17e83c09b4820d8d4900fb0f;hb=7c98ca10eae855571b16cddb19d461a981052730;hp=c2a3b89536430fc0c911f83aae44a8783a1caef2;hpb=e8debf394fbba594fcfc267c61f8c6bbca395b06;p=oweals%2Fu-boot.git
diff --git a/test/py/multiplexed_log.py b/test/py/multiplexed_log.py
index c2a3b89536..f23d5dec68 100644
--- a/test/py/multiplexed_log.py
+++ b/test/py/multiplexed_log.py
@@ -1,12 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2015 Stephen Warren
# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
-#
-# SPDX-License-Identifier: GPL-2.0
# Generate an HTML-formatted log file containing multiple streams of data,
# each represented in a well-delineated/-structured fashion.
import cgi
+import datetime
import os.path
import shutil
import subprocess
@@ -101,6 +101,8 @@ class RunAndLog(object):
self.logfile = logfile
self.name = name
self.chained_file = chained_file
+ self.output = None
+ self.exit_status = None
def close(self):
"""Clean up any resources managed by this object."""
@@ -109,6 +111,9 @@ class RunAndLog(object):
def run(self, cmd, cwd=None, ignore_errors=False):
"""Run a command as a sub-process, and log the results.
+ The output is available at self.output which can be useful if there is
+ an exception.
+
Args:
cmd: The command to execute.
cwd: The directory to run the command in. Can be None to use the
@@ -119,10 +124,10 @@ class RunAndLog(object):
raised if such problems occur.
Returns:
- Nothing.
+ The output as a string.
"""
- msg = "+" + " ".join(cmd) + "\n"
+ msg = '+' + ' '.join(cmd) + '\n'
if self.chained_file:
self.chained_file.write(msg)
self.logfile.write(self, msg)
@@ -159,8 +164,14 @@ class RunAndLog(object):
self.logfile.write(self, output)
if self.chained_file:
self.chained_file.write(output)
+ self.logfile.timestamp()
+
+ # Store the output so it can be accessed if we raise an exception.
+ self.output = output
+ self.exit_status = exit_status
if exception:
raise exception
+ return output
class SectionCtxMgr(object):
"""A context manager for Python's "with" statement, which allows a certain
@@ -168,12 +179,13 @@ class SectionCtxMgr(object):
Objects of this type should be created by factory functions in the Logfile
class rather than directly."""
- def __init__(self, log, marker):
+ def __init__(self, log, marker, anchor):
"""Initialize a new object.
Args:
log: The Logfile object to log to.
marker: The name of the nested log section.
+ anchor: The anchor value to pass to start_section().
Returns:
Nothing.
@@ -181,9 +193,10 @@ class SectionCtxMgr(object):
self.log = log
self.marker = marker
+ self.anchor = anchor
def __enter__(self):
- self.log.start_section(self.marker)
+ self.anchor = self.log.start_section(self.marker, self.anchor)
def __exit__(self, extype, value, traceback):
self.log.end_section(self.marker)
@@ -202,19 +215,83 @@ class Logfile(object):
Nothing.
"""
- self.f = open(fn, "wt")
+ self.f = open(fn, 'wt')
self.last_stream = None
self.blocks = []
self.cur_evt = 1
- shutil.copy(mod_dir + "/multiplexed_log.css", os.path.dirname(fn))
- self.f.write("""\
+ self.anchor = 0
+ self.timestamp_start = self._get_time()
+ self.timestamp_prev = self.timestamp_start
+ self.timestamp_blocks = []
+ self.seen_warning = False
+
+ shutil.copy(mod_dir + '/multiplexed_log.css', os.path.dirname(fn))
+ self.f.write('''\
+
+
-""")
+''')
def close(self):
"""Close the log file.
@@ -228,17 +305,17 @@ class Logfile(object):
Nothing.
"""
- self.f.write("""\
+ self.f.write('''\
-""")
+''')
self.f.close()
# The set of characters that should be represented as hexadecimal codes in
# the log file.
- _nonprint = ("%" + "".join(chr(c) for c in range(0, 32) if c not in (9, 10)) +
- "".join(chr(c) for c in range(127, 256)))
+ _nonprint = ('%' + ''.join(chr(c) for c in range(0, 32) if c not in (9, 10)) +
+ ''.join(chr(c) for c in range(127, 256)))
def _escape(self, data):
"""Render data format suitable for inclusion in an HTML document.
@@ -253,8 +330,8 @@ class Logfile(object):
An escaped version of the data.
"""
- data = data.replace(chr(13), "")
- data = "".join((c in self._nonprint) and ("%%%02x" % ord(c)) or
+ data = data.replace(chr(13), '')
+ data = ''.join((c in self._nonprint) and ('%%%02x' % ord(c)) or
c for c in data)
data = cgi.escape(data)
return data
@@ -272,46 +349,63 @@ class Logfile(object):
self.cur_evt += 1
if not self.last_stream:
return
- self.f.write("\n")
- self.f.write("
\n')
+ self.f.write('\n')
+ self.f.write('\n')
self.last_stream = None
- def _note(self, note_type, msg):
+ def _note(self, note_type, msg, anchor=None):
"""Write a note or one-off message to the log file.
Args:
note_type: The type of note. This must be a value supported by the
accompanying multiplexed_log.css.
msg: The note/message to log.
+ anchor: Optional internal link target.
Returns:
Nothing.
"""
self._terminate_stream()
- self.f.write("
\n")
+ if anchor:
+ self.f.write('')
+ self.f.write('\n
\n')
+ self.f.write('
\n')
- def start_section(self, marker):
+ def start_section(self, marker, anchor=None):
"""Begin a new nested section in the log file.
Args:
marker: The name of the section that is starting.
+ anchor: The value to use for the anchor. If None, a unique value
+ will be calculated and used
Returns:
- Nothing.
+ Name of the HTML anchor emitted before section.
"""
self._terminate_stream()
self.blocks.append(marker)
- blk_path = "/".join(self.blocks)
- self.f.write("