Home | History | Annotate | Download | only in flavor
      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 """Default flavor utils class, used for desktop bots."""
     10 
     11 
     12 import os
     13 import shutil
     14 import sys
     15 
     16 
     17 class DeviceDirs(object):
     18   def __init__(self,
     19                dm_dir,
     20                perf_data_dir,
     21                resource_dir,
     22                images_dir,
     23                skp_dir,
     24                tmp_dir):
     25     self._dm_dir = dm_dir
     26     self._perf_data_dir = perf_data_dir
     27     self._resource_dir = resource_dir
     28     self._images_dir = images_dir
     29     self._skp_dir = skp_dir
     30     self._tmp_dir = tmp_dir
     31 
     32   @property
     33   def dm_dir(self):
     34     """Where DM writes."""
     35     return self._dm_dir
     36 
     37   @property
     38   def perf_data_dir(self):
     39     return self._perf_data_dir
     40 
     41   @property
     42   def resource_dir(self):
     43     return self._resource_dir
     44 
     45   @property
     46   def images_dir(self):
     47     return self._images_dir
     48 
     49   @property
     50   def skp_dir(self):
     51     return self._skp_dir
     52 
     53   @property
     54   def tmp_dir(self):
     55     return self._tmp_dir
     56 
     57 
     58 class DefaultFlavorUtils(object):
     59   """Utilities to be used by build steps.
     60 
     61   The methods in this class define how certain high-level functions should
     62   work. Each build step flavor should correspond to a subclass of
     63   DefaultFlavorUtils which may override any of these functions as appropriate
     64   for that flavor.
     65 
     66   For example, the AndroidFlavorUtils will override the functions for
     67   copying files between the host and Android device, as well as the
     68   'step' function, so that commands may be run through ADB.
     69   """
     70   def __init__(self, bot_info, *args, **kwargs):
     71     self._bot_info = bot_info
     72     self.chrome_path = os.path.join(os.path.expanduser('~'), 'src')
     73 
     74   def step(self, cmd, **kwargs):
     75     """Runs a step as appropriate for this flavor."""
     76     path_to_app = self._bot_info.out_dir.join(
     77         self._bot_info.configuration, cmd[0])
     78     if (sys.platform == 'linux' and
     79         'x86_64' in self._bot_info.bot_name and
     80         not 'TSAN' in self._bot_info.bot_name):
     81       new_cmd = ['catchsegv', path_to_app]
     82     else:
     83       new_cmd = [path_to_app]
     84     new_cmd.extend(cmd[1:])
     85     return self._bot_info.run(new_cmd, **kwargs)
     86 
     87 
     88   def compile(self, target):
     89     """Build the given target."""
     90     # The CHROME_PATH environment variable is needed for bots that use
     91     # toolchains downloaded by Chrome.
     92     env = {'CHROME_PATH': self.chrome_path}
     93     if sys.platform == 'win32':
     94       make_cmd = ['python', 'make.py']
     95     else:
     96       make_cmd = ['make']
     97     cmd = make_cmd + [target]
     98     self._bot_info.run(cmd, env=env)
     99 
    100   def device_path_join(self, *args):
    101     """Like os.path.join(), but for paths on a connected device."""
    102     return os.path.join(*args)
    103 
    104   def device_path_exists(self, path):
    105     """Like os.path.exists(), but for paths on a connected device."""
    106     return os.path.exists(path, infra_step=True)  # pragma: no cover
    107 
    108   def copy_directory_contents_to_device(self, host_dir, device_dir):
    109     """Like shutil.copytree(), but for copying to a connected device."""
    110     # For "normal" bots who don't have an attached device, we expect
    111     # host_dir and device_dir to be the same.
    112     if str(host_dir) != str(device_dir):
    113       raise ValueError('For bots who do not have attached devices, copying '
    114                        'from host to device is undefined and only allowed if '
    115                        'host_path and device_path are the same (%s vs %s).' % (
    116                        str(host_dir), str(device_dir)))  # pragma: no cover
    117 
    118   def copy_directory_contents_to_host(self, device_dir, host_dir):
    119     """Like shutil.copytree(), but for copying from a connected device."""
    120     # For "normal" bots who don't have an attached device, we expect
    121     # host_dir and device_dir to be the same.
    122     if str(host_dir) != str(device_dir):
    123       raise ValueError('For bots who do not have attached devices, copying '
    124                        'from device to host is undefined and only allowed if '
    125                        'host_path and device_path are the same (%s vs %s).' % (
    126                        str(host_dir), str(device_dir)))  # pragma: no cover
    127 
    128   def copy_file_to_device(self, host_path, device_path):
    129     """Like shutil.copyfile, but for copying to a connected device."""
    130     # For "normal" bots who don't have an attached device, we expect
    131     # host_dir and device_dir to be the same.
    132     if str(host_path) != str(device_path):  # pragma: no cover
    133       raise ValueError('For bots who do not have attached devices, copying '
    134                        'from host to device is undefined and only allowed if '
    135                        'host_path and device_path are the same (%s vs %s).' % (
    136                        str(host_path), str(device_path)))
    137 
    138   def create_clean_device_dir(self, path):
    139     """Like shutil.rmtree() + os.makedirs(), but on a connected device."""
    140     self.create_clean_host_dir(path)
    141 
    142   def create_clean_host_dir(self, path):
    143     """Convenience function for creating a clean directory."""
    144     shutil.rmtree(path)
    145     os.makedirs(path)
    146 
    147   def install(self):
    148     """Run device-specific installation steps."""
    149     pass
    150 
    151   def cleanup_steps(self):
    152     """Run any device-specific cleanup steps."""
    153     pass
    154 
    155   def get_device_dirs(self):
    156     """ Set the directories which will be used by the build steps.
    157 
    158     These refer to paths on the same device where the test executables will
    159     run, for example, for Android bots these are paths on the Android device
    160     itself. For desktop bots, these are just local paths.
    161     """
    162     join = lambda p: os.path.join(self._bot_info.build_dir, p)
    163     return DeviceDirs(
    164         dm_dir=join('dm'),
    165         perf_data_dir=self._bot_info.perf_data_dir,
    166         resource_dir=self._bot_info.resource_dir,
    167         images_dir=join('images'),
    168         skp_dir=self._bot_info.local_skp_dir,
    169         tmp_dir=join('tmp'))
    170 
    171   def __repr__(self):
    172     return '<%s object>' % self.__class__.__name__  # pragma: no cover
    173