Home | History | Annotate | Download | only in lib
      1 # Copyright (c) 2013 The Chromium OS 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 """Classes for holding autoupdate_EndToEnd test parameters."""
      6 
      7 import common
      8 
      9 import test_control
     10 
     11 
     12 _DEFAULT_AU_SUITE_NAME = 'au'
     13 _additional_suite_names = ', push_to_prod'
     14 
     15 
     16 class TestEnv(object):
     17     """Contains and formats the environment arguments of a test."""
     18 
     19     def __init__(self, args):
     20         """Initial environment arguments object.
     21 
     22         @param args: parsed program arguments, including test environment ones
     23 
     24         """
     25         self._env_args_str_local = None
     26         self._env_args_str_afe = None
     27 
     28         # Distill environment arguments from all input arguments.
     29         self._env_args = {}
     30         omaha_host = vars(args).get('omaha_host')
     31         if omaha_host is not None:
     32             self._env_args['omaha_host'] = omaha_host
     33 
     34 
     35     def is_var_set(self, var):
     36         """Returns true if a variable is set in this environment.
     37 
     38         @param var: the variable we are interested in
     39 
     40         """
     41         return var in self._env_args
     42 
     43 
     44     def get_cmdline_args(self):
     45         """Return formatted environment arguments for command-line invocation.
     46 
     47         The formatted string is cached for repeated use.
     48 
     49         """
     50         if self._env_args_str_local is None:
     51             self._env_args_str_local = ''
     52             for key, val in self._env_args.iteritems():
     53                 # Convert Booleans to 'yes' / 'no'.
     54                 if val is True:
     55                     val = 'yes'
     56                 elif val is False:
     57                     val = 'no'
     58 
     59                 self._env_args_str_local += ' %s=%s' % (key, val)
     60 
     61         return self._env_args_str_local
     62 
     63 
     64     def get_code_args(self):
     65         """Return formatted environment arguments for inline assignment.
     66 
     67         The formatted string is cached for repeated use.
     68 
     69         """
     70         if self._env_args_str_afe is None:
     71             self._env_args_str_afe = ''
     72             for key, val in self._env_args.iteritems():
     73                 # Everything becomes a string, except for Booleans.
     74                 if type(val) is bool:
     75                     self._env_args_str_afe += "%s = %s\n" % (key, val)
     76                 else:
     77                     self._env_args_str_afe += "%s = '%s'\n" % (key, val)
     78 
     79         return self._env_args_str_afe
     80 
     81 
     82 class TestConfig(object):
     83     """A single test configuration.
     84 
     85     Stores and generates arguments for running autotest_EndToEndTest.
     86 
     87     """
     88     def __init__(self, board, name, is_delta_update, source_release,
     89                  target_release, source_payload_uri, target_payload_uri,
     90                  suite_name=_DEFAULT_AU_SUITE_NAME, source_archive_uri=None):
     91         """Initialize a test configuration.
     92 
     93         @param board: the board being tested (e.g. 'x86-alex')
     94         @param name: a descriptive name of the test
     95         @param is_delta_update: whether this is a delta update test (Boolean)
     96         @param source_release: the source image version (e.g. '2672.0.0')
     97         @param target_release: the target image version (e.g. '2673.0.0')
     98         @param source_payload_uri: source payload URI ('gs://...') or None
     99         @param target_payload_uri: target payload URI ('gs://...')
    100         @param suite_name: the name of the test suite (default: 'au')
    101         @param source_archive_uri: location of source build artifacts
    102 
    103         """
    104         self.board = board
    105         self.name = name
    106         self.is_delta_update = is_delta_update
    107         self.source_release = source_release
    108         self.target_release = target_release
    109         self.source_payload_uri = source_payload_uri
    110         self.target_payload_uri = target_payload_uri
    111         self.suite_name = suite_name
    112         self.source_archive_uri = source_archive_uri
    113 
    114 
    115     def get_update_type(self):
    116         return 'delta' if self.is_delta_update else 'full'
    117 
    118 
    119     def unique_name_suffix(self):
    120         """Unique name suffix for the test config given the target version."""
    121         return '%s_%s_%s' % (self.name,
    122                              'delta' if self.is_delta_update else 'full',
    123                              self.source_release)
    124 
    125 
    126     def get_autotest_name(self):
    127         """Returns job name to use when creating an autotest job.
    128 
    129         Returns a job name that conforms to the suite naming style.
    130 
    131         """
    132         return '%s-release/%s/%s/%s.%s' % (
    133                 self.board, self.target_release, self.suite_name,
    134                 test_control.get_test_name(), self.unique_name_suffix())
    135 
    136 
    137     def get_control_file_name(self):
    138         """Returns the name of the name of the control file to store this in.
    139 
    140         Returns the control file name that should be generated for this test.
    141         A unique name suffix is used to keep from collisions per target
    142         release/board.
    143         """
    144         return 'control.%s' % self.unique_name_suffix()
    145 
    146 
    147     def __str__(self):
    148         """Short textual representation w/o image/payload URIs."""
    149         return ('[%s/%s/%s/%s -> %s]' %
    150                 (self.board, self.name, self.get_update_type(),
    151                  self.source_release, self.target_release))
    152 
    153 
    154     def __repr__(self):
    155         """Full textual representation w/ image/payload URIs."""
    156         return '\n'.join([str(self),
    157                           'source payload : %s' % self.source_payload_uri,
    158                           'target payload : %s' % self.target_payload_uri])
    159 
    160 
    161     def _get_args(self, assign, delim, is_quote_val):
    162         template = "%s%s'%s'" if is_quote_val else "%s%s%s"
    163         arg_values = [
    164             ('name', self.name),
    165             ('update_type', self.get_update_type()),
    166             ('source_release', self.source_release),
    167             ('target_release', self.target_release),
    168             ('target_payload_uri', self.target_payload_uri),
    169             ('SUITE', self.suite_name)
    170         ]
    171         if self.source_payload_uri:
    172             arg_values.append(('source_payload_uri', self.source_payload_uri))
    173         if self.source_archive_uri:
    174             arg_values.append(('source_archive_uri', self.source_archive_uri))
    175 
    176         return delim.join(
    177                 [template % (key, assign, val) for key, val in arg_values])
    178 
    179 
    180     def get_cmdline_args(self):
    181         return self._get_args('=', ' ', False)
    182 
    183 
    184     def get_code_args(self):
    185         args = self._get_args(' = ', '\n', True)
    186         return args + '\n' if args else ''
    187