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" 38FAST_VARIANTS = "FAST_VARIANTS" 39NO_IGNITION = "NO_IGNITION" 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, FAIL_OK, 50 FAST_VARIANTS, NO_IGNITION, NO_VARIANTS, PASS_OR_FAIL, FAIL_SLOPPY, 51 ALWAYS]: 52 KEYWORDS[key] = key 53 54DEFS = {FAIL_OK: [FAIL, OKAY], 55 PASS_OR_FAIL: [PASS, FAIL]} 56 57# Support arches, modes to be written as keywords instead of strings. 58VARIABLES = {ALWAYS: True} 59for var in ["debug", "release", "big", "little", 60 "android_arm", "android_arm64", "android_ia32", "android_x87", 61 "android_x64", "arm", "arm64", "ia32", "mips", "mipsel", "mips64", 62 "mips64el", "x64", "x87", "nacl_ia32", "nacl_x64", "ppc", "ppc64", 63 "s390", "s390x", "macos", "windows", "linux", "aix"]: 64 VARIABLES[var] = var 65 66 67def DoSkip(outcomes): 68 return SKIP in outcomes 69 70 71def IsSlow(outcomes): 72 return SLOW in outcomes 73 74 75def NoIgnitionVariant(outcomes): 76 return NO_IGNITION in outcomes 77 78 79def OnlyStandardVariant(outcomes): 80 return NO_VARIANTS in outcomes 81 82 83def OnlyFastVariants(outcomes): 84 return FAST_VARIANTS in outcomes 85 86 87def IsPassOrFail(outcomes): 88 return ((PASS in outcomes) and (FAIL in outcomes) and 89 (not CRASH in outcomes) and (not OKAY in outcomes)) 90 91 92def IsFailOk(outcomes): 93 return (FAIL in outcomes) and (OKAY in outcomes) 94 95 96def _AddOutcome(result, new): 97 global DEFS 98 if new in DEFS: 99 mapped = DEFS[new] 100 if type(mapped) == list: 101 for m in mapped: 102 _AddOutcome(result, m) 103 elif type(mapped) == str: 104 _AddOutcome(result, mapped) 105 else: 106 result.add(new) 107 108 109def _ParseOutcomeList(rule, outcomes, target_dict, variables): 110 result = set([]) 111 if type(outcomes) == str: 112 outcomes = [outcomes] 113 for item in outcomes: 114 if type(item) == str: 115 _AddOutcome(result, item) 116 elif type(item) == list: 117 if not eval(item[0], variables): continue 118 for outcome in item[1:]: 119 assert type(outcome) == str 120 _AddOutcome(result, outcome) 121 else: 122 assert False 123 if len(result) == 0: return 124 if rule in target_dict: 125 target_dict[rule] |= result 126 else: 127 target_dict[rule] = result 128 129 130def ReadContent(path): 131 with open(path) as f: 132 global KEYWORDS 133 return eval(f.read(), KEYWORDS) 134 135 136def ReadStatusFile(path, variables): 137 contents = ReadContent(path) 138 139 rules = {} 140 wildcards = {} 141 variables.update(VARIABLES) 142 for section in contents: 143 assert type(section) == list 144 assert len(section) == 2 145 if not eval(section[0], variables): continue 146 section = section[1] 147 assert type(section) == dict 148 for rule in section: 149 assert type(rule) == str 150 if rule[-1] == '*': 151 _ParseOutcomeList(rule, section[rule], wildcards, variables) 152 else: 153 _ParseOutcomeList(rule, section[rule], rules, variables) 154 return rules, wildcards 155 156 157def PresubmitCheck(path): 158 contents = ReadContent(path) 159 root_prefix = os.path.basename(os.path.dirname(path)) + "/" 160 status = {"success": True} 161 def _assert(check, message): # Like "assert", but doesn't throw. 162 if not check: 163 print("%s: Error: %s" % (path, message)) 164 status["success"] = False 165 try: 166 for section in contents: 167 _assert(type(section) == list, "Section must be a list") 168 _assert(len(section) == 2, "Section list must have exactly 2 entries") 169 section = section[1] 170 _assert(type(section) == dict, 171 "Second entry of section must be a dictionary") 172 for rule in section: 173 _assert(type(rule) == str, "Rule key must be a string") 174 _assert(not rule.startswith(root_prefix), 175 "Suite name prefix must not be used in rule keys") 176 _assert(not rule.endswith('.js'), 177 ".js extension must not be used in rule keys.") 178 return status["success"] 179 except Exception as e: 180 print e 181 return False 182