Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 perf try job recipe module. | 5 """API for the perf try job recipe module. |
| 6 | 6 |
| 7 This API is meant to enable the perf try job recipe on any chromium-supported | 7 This API is meant to enable the perf try job recipe on 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 |
| 11 import re | 11 import re |
| 12 import urllib | 12 import urllib |
| 13 import uuid | |
| 13 | 14 |
| 14 from recipe_engine import recipe_api | 15 from recipe_engine import recipe_api |
| 16 from . import build_state | |
| 15 | 17 |
| 16 PERF_CONFIG_FILE = 'tools/run-perf-test.cfg' | 18 PERF_CONFIG_FILE = 'tools/run-perf-test.cfg' |
| 17 WEBKIT_PERF_CONFIG_FILE = 'third_party/WebKit/Tools/run-perf-test.cfg' | 19 WEBKIT_PERF_CONFIG_FILE = 'third_party/WebKit/Tools/run-perf-test.cfg' |
| 18 PERF_BENCHMARKS_PATH = 'tools/perf/benchmarks' | 20 PERF_BENCHMARKS_PATH = 'tools/perf/benchmarks' |
| 19 PERF_MEASUREMENTS_PATH = 'tools/perf/measurements' | 21 PERF_MEASUREMENTS_PATH = 'tools/perf/measurements' |
| 20 BUILDBOT_BUILDERNAME = 'BUILDBOT_BUILDERNAME' | 22 BUILDBOT_BUILDERNAME = 'BUILDBOT_BUILDERNAME' |
| 21 BENCHMARKS_JSON_FILE = 'benchmarks.json' | 23 BENCHMARKS_JSON_FILE = 'benchmarks.json' |
| 22 | 24 |
| 23 CLOUD_RESULTS_LINK = (r'\s(?P<VALUES>http://storage.googleapis.com/' | 25 CLOUD_RESULTS_LINK = (r'\s(?P<VALUES>http://storage.googleapis.com/' |
| 24 'chromium-telemetry/html-results/results-[a-z0-9-_]+)\s') | 26 'chromium-telemetry/html-results/results-[a-z0-9-_]+)\s') |
| 25 PROFILER_RESULTS_LINK = (r'\s(?P<VALUES>https://console.developers.google.com/' | 27 PROFILER_RESULTS_LINK = (r'\s(?P<VALUES>https://console.developers.google.com/' |
| 26 'm/cloudstorage/b/[a-z-]+/o/profiler-[a-z0-9-_.]+)\s') | 28 'm/cloudstorage/b/[a-z-]+/o/profiler-[a-z0-9-_.]+)\s') |
| 27 RESULTS_BANNER = """ | 29 RESULTS_BANNER = """ |
| 28 ===== PERF TRY JOB RESULTS ===== | 30 ===== PERF TRY JOB RESULTS ===== |
| 29 | 31 |
| 30 Test Command: %(command)s | 32 Test Command: %(command)s |
| 31 Test Metric: %(metric)s | 33 Test Metric: %(metric)s |
| 32 Relative Change: %(relative_change).05f%% | 34 Relative Change: %(relative_change).05f%% |
| 33 Standard Error: +- %(std_err).05f delta | 35 Standard Error: +- %(std_err).05f delta |
| 34 | 36 |
| 35 %(results)s | 37 %(results)s |
| 36 """ | 38 """ |
| 37 | 39 SERVICE_ACCOUNT = 'chromium_bisect' |
| 38 | 40 |
| 39 class PerfTryJobApi(recipe_api.RecipeApi): | 41 class PerfTryJobApi(recipe_api.RecipeApi): |
| 40 | 42 |
| 41 def __init__(self, *args, **kwargs): | 43 def __init__(self, *args, **kwargs): |
| 42 super(PerfTryJobApi, self).__init__(*args, **kwargs) | 44 super(PerfTryJobApi, self).__init__(*args, **kwargs) |
| 43 | 45 |
| 44 def start_perf_try_job(self, affected_files, bot_update_step, bot_db): | 46 def start_perf_try_job(self, affected_files, bot_update_step, bot_db): |
| 45 """Entry point pert tryjob or CQ tryjob.""" | 47 """Entry point pert tryjob or CQ tryjob.""" |
| 46 perf_config = self._get_perf_config(affected_files) | 48 perf_config = self._get_perf_config(affected_files) |
| 47 if perf_config: | 49 if perf_config: |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 209 overall_success = all(v == 0 for v in retcodes) | 211 overall_success = all(v == 0 for v in retcodes) |
| 210 return { | 212 return { |
| 211 'results': all_values, | 213 'results': all_values, |
| 212 'ret_code': overall_success, | 214 'ret_code': overall_success, |
| 213 'output': ''.join(overall_output) | 215 'output': ''.join(overall_output) |
| 214 } | 216 } |
| 215 | 217 |
| 216 def _build_and_run_tests(self, cfg, update_step, bot_db, revision, | 218 def _build_and_run_tests(self, cfg, update_step, bot_db, revision, |
| 217 **kwargs): | 219 **kwargs): |
| 218 """Compiles binaries and runs tests for a given a revision.""" | 220 """Compiles binaries and runs tests for a given a revision.""" |
| 221 with_patch = kwargs.get('name') == 'With Patch' | |
| 219 update_step = self._checkout_revision(update_step, bot_db, revision) | 222 update_step = self._checkout_revision(update_step, bot_db, revision) |
| 220 self._compile(kwargs['name'], self.m.properties['mastername'], | 223 revision = build_state.BuildState(self, revision, with_patch) |
| 221 self.m.properties['buildername'], update_step, bot_db) | 224 self._request_build(revision) |
| 222 | 225 self._wait_for(revision) |
| 226 self._download_build(update_step, bot_db, revision) | |
|
prasadv
2016/06/21 22:32:56
Also in the test expectation files, I don't see li
RobertoCN
2016/06/21 22:39:43
It doesn't seem from the expectations that we are
| |
| 223 if self.m.chromium.c.TARGET_PLATFORM == 'android': | 227 if self.m.chromium.c.TARGET_PLATFORM == 'android': |
| 224 self.m.chromium_android.adb_install_apk('ChromePublic.apk') | 228 self.m.chromium_android.adb_install_apk('ChromePublic.apk') |
| 225 | 229 |
| 226 return self._run_test(cfg, **kwargs) | 230 return self._run_test(cfg, **kwargs) |
| 227 | 231 |
| 232 # Duplicate code from auto_bisect.revision_state._request_build | |
| 233 def _request_build(self, revision): | |
| 234 bot_name = self.get_builder_bot_for_this_platform() | |
| 235 build_details = { | |
| 236 'bucket': 'master.' + self.m.properties['mastername'], | |
| 237 'parameters': { | |
| 238 'buildername': bot_name, | |
| 239 'properties': { | |
| 240 'parent_got_revision': revision.commit_hash, | |
|
prasadv
2016/06/21 22:32:56
How the builder know what to patch. Since we are j
Ziqi Xiong
2016/06/22 21:41:25
Done.
| |
| 241 'clobber': True, | |
| 242 'build_archive_url': revision.build_file_path | |
| 243 } | |
| 244 }, | |
| 245 'client_operation_id': uuid.uuid4().hex, | |
| 246 'tags':{} | |
| 247 } | |
| 248 result = self.m.buildbucket.put( | |
| 249 [build_details], | |
| 250 self.m.service_account.get_json_path(SERVICE_ACCOUNT)) | |
| 251 revision.build_id = result.stdout['results'][0]['build']['id'] | |
| 252 | |
| 253 | |
| 254 def _wait_for(self, revision): | |
| 255 while True: | |
| 256 if revision.is_completed(): | |
| 257 break | |
| 258 else: | |
| 259 self.m.python.inline( | |
| 260 'sleeping', | |
| 261 """ | |
| 262 import sys | |
| 263 import time | |
| 264 time.sleep(20*60) | |
| 265 sys.exit(0) | |
| 266 """) | |
| 267 | |
| 268 # Duplicate code from auto_bisect.api.start_test_run_for_bisect | |
| 269 def _download_build(self, update_step, bot_db, | |
| 270 revision, run_locally=False, | |
| 271 skip_download=False): | |
| 272 if not revision.build_archived: | |
|
RobertoCN
2016/06/21 22:39:43
This should be set by build_state.is_build_archive
prasadv
2016/06/21 23:11:04
This is the reason why we are not able to get othe
Ziqi Xiong
2016/06/22 21:41:25
Done.
Ziqi Xiong
2016/06/22 21:41:25
Done.
| |
| 273 raise self.m.step.StepFailure('Build %s fails' % revision.build_id) | |
| 274 mastername = self.m.properties.get('mastername') | |
| 275 buildername = self.m.properties.get('buildername') | |
| 276 bot_config = bot_db.get_bot_config(mastername, buildername) | |
| 277 build_archive_url = revision.build_file_path | |
| 278 if not skip_download: | |
| 279 if self.m.chromium.c.TARGET_PLATFORM == 'android': | |
| 280 # The best way to ensure the old build directory is not used is to | |
| 281 # remove it. | |
| 282 build_dir = self.m.chromium.c.build_dir.join( | |
| 283 self.m.chromium.c.build_config_fs) | |
| 284 self.m.file.rmtree('build directory', build_dir) | |
| 285 | |
| 286 # The way android builders on tryserver.chromium.perf are archived is | |
| 287 # different from builders on chromium.perf. In order to support both | |
| 288 # forms of archives, we added this temporary hack until builders are | |
| 289 # fixed. See http://crbug.com/535218. | |
| 290 zip_dir = self.m.path.join(self.m.path['checkout'], 'full-build-linux') | |
| 291 if self.m.path.exists(zip_dir): # pragma: no cover | |
| 292 self.m.file.rmtree('full-build-linux directory', zip_dir) | |
| 293 gs_bucket = 'gs://%s/' % revision.bucket | |
| 294 archive_path = build_archive_url[len(gs_bucket):] | |
| 295 self.m.chromium_android.download_build( | |
| 296 bucket=bot_config['bucket'], | |
| 297 path=archive_path) | |
| 298 | |
| 299 # The way android builders on tryserver.chromium.perf are archived is | |
| 300 # different from builders on chromium.perf. In order to support both | |
| 301 # forms of archives, we added this temporary hack until builders are | |
| 302 # fixed. See http://crbug.com/535218. | |
| 303 if self.m.path.exists(zip_dir): # pragma: no cover | |
| 304 self.m.python.inline( | |
| 305 'moving full-build-linux to out/Release', | |
| 306 """ | |
| 307 import shutil | |
| 308 import sys | |
| 309 shutil.move(sys.argv[1], sys.argv[2]) | |
| 310 """, | |
| 311 args=[zip_dir, build_dir]) | |
| 312 else: | |
| 313 self.m.chromium_tests.download_and_unzip_build( | |
| 314 mastername, buildername, update_step, bot_db, | |
| 315 build_archive_url=build_archive_url, | |
| 316 build_revision=revision.commit_hash, | |
| 317 override_bot_type='tester') | |
| 318 | |
| 319 # Duplicate code from auto_bisect.bisector.get_builder_bot_for_this_platform | |
| 320 def get_builder_bot_for_this_platform(self): | |
| 321 bot_name = self.m.properties.get('buildername', '') | |
| 322 if 'win' in bot_name: | |
| 323 if any(b in bot_name for b in ['x64', 'gpu']): | |
| 324 return 'winx64_bisect_builder' | |
| 325 return 'win_perf_bisect_builder' | |
| 326 | |
| 327 if 'android' in bot_name: | |
| 328 if 'nexus9' in bot_name: | |
| 329 return 'android_arm64_perf_bisect_builder' | |
| 330 return 'android_perf_bisect_builder' | |
| 331 | |
| 332 if 'mac' in bot_name: | |
| 333 return 'mac_perf_bisect_builder' | |
| 334 | |
| 335 return 'linux_perf_bisect_builder' | |
| 336 | |
| 228 def _load_config_file(self, name, src_path, **kwargs): | 337 def _load_config_file(self, name, src_path, **kwargs): |
| 229 """Attempts to load the specified config file and grab config dict.""" | 338 """Attempts to load the specified config file and grab config dict.""" |
| 230 step_result = self.m.python( | 339 step_result = self.m.python( |
| 231 name, | 340 name, |
| 232 self.resource('load_config_to_json.py'), | 341 self.resource('load_config_to_json.py'), |
| 233 ['--source', src_path, '--output_json', self.m.json.output()], | 342 ['--source', src_path, '--output_json', self.m.json.output()], |
| 234 **kwargs) | 343 **kwargs) |
| 235 if not step_result.json.output: # pragma: no cover | 344 if not step_result.json.output: # pragma: no cover |
| 236 raise self.m.step.StepFailure('Loading config file failed. [%s]' % | 345 raise self.m.step.StepFailure('Loading config file failed. [%s]' % |
| 237 src_path) | 346 src_path) |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 511 | 620 |
| 512 def _prepend_src_to_path_in_command(test_cfg): | 621 def _prepend_src_to_path_in_command(test_cfg): |
| 513 command_to_run = [] | 622 command_to_run = [] |
| 514 for v in test_cfg.get('command').split(): | 623 for v in test_cfg.get('command').split(): |
| 515 if v in ['./tools/perf/run_benchmark', | 624 if v in ['./tools/perf/run_benchmark', |
| 516 'tools/perf/run_benchmark', | 625 'tools/perf/run_benchmark', |
| 517 'tools\\perf\\run_benchmark']: | 626 'tools\\perf\\run_benchmark']: |
| 518 v = 'src/tools/perf/run_benchmark' | 627 v = 'src/tools/perf/run_benchmark' |
| 519 command_to_run.append(v) | 628 command_to_run.append(v) |
| 520 test_cfg.update({'command': ' '.join(command_to_run)}) | 629 test_cfg.update({'command': ' '.join(command_to_run)}) |
| OLD | NEW |