Index: tools/testrunner/local/statusfile.py |
diff --git a/tools/testrunner/local/statusfile.py b/tools/testrunner/local/statusfile.py |
index 8464ef22414448e72e59da586a5162485ba8f987..d9f73ac12a6d93ac2e196fcc8a29325cd6b4cf51 100644 |
--- a/tools/testrunner/local/statusfile.py |
+++ b/tools/testrunner/local/statusfile.py |
@@ -26,6 +26,9 @@ |
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
import os |
+import re |
+ |
+from variants import ALL_VARIANTS |
# These outcomes can occur in a TestCase's outcomes list: |
SKIP = "SKIP" |
@@ -63,6 +66,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 +123,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 +159,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) |
@@ -155,24 +199,48 @@ def ReadContent(path): |
def ReadStatusFile(path, variables): |
contents = ReadContent(path) |
- rules = {} |
- wildcards = {} |
+ # 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[""] = {} |
+ |
variables.update(VARIABLES) |
for section in contents: |
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) |
+ 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 rules, 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) |
root_prefix = os.path.basename(os.path.dirname(path)) + "/" |