[Lldb-commits] [lldb] eee887e - [lldb/test] Print build commands in trace mode
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Fri Oct 29 02:33:55 PDT 2021
Author: Pavel Labath
Date: 2021-10-29T11:33:31+02:00
New Revision: eee887e03551685bc03657a61c2f36ff1b522919
URL: https://github.com/llvm/llvm-project/commit/eee887e03551685bc03657a61c2f36ff1b522919
DIFF: https://github.com/llvm/llvm-project/commit/eee887e03551685bc03657a61c2f36ff1b522919.diff
LOG: [lldb/test] Print build commands in trace mode
Running tests with -t prints all lldb commands being run. It makes sense
to print all the build commands as well.
Differential Revision: https://reviews.llvm.org/D112212
Added:
lldb/test/API/test_utils/base/Makefile
lldb/test/API/test_utils/base/TestBaseTest.py
lldb/test/API/test_utils/base/return0.cpp
Modified:
lldb/packages/Python/lldbsuite/test/builders/builder.py
lldb/packages/Python/lldbsuite/test/lldbtest.py
lldb/packages/Python/lldbsuite/test_event/build_exception.py
Removed:
################################################################################
diff --git a/lldb/packages/Python/lldbsuite/test/builders/builder.py b/lldb/packages/Python/lldbsuite/test/builders/builder.py
index 8b17b585ae6c8..98057066f3f3c 100644
--- a/lldb/packages/Python/lldbsuite/test/builders/builder.py
+++ b/lldb/packages/Python/lldbsuite/test/builders/builder.py
@@ -82,15 +82,6 @@ def setOrAppendVariable(k, v):
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
@@ -140,11 +131,11 @@ def _getDebugInfoArgs(self, debug_info):
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"],
@@ -154,8 +145,7 @@ def build(self, debug_info, architecture=None, compiler=None,
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."""
diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index d8940b996f8dc..92d7887e670ac 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/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.
@@ -470,61 +472,6 @@ def launch(self, executable, args, extra_env):
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,
@@ -1335,11 +1282,10 @@ def getCompilerVersion(self):
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):
@@ -1469,10 +1415,22 @@ def build(
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
# ==================================================
@@ -1619,7 +1577,7 @@ def yaml2obj(self, yaml_path, obj_path):
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,
diff --git a/lldb/packages/Python/lldbsuite/test_event/build_exception.py b/lldb/packages/Python/lldbsuite/test_event/build_exception.py
index e08b632eb9a91..e1924ad86cde5 100644
--- a/lldb/packages/Python/lldbsuite/test_event/build_exception.py
+++ b/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 @@ def __str__(self):
@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)
diff --git a/lldb/test/API/test_utils/base/Makefile b/lldb/test/API/test_utils/base/Makefile
new file mode 100644
index 0000000000000..22f1051530f87
--- /dev/null
+++ b/lldb/test/API/test_utils/base/Makefile
@@ -0,0 +1 @@
+include Makefile.rules
diff --git a/lldb/test/API/test_utils/base/TestBaseTest.py b/lldb/test/API/test_utils/base/TestBaseTest.py
new file mode 100644
index 0000000000000..4aceca7d5fb57
--- /dev/null
+++ b/lldb/test/API/test_utils/base/TestBaseTest.py
@@ -0,0 +1,35 @@
+"""
+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
+
+ # override the parent trace method
+ 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])
diff --git a/lldb/test/API/test_utils/base/return0.cpp b/lldb/test/API/test_utils/base/return0.cpp
new file mode 100644
index 0000000000000..76e8197013aab
--- /dev/null
+++ b/lldb/test/API/test_utils/base/return0.cpp
@@ -0,0 +1 @@
+int main() { return 0; }
More information about the lldb-commits
mailing list