| Index: tools/testrunner/local/statusfile.py
|
| diff --git a/tools/testrunner/local/statusfile.py b/tools/testrunner/local/statusfile.py
|
| index 8464ef22414448e72e59da586a5162485ba8f987..877652923d0a80ba06ff0739f87f57d6c00be133 100644
|
| --- a/tools/testrunner/local/statusfile.py
|
| +++ b/tools/testrunner/local/statusfile.py
|
| @@ -26,6 +26,10 @@
|
| # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
| import os
|
| +import re
|
| +
|
| +from variants import ALL_VARIANTS
|
| +from utils import Freeze
|
|
|
| # These outcomes can occur in a TestCase's outcomes list:
|
| SKIP = "SKIP"
|
| @@ -63,6 +67,10 @@ for var in ["debug", "release", "big", "little",
|
| "windows", "linux", "aix"]:
|
| VARIABLES[var] = var
|
|
|
| +# Allow using variants as keywords.
|
| +for var in ALL_VARIANTS:
|
| + VARIABLES[var] = var
|
| +
|
|
|
| def DoSkip(outcomes):
|
| return SKIP in outcomes
|
| @@ -116,6 +124,34 @@ def _JoinsPassAndFail(outcomes1, outcomes2):
|
| FAIL in outcomes2
|
| )
|
|
|
| +VARIANT_EXPRESSION = object()
|
| +
|
| +def _EvalExpression(exp, variables):
|
| + try:
|
| + return eval(exp, variables)
|
| + except NameError as e:
|
| + identifier = re.match("name '(.*)' is not defined", e.message).group(1)
|
| + assert identifier == "variant", "Unknown identifier: %s" % identifier
|
| + return VARIANT_EXPRESSION
|
| +
|
| +
|
| +def _EvalVariantExpression(section, rules, wildcards, variant, variables):
|
| + variables_with_variant = {}
|
| + variables_with_variant.update(variables)
|
| + variables_with_variant["variant"] = variant
|
| + result = _EvalExpression(section[0], variables_with_variant)
|
| + assert result != VARIANT_EXPRESSION
|
| + if result is True:
|
| + _ReadSection(
|
| + section[1],
|
| + rules[variant],
|
| + wildcards[variant],
|
| + variables_with_variant,
|
| + )
|
| + else:
|
| + assert result is False, "Make sure expressions evaluate to boolean values"
|
| +
|
| +
|
| def _ParseOutcomeList(rule, outcomes, target_dict, variables):
|
| result = set([])
|
| if type(outcomes) == str:
|
| @@ -124,7 +160,16 @@ def _ParseOutcomeList(rule, outcomes, target_dict, variables):
|
| if type(item) == str:
|
| _AddOutcome(result, item)
|
| elif type(item) == list:
|
| - if not eval(item[0], variables): continue
|
| + exp = _EvalExpression(item[0], variables)
|
| + assert exp != VARIANT_EXPRESSION, (
|
| + "Nested variant expressions are not supported")
|
| + if exp is False:
|
| + continue
|
| +
|
| + # Ensure nobody uses an identifier by mistake, like "default",
|
| + # which would evaluate to true here otherwise.
|
| + assert exp is True, "Make sure expressions evaluate to boolean values"
|
| +
|
| for outcome in item[1:]:
|
| assert type(outcome) == str
|
| _AddOutcome(result, outcome)
|
| @@ -146,35 +191,57 @@ def _ParseOutcomeList(rule, outcomes, target_dict, variables):
|
| target_dict[rule] = result
|
|
|
|
|
| -def ReadContent(path):
|
| - with open(path) as f:
|
| - global KEYWORDS
|
| - return eval(f.read(), KEYWORDS)
|
| +def ReadContent(content):
|
| + global KEYWORDS
|
| + return eval(content, KEYWORDS)
|
|
|
|
|
| -def ReadStatusFile(path, variables):
|
| - contents = ReadContent(path)
|
| +def ReadStatusFile(content, variables):
|
| + # Empty defaults for rules and wildcards. Variant-independent
|
| + # rules are mapped by "", others by the variant name.
|
| + rules = {variant: {} for variant in ALL_VARIANTS}
|
| + rules[""] = {}
|
| + wildcards = {variant: {} for variant in ALL_VARIANTS}
|
| + wildcards[""] = {}
|
|
|
| - rules = {}
|
| - wildcards = {}
|
| variables.update(VARIABLES)
|
| - for section in contents:
|
| + for section in ReadContent(content):
|
| assert type(section) == list
|
| assert len(section) == 2
|
| - if not eval(section[0], variables): continue
|
| - section = section[1]
|
| - assert type(section) == dict
|
| - for rule in section:
|
| - assert type(rule) == str
|
| - if rule[-1] == '*':
|
| - _ParseOutcomeList(rule, section[rule], wildcards, variables)
|
| - else:
|
| - _ParseOutcomeList(rule, section[rule], rules, variables)
|
| - return rules, wildcards
|
| + exp = _EvalExpression(section[0], variables)
|
| + if exp is False:
|
| + # The expression is variant-independent and evaluates to False.
|
| + continue
|
| + elif exp == VARIANT_EXPRESSION:
|
| + # If the expression contains one or more "variant" keywords, we evaluate
|
| + # it for all possible variants and create rules for those that apply.
|
| + for variant in ALL_VARIANTS:
|
| + _EvalVariantExpression(section, rules, wildcards, variant, variables)
|
| + else:
|
| + # The expression is variant-independent and evaluates to True.
|
| + assert exp is True, "Make sure expressions evaluate to boolean values"
|
| + _ReadSection(
|
| + section[1],
|
| + rules[""],
|
| + wildcards[""],
|
| + variables,
|
| + )
|
| + return Freeze(rules), Freeze(wildcards)
|
| +
|
| +
|
| +def _ReadSection(section, rules, wildcards, variables):
|
| + assert type(section) == dict
|
| + for rule in section:
|
| + assert type(rule) == str
|
| + if rule[-1] == '*':
|
| + _ParseOutcomeList(rule, section[rule], wildcards, variables)
|
| + else:
|
| + _ParseOutcomeList(rule, section[rule], rules, variables)
|
|
|
|
|
| def PresubmitCheck(path):
|
| - contents = ReadContent(path)
|
| + with open(path) as f:
|
| + contents = ReadContent(f.read())
|
| root_prefix = os.path.basename(os.path.dirname(path)) + "/"
|
| status = {"success": True}
|
| def _assert(check, message): # Like "assert", but doesn't throw.
|
|
|