| OLD | NEW |
| 1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import fnmatch | 5 import fnmatch |
| 6 import urlparse | 6 import urlparse |
| 7 | 7 |
| 8 # Valid expectation conditions are: | 8 # Valid expectation conditions are: |
| 9 # | 9 # |
| 10 # Operating systems: | 10 # Operating systems: |
| 11 # win, xp, vista, win7, win8, win10, mac, leopard, snowleopard, | 11 # win, xp, vista, win7, win8, win10, mac, leopard, snowleopard, |
| 12 # lion, mountainlion, mavericks, yosemite, sierra, linux, chromeos, | 12 # lion, mountainlion, mavericks, yosemite, sierra, linux, chromeos, |
| 13 # android | 13 # android |
| 14 # | 14 # |
| 15 # Browser types: | 15 # Browser types: |
| 16 # android-webview-shell, android-content-shell, debug, release | 16 # android-webview-shell, android-content-shell, debug, release |
| 17 # | 17 # |
| 18 # ASAN conditions: |
| 19 # asan, no_asan |
| 20 # |
| 18 # Sample usage in SetExpectations in subclasses: | 21 # Sample usage in SetExpectations in subclasses: |
| 19 # self.Fail('gl-enable-vertex-attrib.html', | 22 # self.Fail('gl-enable-vertex-attrib.html', |
| 20 # ['mac', 'release'], bug=123) | 23 # ['mac', 'release'], bug=123) |
| 21 | 24 |
| 22 WIN_CONDITIONS = ['xp', 'vista', 'win7', 'win8', 'win10'] | 25 WIN_CONDITIONS = ['xp', 'vista', 'win7', 'win8', 'win10'] |
| 23 MAC_CONDITIONS = ['leopard', 'snowleopard', 'lion', 'mountainlion', | 26 MAC_CONDITIONS = ['leopard', 'snowleopard', 'lion', 'mountainlion', |
| 24 'mavericks', 'yosemite', 'sierra'] | 27 'mavericks', 'yosemite', 'sierra'] |
| 25 | 28 |
| 26 OS_CONDITIONS = ['win', 'mac', 'linux', 'chromeos', 'android'] + \ | 29 OS_CONDITIONS = ['win', 'mac', 'linux', 'chromeos', 'android'] + \ |
| 27 WIN_CONDITIONS + MAC_CONDITIONS | 30 WIN_CONDITIONS + MAC_CONDITIONS |
| 28 | 31 |
| 29 BROWSER_TYPE_CONDITIONS = [ | 32 BROWSER_TYPE_CONDITIONS = [ |
| 30 'android-webview-shell', 'android-content-shell', 'android-chromium', | 33 'android-webview-shell', 'android-content-shell', 'android-chromium', |
| 31 'debug', 'release'] | 34 'debug', 'release'] |
| 32 | 35 |
| 36 ASAN_CONDITIONS = ['asan', 'no_asan'] |
| 37 |
| 38 def _SafeLower(opt_str): |
| 39 if not opt_str: |
| 40 return opt_str |
| 41 return opt_str.lower() |
| 42 |
| 43 |
| 33 class Expectation(object): | 44 class Expectation(object): |
| 34 """Represents a single expectation for a test. | 45 """Represents a single expectation for a test. |
| 35 | 46 |
| 36 Supports conditions based on operating system (e.g., win, mac) and | 47 Supports conditions based on operating system (e.g., win, mac) and |
| 37 browser type (e.g. 'debug', 'release'). | 48 browser type (e.g. 'debug', 'release'). |
| 38 | 49 |
| 39 The pattern, if a URL, *must* be a relative URL. Absolute URLs | 50 The pattern, if a URL, *must* be a relative URL. Absolute URLs |
| 40 (e.g. starting with a scheme like http://, https://, file://) are | 51 (e.g. starting with a scheme like http://, https://, file://) are |
| 41 not allowed. A ValueError is raised if one is passed to __init__. | 52 not allowed. A ValueError is raised if one is passed to __init__. |
| 42 | 53 |
| 43 Subclass this class and call super.__init__ last in your constructor | 54 Subclass this class and call super.__init__ last in your constructor |
| 44 in order to add new user-defined conditions. The conditions are | 55 in order to add new user-defined conditions. The conditions are |
| 45 parsed at the end of this class's constructor, so be careful not to | 56 parsed at the end of this class's constructor, so be careful not to |
| 46 overwrite the results of the constructor call! | 57 overwrite the results of the constructor call! |
| 47 | 58 |
| 48 """ | 59 """ |
| 49 | 60 |
| 50 def __init__(self, expectation, pattern, conditions=None, bug=None): | 61 def __init__(self, expectation, pattern, conditions=None, bug=None): |
| 51 self.expectation = expectation.lower() | 62 self.expectation = expectation.lower() |
| 52 if pattern.find('://') > 0: | 63 if pattern.find('://') > 0: |
| 53 raise ValueError('Absolute URLs are not allowed in patterns') | 64 raise ValueError('Absolute URLs are not allowed in patterns') |
| 54 self.pattern = pattern | 65 self.pattern = pattern |
| 55 self.bug = bug | 66 self.bug = bug |
| 56 | 67 |
| 57 self.os_conditions = [] | 68 self.os_conditions = [] |
| 58 self.browser_conditions = [] | 69 self.browser_conditions = [] |
| 70 self.asan_conditions = [] |
| 59 | 71 |
| 60 if conditions: | 72 if conditions: |
| 61 for c in conditions: | 73 for c in conditions: |
| 62 self.ParseCondition(c) | 74 self.ParseCondition(c) |
| 63 | 75 |
| 64 def ParseCondition(self, condition): | 76 def ParseCondition(self, condition): |
| 65 """Parses a single test expectation condition. | 77 """Parses a single test expectation condition. |
| 66 | 78 |
| 67 Can be overridden to handle new types of conditions. Call the | 79 Can be overridden to handle new types of conditions. Call the |
| 68 superclass's implementation of ParseCondition at the end of your | 80 superclass's implementation of ParseCondition at the end of your |
| (...skipping 14 matching lines...) Expand all Loading... |
| 83 | 95 |
| 84 Sample usage in SetExpectations in subclasses: | 96 Sample usage in SetExpectations in subclasses: |
| 85 self.Fail('gl-enable-vertex-attrib.html', | 97 self.Fail('gl-enable-vertex-attrib.html', |
| 86 ['mac', 'release'], bug=123) | 98 ['mac', 'release'], bug=123) |
| 87 | 99 |
| 88 """ | 100 """ |
| 89 cl = condition.lower() | 101 cl = condition.lower() |
| 90 if cl in OS_CONDITIONS: | 102 if cl in OS_CONDITIONS: |
| 91 self.os_conditions.append(cl) | 103 self.os_conditions.append(cl) |
| 92 elif cl in BROWSER_TYPE_CONDITIONS: | 104 elif cl in BROWSER_TYPE_CONDITIONS: |
| 93 self.browser_conditions.append(condition) | 105 self.browser_conditions.append(cl) |
| 106 elif cl in ASAN_CONDITIONS: |
| 107 self.asan_conditions.append(cl) |
| 94 else: | 108 else: |
| 95 raise ValueError('Unknown expectation condition: "%s"' % cl) | 109 raise ValueError('Unknown expectation condition: "%s"' % cl) |
| 96 | 110 |
| 97 | 111 |
| 98 class TestExpectations(object): | 112 class TestExpectations(object): |
| 99 """A class which defines the expectations for a test execution.""" | 113 """A class which defines the expectations for a test execution.""" |
| 100 | 114 |
| 101 def __init__(self, url_prefixes=None): | 115 def __init__(self, url_prefixes=None, is_asan=False): |
| 102 self._expectations = [] | 116 self._expectations = [] |
| 103 self._url_prefixes = [] | 117 self._url_prefixes = [] |
| 118 # The browser doesn't know whether it was built with ASAN or not; |
| 119 # only the surrounding environment knows that. Tests which care to |
| 120 # support ASAN-specific expectations have to tell the |
| 121 # TestExpectations object about this during its construction. |
| 122 self._is_asan = is_asan |
| 104 self._skip_matching_names = False | 123 self._skip_matching_names = False |
| 105 self._built_expectation_cache = True | 124 self._built_expectation_cache = True |
| 106 self._ClearExpectationsCache() | 125 self._ClearExpectationsCache() |
| 107 self.SetExpectations() | 126 self.SetExpectations() |
| 108 if url_prefixes: | 127 if url_prefixes: |
| 109 for p in url_prefixes: | 128 for p in url_prefixes: |
| 110 self._url_prefixes.append(p) | 129 self._url_prefixes.append(p) |
| 111 | 130 |
| 112 def SetExpectations(self): | 131 def SetExpectations(self): |
| 113 """Called on creation. Override to set up custom expectations.""" | 132 """Called on creation. Override to set up custom expectations.""" |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 raise ValueError('Neither test_url nor test_name may be None') | 286 raise ValueError('Neither test_url nor test_name may be None') |
| 268 | 287 |
| 269 # Relative URL. | 288 # Relative URL. |
| 270 if not fnmatch.fnmatch(self._GetURLPath(test_url, browser), | 289 if not fnmatch.fnmatch(self._GetURLPath(test_url, browser), |
| 271 expectation.pattern): | 290 expectation.pattern): |
| 272 # Name. | 291 # Name. |
| 273 if not (test_name and fnmatch.fnmatch(test_name, expectation.pattern)): | 292 if not (test_name and fnmatch.fnmatch(test_name, expectation.pattern)): |
| 274 return False | 293 return False |
| 275 | 294 |
| 276 platform = browser.platform | 295 platform = browser.platform |
| 277 os_matches = (not expectation.os_conditions or | 296 os_matches = ( |
| 278 platform.GetOSName() in expectation.os_conditions or | 297 not expectation.os_conditions or |
| 279 platform.GetOSVersionName() in expectation.os_conditions) | 298 _SafeLower(platform.GetOSName()) in expectation.os_conditions or |
| 299 _SafeLower(platform.GetOSVersionName()) in expectation.os_conditions) |
| 280 | 300 |
| 281 browser_matches = ( | 301 browser_matches = ( |
| 282 (not expectation.browser_conditions) or | 302 (not expectation.browser_conditions) or |
| 283 browser.browser_type in expectation.browser_conditions) | 303 _SafeLower(browser.browser_type) in expectation.browser_conditions) |
| 284 | 304 |
| 285 return os_matches and browser_matches | 305 asan_matches = ( |
| 306 (not expectation.asan_conditions) or |
| 307 ('asan' in expectation.asan_conditions and self._is_asan) or |
| 308 ('no_asan' in expectation.asan_conditions and not self._is_asan)) |
| 309 |
| 310 return os_matches and browser_matches and asan_matches |
| OLD | NEW |