| OLD | NEW |
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 | 5 |
| 6 # pylint: disable=W0201 | 6 # pylint: disable=W0201 |
| 7 | 7 |
| 8 | 8 |
| 9 import json | 9 import json |
| 10 import os | 10 import os |
| 11 import re | 11 import re |
| 12 import sys | 12 import sys |
| 13 | 13 |
| 14 from recipe_engine import recipe_api | 14 from recipe_engine import recipe_api |
| 15 from recipe_engine import config_types | 15 from recipe_engine import config_types |
| 16 | 16 |
| 17 from . import android_flavor | |
| 18 from . import cmake_flavor | |
| 19 from . import coverage_flavor | |
| 20 from . import default_flavor | |
| 21 from . import fake_specs | 17 from . import fake_specs |
| 22 from . import gn_flavor | |
| 23 from . import ios_flavor | |
| 24 from . import pdfium_flavor | |
| 25 from . import valgrind_flavor | |
| 26 from . import xsan_flavor | |
| 27 | 18 |
| 28 | 19 |
| 29 BOTO_CHROMIUM_SKIA_GM = 'chromium-skia-gm.boto' | |
| 30 | |
| 31 GS_SUBDIR_TMPL_SK_IMAGE = 'skimage/v%s' | |
| 32 GS_SUBDIR_TMPL_SKP = 'playback_%s/skps' | |
| 33 | |
| 34 TEST_EXPECTED_SKP_VERSION = '42' | 20 TEST_EXPECTED_SKP_VERSION = '42' |
| 35 TEST_EXPECTED_SK_IMAGE_VERSION = '42' | 21 TEST_EXPECTED_SK_IMAGE_VERSION = '42' |
| 36 | 22 |
| 37 VERSION_FILE_SK_IMAGE = 'SK_IMAGE_VERSION' | 23 VERSION_FILE_SK_IMAGE = 'SK_IMAGE_VERSION' |
| 38 VERSION_FILE_SKP = 'SKP_VERSION' | 24 VERSION_FILE_SKP = 'SKP_VERSION' |
| 39 | 25 |
| 40 VERSION_NONE = -1 | 26 VERSION_NONE = -1 |
| 41 | 27 |
| 42 BUILD_PRODUCTS_ISOLATE_WHITELIST = [ | |
| 43 'dm', | |
| 44 'dm.exe', | |
| 45 'nanobench', | |
| 46 'nanobench.exe', | |
| 47 '*.so', | |
| 48 '*.dll', | |
| 49 '*.dylib', | |
| 50 'skia_launcher', | |
| 51 'lib/*.so', | |
| 52 'iOSShell.app', | |
| 53 'iOSShell.ipa', | |
| 54 'visualbench', | |
| 55 'visualbench.exe', | |
| 56 'vulkan-1.dll', | |
| 57 ] | |
| 58 | |
| 59 | |
| 60 def is_android(builder_cfg): | |
| 61 """Determine whether the given builder is an Android builder.""" | |
| 62 return ('Android' in builder_cfg.get('extra_config', '') or | |
| 63 builder_cfg.get('os') == 'Android') | |
| 64 | |
| 65 | |
| 66 def is_cmake(builder_cfg): | |
| 67 return 'CMake' in builder_cfg.get('extra_config', '') | |
| 68 | |
| 69 | |
| 70 def is_gn(builder_cfg): | |
| 71 return 'GN' == builder_cfg.get('extra_config', '') | |
| 72 | |
| 73 | |
| 74 def is_ios(builder_cfg): | |
| 75 return ('iOS' in builder_cfg.get('extra_config', '') or | |
| 76 builder_cfg.get('os') == 'iOS') | |
| 77 | |
| 78 | |
| 79 def is_pdfium(builder_cfg): | |
| 80 return 'PDFium' in builder_cfg.get('extra_config', '') | |
| 81 | |
| 82 | |
| 83 def is_valgrind(builder_cfg): | |
| 84 return 'Valgrind' in builder_cfg.get('extra_config', '') | |
| 85 | |
| 86 | |
| 87 def is_xsan(builder_cfg): | |
| 88 return ('ASAN' in builder_cfg.get('extra_config', '') or | |
| 89 'MSAN' in builder_cfg.get('extra_config', '') or | |
| 90 'TSAN' in builder_cfg.get('extra_config', '')) | |
| 91 | |
| 92 | 28 |
| 93 class SkiaApi(recipe_api.RecipeApi): | 29 class SkiaApi(recipe_api.RecipeApi): |
| 94 | 30 |
| 95 def get_flavor(self, builder_cfg): | |
| 96 """Return a flavor utils object specific to the given builder.""" | |
| 97 if is_android(builder_cfg): | |
| 98 return android_flavor.AndroidFlavorUtils(self) | |
| 99 elif is_cmake(builder_cfg): | |
| 100 return cmake_flavor.CMakeFlavorUtils(self) | |
| 101 elif is_gn(builder_cfg): | |
| 102 return gn_flavor.GNFlavorUtils(self) | |
| 103 elif is_ios(builder_cfg): | |
| 104 return ios_flavor.iOSFlavorUtils(self) | |
| 105 elif is_pdfium(builder_cfg): | |
| 106 return pdfium_flavor.PDFiumFlavorUtils(self) | |
| 107 elif is_valgrind(builder_cfg): | |
| 108 return valgrind_flavor.ValgrindFlavorUtils(self) | |
| 109 elif is_xsan(builder_cfg): | |
| 110 return xsan_flavor.XSanFlavorUtils(self) | |
| 111 elif builder_cfg.get('configuration') == 'Coverage': | |
| 112 return coverage_flavor.CoverageFlavorUtils(self) | |
| 113 else: | |
| 114 return default_flavor.DefaultFlavorUtils(self) | |
| 115 | |
| 116 @property | |
| 117 def home_dir(self): | |
| 118 """Find the home directory.""" | |
| 119 home_dir = os.path.expanduser('~') | |
| 120 if self._test_data.enabled: | |
| 121 home_dir = '[HOME]' | |
| 122 return home_dir | |
| 123 | |
| 124 def gsutil_env(self, boto_file): | |
| 125 """Environment variables for gsutil.""" | |
| 126 boto_path = None | |
| 127 if boto_file: | |
| 128 boto_path = self.m.path.join(self.home_dir, boto_file) | |
| 129 return {'AWS_CREDENTIAL_FILE': boto_path, | |
| 130 'BOTO_CONFIG': boto_path} | |
| 131 | |
| 132 def get_builder_spec(self, skia_dir, builder_name): | 31 def get_builder_spec(self, skia_dir, builder_name): |
| 133 """Obtain the buildbot spec for the given builder.""" | 32 """Obtain the buildbot spec for the given builder.""" |
| 134 fake_spec = None | 33 fake_spec = None |
| 135 if self._test_data.enabled: | 34 if self._test_data.enabled: |
| 136 fake_spec = fake_specs.FAKE_SPECS[builder_name] | 35 fake_spec = fake_specs.FAKE_SPECS[builder_name] |
| 137 builder_spec = self.json_from_file( | 36 builder_spec = self.m.run.json_from_file( |
| 138 skia_dir.join('tools', 'buildbot_spec.py'), | 37 skia_dir.join('tools', 'buildbot_spec.py'), |
| 139 skia_dir, | 38 skia_dir, |
| 140 builder_name, | 39 builder_name, |
| 141 fake_spec) | 40 fake_spec) |
| 142 return builder_spec | 41 return builder_spec |
| 143 | 42 |
| 144 def make_path(self, *path): | |
| 145 """Return a Path object for the given path.""" | |
| 146 key = 'custom_%s' % '_'.join(path) | |
| 147 self.m.path.c.base_paths[key] = tuple(path) | |
| 148 return self.m.path[key] | |
| 149 | |
| 150 def setup(self): | 43 def setup(self): |
| 151 """Prepare the bot to run.""" | 44 """Prepare the bot to run.""" |
| 152 # Setup | 45 # Setup dependencies. |
| 153 self.failed = [] | 46 self.m.vars.setup() |
| 154 | 47 self.m.run.setup() |
| 155 self.builder_name = self.m.properties['buildername'] | |
| 156 self.master_name = self.m.properties['mastername'] | |
| 157 self.slave_name = self.m.properties['slavename'] | |
| 158 | |
| 159 self.slave_dir = self.m.path['slave_build'] | |
| 160 self.checkout_root = self.slave_dir | |
| 161 self.default_env = {} | |
| 162 self.gclient_env = {} | |
| 163 self.is_compile_bot = self.builder_name.startswith('Build-') | |
| 164 | |
| 165 self.default_env['CHROME_HEADLESS'] = '1' | |
| 166 # The 'depot_tools' directory comes from recipe DEPS and isn't provided by | |
| 167 # default. We have to set it manually. | |
| 168 self.m.path.c.base_paths['depot_tools'] = ( | |
| 169 self.m.path.c.base_paths['slave_build'] + | |
| 170 ('skia', 'infra', 'bots', '.recipe_deps', 'depot_tools')) | |
| 171 if 'Win' in self.builder_name: | |
| 172 self.m.path.c.base_paths['depot_tools'] = ( | |
| 173 'c:\\', 'Users', 'chrome-bot', 'depot_tools') | |
| 174 | |
| 175 # Compile bots keep a persistent checkout. | |
| 176 self.persistent_checkout = (self.is_compile_bot or | |
| 177 'RecreateSKPs' in self.builder_name) | |
| 178 if self.persistent_checkout: | |
| 179 if 'Win' in self.builder_name: | |
| 180 self.checkout_root = self.make_path('C:\\', 'b', 'work') | |
| 181 self.gclient_cache = self.make_path('C:\\', 'b', 'cache') | |
| 182 else: | |
| 183 self.checkout_root = self.make_path('/', 'b', 'work') | |
| 184 self.gclient_cache = self.make_path('/', 'b', 'cache') | |
| 185 | |
| 186 self.skia_dir = self.checkout_root.join('skia') | |
| 187 self.infrabots_dir = self.skia_dir.join('infra', 'bots') | |
| 188 | |
| 189 # Some bots also require a checkout of chromium. | |
| 190 self._need_chromium_checkout = 'CommandBuffer' in self.builder_name | |
| 191 if 'CommandBuffer' in self.builder_name: | |
| 192 self.gclient_env['GYP_CHROMIUM_NO_ACTION'] = '0' | |
| 193 if ((self.is_compile_bot and | |
| 194 'SAN' in self.builder_name) or | |
| 195 'RecreateSKPs' in self.builder_name): | |
| 196 self._need_chromium_checkout = True | |
| 197 if 'RecreateSKPs' in self.builder_name: | |
| 198 self.gclient_env['CPPFLAGS'] = ( | |
| 199 '-DSK_ALLOW_CROSSPROCESS_PICTUREIMAGEFILTERS=1') | |
| 200 | |
| 201 # Some bots also require a checkout of PDFium. | |
| 202 self._need_pdfium_checkout = 'PDFium' in self.builder_name | |
| 203 | 48 |
| 204 # Check out the Skia code. | 49 # Check out the Skia code. |
| 205 self.checkout_steps() | 50 self.checkout_steps() |
| 206 | 51 |
| 207 # Obtain the spec for this builder from the Skia repo. Use it to set more | 52 # Obtain the spec for this builder from the Skia repo. Use it to set more |
| 208 # properties. | 53 # properties. |
| 209 self.builder_spec = self.get_builder_spec(self.skia_dir, self.builder_name) | 54 builder_spec = self.get_builder_spec(self.m.vars.skia_dir, |
| 55 self.m.vars.builder_name) |
| 210 | 56 |
| 211 self.builder_cfg = self.builder_spec['builder_cfg'] | 57 # Continue setting up vars with the builder_spec. |
| 212 self.role = self.builder_cfg['role'] | 58 self.m.vars.update_with_builder_spec(builder_spec) |
| 213 | 59 |
| 214 # Set some important variables. | 60 |
| 215 self.resource_dir = self.skia_dir.join('resources') | 61 if not self.m.path.exists(self.m.vars.tmp_dir): |
| 216 self.images_dir = self.slave_dir.join('skimage') | 62 self.m.run.run_once(self.m.file.makedirs, |
| 217 if not self.m.path.exists(self.infrabots_dir.join( | 63 'tmp_dir', |
| 218 'assets', 'skimage', 'VERSION')): | 64 self.m.vars.tmp_dir, |
| 219 # TODO(borenet): Remove this once enough time has passed. | 65 infra_step=True) |
| 220 self.images_dir = self.slave_dir.join('images') | |
| 221 self.skia_out = self.skia_dir.join('out', self.builder_name) | |
| 222 self.swarming_out_dir = self.make_path(self.m.properties['swarm_out_dir']) | |
| 223 self.local_skp_dir = self.slave_dir.join('skp') | |
| 224 if not self.m.path.exists(self.infrabots_dir.join( | |
| 225 'assets', 'skp', 'VERSION')): | |
| 226 # TODO(borenet): Remove this once enough time has passed. | |
| 227 self.local_skp_dir = self.slave_dir.join('skps') | |
| 228 if not self.is_compile_bot: | |
| 229 self.skia_out = self.slave_dir.join('out') | |
| 230 self.tmp_dir = self.m.path['slave_build'].join('tmp') | |
| 231 if not self.m.path.exists(self.tmp_dir): | |
| 232 self._run_once(self.m.file.makedirs, | |
| 233 'tmp_dir', | |
| 234 self.tmp_dir, | |
| 235 infra_step=True) | |
| 236 | 66 |
| 237 self.gsutil_env_chromium_skia_gm = self.gsutil_env(BOTO_CHROMIUM_SKIA_GM) | 67 self.m.flavor.setup() |
| 238 | |
| 239 self.device_dirs = None | |
| 240 self._ccache = None | |
| 241 self._checked_for_ccache = False | |
| 242 self.configuration = self.builder_spec['configuration'] | |
| 243 self.default_env.update({'SKIA_OUT': self.skia_out, | |
| 244 'BUILDTYPE': self.configuration}) | |
| 245 self.default_env.update(self.builder_spec['env']) | |
| 246 self.build_targets = [str(t) for t in self.builder_spec['build_targets']] | |
| 247 self.do_compile_steps = self.builder_spec.get('do_compile_steps', True) | |
| 248 self.do_test_steps = self.builder_spec['do_test_steps'] | |
| 249 self.do_perf_steps = self.builder_spec['do_perf_steps'] | |
| 250 self.is_trybot = self.builder_cfg['is_trybot'] | |
| 251 self.upload_dm_results = self.builder_spec['upload_dm_results'] | |
| 252 self.upload_perf_results = self.builder_spec['upload_perf_results'] | |
| 253 self.dm_dir = self.m.path.join( | |
| 254 self.swarming_out_dir, 'dm') | |
| 255 self.perf_data_dir = self.m.path.join(self.swarming_out_dir, | |
| 256 'perfdata', self.builder_name, 'data') | |
| 257 self.dm_flags = self.builder_spec['dm_flags'] | |
| 258 self.nanobench_flags = self.builder_spec['nanobench_flags'] | |
| 259 | |
| 260 self.flavor = self.get_flavor(self.builder_cfg) | |
| 261 | |
| 262 def check_failure(self): | |
| 263 """Raise an exception if any step failed.""" | |
| 264 if self.failed: | |
| 265 raise self.m.step.StepFailure('Failed build steps: %s' % | |
| 266 ', '.join([f.name for f in self.failed])) | |
| 267 | |
| 268 def _run_once(self, fn, *args, **kwargs): | |
| 269 if not hasattr(self, '_already_ran'): | |
| 270 self._already_ran = {} | |
| 271 if not fn.__name__ in self._already_ran: | |
| 272 self._already_ran[fn.__name__] = fn(*args, **kwargs) | |
| 273 return self._already_ran[fn.__name__] | |
| 274 | 68 |
| 275 def update_repo(self, parent_dir, repo): | 69 def update_repo(self, parent_dir, repo): |
| 276 """Update an existing repo. This is safe to call without gen_steps.""" | 70 """Update an existing repo. This is safe to call without gen_steps.""" |
| 277 repo_path = parent_dir.join(repo.name) | 71 repo_path = parent_dir.join(repo.name) |
| 278 if self.m.path.exists(repo_path): # pragma: nocover | 72 if self.m.path.exists(repo_path): # pragma: nocover |
| 279 if self.m.platform.is_win: | 73 if self.m.platform.is_win: |
| 280 git = 'git.bat' | 74 git = 'git.bat' |
| 281 else: | 75 else: |
| 282 git = 'git' | 76 git = 'git' |
| 283 self.m.step('git remote set-url', | 77 self.m.step('git remote set-url', |
| 284 cmd=[git, 'remote', 'set-url', 'origin', repo.url], | 78 cmd=[git, 'remote', 'set-url', 'origin', repo.url], |
| 285 cwd=repo_path, | 79 cwd=repo_path, |
| 286 infra_step=True) | 80 infra_step=True) |
| 287 self.m.step('git fetch', | 81 self.m.step('git fetch', |
| 288 cmd=[git, 'fetch'], | 82 cmd=[git, 'fetch'], |
| 289 cwd=repo_path, | 83 cwd=repo_path, |
| 290 infra_step=True) | 84 infra_step=True) |
| 291 self.m.step('git reset', | 85 self.m.step('git reset', |
| 292 cmd=[git, 'reset', '--hard', repo.revision], | 86 cmd=[git, 'reset', '--hard', repo.revision], |
| 293 cwd=repo_path, | 87 cwd=repo_path, |
| 294 infra_step=True) | 88 infra_step=True) |
| 295 self.m.step('git clean', | 89 self.m.step('git clean', |
| 296 cmd=[git, 'clean', '-d', '-f'], | 90 cmd=[git, 'clean', '-d', '-f'], |
| 297 cwd=repo_path, | 91 cwd=repo_path, |
| 298 infra_step=True) | 92 infra_step=True) |
| 299 | 93 |
| 300 def checkout_steps(self): | 94 def checkout_steps(self): |
| 301 """Run the steps to obtain a checkout of Skia.""" | 95 """Run the steps to obtain a checkout of Skia.""" |
| 302 cfg_kwargs = {} | 96 cfg_kwargs = {} |
| 303 if not self.persistent_checkout: | 97 if not self.m.vars.persistent_checkout: |
| 304 # We should've obtained the Skia checkout through isolates, so we don't | 98 # We should've obtained the Skia checkout through isolates, so we don't |
| 305 # need to perform the checkout ourselves. | 99 # need to perform the checkout ourselves. |
| 306 self.m.path['checkout'] = self.skia_dir | |
| 307 self.got_revision = self.m.properties['revision'] | |
| 308 return | 100 return |
| 309 | 101 |
| 310 # Use a persistent gclient cache for Swarming. | 102 # Use a persistent gclient cache for Swarming. |
| 311 cfg_kwargs['CACHE_DIR'] = self.gclient_cache | 103 cfg_kwargs['CACHE_DIR'] = self.m.vars.gclient_cache |
| 312 | 104 |
| 313 # Create the checkout path if necessary. | 105 # Create the checkout path if necessary. |
| 314 if not self.m.path.exists(self.checkout_root): | 106 if not self.m.path.exists(self.m.vars.checkout_root): |
| 315 self.m.file.makedirs('checkout_path', self.checkout_root, infra_step=True) | 107 self.m.file.makedirs('checkout_path', |
| 108 self.m.vars.checkout_root, |
| 109 infra_step=True) |
| 316 | 110 |
| 317 # Initial cleanup. | 111 # Initial cleanup. |
| 318 gclient_cfg = self.m.gclient.make_config(**cfg_kwargs) | 112 gclient_cfg = self.m.gclient.make_config(**cfg_kwargs) |
| 319 skia = gclient_cfg.solutions.add() | 113 skia = gclient_cfg.solutions.add() |
| 320 skia.name = 'skia' | 114 skia.name = 'skia' |
| 321 skia.managed = False | 115 skia.managed = False |
| 322 skia.url = 'https://skia.googlesource.com/skia.git' | 116 skia.url = 'https://skia.googlesource.com/skia.git' |
| 323 skia.revision = self.m.properties.get('revision') or 'origin/master' | 117 skia.revision = self.m.properties.get('revision') or 'origin/master' |
| 324 self.update_repo(self.checkout_root, skia) | 118 self.update_repo(self.m.vars.checkout_root, skia) |
| 325 | 119 |
| 326 # TODO(rmistry): Remove the below block after there is a solution for | 120 # TODO(rmistry): Remove the below block after there is a solution for |
| 327 # crbug.com/616443 | 121 # crbug.com/616443 |
| 328 entries_file = self.checkout_root.join('.gclient_entries') | 122 entries_file = self.m.vars.checkout_root.join('.gclient_entries') |
| 329 if self.m.path.exists(entries_file): | 123 if self.m.path.exists(entries_file): |
| 330 self.m.file.remove('remove %s' % entries_file, | 124 self.m.file.remove('remove %s' % entries_file, |
| 331 entries_file, | 125 entries_file, |
| 332 infra_step=True) # pragma: no cover | 126 infra_step=True) # pragma: no cover |
| 333 | 127 |
| 334 if self._need_chromium_checkout: | 128 if self.m.vars.need_chromium_checkout: |
| 335 chromium = gclient_cfg.solutions.add() | 129 chromium = gclient_cfg.solutions.add() |
| 336 chromium.name = 'src' | 130 chromium.name = 'src' |
| 337 chromium.managed = False | 131 chromium.managed = False |
| 338 chromium.url = 'https://chromium.googlesource.com/chromium/src.git' | 132 chromium.url = 'https://chromium.googlesource.com/chromium/src.git' |
| 339 chromium.revision = 'origin/lkgr' | 133 chromium.revision = 'origin/lkgr' |
| 340 self.update_repo(self.checkout_root, chromium) | 134 self.update_repo(self.m.vars.checkout_root, chromium) |
| 341 | 135 |
| 342 if self._need_pdfium_checkout: | 136 if self.m.vars.need_pdfium_checkout: |
| 343 pdfium = gclient_cfg.solutions.add() | 137 pdfium = gclient_cfg.solutions.add() |
| 344 pdfium.name = 'pdfium' | 138 pdfium.name = 'pdfium' |
| 345 pdfium.managed = False | 139 pdfium.managed = False |
| 346 pdfium.url = 'https://pdfium.googlesource.com/pdfium.git' | 140 pdfium.url = 'https://pdfium.googlesource.com/pdfium.git' |
| 347 pdfium.revision = 'origin/master' | 141 pdfium.revision = 'origin/master' |
| 348 self.update_repo(self.checkout_root, pdfium) | 142 self.update_repo(self.m.vars.checkout_root, pdfium) |
| 349 | 143 |
| 350 # Run 'gclient sync'. | 144 # Run 'gclient sync'. |
| 351 gclient_cfg.got_revision_mapping['skia'] = 'got_revision' | 145 gclient_cfg.got_revision_mapping['skia'] = 'got_revision' |
| 352 gclient_cfg.target_os.add('llvm') | 146 gclient_cfg.target_os.add('llvm') |
| 353 checkout_kwargs = {} | 147 checkout_kwargs = {} |
| 354 checkout_kwargs['env'] = self.default_env | 148 checkout_kwargs['env'] = self.m.vars.default_env |
| 355 | 149 |
| 356 # api.gclient.revert() assumes things about the layout of the code, so it | 150 # api.gclient.revert() assumes things about the layout of the code, so it |
| 357 # fails for us. Run an appropriate revert sequence for trybots instead. | 151 # fails for us. Run an appropriate revert sequence for trybots instead. |
| 358 gclient_file = self.checkout_root.join('.gclient') | 152 gclient_file = self.m.vars.checkout_root.join('.gclient') |
| 359 if (self.m.tryserver.is_tryserver and | 153 if (self.m.tryserver.is_tryserver and |
| 360 self.m.path.exists(gclient_file)): # pragma: no cover | 154 self.m.path.exists(gclient_file)): # pragma: no cover |
| 361 # These steps taken from: | 155 # These steps taken from: |
| 362 # https://chromium.googlesource.com/chromium/tools/build/+/ | 156 # https://chromium.googlesource.com/chromium/tools/build/+/ |
| 363 # 81a696760ab7c25f6606c54fc781b90b8af9fdd2/scripts/slave/ | 157 # 81a696760ab7c25f6606c54fc781b90b8af9fdd2/scripts/slave/ |
| 364 # gclient_safe_revert.py | 158 # gclient_safe_revert.py |
| 365 if self.m.path.exists(entries_file): | 159 if self.m.path.exists(entries_file): |
| 366 self.m.gclient('recurse', [ | 160 self.m.gclient('recurse', [ |
| 367 'recurse', '-i', 'sh', '-c', | 161 'recurse', '-i', 'sh', '-c', |
| 368 'if [ -e .git ]; then git remote update; fi']) | 162 'if [ -e .git ]; then git remote update; fi']) |
| 369 self.m.gclient( | 163 self.m.gclient( |
| 370 'revert', | 164 'revert', |
| 371 ['revert', '-v', '-v', '-v', '--nohooks', '--upstream'], | 165 ['revert', '-v', '-v', '-v', '--nohooks', '--upstream'], |
| 372 cwd=self.checkout_root) | 166 cwd=self.m.vars.checkout_root) |
| 373 | 167 |
| 374 update_step = self.m.gclient.checkout(gclient_config=gclient_cfg, | 168 update_step = self.m.gclient.checkout(gclient_config=gclient_cfg, |
| 375 cwd=self.checkout_root, | 169 cwd=self.m.vars.checkout_root, |
| 376 revert=False, | 170 revert=False, |
| 377 **checkout_kwargs) | 171 **checkout_kwargs) |
| 378 | 172 |
| 379 self.got_revision = update_step.presentation.properties['got_revision'] | 173 self.m.vars.got_revision = ( |
| 174 update_step.presentation.properties['got_revision']) |
| 380 self.m.tryserver.maybe_apply_issue() | 175 self.m.tryserver.maybe_apply_issue() |
| 381 | 176 |
| 382 if self._need_chromium_checkout: | 177 if self.m.vars.need_chromium_checkout: |
| 383 self.m.gclient.runhooks(cwd=self.checkout_root, env=self.gclient_env) | 178 self.m.gclient.runhooks(cwd=self.m.vars.checkout_root, |
| 384 | 179 env=self.m.vars.gclient_env) |
| 385 def copy_build_products(self, src, dst): | |
| 386 """Copy whitelisted build products from src to dst.""" | |
| 387 self.m.python.inline( | |
| 388 name='copy build products', | |
| 389 program='''import errno | |
| 390 import glob | |
| 391 import os | |
| 392 import shutil | |
| 393 import sys | |
| 394 | |
| 395 src = sys.argv[1] | |
| 396 dst = sys.argv[2] | |
| 397 build_products_whitelist = %s | |
| 398 | |
| 399 try: | |
| 400 os.makedirs(dst) | |
| 401 except OSError as e: | |
| 402 if e.errno != errno.EEXIST: | |
| 403 raise | |
| 404 | |
| 405 for pattern in build_products_whitelist: | |
| 406 path = os.path.join(src, pattern) | |
| 407 for f in glob.glob(path): | |
| 408 dst_path = os.path.join(dst, os.path.relpath(f, src)) | |
| 409 if not os.path.isdir(os.path.dirname(dst_path)): | |
| 410 os.makedirs(os.path.dirname(dst_path)) | |
| 411 print 'Copying build product %%s to %%s' %% (f, dst_path) | |
| 412 shutil.move(f, dst_path) | |
| 413 ''' % str(BUILD_PRODUCTS_ISOLATE_WHITELIST), | |
| 414 args=[src, dst], | |
| 415 infra_step=True) | |
| 416 | |
| 417 def compile_steps(self, clobber=False): | |
| 418 """Run the steps to build Skia.""" | |
| 419 try: | |
| 420 for target in self.build_targets: | |
| 421 self.flavor.compile(target) | |
| 422 self.copy_build_products( | |
| 423 self.flavor.out_dir, | |
| 424 self.swarming_out_dir.join('out', self.configuration)) | |
| 425 self.flavor.copy_extra_build_products(self.swarming_out_dir) | |
| 426 finally: | |
| 427 if 'Win' in self.builder_cfg.get('os', ''): | |
| 428 self.m.python.inline( | |
| 429 name='cleanup', | |
| 430 program='''import psutil | |
| 431 for p in psutil.process_iter(): | |
| 432 try: | |
| 433 if p.name in ('mspdbsrv.exe', 'vctip.exe', 'cl.exe', 'link.exe'): | |
| 434 p.kill() | |
| 435 except psutil._error.AccessDenied: | |
| 436 pass | |
| 437 ''', | |
| 438 infra_step=True) | |
| 439 | |
| 440 def _readfile(self, filename, *args, **kwargs): | |
| 441 """Convenience function for reading files.""" | |
| 442 name = kwargs.pop('name') or 'read %s' % self.m.path.basename(filename) | |
| 443 return self.m.file.read(name, filename, infra_step=True, *args, **kwargs) | |
| 444 | |
| 445 def _writefile(self, filename, contents): | |
| 446 """Convenience function for writing files.""" | |
| 447 return self.m.file.write('write %s' % self.m.path.basename(filename), | |
| 448 filename, contents, infra_step=True) | |
| 449 | |
| 450 def rmtree(self, path): | |
| 451 """Wrapper around api.file.rmtree with environment fix.""" | |
| 452 env = {} | |
| 453 env['PYTHONPATH'] = str(self.m.path['checkout'].join( | |
| 454 'infra', 'bots', '.recipe_deps', 'build', 'scripts')) | |
| 455 self.m.file.rmtree(self.m.path.basename(path), | |
| 456 path, | |
| 457 env=env, | |
| 458 infra_step=True) | |
| 459 | |
| 460 def run(self, steptype, name, abort_on_failure=True, | |
| 461 fail_build_on_failure=True, env=None, **kwargs): | |
| 462 """Run a step. If it fails, keep going but mark the build status failed.""" | |
| 463 env = dict(env or {}) | |
| 464 env.update(self.default_env) | |
| 465 try: | |
| 466 return steptype(name=name, env=env, **kwargs) | |
| 467 except self.m.step.StepFailure as e: | |
| 468 if abort_on_failure: | |
| 469 raise # pragma: no cover | |
| 470 if fail_build_on_failure: | |
| 471 self.failed.append(e) | |
| 472 | |
| 473 def check_actual_version(self, version_file, tmp_dir, test_actual_version): | |
| 474 """Assert that we have an actually-downloaded version of the dir.""" | |
| 475 actual_version_file = self.m.path.join(tmp_dir, version_file) | |
| 476 actual_version = self._readfile( | |
| 477 actual_version_file, | |
| 478 name='Get downloaded %s' % version_file, | |
| 479 test_data=test_actual_version).rstrip() | |
| 480 assert actual_version != VERSION_NONE | |
| 481 return actual_version | |
| 482 | 180 |
| 483 def copy_dir(self, host_version, version_file, tmp_dir, | 181 def copy_dir(self, host_version, version_file, tmp_dir, |
| 484 host_path, device_path, test_expected_version, | 182 host_path, device_path, test_expected_version, |
| 485 test_actual_version): | 183 test_actual_version): |
| 486 actual_version_file = self.m.path.join(tmp_dir, version_file) | 184 actual_version_file = self.m.path.join(tmp_dir, version_file) |
| 487 # Copy to device. | 185 # Copy to device. |
| 488 device_version_file = self.flavor.device_path_join( | 186 device_version_file = self.m.flavor.device_path_join( |
| 489 self.device_dirs.tmp_dir, version_file) | 187 self.m.flavor.device_dirs.tmp_dir, version_file) |
| 490 if str(actual_version_file) != str(device_version_file): | 188 if str(actual_version_file) != str(device_version_file): |
| 491 try: | 189 try: |
| 492 device_version = self.flavor.read_file_on_device(device_version_file) | 190 device_version = ( |
| 191 self.m.flavor.read_file_on_device(device_version_file)) |
| 493 except self.m.step.StepFailure: | 192 except self.m.step.StepFailure: |
| 494 device_version = VERSION_NONE | 193 device_version = VERSION_NONE |
| 495 if device_version != host_version: | 194 if device_version != host_version: |
| 496 self.flavor.remove_file_on_device(device_version_file) | 195 self.m.flavor.remove_file_on_device(device_version_file) |
| 497 self.flavor.create_clean_device_dir(device_path) | 196 self.m.flavor.create_clean_device_dir(device_path) |
| 498 self.flavor.copy_directory_contents_to_device(host_path, device_path) | 197 self.m.flavor.copy_directory_contents_to_device( |
| 198 host_path, device_path) |
| 499 | 199 |
| 500 # Copy the new version file. | 200 # Copy the new version file. |
| 501 self.flavor.copy_file_to_device(actual_version_file, | 201 self.m.flavor.copy_file_to_device(actual_version_file, |
| 502 device_version_file) | 202 device_version_file) |
| 503 | 203 |
| 504 def _copy_images(self): | 204 def _copy_images(self): |
| 505 """Download and copy test images if needed.""" | 205 """Download and copy test images if needed.""" |
| 506 version_file = self.infrabots_dir.join('assets', 'skimage', 'VERSION') | 206 version_file = self.m.vars.infrabots_dir.join( |
| 507 if self.m.path.exists(version_file): | 207 'assets', 'skimage', 'VERSION') |
| 508 test_data = self.m.properties.get( | 208 test_data = self.m.properties.get( |
| 509 'test_downloaded_sk_image_version', TEST_EXPECTED_SK_IMAGE_VERSION) | 209 'test_downloaded_sk_image_version', TEST_EXPECTED_SK_IMAGE_VERSION) |
| 510 version = self._readfile(version_file, | 210 version = self.m.run.readfile( |
| 511 name='Get downloaded skimage VERSION', | 211 version_file, |
| 512 test_data=test_data).rstrip() | 212 name='Get downloaded skimage VERSION', |
| 513 self._writefile(self.m.path.join(self.tmp_dir, VERSION_FILE_SK_IMAGE), | 213 test_data=test_data).rstrip() |
| 514 version) | 214 self.m.run.writefile( |
| 515 else: | 215 self.m.path.join(self.m.vars.tmp_dir, VERSION_FILE_SK_IMAGE), |
| 516 # TODO(borenet): Remove this once enough time has passed. | 216 version) |
| 517 version = self.check_actual_version( | |
| 518 VERSION_FILE_SK_IMAGE, | |
| 519 self.tmp_dir, | |
| 520 test_actual_version=self.m.properties.get( | |
| 521 'test_downloaded_sk_image_version', | |
| 522 TEST_EXPECTED_SK_IMAGE_VERSION), | |
| 523 ) | |
| 524 self.copy_dir( | 217 self.copy_dir( |
| 525 version, | 218 version, |
| 526 VERSION_FILE_SK_IMAGE, | 219 VERSION_FILE_SK_IMAGE, |
| 527 self.tmp_dir, | 220 self.m.vars.tmp_dir, |
| 528 self.images_dir, | 221 self.m.vars.images_dir, |
| 529 self.device_dirs.images_dir, | 222 self.m.flavor.device_dirs.images_dir, |
| 530 test_expected_version=self.m.properties.get( | 223 test_expected_version=self.m.properties.get( |
| 531 'test_downloaded_sk_image_version', | 224 'test_downloaded_sk_image_version', |
| 532 TEST_EXPECTED_SK_IMAGE_VERSION), | 225 TEST_EXPECTED_SK_IMAGE_VERSION), |
| 533 test_actual_version=self.m.properties.get( | 226 test_actual_version=self.m.properties.get( |
| 534 'test_downloaded_sk_image_version', | 227 'test_downloaded_sk_image_version', |
| 535 TEST_EXPECTED_SK_IMAGE_VERSION)) | 228 TEST_EXPECTED_SK_IMAGE_VERSION)) |
| 536 return version | 229 return version |
| 537 | 230 |
| 538 def _copy_skps(self): | 231 def _copy_skps(self): |
| 539 """Download and copy the SKPs if needed.""" | 232 """Download and copy the SKPs if needed.""" |
| 540 version_file = self.infrabots_dir.join('assets', 'skp', 'VERSION') | 233 version_file = self.m.vars.infrabots_dir.join( |
| 541 if self.m.path.exists(version_file): | 234 'assets', 'skp', 'VERSION') |
| 542 test_data = self.m.properties.get( | 235 test_data = self.m.properties.get( |
| 543 'test_downloaded_skp_version', TEST_EXPECTED_SKP_VERSION) | 236 'test_downloaded_skp_version', TEST_EXPECTED_SKP_VERSION) |
| 544 version = self._readfile(version_file, | 237 version = self.m.run.readfile( |
| 545 name='Get downloaded SKP VERSION', | 238 version_file, |
| 546 test_data=test_data).rstrip() | 239 name='Get downloaded SKP VERSION', |
| 547 self._writefile(self.m.path.join(self.tmp_dir, VERSION_FILE_SKP), version) | 240 test_data=test_data).rstrip() |
| 548 else: | 241 self.m.run.writefile( |
| 549 # TODO(borenet): Remove this once enough time has passed. | 242 self.m.path.join(self.m.vars.tmp_dir, VERSION_FILE_SKP), |
| 550 version = self.check_actual_version( | 243 version) |
| 551 VERSION_FILE_SKP, | |
| 552 self.tmp_dir, | |
| 553 test_actual_version=self.m.properties.get( | |
| 554 'test_downloaded_skp_version', | |
| 555 TEST_EXPECTED_SKP_VERSION), | |
| 556 ) | |
| 557 self.copy_dir( | 244 self.copy_dir( |
| 558 version, | 245 version, |
| 559 VERSION_FILE_SKP, | 246 VERSION_FILE_SKP, |
| 560 self.tmp_dir, | 247 self.m.vars.tmp_dir, |
| 561 self.local_skp_dir, | 248 self.m.vars.local_skp_dir, |
| 562 self.device_dirs.skp_dir, | 249 self.m.flavor.device_dirs.skp_dir, |
| 563 test_expected_version=self.m.properties.get( | 250 test_expected_version=self.m.properties.get( |
| 564 'test_downloaded_skp_version', TEST_EXPECTED_SKP_VERSION), | 251 'test_downloaded_skp_version', TEST_EXPECTED_SKP_VERSION), |
| 565 test_actual_version=self.m.properties.get( | 252 test_actual_version=self.m.properties.get( |
| 566 'test_downloaded_skp_version', TEST_EXPECTED_SKP_VERSION)) | 253 'test_downloaded_skp_version', TEST_EXPECTED_SKP_VERSION)) |
| 567 return version | 254 return version |
| 568 | 255 |
| 569 def install(self): | 256 def install(self): |
| 570 """Copy the required executables and files to the device.""" | 257 """Copy the required executables and files to the device.""" |
| 571 self.device_dirs = self.flavor.get_device_dirs() | |
| 572 | |
| 573 # Run any device-specific installation. | 258 # Run any device-specific installation. |
| 574 self.flavor.install() | 259 self.m.flavor.install() |
| 575 | 260 |
| 576 # TODO(borenet): Only copy files which have changed. | 261 # TODO(borenet): Only copy files which have changed. |
| 577 # Resources | 262 # Resources |
| 578 self.flavor.copy_directory_contents_to_device(self.resource_dir, | 263 self.m.flavor.copy_directory_contents_to_device( |
| 579 self.device_dirs.resource_dir) | 264 self.m.vars.resource_dir, |
| 580 | 265 self.m.flavor.device_dirs.resource_dir) |
| 581 def ccache(self): | |
| 582 if not self._checked_for_ccache: | |
| 583 self._checked_for_ccache = True | |
| 584 if not self.m.platform.is_win: | |
| 585 result = self.run( | |
| 586 self.m.python.inline, | |
| 587 name='has ccache?', | |
| 588 program='''import json | |
| 589 import subprocess | |
| 590 import sys | |
| 591 | |
| 592 ccache = None | |
| 593 try: | |
| 594 ccache = subprocess.check_output(['which', 'ccache']).rstrip() | |
| 595 except: | |
| 596 pass | |
| 597 print json.dumps({'ccache': ccache}) | |
| 598 ''', | |
| 599 stdout=self.m.json.output(), | |
| 600 infra_step=True, | |
| 601 abort_on_failure=False, | |
| 602 fail_build_on_failure=False) | |
| 603 if result and result.stdout and result.stdout.get('ccache'): | |
| 604 self._ccache = result.stdout['ccache'] | |
| 605 | |
| 606 return self._ccache | |
| 607 | |
| 608 def json_from_file(self, filename, cwd, builder_name, test_data): | |
| 609 """Execute the given script to obtain JSON data.""" | |
| 610 return self.m.python( | |
| 611 'exec %s' % self.m.path.basename(filename), | |
| 612 filename, | |
| 613 args=[self.m.json.output(), builder_name], | |
| 614 step_test_data=lambda: self.m.json.test_api.output(test_data), | |
| 615 cwd=cwd, | |
| 616 infra_step=True).json.output | |
| 617 | 266 |
| 618 def test_steps(self): | 267 def test_steps(self): |
| 619 """Run the DM test.""" | 268 """Run the DM test.""" |
| 620 self._run_once(self.install) | 269 self.m.run.run_once(self.install) |
| 621 self._run_once(self._copy_skps) | 270 self.m.run.run_once(self._copy_skps) |
| 622 self._run_once(self._copy_images) | 271 self.m.run.run_once(self._copy_images) |
| 623 | 272 |
| 624 use_hash_file = False | 273 use_hash_file = False |
| 625 if self.upload_dm_results: | 274 if self.m.vars.upload_dm_results: |
| 626 # This must run before we write anything into self.device_dirs.dm_dir | 275 # This must run before we write anything into |
| 627 # or we may end up deleting our output on machines where they're the same. | 276 # self.m.flavor.device_dirs.dm_dir or we may end up deleting our |
| 628 self.flavor.create_clean_host_dir(self.dm_dir) | 277 # output on machines where they're the same. |
| 629 if str(self.dm_dir) != str(self.device_dirs.dm_dir): | 278 self.m.flavor.create_clean_host_dir(self.m.vars.dm_dir) |
| 630 self.flavor.create_clean_device_dir(self.device_dirs.dm_dir) | 279 host_dm_dir = str(self.m.vars.dm_dir) |
| 280 device_dm_dir = str(self.m.flavor.device_dirs.dm_dir) |
| 281 if host_dm_dir != device_dm_dir: |
| 282 self.m.flavor.create_clean_device_dir(device_dm_dir) |
| 631 | 283 |
| 632 # Obtain the list of already-generated hashes. | 284 # Obtain the list of already-generated hashes. |
| 633 hash_filename = 'uninteresting_hashes.txt' | 285 hash_filename = 'uninteresting_hashes.txt' |
| 634 | 286 |
| 635 # Ensure that the tmp_dir exists. | 287 # Ensure that the tmp_dir exists. |
| 636 self._run_once(self.m.file.makedirs, | 288 self.m.run.run_once(self.m.file.makedirs, |
| 637 'tmp_dir', | 289 'tmp_dir', |
| 638 self.tmp_dir, | 290 self.m.vars.tmp_dir, |
| 639 infra_step=True) | 291 infra_step=True) |
| 640 | 292 |
| 641 host_hashes_file = self.tmp_dir.join(hash_filename) | 293 host_hashes_file = self.m.vars.tmp_dir.join(hash_filename) |
| 642 hashes_file = self.flavor.device_path_join( | 294 hashes_file = self.m.flavor.device_path_join( |
| 643 self.device_dirs.tmp_dir, hash_filename) | 295 self.m.flavor.device_dirs.tmp_dir, hash_filename) |
| 644 self.run( | 296 self.m.run( |
| 645 self.m.python.inline, | 297 self.m.python.inline, |
| 646 'get uninteresting hashes', | 298 'get uninteresting hashes', |
| 647 program=""" | 299 program=""" |
| 648 import contextlib | 300 import contextlib |
| 649 import math | 301 import math |
| 650 import socket | 302 import socket |
| 651 import sys | 303 import sys |
| 652 import time | 304 import time |
| 653 import urllib2 | 305 import urllib2 |
| 654 | 306 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 669 except Exception as e: | 321 except Exception as e: |
| 670 print 'Failed to get uninteresting hashes from %s:' % HASHES_URL | 322 print 'Failed to get uninteresting hashes from %s:' % HASHES_URL |
| 671 print e | 323 print e |
| 672 if retry == RETRIES: | 324 if retry == RETRIES: |
| 673 raise | 325 raise |
| 674 waittime = WAIT_BASE * math.pow(2, retry) | 326 waittime = WAIT_BASE * math.pow(2, retry) |
| 675 print 'Retry in %d seconds.' % waittime | 327 print 'Retry in %d seconds.' % waittime |
| 676 time.sleep(waittime) | 328 time.sleep(waittime) |
| 677 """, | 329 """, |
| 678 args=[host_hashes_file], | 330 args=[host_hashes_file], |
| 679 cwd=self.skia_dir, | 331 cwd=self.m.vars.skia_dir, |
| 680 abort_on_failure=False, | 332 abort_on_failure=False, |
| 681 fail_build_on_failure=False, | 333 fail_build_on_failure=False, |
| 682 infra_step=True) | 334 infra_step=True) |
| 683 | 335 |
| 684 if self.m.path.exists(host_hashes_file): | 336 if self.m.path.exists(host_hashes_file): |
| 685 self.flavor.copy_file_to_device(host_hashes_file, hashes_file) | 337 self.m.flavor.copy_file_to_device(host_hashes_file, hashes_file) |
| 686 use_hash_file = True | 338 use_hash_file = True |
| 687 | 339 |
| 688 # Run DM. | 340 # Run DM. |
| 689 properties = [ | 341 properties = [ |
| 690 'gitHash', self.got_revision, | 342 'gitHash', self.m.vars.got_revision, |
| 691 'master', self.master_name, | 343 'master', self.m.vars.master_name, |
| 692 'builder', self.builder_name, | 344 'builder', self.m.vars.builder_name, |
| 693 'build_number', self.m.properties['buildnumber'], | 345 'build_number', self.m.vars.build_number, |
| 694 ] | 346 ] |
| 695 if self.is_trybot: | 347 if self.m.vars.is_trybot: |
| 696 properties.extend([ | 348 properties.extend([ |
| 697 'issue', self.m.properties['issue'], | 349 'issue', self.m.vars.issue, |
| 698 'patchset', self.m.properties['patchset'], | 350 'patchset', self.m.vars.patchset, |
| 699 ]) | 351 ]) |
| 700 | 352 |
| 701 args = [ | 353 args = [ |
| 702 'dm', | 354 'dm', |
| 703 '--undefok', # This helps branches that may not know new flags. | 355 '--undefok', # This helps branches that may not know new flags. |
| 704 '--resourcePath', self.device_dirs.resource_dir, | 356 '--resourcePath', self.m.flavor.device_dirs.resource_dir, |
| 705 '--skps', self.device_dirs.skp_dir, | 357 '--skps', self.m.flavor.device_dirs.skp_dir, |
| 706 '--images', self.flavor.device_path_join( | 358 '--images', self.m.flavor.device_path_join( |
| 707 self.device_dirs.images_dir, 'dm'), | 359 self.m.flavor.device_dirs.images_dir, 'dm'), |
| 708 '--colorImages', self.flavor.device_path_join(self.device_dirs.images_dir, | 360 '--colorImages', self.m.flavor.device_path_join( |
| 709 'colorspace'), | 361 self.m.flavor.device_dirs.images_dir, 'colorspace'), |
| 710 '--nameByHash', | 362 '--nameByHash', |
| 711 '--properties' | 363 '--properties' |
| 712 ] + properties | 364 ] + properties |
| 713 | 365 |
| 714 args.append('--key') | 366 args.append('--key') |
| 715 args.extend(self._KeyParams()) | 367 args.extend(self._KeyParams()) |
| 716 if use_hash_file: | 368 if use_hash_file: |
| 717 args.extend(['--uninterestingHashesFile', hashes_file]) | 369 args.extend(['--uninterestingHashesFile', hashes_file]) |
| 718 if self.upload_dm_results: | 370 if self.m.vars.upload_dm_results: |
| 719 args.extend(['--writePath', self.device_dirs.dm_dir]) | 371 args.extend(['--writePath', self.m.flavor.device_dirs.dm_dir]) |
| 720 | 372 |
| 721 skip_flag = None | 373 skip_flag = None |
| 722 if self.builder_cfg.get('cpu_or_gpu') == 'CPU': | 374 if self.m.vars.builder_cfg.get('cpu_or_gpu') == 'CPU': |
| 723 skip_flag = '--nogpu' | 375 skip_flag = '--nogpu' |
| 724 elif self.builder_cfg.get('cpu_or_gpu') == 'GPU': | 376 elif self.m.vars.builder_cfg.get('cpu_or_gpu') == 'GPU': |
| 725 skip_flag = '--nocpu' | 377 skip_flag = '--nocpu' |
| 726 if skip_flag: | 378 if skip_flag: |
| 727 args.append(skip_flag) | 379 args.append(skip_flag) |
| 728 args.extend(self.dm_flags) | 380 args.extend(self.m.vars.dm_flags) |
| 729 | 381 |
| 730 self.run(self.flavor.step, 'dm', cmd=args, abort_on_failure=False, | 382 self.m.run(self.m.flavor.step, 'dm', cmd=args, |
| 731 env=self.default_env) | 383 abort_on_failure=False, |
| 384 env=self.m.vars.default_env) |
| 732 | 385 |
| 733 if self.upload_dm_results: | 386 if self.m.vars.upload_dm_results: |
| 734 # Copy images and JSON to host machine if needed. | 387 # Copy images and JSON to host machine if needed. |
| 735 self.flavor.copy_directory_contents_to_host(self.device_dirs.dm_dir, | 388 self.m.flavor.copy_directory_contents_to_host( |
| 736 self.dm_dir) | 389 self.m.flavor.device_dirs.dm_dir, self.m.vars.dm_dir) |
| 737 | 390 |
| 738 # See skia:2789. | 391 # See skia:2789. |
| 739 if ('Valgrind' in self.builder_name and | 392 if ('Valgrind' in self.m.vars.builder_name and |
| 740 self.builder_cfg.get('cpu_or_gpu') == 'GPU'): | 393 self.m.vars.builder_cfg.get('cpu_or_gpu') == 'GPU'): |
| 741 abandonGpuContext = list(args) | 394 abandonGpuContext = list(args) |
| 742 abandonGpuContext.append('--abandonGpuContext') | 395 abandonGpuContext.append('--abandonGpuContext') |
| 743 self.run(self.flavor.step, 'dm --abandonGpuContext', | 396 self.m.run(self.m.flavor.step, 'dm --abandonGpuContext', |
| 744 cmd=abandonGpuContext, abort_on_failure=False) | 397 cmd=abandonGpuContext, abort_on_failure=False) |
| 745 preAbandonGpuContext = list(args) | 398 preAbandonGpuContext = list(args) |
| 746 preAbandonGpuContext.append('--preAbandonGpuContext') | 399 preAbandonGpuContext.append('--preAbandonGpuContext') |
| 747 self.run(self.flavor.step, 'dm --preAbandonGpuContext', | 400 self.m.run(self.m.flavor.step, 'dm --preAbandonGpuContext', |
| 748 cmd=preAbandonGpuContext, abort_on_failure=False, | 401 cmd=preAbandonGpuContext, abort_on_failure=False, |
| 749 env=self.default_env) | 402 env=self.m.vars.default_env) |
| 750 | 403 |
| 751 def perf_steps(self): | 404 def perf_steps(self): |
| 752 """Run Skia benchmarks.""" | 405 """Run Skia benchmarks.""" |
| 753 self._run_once(self.install) | 406 self.m.run.run_once(self.install) |
| 754 self._run_once(self._copy_skps) | 407 self.m.run.run_once(self._copy_skps) |
| 755 self._run_once(self._copy_images) | 408 self.m.run.run_once(self._copy_images) |
| 756 | 409 |
| 757 if self.upload_perf_results: | 410 if self.m.vars.upload_perf_results: |
| 758 self.flavor.create_clean_device_dir(self.device_dirs.perf_data_dir) | 411 self.m.flavor.create_clean_device_dir( |
| 412 self.m.flavor.device_dirs.perf_data_dir) |
| 759 | 413 |
| 760 # Run nanobench. | 414 # Run nanobench. |
| 761 properties = [ | 415 properties = [ |
| 762 '--properties', | 416 '--properties', |
| 763 'gitHash', self.got_revision, | 417 'gitHash', self.m.vars.got_revision, |
| 764 'build_number', self.m.properties['buildnumber'], | 418 'build_number', self.m.vars.build_number, |
| 765 ] | 419 ] |
| 766 if self.is_trybot: | 420 if self.m.vars.is_trybot: |
| 767 properties.extend([ | 421 properties.extend([ |
| 768 'issue', self.m.properties['issue'], | 422 'issue', self.m.vars.issue, |
| 769 'patchset', self.m.properties['patchset'], | 423 'patchset', self.m.vars.patchset, |
| 770 ]) | 424 ]) |
| 771 | 425 |
| 772 target = 'nanobench' | 426 target = 'nanobench' |
| 773 if 'VisualBench' in self.builder_name: | 427 if 'VisualBench' in self.m.vars.builder_name: |
| 774 target = 'visualbench' | 428 target = 'visualbench' |
| 775 args = [ | 429 args = [ |
| 776 target, | 430 target, |
| 777 '--undefok', # This helps branches that may not know new flags. | 431 '--undefok', # This helps branches that may not know new flags. |
| 778 '-i', self.device_dirs.resource_dir, | 432 '-i', self.m.flavor.device_dirs.resource_dir, |
| 779 '--skps', self.device_dirs.skp_dir, | 433 '--skps', self.m.flavor.device_dirs.skp_dir, |
| 780 '--images', self.flavor.device_path_join( | 434 '--images', self.m.flavor.device_path_join( |
| 781 self.device_dirs.images_dir, 'nanobench'), | 435 self.m.flavor.device_dirs.images_dir, 'nanobench'), |
| 782 ] | 436 ] |
| 783 | 437 |
| 784 skip_flag = None | 438 skip_flag = None |
| 785 if self.builder_cfg.get('cpu_or_gpu') == 'CPU': | 439 if self.m.vars.builder_cfg.get('cpu_or_gpu') == 'CPU': |
| 786 skip_flag = '--nogpu' | 440 skip_flag = '--nogpu' |
| 787 elif self.builder_cfg.get('cpu_or_gpu') == 'GPU': | 441 elif self.m.vars.builder_cfg.get('cpu_or_gpu') == 'GPU': |
| 788 skip_flag = '--nocpu' | 442 skip_flag = '--nocpu' |
| 789 if skip_flag: | 443 if skip_flag: |
| 790 args.append(skip_flag) | 444 args.append(skip_flag) |
| 791 args.extend(self.nanobench_flags) | 445 args.extend(self.m.vars.nanobench_flags) |
| 792 | 446 |
| 793 if self.upload_perf_results: | 447 if self.m.vars.upload_perf_results: |
| 794 json_path = self.flavor.device_path_join( | 448 json_path = self.m.flavor.device_path_join( |
| 795 self.device_dirs.perf_data_dir, | 449 self.m.flavor.device_dirs.perf_data_dir, |
| 796 'nanobench_%s.json' % self.got_revision) | 450 'nanobench_%s.json' % self.m.vars.got_revision) |
| 797 args.extend(['--outResultsFile', json_path]) | 451 args.extend(['--outResultsFile', json_path]) |
| 798 args.extend(properties) | 452 args.extend(properties) |
| 799 | 453 |
| 800 keys_blacklist = ['configuration', 'role', 'is_trybot'] | 454 keys_blacklist = ['configuration', 'role', 'is_trybot'] |
| 801 args.append('--key') | 455 args.append('--key') |
| 802 for k in sorted(self.builder_cfg.keys()): | 456 for k in sorted(self.m.vars.builder_cfg.keys()): |
| 803 if not k in keys_blacklist: | 457 if not k in keys_blacklist: |
| 804 args.extend([k, self.builder_cfg[k]]) | 458 args.extend([k, self.m.vars.builder_cfg[k]]) |
| 805 | 459 |
| 806 self.run(self.flavor.step, target, cmd=args, abort_on_failure=False, | 460 self.m.run(self.m.flavor.step, target, cmd=args, |
| 807 env=self.default_env) | 461 abort_on_failure=False, |
| 462 env=self.m.vars.default_env) |
| 808 | 463 |
| 809 # See skia:2789. | 464 # See skia:2789. |
| 810 if ('Valgrind' in self.builder_name and | 465 if ('Valgrind' in self.m.vars.builder_name and |
| 811 self.builder_cfg.get('cpu_or_gpu') == 'GPU'): | 466 self.m.vars.builder_cfg.get('cpu_or_gpu') == 'GPU'): |
| 812 abandonGpuContext = list(args) | 467 abandonGpuContext = list(args) |
| 813 abandonGpuContext.extend(['--abandonGpuContext', '--nocpu']) | 468 abandonGpuContext.extend(['--abandonGpuContext', '--nocpu']) |
| 814 self.run(self.flavor.step, '%s --abandonGpuContext' % target, | 469 self.m.run(self.m.flavor.step, |
| 815 cmd=abandonGpuContext, abort_on_failure=False, | 470 '%s --abandonGpuContext' % target, |
| 816 env=self.default_env) | 471 cmd=abandonGpuContext, abort_on_failure=False, |
| 472 env=self.m.vars.default_env) |
| 817 | 473 |
| 818 # Upload results. | 474 # Upload results. |
| 819 if self.upload_perf_results: | 475 if self.m.vars.upload_perf_results: |
| 820 self.m.file.makedirs('perf_dir', self.perf_data_dir) | 476 self.m.file.makedirs('perf_dir', self.m.vars.perf_data_dir) |
| 821 self.flavor.copy_directory_contents_to_host( | 477 self.m.flavor.copy_directory_contents_to_host( |
| 822 self.device_dirs.perf_data_dir, self.perf_data_dir) | 478 self.m.flavor.device_dirs.perf_data_dir, |
| 479 self.m.vars.perf_data_dir) |
| 823 | 480 |
| 824 def cleanup_steps(self): | 481 def cleanup_steps(self): |
| 825 """Run any cleanup steps.""" | 482 """Run any cleanup steps.""" |
| 826 self.flavor.cleanup_steps() | 483 self.m.flavor.cleanup_steps() |
| 827 | 484 |
| 828 def _KeyParams(self): | 485 def _KeyParams(self): |
| 829 """Build a unique key from the builder name (as a list). | 486 """Build a unique key from the builder name (as a list). |
| 830 | 487 |
| 831 E.g. arch x86 gpu GeForce320M mode MacMini4.1 os Mac10.6 | 488 E.g. arch x86 gpu GeForce320M mode MacMini4.1 os Mac10.6 |
| 832 """ | 489 """ |
| 833 # Don't bother to include role, which is always Test. | 490 # Don't bother to include role, which is always Test. |
| 834 # TryBots are uploaded elsewhere so they can use the same key. | 491 # TryBots are uploaded elsewhere so they can use the same key. |
| 835 blacklist = ['role', 'is_trybot'] | 492 blacklist = ['role', 'is_trybot'] |
| 836 | 493 |
| 837 flat = [] | 494 flat = [] |
| 838 for k in sorted(self.builder_cfg.keys()): | 495 for k in sorted(self.m.vars.builder_cfg.keys()): |
| 839 if k not in blacklist: | 496 if k not in blacklist: |
| 840 flat.append(k) | 497 flat.append(k) |
| 841 flat.append(self.builder_cfg[k]) | 498 flat.append(self.m.vars.builder_cfg[k]) |
| 842 return flat | 499 return flat |
| OLD | NEW |