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
9from recipe_engine import recipe_api
10
11
12CONFIG_DEBUG = 'Debug'
13CONFIG_RELEASE = 'Release'
14
15
16class 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    self.master_name = self.m.properties['mastername']
29    self.slave_name = self.m.properties['slavename']
30    self.build_number = self.m.properties['buildnumber']
31
32    self.slave_dir = self.m.path['start_dir']
33    self.checkout_root = self.slave_dir
34    self.default_env = self.m.step.get_from_context('env', {})
35    self.default_env['PATH'] = self.m.path.pathsep.join([
36        self.default_env.get('PATH', '%(PATH)s'),
37        str(self.m.bot_update._module.PACKAGE_REPO_ROOT),
38    ])
39    self.gclient_env = {}
40    self.is_compile_bot = self.builder_name.startswith('Build-')
41    self.no_buildbot = self.m.properties.get('nobuildbot', '') == 'True'
42    self.skia_task_id = self.m.properties.get('skia_task_id', None)
43
44    self.default_env['CHROME_HEADLESS'] = '1'
45    # The 'depot_tools' directory comes from recipe DEPS and isn't provided by
46    # default. We have to set it manually.
47    self.m.path.c.base_paths['depot_tools'] = (
48        self.m.path.c.base_paths['start_dir'] +
49        ('skia', 'infra', 'bots', '.recipe_deps', 'depot_tools'))
50    if 'Win' in self.builder_name:
51      self.m.path.c.base_paths['depot_tools'] = (
52          'c:\\', 'Users', 'chrome-bot', 'depot_tools')
53
54    # Compile bots keep a persistent checkout.
55    self.persistent_checkout = (self.is_compile_bot or
56                                'RecreateSKPs' in self.builder_name or
57                                '-CT_' in self.builder_name or
58                                'Presubmit' in self.builder_name or
59                                'InfraTests' in self.builder_name or
60                                self.builder_name == "Housekeeper-PerCommit")
61    if self.persistent_checkout:
62      if 'Win' in self.builder_name:
63        self.checkout_root = self.make_path('C:\\', 'b', 'work')
64        self.gclient_cache = self.make_path('C:\\', 'b', 'cache')
65      else:
66        self.checkout_root = self.make_path('/', 'b', 'work')
67        self.gclient_cache = self.make_path('/', 'b', 'cache')
68
69      # got_revision is filled in after checkout steps.
70      self.got_revision = None
71    else:
72      # If there's no persistent checkout, then we have to asume we got the
73      # correct revision of the files from isolate.
74      self.got_revision = self.m.properties['revision']
75
76    # Some bots also require a checkout of PDFium; in this case we use the
77    # checkout of Skia obtained through DEPS in pdfium/third_party/skia.
78    self.need_pdfium_checkout = 'PDFium' in self.builder_name
79
80    # Some bots also require a checkout of Flutter; in this case we use the
81    # checkout of Skia obtained through DEPS in src/third_party/skia.
82    self.need_flutter_checkout = 'Flutter' in self.builder_name
83
84    self.skia_dir = self.checkout_root.join('skia')
85    if self.need_pdfium_checkout:
86      self.skia_dir = self.checkout_root.join('pdfium', 'third_party', 'skia')
87    elif self.need_flutter_checkout:
88      self.checkout_root = self.checkout_root.join('flutter')
89      self.skia_dir = self.checkout_root.join('src', 'third_party', 'skia')
90
91    if not self.persistent_checkout:
92      self.m.path['checkout'] = self.skia_dir
93
94    self.infrabots_dir = self.skia_dir.join('infra', 'bots')
95    self.resource_dir = self.skia_dir.join('resources')
96    self.images_dir = self.slave_dir.join('skimage')
97    self.skia_out = self.skia_dir.join('out', self.builder_name)
98    self.swarming_out_dir = self.make_path(self.m.properties['swarm_out_dir'])
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:  # pragma: no cover
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 == self.m.builder_name_schema.BUILDER_ROLE_HOUSEKEEPER:
119      self.configuration = CONFIG_RELEASE
120    else:
121      self.configuration = self.builder_cfg.get('configuration', CONFIG_DEBUG)
122    arch = (self.builder_cfg.get('arch') or self.builder_cfg.get('target_arch'))
123    if ('Win' in self.builder_cfg.get('os', '') and arch == 'x86_64'):
124      self.configuration += '_x64'
125
126    self.default_env.update({'SKIA_OUT': self.skia_out,
127                             'BUILDTYPE': self.configuration})
128
129    self.patch_storage = self.m.properties.get('patch_storage', 'rietveld')
130    self.issue = None
131    self.patchset = None
132    if self.no_buildbot:
133      self.is_trybot = False
134      if (self.m.properties.get('issue', '') and
135          self.m.properties.get('patchset', '')):
136        self.is_trybot = True
137        self.issue = self.m.properties['issue']
138        self.patchset = self.m.properties['patchset']
139      elif (self.m.properties.get('patch_issue', '') and
140            self.m.properties.get('patch_set', '')):
141        self.is_trybot = True
142        self.issue = self.m.properties['patch_issue']
143        self.patchset = self.m.properties['patch_set']
144    else:
145      self.is_trybot = self.builder_cfg['is_trybot']
146      if self.is_trybot:
147        if self.patch_storage == 'gerrit':
148          self.issue = self.m.properties['patch_issue']
149          self.patchset = self.m.properties['patch_set']
150        else:
151          self.issue = self.m.properties['issue']
152          self.patchset = self.m.properties['patchset']
153
154    self.dm_dir = self.m.path.join(
155        self.swarming_out_dir, 'dm')
156    self.perf_data_dir = self.m.path.join(self.swarming_out_dir,
157        'perfdata', self.builder_name, 'data')
158    self._swarming_bot_id = None
159    self._swarming_task_id = None
160
161    # Data should go under in _data_dir, which may be preserved across runs.
162    self.android_data_dir = '/sdcard/revenge_of_the_skiabot/'
163    # Executables go under _bin_dir, which, well, allows executable files.
164    self.android_bin_dir  = '/data/local/tmp/'
165
166    if self.builder_cfg.get('os', '') == 'Chromecast':
167      # On the Chromecast, everything goes in the (~110M) /cache/skia
168      self.android_bin_dir  = '/cache/skia/'
169      self.android_data_dir = '/cache/skia/'
170
171  @property
172  def upload_dm_results(self):
173    # TODO(borenet): Move this into the swarm_test recipe.
174    skip_upload_bots = [
175      'ASAN',
176      'Coverage',
177      'MSAN',
178      'TSAN',
179      'UBSAN',
180      'Valgrind',
181    ]
182    upload_dm_results = True
183    for s in skip_upload_bots:
184      if s in self.m.properties['buildername']:
185        upload_dm_results = False
186        break
187    return upload_dm_results
188
189  @property
190  def upload_perf_results(self):
191    # TODO(borenet): Move this into the swarm_perf recipe.
192    if 'Release' not in self.m.properties['buildername']:
193      return False
194    skip_upload_bots = [
195      'ASAN',
196      'Coverage',
197      'MSAN',
198      'TSAN',
199      'UBSAN',
200      'Valgrind',
201    ]
202    upload_perf_results = True
203    for s in skip_upload_bots:
204      if s in self.m.properties['buildername']:
205        upload_perf_results = False
206        break
207    return upload_perf_results
208
209  @property
210  def swarming_bot_id(self):
211    if not self._swarming_bot_id:
212      self._swarming_bot_id = self.m.python.inline(
213          name='get swarming bot id',
214          program='''import os
215print os.environ.get('SWARMING_BOT_ID', '')
216''',
217          stdout=self.m.raw_io.output()).stdout.rstrip()
218    return self._swarming_bot_id
219
220  @property
221  def swarming_task_id(self):
222    if not self._swarming_task_id:
223      self._swarming_task_id = self.m.python.inline(
224          name='get swarming task id',
225          program='''import os
226print os.environ.get('SWARMING_TASK_ID', '')
227''',
228          stdout=self.m.raw_io.output()).stdout.rstrip()
229    return self._swarming_task_id
230
231