labath updated this revision to Diff 381500.
labath added a comment.

- support single command only
- add a test


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D112212/new/

https://reviews.llvm.org/D112212

Files:
  lldb/packages/Python/lldbsuite/test/builders/builder.py
  lldb/packages/Python/lldbsuite/test/lldbtest.py
  lldb/packages/Python/lldbsuite/test_event/build_exception.py
  lldb/test/API/test_utils/Makefile
  lldb/test/API/test_utils/TestBaseTest.py
  lldb/test/API/test_utils/return0.cpp

Index: lldb/test/API/test_utils/return0.cpp
===================================================================
--- /dev/null
+++ lldb/test/API/test_utils/return0.cpp
@@ -0,0 +1 @@
+int main() { return 0; }
Index: lldb/test/API/test_utils/TestBaseTest.py
===================================================================
--- /dev/null
+++ lldb/test/API/test_utils/TestBaseTest.py
@@ -0,0 +1,34 @@
+"""
+Test TestBase test functions.
+"""
+
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test_event import build_exception
+import six
+
+class TestBuildMethod(Base):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    def setUp(self):
+        super().setUp()
+        self._traces = []
+        self.traceAlways = True
+
+    def trace(self, *args, **kwargs):
+        io = six.StringIO()
+        print(*args, file=io, **kwargs)
+        self._traces.append(io.getvalue())
+
+    def test_build_fails_helpfully(self):
+        try:
+            self.build(dictionary={"CXX_SOURCES": "nonexisting-file.cpp"})
+        except build_exception.BuildError as e:
+            self.assertIn("nonexisting-file.cpp", str(e))
+        else:
+            self.fail("BuildError not raised!")
+
+    def test_build_logs_traces(self):
+        self.build(dictionary={"CXX_SOURCES": "return0.cpp"})
+        self.assertIn("CXX_SOURCES", self._traces[0])
+        self.assertIn("return0.o", self._traces[1])
Index: lldb/test/API/test_utils/Makefile
===================================================================
--- /dev/null
+++ lldb/test/API/test_utils/Makefile
@@ -0,0 +1 @@
+include Makefile.rules
Index: lldb/packages/Python/lldbsuite/test_event/build_exception.py
===================================================================
--- lldb/packages/Python/lldbsuite/test_event/build_exception.py
+++ lldb/packages/Python/lldbsuite/test_event/build_exception.py
@@ -1,10 +1,11 @@
+import shlex
+
 class BuildError(Exception):
 
     def __init__(self, called_process_error):
         super(BuildError, self).__init__("Error when building test subject")
-        self.command = called_process_error.lldb_extensions.get(
-            "command", "<command unavailable>")
-        self.build_error = called_process_error.lldb_extensions["combined_output"]
+        self.command = shlex.join(called_process_error.cmd)
+        self.build_error = called_process_error.output
 
     def __str__(self):
         return self.format_build_error(self.command, self.build_error)
@@ -12,4 +13,4 @@
     @staticmethod
     def format_build_error(command, command_output):
         return "Error when building test subject.\n\nBuild Command:\n{}\n\nBuild Command Output:\n{}".format(
-            command, command_output.decode("utf-8", errors='ignore'))
+            command, command_output)
Index: lldb/packages/Python/lldbsuite/test/lldbtest.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -45,6 +45,7 @@
 import re
 import shutil
 import signal
+import shlex
 from subprocess import *
 import sys
 import time
@@ -68,6 +69,7 @@
 from lldbsuite.support import encoded_file
 from lldbsuite.support import funcutils
 from lldbsuite.test.builders import get_builder
+from lldbsuite.test_event import build_exception
 
 # See also dotest.parseOptionsAndInitTestdirs(), where the environment variables
 # LLDB_COMMAND_TRACE is set from '-t' option.
@@ -469,61 +471,6 @@
     def terminate(self):
         lldb.remote_platform.Kill(self._pid)
 
