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

Side by Side Diff: infra/bots/recipe_modules/core/api.py

Issue 2198973002: [Recipes] Move test and perf steps into test and perf recipes (Closed) Base URL: https://skia.googlesource.com/skia.git@fix_buildbot_spec
Patch Set: ready for review Created 4 years, 4 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
« no previous file with comments | « no previous file | infra/bots/recipe_modules/flavor/__init__.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 fake_specs 17 from . import fake_specs
18 18
19 19
20 TEST_EXPECTED_SKP_VERSION = '42'
21 TEST_EXPECTED_SK_IMAGE_VERSION = '42'
22
23 VERSION_FILE_SK_IMAGE = 'SK_IMAGE_VERSION'
24 VERSION_FILE_SKP = 'SKP_VERSION'
25
26 VERSION_NONE = -1
27
28
29 class SkiaApi(recipe_api.RecipeApi): 20 class SkiaApi(recipe_api.RecipeApi):
30 21
31 def get_builder_spec(self, skia_dir, builder_name): 22 def get_builder_spec(self, skia_dir, builder_name):
32 """Obtain the buildbot spec for the given builder.""" 23 """Obtain the buildbot spec for the given builder."""
33 fake_spec = None 24 fake_spec = None
34 if self._test_data.enabled: 25 if self._test_data.enabled:
35 fake_spec = fake_specs.FAKE_SPECS[builder_name] 26 fake_spec = fake_specs.FAKE_SPECS[builder_name]
36 builder_spec = self.m.run.json_from_file( 27 builder_spec = self.m.run.json_from_file(
37 skia_dir.join('tools', 'buildbot_spec.py'), 28 skia_dir.join('tools', 'buildbot_spec.py'),
38 skia_dir, 29 skia_dir,
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 revert=False, 160 revert=False,
170 **checkout_kwargs) 161 **checkout_kwargs)
171 162
172 self.m.vars.got_revision = ( 163 self.m.vars.got_revision = (
173 update_step.presentation.properties['got_revision']) 164 update_step.presentation.properties['got_revision'])
174 self.m.tryserver.maybe_apply_issue() 165 self.m.tryserver.maybe_apply_issue()
175 166
176 if self.m.vars.need_chromium_checkout: 167 if self.m.vars.need_chromium_checkout:
177 self.m.gclient.runhooks(cwd=self.m.vars.checkout_root, 168 self.m.gclient.runhooks(cwd=self.m.vars.checkout_root,
178 env=self.m.vars.gclient_env) 169 env=self.m.vars.gclient_env)
179
180 def copy_dir(self, host_version, version_file, tmp_dir,
181 host_path, device_path, test_expected_version,
182 test_actual_version):
183 actual_version_file = self.m.path.join(tmp_dir, version_file)
184 # Copy to device.
185 device_version_file = self.m.flavor.device_path_join(
186 self.m.flavor.device_dirs.tmp_dir, version_file)
187 if str(actual_version_file) != str(device_version_file):
188 try:
189 device_version = (
190 self.m.flavor.read_file_on_device(device_version_file))
191 except self.m.step.StepFailure:
192 device_version = VERSION_NONE
193 if device_version != host_version:
194 self.m.flavor.remove_file_on_device(device_version_file)
195 self.m.flavor.create_clean_device_dir(device_path)
196 self.m.flavor.copy_directory_contents_to_device(
197 host_path, device_path)
198
199 # Copy the new version file.
200 self.m.flavor.copy_file_to_device(actual_version_file,
201 device_version_file)
202
203 def _copy_images(self):
204 """Download and copy test images if needed."""
205 version_file = self.m.vars.infrabots_dir.join(
206 'assets', 'skimage', 'VERSION')
207 test_data = self.m.properties.get(
208 'test_downloaded_sk_image_version', TEST_EXPECTED_SK_IMAGE_VERSION)
209 version = self.m.run.readfile(
210 version_file,
211 name='Get downloaded skimage VERSION',
212 test_data=test_data).rstrip()
213 self.m.run.writefile(
214 self.m.path.join(self.m.vars.tmp_dir, VERSION_FILE_SK_IMAGE),
215 version)
216 self.copy_dir(
217 version,
218 VERSION_FILE_SK_IMAGE,
219 self.m.vars.tmp_dir,
220 self.m.vars.images_dir,
221 self.m.flavor.device_dirs.images_dir,
222 test_expected_version=self.m.properties.get(
223 'test_downloaded_sk_image_version',
224 TEST_EXPECTED_SK_IMAGE_VERSION),
225 test_actual_version=self.m.properties.get(
226 'test_downloaded_sk_image_version',
227 TEST_EXPECTED_SK_IMAGE_VERSION))
228 return version
229
230 def _copy_skps(self):
231 """Download and copy the SKPs if needed."""
232 version_file = self.m.vars.infrabots_dir.join(
233 'assets', 'skp', 'VERSION')
234 test_data = self.m.properties.get(
235 'test_downloaded_skp_version', TEST_EXPECTED_SKP_VERSION)
236 version = self.m.run.readfile(
237 version_file,
238 name='Get downloaded SKP VERSION',
239 test_data=test_data).rstrip()
240 self.m.run.writefile(
241 self.m.path.join(self.m.vars.tmp_dir, VERSION_FILE_SKP),
242 version)
243 self.copy_dir(
244 version,
245 VERSION_FILE_SKP,
246 self.m.vars.tmp_dir,
247 self.m.vars.local_skp_dir,
248 self.m.flavor.device_dirs.skp_dir,
249 test_expected_version=self.m.properties.get(
250 'test_downloaded_skp_version', TEST_EXPECTED_SKP_VERSION),
251 test_actual_version=self.m.properties.get(
252 'test_downloaded_skp_version', TEST_EXPECTED_SKP_VERSION))
253 return version
254
255 def install(self):
256 """Copy the required executables and files to the device."""
257 # Run any device-specific installation.
258 self.m.flavor.install()
259
260 # TODO(borenet): Only copy files which have changed.
261 # Resources
262 self.m.flavor.copy_directory_contents_to_device(
263 self.m.vars.resource_dir,
264 self.m.flavor.device_dirs.resource_dir)
265
266 def test_steps(self):
267 """Run the DM test."""
268 self.m.run.run_once(self.install)
269 self.m.run.run_once(self._copy_skps)
270 self.m.run.run_once(self._copy_images)
271
272 use_hash_file = False
273 if self.m.vars.upload_dm_results:
274 # This must run before we write anything into
275 # self.m.flavor.device_dirs.dm_dir or we may end up deleting our
276 # output on machines where they're the same.
277 self.m.flavor.create_clean_host_dir(self.m.vars.dm_dir)
278 host_dm_dir = str(self.m.vars.dm_dir)
279 device_dm_dir = str(self.m.flavor.device_dirs.dm_dir)
280 if host_dm_dir != device_dm_dir:
281 self.m.flavor.create_clean_device_dir(device_dm_dir)
282
283 # Obtain the list of already-generated hashes.
284 hash_filename = 'uninteresting_hashes.txt'
285
286 # Ensure that the tmp_dir exists.
287 self.m.run.run_once(self.m.file.makedirs,
288 'tmp_dir',
289 self.m.vars.tmp_dir,
290 infra_step=True)
291
292 host_hashes_file = self.m.vars.tmp_dir.join(hash_filename)
293 hashes_file = self.m.flavor.device_path_join(
294 self.m.flavor.device_dirs.tmp_dir, hash_filename)
295 self.m.run(
296 self.m.python.inline,
297 'get uninteresting hashes',
298 program="""
299 import contextlib
300 import math
301 import socket
302 import sys
303 import time
304 import urllib2
305
306 HASHES_URL = 'https://gold.skia.org/_/hashes'
307 RETRIES = 5
308 TIMEOUT = 60
309 WAIT_BASE = 15
310
311 socket.setdefaulttimeout(TIMEOUT)
312 for retry in range(RETRIES):
313 try:
314 with contextlib.closing(
315 urllib2.urlopen(HASHES_URL, timeout=TIMEOUT)) as w:
316 hashes = w.read()
317 with open(sys.argv[1], 'w') as f:
318 f.write(hashes)
319 break
320 except Exception as e:
321 print 'Failed to get uninteresting hashes from %s:' % HASHES_URL
322 print e
323 if retry == RETRIES:
324 raise
325 waittime = WAIT_BASE * math.pow(2, retry)
326 print 'Retry in %d seconds.' % waittime
327 time.sleep(waittime)
328 """,
329 args=[host_hashes_file],
330 cwd=self.m.vars.skia_dir,
331 abort_on_failure=False,
332 fail_build_on_failure=False,
333 infra_step=True)
334
335 if self.m.path.exists(host_hashes_file):
336 self.m.flavor.copy_file_to_device(host_hashes_file, hashes_file)
337 use_hash_file = True
338
339 # Run DM.
340 properties = [
341 'gitHash', self.m.vars.got_revision,
342 'master', self.m.vars.master_name,
343 'builder', self.m.vars.builder_name,
344 'build_number', self.m.vars.build_number,
345 ]
346 if self.m.vars.is_trybot:
347 properties.extend([
348 'issue', self.m.vars.issue,
349 'patchset', self.m.vars.patchset,
350 ])
351
352 args = [
353 'dm',
354 '--undefok', # This helps branches that may not know new flags.
355 '--resourcePath', self.m.flavor.device_dirs.resource_dir,
356 '--skps', self.m.flavor.device_dirs.skp_dir,
357 '--images', self.m.flavor.device_path_join(
358 self.m.flavor.device_dirs.images_dir, 'dm'),
359 '--colorImages', self.m.flavor.device_path_join(
360 self.m.flavor.device_dirs.images_dir, 'colorspace'),
361 '--nameByHash',
362 '--properties'
363 ] + properties
364
365 args.append('--key')
366 args.extend(self._KeyParams())
367 if use_hash_file:
368 args.extend(['--uninterestingHashesFile', hashes_file])
369 if self.m.vars.upload_dm_results:
370 args.extend(['--writePath', self.m.flavor.device_dirs.dm_dir])
371
372 skip_flag = None
373 if self.m.vars.builder_cfg.get('cpu_or_gpu') == 'CPU':
374 skip_flag = '--nogpu'
375 elif self.m.vars.builder_cfg.get('cpu_or_gpu') == 'GPU':
376 skip_flag = '--nocpu'
377 if skip_flag:
378 args.append(skip_flag)
379 args.extend(self.m.vars.dm_flags)
380
381 self.m.run(self.m.flavor.step, 'dm', cmd=args,
382 abort_on_failure=False,
383 env=self.m.vars.default_env)
384
385 if self.m.vars.upload_dm_results:
386 # Copy images and JSON to host machine if needed.
387 self.m.flavor.copy_directory_contents_to_host(
388 self.m.flavor.device_dirs.dm_dir, self.m.vars.dm_dir)
389
390 # See skia:2789.
391 if ('Valgrind' in self.m.vars.builder_name and
392 self.m.vars.builder_cfg.get('cpu_or_gpu') == 'GPU'):
393 abandonGpuContext = list(args)
394 abandonGpuContext.append('--abandonGpuContext')
395 self.m.run(self.m.flavor.step, 'dm --abandonGpuContext',
396 cmd=abandonGpuContext, abort_on_failure=False)
397 preAbandonGpuContext = list(args)
398 preAbandonGpuContext.append('--preAbandonGpuContext')
399 self.m.run(self.m.flavor.step, 'dm --preAbandonGpuContext',
400 cmd=preAbandonGpuContext, abort_on_failure=False,
401 env=self.m.vars.default_env)
402
403 def perf_steps(self):
404 """Run Skia benchmarks."""
405 self.m.run.run_once(self.install)
406 self.m.run.run_once(self._copy_skps)
407 self.m.run.run_once(self._copy_images)
408
409 if self.m.vars.upload_perf_results:
410 self.m.flavor.create_clean_device_dir(
411 self.m.flavor.device_dirs.perf_data_dir)
412
413 # Run nanobench.
414 properties = [
415 '--properties',
416 'gitHash', self.m.vars.got_revision,
417 'build_number', self.m.vars.build_number,
418 ]
419 if self.m.vars.is_trybot:
420 properties.extend([
421 'issue', self.m.vars.issue,
422 'patchset', self.m.vars.patchset,
423 ])
424
425 target = 'nanobench'
426 if 'VisualBench' in self.m.vars.builder_name:
427 target = 'visualbench'
428 args = [
429 target,
430 '--undefok', # This helps branches that may not know new flags.
431 '-i', self.m.flavor.device_dirs.resource_dir,
432 '--skps', self.m.flavor.device_dirs.skp_dir,
433 '--images', self.m.flavor.device_path_join(
434 self.m.flavor.device_dirs.images_dir, 'nanobench'),
435 ]
436
437 skip_flag = None
438 if self.m.vars.builder_cfg.get('cpu_or_gpu') == 'CPU':
439 skip_flag = '--nogpu'
440 elif self.m.vars.builder_cfg.get('cpu_or_gpu') == 'GPU':
441 skip_flag = '--nocpu'
442 if skip_flag:
443 args.append(skip_flag)
444 args.extend(self.m.vars.nanobench_flags)
445
446 if self.m.vars.upload_perf_results:
447 json_path = self.m.flavor.device_path_join(
448 self.m.flavor.device_dirs.perf_data_dir,
449 'nanobench_%s.json' % self.m.vars.got_revision)
450 args.extend(['--outResultsFile', json_path])
451 args.extend(properties)
452
453 keys_blacklist = ['configuration', 'role', 'is_trybot']
454 args.append('--key')
455 for k in sorted(self.m.vars.builder_cfg.keys()):
456 if not k in keys_blacklist:
457 args.extend([k, self.m.vars.builder_cfg[k]])
458
459 self.m.run(self.m.flavor.step, target, cmd=args,
460 abort_on_failure=False,
461 env=self.m.vars.default_env)
462
463 # See skia:2789.
464 if ('Valgrind' in self.m.vars.builder_name and
465 self.m.vars.builder_cfg.get('cpu_or_gpu') == 'GPU'):
466 abandonGpuContext = list(args)
467 abandonGpuContext.extend(['--abandonGpuContext', '--nocpu'])
468 self.m.run(self.m.flavor.step,
469 '%s --abandonGpuContext' % target,
470 cmd=abandonGpuContext, abort_on_failure=False,
471 env=self.m.vars.default_env)
472
473 # Upload results.
474 if self.m.vars.upload_perf_results:
475 self.m.file.makedirs('perf_dir', self.m.vars.perf_data_dir)
476 self.m.flavor.copy_directory_contents_to_host(
477 self.m.flavor.device_dirs.perf_data_dir,
478 self.m.vars.perf_data_dir)
479
480 def cleanup_steps(self):
481 """Run any cleanup steps."""
482 self.m.flavor.cleanup_steps()
483
484 def _KeyParams(self):
485 """Build a unique key from the builder name (as a list).
486
487 E.g. arch x86 gpu GeForce320M mode MacMini4.1 os Mac10.6
488 """
489 # Don't bother to include role, which is always Test.
490 # TryBots are uploaded elsewhere so they can use the same key.
491 blacklist = ['role', 'is_trybot']
492
493 flat = []
494 for k in sorted(self.m.vars.builder_cfg.keys()):
495 if k not in blacklist:
496 flat.append(k)
497 flat.append(self.m.vars.builder_cfg[k])
498 return flat
OLDNEW
« no previous file with comments | « no previous file | infra/bots/recipe_modules/flavor/__init__.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698