1""" 2Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 3See https://llvm.org/LICENSE.txt for license information. 4SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 5""" 6 7from __future__ import print_function 8from __future__ import absolute_import 9 10# System modules 11import importlib 12import socket 13import sys 14 15# Third-party modules 16 17# LLDB modules 18 19 20# Ignore method count on DTOs. 21# pylint: disable=too-few-public-methods 22class FormatterConfig(object): 23 """Provides formatter configuration info to create_results_formatter().""" 24 25 def __init__(self): 26 self.filename = None 27 self.formatter_name = None 28 self.formatter_options = None 29 30 31# Ignore method count on DTOs. 32# pylint: disable=too-few-public-methods 33class CreatedFormatter(object): 34 """Provides transfer object for returns from create_results_formatter().""" 35 36 def __init__(self, formatter, cleanup_func): 37 self.formatter = formatter 38 self.cleanup_func = cleanup_func 39 40 41def create_results_formatter(config): 42 """Sets up a test results formatter. 43 44 @param config an instance of FormatterConfig 45 that indicates how to setup the ResultsFormatter. 46 47 @return an instance of CreatedFormatter. 48 """ 49 50 default_formatter_name = None 51 results_file_object = None 52 cleanup_func = None 53 54 if config.filename: 55 # Open the results file for writing. 56 if config.filename == 'stdout': 57 results_file_object = sys.stdout 58 cleanup_func = None 59 elif config.filename == 'stderr': 60 results_file_object = sys.stderr 61 cleanup_func = None 62 else: 63 results_file_object = open(config.filename, "w") 64 cleanup_func = results_file_object.close 65 default_formatter_name = ( 66 "lldbsuite.test_event.formatter.xunit.XunitFormatter") 67 68 # If we have a results formatter name specified and we didn't specify 69 # a results file, we should use stdout. 70 if config.formatter_name is not None and results_file_object is None: 71 # Use stdout. 72 results_file_object = sys.stdout 73 cleanup_func = None 74 75 if results_file_object: 76 # We care about the formatter. Choose user-specified or, if 77 # none specified, use the default for the output type. 78 if config.formatter_name: 79 formatter_name = config.formatter_name 80 else: 81 formatter_name = default_formatter_name 82 83 # Create an instance of the class. 84 # First figure out the package/module. 85 components = formatter_name.split(".") 86 module = importlib.import_module(".".join(components[:-1])) 87 88 # Create the class name we need to load. 89 cls = getattr(module, components[-1]) 90 91 # Handle formatter options for the results formatter class. 92 formatter_arg_parser = cls.arg_parser() 93 if config.formatter_options and len(config.formatter_options) > 0: 94 command_line_options = config.formatter_options 95 else: 96 command_line_options = [] 97 98 formatter_options = formatter_arg_parser.parse_args( 99 command_line_options) 100 101 # Create the TestResultsFormatter given the processed options. 102 results_formatter_object = cls( 103 results_file_object, 104 formatter_options) 105 106 def shutdown_formatter(): 107 """Shuts down the formatter when it is no longer needed.""" 108 # Tell the formatter to write out anything it may have 109 # been saving until the very end (e.g. xUnit results 110 # can't complete its output until this point). 111 results_formatter_object.send_terminate_as_needed() 112 113 # And now close out the output file-like object. 114 if cleanup_func is not None: 115 cleanup_func() 116 117 return CreatedFormatter( 118 results_formatter_object, 119 shutdown_formatter) 120 else: 121 return None 122