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.
4import unittest
5
6from telemetry.core import browser_options
7from telemetry.core.backends.chrome import desktop_browser_finder
8from telemetry.unittest import system_stub
9
10
11# This file verifies the logic for finding a browser instance on all platforms
12# at once. It does so by providing stubs for the OS/sys/subprocess primitives
13# that the underlying finding logic usually uses to locate a suitable browser.
14# We prefer this approach to having to run the same test on every platform on
15# which we want this code to work.
16
17class FindTestBase(unittest.TestCase):
18  def setUp(self):
19    self._finder_options = browser_options.BrowserFinderOptions()
20    self._finder_options.chrome_root = '../../../'
21    self._finder_stubs = system_stub.Override(desktop_browser_finder,
22                                              ['os', 'subprocess', 'sys'])
23    self._path_stubs = system_stub.Override(desktop_browser_finder.path,
24                                            ['os', 'sys'])
25
26  def tearDown(self):
27    self._finder_stubs.Restore()
28    self._path_stubs.Restore()
29
30  @property
31  def _files(self):
32    return self._path_stubs.os.path.files
33
34  def DoFindAll(self):
35    return desktop_browser_finder.FindAllAvailableBrowsers(self._finder_options)
36
37  def DoFindAllTypes(self):
38    browsers = self.DoFindAll()
39    return [b.browser_type for b in browsers]
40
41  def CanFindAvailableBrowsers(self):
42    return desktop_browser_finder.CanFindAvailableBrowsers()
43
44
45def has_type(array, browser_type):
46  return len([x for x in array if x.browser_type == browser_type]) != 0
47
48
49class FindSystemTest(FindTestBase):
50  def setUp(self):
51    super(FindSystemTest, self).setUp()
52    self._finder_stubs.sys.platform = 'win32'
53    self._path_stubs.sys.platform = 'win32'
54
55  def testFindProgramFiles(self):
56    if not self.CanFindAvailableBrowsers():
57      return
58
59    self._files.append(
60        'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe')
61    self._path_stubs.os.program_files = 'C:\\Program Files'
62    self.assertIn('system', self.DoFindAllTypes())
63
64  def testFindProgramFilesX86(self):
65    if not self.CanFindAvailableBrowsers():
66      return
67
68    self._files.append(
69        'C:\\Program Files(x86)\\Google\\Chrome\\Application\\chrome.exe')
70    self._path_stubs.os.program_files_x86 = 'C:\\Program Files(x86)'
71    self.assertIn('system', self.DoFindAllTypes())
72
73  def testFindLocalAppData(self):
74    if not self.CanFindAvailableBrowsers():
75      return
76
77    self._files.append(
78        'C:\\Local App Data\\Google\\Chrome\\Application\\chrome.exe')
79    self._path_stubs.os.local_app_data = 'C:\\Local App Data'
80    self.assertIn('system', self.DoFindAllTypes())
81
82
83class FindLocalBuildsTest(FindTestBase):
84  def setUp(self):
85    super(FindLocalBuildsTest, self).setUp()
86    self._finder_stubs.sys.platform = 'win32'
87    self._path_stubs.sys.platform = 'win32'
88
89  def testFindBuild(self):
90    if not self.CanFindAvailableBrowsers():
91      return
92
93    self._files.append('..\\..\\..\\build\\Release\\chrome.exe')
94    self.assertIn('release', self.DoFindAllTypes())
95
96  def testFindOut(self):
97    if not self.CanFindAvailableBrowsers():
98      return
99
100    self._files.append('..\\..\\..\\out\\Release\\chrome.exe')
101    self.assertIn('release', self.DoFindAllTypes())
102
103  def testFindXcodebuild(self):
104    if not self.CanFindAvailableBrowsers():
105      return
106
107    self._files.append('..\\..\\..\\xcodebuild\\Release\\chrome.exe')
108    self.assertIn('release', self.DoFindAllTypes())
109
110
111class OSXFindTest(FindTestBase):
112  def setUp(self):
113    super(OSXFindTest, self).setUp()
114    self._finder_stubs.sys.platform = 'darwin'
115    self._path_stubs.sys.platform = 'darwin'
116    self._files.append('/Applications/Google Chrome Canary.app/'
117                       'Contents/MacOS/Google Chrome Canary')
118    self._files.append('/Applications/Google Chrome.app/' +
119                       'Contents/MacOS/Google Chrome')
120    self._files.append(
121      '../../../out/Release/Chromium.app/Contents/MacOS/Chromium')
122    self._files.append(
123      '../../../out/Debug/Chromium.app/Contents/MacOS/Chromium')
124    self._files.append(
125      '../../../out/Release/Content Shell.app/Contents/MacOS/Content Shell')
126    self._files.append(
127      '../../../out/Debug/Content Shell.app/Contents/MacOS/Content Shell')
128
129  def testFindAll(self):
130    if not self.CanFindAvailableBrowsers():
131      return
132
133    types = self.DoFindAllTypes()
134    self.assertEquals(
135      set(types),
136      set(['debug', 'release',
137           'content-shell-debug', 'content-shell-release',
138           'canary', 'system']))
139
140
141class LinuxFindTest(FindTestBase):
142  def setUp(self):
143    super(LinuxFindTest, self).setUp()
144
145    self._finder_stubs.sys.platform = 'linux2'
146    self._path_stubs.sys.platform = 'linux2'
147    self._files.append('/foo/chrome')
148    self._files.append('../../../out/Release/chrome')
149    self._files.append('../../../out/Debug/chrome')
150    self._files.append('../../../out/Release/content_shell')
151    self._files.append('../../../out/Debug/content_shell')
152
153    self.has_google_chrome_on_path = False
154    this = self
155    def call_hook(*args, **kwargs): # pylint: disable=W0613
156      if this.has_google_chrome_on_path:
157        return 0
158      raise OSError('Not found')
159    self._finder_stubs.subprocess.call = call_hook
160
161  def testFindAllWithExact(self):
162    if not self.CanFindAvailableBrowsers():
163      return
164
165    types = self.DoFindAllTypes()
166    self.assertEquals(
167        set(types),
168        set(['debug', 'release',
169             'content-shell-debug', 'content-shell-release']))
170
171  def testFindWithProvidedExecutable(self):
172    if not self.CanFindAvailableBrowsers():
173      return
174
175    self._finder_options.browser_executable = '/foo/chrome'
176    self.assertIn('exact', self.DoFindAllTypes())
177
178  def testFindUsingDefaults(self):
179    if not self.CanFindAvailableBrowsers():
180      return
181
182    self.has_google_chrome_on_path = True
183    self.assertIn('release', self.DoFindAllTypes())
184
185    del self._files[1]
186    self.has_google_chrome_on_path = True
187    self.assertIn('system', self.DoFindAllTypes())
188
189    self.has_google_chrome_on_path = False
190    del self._files[1]
191    self.assertEquals(['content-shell-debug', 'content-shell-release'],
192                      self.DoFindAllTypes())
193
194  def testFindUsingRelease(self):
195    if not self.CanFindAvailableBrowsers():
196      return
197
198    self.assertIn('release', self.DoFindAllTypes())
199
200
201class WinFindTest(FindTestBase):
202  def setUp(self):
203    super(WinFindTest, self).setUp()
204
205    self._finder_stubs.sys.platform = 'win32'
206    self._path_stubs.sys.platform = 'win32'
207    self._path_stubs.os.local_app_data = 'c:\\Users\\Someone\\AppData\\Local'
208    self._files.append('c:\\tmp\\chrome.exe')
209    self._files.append('..\\..\\..\\build\\Release\\chrome.exe')
210    self._files.append('..\\..\\..\\build\\Debug\\chrome.exe')
211    self._files.append('..\\..\\..\\build\\Release\\content_shell.exe')
212    self._files.append('..\\..\\..\\build\\Debug\\content_shell.exe')
213    self._files.append(self._path_stubs.os.local_app_data + '\\' +
214                       'Google\\Chrome\\Application\\chrome.exe')
215    self._files.append(self._path_stubs.os.local_app_data + '\\' +
216                       'Google\\Chrome SxS\\Application\\chrome.exe')
217
218  def testFindAllGivenDefaults(self):
219    if not self.CanFindAvailableBrowsers():
220      return
221
222    types = self.DoFindAllTypes()
223    self.assertEquals(set(types),
224                      set(['debug', 'release',
225                           'content-shell-debug', 'content-shell-release',
226                           'system', 'canary']))
227
228  def testFindAllWithExact(self):
229    if not self.CanFindAvailableBrowsers():
230      return
231
232    self._finder_options.browser_executable = 'c:\\tmp\\chrome.exe'
233    types = self.DoFindAllTypes()
234    self.assertEquals(
235        set(types),
236        set(['exact',
237             'debug', 'release',
238             'content-shell-debug', 'content-shell-release',
239             'system', 'canary']))
240