1 # Copyright 2014 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.
10 from telemetry.core import browser_options
11 from telemetry.core.backends.remote import trybot_browser_finder
12 from telemetry.unittest import simple_mock
13 from telemetry.unittest import system_stub
16 class TrybotBrowserFinderTest(unittest.TestCase):
19 self.log_output = StringIO.StringIO()
20 self.stream_handler = logging.StreamHandler(self.log_output)
21 logging.getLogger().addHandler(self.stream_handler)
22 self._real_subprocess = trybot_browser_finder.subprocess
23 self._real_urllib2 = trybot_browser_finder.urllib2
24 self._stubs = system_stub.Override(trybot_browser_finder,
25 ['sys', 'open', 'os'])
28 logging.getLogger().removeHandler(self.stream_handler)
29 self.log_output.close()
30 trybot_browser_finder.subprocess = self._real_subprocess
31 trybot_browser_finder.urllib2 = self._real_urllib2
34 def _ExpectProcesses(self, args):
35 mock_subprocess = simple_mock.MockObject()
36 mock_subprocess.SetAttribute('PIPE', simple_mock.MockObject())
38 mock_popen = simple_mock.MockObject()
39 mock_popen.ExpectCall('communicate').WillReturn(arg[1][1:])
40 mock_popen.ExpectCall('poll').WillReturn(arg[1][0])
41 mock_subprocess.ExpectCall(
42 'Popen').WithArgs(arg[0]).WillReturn(mock_popen)
43 trybot_browser_finder.subprocess = mock_subprocess
45 def test_find_all_browser_types_list(self):
46 finder_options = browser_options.BrowserFinderOptions(browser_type='list')
47 trybot_browser_finder.urllib2 = simple_mock.MockObject()
48 trybot_browser_finder.urllib2.ExpectCall('urlopen').WithArgs(
49 'http://build.chromium.org/p/tryserver.chromium.perf/json').WillReturn(
50 StringIO.StringIO(json.dumps({'builders': {
51 'android_nexus4_perf_bisect': 'stuff',
52 'mac_10_9_perf_bisect': 'otherstuff',
53 'win_perf_bisect_builder': 'not a trybot',
56 ['trybot-android-nexus4', 'trybot-mac-10-9'],
57 # pylint: disable=W0212
58 sorted(trybot_browser_finder.FindAllBrowserTypes(finder_options)))
60 def test_find_all_browser_types_trybot(self):
61 finder_options = browser_options.BrowserFinderOptions(
62 browser_type='trybot-win')
63 trybot_browser_finder.urllib2 = simple_mock.MockObject()
64 trybot_browser_finder.urllib2.ExpectCall('urlopen').WithArgs(
65 'http://build.chromium.org/p/tryserver.chromium.perf/json').WillReturn(
66 StringIO.StringIO(json.dumps({'builders': {
67 'android_nexus4_perf_bisect': 'stuff',
68 'mac_10_9_perf_bisect': 'otherstuff',
69 'win_perf_bisect_builder': 'not a trybot',
72 ['trybot-android-nexus4', 'trybot-mac-10-9'],
73 # pylint: disable=W0212
74 sorted(trybot_browser_finder.FindAllBrowserTypes(finder_options)))
76 def test_find_all_browser_types_non_trybot_browser(self):
77 finder_options = browser_options.BrowserFinderOptions(
78 browser_type='release')
79 trybot_browser_finder.urllib2 = simple_mock.MockObject()
82 # pylint: disable=W0212
83 sorted(trybot_browser_finder.FindAllBrowserTypes(finder_options)))
85 def test_constructor(self):
86 finder_options = browser_options.BrowserFinderOptions()
87 browser = trybot_browser_finder.PossibleTrybotBrowser(
88 'trybot-android-nexus4', finder_options)
89 # pylint: disable=W0212
90 self.assertEquals('android', browser._target_os)
91 # pylint: disable=W0212
92 self.assertEquals('android_nexus4_perf_bisect', browser._buildername)
94 def test_no_git(self):
95 finder_options = browser_options.BrowserFinderOptions()
96 browser = trybot_browser_finder.PossibleTrybotBrowser(
97 'trybot-android-nexus4', finder_options)
98 self._ExpectProcesses((
99 (['git', 'rev-parse', '--abbrev-ref', 'HEAD'], (128, None, None)),
103 'Must be in a git repository to send changes to trybots.\n',
104 self.log_output.getvalue())
106 def test_dirty_tree(self):
107 finder_options = browser_options.BrowserFinderOptions()
108 browser = trybot_browser_finder.PossibleTrybotBrowser(
109 'trybot-android-nexus4', finder_options)
110 self._ExpectProcesses((
111 (['git', 'rev-parse', '--abbrev-ref', 'HEAD'], (0, 'br', None)),
112 (['git', 'update-index', '--refresh', '-q'], (0, None, None,)),
113 (['git', 'diff-index', 'HEAD'], (0, 'dirty tree', None)),
118 'Cannot send a try job with a dirty tree. Commit locally first.\n',
119 self.log_output.getvalue())
121 def test_no_local_commits(self):
122 finder_options = browser_options.BrowserFinderOptions()
123 browser = trybot_browser_finder.PossibleTrybotBrowser(
124 'trybot-android-nexus4', finder_options)
125 self._ExpectProcesses((
126 (['git', 'rev-parse', '--abbrev-ref', 'HEAD'], (0, 'br', None)),
127 (['git', 'update-index', '--refresh', '-q'], (0, None, None,)),
128 (['git', 'diff-index', 'HEAD'], (0, '', None)),
129 (['git', 'log', 'origin/master..HEAD'], (0, '', None)),
130 (['git', 'rev-parse', '--abbrev-ref', 'HEAD'], (0, 'br', None)),
131 (['git', 'update-index', '--refresh', '-q'], (0, None, None,)),
132 (['git', 'diff-index', 'HEAD'], (0, '', None)),
133 (['git', 'log', 'origin/master..HEAD'], (0, '', None)),
138 ('No local changes found in chromium or blink trees. '
139 'browser=trybot-android-nexus4 argument sends local changes to the '
140 'android_nexus4_perf_bisect perf trybot.\n'),
141 self.log_output.getvalue())
143 def test_branch_checkout_fails(self):
144 finder_options = browser_options.BrowserFinderOptions()
145 browser = trybot_browser_finder.PossibleTrybotBrowser(
146 'trybot-android-nexus4', finder_options)
147 self._ExpectProcesses((
148 (['git', 'rev-parse', '--abbrev-ref', 'HEAD'], (0, 'br', None)),
149 (['git', 'update-index', '--refresh', '-q'], (0, None, None,)),
150 (['git', 'diff-index', 'HEAD'], (0, '', None)),
151 (['git', 'log', 'origin/master..HEAD'], (0, 'logs here', None)),
152 (['git', 'checkout', '-b', 'telemetry-tryjob'],
153 (1, None, 'fatal: A branch named \'telemetry-try\' already exists.')),
158 ('Error creating branch telemetry-tryjob. '
159 'Please delete it if it exists.\n'
160 'fatal: A branch named \'telemetry-try\' already exists.\n'),
161 self.log_output.getvalue())
163 def _GetConfigForBrowser(self, name, branch, cfg_filename, is_blink=False):
164 finder_options = browser_options.BrowserFinderOptions()
165 browser = trybot_browser_finder.PossibleTrybotBrowser(name, finder_options)
166 bot = '%s_perf_bisect' % name.replace('trybot-', '').replace('-', '_')
170 (['git', 'rev-parse', '--abbrev-ref', 'HEAD'], (0, 'br', None)),
171 (['git', 'update-index', '--refresh', '-q'], (0, None, None,)),
172 (['git', 'diff-index', 'HEAD'], (0, '', None)),
173 (['git', 'log', 'origin/master..HEAD'], (0, '', None))
175 self._ExpectProcesses(first_processes + (
176 (['git', 'rev-parse', '--abbrev-ref', 'HEAD'], (0, branch, None)),
177 (['git', 'update-index', '--refresh', '-q'], (0, None, None,)),
178 (['git', 'diff-index', 'HEAD'], (0, '', None)),
179 (['git', 'log', 'origin/master..HEAD'], (0, 'logs here', None)),
180 (['git', 'checkout', '-b', 'telemetry-tryjob'], (0, None, None)),
181 (['git', 'branch', '--set-upstream-to', 'origin/master'],
183 (['git', 'commit', '-a', '-m', 'bisect config'], (0, None, None)),
184 (['git', 'cl', 'upload', '-f', '--bypass-hooks', '-m',
185 'CL for perf tryjob'],
186 (0, 'stuff https://codereview.chromium.org/12345 stuff', None)),
187 (['git', 'cl', 'try', '-m', 'tryserver.chromium.perf', '-b', bot],
189 (['git', 'checkout', branch], (0, None, None)),
190 (['git', 'branch', '-D', 'telemetry-tryjob'], (0, None, None))
192 self._stubs.sys.argv = [
193 'tools/perf/run_benchmark',
194 '--browser=%s' % browser,
196 cfg = StringIO.StringIO()
197 self._stubs.open.files = {cfg_filename: cfg}
200 return cfg.getvalue()
202 def test_config_android(self):
203 config = self._GetConfigForBrowser(
204 'trybot-android-nexus4', 'somebranch', 'tools/run-perf-test.cfg')
207 ' "command": "./tools/perf/run_measurement '
208 '--browser=android-chrome-shell sunspider",\n'
209 ' "max_time_minutes": "120",\n'
210 ' "repeat_count": "1",\n'
211 ' "truncate_percent": "0"\n'
214 def test_config_mac(self):
215 config = self._GetConfigForBrowser(
216 'trybot-mac-10-9', 'currentwork', 'tools/run-perf-test.cfg')
219 ' "command": "./tools/perf/run_measurement '
220 '--browser=release sunspider",\n'
221 ' "max_time_minutes": "120",\n'
222 ' "repeat_count": "1",\n'
223 ' "truncate_percent": "0"\n'
226 def test_config_blink(self):
227 config = self._GetConfigForBrowser(
228 'trybot-mac-10-9', 'blinkbranch', 'Tools/run-perf-test.cfg', True)
231 ' "command": "./tools/perf/run_measurement '
232 '--browser=release sunspider",\n'
233 ' "max_time_minutes": "120",\n'
234 ' "repeat_count": "1",\n'
235 ' "truncate_percent": "0"\n'