| 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 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 break | 78 break |
| 79 | 79 |
| 80 return int(percent_passed) | 80 return int(percent_passed) |
| 81 | 81 |
| 82 # TODO(sosa) - Remove try and convert function to DeltaUpdateImage(). | 82 # TODO(sosa) - Remove try and convert function to DeltaUpdateImage(). |
| 83 def TryDeltaAndFallbackToFull(self, src_image, image, stateful_change='old'): | 83 def TryDeltaAndFallbackToFull(self, src_image, image, stateful_change='old'): |
| 84 """Tries the delta update first if set and falls back to full update.""" | 84 """Tries the delta update first if set and falls back to full update.""" |
| 85 if self.use_delta_updates: | 85 if self.use_delta_updates: |
| 86 try: | 86 try: |
| 87 self.source_image = src_image | 87 self.source_image = src_image |
| 88 self._UpdateImageReportError(image) | 88 self._UpdateImageReportError(image, stateful_change) |
| 89 except: | 89 except: |
| 90 Warning('Delta update failed, disabling delta updates and retrying.') | 90 Warning('Delta update failed, disabling delta updates and retrying.') |
| 91 self.use_delta_updates = False | 91 self.use_delta_updates = False |
| 92 self.source_image = '' | 92 self.source_image = '' |
| 93 self._UpdateImageReportError(image) | 93 self._UpdateImageReportError(image, stateful_change) |
| 94 else: | 94 else: |
| 95 self._UpdateImageReportError(image) | 95 self._UpdateImageReportError(image, stateful_change) |
| 96 | 96 |
| 97 def _UpdateImageReportError(self, image_path, stateful_change='old', | 97 def _UpdateImageReportError(self, image_path, stateful_change='old', |
| 98 proxy_port=None): | 98 proxy_port=None): |
| 99 """Calls UpdateImage and reports any error to the console. | 99 """Calls UpdateImage and reports any error to the console. |
| 100 | 100 |
| 101 Still throws the exception. | 101 Still throws the exception. |
| 102 """ | 102 """ |
| 103 try: | 103 try: |
| 104 self.UpdateImage(image_path, stateful_change, proxy_port) | 104 self.UpdateImage(image_path, stateful_change, proxy_port) |
| 105 except UpdateException as err: | 105 except UpdateException as err: |
| (...skipping 12 matching lines...) Expand all Loading... |
| 118 | 118 |
| 119 Warning("Didn't find '%s' in:" % expected_msg) | 119 Warning("Didn't find '%s' in:" % expected_msg) |
| 120 Warning(err.stdout) | 120 Warning(err.stdout) |
| 121 self.fail('We managed to update when failure was expected') | 121 self.fail('We managed to update when failure was expected') |
| 122 | 122 |
| 123 def _AttemptUpdateWithFilter(self, filter): | 123 def _AttemptUpdateWithFilter(self, filter): |
| 124 """Update through a proxy, with a specified filter, and expect success.""" | 124 """Update through a proxy, with a specified filter, and expect success.""" |
| 125 | 125 |
| 126 self.PrepareBase(target_image_path) | 126 self.PrepareBase(target_image_path) |
| 127 | 127 |
| 128 # The devserver runs at port 8080 by default. We assume that here, and | 128 # The devserver runs at port 8080 by default. We assume that here, and |
| 129 # start our proxy at 8081. We then tell our update tools to have the | 129 # start our proxy at 8081. We then tell our update tools to have the |
| 130 # client connect to 8081 instead of 8080. | 130 # client connect to 8081 instead of 8080. |
| 131 proxy_port = 8081 | 131 proxy_port = 8081 |
| 132 proxy = cros_test_proxy.CrosTestProxy(port_in=proxy_port, | 132 proxy = cros_test_proxy.CrosTestProxy(port_in=proxy_port, |
| 133 address_out='127.0.0.1', | 133 address_out='127.0.0.1', |
| 134 port_out=8080, | 134 port_out=8080, |
| 135 filter=filter) | 135 filter=filter) |
| 136 proxy.serve_forever_in_thread() | 136 proxy.serve_forever_in_thread() |
| 137 | 137 |
| 138 # This update is expected to fail... | 138 # This update is expected to fail... |
| 139 try: | 139 try: |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 | 291 |
| 292 # This update is expected to fail... | 292 # This update is expected to fail... |
| 293 expected_msg = 'zlib inflate() error:-3' | 293 expected_msg = 'zlib inflate() error:-3' |
| 294 self._AttemptUpdateWithPayloadExpectedFailure(payload, expected_msg) | 294 self._AttemptUpdateWithPayloadExpectedFailure(payload, expected_msg) |
| 295 | 295 |
| 296 def testInterruptedUpdate(self): | 296 def testInterruptedUpdate(self): |
| 297 """Tests what happens if we interrupt payload delivery 3 times.""" | 297 """Tests what happens if we interrupt payload delivery 3 times.""" |
| 298 | 298 |
| 299 class InterruptionFilter(cros_test_proxy.Filter): | 299 class InterruptionFilter(cros_test_proxy.Filter): |
| 300 """This filter causes the proxy to interrupt the download 3 times | 300 """This filter causes the proxy to interrupt the download 3 times |
| 301 | 301 |
| 302 It does this by closing the first three connections to transfer | 302 It does this by closing the first three connections to transfer |
| 303 2M total in the outbound connection after they transfer the | 303 2M total in the outbound connection after they transfer the |
| 304 2M. | 304 2M. |
| 305 """ | 305 """ |
| 306 def __init__(self): | 306 def __init__(self): |
| 307 """Defines variable shared across all connections""" | 307 """Defines variable shared across all connections""" |
| 308 self.close_count = 0 | 308 self.close_count = 0 |
| 309 | 309 |
| 310 def setup(self): | 310 def setup(self): |
| 311 """Called once at the start of each connection.""" | 311 """Called once at the start of each connection.""" |
| 312 self.data_size = 0 | 312 self.data_size = 0 |
| 313 | 313 |
| 314 def OutBound(self, data): | 314 def OutBound(self, data): |
| 315 """Called once per packet for outgoing data. | 315 """Called once per packet for outgoing data. |
| 316 | 316 |
| 317 The first three connections transferring more than 2M | 317 The first three connections transferring more than 2M |
| 318 outbound will be closed. | 318 outbound will be closed. |
| 319 """ | 319 """ |
| 320 if self.close_count < 3: | 320 if self.close_count < 3: |
| 321 if self.data_size > (2 * 1024 * 1024): | 321 if self.data_size > (2 * 1024 * 1024): |
| 322 self.close_count += 1 | 322 self.close_count += 1 |
| 323 return None | 323 return None |
| 324 | 324 |
| 325 self.data_size += len(data) | 325 self.data_size += len(data) |
| 326 return data | 326 return data |
| 327 | 327 |
| 328 self._AttemptUpdateWithFilter(InterruptionFilter()) | 328 self._AttemptUpdateWithFilter(InterruptionFilter()) |
| 329 | 329 |
| 330 def testDelayedUpdate(self): | 330 def testDelayedUpdate(self): |
| 331 """Tests what happens if some data is delayed during update delivery""" | 331 """Tests what happens if some data is delayed during update delivery""" |
| 332 | 332 |
| 333 class DelayedFilter(cros_test_proxy.Filter): | 333 class DelayedFilter(cros_test_proxy.Filter): |
| 334 """Causes intermittent delays in data transmission. | 334 """Causes intermittent delays in data transmission. |
| 335 | 335 |
| 336 It does this by inserting 3 20 second delays when transmitting | 336 It does this by inserting 3 20 second delays when transmitting |
| 337 data after 2M has been sent. | 337 data after 2M has been sent. |
| 338 """ | 338 """ |
| 339 def setup(self): | 339 def setup(self): |
| 340 """Called once at the start of each connection.""" | 340 """Called once at the start of each connection.""" |
| 341 self.data_size = 0 | 341 self.data_size = 0 |
| 342 self.delay_count = 0 | 342 self.delay_count = 0 |
| 343 | 343 |
| 344 def OutBound(self, data): | 344 def OutBound(self, data): |
| 345 """Called once per packet for outgoing data. | 345 """Called once per packet for outgoing data. |
| 346 | 346 |
| 347 The first three packets after we reach 2M transferred | 347 The first three packets after we reach 2M transferred |
| 348 are delayed by 20 seconds. | 348 are delayed by 20 seconds. |
| 349 """ | 349 """ |
| 350 if self.delay_count < 3: | 350 if self.delay_count < 3: |
| 351 if self.data_size > (2 * 1024 * 1024): | 351 if self.data_size > (2 * 1024 * 1024): |
| 352 self.delay_count += 1 | 352 self.delay_count += 1 |
| 353 time.sleep(20) | 353 time.sleep(20) |
| 354 | 354 |
| 355 self.data_size += len(data) | 355 self.data_size += len(data) |
| 356 return data | 356 return data |
| 357 | |
| 358 | 357 |
| 359 self._AttemptUpdateWithFilter(DelayedFilter()) | 358 self._AttemptUpdateWithFilter(DelayedFilter()) |
| 360 | 359 |
| 360 def SimpleTest(self): |
| 361 """A simple update that updates the target image to itself. |
| 362 |
| 363 We explicitly don't use test prefix so that isn't run by default. Can be |
| 364 run using test_prefix option. |
| 365 """ |
| 366 self.PrepareBase(target_image_path) |
| 367 self.UpdateImage(target_image_path) |
| 368 self.VerifyImage(100) |
| 369 |
| 370 |
| 361 class RealAUTest(unittest.TestCase, AUTest): | 371 class RealAUTest(unittest.TestCase, AUTest): |
| 362 """Test harness for updating real images.""" | 372 """Test harness for updating real images.""" |
| 363 | 373 |
| 364 def setUp(self): | 374 def setUp(self): |
| 365 AUTest.setUp(self) | 375 AUTest.setUp(self) |
| 366 | 376 |
| 367 def PrepareBase(self, image_path): | 377 def PrepareBase(self, image_path): |
| 368 """Auto-update to base image to prepare for test.""" | 378 """Auto-update to base image to prepare for test.""" |
| 369 self._UpdateImageReportError(image_path) | 379 self._UpdateImageReportError(image_path) |
| 370 | 380 |
| 371 def UpdateImage(self, image_path, stateful_change='old', proxy_port=None): | 381 def UpdateImage(self, image_path, stateful_change='old', proxy_port=None): |
| 372 """Updates a remote image using image_to_live.sh.""" | 382 """Updates a remote image using image_to_live.sh.""" |
| 373 stateful_change_flag = self.GetStatefulChangeFlag(stateful_change) | 383 stateful_change_flag = self.GetStatefulChangeFlag(stateful_change) |
| 374 cmd = ['%s/image_to_live.sh' % self.crosutils, | 384 cmd = ['%s/image_to_live.sh' % self.crosutils, |
| 375 '--image=%s' % image_path, | 385 '--image=%s' % image_path, |
| 376 '--remote=%s' % remote, | 386 '--remote=%s' % remote, |
| 377 stateful_change_flag, | 387 stateful_change_flag, |
| 378 '--verify', | 388 '--verify', |
| 379 '--src_image=%s' % self.source_image | 389 '--src_image=%s' % self.source_image |
| 380 ] | 390 ] |
| 381 | 391 |
| 382 if proxy_port: | 392 if proxy_port: |
| 383 cmd.append('--proxy_port=%s' % proxy_port) | 393 cmd.append('--proxy_port=%s' % proxy_port) |
| 384 | 394 |
| 385 if self.verbose: | 395 if self.verbose: |
| 386 try: | 396 try: |
| 387 RunCommand(cmd) | 397 RunCommand(cmd) |
| 388 except Exception, e: | 398 except Exception, e: |
| 389 raise UpdateException(1, e.message) | 399 raise UpdateException(1, e.message) |
| 390 else: | 400 else: |
| 391 (code, stdout, stderr) = RunCommandCaptureOutput(cmd) | 401 (code, stdout, stderr) = RunCommandCaptureOutput(cmd) |
| 392 if code != 0: | 402 if code != 0: |
| 393 raise UpdateException(code, stdout) | 403 raise UpdateException(code, stdout) |
| 394 | 404 |
| 395 def UpdateUsingPayload(self, | 405 def UpdateUsingPayload(self, |
| 396 update_path, | 406 update_path, |
| 397 stateful_change='old', | 407 stateful_change='old', |
| 398 proxy_port=None): | 408 proxy_port=None): |
| 399 """Updates a remote image using image_to_live.sh.""" | 409 """Updates a remote image using image_to_live.sh.""" |
| 400 stateful_change_flag = self.GetStatefulChangeFlag(stateful_change) | 410 stateful_change_flag = self.GetStatefulChangeFlag(stateful_change) |
| 401 cmd = ['%s/image_to_live.sh' % self.crosutils, | 411 cmd = ['%s/image_to_live.sh' % self.crosutils, |
| 402 '--payload=%s' % update_path, | 412 '--payload=%s' % update_path, |
| 403 '--remote=%s' % remote, | 413 '--remote=%s' % remote, |
| 404 stateful_change_flag, | 414 stateful_change_flag, |
| 405 '--verify', | 415 '--verify', |
| 406 ] | 416 ] |
| 407 | 417 |
| 408 if proxy_port: | 418 if proxy_port: |
| 409 cmd.append('--proxy_port=%s' % proxy_port) | 419 cmd.append('--proxy_port=%s' % proxy_port) |
| 410 | 420 |
| 411 if self.verbose: | 421 if self.verbose: |
| 412 try: | 422 try: |
| 413 RunCommand(cmd) | 423 RunCommand(cmd) |
| 414 except Exception, e: | 424 except Exception, e: |
| 415 raise UpdateException(1, e.message) | 425 raise UpdateException(1, e.message) |
| 416 else: | 426 else: |
| 417 (code, stdout, stderr) = RunCommandCaptureOutput(cmd) | 427 (code, stdout, stderr) = RunCommandCaptureOutput(cmd) |
| 418 if code != 0: | 428 if code != 0: |
| 419 raise UpdateException(code, stdout) | 429 raise UpdateException(code, stdout) |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 484 '--vm_image_path=%s' % self.vm_image_path, | 494 '--vm_image_path=%s' % self.vm_image_path, |
| 485 '--snapshot', | 495 '--snapshot', |
| 486 vm_graphics_flag, | 496 vm_graphics_flag, |
| 487 '--persist', | 497 '--persist', |
| 488 '--kvm_pid=%s' % _KVM_PID_FILE, | 498 '--kvm_pid=%s' % _KVM_PID_FILE, |
| 489 stateful_change_flag, | 499 stateful_change_flag, |
| 490 '--src_image=%s' % self.source_image, | 500 '--src_image=%s' % self.source_image, |
| 491 ] | 501 ] |
| 492 | 502 |
| 493 if proxy_port: | 503 if proxy_port: |
| 494 cmd.append('--proxy_port=%s' % proxy_port) | 504 cmd.append('--proxy_port=%s' % proxy_port) |
| 495 | 505 |
| 496 if self.verbose: | 506 if self.verbose: |
| 497 try: | 507 try: |
| 498 RunCommand(cmd) | 508 RunCommand(cmd) |
| 499 except Exception, e: | 509 except Exception, e: |
| 500 raise UpdateException(1, e.message) | 510 raise UpdateException(1, e.message) |
| 501 else: | 511 else: |
| 502 (code, stdout, stderr) = RunCommandCaptureOutput(cmd) | 512 (code, stdout, stderr) = RunCommandCaptureOutput(cmd) |
| 503 if code != 0: | 513 if code != 0: |
| 504 raise UpdateException(code, stdout) | 514 raise UpdateException(code, stdout) |
| (...skipping 12 matching lines...) Expand all Loading... |
| 517 '--vm_image_path=%s' % self.vm_image_path, | 527 '--vm_image_path=%s' % self.vm_image_path, |
| 518 '--snapshot', | 528 '--snapshot', |
| 519 vm_graphics_flag, | 529 vm_graphics_flag, |
| 520 '--persist', | 530 '--persist', |
| 521 '--kvm_pid=%s' % _KVM_PID_FILE, | 531 '--kvm_pid=%s' % _KVM_PID_FILE, |
| 522 stateful_change_flag, | 532 stateful_change_flag, |
| 523 '--src_image=%s' % self.source_image, | 533 '--src_image=%s' % self.source_image, |
| 524 ] | 534 ] |
| 525 | 535 |
| 526 if proxy_port: | 536 if proxy_port: |
| 527 cmd.append('--proxy_port=%s' % proxy_port) | 537 cmd.append('--proxy_port=%s' % proxy_port) |
| 528 | 538 |
| 529 if self.verbose: | 539 if self.verbose: |
| 530 try: | 540 try: |
| 531 RunCommand(cmd) | 541 RunCommand(cmd) |
| 532 except Exception, e: | 542 except Exception, e: |
| 533 raise UpdateException(1, e.message) | 543 raise UpdateException(1, e.message) |
| 534 else: | 544 else: |
| 535 (code, stdout, stderr) = RunCommandCaptureOutput(cmd) | 545 (code, stdout, stderr) = RunCommandCaptureOutput(cmd) |
| 536 if code != 0: | 546 if code != 0: |
| 537 raise UpdateException(code, stdout) | 547 raise UpdateException(code, stdout) |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 619 elif options.type == 'real': test_class = RealAUTest | 629 elif options.type == 'real': test_class = RealAUTest |
| 620 else: parser.error('Could not parse harness type %s.' % options.type) | 630 else: parser.error('Could not parse harness type %s.' % options.type) |
| 621 | 631 |
| 622 remote = options.remote | 632 remote = options.remote |
| 623 | 633 |
| 624 test_suite = test_loader.loadTestsFromTestCase(test_class) | 634 test_suite = test_loader.loadTestsFromTestCase(test_class) |
| 625 test_result = unittest.TextTestRunner(verbosity=2).run(test_suite) | 635 test_result = unittest.TextTestRunner(verbosity=2).run(test_suite) |
| 626 | 636 |
| 627 if not test_result.wasSuccessful(): | 637 if not test_result.wasSuccessful(): |
| 628 Die('Test harness was not successful') | 638 Die('Test harness was not successful') |
| OLD | NEW |