Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 | 2 |
| 3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| 4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
| 6 | 6 |
| 7 import optparse | 7 import optparse |
| 8 import os | 8 import os |
| 9 import re | |
| 9 import sys | 10 import sys |
| 10 import unittest | 11 import unittest |
| 12 import urllib | |
| 11 | 13 |
| 12 sys.path.append(os.path.join(os.path.dirname(__file__), '../lib')) | 14 sys.path.append(os.path.join(os.path.dirname(__file__), '../lib')) |
| 13 from cros_build_lib import Die | 15 from cros_build_lib import Die |
| 14 from cros_build_lib import Info | 16 from cros_build_lib import Info |
| 15 from cros_build_lib import ReinterpretPathForChroot | 17 from cros_build_lib import ReinterpretPathForChroot |
| 16 from cros_build_lib import RunCommand | 18 from cros_build_lib import RunCommand |
| 19 from cros_build_lib import RunCommandCaptureOutput | |
| 17 from cros_build_lib import Warning | 20 from cros_build_lib import Warning |
| 18 | 21 |
| 19 # VM Constants. | 22 # VM Constants. |
| 20 _FULL_VDISK_SIZE = 6072 | 23 _FULL_VDISK_SIZE = 6072 |
| 21 _FULL_STATEFULFS_SIZE = 3074 | 24 _FULL_STATEFULFS_SIZE = 3074 |
| 22 _KVM_PID_FILE = '/tmp/harness_pid' | 25 _KVM_PID_FILE = '/tmp/harness_pid' |
| 23 _VERIFY_SUITE = 'suite_Smoke' | 26 _VERIFY_SUITE = 'suite_Smoke' |
| 24 | 27 |
| 25 # Globals to communicate options to unit tests. | 28 # Globals to communicate options to unit tests. |
| 26 global base_image_path | 29 global base_image_path |
| 27 global board | 30 global board |
| 28 global remote | 31 global remote |
| 29 global target_image_path | 32 global target_image_path |
| 30 global vm_graphics_flag | 33 global vm_graphics_flag |
| 31 | 34 |
| 35 class UpdateException(Exception): | |
| 36 """Exception thrown when UpdateImage or UpdateUsingPayload fail""" | |
| 37 def __init__(self, code, stdout): | |
| 38 self.code = code | |
| 39 self.stdout = stdout | |
| 32 | 40 |
| 33 class AUTest(object): | 41 class AUTest(object): |
| 34 """Abstract interface that defines an Auto Update test.""" | 42 """Abstract interface that defines an Auto Update test.""" |
| 35 source_image = '' | 43 source_image = '' |
| 36 use_delta_updates = False | 44 use_delta_updates = False |
| 37 | 45 |
| 38 def setUp(self): | 46 def setUp(self): |
| 39 unittest.TestCase.setUp(self) | 47 unittest.TestCase.setUp(self) |
| 40 # Set these up as they are used often. | 48 # Set these up as they are used often. |
| 41 self.crosutils = os.path.join(os.path.dirname(__file__), '..') | 49 self.crosutils = os.path.join(os.path.dirname(__file__), '..') |
| 42 self.crosutilsbin = os.path.join(os.path.dirname(__file__)) | 50 self.crosutilsbin = os.path.join(os.path.dirname(__file__)) |
| 51 self.download_folder = os.path.join(self.crosutilsbin, 'latest_download') | |
| 43 | 52 |
| 44 def GetStatefulChangeFlag(self, stateful_change): | 53 def GetStatefulChangeFlag(self, stateful_change): |
| 45 """Returns the flag to pass to image_to_vm for the stateful change.""" | 54 """Returns the flag to pass to image_to_vm for the stateful change.""" |
| 46 stateful_change_flag = '' | 55 stateful_change_flag = '' |
| 47 if stateful_change: | 56 if stateful_change: |
| 48 stateful_change_flag = '--stateful_update_flag=%s' % stateful_change | 57 stateful_change_flag = '--stateful_update_flag=%s' % stateful_change |
| 49 | 58 |
| 50 return stateful_change_flag | 59 return stateful_change_flag |
| 51 | 60 |
| 52 def ParseGenerateTestReportOutput(self, output): | 61 def ParseGenerateTestReportOutput(self, output): |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 67 def TryDeltaAndFallbackToFull(self, src_image, image, stateful_change='old'): | 76 def TryDeltaAndFallbackToFull(self, src_image, image, stateful_change='old'): |
| 68 """Tries the delta update first if set and falls back to full update.""" | 77 """Tries the delta update first if set and falls back to full update.""" |
| 69 if self.use_delta_updates: | 78 if self.use_delta_updates: |
| 70 try: | 79 try: |
| 71 self.source_image = src_image | 80 self.source_image = src_image |
| 72 self.UpdateImage(image) | 81 self.UpdateImage(image) |
| 73 except: | 82 except: |
| 74 Warning('Delta update failed, disabling delta updates and retrying.') | 83 Warning('Delta update failed, disabling delta updates and retrying.') |
| 75 self.use_delta_updates = False | 84 self.use_delta_updates = False |
| 76 self.source_image = '' | 85 self.source_image = '' |
| 77 self.UpdateImage(image) | 86 self._UpdateImageReportError(image) |
| 78 else: | 87 else: |
| 79 self.UpdateImage(image) | 88 self._UpdateImageReportError(image) |
| 80 | 89 |
| 81 def PrepareBase(self): | 90 def _UpdateImageReportError(self, image_path, stateful_change='old'): |
| 91 """Calls UpdateImage and reports any error to the console. | |
| 92 | |
| 93 Still throws the exception. | |
| 94 """ | |
| 95 try: | |
| 96 self.UpdateImage(image_path, stateful_change) | |
| 97 except UpdateException as err: | |
| 98 # If the update fails, print it out | |
| 99 Warning(err.stdout) | |
| 100 raise | |
| 101 | |
| 102 def _AttemptUpdateWithPayloadExpectedFailure(self, payload, expected_msg): | |
| 103 # This update is expected to fail... | |
| 104 try: | |
| 105 self.UpdateUsingPayload(payload) | |
| 106 except UpdateException as err: | |
| 107 # Will raise ValueError if expected is not found. | |
| 108 if re.search(re.escape(expected_msg), err.stdout, re.MULTILINE): | |
| 109 return | |
| 110 | |
| 111 Warning("Didn't find '%s' in:" % expected_msg) | |
| 112 Warning(err.stdout) | |
| 113 self.fail('We managed to update when failure was expected') | |
| 114 | |
| 115 def PrepareBase(self, image_path): | |
| 82 """Prepares target with base_image_path.""" | 116 """Prepares target with base_image_path.""" |
| 83 pass | 117 pass |
| 84 | 118 |
| 85 def UpdateImage(self, image_path, stateful_change='old'): | 119 def UpdateImage(self, image_path, stateful_change='old'): |
| 86 """Updates target with the image given by the image_path. | 120 """Updates target with the image given by the image_path. |
| 87 | 121 |
| 88 Args: | 122 Args: |
| 89 image_path: Path to the image to update with. This image must be a test | 123 image_path: Path to the image to update with. This image must be a test |
| 90 image. | 124 image. |
| 91 stateful_change: How to modify the stateful partition. Values are: | 125 stateful_change: How to modify the stateful partition. Values are: |
| 92 'old': Don't modify stateful partition. Just update normally. | 126 'old': Don't modify stateful partition. Just update normally. |
| 93 'clean': Uses clobber-state to wipe the stateful partition with the | 127 'clean': Uses clobber-state to wipe the stateful partition with the |
| 94 exception of code needed for ssh. | 128 exception of code needed for ssh. |
| 95 """ | 129 """ |
| 96 pass | 130 pass |
| 97 | 131 |
| 132 def UpdateUsingPayload(self, update_path, stateful_change='old'): | |
| 133 """Updates target with the pre-generated update stored in update_path | |
| 134 | |
| 135 Args: | |
| 136 update_path: Path to the image to update with. This directory should | |
| 137 contain both update.gz, and stateful.image.gz | |
| 138 """ | |
| 139 pass | |
| 140 | |
| 98 def VerifyImage(self, percent_required_to_pass): | 141 def VerifyImage(self, percent_required_to_pass): |
| 99 """Verifies the image with tests. | 142 """Verifies the image with tests. |
| 100 | 143 |
| 101 Verifies that the test images passes the percent required. | 144 Verifies that the test images passes the percent required. |
| 102 | 145 |
| 103 Args: | 146 Args: |
| 104 percent_required_to_pass: percentage required to pass. This should be | 147 percent_required_to_pass: percentage required to pass. This should be |
| 105 fall between 0-100. | 148 fall between 0-100. |
| 106 | 149 |
| 107 Returns: | 150 Returns: |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 133 return percent_passed | 176 return percent_passed |
| 134 | 177 |
| 135 def testFullUpdateKeepStateful(self): | 178 def testFullUpdateKeepStateful(self): |
| 136 """Tests if we can update normally. | 179 """Tests if we can update normally. |
| 137 | 180 |
| 138 This test checks that we can update by updating the stateful partition | 181 This test checks that we can update by updating the stateful partition |
| 139 rather than wiping it. | 182 rather than wiping it. |
| 140 """ | 183 """ |
| 141 # Just make sure some tests pass on original image. Some old images | 184 # Just make sure some tests pass on original image. Some old images |
| 142 # don't pass many tests. | 185 # don't pass many tests. |
| 143 self.PrepareBase() | 186 self.PrepareBase(base_image_path) |
| 144 # TODO(sosa): move to 100% once we start testing using the autotest paired | 187 # TODO(sosa): move to 100% once we start testing using the autotest paired |
| 145 # with the dev channel. | 188 # with the dev channel. |
| 146 percent_passed = self.VerifyImage(10) | 189 percent_passed = self.VerifyImage(10) |
| 147 | 190 |
| 148 # Update to - all tests should pass on new image. | 191 # Update to - all tests should pass on new image. |
| 149 Info('Updating from base image on vm to target image.') | 192 Info('Updating from base image on vm to target image.') |
| 150 self.TryDeltaAndFallbackToFull(base_image_path, target_image_path) | 193 self.TryDeltaAndFallbackToFull(base_image_path, target_image_path) |
| 151 self.VerifyImage(100) | 194 self.VerifyImage(100) |
| 152 | 195 |
| 153 # Update from - same percentage should pass that originally passed. | 196 # Update from - same percentage should pass that originally passed. |
| 154 Info('Updating from updated image on vm back to base image.') | 197 Info('Updating from updated image on vm back to base image.') |
| 155 self.TryDeltaAndFallbackToFull(target_image_path, base_image_path) | 198 self.TryDeltaAndFallbackToFull(target_image_path, base_image_path) |
| 156 self.VerifyImage(percent_passed) | 199 self.VerifyImage(percent_passed) |
| 157 | 200 |
| 158 def testFullUpdateWipeStateful(self): | 201 def testFullUpdateWipeStateful(self): |
| 159 """Tests if we can update after cleaning the stateful partition. | 202 """Tests if we can update after cleaning the stateful partition. |
| 160 | 203 |
| 161 This test checks that we can update successfully after wiping the | 204 This test checks that we can update successfully after wiping the |
| 162 stateful partition. | 205 stateful partition. |
| 163 """ | 206 """ |
| 164 # Just make sure some tests pass on original image. Some old images | 207 # Just make sure some tests pass on original image. Some old images |
| 165 # don't pass many tests. | 208 # don't pass many tests. |
| 166 self.PrepareBase() | 209 self.PrepareBase(base_image_path) |
|
sosa
2010/12/03 01:07:38
use image_path?
| |
| 167 # TODO(sosa): move to 100% once we start testing using the autotest paired | 210 # TODO(sosa): move to 100% once we start testing using the autotest paired |
| 168 # with the dev channel. | 211 # with the dev channel. |
| 169 percent_passed = self.VerifyImage(10) | 212 percent_passed = self.VerifyImage(10) |
| 170 | 213 |
| 171 # Update to - all tests should pass on new image. | 214 # Update to - all tests should pass on new image. |
| 172 Info('Updating from base image on vm to target image and wiping stateful.') | 215 Info('Updating from base image on vm to target image and wiping stateful.') |
| 173 self.TryDeltaAndFallbackToFull(base_image_path, target_image_path, 'clean') | 216 self.TryDeltaAndFallbackToFull(base_image_path, target_image_path, 'clean') |
| 174 self.VerifyImage(100) | 217 self.VerifyImage(100) |
| 175 | 218 |
| 176 # Update from - same percentage should pass that originally passed. | 219 # Update from - same percentage should pass that originally passed. |
| 177 Info('Updating from updated image back to base image and wiping stateful.') | 220 Info('Updating from updated image back to base image and wiping stateful.') |
| 178 self.TryDeltaAndFallbackToFull(target_image_path, base_image_path, 'clean') | 221 self.TryDeltaAndFallbackToFull(target_image_path, base_image_path, 'clean') |
| 179 self.VerifyImage(percent_passed) | 222 self.VerifyImage(percent_passed) |
| 180 | 223 |
| 224 def testPartialUpdate(self): | |
| 225 """Tests what happens if we attempt to update with a truncated payload.""" | |
| 226 # Preload with the version we are trying to test. | |
| 227 self.PrepareBase(target_image_path) | |
| 228 | |
| 229 # Image can be updated at: | |
| 230 # ~chrome-eng/chromeos/localmirror/autest-images | |
| 231 url = 'http://gsdview.appspot.com/chromeos-localmirror/' \ | |
| 232 'autest-images/truncated_image.gz' | |
| 233 payload = os.path.join(self.download_folder, 'truncated_image.gz') | |
| 234 | |
| 235 # Read from the URL and write to the local file | |
| 236 urllib.urlretrieve(url, payload) | |
| 237 | |
| 238 expected_msg='download_hash_data == update_check_response_hash failed' | |
| 239 self._AttemptUpdateWithPayloadExpectedFailure(payload, expected_msg) | |
| 240 | |
| 241 def testCorruptedUpdate(self): | |
| 242 """Tests what happens if we attempt to update with a corrupted payload.""" | |
| 243 # Preload with the version we are trying to test. | |
| 244 self.PrepareBase(target_image_path) | |
| 245 | |
| 246 # Image can be updated at: | |
| 247 # ~chrome-eng/chromeos/localmirror/autest-images | |
| 248 url = 'http://gsdview.appspot.com/chromeos-localmirror/' \ | |
| 249 'autest-images/corrupted_image.gz' | |
| 250 payload = os.path.join(self.download_folder, 'corrupted.gz') | |
| 251 | |
| 252 # Read from the URL and write to the local file | |
| 253 urllib.urlretrieve(url, payload) | |
| 254 | |
| 255 # This update is expected to fail... | |
| 256 expected_msg='zlib inflate() error:-3' | |
| 257 self._AttemptUpdateWithPayloadExpectedFailure(payload, expected_msg) | |
| 181 | 258 |
| 182 class RealAUTest(unittest.TestCase, AUTest): | 259 class RealAUTest(unittest.TestCase, AUTest): |
| 183 """Test harness for updating real images.""" | 260 """Test harness for updating real images.""" |
| 184 | 261 |
| 185 def setUp(self): | 262 def setUp(self): |
| 186 AUTest.setUp(self) | 263 AUTest.setUp(self) |
| 187 | 264 |
| 188 def PrepareBase(self): | 265 def PrepareBase(self, image_path): |
| 189 """Auto-update to base image to prepare for test.""" | 266 """Auto-update to base image to prepare for test.""" |
| 190 self.UpdateImage(base_image_path) | 267 self._UpdateImageReportError(image_path) |
| 191 | 268 |
| 192 def UpdateImage(self, image_path, stateful_change='old'): | 269 def UpdateImage(self, image_path, stateful_change='old'): |
| 193 """Updates a remote image using image_to_live.sh.""" | 270 """Updates a remote image using image_to_live.sh.""" |
| 194 stateful_change_flag = self.GetStatefulChangeFlag(stateful_change) | 271 stateful_change_flag = self.GetStatefulChangeFlag(stateful_change) |
| 195 | 272 |
| 196 RunCommand([ | 273 (code, stdout, stderr) = RunCommandCaptureOutput([ |
| 197 '%s/image_to_live.sh' % self.crosutils, | 274 '%s/image_to_live.sh' % self.crosutils, |
| 198 '--image=%s' % image_path, | 275 '--image=%s' % image_path, |
| 199 '--remote=%s' % remote, | 276 '--remote=%s' % remote, |
| 200 stateful_change_flag, | 277 stateful_change_flag, |
| 201 '--verify', | 278 '--verify', |
| 202 '--src_image=%s' % self.source_image, | 279 '--src_image=%s' % self.source_image |
| 203 ], enter_chroot=False) | 280 ]) |
| 204 | 281 |
| 282 if code != 0: | |
| 283 raise UpdateException(code, stdout) | |
| 284 | |
| 285 def UpdateUsingPayload(self, update_path, stateful_change='old'): | |
| 286 """Updates a remote image using image_to_live.sh.""" | |
| 287 stateful_change_flag = self.GetStatefulChangeFlag(stateful_change) | |
| 288 | |
| 289 (code, stdout, stderr) = RunCommandCaptureOutput([ | |
| 290 '%s/image_to_live.sh' % self.crosutils, | |
| 291 '--payload=%s' % update_path, | |
| 292 '--remote=%s' % remote, | |
| 293 stateful_change_flag, | |
| 294 '--verify', | |
| 295 ]) | |
| 296 | |
| 297 if code != 0: | |
| 298 raise UpdateException(code, stdout) | |
| 205 | 299 |
| 206 def VerifyImage(self, percent_required_to_pass): | 300 def VerifyImage(self, percent_required_to_pass): |
| 207 """Verifies an image using run_remote_tests.sh with verification suite.""" | 301 """Verifies an image using run_remote_tests.sh with verification suite.""" |
| 208 output = RunCommand([ | 302 output = RunCommand([ |
| 209 '%s/run_remote_tests.sh' % self.crosutils, | 303 '%s/run_remote_tests.sh' % self.crosutils, |
| 210 '--remote=%s' % remote, | 304 '--remote=%s' % remote, |
| 211 _VERIFY_SUITE, | 305 _VERIFY_SUITE, |
| 212 ], error_ok=True, enter_chroot=False, redirect_stdout=True) | 306 ], error_ok=True, enter_chroot=False, redirect_stdout=True) |
| 213 return self.CommonVerifyImage(self, output, percent_required_to_pass) | 307 return self.CommonVerifyImage(self, output, percent_required_to_pass) |
| 214 | 308 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 226 if pid: | 320 if pid: |
| 227 RunCommand(['sudo', 'kill', pid.strip()], error_ok=True, | 321 RunCommand(['sudo', 'kill', pid.strip()], error_ok=True, |
| 228 enter_chroot=False) | 322 enter_chroot=False) |
| 229 RunCommand(['sudo', 'rm', pid_file], enter_chroot=False) | 323 RunCommand(['sudo', 'rm', pid_file], enter_chroot=False) |
| 230 | 324 |
| 231 def setUp(self): | 325 def setUp(self): |
| 232 """Unit test overriden method. Is called before every test.""" | 326 """Unit test overriden method. Is called before every test.""" |
| 233 AUTest.setUp(self) | 327 AUTest.setUp(self) |
| 234 self._KillExistingVM(_KVM_PID_FILE) | 328 self._KillExistingVM(_KVM_PID_FILE) |
| 235 | 329 |
| 236 def PrepareBase(self): | 330 def PrepareBase(self, image_path): |
| 237 """Creates an update-able VM based on base image.""" | 331 """Creates an update-able VM based on base image.""" |
| 238 self.vm_image_path = '%s/chromiumos_qemu_image.bin' % os.path.dirname( | 332 self.vm_image_path = '%s/chromiumos_qemu_image.bin' % os.path.dirname( |
| 239 base_image_path) | 333 image_path) |
| 334 | |
| 335 Info('Creating: %s' % self.vm_image_path) | |
| 240 | 336 |
| 241 if not os.path.exists(self.vm_image_path): | 337 if not os.path.exists(self.vm_image_path): |
| 242 Info('Qemu image %s not found, creating one.' % self.vm_image_path) | 338 Info('Qemu image %s not found, creating one.' % self.vm_image_path) |
| 243 RunCommand(['%s/image_to_vm.sh' % self.crosutils, | 339 RunCommand(['%s/image_to_vm.sh' % self.crosutils, |
| 244 '--full', | 340 '--full', |
| 245 '--from=%s' % ReinterpretPathForChroot( | 341 '--from=%s' % ReinterpretPathForChroot( |
| 246 os.path.dirname(base_image_path)), | 342 os.path.dirname(image_path)), |
| 247 '--vdisk_size=%s' % _FULL_VDISK_SIZE, | 343 '--vdisk_size=%s' % _FULL_VDISK_SIZE, |
| 248 '--statefulfs_size=%s' % _FULL_STATEFULFS_SIZE, | 344 '--statefulfs_size=%s' % _FULL_STATEFULFS_SIZE, |
| 249 '--board=%s' % board, | 345 '--board=%s' % board, |
| 250 '--test_image'], enter_chroot=True) | 346 '--test_image'], enter_chroot=True) |
| 251 else: | 347 else: |
| 252 Info('Using existing VM image %s' % self.vm_image_path) | 348 Info('Using existing VM image %s' % self.vm_image_path) |
| 253 | 349 |
| 350 | |
| 351 Info('Testing for %s' % self.vm_image_path) | |
| 352 | |
| 254 self.assertTrue(os.path.exists(self.vm_image_path)) | 353 self.assertTrue(os.path.exists(self.vm_image_path)) |
| 255 | 354 |
| 256 def UpdateImage(self, image_path, stateful_change='old'): | 355 def UpdateImage(self, image_path, stateful_change='old'): |
| 257 """Updates VM image with image_path.""" | 356 """Updates VM image with image_path.""" |
| 258 stateful_change_flag = self.GetStatefulChangeFlag(stateful_change) | 357 stateful_change_flag = self.GetStatefulChangeFlag(stateful_change) |
| 259 if self.source_image == base_image_path: | 358 if self.source_image == base_image_path: |
| 260 self.source_image = self.vm_image_path | 359 self.source_image = self.vm_image_path |
| 261 | 360 |
| 262 RunCommand(['%s/cros_run_vm_update' % self.crosutilsbin, | 361 (code, stdout, stderr) = RunCommandCaptureOutput([ |
| 263 '--update_image_path=%s' % image_path, | 362 '%s/cros_run_vm_update' % self.crosutilsbin, |
| 264 '--vm_image_path=%s' % self.vm_image_path, | 363 '--update_image_path=%s' % image_path, |
| 265 '--snapshot', | 364 '--vm_image_path=%s' % self.vm_image_path, |
| 266 vm_graphics_flag, | 365 '--snapshot', |
| 267 '--persist', | 366 vm_graphics_flag, |
| 268 '--kvm_pid=%s' % _KVM_PID_FILE, | 367 '--persist', |
| 269 stateful_change_flag, | 368 '--kvm_pid=%s' % _KVM_PID_FILE, |
| 270 '--src_image=%s' % self.source_image, | 369 stateful_change_flag, |
| 271 ], enter_chroot=False) | 370 '--src_image=%s' % self.source_image, |
| 371 ]) | |
| 372 | |
| 373 if code != 0: | |
| 374 raise UpdateException(code, stdout) | |
| 375 | |
| 376 def UpdateUsingPayload(self, update_path, stateful_change='old'): | |
| 377 """Updates a remote image using image_to_live.sh.""" | |
| 378 stateful_change_flag = self.GetStatefulChangeFlag(stateful_change) | |
| 379 if self.source_image == base_image_path: | |
| 380 self.source_image = self.vm_image_path | |
| 381 | |
| 382 (code, stdout, stderr) = RunCommandCaptureOutput([ | |
| 383 '%s/cros_run_vm_update' % self.crosutilsbin, | |
| 384 '--payload=%s' % update_path, | |
| 385 '--vm_image_path=%s' % self.vm_image_path, | |
| 386 '--snapshot', | |
| 387 vm_graphics_flag, | |
| 388 '--persist', | |
| 389 '--kvm_pid=%s' % _KVM_PID_FILE, | |
| 390 stateful_change_flag, | |
| 391 '--src_image=%s' % self.source_image, | |
| 392 ]) | |
| 393 | |
| 394 if code != 0: | |
| 395 raise UpdateException(code, stdout) | |
| 272 | 396 |
| 273 def VerifyImage(self, percent_required_to_pass): | 397 def VerifyImage(self, percent_required_to_pass): |
| 274 """Runs vm smoke suite to verify image.""" | 398 """Runs vm smoke suite to verify image.""" |
| 275 # image_to_live already verifies lsb-release matching. This is just | 399 # image_to_live already verifies lsb-release matching. This is just |
| 276 # for additional steps. | 400 # for additional steps. |
| 277 | 401 |
| 278 commandWithArgs = ['%s/cros_run_vm_test' % self.crosutilsbin, | 402 commandWithArgs = ['%s/cros_run_vm_test' % self.crosutilsbin, |
| 279 '--image_path=%s' % self.vm_image_path, | 403 '--image_path=%s' % self.vm_image_path, |
| 280 '--snapshot', | 404 '--snapshot', |
| 281 '--persist', | 405 '--persist', |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 348 else: | 472 else: |
| 349 remote = options.remote | 473 remote = options.remote |
| 350 | 474 |
| 351 suite = unittest.TestLoader().loadTestsFromTestCase(RealAUTest) | 475 suite = unittest.TestLoader().loadTestsFromTestCase(RealAUTest) |
| 352 test_result = unittest.TextTestRunner(verbosity=2).run(suite) | 476 test_result = unittest.TextTestRunner(verbosity=2).run(suite) |
| 353 else: | 477 else: |
| 354 parser.error('Could not parse harness type %s.' % options.type) | 478 parser.error('Could not parse harness type %s.' % options.type) |
| 355 | 479 |
| 356 if not test_result.wasSuccessful(): | 480 if not test_result.wasSuccessful(): |
| 357 Die('Test harness was not successful') | 481 Die('Test harness was not successful') |
| OLD | NEW |