1# Copyright 2012 the V8 project authors. All rights reserved. 2# Redistribution and use in source and binary forms, with or without 3# modification, are permitted provided that the following conditions are 4# met: 5# 6# * Redistributions of source code must retain the above copyright 7# notice, this list of conditions and the following disclaimer. 8# * Redistributions in binary form must reproduce the above 9# copyright notice, this list of conditions and the following 10# disclaimer in the documentation and/or other materials provided 11# with the distribution. 12# * Neither the name of Google Inc. nor the names of its 13# contributors may be used to endorse or promote products derived 14# from this software without specific prior written permission. 15# 16# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28import os 29 30# These outcomes can occur in a TestCase's outcomes list: 31SKIP = "SKIP" 32FAIL = "FAIL" 33PASS = "PASS" 34OKAY = "OKAY" 35TIMEOUT = "TIMEOUT" 36CRASH = "CRASH" 37SLOW = "SLOW" 38FLAKY = "FLAKY" 39FAST_VARIANTS = "FAST_VARIANTS" 40NO_VARIANTS = "NO_VARIANTS" 41# These are just for the status files and are mapped below in DEFS: 42FAIL_OK = "FAIL_OK" 43PASS_OR_FAIL = "PASS_OR_FAIL" 44FAIL_SLOPPY = "FAIL_SLOPPY" 45 46ALWAYS = "ALWAYS" 47 48KEYWORDS = {} 49for key in [SKIP, FAIL, PASS, OKAY, TIMEOUT, CRASH, SLOW, FLAKY, FAIL_OK, 50 FAST_VARIANTS, NO_VARIANTS, PASS_OR_FAIL, FAIL_SLOPPY, ALWAYS]: 51 KEYWORDS[key] = key 52 53DEFS = {FAIL_OK: [FAIL, OKAY], 54 PASS_OR_FAIL: [PASS, FAIL]} 55 56# Support arches, modes to be written as keywords instead of strings. 57VARIABLES = {ALWAYS: True} 58for var in ["debug", "release", "big", "little", 59 "android_arm", "android_arm64", "android_ia32", "android_x87", 60 "android_x64", "arm", "arm64", "ia32", "mips", "mipsel", "mips64", 61 "mips64el", "x64", "x87", "nacl_ia32", "nacl_x64", "ppc", "ppc64", 62 "macos", "windows", "linux", "aix"]: 63 VARIABLES[var] = var 64 65 66def DoSkip(outcomes): 67 return SKIP in outcomes 68 69 70def IsSlow(outcomes): 71 return SLOW in outcomes 72 73 74def OnlyStandardVariant(outcomes): 75 return NO_VARIANTS in outcomes 76 77 78def OnlyFastVariants(outcomes): 79 return FAST_VARIANTS in outcomes 80 81 82def IsFlaky(outcomes): 83 return FLAKY in outcomes 84 85 86def IsPassOrFail(outcomes): 87 return ((PASS in outcomes) and (FAIL in outcomes) and 88 (not CRASH in outcomes) and (not OKAY in outcomes)) 89 90 91def IsFailOk(outcomes): 92 return (FAIL in outcomes) and (OKAY in outcomes) 93 94 95def _AddOutcome(result, new): 96 global DEFS 97 if new in DEFS: 98 mapped = DEFS[new] 99 if type(mapped) == list: 100 for m in mapped: 101 _AddOutcome(result, m) 102 elif type(mapped) == str: 103 _AddOutcome(result, mapped) 104 else: 105 result.add(new) 106 107 108def _ParseOutcomeList(rule, outcomes, target_dict, variables): 109 result = set([]) 110 if type(outcomes) == str: 111 outcomes = [outcomes] 112 for item in outcomes: 113 if type(item) == str: 114 _AddOutcome(result, item) 115 elif type(item) == list: 116 if not eval(item[0], variables): continue 117 for outcome in item[1:]: 118 assert type(outcome) == str 119 _AddOutcome(result, outcome) 120 else: 121 assert False 122 if len(result) == 0: return 123 if rule in target_dict: 124 target_dict[rule] |= result 125 else: 126 target_dict[rule] = result 127 128 129def ReadContent(path): 130 with open(path) as f: 131 global KEYWORDS 132 return eval(f.read(), KEYWORDS) 133 134 135def ReadStatusFile(path, variables): 136 contents = ReadContent(path) 137 138 rules = {} 139 wildcards = {} 140 variables.update(VARIABLES) 141 for section in contents: 142 assert type(section) == list 143 assert len(section) == 2 144 if not eval(section[0], variables): continue 145 section = section[1] 146 assert type(section) == dict 147 for rule in section: 148 assert type(rule) == str 149 if rule[-1] == '*': 150 _ParseOutcomeList(rule, section[rule], wildcards, variables) 151 else: 152 _ParseOutcomeList(rule, section[rule], rules, variables) 153 return rules, wildcards 154 155 156def PresubmitCheck(path): 157 contents = ReadContent(path) 158 root_prefix = os.path.basename(os.path.dirname(path)) + "/" 159 status = {"success": True} 160 def _assert(check, message): # Like "assert", but doesn't throw. 161 if not check: 162 print("%s: Error: %s" % (path, message)) 163 status["success"] = False 164 try: 165 for section in contents: 166 _assert(type(section) == list, "Section must be a list") 167 _assert(len(section) == 2, "Section list must have exactly 2 entries") 168 section = section[1] 169 _assert(type(section) == dict, 170 "Second entry of section must be a dictionary") 171 for rule in section: 172 _assert(type(rule) == str, "Rule key must be a string") 173 _assert(not rule.startswith(root_prefix), 174 "Suite name prefix must not be used in rule keys") 175 _assert(not rule.endswith('.js'), 176 ".js extension must not be used in rule keys.") 177 return status["success"] 178 except Exception as e: 179 print e 180 return False 181