forked from OSchip/llvm-project
Cleaned up results formatter options hand-off.
* --results-formatter-options renamed to --results-formatter-option, with short version of -O * Multiple --results-formatter-option=OPTION can be specified. The comma-separating mechanism has been removed. * XunitFormatter options modified: -n and -r are now short forms of --ignore-skip-name and --ignore-skip-reason. Those long option names were tweaked lightly. They also can be specified multiple times on the command line. The comma-separating, multiple-pattern- per-option mechanism has been removed. One can now specify: dotest.py --results-file stdout -O-ndsym -O-nlldb-mi for example, to ignore reporting skips for dsym-related or lldb-mi-related tests in the xUnit report. llvm-svn: 248384
This commit is contained in:
parent
0d427986f5
commit
ea73624e5f
|
@ -1068,43 +1068,87 @@ def get_test_runner_strategies(num_threads):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def _remove_option(args, option_name, removal_count):
|
def _remove_option(
|
||||||
|
args, long_option_name, short_option_name, takes_arg):
|
||||||
"""Removes option and related option arguments from args array.
|
"""Removes option and related option arguments from args array.
|
||||||
|
|
||||||
|
This method removes all short/long options that match the given
|
||||||
|
arguments.
|
||||||
|
|
||||||
@param args the array of command line arguments (in/out)
|
@param args the array of command line arguments (in/out)
|
||||||
@param option_name the full command line representation of the
|
|
||||||
option that will be removed (including '--' or '-').
|
@param long_option_name the full command line representation of the
|
||||||
@param the count of elements to remove. A value of 1 will remove
|
long-form option that will be removed (including '--').
|
||||||
just the found option, while 2 will remove the option and its first
|
|
||||||
argument.
|
@param short_option_name the short version of the command line option
|
||||||
|
that will be removed (including '-').
|
||||||
|
|
||||||
|
@param takes_arg True if the option takes an argument.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
if long_option_name is not None:
|
||||||
index = args.index(option_name)
|
regex_string = "^" + long_option_name + "="
|
||||||
# Handle the exact match case.
|
long_regex = re.compile(regex_string)
|
||||||
del args[index:index+removal_count]
|
if short_option_name is not None:
|
||||||
return
|
# Short options we only match the -X and assume
|
||||||
except ValueError:
|
# any arg is one command line argument jammed together.
|
||||||
# Thanks to argparse not handling options with known arguments
|
# i.e. -O--abc=1 is a single argument in the args list.
|
||||||
# like other options parsing libraries (see
|
# We don't handle -O --abc=1, as argparse doesn't handle
|
||||||
# https://bugs.python.org/issue9334), we need to support the
|
# it, either.
|
||||||
# --results-formatter-options={second-level-arguments} (note
|
regex_string = "^" + short_option_name
|
||||||
# the equal sign to fool the first-level arguments parser into
|
short_regex = re.compile(regex_string)
|
||||||
# not treating the second-level arguments as first-level
|
|
||||||
# options). We're certainly at risk of getting this wrong
|
def remove_long_internal():
|
||||||
# since now we're forced into the business of trying to figure
|
"""Removes one matching long option from args.
|
||||||
# out what is an argument (although I think this
|
@returns True if one was found and removed; False otherwise.
|
||||||
# implementation will suffice).
|
"""
|
||||||
regex_string = "^" + option_name + "="
|
try:
|
||||||
regex = re.compile(regex_string)
|
index = args.index(long_option_name)
|
||||||
|
# Handle the exact match case.
|
||||||
|
if takes_arg:
|
||||||
|
removal_count = 2
|
||||||
|
else:
|
||||||
|
removal_count = 1
|
||||||
|
del args[index:index+removal_count]
|
||||||
|
return True
|
||||||
|
except ValueError:
|
||||||
|
# Thanks to argparse not handling options with known arguments
|
||||||
|
# like other options parsing libraries (see
|
||||||
|
# https://bugs.python.org/issue9334), we need to support the
|
||||||
|
# --results-formatter-options={second-level-arguments} (note
|
||||||
|
# the equal sign to fool the first-level arguments parser into
|
||||||
|
# not treating the second-level arguments as first-level
|
||||||
|
# options). We're certainly at risk of getting this wrong
|
||||||
|
# since now we're forced into the business of trying to figure
|
||||||
|
# out what is an argument (although I think this
|
||||||
|
# implementation will suffice).
|
||||||
|
for index in range(len(args)):
|
||||||
|
match = long_regex.search(args[index])
|
||||||
|
if match:
|
||||||
|
del args[index]
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def remove_short_internal():
|
||||||
|
"""Removes one matching short option from args.
|
||||||
|
@returns True if one was found and removed; False otherwise.
|
||||||
|
"""
|
||||||
for index in range(len(args)):
|
for index in range(len(args)):
|
||||||
match = regex.match(args[index])
|
match = short_regex.search(args[index])
|
||||||
if match:
|
if match:
|
||||||
del args[index]
|
del args[index]
|
||||||
return
|
return True
|
||||||
print "failed to find regex '{}'".format(regex_string)
|
return False
|
||||||
|
|
||||||
# We didn't find the option but we should have.
|
removal_count = 0
|
||||||
raise Exception("failed to find option '{}' in args '{}'".format(
|
while long_option_name is not None and remove_long_internal():
|
||||||
option_name, args))
|
removal_count += 1
|
||||||
|
while short_option_name is not None and remove_short_internal():
|
||||||
|
removal_count += 1
|
||||||
|
if removal_count == 0:
|
||||||
|
raise Exception(
|
||||||
|
"failed to find at least one of '{}', '{}' in options".format(
|
||||||
|
long_option_name, short_option_name))
|
||||||
|
|
||||||
|
|
||||||
def adjust_inferior_options(dotest_argv):
|
def adjust_inferior_options(dotest_argv):
|
||||||
|
@ -1132,17 +1176,18 @@ def adjust_inferior_options(dotest_argv):
|
||||||
# we'll have inferiors spawn with the --results-port option and
|
# we'll have inferiors spawn with the --results-port option and
|
||||||
# strip the original test runner options.
|
# strip the original test runner options.
|
||||||
if dotest_options.results_file is not None:
|
if dotest_options.results_file is not None:
|
||||||
_remove_option(dotest_argv, "--results-file", 2)
|
_remove_option(dotest_argv, "--results-file", None, True)
|
||||||
if dotest_options.results_port is not None:
|
if dotest_options.results_port is not None:
|
||||||
_remove_option(dotest_argv, "--results-port", 2)
|
_remove_option(dotest_argv, "--results-port", None, True)
|
||||||
if dotest_options.results_formatter is not None:
|
if dotest_options.results_formatter is not None:
|
||||||
_remove_option(dotest_argv, "--results-formatter", 2)
|
_remove_option(dotest_argv, "--results-formatter", None, True)
|
||||||
if dotest_options.results_formatter_options is not None:
|
if dotest_options.results_formatter_options is not None:
|
||||||
_remove_option(dotest_argv, "--results-formatter-options", 2)
|
_remove_option(dotest_argv, "--results-formatter-option", "-O",
|
||||||
|
True)
|
||||||
|
|
||||||
# Remove test runner name if present.
|
# Remove test runner name if present.
|
||||||
if dotest_options.test_runner_name is not None:
|
if dotest_options.test_runner_name is not None:
|
||||||
_remove_option(dotest_argv, "--test-runner-name", 2)
|
_remove_option(dotest_argv, "--test-runner-name", None, True)
|
||||||
|
|
||||||
|
|
||||||
def is_darwin_version_lower_than(target_version):
|
def is_darwin_version_lower_than(target_version):
|
||||||
|
|
|
@ -1000,12 +1000,10 @@ def setupTestResults():
|
||||||
# Handle formatter options for the results formatter class.
|
# Handle formatter options for the results formatter class.
|
||||||
formatter_arg_parser = clazz.arg_parser()
|
formatter_arg_parser = clazz.arg_parser()
|
||||||
if results_formatter_options and len(results_formatter_options) > 0:
|
if results_formatter_options and len(results_formatter_options) > 0:
|
||||||
import shlex
|
formatter_options = formatter_arg_parser.parse_args(
|
||||||
split_options = shlex.split(results_formatter_options)
|
results_formatter_options)
|
||||||
else:
|
else:
|
||||||
split_options = []
|
formatter_options = []
|
||||||
|
|
||||||
formatter_options = formatter_arg_parser.parse_args(split_options)
|
|
||||||
|
|
||||||
# Create the TestResultsFormatter given the processed options.
|
# Create the TestResultsFormatter given the processed options.
|
||||||
results_formatter_object = clazz(results_file_object, formatter_options)
|
results_formatter_object = clazz(results_file_object, formatter_options)
|
||||||
|
|
|
@ -172,11 +172,13 @@ def create_parser():
|
||||||
'test events into some kind of meaningful report, written to '
|
'test events into some kind of meaningful report, written to '
|
||||||
'the designated output results file-like object'))
|
'the designated output results file-like object'))
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
'--results-formatter-options',
|
'--results-formatter-option',
|
||||||
action='store',
|
'-O',
|
||||||
help=('Specify comma-separated options to pass to the formatter. '
|
action='append',
|
||||||
'Use --results-formatter-options="--option1[,--option2[,...]]" '
|
dest='results_formatter_options',
|
||||||
'syntax. Note the "=" is critical, and don\'t use whitespace.'))
|
help=('Specify an option to pass to the formatter. '
|
||||||
|
'Use --results-formatter-option="--option1=val1" '
|
||||||
|
'syntax. Note the "=" is critical, don\'t include whitespace.'))
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
'--event-add-entries',
|
'--event-add-entries',
|
||||||
action='store',
|
action='store',
|
||||||
|
|
|
@ -538,19 +538,25 @@ class XunitFormatter(ResultsFormatter):
|
||||||
help=('cause unknown test events to generate '
|
help=('cause unknown test events to generate '
|
||||||
'a python assert. Default is to ignore.'))
|
'a python assert. Default is to ignore.'))
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--ignore-skip-matching-name",
|
"--ignore-skip-name",
|
||||||
action="store",
|
"-n",
|
||||||
help=('one or more comma-separated python regex patterns, where '
|
metavar='PATTERN',
|
||||||
|
action="append",
|
||||||
|
dest='ignore_skip_name_patterns',
|
||||||
|
help=('a python regex pattern, where '
|
||||||
'any skipped test with a test method name where regex '
|
'any skipped test with a test method name where regex '
|
||||||
'matches (via search) will be ignored for xUnit test '
|
'matches (via search) will be ignored for xUnit test '
|
||||||
'result purposes.'))
|
'result purposes. Can be specified multiple times.'))
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--ignore-skip-matching-reason",
|
"--ignore-skip-reason",
|
||||||
action="store",
|
"-r",
|
||||||
help=('one or more comma-separated python regex patterns, where '
|
metavar='PATTERN',
|
||||||
|
action="append",
|
||||||
|
dest='ignore_skip_reason_patterns',
|
||||||
|
help=('a python regex pattern, where '
|
||||||
'any skipped test with a skip reason where the regex '
|
'any skipped test with a skip reason where the regex '
|
||||||
'matches (via search) will be ignored for xUnit test '
|
'matches (via search) will be ignored for xUnit test '
|
||||||
'result purposes.'))
|
'result purposes. Can be specified multiple times.'))
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--xpass", action="store", choices=results_mapping_choices,
|
"--xpass", action="store", choices=results_mapping_choices,
|
||||||
default=XunitFormatter.RM_FAILURE,
|
default=XunitFormatter.RM_FAILURE,
|
||||||
|
@ -564,7 +570,7 @@ class XunitFormatter(ResultsFormatter):
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _build_regex_list_from_option(option):
|
def _build_regex_list_from_patterns(patterns):
|
||||||
"""Builds a list of compiled regexes from option value.
|
"""Builds a list of compiled regexes from option value.
|
||||||
|
|
||||||
@param option string containing a comma-separated list of regex
|
@param option string containing a comma-separated list of regex
|
||||||
|
@ -574,8 +580,8 @@ class XunitFormatter(ResultsFormatter):
|
||||||
patterns provided.
|
patterns provided.
|
||||||
"""
|
"""
|
||||||
regex_list = []
|
regex_list = []
|
||||||
if option is not None and len(option) > 0:
|
if patterns is not None:
|
||||||
for pattern in option.split(","):
|
for pattern in patterns:
|
||||||
regex_list.append(re.compile(pattern))
|
regex_list.append(re.compile(pattern))
|
||||||
return regex_list
|
return regex_list
|
||||||
|
|
||||||
|
@ -591,11 +597,11 @@ class XunitFormatter(ResultsFormatter):
|
||||||
self.invalid_xml_re = XunitFormatter._build_illegal_xml_regex()
|
self.invalid_xml_re = XunitFormatter._build_illegal_xml_regex()
|
||||||
self.total_test_count = 0
|
self.total_test_count = 0
|
||||||
self.ignore_skip_name_regexes = (
|
self.ignore_skip_name_regexes = (
|
||||||
XunitFormatter._build_regex_list_from_option(
|
XunitFormatter._build_regex_list_from_patterns(
|
||||||
options.ignore_skip_matching_name))
|
options.ignore_skip_name_patterns))
|
||||||
self.ignore_skip_reason_regexes = (
|
self.ignore_skip_reason_regexes = (
|
||||||
XunitFormatter._build_regex_list_from_option(
|
XunitFormatter._build_regex_list_from_patterns(
|
||||||
options.ignore_skip_matching_reason))
|
options.ignore_skip_reason_patterns))
|
||||||
|
|
||||||
self.elements = {
|
self.elements = {
|
||||||
"successes": [],
|
"successes": [],
|
||||||
|
|
Loading…
Reference in New Issue