Home | History | Annotate | Download | only in bots
      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