[Lldb-commits] [lldb] r254979 - Refactor ResultsFormatter creation into result_formatter.

Todd Fiala via lldb-commits lldb-commits at lists.llvm.org
Tue Dec 8 07:49:34 PST 2015


Perfect.  I have a few things I'm trying to work in - finishing up wiring
things up (timeouts and exceptional process exits) to the new basic
formatter, then getting the low-load, single worker test runner pass up for
review.   I have most of the first one done, should have that in today.
The second one will take me a bit longer but I hope to have that done by,
say, end of tomorrow or the day after.

Looks like Pavel got to fix up the OS X dotest.py.  I ran out of steam last
night to diagnose.

-Todd

On Mon, Dec 7, 2015 at 9:37 PM, Zachary Turner <zturner at google.com> wrote:

> I'll hold off a bit on major changes for now.  I'm going to start working
> on non-controversial command line options tomorrow, but no more major code
> moves.  I worked on this today since I wanted to get final agreement on the
> command line options first.
>
> On Mon, Dec 7, 2015 at 9:21 PM Todd Fiala <todd.fiala at gmail.com> wrote:
>
>> (We're highly intersecting right now - I've got some other goo that I
>> figured I'd hold off on since I'm sure we're hitting the same files).
>>
>> On Mon, Dec 7, 2015 at 9:21 PM, Todd Fiala <todd.fiala at gmail.com> wrote:
>>
>>> Yep sure thing.
>>>
>>> On Mon, Dec 7, 2015 at 5:00 PM, Zachary Turner <zturner at google.com>
>>> wrote:
>>>
>>>> I'm going to have to merge this into my patch.  Can you hold off on any
>>>> other patches until I get in?
>>>>
>>>> On Mon, Dec 7, 2015 at 4:56 PM Todd Fiala via lldb-commits <
>>>> lldb-commits at lists.llvm.org> wrote:
>>>>
>>>>> Author: tfiala
>>>>> Date: Mon Dec  7 18:53:56 2015
>>>>> New Revision: 254979
>>>>>
>>>>> URL: http://llvm.org/viewvc/llvm-project?rev=254979&view=rev
>>>>> Log:
>>>>> Refactor ResultsFormatter creation into result_formatter.
>>>>>
>>>>> This cleans up dotest.py and is a pre-step for getting
>>>>> the test inferior runner to send post-inferior run events
>>>>> to the events collector, as this code needs to be accessed
>>>>> from within dosep.py.
>>>>>
>>>>> Modified:
>>>>>     lldb/trunk/packages/Python/lldbsuite/test/dotest.py
>>>>>     lldb/trunk/packages/Python/lldbsuite/test/result_formatter.py
>>>>>
>>>>> Modified: lldb/trunk/packages/Python/lldbsuite/test/dotest.py
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/dotest.py?rev=254979&r1=254978&r2=254979&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- lldb/trunk/packages/Python/lldbsuite/test/dotest.py (original)
>>>>> +++ lldb/trunk/packages/Python/lldbsuite/test/dotest.py Mon Dec  7
>>>>> 18:53:56 2015
>>>>> @@ -239,7 +239,6 @@ test_runner_name = None
>>>>>  # Test results handling globals
>>>>>  results_filename = None
>>>>>  results_port = None
>>>>> -results_file_object = None
>>>>>  results_formatter_name = None
>>>>>  results_formatter_object = None
>>>>>  results_formatter_options = None
>>>>> @@ -910,73 +909,24 @@ def createSocketToLocalPort(port):
>>>>>  def setupTestResults():
>>>>>      """Sets up test results-related objects based on arg settings."""
>>>>>      global results_filename
>>>>> -    global results_file_object
>>>>>      global results_formatter_name
>>>>>      global results_formatter_object
>>>>>      global results_formatter_options
>>>>>      global results_port
>>>>>
>>>>> -    default_formatter_name = None
>>>>> -    cleanup_func = None
>>>>> +    # Setup the results formatter configuration.
>>>>> +    config = result_formatter.FormatterConfig()
>>>>> +    config.filename = results_filename
>>>>> +    config.formatter_name = results_formatter_name
>>>>> +    config.formatter_options = results_formatter_options
>>>>> +    config.port = results_port
>>>>> +
>>>>> +    # Create the results formatter.
>>>>> +    formatter_spec = result_formatter.create_results_formatter(config)
>>>>> +    if formatter_spec is not None and formatter_spec.formatter is not
>>>>> None:
>>>>> +        results_formatter_object = formatter_spec.formatter
>>>>>
>>>>> -    if results_filename:
>>>>> -        # Open the results file for writing.
>>>>> -        if results_filename == 'stdout':
>>>>> -            results_file_object = sys.stdout
>>>>> -            cleanup_func = None
>>>>> -        elif results_filename == 'stderr':
>>>>> -            results_file_object = sys.stderr
>>>>> -            cleanup_func = None
>>>>> -        else:
>>>>> -            results_file_object = open(results_filename, "w")
>>>>> -            cleanup_func = results_file_object.close
>>>>> -        default_formatter_name =
>>>>> "lldbsuite.test.result_formatter.XunitFormatter"
>>>>> -    elif results_port:
>>>>> -        # Connect to the specified localhost port.
>>>>> -        results_file_object, cleanup_func = createSocketToLocalPort(
>>>>> -            results_port)
>>>>> -        default_formatter_name = (
>>>>> -            "lldbsuite.test.result_formatter.RawPickledFormatter")
>>>>> -
>>>>> -    # If we have a results formatter name specified and we didn't
>>>>> specify
>>>>> -    # a results file, we should use stdout.
>>>>> -    if results_formatter_name is not None and results_file_object is
>>>>> None:
>>>>> -        # Use stdout.
>>>>> -        results_file_object = sys.stdout
>>>>> -        cleanup_func = None
>>>>> -
>>>>> -    if results_file_object:
>>>>> -        # We care about the formatter.  Choose user-specified or, if
>>>>> -        # none specified, use the default for the output type.
>>>>> -        if results_formatter_name:
>>>>> -            formatter_name = results_formatter_name
>>>>> -        else:
>>>>> -            formatter_name = default_formatter_name
>>>>> -
>>>>> -        # Create an instance of the class.
>>>>> -        # First figure out the package/module.
>>>>> -        components = formatter_name.split(".")
>>>>> -        module = importlib.import_module(".".join(components[:-1]))
>>>>> -
>>>>> -        # Create the class name we need to load.
>>>>> -        clazz = getattr(module, components[-1])
>>>>> -
>>>>> -        # Handle formatter options for the results formatter class.
>>>>> -        formatter_arg_parser = clazz.arg_parser()
>>>>> -        if results_formatter_options and
>>>>> len(results_formatter_options) > 0:
>>>>> -            command_line_options = results_formatter_options
>>>>> -        else:
>>>>> -            command_line_options = []
>>>>> -
>>>>> -        formatter_options = formatter_arg_parser.parse_args(
>>>>> -            command_line_options)
>>>>> -
>>>>> -        # Create the TestResultsFormatter given the processed options.
>>>>> -        results_formatter_object = clazz(
>>>>> -            results_file_object, formatter_options)
>>>>> -
>>>>> -        # Start the results formatter session - we'll only have one
>>>>> -        # during a given dotest process invocation.
>>>>> +        # Send an intialize message to the formatter.
>>>>>          initialize_event = EventBuilder.bare_event("initialize")
>>>>>          if isMultiprocessTestRunner():
>>>>>              if test_runner_name is not None and test_runner_name ==
>>>>> "serial":
>>>>> @@ -989,19 +939,11 @@ def setupTestResults():
>>>>>              worker_count = 1
>>>>>          initialize_event["worker_count"] = worker_count
>>>>>
>>>>> -        results_formatter_object.handle_event(initialize_event)
>>>>> -
>>>>> -        def shutdown_formatter():
>>>>> -            # Tell the formatter to write out anything it may have
>>>>> -            # been saving until the very end (e.g. xUnit results
>>>>> -            # can't complete its output until this point).
>>>>> -            results_formatter_object.send_terminate_as_needed()
>>>>> -
>>>>> -            # And now close out the output file-like object.
>>>>> -            if cleanup_func is not None:
>>>>> -                cleanup_func()
>>>>> +        formatter_spec.formatter.handle_event(initialize_event)
>>>>>
>>>>> -        atexit.register(shutdown_formatter)
>>>>> +        # Make sure we clean up the formatter on shutdown.
>>>>> +        if formatter_spec.cleanup_func is not None:
>>>>> +            atexit.register(formatter_spec.cleanup_func)
>>>>>
>>>>>
>>>>>  def getOutputPaths(lldbRootDirectory):
>>>>>
>>>>> Modified: lldb/trunk/packages/Python/lldbsuite/test/result_formatter.py
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/result_formatter.py?rev=254979&r1=254978&r2=254979&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- lldb/trunk/packages/Python/lldbsuite/test/result_formatter.py
>>>>> (original)
>>>>> +++ lldb/trunk/packages/Python/lldbsuite/test/result_formatter.py Mon
>>>>> Dec  7 18:53:56 2015
>>>>> @@ -13,10 +13,12 @@ from __future__ import absolute_import
>>>>>
>>>>>  # System modules
>>>>>  import argparse
>>>>> +import importlib
>>>>>  import inspect
>>>>>  import os
>>>>>  import pprint
>>>>>  import re
>>>>> +import socket
>>>>>  import sys
>>>>>  import threading
>>>>>  import time
>>>>> @@ -30,6 +32,122 @@ from six.moves import cPickle
>>>>>  # LLDB modules
>>>>>
>>>>>
>>>>> +class FormatterConfig(object):
>>>>> +    def __init__(self):
>>>>> +        self.filename = None
>>>>> +        self.port = None
>>>>> +        self.formatter_name = None
>>>>> +        self.formatter_options = None
>>>>> +
>>>>> +
>>>>> +class CreatedFormatter(object):
>>>>> +    def __init__(self, formatter, cleanup_func):
>>>>> +        self.formatter = formatter
>>>>> +        self.cleanup_func = cleanup_func
>>>>> +
>>>>> +
>>>>> +def create_results_formatter(config):
>>>>> +    """Sets up a test results formatter.
>>>>> +
>>>>> +    @param config an instance of FormatterConfig
>>>>> +    that indicates how to setup the ResultsFormatter.
>>>>> +
>>>>> +    @return an instance of CreatedFormatter.
>>>>> +    """
>>>>> +    def create_socket(port):
>>>>> +        """Creates a socket to the localhost on the given port.
>>>>> +
>>>>> +        @param port the port number of the listenering port on
>>>>> +        the localhost.
>>>>> +
>>>>> +        @return (socket object, socket closing function)
>>>>> +        """
>>>>> +        def socket_closer(open_sock):
>>>>> +            """Close down an opened socket properly."""
>>>>> +            open_sock.shutdown(socket.SHUT_RDWR)
>>>>> +            open_sock.close()
>>>>> +
>>>>> +        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>>>> +        sock.connect(("localhost", port))
>>>>> +        return (sock, lambda: socket_closer(sock))
>>>>> +
>>>>> +    default_formatter_name = None
>>>>> +    results_file_object = None
>>>>> +    cleanup_func = None
>>>>> +
>>>>> +    if config.filename:
>>>>> +        # Open the results file for writing.
>>>>> +        if config.filename == 'stdout':
>>>>> +            results_file_object = sys.stdout
>>>>> +            cleanup_func = None
>>>>> +        elif config.filename == 'stderr':
>>>>> +            results_file_object = sys.stderr
>>>>> +            cleanup_func = None
>>>>> +        else:
>>>>> +            results_file_object = open(config.filename, "w")
>>>>> +            cleanup_func = results_file_object.close
>>>>> +        default_formatter_name = (
>>>>> +            "lldbsuite.test.result_formatter.XunitFormatter")
>>>>> +    elif config.port:
>>>>> +        # Connect to the specified localhost port.
>>>>> +        results_file_object, cleanup_func = create_socket(config.port)
>>>>> +        default_formatter_name = (
>>>>> +            "lldbsuite.test.result_formatter.RawPickledFormatter")
>>>>> +
>>>>> +    # If we have a results formatter name specified and we didn't
>>>>> specify
>>>>> +    # a results file, we should use stdout.
>>>>> +    if config.formatter_name is not None and results_file_object is
>>>>> None:
>>>>> +        # Use stdout.
>>>>> +        results_file_object = sys.stdout
>>>>> +        cleanup_func = None
>>>>> +
>>>>> +    if results_file_object:
>>>>> +        # We care about the formatter.  Choose user-specified or, if
>>>>> +        # none specified, use the default for the output type.
>>>>> +        if config.formatter_name:
>>>>> +            formatter_name = config.formatter_name
>>>>> +        else:
>>>>> +            formatter_name = default_formatter_name
>>>>> +
>>>>> +        # Create an instance of the class.
>>>>> +        # First figure out the package/module.
>>>>> +        components = formatter_name.split(".")
>>>>> +        module = importlib.import_module(".".join(components[:-1]))
>>>>> +
>>>>> +        # Create the class name we need to load.
>>>>> +        cls = getattr(module, components[-1])
>>>>> +
>>>>> +        # Handle formatter options for the results formatter class.
>>>>> +        formatter_arg_parser = cls.arg_parser()
>>>>> +        if config.formatter_options and len(config.formatter_options)
>>>>> > 0:
>>>>> +            command_line_options = config.formatter_options
>>>>> +        else:
>>>>> +            command_line_options = []
>>>>> +
>>>>> +        formatter_options = formatter_arg_parser.parse_args(
>>>>> +            command_line_options)
>>>>> +
>>>>> +        # Create the TestResultsFormatter given the processed options.
>>>>> +        results_formatter_object = cls(results_file_object,
>>>>> formatter_options)
>>>>> +
>>>>> +        def shutdown_formatter():
>>>>> +            """Shuts down the formatter when it is no longer
>>>>> needed."""
>>>>> +            # Tell the formatter to write out anything it may have
>>>>> +            # been saving until the very end (e.g. xUnit results
>>>>> +            # can't complete its output until this point).
>>>>> +            results_formatter_object.send_terminate_as_needed()
>>>>> +
>>>>> +            # And now close out the output file-like object.
>>>>> +            if cleanup_func is not None:
>>>>> +                cleanup_func()
>>>>> +
>>>>> +        return CreatedFormatter(
>>>>> +            results_formatter_object,
>>>>> +            shutdown_formatter)
>>>>> +    else:
>>>>> +        return None
>>>>> +
>>>>> +
>>>>>  class EventBuilder(object):
>>>>>      """Helper class to build test result event dictionaries."""
>>>>>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> lldb-commits mailing list
>>>>> lldb-commits at lists.llvm.org
>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
>>>>>
>>>>
>>>
>>>
>>> --
>>> -Todd
>>>
>>
>>
>>
>> --
>> -Todd
>>
>


-- 
-Todd
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20151208/deb4bb21/attachment-0001.html>


More information about the lldb-commits mailing list