1 #!/usr/bin/env python 2 # 3 # Copyright 2016 Google Inc. 4 # 5 # Use of this source code is governed by a BSD-style license that can be 6 # found in the LICENSE file. 7 8 9 import os 10 import subprocess 11 import sys 12 13 from flavor import android_flavor 14 from flavor import chromeos_flavor 15 from flavor import cmake_flavor 16 from flavor import coverage_flavor 17 from flavor import default_flavor 18 from flavor import ios_flavor 19 from flavor import valgrind_flavor 20 from flavor import xsan_flavor 21 22 23 CONFIG_COVERAGE = 'Coverage' 24 CONFIG_DEBUG = 'Debug' 25 CONFIG_RELEASE = 'Release' 26 VALID_CONFIGS = (CONFIG_COVERAGE, CONFIG_DEBUG, CONFIG_RELEASE) 27 28 GM_ACTUAL_FILENAME = 'actual-results.json' 29 GM_EXPECTATIONS_FILENAME = 'expected-results.json' 30 GM_IGNORE_TESTS_FILENAME = 'ignored-tests.txt' 31 32 GS_GM_BUCKET = 'chromium-skia-gm' 33 GS_SUMMARIES_BUCKET = 'chromium-skia-gm-summaries' 34 35 SKIA_REPO = 'https://skia.googlesource.com/skia.git' 36 INFRA_REPO = 'https://skia.googlesource.com/buildbot.git' 37 38 SERVICE_ACCOUNT_FILE = 'service-account-skia.json' 39 SERVICE_ACCOUNT_INTERNAL_FILE = 'service-account-skia-internal.json' 40 41 42 def is_android(bot_cfg): 43 """Determine whether the given bot is an Android bot.""" 44 return ('Android' in bot_cfg.get('extra_config', '') or 45 bot_cfg.get('os') == 'Android') 46 47 def is_chromeos(bot_cfg): 48 return ('CrOS' in bot_cfg.get('extra_config', '') or 49 bot_cfg.get('os') == 'ChromeOS') 50 51 def is_cmake(bot_cfg): 52 return 'CMake' in bot_cfg.get('extra_config', '') 53 54 def is_ios(bot_cfg): 55 return ('iOS' in bot_cfg.get('extra_config', '') or 56 bot_cfg.get('os') == 'iOS') 57 58 59 def is_valgrind(bot_cfg): 60 return 'Valgrind' in bot_cfg.get('extra_config', '') 61 62 63 def is_xsan(bot_cfg): 64 return (bot_cfg.get('extra_config') == 'ASAN' or 65 bot_cfg.get('extra_config') == 'MSAN' or 66 bot_cfg.get('extra_config') == 'TSAN') 67 68 69 class BotInfo(object): 70 def __init__(self, bot_name, slave_name, out_dir): 71 """Initialize the bot, given its name. 72 73 Assumes that CWD is the directory containing this file. 74 """ 75 self.name = bot_name 76 self.slave_name = slave_name 77 self.skia_dir = os.path.abspath(os.path.join( 78 os.path.dirname(os.path.realpath(__file__)), 79 os.pardir, os.pardir)) 80 os.chdir(self.skia_dir) 81 self.build_dir = os.path.abspath(os.path.join(self.skia_dir, os.pardir)) 82 self.out_dir = out_dir 83 self.spec = self.get_bot_spec(bot_name) 84 self.configuration = self.spec['configuration'] 85 self.default_env = { 86 'SKIA_OUT': self.out_dir, 87 'BUILDTYPE': self.configuration, 88 'PATH': os.environ['PATH'], 89 } 90 self.default_env.update(self.spec['env']) 91 self.build_targets = [str(t) for t in self.spec['build_targets']] 92 self.bot_cfg = self.spec['builder_cfg'] 93 self.is_trybot = self.bot_cfg['is_trybot'] 94 self.upload_dm_results = self.spec['upload_dm_results'] 95 self.upload_perf_results = self.spec['upload_perf_results'] 96 self.dm_flags = self.spec['dm_flags'] 97 self.nanobench_flags = self.spec['nanobench_flags'] 98 self._ccache = None 99 self._checked_for_ccache = False 100 self.flavor = self.get_flavor(self.bot_cfg) 101 102 @property 103 def ccache(self): 104 if not self._checked_for_ccache: 105 self._checked_for_ccache = True 106 if sys.platform != 'win32': 107 try: 108 result = subprocess.check_output(['which', 'ccache']) 109 self._ccache = result.rstrip() 110 except subprocess.CalledProcessError: 111 pass 112 113 return self._ccache 114 115 def get_bot_spec(self, bot_name): 116 """Retrieve the bot spec for this bot.""" 117 sys.path.append(self.skia_dir) 118 from tools import buildbot_spec 119 return buildbot_spec.get_builder_spec(bot_name) 120 121 def get_flavor(self, bot_cfg): 122 """Return a flavor utils object specific to the given bot.""" 123 if is_android(bot_cfg): 124 return android_flavor.AndroidFlavorUtils(self) 125 elif is_chromeos(bot_cfg): 126 return chromeos_flavor.ChromeOSFlavorUtils(self) 127 elif is_cmake(bot_cfg): 128 return cmake_flavor.CMakeFlavorUtils(self) 129 elif is_ios(bot_cfg): 130 return ios_flavor.iOSFlavorUtils(self) 131 elif is_valgrind(bot_cfg): 132 return valgrind_flavor.ValgrindFlavorUtils(self) 133 elif is_xsan(bot_cfg): 134 return xsan_flavor.XSanFlavorUtils(self) 135 elif bot_cfg.get('configuration') == CONFIG_COVERAGE: 136 return coverage_flavor.CoverageFlavorUtils(self) 137 else: 138 return default_flavor.DefaultFlavorUtils(self) 139 140 def run(self, cmd, env=None, cwd=None): 141 _env = {} 142 _env.update(self.default_env) 143 _env.update(env or {}) 144 cwd = cwd or self.skia_dir 145 print '============' 146 print 'CMD: %s' % cmd 147 print 'CWD: %s' % cwd 148 print 'ENV: %s' % _env 149 print '============' 150 subprocess.check_call(cmd, env=_env, cwd=cwd) 151