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