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
3# found in the LICENSE file.
4
5import fnmatch
6
7OS_MODIFIERS = ['win', 'xp', 'vista', 'win7',
8                'mac', 'leopard', 'snowleopard', 'lion', 'mountainlion',
9                'mavericks', 'yosemite', 'linux', 'chromeos', 'android']
10GPU_MODIFIERS = ['amd', 'arm', 'broadcom', 'hisilicon', 'intel', 'imagination',
11                 'nvidia', 'qualcomm', 'vivante']
12CONFIG_MODIFIERS = ['debug', 'release']
13
14class Expectation(object):
15  def __init__(self, expectation, pattern, conditions=None, bug=None):
16    self.expectation = expectation.lower()
17    self.name_pattern = pattern
18    self.url_pattern = pattern
19    self.bug = bug
20
21    self.os_conditions = []
22    self.gpu_conditions = []
23    self.config_conditions = []
24    self.device_id_conditions = []
25
26    # Make sure that non-absolute paths are searchable
27    if not '://' in self.url_pattern:
28      self.url_pattern = '*/' + self.url_pattern
29
30    if conditions:
31      for c in conditions:
32        if isinstance(c, tuple):
33          c0 = c[0].lower()
34          if c0 in GPU_MODIFIERS:
35            self.device_id_conditions.append((c0, c[1]))
36          else:
37            raise ValueError('Unknown expectation condition: "%s"' % c0)
38        else:
39          condition = c.lower()
40          if condition in OS_MODIFIERS:
41            self.os_conditions.append(condition)
42          elif condition in GPU_MODIFIERS:
43            self.gpu_conditions.append(condition)
44          elif condition in CONFIG_MODIFIERS:
45            self.config_conditions.append(condition)
46          else:
47            raise ValueError('Unknown expectation condition: "%s"' % condition)
48
49class TestExpectations(object):
50  """A class which defines the expectations for a page set test execution"""
51
52  def __init__(self):
53    self.expectations = []
54    self.SetExpectations()
55
56  def SetExpectations(self):
57    """Called on creation. Override to set up custom expectations."""
58    pass
59
60  def Fail(self, url_pattern, conditions=None, bug=None):
61    self._Expect('fail', url_pattern, conditions, bug)
62
63  def Skip(self, url_pattern, conditions=None, bug=None):
64    self._Expect('skip', url_pattern, conditions, bug)
65
66  def _Expect(self, expectation, url_pattern, conditions=None, bug=None):
67    self.expectations.append(Expectation(expectation, url_pattern, conditions,
68      bug))
69
70  def GetExpectationForPage(self, browser, page):
71    platform = browser.platform
72    gpu_info = None
73
74    for e in self.expectations:
75      matches_url = fnmatch.fnmatch(page.url, e.url_pattern)
76      matches_name = page.name and fnmatch.fnmatch(page.name, e.name_pattern)
77      if matches_url or matches_name:
78        if gpu_info == None and browser.supports_system_info:
79          gpu_info = browser.GetSystemInfo().gpu
80        if self._ModifiersApply(platform, gpu_info, e):
81          return e.expectation
82    return 'pass'
83
84  def _GetGpuVendorString(self, gpu_info):
85    if gpu_info:
86      primary_gpu = gpu_info.devices[0]
87      if primary_gpu:
88        vendor_string = primary_gpu.vendor_string.lower()
89        vendor_id = primary_gpu.vendor_id
90        if vendor_string:
91          return vendor_string.split(' ')[0]
92        elif vendor_id == 0x10DE:
93          return 'nvidia'
94        elif vendor_id == 0x1002:
95          return 'amd'
96        elif vendor_id == 0x8086:
97          return 'intel'
98
99    return 'unknown_gpu'
100
101  def _GetGpuDeviceId(self, gpu_info):
102    if gpu_info:
103      primary_gpu = gpu_info.devices[0]
104      if primary_gpu:
105        return primary_gpu.device_id or primary_gpu.device_string
106
107    return 0
108
109  def _ModifiersApply(self, platform, gpu_info, expectation):
110    """Determines if the conditions for an expectation apply to this system."""
111    os_matches = (not expectation.os_conditions or
112        platform.GetOSName() in expectation.os_conditions or
113        platform.GetOSVersionName() in expectation.os_conditions)
114
115    gpu_vendor = self._GetGpuVendorString(gpu_info)
116    gpu_device_id = self._GetGpuDeviceId(gpu_info)
117
118    gpu_matches = ((not expectation.gpu_conditions and
119        not expectation.device_id_conditions) or
120        gpu_vendor in expectation.gpu_conditions or
121        (gpu_vendor, gpu_device_id) in expectation.device_id_conditions)
122
123    return os_matches and gpu_matches
124