-# From 2.7's subprocess.check_output() convenience function.
-# Return a tuple (stdoutdata, stderrdata).
-
-
-def system(commands, **kwargs):
-    r"""Run an os command with arguments and return its output as a byte string.
-
-    If the exit code was non-zero it raises a CalledProcessError.  The
-    CalledProcessError object will have the return code in the returncode
-    attribute and output in the output attribute.
-
-    The arguments are the same as for the Popen constructor.  Example:
-
-    >>> check_output(["ls", "-l", "/dev/null"])
-    'crw-rw-rw- 1 root root 1, 3 Oct 18  2007 /dev/null\n'
-
-    The stdout argument is not allowed as it is used internally.
-    To capture standard error in the result, use stderr=STDOUT.
-
-    >>> check_output(["/bin/sh", "-c",
-    ...               "ls -l non_existent_file ; exit 0"],
-    ...              stderr=STDOUT)
-    'ls: non_existent_file: No such file or directory\n'
-    """
-
-    output = ""
-    error = ""
-    for shellCommand in commands:
-        if 'stdout' in kwargs:
-            raise ValueError(
-                'stdout argument not allowed, it will be overridden.')
-        process = Popen(
-            shellCommand,
-            stdout=PIPE,
-            stderr=STDOUT,
-            **kwargs)
-        pid = process.pid
-        this_output, this_error = process.communicate()
-        retcode = process.poll()
-
-        if retcode:
-            cmd = kwargs.get("args")
-            if cmd is None:
-                cmd = shellCommand
-            cpe = CalledProcessError(retcode, cmd)
-            # Ensure caller can access the stdout/stderr.
-            cpe.lldb_extensions = {
-                "combined_output": this_output,
-                "command": shellCommand
-            }
-            raise cpe
-        output = output + this_output.decode("utf-8", errors='ignore')
-    return output
-
-
 def getsource_if_available(obj):
     """
     Return the text of the source code for an object if available.  Otherwise,
@@ -1334,11 +1281,10 @@
             Supports: llvm, clang.
         """
         compiler = self.getCompilerBinary()
-        version_output = system([[compiler, "--version"]])
-        for line in version_output.split(os.linesep):
-            m = re.search('version ([0-9.]+)', line)
-            if m:
-                return m.group(1)
+        version_output = check_output([compiler, "--version"], errors="replace")
+        m = re.search('version ([0-9.]+)', version_output)
+        if m:
+            return m.group(1)
         return 'unknown'
 
     def getDwarfVersion(self):
@@ -1465,10 +1411,22 @@
         testname = self.getBuildDirBasename()
 
         module = builder_module()
-        if not module.build(debug_info, architecture, compiler, dictionary,
-                testdir, testname):
+        command = builder_module().getBuildCommand(debug_info, architecture,
+                compiler, dictionary, testdir, testname)
+        if command is None:
             raise Exception("Don't know how to build binary")
 
+        self.runBuildCommand(command)
+
+    def runBuildCommand(self, command):
+        self.trace(shlex.join(command))
+        try:
+            output = check_output(command, stderr=STDOUT, errors="replace")
+        except CalledProcessError as cpe:
+            raise build_exception.BuildError(cpe)
+        self.trace(output)
+
+
     # ==================================================
     # Build methods supported through a plugin interface
     # ==================================================
@@ -1615,7 +1573,7 @@
         if not yaml2obj_bin:
             self.assertTrue(False, "No valid yaml2obj executable specified")
         command = [yaml2obj_bin, "-o=%s" % obj_path, yaml_path]
-        system([command])
+        self.runBuildCommand(command)
 
     def getBuildFlags(
             self,
Index: lldb/packages/Python/lldbsuite/test/builders/builder.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/builders/builder.py
+++ lldb/packages/Python/lldbsuite/test/builders/builder.py
@@ -78,15 +78,6 @@
 
         return cmdline
 
-    def runBuildCommands(self, commands):
-        try:
-            lldbtest.system(commands)
-        except subprocess.CalledProcessError as called_process_error:
-            # Convert to a build-specific error.
-            # We don't do that in lldbtest.system() since that
-            # is more general purpose.
-            raise build_exception.BuildError(called_process_error)
-
     def getArchSpec(self, architecture):
         """
         Helper function to return the key-value string to specify the architecture
@@ -136,11 +127,11 @@
             return ["MAKE_DSYM=NO", "MAKE_GMODULES=YES"]
         return None
 
-    def build(self, debug_info, architecture=None, compiler=None,
+    def getBuildCommand(self, debug_info, architecture=None, compiler=None,
             dictionary=None, testdir=None, testname=None):
         debug_info_args = self._getDebugInfoArgs(debug_info)
         if debug_info_args is None:
-            return False
+            return None
 
         command_parts = [
             self.getMake(testdir, testname), debug_info_args, ["all"],
@@ -150,8 +141,7 @@
             self.getCmdLine(dictionary)]
         command = list(itertools.chain(*command_parts))
 
-        self.runBuildCommands([command])
-        return True
+        return command
 
     def cleanup(self, dictionary=None):
         """Perform a platform-specific cleanup after the test."""
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to