Also write to a log file by default

Write the log of outcome analysis to a log file by default. This is a cheap
way of getting the outcome analysis log in an easy-to-access form on the CI:
with our current CI scripts, they are now automatically available as an
artifact called `analyze_outcomes.log`.

Signed-off-by: Gilles Peskine <[email protected]>
This commit is contained in:
Gilles Peskine
2024-10-09 13:53:57 +02:00
parent 48c005f569
commit 67e415fc6a
+24 -6
View File
@@ -47,9 +47,20 @@ Outcomes = typing.Dict[str, ComponentOutcomes]
class Results:
"""Process analysis results."""
def __init__(self):
def __init__(self,
stderr: bool = True,
log_file: str = '') -> None:
"""Log and count errors.
Log to stderr if stderr is true.
Log to log_file if specified and non-empty.
"""
self.error_count = 0
self.warning_count = 0
self.stderr = stderr
self.log_file = None
if log_file:
self.log_file = open(log_file, 'w', encoding='utf-8')
def new_section(self, fmt, *args, **kwargs):
self._print_line('\n*** ' + fmt + ' ***\n', *args, **kwargs)
@@ -65,9 +76,12 @@ class Results:
self.warning_count += 1
self._print_line('Warning: ' + fmt, *args, **kwargs)
@staticmethod
def _print_line(fmt, *args, **kwargs):
sys.stderr.write((fmt + '\n').format(*args, **kwargs))
def _print_line(self, fmt, *args, **kwargs):
line = (fmt + '\n').format(*args, **kwargs)
if self.stderr:
sys.stderr.write(line)
if self.log_file:
self.log_file.write(line)
def execute_reference_driver_tests(results: Results, ref_component: str, driver_component: str, \
outcome_file: str) -> None:
@@ -284,8 +298,6 @@ class DriverVSReference(Task):
def main(known_tasks: typing.Dict[str, typing.Type[Task]]) -> None:
main_results = Results()
try:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('outcomes', metavar='OUTCOMES.CSV',
@@ -297,6 +309,10 @@ def main(known_tasks: typing.Dict[str, typing.Type[Task]]) -> None:
'comma/space-separated list of tasks. ')
parser.add_argument('--list', action='store_true',
help='List all available tasks and exit.')
parser.add_argument('--log-file',
default='tests/analyze_outcomes.log',
help='Log file (default: tests/analyze_outcomes.log;'
' empty means no log file)')
parser.add_argument('--require-full-coverage', action='store_true',
dest='full_coverage', help="Require all available "
"test cases to be executed and issue an error "
@@ -309,6 +325,8 @@ def main(known_tasks: typing.Dict[str, typing.Type[Task]]) -> None:
print(task_name)
sys.exit(0)
main_results = Results(log_file=options.log_file)
if options.specified_tasks == 'all':
tasks_list = list(known_tasks.keys())
else: