Please use GitHub pull requests for new patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
utils/lit/lit/TestRunner.py
Show First 20 Lines • Show All 666 Lines • ▼ Show 20 Lines | def processLine(ln): | ||||
ln = re.sub(a, b, ln) | ln = re.sub(a, b, ln) | ||||
# Strip the trailing newline and any extra whitespace. | # Strip the trailing newline and any extra whitespace. | ||||
return ln.strip() | return ln.strip() | ||||
# Note Python 3 map() gives an iterator rather than a list so explicitly | # Note Python 3 map() gives an iterator rather than a list so explicitly | ||||
# convert to list before returning. | # convert to list before returning. | ||||
return list(map(processLine, script)) | return list(map(processLine, script)) | ||||
def parseIntegratedTestScript(test, require_script=True): | def parseIntegratedTestScript(test, require_script=True, xFailRequirePR=False, bugTrackerRegex=None): | ||||
"""parseIntegratedTestScript - Scan an LLVM/Clang style integrated test | """parseIntegratedTestScript - Scan an LLVM/Clang style integrated test | ||||
script and extract the lines to 'RUN' as well as 'XFAIL' and 'REQUIRES' | script and extract the lines to 'RUN' as well as 'XFAIL' and 'REQUIRES' | ||||
and 'UNSUPPORTED' information. If 'require_script' is False an empty script | and 'UNSUPPORTED' information. If 'require_script' is False an empty script | ||||
may be returned. This can be used for test formats where the actual script | may be returned. This can be used for test formats where the actual script | ||||
is optional or ignored. | is optional or ignored. | ||||
""" | """ | ||||
# Collect the test lines from the script. | # Collect the test lines from the script. | ||||
sourcepath = test.getSourcePath() | sourcepath = test.getSourcePath() | ||||
Show All 19 Lines | for line_number, command_type, ln in \ | ||||
ln = re.sub('%\(line *([\+-]) *(\d+)\)', replace_line_number, ln) | ln = re.sub('%\(line *([\+-]) *(\d+)\)', replace_line_number, ln) | ||||
# Collapse lines with trailing '\\'. | # Collapse lines with trailing '\\'. | ||||
if script and script[-1][-1] == '\\': | if script and script[-1][-1] == '\\': | ||||
script[-1] = script[-1][:-1] + ln | script[-1] = script[-1][:-1] + ln | ||||
else: | else: | ||||
script.append(ln) | script.append(ln) | ||||
elif command_type == 'XFAIL': | elif command_type == 'XFAIL': | ||||
test.xfails.extend([s.strip() for s in ln.split(',')]) | xfail_prs = [s.strip() for s in ln.split(',') if bugTrackerRegex.match(s.strip())] | ||||
if len(xfail_prs) > 1: | |||||
raise ValueError("XFAIL command cannot have more than one PR, " | |||||
"use multiple xfail commands.") | |||||
xfail_pr = None | |||||
if(len(xfail_prs) > 0): | |||||
xfail_pr = xfail_prs[0] | |||||
xfail_features = [s.strip() for s in ln.split(',') if not bugTrackerRegex.match(s.strip())] | |||||
for feature in xfail_features: | |||||
test.xfails[feature] = xfail_pr | |||||
elif command_type == 'REQUIRES': | elif command_type == 'REQUIRES': | ||||
requires.extend([s.strip() for s in ln.split(',')]) | requires.extend([s.strip() for s in ln.split(',')]) | ||||
elif command_type == 'REQUIRES-ANY': | elif command_type == 'REQUIRES-ANY': | ||||
requires_any.extend([s.strip() for s in ln.split(',')]) | requires_any.extend([s.strip() for s in ln.split(',')]) | ||||
elif command_type == 'UNSUPPORTED': | elif command_type == 'UNSUPPORTED': | ||||
unsupported.extend([s.strip() for s in ln.split(',')]) | unsupported.extend([s.strip() for s in ln.split(',')]) | ||||
elif command_type == 'END': | elif command_type == 'END': | ||||
# END commands are only honored if the rest of the line is empty. | # END commands are only honored if the rest of the line is empty. | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | if test.config.limit_to_features: | ||||
# Check that we have one of the limit_to_features features in requires. | # Check that we have one of the limit_to_features features in requires. | ||||
limit_to_features_tests = [f for f in test.config.limit_to_features | limit_to_features_tests = [f for f in test.config.limit_to_features | ||||
if f in requires] | if f in requires] | ||||
if not limit_to_features_tests: | if not limit_to_features_tests: | ||||
msg = ', '.join(test.config.limit_to_features) | msg = ', '.join(test.config.limit_to_features) | ||||
return lit.Test.Result(Test.UNSUPPORTED, | return lit.Test.Result(Test.UNSUPPORTED, | ||||
"Test requires one of the limit_to_features features %s" % msg) | "Test requires one of the limit_to_features features %s" % msg) | ||||
if xFailRequirePR: | |||||
for feature, pr in test.xfails.iteritems(): | |||||
if pr is None: | |||||
return lit.Test.Result(Test.UNXFAIL, "XFAIL command missing PR") | |||||
return script | return script | ||||
def _runShTest(test, litConfig, useExternalSh, script, tmpBase): | def _runShTest(test, litConfig, useExternalSh, script, tmpBase): | ||||
# Create the output directory if it does not already exist. | # Create the output directory if it does not already exist. | ||||
lit.util.mkdir_p(os.path.dirname(tmpBase)) | lit.util.mkdir_p(os.path.dirname(tmpBase)) | ||||
execdir = os.path.dirname(test.getExecPath()) | execdir = os.path.dirname(test.getExecPath()) | ||||
if useExternalSh: | if useExternalSh: | ||||
Show All 29 Lines | def _runShTest(test, litConfig, useExternalSh, script, tmpBase): | ||||
return lit.Test.Result(status, output) | return lit.Test.Result(status, output) | ||||
def executeShTest(test, litConfig, useExternalSh, | def executeShTest(test, litConfig, useExternalSh, | ||||
extra_substitutions=[]): | extra_substitutions=[]): | ||||
if test.config.unsupported: | if test.config.unsupported: | ||||
return (Test.UNSUPPORTED, 'Test is unsupported') | return (Test.UNSUPPORTED, 'Test is unsupported') | ||||
script = parseIntegratedTestScript(test) | script = parseIntegratedTestScript(test, | ||||
xFailRequirePR=litConfig.xFailRequirePR, | |||||
bugTrackerRegex=litConfig.bugTrackerRegex) | |||||
MatzeB: You should use test.config.xFailRequirePR, test.config.bugTrackerRegex after adding some… | |||||
if isinstance(script, lit.Test.Result): | if isinstance(script, lit.Test.Result): | ||||
return script | return script | ||||
if litConfig.noExecute: | if litConfig.noExecute: | ||||
return lit.Test.Result(Test.PASS) | return lit.Test.Result(Test.PASS) | ||||
tmpDir, tmpBase = getTempPaths(test) | tmpDir, tmpBase = getTempPaths(test) | ||||
substitutions = list(extra_substitutions) | substitutions = list(extra_substitutions) | ||||
substitutions += getDefaultSubstitutions(test, tmpDir, tmpBase, | substitutions += getDefaultSubstitutions(test, tmpDir, tmpBase, | ||||
Show All 16 Lines |
You should use test.config.xFailRequirePR, test.config.bugTrackerRegex after adding some default values to TestingConfig.py. That way these values can be specified in lit.cfg and lit.site.cfg rather than the lit commandline. That will ensure nobody forgets to use those flags and also allows to run test from two testsuites with different bugtrackers in a single lit run.