1 # Copyright 2016 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. 4 5 6 # pylint: disable=W0201 7 8 9 from recipe_engine import recipe_api 10 11 12 CONFIG_DEBUG = 'Debug' 13 CONFIG_RELEASE = 'Release' 14 15 16 class SkiaVarsApi(recipe_api.RecipeApi): 17 18 def make_path(self, *path): 19 """Return a Path object for the given path.""" 20 key = 'custom_%s' % '_'.join(path) 21 self.m.path.c.base_paths[key] = tuple(path) 22 return self.m.path[key] 23 24 def setup(self): 25 """Prepare the variables.""" 26 # Setup 27 self.builder_name = self.m.properties['buildername'] 28 29 self.slave_dir = self.m.path['start_dir'] 30 self.checkout_root = self.slave_dir 31 self.default_env = self.m.context.env 32 self.default_env['CHROME_HEADLESS'] = '1' 33 self.default_env['PATH'] = self.m.path.pathsep.join([ 34 self.default_env.get('PATH', '%(PATH)s'), 35 str(self.m.bot_update._module.PACKAGE_REPO_ROOT), 36 ]) 37 self.gclient_env = {} 38 self.is_compile_bot = self.builder_name.startswith('Build-') 39 40 self.persistent_checkout = False 41 # Compile bots keep a persistent checkout. 42 if self.is_compile_bot: 43 self.persistent_checkout = True 44 if 'Housekeeper' in self.builder_name: 45 self.persistent_checkout = True 46 if '-CT_' in self.builder_name: 47 self.persistent_checkout = True 48 # We need the source code for the Coverage's Upload step to be in the 49 # same absolute location as when we compiled it so we can map the 50 # coverage data to actual line numbers. We ensure this by making sure 51 # we have a checkout on the Coverage's Upload step and that the Upload 52 # step runs on the same bots that Compile. 53 if 'Coverage' in self.builder_name and 'Upload' in self.builder_name: 54 self.persistent_checkout = True 55 56 if self.persistent_checkout: 57 if 'Win' in self.builder_name: 58 self.checkout_root = self.make_path('C:\\', 'b', 'work') 59 self.gclient_cache = self.make_path('C:\\', 'b', 'cache') 60 else: 61 self.checkout_root = self.make_path('/', 'b', 'work') 62 self.gclient_cache = self.make_path('/', 'b', 'cache') 63 64 # got_revision is filled in after checkout steps. 65 self.got_revision = None 66 else: 67 # If there's no persistent checkout, then we have to asume we got the 68 # correct revision of the files from isolate. 69 self.got_revision = self.m.properties['revision'] 70 71 # Some bots also require a checkout of PDFium; in this case we use the 72 # checkout of Skia obtained through DEPS in pdfium/third_party/skia. 73 self.need_pdfium_checkout = 'PDFium' in self.builder_name 74 75 # Some bots also require a checkout of Flutter; in this case we use the 76 # checkout of Skia obtained through DEPS in src/third_party/skia. 77 self.need_flutter_checkout = 'Flutter' in self.builder_name 78 79 self.skia_dir = self.checkout_root.join('skia') 80 if self.need_pdfium_checkout: 81 self.skia_dir = self.checkout_root.join('pdfium', 'third_party', 'skia') 82 elif self.need_flutter_checkout: 83 self.checkout_root = self.checkout_root.join('flutter') 84 self.skia_dir = self.checkout_root.join('src', 'third_party', 'skia') 85 86 if not self.persistent_checkout: 87 self.m.path['checkout'] = self.skia_dir 88 89 self.infrabots_dir = self.skia_dir.join('infra', 'bots') 90 self.resource_dir = self.skia_dir.join('resources') 91 self.images_dir = self.slave_dir.join('skimage') 92 self.skia_out = self.skia_dir.join('out', self.builder_name) 93 self.swarming_out_dir = self.make_path(self.m.properties['swarm_out_dir']) 94 if 'ParentRevision' in self.builder_name: 95 # Tasks that depend on ParentRevision builds usually also depend on a 96 # second build task. Use a different path for build results so that the 97 # binaries end up in different directories in the isolate. 98 self.swarming_out_dir = self.swarming_out_dir.join('ParentRevision') 99 self.local_skp_dir = self.slave_dir.join('skp') 100 self.local_svg_dir = self.slave_dir.join('svg') 101 if not self.is_compile_bot: 102 self.skia_out = self.slave_dir.join('out') 103 self.tmp_dir = self.m.path['start_dir'].join('tmp') 104 105 # Some bots also require a checkout of chromium. 106 self.need_chromium_checkout = False 107 if 'CommandBuffer' in self.builder_name: 108 self.need_chromium_checkout = True 109 self.gclient_env['GYP_CHROMIUM_NO_ACTION'] = '0' 110 if 'RecreateSKPs' in self.builder_name: 111 self.need_chromium_checkout = True 112 self.gclient_env['CPPFLAGS'] = ( 113 '-DSK_ALLOW_CROSSPROCESS_PICTUREIMAGEFILTERS=1') 114 115 self.builder_cfg = self.m.builder_name_schema.DictForBuilderName( 116 self.builder_name) 117 self.role = self.builder_cfg['role'] 118 if self.role in [self.m.builder_name_schema.BUILDER_ROLE_HOUSEKEEPER, 119 self.m.builder_name_schema.BUILDER_ROLE_CALMBENCH]: 120 self.configuration = CONFIG_RELEASE 121 else: 122 self.configuration = self.builder_cfg.get('configuration', CONFIG_DEBUG) 123 arch = (self.builder_cfg.get('arch') or self.builder_cfg.get('target_arch')) 124 if ('Win' in self.builder_cfg.get('os', '') and arch == 'x86_64'): 125 self.configuration += '_x64' 126 self.extra_tokens = [] 127 if len(self.builder_cfg.get('extra_config', '')) > 0: 128 if self.builder_cfg['extra_config'].startswith('SK'): 129 assert self.builder_cfg['extra_config'].isupper() 130 self.extra_tokens = [self.builder_cfg['extra_config']] 131 else: 132 self.extra_tokens = self.builder_cfg['extra_config'].split('_') 133 134 self.default_env.update({'SKIA_OUT': self.skia_out, 135 'BUILDTYPE': self.configuration}) 136 137 self.patch_storage = self.m.properties.get('patch_storage', 'gerrit') 138 self.issue = None 139 self.patchset = None 140 self.is_trybot = False 141 if (self.m.properties.get('patch_issue', '') and 142 self.m.properties.get('patch_set', '')): 143 self.is_trybot = True 144 self.issue = self.m.properties['patch_issue'] 145 self.patchset = self.m.properties['patch_set'] 146 147 self.dm_dir = self.m.path.join( 148 self.swarming_out_dir, 'dm') 149 self.perf_data_dir = self.m.path.join(self.swarming_out_dir, 150 'perfdata', self.builder_name, 'data') 151 self._swarming_bot_id = None 152 self._swarming_task_id = None 153 154 # Data should go under in _data_dir, which may be preserved across runs. 155 self.android_data_dir = '/sdcard/revenge_of_the_skiabot/' 156 # Executables go under _bin_dir, which, well, allows executable files. 157 self.android_bin_dir = '/data/local/tmp/' 158 159 if self.builder_cfg.get('os', '') == 'Chromecast': 160 # On the Chromecast, everything goes in the (~110M) /cache/skia 161 self.android_bin_dir = '/cache/skia/' 162 self.android_data_dir = '/cache/skia/' 163 164 self.chromeos_homedir = '/home/chronos/user/' 165 166 # Internal bot support. 167 self.internal_hardware_label = ( 168 self.m.properties.get('internal_hardware_label')) 169 self.is_internal_bot = self.internal_hardware_label is not None 170 171 @property 172 def is_linux(self): 173 return 'Ubuntu' in self.builder_name or 'Debian' in self.builder_name 174 175 @property 176 def upload_dm_results(self): 177 # TODO(borenet): Move this into the swarm_test recipe. 178 skip_upload_bots = [ 179 'ASAN', 180 'Coverage', 181 'MSAN', 182 'TSAN', 183 'UBSAN', 184 'Valgrind', 185 ] 186 upload_dm_results = True 187 for s in skip_upload_bots: 188 if s in self.m.properties['buildername']: 189 upload_dm_results = False 190 break 191 return upload_dm_results 192 193 @property 194 def upload_perf_results(self): 195 # TODO(borenet): Move this into the swarm_perf recipe. 196 if 'Release' not in self.m.properties['buildername']: 197 return False 198 skip_upload_bots = [ 199 'ASAN', 200 'Coverage', 201 'MSAN', 202 'TSAN', 203 'UBSAN', 204 'Valgrind', 205 ] 206 upload_perf_results = True 207 for s in skip_upload_bots: 208 if s in self.m.properties['buildername']: 209 upload_perf_results = False 210 break 211 return upload_perf_results 212 213 @property 214 def swarming_bot_id(self): 215 if not self._swarming_bot_id: 216 self._swarming_bot_id = self.m.python.inline( 217 name='get swarming bot id', 218 program='''import os 219 print os.environ.get('SWARMING_BOT_ID', '') 220 ''', 221 stdout=self.m.raw_io.output()).stdout.rstrip() 222 return self._swarming_bot_id 223 224 @property 225 def swarming_task_id(self): 226 if not self._swarming_task_id: 227 self._swarming_task_id = self.m.python.inline( 228 name='get swarming task id', 229 program='''import os 230 print os.environ.get('SWARMING_TASK_ID', '') 231 ''', 232 stdout=self.m.raw_io.output()).stdout.rstrip() 233 return self._swarming_task_id 234