1ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch# Copyright 2013 The Chromium Authors. All rights reserved.
2ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch# Use of this source code is governed by a BSD-style license that can be
3ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch# found in the LICENSE file.
4ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
5ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochimport fnmatch
6ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
7ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochOS_MODIFIERS = ['win', 'xp', 'vista', 'win7',
8ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                'mac', 'leopard', 'snowleopard', 'lion', 'mountainlion',
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                'mavericks', 'yosemite', 'linux', 'chromeos', 'android']
104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)GPU_MODIFIERS = ['amd', 'arm', 'broadcom', 'hisilicon', 'intel', 'imagination',
114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                 'nvidia', 'qualcomm', 'vivante']
12ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochCONFIG_MODIFIERS = ['debug', 'release']
13ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
14ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochclass Expectation(object):
151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def __init__(self, expectation, pattern, conditions=None, bug=None):
16ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    self.expectation = expectation.lower()
171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    self.name_pattern = pattern
181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    self.url_pattern = pattern
19ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    self.bug = bug
20ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
21ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    self.os_conditions = []
22ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    self.gpu_conditions = []
23ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    self.config_conditions = []
243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    self.device_id_conditions = []
25ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
26ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    # Make sure that non-absolute paths are searchable
27ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    if not '://' in self.url_pattern:
28ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      self.url_pattern = '*/' + self.url_pattern
29ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
30ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    if conditions:
31ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      for c in conditions:
323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        if isinstance(c, tuple):
333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          c0 = c[0].lower()
343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          if c0 in GPU_MODIFIERS:
353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            self.device_id_conditions.append((c0, c[1]))
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          else:
374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            raise ValueError('Unknown expectation condition: "%s"' % c0)
38ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        else:
393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          condition = c.lower()
403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          if condition in OS_MODIFIERS:
413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            self.os_conditions.append(condition)
423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          elif condition in GPU_MODIFIERS:
433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            self.gpu_conditions.append(condition)
443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          elif condition in CONFIG_MODIFIERS:
453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            self.config_conditions.append(condition)
463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          else:
473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            raise ValueError('Unknown expectation condition: "%s"' % condition)
48ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
49ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochclass TestExpectations(object):
50ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  """A class which defines the expectations for a page set test execution"""
51ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
52ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  def __init__(self):
53ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    self.expectations = []
54ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    self.SetExpectations()
55ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
56ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  def SetExpectations(self):
57ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    """Called on creation. Override to set up custom expectations."""
58ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    pass
59ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
60ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  def Fail(self, url_pattern, conditions=None, bug=None):
61ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    self._Expect('fail', url_pattern, conditions, bug)
62ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
63424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  def Skip(self, url_pattern, conditions=None, bug=None):
64424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    self._Expect('skip', url_pattern, conditions, bug)
65424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
66ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  def _Expect(self, expectation, url_pattern, conditions=None, bug=None):
67ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    self.expectations.append(Expectation(expectation, url_pattern, conditions,
68ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      bug))
69ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  def GetExpectationForPage(self, browser, page):
713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    platform = browser.platform
723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    gpu_info = None
733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
74ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    for e in self.expectations:
751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      matches_url = fnmatch.fnmatch(page.url, e.url_pattern)
761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      matches_name = page.name and fnmatch.fnmatch(page.name, e.name_pattern)
771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      if matches_url or matches_name:
783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        if gpu_info == None and browser.supports_system_info:
793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          gpu_info = browser.GetSystemInfo().gpu
803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        if self._ModifiersApply(platform, gpu_info, e):
81ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch          return e.expectation
82ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return 'pass'
83ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  def _GetGpuVendorString(self, gpu_info):
853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if gpu_info:
863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      primary_gpu = gpu_info.devices[0]
873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      if primary_gpu:
883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        vendor_string = primary_gpu.vendor_string.lower()
893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        vendor_id = primary_gpu.vendor_id
903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        if vendor_string:
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          return vendor_string.split(' ')[0]
923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        elif vendor_id == 0x10DE:
933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          return 'nvidia'
943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        elif vendor_id == 0x1002:
953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          return 'amd'
963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        elif vendor_id == 0x8086:
973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          return 'intel'
983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return 'unknown_gpu'
1003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  def _GetGpuDeviceId(self, gpu_info):
1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if gpu_info:
1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      primary_gpu = gpu_info.devices[0]
1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      if primary_gpu:
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        return primary_gpu.device_id or primary_gpu.device_string
1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return 0
1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  def _ModifiersApply(self, platform, gpu_info, expectation):
110ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    """Determines if the conditions for an expectation apply to this system."""
111ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    os_matches = (not expectation.os_conditions or
1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        platform.GetOSName() in expectation.os_conditions or
1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        platform.GetOSVersionName() in expectation.os_conditions)
1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    gpu_vendor = self._GetGpuVendorString(gpu_info)
1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    gpu_device_id = self._GetGpuDeviceId(gpu_info)
117ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    gpu_matches = ((not expectation.gpu_conditions and
1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        not expectation.device_id_conditions) or
1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        gpu_vendor in expectation.gpu_conditions or
1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        (gpu_vendor, gpu_device_id) in expectation.device_id_conditions)
122ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return os_matches and gpu_matches
124