Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions compiler-rt/test/lit.common.cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,16 +195,14 @@ def push_dynamic_library_lookup_path(config, new_path):
# Normalize the path for comparison
if test_cc_resource_dir is not None:
test_cc_resource_dir = os.path.realpath(test_cc_resource_dir)
if lit_config.debug:
lit_config.note(f"Resource dir for {config.clang} is {test_cc_resource_dir}")
lit_config.dbg(f"Resource dir for {config.clang} is {test_cc_resource_dir}")
local_build_resource_dir = os.path.realpath(config.compiler_rt_output_dir)
if test_cc_resource_dir != local_build_resource_dir and config.test_standalone_build_libs:
if config.compiler_id == "Clang":
if lit_config.debug:
lit_config.note(
f"Overriding test compiler resource dir to use "
f'libraries in "{config.compiler_rt_libdir}"'
)
lit_config.dbg(
f"Overriding test compiler resource dir to use "
f'libraries in "{config.compiler_rt_libdir}"'
)
# Ensure that we use the just-built static libraries when linking by
# overriding the Clang resource directory. Additionally, we want to use
# the builtin headers shipped with clang (e.g. stdint.h), so we
Expand Down
2 changes: 1 addition & 1 deletion libcxx/test/selftest/dsl/dsl.sh.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def setUp(self):
self.litConfig = lit.LitConfig.LitConfig(
progname="lit",
path=[],
quiet=False,
diagnostic_level="note",
useValgrind=False,
valgrindLeakCheck=False,
valgrindArgs=[],
Expand Down
21 changes: 10 additions & 11 deletions libcxx/utils/libcxx/test/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ def _appendToSubstitution(substitutions, key, value):

def configure(parameters, features, config, lit_config):
note = lambda s: lit_config.note("({}) {}".format(config.name, s))
debug = lambda s: lit_config.dbg("({}) {}".format(config.name, s))
config.environment = dict(os.environ)

# Apply the actions supplied by parameters to the configuration first, since
Expand All @@ -31,25 +32,23 @@ def configure(parameters, features, config, lit_config):
actions = param.getActions(config, lit_config.params)
for action in actions:
action.applyTo(config)
if lit_config.debug:
note(
"Applied '{}' as a result of parameter '{}'".format(
action.pretty(config, lit_config.params),
param.pretty(config, lit_config.params),
)
debug(
"Applied '{}' as a result of parameter '{}'".format(
action.pretty(config, lit_config.params),
param.pretty(config, lit_config.params),
)
)

# Then, apply the automatically-detected features.
for feature in features:
actions = feature.getActions(config)
for action in actions:
action.applyTo(config)
if lit_config.debug:
note(
"Applied '{}' as a result of implicitly detected feature '{}'".format(
action.pretty(config, lit_config.params), feature.pretty(config)
)
debug(
"Applied '{}' as a result of implicitly detected feature '{}'".format(
action.pretty(config, lit_config.params), feature.pretty(config)
)
)

# Print the basic substitutions
for sub in ("%{cxx}", "%{flags}", "%{compile_flags}", "%{link_flags}", "%{benchmark_flags}", "%{exec}"):
Expand Down
2 changes: 1 addition & 1 deletion libcxx/utils/libcxx/test/dsl.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def _executeWithFakeConfig(test, commands):
litConfig = lit.LitConfig.LitConfig(
progname="lit",
path=[],
quiet=False,
diagnostic_level="note",
useValgrind=False,
valgrindLeakCheck=False,
valgrindArgs=[],
Expand Down
48 changes: 40 additions & 8 deletions llvm/utils/lit/lit/LitConfig.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import absolute_import
import inspect
import os
import enum
import platform
import sys

Expand All @@ -25,7 +26,7 @@ def __init__(
self,
progname,
path,
quiet,
diagnostic_level,
useValgrind,
valgrindLeakCheck,
valgrindArgs,
Expand All @@ -46,7 +47,7 @@ def __init__(
self.progname = progname
# The items to add to the PATH environment variable.
self.path = [str(p) for p in path]
self.quiet = bool(quiet)
self.diagnostic_level = diagnostic_level
self.useValgrind = bool(useValgrind)
self.valgrindLeakCheck = bool(valgrindLeakCheck)
self.valgrindUserArgs = list(valgrindArgs)
Expand Down Expand Up @@ -155,8 +156,7 @@ def per_test_coverage(self, value):
def load_config(self, config, path):
"""load_config(config, path) - Load a config object from an alternate
path."""
if self.debug:
self.note("load_config from %r" % path)
self.dbg("load_config from %r" % path)
config.load_from_path(path, self)
return config

Expand Down Expand Up @@ -209,6 +209,8 @@ def getToolsPath(self, dir, paths, tools):
return dir

def _write_message(self, kind, message):
if not self.diagnostic_level_enabled(kind):
return
# Get the file/line where this message was generated.
f = inspect.currentframe()
# Step out of _write_message, and then out of wrapper.
Expand All @@ -234,13 +236,21 @@ def substitute(self, string):
"unable to find %r parameter, use '--param=%s=VALUE'" % (key, key)
)

def diagnostic_level_enabled(self, kind):
if kind == "debug":
return self.debug
return DiagnosticLevel.create(self.diagnostic_level) >= DiagnosticLevel.create(
kind
)

def dbg(self, message):
self._write_message("debug", message)

def note(self, message):
if not self.quiet:
self._write_message("note", message)
self._write_message("note", message)

def warning(self, message):
if not self.quiet:
self._write_message("warning", message)
self._write_message("warning", message)
self.numWarnings += 1

def error(self, message):
Expand All @@ -250,3 +260,25 @@ def error(self, message):
def fatal(self, message):
self._write_message("fatal", message)
sys.exit(2)


@enum.unique
class DiagnosticLevel(enum.IntEnum):
FATAL = 0
ERROR = 1
WARNING = 2
NOTE = 3

@classmethod
def create(cls, value):
if value == "fatal":
return cls.FATAL
if value == "error":
return cls.ERROR
if value == "warning":
return cls.WARNING
if value == "note":
return cls.NOTE
raise ValueError(
f"invalid diagnostic level {repr(value)} of type {type(value)}"
)
2 changes: 1 addition & 1 deletion llvm/utils/lit/lit/LitTestCase.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def load_test_suite(inputs):
lit_config = lit.LitConfig.LitConfig(
progname="lit",
path=[],
quiet=False,
diagnostic_level="note",
useValgrind=False,
valgrindLeakCheck=False,
valgrindArgs=[],
Expand Down
3 changes: 1 addition & 2 deletions llvm/utils/lit/lit/TestingConfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,7 @@ def load_from_path(self, path, litConfig):
cfg_globals["__file__"] = path
try:
exec(compile(data, path, "exec"), cfg_globals, None)
if litConfig.debug:
litConfig.note("... loaded config %r" % path)
litConfig.dbg("... loaded config %r" % path)
except SystemExit:
e = sys.exc_info()[1]
# We allow normal system exit inside a config file to just
Expand Down
153 changes: 137 additions & 16 deletions llvm/utils/lit/lit/cl_arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,59 @@ class TestOrder(enum.Enum):
SMART = "smart"


@enum.unique
class TestOutputLevel(enum.IntEnum):
OFF = 0
FAILED = 1
ALL = 2

@classmethod
def create(cls, value):
if value == "off":
return cls.OFF
if value == "failed":
return cls.FAILED
if value == "all":
return cls.ALL
raise ValueError(f"invalid output level {repr(value)} of type {type(value)}")


class TestOutputAction(argparse.Action):
def __init__(self, option_strings, dest, **kwargs):
super().__init__(option_strings, dest, nargs=None, **kwargs)

def __call__(self, parser, namespace, value, option_string=None):
TestOutputAction.setOutputLevel(namespace, self.dest, value)

@classmethod
def setOutputLevel(cls, namespace, dest, value):
setattr(namespace, dest, value)
if dest == "test_output" and TestOutputLevel.create(
namespace.print_result_after
) < TestOutputLevel.create(value):
setattr(namespace, "print_result_after", value)
elif dest == "print_result_after" and TestOutputLevel.create(
namespace.test_output
) > TestOutputLevel.create(value):
setattr(namespace, "test_output", value)


class AliasAction(argparse.Action):
def __init__(self, option_strings, dest, nargs=None, **kwargs):
self.expansion = kwargs.pop("alias", None)
if not self.expansion:
raise ValueError("no aliases expansion provided")
super().__init__(option_strings, dest, nargs=0, **kwargs)

def __call__(self, parser, namespace, value, option_string=None):
for e in self.expansion:
if callable(e):
e(namespace)
else:
dest, val = e
setattr(namespace, dest, val)


def parse_args():
parser = argparse.ArgumentParser(prog="lit", fromfile_prefix_chars="@")
parser.add_argument(
Expand Down Expand Up @@ -55,41 +108,103 @@ def parse_args():
)

format_group = parser.add_argument_group("Output Format")
# FIXME: I find these names very confusing, although I like the
# functionality.
format_group.add_argument(
"-q", "--quiet", help="Suppress no error output", action="store_true"
"--test-output",
help="Control whether the executed commands and their outputs are printed after each test has executed (default off). "
"If --print-result-after is set lower than the level given to --test-output, --print-result-after is raised to match.",
choices=["off", "failed", "all"],
default="off",
action=TestOutputAction,
)
format_group.add_argument(
"--print-result-after",
help="Control which the executed test names and results are printed after each test has executed (default all). "
"If --test-output is set higher than the level given to --print-result-after, --test-output is lowered to match.",
choices=["off", "failed", "all"],
default="all",
action=TestOutputAction,
)
format_group.add_argument(
"--diagnostic-level",
help="Control how verbose lit diagnostics should be (default note)",
choices=["error", "warning", "note"],
default="note",
)
format_group.add_argument(
"--terse-summary",
help="Print the elapsed time and the number of passed tests after all tests have finished (default on)",
action="store_true",
dest="terse_summary",
)
format_group.add_argument(
"--no-terse-summary",
help="Don't show the elapsed time after all tests have finished, and only show the number of failed tests.",
action="store_false",
dest="terse_summary",
)
parser.set_defaults(terse_summary=False)
format_group.add_argument(
"-q",
"--quiet",
help="Alias for '--diagnostic-level=error --test-output=off --terse-summary'",
action=AliasAction,
alias=[
lambda namespace: TestOutputAction.setOutputLevel(
namespace, "print_result_after", "failed"
),
lambda namespace: TestOutputAction.setOutputLevel(
namespace, "test_output", "off"
),
("diagnostic_level", "error"),
("terse_summary", True),
],
)
format_group.add_argument(
"-s",
"--succinct",
help="Reduce amount of output."
" Additionally, show a progress bar,"
" unless --no-progress-bar is specified.",
action="store_true",
help="Alias for '--progress-bar --print-result-after=failed'",
action=AliasAction,
alias=[
("useProgressBar", True),
lambda namespace: TestOutputAction.setOutputLevel(
namespace, "print_result_after", "failed"
),
],
)
format_group.add_argument(
"-v",
"--verbose",
dest="showOutput",
help="For failed tests, show all output. For example, each command is"
" printed before it is executed, so the last printed command is the one"
" that failed.",
action="store_true",
" that failed. Alias for '--test-output=failed'",
action=AliasAction,
alias=[
lambda namespace: TestOutputAction.setOutputLevel(
namespace, "test_output", "failed"
),
],
)
format_group.add_argument(
"-vv",
"--echo-all-commands",
dest="showOutput",
help="Deprecated alias for -v.",
action="store_true",
action=AliasAction,
alias=[
lambda namespace: TestOutputAction.setOutputLevel(
namespace, "test_output", "failed"
),
],
)
format_group.add_argument(
"-a",
"--show-all",
dest="showAllOutput",
help="Enable -v, but for all tests not just failed tests.",
action="store_true",
help="Enable -v, but for all tests not just failed tests. Alias for '--test-output=all'",
action=AliasAction,
alias=[
lambda namespace: TestOutputAction.setOutputLevel(
namespace, "test_output", "all"
),
],
)
format_group.add_argument(
"-r",
Expand All @@ -105,10 +220,16 @@ def parse_args():
help="Write test results to the provided path",
metavar="PATH",
)
format_group.add_argument(
"--progress-bar",
dest="useProgressBar",
help="Show curses based progress bar",
action="store_true",
)
format_group.add_argument(
"--no-progress-bar",
dest="useProgressBar",
help="Do not use curses based progress bar",
help="Do not use curses based progress bar (default)",
action="store_false",
)

Expand Down
Loading
Loading