Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(246)

Side by Side Diff: au_test_harness/au_worker.py

Issue 6857004: Clean up extreme verbosity of logs in test harness. (Closed) Base URL: http://git.chromium.org/git/crostestutils.git@master
Patch Set: Last patch Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « au_test_harness/au_test.py ('k') | au_test_harness/cros_au_test_harness.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2011 The Chromium OS Authors. All rights reserved. 1 # Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Module that contains the interface for au_test_harness workers. 5 """Module that contains the interface for au_test_harness workers.
6 6
7 An au test harnss worker is a class that contains the logic for performing 7 An au test harnss worker is a class that contains the logic for performing
8 and validating updates on a target. This should be subclassed to handle 8 and validating updates on a target. This should be subclassed to handle
9 various types of target. Types of targets include VM's, real devices, etc. 9 various types of target. Types of targets include VM's, real devices, etc.
10 """ 10 """
(...skipping 30 matching lines...) Expand all
41 self.verify_suite = 'suite_Smoke' 41 self.verify_suite = 'suite_Smoke'
42 42
43 # Set these up as they are used often. 43 # Set these up as they are used often.
44 self.crosutils = cros_lib.GetCrosUtilsPath() 44 self.crosutils = cros_lib.GetCrosUtilsPath()
45 self.crosutilsbin = cros_lib.GetCrosUtilsBinPath() 45 self.crosutilsbin = cros_lib.GetCrosUtilsBinPath()
46 46
47 def CleanUp(self): 47 def CleanUp(self):
48 """Called at the end of every test.""" 48 """Called at the end of every test."""
49 pass 49 pass
50 50
51 def GetUpdateMessage(self, update_target, update_base, from_vm, proxy):
52 if update_base:
53 str = 'Performing a delta update from %s to %s' % (
54 update_base, update_target)
55 else:
56 str = 'Performing a full update to %s' % update_target
57
58 if from_vm: str += ' in a VM'
59 if proxy: ' using a proxy on port %s' % proxy
60 return str
61
51 def UpdateImage(self, image_path, src_image_path='', stateful_change='old', 62 def UpdateImage(self, image_path, src_image_path='', stateful_change='old',
52 proxy_port=None, private_key_path=None): 63 proxy_port=None, private_key_path=None):
53 """Implementation of an actual update. 64 """Implementation of an actual update.
54 65
55 See PerformUpdate for description of args. Subclasses must override this 66 See PerformUpdate for description of args. Subclasses must override this
56 method with the correct update procedure for the class. 67 method with the correct update procedure for the class.
57 """ 68 """
58 pass 69 pass
59 70
60 def UpdateUsingPayload(self, update_path, stateful_change='old', 71 def UpdateUsingPayload(self, update_path, stateful_change='old',
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 image specified by the path as the source image. 115 image specified by the path as the source image.
105 stateful_change: How to modify the stateful partition. Values are: 116 stateful_change: How to modify the stateful partition. Values are:
106 'old': Don't modify stateful partition. Just update normally. 117 'old': Don't modify stateful partition. Just update normally.
107 'clean': Uses clobber-state to wipe the stateful partition with the 118 'clean': Uses clobber-state to wipe the stateful partition with the
108 exception of code needed for ssh. 119 exception of code needed for ssh.
109 proxy_port: Port to have the client connect to. For use with 120 proxy_port: Port to have the client connect to. For use with
110 CrosTestProxy. 121 CrosTestProxy.
111 private_key_path: Path to a private key to use with update payload. 122 private_key_path: Path to a private key to use with update payload.
112 Raises an update_exception.UpdateException if _UpdateImage returns an error. 123 Raises an update_exception.UpdateException if _UpdateImage returns an error.
113 """ 124 """
114 try: 125 if not self.use_delta_updates: src_image_path = ''
115 if not self.use_delta_updates: src_image_path = '' 126 if private_key_path:
116 if private_key_path: 127 key_to_use = private_key_path
117 key_to_use = private_key_path 128 else:
118 else: 129 key_to_use = self.private_key
119 key_to_use = self.private_key
120 130
121 self.UpdateImage(image_path, src_image_path, stateful_change, 131 self.UpdateImage(image_path, src_image_path, stateful_change,
122 proxy_port, key_to_use) 132 proxy_port, key_to_use)
123 except update_exception.UpdateException as err:
124 # If the update fails, print it out
125 Warning(err.stdout)
126 raise
127 133
128 @classmethod 134 @classmethod
129 def SetUpdateCache(cls, update_cache): 135 def SetUpdateCache(cls, update_cache):
130 """Sets the global update cache for getting paths to devserver payloads.""" 136 """Sets the global update cache for getting paths to devserver payloads."""
131 cls.update_cache = update_cache 137 cls.update_cache = update_cache
132 138
133 # --- METHODS FOR SUB CLASS USE --- 139 # --- METHODS FOR SUB CLASS USE ---
134 140
135 def PrepareRealBase(self, image_path): 141 def PrepareRealBase(self, image_path):
136 """Prepares a remote device for worker test by updating it to the image.""" 142 """Prepares a remote device for worker test by updating it to the image."""
(...skipping 17 matching lines...) Expand all
154 cros_lib.RunCommand(['./image_to_vm.sh', 160 cros_lib.RunCommand(['./image_to_vm.sh',
155 '--full', 161 '--full',
156 '--from=%s' % cros_lib.ReinterpretPathForChroot( 162 '--from=%s' % cros_lib.ReinterpretPathForChroot(
157 os.path.dirname(image_path)), 163 os.path.dirname(image_path)),
158 '--vdisk_size=%s' % FULL_VDISK_SIZE, 164 '--vdisk_size=%s' % FULL_VDISK_SIZE,
159 '--statefulfs_size=%s' % FULL_STATEFULFS_SIZE, 165 '--statefulfs_size=%s' % FULL_STATEFULFS_SIZE,
160 '--board=%s' % self.board, 166 '--board=%s' % self.board,
161 '--test_image' 167 '--test_image'
162 ], enter_chroot=True, cwd=self.crosutils) 168 ], enter_chroot=True, cwd=self.crosutils)
163 169
164 cros_lib.Info('Using %s as base' % self.vm_image_path)
165 assert os.path.exists(self.vm_image_path) 170 assert os.path.exists(self.vm_image_path)
166 171
167 def GetStatefulChangeFlag(self, stateful_change): 172 def GetStatefulChangeFlag(self, stateful_change):
168 """Returns the flag to pass to image_to_vm for the stateful change.""" 173 """Returns the flag to pass to image_to_vm for the stateful change."""
169 stateful_change_flag = '' 174 stateful_change_flag = ''
170 if stateful_change: 175 if stateful_change:
171 stateful_change_flag = '--stateful_update_flag=%s' % stateful_change 176 stateful_change_flag = '--stateful_update_flag=%s' % stateful_change
172 177
173 return stateful_change_flag 178 return stateful_change_flag
174 179
175 def AppendUpdateFlags(self, cmd, image_path, src_image_path, proxy_port, 180 def AppendUpdateFlags(self, cmd, image_path, src_image_path, proxy_port,
176 private_key_path): 181 private_key_path):
177 """Appends common args to an update cmd defined by an array. 182 """Appends common args to an update cmd defined by an array.
178 183
179 Modifies cmd in places by appending appropriate items given args. 184 Modifies cmd in places by appending appropriate items given args.
180 """ 185 """
181 if proxy_port: cmd.append('--proxy_port=%s' % proxy_port) 186 if proxy_port: cmd.append('--proxy_port=%s' % proxy_port)
182
183 # Get pregenerated update if we have one. 187 # Get pregenerated update if we have one.
184 update_id = dev_server_wrapper.GenerateUpdateId(image_path, src_image_path, 188 update_id = dev_server_wrapper.GenerateUpdateId(image_path, src_image_path,
185 private_key_path) 189 private_key_path)
186 cache_path = self.update_cache[update_id] 190 cache_path = self.update_cache[update_id]
187 if cache_path: 191 if cache_path:
188 update_url = dev_server_wrapper.DevServerWrapper.GetDevServerURL( 192 update_url = dev_server_wrapper.DevServerWrapper.GetDevServerURL(
189 proxy_port, cache_path) 193 proxy_port, cache_path)
190 cmd.append('--update_url=%s' % update_url) 194 cmd.append('--update_url=%s' % update_url)
191 else: 195 else:
192 cmd.append('--image=%s' % image_path) 196 cmd.append('--image=%s' % image_path)
193 if src_image_path: cmd.append('--src_image=%s' % src_image_path) 197 if src_image_path: cmd.append('--src_image=%s' % src_image_path)
194 198
195 def RunUpdateCmd(self, cmd, log_directory=None): 199 def RunUpdateCmd(self, cmd, log_directory=None):
196 """Runs the given update cmd given verbose options. 200 """Runs the given update cmd given verbose options.
197 201
198 Raises an update_exception.UpdateException if the update fails. 202 Raises an update_exception.UpdateException if the update fails.
199 """ 203 """
200 if self.verbose: 204 if self.verbose:
201 try: 205 try:
202 if log_directory: 206 if log_directory:
203 cros_lib.RunCommand(cmd, log_to_file=os.path.join(log_directory, 207 cros_lib.RunCommand(
204 'update.log')) 208 cmd, log_to_file=os.path.join(log_directory, 'update.log'),
209 print_cmd=False)
205 else: 210 else:
206 cros_lib.RunCommand(cmd) 211 cros_lib.RunCommand(cmd, print_cmd=False)
207 except Exception as e: 212 except cros_lib.RunCommandException as e:
208 Warning(str(e))
209 raise update_exception.UpdateException(1, str(e)) 213 raise update_exception.UpdateException(1, str(e))
210 else: 214 else:
211 (code, stdout, stderr) = cros_lib.RunCommandCaptureOutput(cmd) 215 (code, stdout, unused_stderr) = cros_lib.RunCommandCaptureOutput(
216 cmd, print_cmd=False)
212 if code != 0: 217 if code != 0:
213 Warning(stdout) 218 cros_lib.Warning(stdout)
214 raise update_exception.UpdateException(code, stdout) 219 raise update_exception.UpdateException(code, stdout)
215 220
216 def AssertEnoughTestsPassed(self, unittest, output, percent_required_to_pass): 221 def AssertEnoughTestsPassed(self, unittest, output, percent_required_to_pass):
217 """Helper function that asserts a sufficient number of tests passed. 222 """Helper function that asserts a sufficient number of tests passed.
218 223
219 Args: 224 Args:
220 output: stdout from a test run. 225 output: stdout from a test run.
221 percent_required_to_pass: percentage required to pass. This should be 226 percent_required_to_pass: percentage required to pass. This should be
222 fall between 0-100. 227 fall between 0-100.
223 Returns: 228 Returns:
224 percent that passed. 229 percent that passed.
225 """ 230 """
226 cros_lib.Info('Output from VerifyImage():')
227 print >> sys.stderr, output
228 sys.stderr.flush()
229 percent_passed = self._ParseGenerateTestReportOutput(output) 231 percent_passed = self._ParseGenerateTestReportOutput(output)
230 cros_lib.Info('Percent passed: %d vs. Percent required: %d' % ( 232 self.TestInfo('Percent passed: %d vs. Percent required: %d' % (
231 percent_passed, percent_required_to_pass)) 233 percent_passed, percent_required_to_pass))
232 unittest.assertTrue(percent_passed >= percent_required_to_pass) 234 if percent_passed < percent_required_to_pass:
235 print output
236 unittest.fail('%d percent of tests are required to pass' %
237 percent_required_to_pass)
238
233 return percent_passed 239 return percent_passed
234 240
241 def TestInfo(self, message):
242 cros_lib.Info('%s: %s' % (self.test_name, message))
243
235 def Initialize(self, port): 244 def Initialize(self, port):
236 """Initializes test specific variables for each test. 245 """Initializes test specific variables for each test.
237 246
238 Each test needs to specify a unique ssh port. 247 Each test needs to specify a unique ssh port.
239 248
240 Args: 249 Args:
241 port: Unique port for ssh access. 250 port: Unique port for ssh access.
242 """ 251 """
243 # Initialize port vars. 252 # Initialize port vars.
244 self._ssh_port = port 253 self._ssh_port = port
245 self._kvm_pid_file = '/tmp/kvm.%d' % port 254 self._kvm_pid_file = '/tmp/kvm.%d' % port
246 255
247 # Initialize test results directory. 256 # Initialize test results directory.
248 test_name = inspect.stack()[1][3] 257 self.test_name = inspect.stack()[1][3]
249 self.results_directory = os.path.join(self.test_results_root, test_name) 258 self.results_directory = os.path.join(self.test_results_root,
259 self.test_name)
250 self.results_count = 0 260 self.results_count = 0
251 261
252 def GetNextResultsPath(self, label): 262 def GetNextResultsPath(self, label):
253 """Returns a path for the results directory for this label. 263 """Returns a path for the results directory for this label.
254 264
255 Prefixes directory returned for worker with time called i.e. 1_label, 265 Prefixes directory returned for worker with time called i.e. 1_label,
256 2_label, etc. The directory returned is outside the chroot so if passing 266 2_label, etc. The directory returned is outside the chroot so if passing
257 to an script that is called with enther_chroot, make sure to use 267 to an script that is called with enther_chroot, make sure to use
258 ReinterpretPathForChroot. 268 ReinterpretPathForChroot.
259 """ 269 """
260 self.results_count += 1 270 self.results_count += 1
261 dir = os.path.join(self.results_directory, '%s_%s' % (self.results_count, 271 dir = os.path.join(self.results_directory, '%s_%s' % (self.results_count,
262 label)) 272 label))
263 if not os.path.exists(dir): 273 if not os.path.exists(dir):
264 os.makedirs(dir) 274 os.makedirs(dir)
265 275
266 return dir 276 return dir
267 277
268 # --- PRIVATE HELPER FUNCTIONS --- 278 # --- PRIVATE HELPER FUNCTIONS ---
269 279
270 def _ParseGenerateTestReportOutput(self, output): 280 def _ParseGenerateTestReportOutput(self, output):
271 """Returns the percentage of tests that passed based on output.""" 281 """Returns the percentage of tests that passed based on output."""
272 percent_passed = 0 282 percent_passed = 0
273 lines = output.split('\n') 283 lines = output.split('\n')
274 284
275 for line in lines: 285 for line in lines:
276 if line.startswith("Total PASS:"): 286 if line.startswith("Total PASS:"):
277 # FORMAT: ^TOTAL PASS: num_passed/num_total (percent%)$ 287 # FORMAT: ^TOTAL PASS: num_passed/num_total (percent%)$
278 percent_passed = line.split()[3].strip('()%') 288 percent_passed = line.split()[3].strip('()%')
279 cros_lib.Info('Percent of tests passed %s' % percent_passed)
280 break 289 break
281 290
282 return int(percent_passed) 291 return int(percent_passed)
OLDNEW
« no previous file with comments | « au_test_harness/au_test.py ('k') | au_test_harness/cros_au_test_harness.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698