Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 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 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 28 | import os |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 29 | |
| 30 | # These outcomes can occur in a TestCase's outcomes list: |
| 31 | SKIP = "SKIP" |
| 32 | FAIL = "FAIL" |
| 33 | PASS = "PASS" |
| 34 | OKAY = "OKAY" |
| 35 | TIMEOUT = "TIMEOUT" |
| 36 | CRASH = "CRASH" |
| 37 | SLOW = "SLOW" |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 38 | FAST_VARIANTS = "FAST_VARIANTS" |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame^] | 39 | NO_IGNITION = "NO_IGNITION" |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 40 | NO_VARIANTS = "NO_VARIANTS" |
| 41 | # These are just for the status files and are mapped below in DEFS: |
| 42 | FAIL_OK = "FAIL_OK" |
| 43 | PASS_OR_FAIL = "PASS_OR_FAIL" |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 44 | FAIL_SLOPPY = "FAIL_SLOPPY" |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 45 | |
| 46 | ALWAYS = "ALWAYS" |
| 47 | |
| 48 | KEYWORDS = {} |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 49 | for key in [SKIP, FAIL, PASS, OKAY, TIMEOUT, CRASH, SLOW, FAIL_OK, |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame^] | 50 | FAST_VARIANTS, NO_IGNITION, NO_VARIANTS, PASS_OR_FAIL, FAIL_SLOPPY, |
| 51 | ALWAYS]: |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 52 | KEYWORDS[key] = key |
| 53 | |
| 54 | DEFS = {FAIL_OK: [FAIL, OKAY], |
| 55 | PASS_OR_FAIL: [PASS, FAIL]} |
| 56 | |
| 57 | # Support arches, modes to be written as keywords instead of strings. |
| 58 | VARIABLES = {ALWAYS: True} |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 59 | for 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", |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 63 | "s390", "s390x", "macos", "windows", "linux", "aix"]: |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 64 | VARIABLES[var] = var |
| 65 | |
| 66 | |
| 67 | def DoSkip(outcomes): |
| 68 | return SKIP in outcomes |
| 69 | |
| 70 | |
| 71 | def IsSlow(outcomes): |
| 72 | return SLOW in outcomes |
| 73 | |
| 74 | |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame^] | 75 | def NoIgnitionVariant(outcomes): |
| 76 | return NO_IGNITION in outcomes |
| 77 | |
| 78 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 79 | def OnlyStandardVariant(outcomes): |
| 80 | return NO_VARIANTS in outcomes |
| 81 | |
| 82 | |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 83 | def OnlyFastVariants(outcomes): |
| 84 | return FAST_VARIANTS in outcomes |
| 85 | |
| 86 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 87 | def IsPassOrFail(outcomes): |
| 88 | return ((PASS in outcomes) and (FAIL in outcomes) and |
| 89 | (not CRASH in outcomes) and (not OKAY in outcomes)) |
| 90 | |
| 91 | |
| 92 | def IsFailOk(outcomes): |
| 93 | return (FAIL in outcomes) and (OKAY in outcomes) |
| 94 | |
| 95 | |
| 96 | def _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 | |
| 109 | def _ParseOutcomeList(rule, outcomes, target_dict, variables): |
| 110 | result = set([]) |
| 111 | if type(outcomes) == str: |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 112 | outcomes = [outcomes] |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 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 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 130 | def ReadContent(path): |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 131 | with open(path) as f: |
| 132 | global KEYWORDS |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 133 | return eval(f.read(), KEYWORDS) |
| 134 | |
| 135 | |
| 136 | def ReadStatusFile(path, variables): |
| 137 | contents = ReadContent(path) |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 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 |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 155 | |
| 156 | |
| 157 | def 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 |