Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(152)

Side by Side Diff: scripts/slave/recipe_modules/auto_bisect/api.py

Issue 2247373002: Refactor stages 1, 2 and test_api overhaul. (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/build.git@master
Patch Set: Rebasing, addressing feedback. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright 2015 The Chromium Authors. All rights reserved. 1 # Copyright 2015 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 """API for the bisect recipe module. 5 """API for the bisect recipe module.
6 6
7 This API is meant to enable the bisect recipe to bisect any chromium-supported 7 This API is meant to enable the bisect recipe to bisect any chromium-supported
8 platform for any test that can be run via buildbot, perf or otherwise. 8 platform for any test that can be run via buildbot, perf or otherwise.
9 """ 9 """
10 10
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 # Keep track of working directory (which contains the checkout). 50 # Keep track of working directory (which contains the checkout).
51 # None means "default value". 51 # None means "default value".
52 self._working_dir = None 52 self._working_dir = None
53 53
54 @property 54 @property
55 def working_dir(self): 55 def working_dir(self):
56 if not self._working_dir: 56 if not self._working_dir:
57 self._working_dir = self.m.chromium_checkout.get_checkout_dir({}) 57 self._working_dir = self.m.chromium_checkout.get_checkout_dir({})
58 return self._working_dir or self.m.path['slave_build'] 58 return self._working_dir or self.m.path['slave_build']
59 59
60 def perform_bisect(self, **flags):
61 return local_bisect.perform_bisect(self, **flags)
62
63 def create_bisector(self, bisect_config_dict, dummy_mode=False, **flags): 60 def create_bisector(self, bisect_config_dict, dummy_mode=False, **flags):
64 """Passes the api and the config dictionary to the Bisector constructor. 61 """Passes the api and the config dictionary to the Bisector constructor.
65 62
66 For details about the keys in the bisect config dictionary go to: 63 For details about the keys in the bisect config dictionary go to:
67 http://chromium.org/developers/speed-infra/perf-try-bots-bisect-bots/config 64 http://chromium.org/developers/speed-infra/perf-try-bots-bisect-bots/config
68 65
69 Args: 66 Args:
70 bisect_config_dict (dict): Contains the configuration for the bisect job. 67 bisect_config_dict (dict): Contains the configuration for the bisect job.
71 dummy_mode (bool): In dummy mode we prevent the bisector for expanding 68 dummy_mode (bool): In dummy mode we prevent the bisector for expanding
72 the revision range at construction, to avoid the need for lots of step 69 the revision range at construction, to avoid the need for lots of step
(...skipping 24 matching lines...) Expand all
97 depot_config.add_addition_depot_into(depot_info) # pragma: no cover 94 depot_config.add_addition_depot_into(depot_info) # pragma: no cover
98 95
99 def set_deploy_script(self, path): # pragma: no cover 96 def set_deploy_script(self, path): # pragma: no cover
100 """Sets apk deployment script path for android-chrome.""" 97 """Sets apk deployment script path for android-chrome."""
101 self.full_deploy_script = path 98 self.full_deploy_script = path
102 99
103 def set_svn_repo(self, svn_repo_url): # pragma: no cover 100 def set_svn_repo(self, svn_repo_url): # pragma: no cover
104 """Sets SVN repo url for triggering build jobs.""" 101 """Sets SVN repo url for triggering build jobs."""
105 self.svn_repo_url = svn_repo_url 102 self.svn_repo_url = svn_repo_url
106 103
107 def gsutil_file_exists(self, path): 104 def gsutil_file_exists(self, path, **kwargs):
eakuefner 2016/09/09 20:35:42 I don't like this idea of putting **kwargs everywh
RobertoCN 2016/09/13 22:11:40 I agree, but this is a pattern that is used all ov
108 """Returns True if a file exists at the given GS path.""" 105 """Returns True if a file exists at the given GS path."""
109 try: 106 try:
110 self.m.gsutil(['ls', path]) 107 self.m.gsutil( ['ls', path], **kwargs)
111 except self.m.step.StepFailure: # pragma: no cover 108 except self.m.step.StepFailure:
112 # A step failure here simply means that the file does not exist, and 109 # A step failure here simply means that the file does not exist, and
113 # should not be treated as an error. 110 # should not be treated as an error.
114 self.m.step.active_result.presentation.status = self.m.step.SUCCESS 111 self.m.step.active_result.presentation.status = self.m.step.SUCCESS
115 return False 112 return False
116 return True 113 return True
117 114
118 def query_revision_info(self, revision): 115 def query_revision_info(self, revision):
119 """Gathers information on a particular revision. 116 """Gathers information on a particular revision.
120 117
121 Args: 118 Args:
122 revision (str): A git commit hash. 119 revision (str): A git commit hash.
123 120
124 Returns: 121 Returns:
125 A dict with the keys "author", "email", "date", "subject" and "body", 122 A dict with the keys "author", "email", "date", "subject" and "body",
126 as output by fetch_revision_info.py. 123 as output by fetch_revision_info.py.
127 """ 124 """
128 step_name = 'Reading culprit cl information.' 125 step_name = 'Reading culprit cl information.'
129 # Use gitiles to get commit information. 126 # Use gitiles to get commit information.
130 if revision.depot_name == 'android-chrome': # pragma: no cover 127 if revision.depot_name == 'android-chrome': # pragma: no cover
131 commit_url = depot_config.DEPOT_DEPS_NAME[revision.depot_name]['url'] 128 commit_url = depot_config.DEPOT_DEPS_NAME[revision.depot_name]['url']
132 return self._commit_info(revision.commit_hash, commit_url, step_name) 129 return self._commit_info(revision.commit_hash, commit_url, step_name)
133 result = self.m.python( 130 result = self.m.python(
134 step_name, 131 step_name,
135 self.resource('fetch_revision_info.py'), 132 self.resource('fetch_revision_info.py'),
136 [revision.commit_hash, revision.depot_name], 133 [revision.commit_hash, revision.depot_name],
137 stdout=self.m.json.output()) 134 stdout=self.m.json.output(),
135 step_test_data=lambda: self._test_data['cl_info'][revision.commit_hash],
136 )
138 return result.stdout 137 return result.stdout
139 138
140 def _commit_info(self, commit_hash, url, step_name=None): # pragma: no cover 139 def _commit_info(self, commit_hash, url, step_name=None): # pragma: no cover
141 """Fetches information about a given commit. 140 """Fetches information about a given commit.
142 141
143 Args: 142 Args:
144 commit_hash (str): A git commit hash. 143 commit_hash (str): A git commit hash.
145 url (str): The URL of a repository, e.g. 144 url (str): The URL of a repository, e.g.
146 "https://chromium.googlesource.com/chromium/src". 145 "https://chromium.googlesource.com/chromium/src".
147 step_name (str): Optional step name. 146 step_name (str): Optional step name.
(...skipping 14 matching lines...) Expand all
162 'email': commit_info['author']['email'], 161 'email': commit_info['author']['email'],
163 'subject': subject, 162 'subject': subject,
164 'body': body, 163 'body': body,
165 'date': commit_info['committer']['time'], 164 'date': commit_info['committer']['time'],
166 } 165 }
167 return None 166 return None
168 except self.m.step.StepFailure: # pragma: no cover 167 except self.m.step.StepFailure: # pragma: no cover
169 self.surface_result('BAD_REV') 168 self.surface_result('BAD_REV')
170 raise 169 raise
171 170
172 def run_bisect_script(self, **kwargs): 171 def run_bisect_script(self, **kwargs): # pragma: no cover
prasadv 2016/09/09 18:52:30 Do we still want to support this? As far as I know
RobertoCN 2016/09/13 22:11:40 Done.
173 """Executes src/tools/run-perf-bisect-regression.py to perform bisection.""" 172 """Executes src/tools/run-perf-bisect-regression.py to perform bisection."""
174 self.m.python( 173 self.m.python(
175 'Preparing for Bisection', 174 'Preparing for Bisection',
176 script=self.m.path['checkout'].join( 175 script=self.m.path['checkout'].join(
177 'tools', 'prepare-bisect-perf-regression.py'), 176 'tools', 'prepare-bisect-perf-regression.py'),
178 args=['-w', self.m.path['cache'].join('bisect')]) 177 args=['-w', self.m.path['cache'].join('bisect')])
179 args = [] 178 args = []
180 179
181 kwargs['allow_subannotations'] = True 180 kwargs['allow_subannotations'] = True
182 181
183 # TODO(prasadv): Remove this once bisect runs are no longer running 182 # TODO(prasadv): Remove this once bisect runs are no longer running
184 # against revisions from February 2016 or earlier. 183 # against revisions from February 2016 or earlier.
185 if self.internal_bisect: # pragma: no cover 184 if self.internal_bisect:
186 kwargs['env'] = {'CHROMIUM_OUTPUT_DIR': self.m.chromium.output_dir} 185 kwargs['env'] = {'CHROMIUM_OUTPUT_DIR': self.m.chromium.output_dir}
187 186
188 if kwargs.get('extra_src'): 187 if kwargs.get('extra_src'):
189 args = args + ['--extra_src', kwargs.pop('extra_src')] 188 args = args + ['--extra_src', kwargs.pop('extra_src')]
190 if kwargs.get('path_to_config'): 189 if kwargs.get('path_to_config'):
191 args = args + ['--path_to_config', kwargs.pop('path_to_config')] 190 args = args + ['--path_to_config', kwargs.pop('path_to_config')]
192 if self.m.chromium.c.TARGET_PLATFORM != 'android': 191 if self.m.chromium.c.TARGET_PLATFORM != 'android':
193 goma_dir = self.m.goma.ensure_goma() 192 goma_dir = self.m.goma.ensure_goma()
194 args += ['--path_to_goma', goma_dir] 193 args += ['--path_to_goma', goma_dir]
195 args += [ 194 args += [
196 '--build-properties', 195 '--build-properties',
197 self.m.json.dumps(dict(self.m.properties.legacy())), 196 self.m.json.dumps(dict(self.m.properties.legacy())),
198 ] 197 ]
199 self.m.chromium.runtest( 198 self.m.chromium.runtest(
200 self.m.path['checkout'].join('tools', 'run-bisect-perf-regression.py'), 199 self.m.path['checkout'].join('tools', 'run-bisect-perf-regression.py'),
201 ['-w', self.m.path['cache'].join('bisect')] + args, 200 ['-w', self.m.path['cache'].join('bisect')] + args,
202 name='Running Bisection', 201 name='Running Bisection',
203 xvfb=True, **kwargs) 202 xvfb=True, **kwargs)
204 203
205 def run_local_test_run(self, test_config_params, 204 def run_local_test_run(self, test_config_params,
206 skip_download=False): # pragma: no cover 205 skip_download=False, **kwargs):
207 """Starts a test run on the same machine. 206 """Starts a test run on the same machine.
208 207
209 This is for the merged director/tester flow. 208 This is for the merged director/tester flow.
210 """ 209 """
211 if self.m.platform.is_win: 210 if self.m.platform.is_win:
212 self.m.chromium.taskkill() 211 self.m.chromium.taskkill()
213 212
214 if skip_download: 213 if skip_download: # pragma: no cover
215 update_step = None 214 update_step = None
216 else: 215 else:
217 update_step = self._SyncRevisionToTest(test_config_params) 216 update_step = self._SyncRevisionToTest(test_config_params)
218 self.start_test_run_for_bisect(update_step, self.bot_db, 217 return self.start_test_run_for_bisect(
219 test_config_params, run_locally=True, 218 update_step, self.bot_db, test_config_params,
220 skip_download=skip_download) 219 skip_download=skip_download, **kwargs)
221 220
222 def ensure_checkout(self, *args, **kwargs): 221 def ensure_checkout(self, *args, **kwargs):
223 if self.working_dir: 222 if self.working_dir:
224 kwargs.setdefault('cwd', self.working_dir) 223 kwargs.setdefault('cwd', self.working_dir)
225 224
226 return self.m.bot_update.ensure_checkout(*args, **kwargs) 225 return self.m.bot_update.ensure_checkout(*args, **kwargs)
227 226
228 def _SyncRevisionToTest(self, test_config_params): # pragma: no cover 227 def _SyncRevisionToTest(self, test_config_params):
229 if not self.internal_bisect: 228 if not self.internal_bisect:
230 return self.ensure_checkout( 229 return self.ensure_checkout(
231 root_solution_revision=test_config_params['revision']) 230 root_solution_revision=test_config_params['revision'])
232 else: 231 else: # pragma: no cover
233 return self._SyncRevisionsForAndroidChrome( 232 return self._SyncRevisionsForAndroidChrome(
234 test_config_params['revision_ladder']) 233 test_config_params['revision_ladder'])
235 234
236 def _SyncRevisionsForAndroidChrome(self, revision_ladder): # pragma: no cover 235 def _SyncRevisionsForAndroidChrome(self, revision_ladder): # pragma: no cover
237 """Syncs android-chrome and chromium repos to particular revision.""" 236 """Syncs android-chrome and chromium repos to particular revision."""
238 revisions = [] 237 revisions = []
239 for d, r in revision_ladder.iteritems(): 238 for d, r in revision_ladder.iteritems():
240 revisions.append('%s@%s' % (depot_config.DEPOT_DEPS_NAME[d]['src'], r)) 239 revisions.append('%s@%s' % (depot_config.DEPOT_DEPS_NAME[d]['src'], r))
241 params = ['sync', '--verbose', '--nohooks', '--force', 240 params = ['sync', '--verbose', '--nohooks', '--force',
242 '--delete_unversioned_trees'] 241 '--delete_unversioned_trees']
243 for revision in revisions: 242 for revision in revisions:
244 params.extend(['--revision', revision]) 243 params.extend(['--revision', revision])
245 self.m.gclient('sync %s' % '-'.join(revisions), params) 244 self.m.gclient('sync %s' % '-'.join(revisions), params)
246 return None 245 return None
247 246
248 def start_test_run_for_bisect(self, update_step, bot_db, 247 def start_test_run_for_bisect(self, update_step, bot_db, test_config_params,
249 test_config_params, run_locally=False, 248 skip_download=False, **kwargs):
250 skip_download=False):
251 mastername = self.m.properties.get('mastername') 249 mastername = self.m.properties.get('mastername')
252 buildername = self.m.properties.get('buildername') 250 buildername = self.m.properties.get('buildername')
253 bot_config = bot_db.get_bot_config(mastername, buildername) 251 bot_config = bot_db.get_bot_config(mastername, buildername)
254 build_archive_url = test_config_params['parent_build_archive_url'] 252 build_archive_url = test_config_params['parent_build_archive_url']
255 if not run_locally:
256 self.m.bisect_tester.upload_job_url()
257 if not skip_download: 253 if not skip_download:
258 if self.m.chromium.c.TARGET_PLATFORM == 'android': 254 if self.m.chromium.c.TARGET_PLATFORM == 'android':
259 # The best way to ensure the old build directory is not used is to 255 # The best way to ensure the old build directory is not used is to
260 # remove it. 256 # remove it.
261 build_dir = self.m.chromium.c.build_dir.join( 257 build_dir = self.m.chromium.c.build_dir.join(
262 self.m.chromium.c.build_config_fs) 258 self.m.chromium.c.build_config_fs)
263 self.m.file.rmtree('build directory', build_dir) 259 self.m.file.rmtree('build directory', build_dir)
264 260
265 # The way android builders on tryserver.chromium.perf are archived is 261 # The way android builders on tryserver.chromium.perf are archived is
266 # different from builders on chromium.perf. In order to support both 262 # different from builders on chromium.perf. In order to support both
(...skipping 22 matching lines...) Expand all
289 shutil.move(sys.argv[1], sys.argv[2]) 285 shutil.move(sys.argv[1], sys.argv[2])
290 """, 286 """,
291 args=[zip_dir, build_dir]) 287 args=[zip_dir, build_dir])
292 else: 288 else:
293 self.m.chromium_tests.download_and_unzip_build( 289 self.m.chromium_tests.download_and_unzip_build(
294 mastername, buildername, update_step, bot_db, 290 mastername, buildername, update_step, bot_db,
295 build_archive_url=build_archive_url, 291 build_archive_url=build_archive_url,
296 build_revision=test_config_params['parent_got_revision'], 292 build_revision=test_config_params['parent_got_revision'],
297 override_bot_type='tester') 293 override_bot_type='tester')
298 294
299 tests = [self.m.chromium_tests.steps.BisectTest(test_config_params)] 295 tests = [
296 self.m.chromium_tests.steps.BisectTest(
297 test_config_params, **kwargs)]
300 298
301 if not tests: # pragma: no cover 299 if not tests: # pragma: no cover
302 return 300 return
303 self.m.chromium_swarming.configure_swarming( 301 self.m.chromium_swarming.configure_swarming(
304 'chromium', precommit=False, mastername=mastername) 302 'chromium', precommit=False, mastername=mastername)
305 test_runner = self.m.chromium_tests.create_test_runner(self.m, tests) 303 test_runner = self.m.chromium_tests.create_test_runner(self.m, tests)
306 304
307 bot_config_object = self.m.chromium_tests.create_bot_config_object( 305 bot_config_object = self.m.chromium_tests.create_bot_config_object(
308 mastername, buildername) 306 mastername, buildername)
309 with self.m.chromium_tests.wrap_chromium_tests(bot_config_object, tests): 307 with self.m.chromium_tests.wrap_chromium_tests(bot_config_object, tests):
310 if self.m.chromium.c.TARGET_PLATFORM == 'android' and not skip_download: 308 if self.m.chromium.c.TARGET_PLATFORM == 'android' and not skip_download:
311 deploy_apks = [] 309 deploy_apks = []
312 deploy_args = [] 310 deploy_args = []
313 if self.internal_bisect: # pragma: no cover 311 if self.internal_bisect: # pragma: no cover
314 deploy_args = list(bot_config['deploy_args']) 312 deploy_args = list(bot_config['deploy_args'])
315 deploy_apks = bot_config.get('deploy_apks') 313 deploy_apks = bot_config.get('deploy_apks')
316 if deploy_apks: 314 if deploy_apks:
317 deploy_args.extend([ 315 deploy_args.extend([
318 '--apks', 316 '--apks',
319 ','.join(str(self.m.chromium_android.apk_path(apk)) 317 ','.join(str(self.m.chromium_android.apk_path(apk))
320 for apk in deploy_apks)]) 318 for apk in deploy_apks)])
321 else: 319 else:
322 if bot_config.get('webview'): 320 if bot_config.get('webview'):
323 deploy_apks = ['SystemWebView.apk', 'SystemWebViewShell.apk'] 321 deploy_apks = ['SystemWebView.apk', 'SystemWebViewShell.apk']
324 else: 322 else:
325 deploy_apks = ['ChromePublic.apk'] 323 deploy_apks = ['ChromePublic.apk']
326 self.deploy_apk_on_device( 324 self.deploy_apk_on_device(
327 self.full_deploy_script, deploy_apks, deploy_args) 325 self.full_deploy_script, deploy_apks, deploy_args)
328 test_runner() 326 test_runner()
327 return tests[0].run_results
329 328
330 def deploy_apk_on_device(self, deploy_script, deploy_apks, deploy_args): 329 def deploy_apk_on_device(self, deploy_script, deploy_apks, deploy_args):
331 """Installs apk on the android device.""" 330 """Installs apk on the android device."""
332 if deploy_script: # pragma: no cover 331 if deploy_script: # pragma: no cover
333 self.full_deploy_on_device(deploy_script, deploy_args) 332 self.full_deploy_on_device(deploy_script, deploy_args)
334 else: 333 else:
335 for apk in deploy_apks: 334 for apk in deploy_apks:
336 self.m.chromium_android.adb_install_apk(apk) 335 self.m.chromium_android.adb_install_apk(apk)
337 336
338 def full_deploy_on_device(self, deploy_script, args=None): # pragma: no cover 337 def full_deploy_on_device(self, deploy_script, args=None): # pragma: no cover
(...skipping 29 matching lines...) Expand all
368 api: The recipe api object. 367 api: The recipe api object.
369 update_step: Extra update_step to, used for some job types. 368 update_step: Extra update_step to, used for some job types.
370 bot_db: A BotConfigAndTestDB object, used for some job types. 369 bot_db: A BotConfigAndTestDB object, used for some job types.
371 kwargs: Args to use only for legacy bisect. 370 kwargs: Args to use only for legacy bisect.
372 """ 371 """
373 flags = {} 372 flags = {}
374 if kwargs.get('do_not_nest_wait_for_revision'): 373 if kwargs.get('do_not_nest_wait_for_revision'):
375 flags['do_not_nest_wait_for_revision'] = kwargs.pop( 374 flags['do_not_nest_wait_for_revision'] = kwargs.pop(
376 'do_not_nest_wait_for_revision') 375 'do_not_nest_wait_for_revision')
377 if bot_db is None: # pragma: no cover 376 if bot_db is None: # pragma: no cover
378 self.bot_db = api.chromium_tests.create_bot_db_from_master_dict( 377 self.bot_db = api.chromium_tests.create_bot_db_from_master_dict('', None)
379 '', None, None)
380 else: 378 else:
381 self.bot_db = bot_db 379 self.bot_db = bot_db
382 380
383 context = {} 381 context = {}
384 if self.working_dir: 382 if self.working_dir:
385 context['cwd'] = self.working_dir 383 context['cwd'] = self.working_dir
386 384
387 with api.step.context(context): 385 with api.step.context(context):
388 affected_files = self.m.tryserver.get_files_affected_by_patch() 386 affected_files = self.m.tryserver.get_files_affected_by_patch()
389 # Skip device setup for internal bisect as it is taken care in 387 # Skip device setup for internal bisect as it is taken care in
390 # internal recipes. 388 # internal recipes.
391 if (api.chromium.c.TARGET_PLATFORM == 'android' and 389 if (api.chromium.c.TARGET_PLATFORM == 'android' and
392 not self.internal_bisect): 390 not self.internal_bisect):
393 api.chromium_android.common_tests_setup_steps( 391 api.chromium_android.common_tests_setup_steps(
394 perf_setup=True, remove_system_webview=True) 392 perf_setup=True, remove_system_webview=True)
395 api.chromium.runhooks() 393 api.chromium.runhooks()
396 try: 394 try:
397 # Run legacy bisect script if the patch contains bisect.cfg. 395 # Run legacy bisect script if the patch contains bisect.cfg.
398 if BISECT_CONFIG_FILE in affected_files: 396 if BISECT_CONFIG_FILE in affected_files:
399 api.step('***LEGACY BISECT (deprecated)***', []) 397 api.step('***LEGACY BISECT (deprecated)***', [])
400 self.run_bisect_script(**kwargs) 398 self.run_bisect_script(**kwargs)
401 elif api.properties.get('bisect_config'): 399 elif api.properties.get('bisect_config'):
402 # We can distinguish between a config for a full bisect vs a single 400 # We can distinguish between a config for a full bisect vs a single
403 # test by checking for the presence of the good_revision key. 401 # test by checking for the presence of the good_revision key.
404 if api.properties.get('bisect_config').get('good_revision'): 402 if api.properties.get('bisect_config').get('good_revision'):
405 api.step('***BISECT***', []) 403 api.step('***BISECT***', [])
406 local_bisect.perform_bisect(self, **flags) # pragma: no cover 404 local_bisect.perform_bisect(self, **flags)
407 else: 405 else:
408 api.step('***SINGLE TEST (deprecated)***', []) 406 api.step('***SINGLE TEST (deprecated)***', [])
409 self.start_test_run_for_bisect(update_step, self.bot_db, 407 self.start_test_run_for_bisect(update_step, self.bot_db,
410 api.properties) 408 api.properties)
411 else: 409 else:
412 api.step('***PERF TRYJOB***', []) 410 api.step('***PERF TRYJOB***', [])
413 self.m.perf_try.start_perf_try_job( 411 self.m.perf_try.start_perf_try_job(
414 api, affected_files, update_step, self.bot_db) 412 api, affected_files, update_step, self.bot_db)
415 finally: 413 finally:
416 if api.chromium.c.TARGET_PLATFORM == 'android': 414 if api.chromium.c.TARGET_PLATFORM == 'android':
417 if self.internal_bisect: # pragma: no cover 415 if self.internal_bisect: # pragma: no cover
418 api.chromium_android.init_and_sync( 416 api.chromium_android.init_and_sync(
419 gclient_config=api.chromium_android.c.internal_dir_name, 417 gclient_config=api.chromium_android.c.internal_dir_name,
420 use_bot_update=True) 418 use_bot_update=True)
421 else: 419 else:
422 self.ensure_checkout() 420 self.ensure_checkout()
423 api.chromium_android.common_tests_final_steps() 421 api.chromium_android.common_tests_final_steps()
422
423 def stat_compare(self, values_a, values_b, metric,
424 output_format='chartjson', **kwargs):
425 """Compares samples using catapult's statistics implementation.
426
427 Args:
428 values_a, values_b: lists of paths to the json files containing the values
429 produced by the test.
430 metric: the name of the metric as sent by dashboard.
431 output_format: either 'chartjson' or 'valueset'
eakuefner 2016/09/09 20:35:42 will 'buildbot' be supported?
RobertoCN 2016/09/13 22:11:40 yeah, done.
432
433 Returns:
434 a dict containing 'result' which may be True, False or 'needMoreData', as
435 well as details about each sample ('debug_values', 'mean' and 'std_dev').
436
437 """
438 args = [','.join(map(str, values_a)),
439 ','.join(map(str, values_b)),
440 metric,
441 '--' + output_format]
442
443 script = self.m.path['catapult'].join(
444 'tracing', 'bin', 'compare_samples')
445 return self.m.python(
446 'Compare samples',
447 script=script,
448 args=args,
449 stdout=self.m.json.output(),
450 **kwargs).stdout
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698