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 7import common 8 9import test_control 10 11 12_DEFAULT_AU_SUITE_NAME = 'au' 13_additional_suite_names = ', push_to_prod' 14 15 16class 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 82class 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