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 re |
| 10 import sys | 10 import sys |
| 11 import thread | |
| 12 import time | |
| 11 import unittest | 13 import unittest |
| 12 import urllib | 14 import urllib |
| 13 | 15 |
| 14 sys.path.append(os.path.join(os.path.dirname(__file__), '../lib')) | 16 sys.path.append(os.path.join(os.path.dirname(__file__), '../lib')) |
| 15 from cros_build_lib import Die | 17 from cros_build_lib import Die |
| 16 from cros_build_lib import Info | 18 from cros_build_lib import Info |
| 17 from cros_build_lib import ReinterpretPathForChroot | 19 from cros_build_lib import ReinterpretPathForChroot |
| 18 from cros_build_lib import RunCommand | 20 from cros_build_lib import RunCommand |
| 19 from cros_build_lib import RunCommandCaptureOutput | 21 from cros_build_lib import RunCommandCaptureOutput |
| 20 from cros_build_lib import Warning | 22 from cros_build_lib import Warning |
| 21 | 23 |
| 24 import cros_test_proxy | |
| 25 | |
| 22 # VM Constants. | 26 # VM Constants. |
| 23 _FULL_VDISK_SIZE = 6072 | 27 _FULL_VDISK_SIZE = 6072 |
| 24 _FULL_STATEFULFS_SIZE = 3074 | 28 _FULL_STATEFULFS_SIZE = 3074 |
| 25 _KVM_PID_FILE = '/tmp/harness_pid' | 29 _KVM_PID_FILE = '/tmp/harness_pid' |
| 26 _VERIFY_SUITE = 'suite_Smoke' | 30 _VERIFY_SUITE = 'suite_Smoke' |
| 27 | 31 |
| 28 # Globals to communicate options to unit tests. | 32 # Globals to communicate options to unit tests. |
| 29 global base_image_path | 33 global base_image_path |
| 30 global board | 34 global board |
| 31 global remote | 35 global remote |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 83 self.source_image = src_image | 87 self.source_image = src_image |
| 84 self._UpdateImageReportError(image) | 88 self._UpdateImageReportError(image) |
| 85 except: | 89 except: |
| 86 Warning('Delta update failed, disabling delta updates and retrying.') | 90 Warning('Delta update failed, disabling delta updates and retrying.') |
| 87 self.use_delta_updates = False | 91 self.use_delta_updates = False |
| 88 self.source_image = '' | 92 self.source_image = '' |
| 89 self._UpdateImageReportError(image) | 93 self._UpdateImageReportError(image) |
| 90 else: | 94 else: |
| 91 self._UpdateImageReportError(image) | 95 self._UpdateImageReportError(image) |
| 92 | 96 |
| 93 def _UpdateImageReportError(self, image_path, stateful_change='old'): | 97 def _UpdateImageReportError(self, image_path, stateful_change='old', |
| 98 proxy_port=None): | |
| 94 """Calls UpdateImage and reports any error to the console. | 99 """Calls UpdateImage and reports any error to the console. |
| 95 | 100 |
| 96 Still throws the exception. | 101 Still throws the exception. |
| 97 """ | 102 """ |
| 98 try: | 103 try: |
| 99 self.UpdateImage(image_path, stateful_change) | 104 self.UpdateImage(image_path, stateful_change, proxy_port) |
| 100 except UpdateException as err: | 105 except UpdateException as err: |
| 101 # If the update fails, print it out | 106 # If the update fails, print it out |
| 102 Warning(err.stdout) | 107 Warning(err.stdout) |
| 103 raise | 108 raise |
| 104 | 109 |
| 105 def _AttemptUpdateWithPayloadExpectedFailure(self, payload, expected_msg): | 110 def _AttemptUpdateWithPayloadExpectedFailure(self, payload, expected_msg): |
| 106 # This update is expected to fail... | 111 """Attempt a payload update, expect it to fail with expected log""" |
| 107 try: | 112 try: |
| 108 self.UpdateUsingPayload(payload) | 113 self.UpdateUsingPayload(payload) |
| 109 except UpdateException as err: | 114 except UpdateException as err: |
| 110 # Will raise ValueError if expected is not found. | 115 # Will raise ValueError if expected is not found. |
| 111 if re.search(re.escape(expected_msg), err.stdout, re.MULTILINE): | 116 if re.search(re.escape(expected_msg), err.stdout, re.MULTILINE): |
| 112 return | 117 return |
| 113 | 118 |
| 114 Warning("Didn't find '%s' in:" % expected_msg) | 119 Warning("Didn't find '%s' in:" % expected_msg) |
| 115 Warning(err.stdout) | 120 Warning(err.stdout) |
| 116 self.fail('We managed to update when failure was expected') | 121 self.fail('We managed to update when failure was expected') |
| 117 | 122 |
| 123 def _AttemptUpdateWithFilter(self, filter): | |
| 124 """Update through a proxy, with a specified filter, and expect success.""" | |
| 125 | |
| 126 self.PrepareBase(target_image_path) | |
| 127 | |
|
sosa
2010/12/09 23:51:01
Where'd this comment go?
# The devserver runs at
| |
| 128 proxy_port = 8081 | |
| 129 proxy = cros_test_proxy.CrosTestProxy(port_in=proxy_port, | |
| 130 address_out='127.0.0.1', | |
| 131 port_out=8080, | |
| 132 filter=filter) | |
| 133 proxy.serve_forever_in_thread() | |
| 134 | |
| 135 # This update is expected to fail... | |
| 136 try: | |
| 137 self._UpdateImageReportError(target_image_path, proxy_port=proxy_port) | |
| 138 finally: | |
| 139 proxy.shutdown() | |
| 140 | |
| 118 def PrepareBase(self, image_path): | 141 def PrepareBase(self, image_path): |
| 119 """Prepares target with base_image_path.""" | 142 """Prepares target with base_image_path.""" |
| 120 pass | 143 pass |
| 121 | 144 |
| 122 def UpdateImage(self, image_path, stateful_change='old'): | 145 def UpdateImage(self, image_path, stateful_change='old', proxy_port=None): |
| 123 """Updates target with the image given by the image_path. | 146 """Updates target with the image given by the image_path. |
| 124 | 147 |
| 125 Args: | 148 Args: |
| 126 image_path: Path to the image to update with. This image must be a test | 149 image_path: Path to the image to update with. This image must be a test |
| 127 image. | 150 image. |
| 128 stateful_change: How to modify the stateful partition. Values are: | 151 stateful_change: How to modify the stateful partition. Values are: |
| 129 'old': Don't modify stateful partition. Just update normally. | 152 'old': Don't modify stateful partition. Just update normally. |
| 130 'clean': Uses clobber-state to wipe the stateful partition with the | 153 'clean': Uses clobber-state to wipe the stateful partition with the |
| 131 exception of code needed for ssh. | 154 exception of code needed for ssh. |
| 155 proxy_port: Port to have the client connect to. For use with | |
| 156 CrosTestProxy. | |
| 132 """ | 157 """ |
| 133 pass | 158 pass |
| 134 | 159 |
| 135 def UpdateUsingPayload(self, update_path, stateful_change='old'): | 160 def UpdateUsingPayload(self, |
| 161 update_path, | |
| 162 stateful_change='old', | |
| 163 proxy_port=None): | |
| 136 """Updates target with the pre-generated update stored in update_path | 164 """Updates target with the pre-generated update stored in update_path |
| 137 | 165 |
| 138 Args: | 166 Args: |
| 139 update_path: Path to the image to update with. This directory should | 167 update_path: Path to the image to update with. This directory should |
| 140 contain both update.gz, and stateful.image.gz | 168 contain both update.gz, and stateful.image.gz |
| 169 proxy_port: Port to have the client connect to. For use with | |
| 170 CrosTestProxy. | |
| 141 """ | 171 """ |
| 142 pass | 172 pass |
| 143 | 173 |
| 144 def VerifyImage(self, percent_required_to_pass): | 174 def VerifyImage(self, percent_required_to_pass): |
| 145 """Verifies the image with tests. | 175 """Verifies the image with tests. |
| 146 | 176 |
| 147 Verifies that the test images passes the percent required. | 177 Verifies that the test images passes the percent required. |
| 148 | 178 |
| 149 Args: | 179 Args: |
| 150 percent_required_to_pass: percentage required to pass. This should be | 180 percent_required_to_pass: percentage required to pass. This should be |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 180 return percent_passed | 210 return percent_passed |
| 181 | 211 |
| 182 def testFullUpdateKeepStateful(self): | 212 def testFullUpdateKeepStateful(self): |
| 183 """Tests if we can update normally. | 213 """Tests if we can update normally. |
| 184 | 214 |
| 185 This test checks that we can update by updating the stateful partition | 215 This test checks that we can update by updating the stateful partition |
| 186 rather than wiping it. | 216 rather than wiping it. |
| 187 """ | 217 """ |
| 188 # Just make sure some tests pass on original image. Some old images | 218 # Just make sure some tests pass on original image. Some old images |
| 189 # don't pass many tests. | 219 # don't pass many tests. |
| 190 self.PrepareBase(image_path=base_image_path) | 220 self.PrepareBase(base_image_path) |
| 191 # TODO(sosa): move to 100% once we start testing using the autotest paired | 221 # TODO(sosa): move to 100% once we start testing using the autotest paired |
| 192 # with the dev channel. | 222 # with the dev channel. |
| 193 percent_passed = self.VerifyImage(10) | 223 percent_passed = self.VerifyImage(10) |
| 194 | 224 |
| 195 # Update to - all tests should pass on new image. | 225 # Update to - all tests should pass on new image. |
| 196 Info('Updating from base image on vm to target image.') | 226 Info('Updating from base image on vm to target image.') |
| 197 self.TryDeltaAndFallbackToFull(base_image_path, target_image_path) | 227 self.TryDeltaAndFallbackToFull(base_image_path, target_image_path) |
| 198 self.VerifyImage(100) | 228 self.VerifyImage(100) |
| 199 | 229 |
| 200 # Update from - same percentage should pass that originally passed. | 230 # Update from - same percentage should pass that originally passed. |
| 201 Info('Updating from updated image on vm back to base image.') | 231 Info('Updating from updated image on vm back to base image.') |
| 202 self.TryDeltaAndFallbackToFull(target_image_path, base_image_path) | 232 self.TryDeltaAndFallbackToFull(target_image_path, base_image_path) |
| 203 self.VerifyImage(percent_passed) | 233 self.VerifyImage(percent_passed) |
| 204 | 234 |
| 205 def testFullUpdateWipeStateful(self): | 235 def testFullUpdateWipeStateful(self): |
| 206 """Tests if we can update after cleaning the stateful partition. | 236 """Tests if we can update after cleaning the stateful partition. |
| 207 | 237 |
| 208 This test checks that we can update successfully after wiping the | 238 This test checks that we can update successfully after wiping the |
| 209 stateful partition. | 239 stateful partition. |
| 210 """ | 240 """ |
| 211 # Just make sure some tests pass on original image. Some old images | 241 # Just make sure some tests pass on original image. Some old images |
| 212 # don't pass many tests. | 242 # don't pass many tests. |
| 213 self.PrepareBase(image_path=base_image_path) | 243 self.PrepareBase(base_image_path) |
| 214 # TODO(sosa): move to 100% once we start testing using the autotest paired | 244 # TODO(sosa): move to 100% once we start testing using the autotest paired |
| 215 # with the dev channel. | 245 # with the dev channel. |
| 216 percent_passed = self.VerifyImage(10) | 246 percent_passed = self.VerifyImage(10) |
| 217 | 247 |
| 218 # Update to - all tests should pass on new image. | 248 # Update to - all tests should pass on new image. |
| 219 Info('Updating from base image on vm to target image and wiping stateful.') | 249 Info('Updating from base image on vm to target image and wiping stateful.') |
| 220 self.TryDeltaAndFallbackToFull(base_image_path, target_image_path, 'clean') | 250 self.TryDeltaAndFallbackToFull(base_image_path, target_image_path, 'clean') |
| 221 self.VerifyImage(100) | 251 self.VerifyImage(100) |
| 222 | 252 |
| 223 # Update from - same percentage should pass that originally passed. | 253 # Update from - same percentage should pass that originally passed. |
| 224 Info('Updating from updated image back to base image and wiping stateful.') | 254 Info('Updating from updated image back to base image and wiping stateful.') |
| 225 self.TryDeltaAndFallbackToFull(target_image_path, base_image_path, 'clean') | 255 self.TryDeltaAndFallbackToFull(target_image_path, base_image_path, 'clean') |
| 226 self.VerifyImage(percent_passed) | 256 self.VerifyImage(percent_passed) |
| 227 | 257 |
| 228 def testPartialUpdate(self): | 258 def testPartialUpdate(self): |
| 229 """Tests what happens if we attempt to update with a truncated payload.""" | 259 """Tests what happens if we attempt to update with a truncated payload.""" |
| 230 # Preload with the version we are trying to test. | 260 # Preload with the version we are trying to test. |
| 231 self.PrepareBase(image_path=target_image_path) | 261 self.PrepareBase(target_image_path) |
| 232 | 262 |
| 233 # Image can be updated at: | 263 # Image can be updated at: |
| 234 # ~chrome-eng/chromeos/localmirror/autest-images | 264 # ~chrome-eng/chromeos/localmirror/autest-images |
| 235 url = 'http://gsdview.appspot.com/chromeos-localmirror/' \ | 265 url = 'http://gsdview.appspot.com/chromeos-localmirror/' \ |
| 236 'autest-images/truncated_image.gz' | 266 'autest-images/truncated_image.gz' |
| 237 payload = os.path.join(self.download_folder, 'truncated_image.gz') | 267 payload = os.path.join(self.download_folder, 'truncated_image.gz') |
| 238 | 268 |
| 239 # Read from the URL and write to the local file | 269 # Read from the URL and write to the local file |
| 240 urllib.urlretrieve(url, payload) | 270 urllib.urlretrieve(url, payload) |
| 241 | 271 |
| 242 expected_msg = 'download_hash_data == update_check_response_hash failed' | 272 expected_msg = 'download_hash_data == update_check_response_hash failed' |
| 243 self._AttemptUpdateWithPayloadExpectedFailure(payload, expected_msg) | 273 self._AttemptUpdateWithPayloadExpectedFailure(payload, expected_msg) |
| 244 | 274 |
| 245 def testCorruptedUpdate(self): | 275 def testCorruptedUpdate(self): |
| 246 """Tests what happens if we attempt to update with a corrupted payload.""" | 276 """Tests what happens if we attempt to update with a corrupted payload.""" |
| 247 # Preload with the version we are trying to test. | 277 # Preload with the version we are trying to test. |
| 248 self.PrepareBase(image_path=target_image_path) | 278 self.PrepareBase(target_image_path) |
| 249 | 279 |
| 250 # Image can be updated at: | 280 # Image can be updated at: |
| 251 # ~chrome-eng/chromeos/localmirror/autest-images | 281 # ~chrome-eng/chromeos/localmirror/autest-images |
| 252 url = 'http://gsdview.appspot.com/chromeos-localmirror/' \ | 282 url = 'http://gsdview.appspot.com/chromeos-localmirror/' \ |
| 253 'autest-images/corrupted_image.gz' | 283 'autest-images/corrupted_image.gz' |
| 254 payload = os.path.join(self.download_folder, 'corrupted.gz') | 284 payload = os.path.join(self.download_folder, 'corrupted.gz') |
| 255 | 285 |
| 256 # Read from the URL and write to the local file | 286 # Read from the URL and write to the local file |
| 257 urllib.urlretrieve(url, payload) | 287 urllib.urlretrieve(url, payload) |
| 258 | 288 |
| 259 # This update is expected to fail... | 289 # This update is expected to fail... |
| 260 expected_msg = 'zlib inflate() error:-3' | 290 expected_msg = 'zlib inflate() error:-3' |
| 261 self._AttemptUpdateWithPayloadExpectedFailure(payload, expected_msg) | 291 self._AttemptUpdateWithPayloadExpectedFailure(payload, expected_msg) |
| 262 | 292 |
| 293 def testInterruptedUpdate(self): | |
| 294 """Tests what happens if we interrupt payload delivery 3 times.""" | |
| 295 | |
| 296 class InterruptionFilter(cros_test_proxy.Filter): | |
| 297 """This filter causes the proxy to interrupt the download 3 times | |
| 298 | |
| 299 It does this by closing the first three connections to transfer | |
| 300 2M total in the outbound connection after they transfer the | |
| 301 2M. | |
| 302 """ | |
| 303 def __init__(self): | |
| 304 """Defines variable shared across all connections""" | |
| 305 self.close_count = 0 | |
| 306 | |
| 307 def setup(self): | |
| 308 """Called once at the start of each connection.""" | |
| 309 self.data_size = 0 | |
| 310 | |
| 311 def OutBound(self, data): | |
| 312 """Called once per packet for outgoing data. | |
| 313 | |
| 314 The first three connections transferring more than 2M | |
| 315 outbound will be closed. | |
| 316 """ | |
| 317 if self.close_count < 3: | |
| 318 if self.data_size > (2 * 1024 * 1024): | |
| 319 self.close_count += 1 | |
| 320 return None | |
| 321 | |
| 322 self.data_size += len(data) | |
| 323 return data | |
| 324 | |
| 325 self._AttemptUpdateWithFilter(InterruptionFilter()) | |
| 326 | |
| 327 def testDelayedUpdate(self): | |
| 328 """Tests what happens if some data is delayed during update delivery""" | |
| 329 | |
| 330 class DelayedFilter(cros_test_proxy.Filter): | |
| 331 """Causes intermittent delays in data transmission. | |
| 332 | |
| 333 It does this by inserting 3 20 second delays when transmitting | |
| 334 data after 2M has been sent. | |
| 335 """ | |
| 336 def setup(self): | |
| 337 """Called once at the start of each connection.""" | |
| 338 self.data_size = 0 | |
| 339 self.delay_count = 0 | |
| 340 | |
| 341 def OutBound(self, data): | |
| 342 """Called once per packet for outgoing data. | |
| 343 | |
| 344 The first three packets after we reach 2M transferred | |
| 345 are delayed by 20 seconds. | |
| 346 """ | |
| 347 if self.delay_count < 3: | |
| 348 if self.data_size > (2 * 1024 * 1024): | |
| 349 self.delay_count += 1 | |
| 350 time.sleep(20) | |
| 351 | |
| 352 self.data_size += len(data) | |
| 353 return data | |
| 354 | |
| 355 | |
| 356 self._AttemptUpdateWithFilter(DelayedFilter()) | |
| 357 | |
| 263 class RealAUTest(unittest.TestCase, AUTest): | 358 class RealAUTest(unittest.TestCase, AUTest): |
| 264 """Test harness for updating real images.""" | 359 """Test harness for updating real images.""" |
| 265 | 360 |
| 266 def setUp(self): | 361 def setUp(self): |
| 267 AUTest.setUp(self) | 362 AUTest.setUp(self) |
| 268 | 363 |
| 269 def PrepareBase(self, image_path): | 364 def PrepareBase(self, image_path): |
| 270 """Auto-update to base image to prepare for test.""" | 365 """Auto-update to base image to prepare for test.""" |
| 271 self._UpdateImageReportError(image_path) | 366 self._UpdateImageReportError(image_path) |
| 272 | 367 |
| 273 def UpdateImage(self, image_path, stateful_change='old'): | 368 def UpdateImage(self, image_path, stateful_change='old', proxy_port=None): |
| 274 """Updates a remote image using image_to_live.sh.""" | 369 """Updates a remote image using image_to_live.sh.""" |
| 275 stateful_change_flag = self.GetStatefulChangeFlag(stateful_change) | 370 stateful_change_flag = self.GetStatefulChangeFlag(stateful_change) |
| 276 cmd = ['%s/image_to_live.sh' % self.crosutils, | 371 cmd = ['%s/image_to_live.sh' % self.crosutils, |
| 277 '--image=%s' % image_path, | 372 '--image=%s' % image_path, |
| 278 '--remote=%s' % remote, | 373 '--remote=%s' % remote, |
| 279 stateful_change_flag, | 374 stateful_change_flag, |
| 280 '--verify', | 375 '--verify', |
| 281 '--src_image=%s' % self.source_image | 376 '--src_image=%s' % self.source_image |
| 282 ] | 377 ] |
| 283 | 378 |
| 379 if proxy_port: | |
| 380 cmd.append('--proxy_port=%s' % proxy_port) | |
| 381 | |
| 284 if self.verbose: | 382 if self.verbose: |
| 285 try: | 383 try: |
| 286 RunCommand(cmd) | 384 RunCommand(cmd) |
| 287 except Exception, e: | 385 except Exception, e: |
| 288 raise UpdateException(1, e.message) | 386 raise UpdateException(1, e.message) |
| 289 else: | 387 else: |
| 290 (code, stdout, stderr) = RunCommandCaptureOutput(cmd) | 388 (code, stdout, stderr) = RunCommandCaptureOutput(cmd) |
| 291 if code != 0: | 389 if code != 0: |
| 292 raise UpdateException(code, stdout) | 390 raise UpdateException(code, stdout) |
| 293 | 391 |
| 294 def UpdateUsingPayload(self, update_path, stateful_change='old'): | 392 def UpdateUsingPayload(self, |
| 393 update_path, | |
| 394 stateful_change='old', | |
| 395 proxy_port=None): | |
| 295 """Updates a remote image using image_to_live.sh.""" | 396 """Updates a remote image using image_to_live.sh.""" |
| 296 stateful_change_flag = self.GetStatefulChangeFlag(stateful_change) | 397 stateful_change_flag = self.GetStatefulChangeFlag(stateful_change) |
| 297 cmd = ['%s/image_to_live.sh' % self.crosutils, | 398 cmd = ['%s/image_to_live.sh' % self.crosutils, |
| 298 '--payload=%s' % update_path, | 399 '--payload=%s' % update_path, |
| 299 '--remote=%s' % remote, | 400 '--remote=%s' % remote, |
| 300 stateful_change_flag, | 401 stateful_change_flag, |
| 301 '--verify', | 402 '--verify', |
| 302 ] | 403 ] |
| 303 | 404 |
| 405 if proxy_port: | |
| 406 cmd.append('--proxy_port=%s' % proxy_port) | |
| 407 | |
| 304 if self.verbose: | 408 if self.verbose: |
| 305 try: | 409 try: |
| 306 RunCommand(cmd) | 410 RunCommand(cmd) |
| 307 except Exception, e: | 411 except Exception, e: |
| 308 raise UpdateException(1, e.message) | 412 raise UpdateException(1, e.message) |
| 309 else: | 413 else: |
| 310 (code, stdout, stderr) = RunCommandCaptureOutput(cmd) | 414 (code, stdout, stderr) = RunCommandCaptureOutput(cmd) |
| 311 if code != 0: | 415 if code != 0: |
| 312 raise UpdateException(code, stdout) | 416 raise UpdateException(code, stdout) |
| 313 | 417 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 359 '--board=%s' % board, | 463 '--board=%s' % board, |
| 360 '--test_image'], enter_chroot=True) | 464 '--test_image'], enter_chroot=True) |
| 361 else: | 465 else: |
| 362 Info('Using existing VM image %s' % self.vm_image_path) | 466 Info('Using existing VM image %s' % self.vm_image_path) |
| 363 | 467 |
| 364 | 468 |
| 365 Info('Testing for %s' % self.vm_image_path) | 469 Info('Testing for %s' % self.vm_image_path) |
| 366 | 470 |
| 367 self.assertTrue(os.path.exists(self.vm_image_path)) | 471 self.assertTrue(os.path.exists(self.vm_image_path)) |
| 368 | 472 |
| 369 def UpdateImage(self, image_path, stateful_change='old'): | 473 def UpdateImage(self, image_path, stateful_change='old', proxy_port=None): |
| 370 """Updates VM image with image_path.""" | 474 """Updates VM image with image_path.""" |
| 371 stateful_change_flag = self.GetStatefulChangeFlag(stateful_change) | 475 stateful_change_flag = self.GetStatefulChangeFlag(stateful_change) |
| 372 if self.source_image == base_image_path: | 476 if self.source_image == base_image_path: |
| 373 self.source_image = self.vm_image_path | 477 self.source_image = self.vm_image_path |
| 374 | 478 |
| 375 cmd = ['%s/cros_run_vm_update' % self.crosutilsbin, | 479 cmd = ['%s/cros_run_vm_update' % self.crosutilsbin, |
| 376 '--update_image_path=%s' % image_path, | 480 '--update_image_path=%s' % image_path, |
| 377 '--vm_image_path=%s' % self.vm_image_path, | 481 '--vm_image_path=%s' % self.vm_image_path, |
| 378 '--snapshot', | 482 '--snapshot', |
| 379 vm_graphics_flag, | 483 vm_graphics_flag, |
| 380 '--persist', | 484 '--persist', |
| 381 '--kvm_pid=%s' % _KVM_PID_FILE, | 485 '--kvm_pid=%s' % _KVM_PID_FILE, |
| 382 stateful_change_flag, | 486 stateful_change_flag, |
| 383 '--src_image=%s' % self.source_image, | 487 '--src_image=%s' % self.source_image, |
| 384 ] | 488 ] |
| 489 | |
| 490 if proxy_port: | |
| 491 cmd.append('--proxy_port=%s' % proxy_port) | |
| 492 | |
| 385 if self.verbose: | 493 if self.verbose: |
| 386 try: | 494 try: |
| 387 RunCommand(cmd) | 495 RunCommand(cmd) |
| 388 except Exception, e: | 496 except Exception, e: |
| 389 raise UpdateException(1, e.message) | 497 raise UpdateException(1, e.message) |
| 390 else: | 498 else: |
| 391 (code, stdout, stderr) = RunCommandCaptureOutput(cmd) | 499 (code, stdout, stderr) = RunCommandCaptureOutput(cmd) |
| 392 if code != 0: | 500 if code != 0: |
| 393 raise UpdateException(code, stdout) | 501 raise UpdateException(code, stdout) |
| 394 | 502 |
| 395 def UpdateUsingPayload(self, update_path, stateful_change='old'): | 503 def UpdateUsingPayload(self, |
| 504 update_path, | |
| 505 stateful_change='old', | |
| 506 proxy_port=None): | |
| 396 """Updates a remote image using image_to_live.sh.""" | 507 """Updates a remote image using image_to_live.sh.""" |
| 397 stateful_change_flag = self.GetStatefulChangeFlag(stateful_change) | 508 stateful_change_flag = self.GetStatefulChangeFlag(stateful_change) |
| 398 if self.source_image == base_image_path: | 509 if self.source_image == base_image_path: |
| 399 self.source_image = self.vm_image_path | 510 self.source_image = self.vm_image_path |
| 400 | 511 |
| 401 cmd = ['%s/cros_run_vm_update' % self.crosutilsbin, | 512 cmd = ['%s/cros_run_vm_update' % self.crosutilsbin, |
| 402 '--payload=%s' % update_path, | 513 '--payload=%s' % update_path, |
| 403 '--vm_image_path=%s' % self.vm_image_path, | 514 '--vm_image_path=%s' % self.vm_image_path, |
| 404 '--snapshot', | 515 '--snapshot', |
| 405 vm_graphics_flag, | 516 vm_graphics_flag, |
| 406 '--persist', | 517 '--persist', |
| 407 '--kvm_pid=%s' % _KVM_PID_FILE, | 518 '--kvm_pid=%s' % _KVM_PID_FILE, |
| 408 stateful_change_flag, | 519 stateful_change_flag, |
| 409 '--src_image=%s' % self.source_image, | 520 '--src_image=%s' % self.source_image, |
| 410 ] | 521 ] |
| 411 | 522 |
| 523 if proxy_port: | |
| 524 cmd.append('--proxy_port=%s' % proxy_port) | |
| 525 | |
| 412 if self.verbose: | 526 if self.verbose: |
| 413 try: | 527 try: |
| 414 RunCommand(cmd) | 528 RunCommand(cmd) |
| 415 except Exception, e: | 529 except Exception, e: |
| 416 raise UpdateException(1, e.message) | 530 raise UpdateException(1, e.message) |
| 417 else: | 531 else: |
| 418 (code, stdout, stderr) = RunCommandCaptureOutput(cmd) | 532 (code, stdout, stderr) = RunCommandCaptureOutput(cmd) |
| 419 if code != 0: | 533 if code != 0: |
| 420 raise UpdateException(code, stdout) | 534 raise UpdateException(code, stdout) |
| 421 | 535 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 495 AUTest.use_delta_updates = options.delta | 609 AUTest.use_delta_updates = options.delta |
| 496 | 610 |
| 497 # Only run the test harness we care about. | 611 # Only run the test harness we care about. |
| 498 test_loader = unittest.TestLoader() | 612 test_loader = unittest.TestLoader() |
| 499 test_loader.testMethodPrefix = options.test_prefix | 613 test_loader.testMethodPrefix = options.test_prefix |
| 500 | 614 |
| 501 if options.type == 'vm': test_class = VirtualAUTest | 615 if options.type == 'vm': test_class = VirtualAUTest |
| 502 elif options.type == 'real': test_class = RealAUTest | 616 elif options.type == 'real': test_class = RealAUTest |
| 503 else: parser.error('Could not parse harness type %s.' % options.type) | 617 else: parser.error('Could not parse harness type %s.' % options.type) |
| 504 | 618 |
| 619 remote = options.remote | |
| 620 | |
| 505 test_suite = test_loader.loadTestsFromTestCase(test_class) | 621 test_suite = test_loader.loadTestsFromTestCase(test_class) |
| 506 test_result = unittest.TextTestRunner(verbosity=2).run(test_suite) | 622 test_result = unittest.TextTestRunner(verbosity=2).run(test_suite) |
| 507 | 623 |
| 508 if not test_result.wasSuccessful(): | 624 if not test_result.wasSuccessful(): |
| 509 Die('Test harness was not successful') | 625 Die('Test harness was not successful') |
| OLD | NEW |