Chromium Code Reviews| Index: bin/cros_au_test_harness.py |
| diff --git a/bin/cros_au_test_harness.py b/bin/cros_au_test_harness.py |
| index eacf837d1856df1d01b555ca2ee8eb9e8d59c125..d7d655a87149ceec11b0df480667ba16ba4b1812 100755 |
| --- a/bin/cros_au_test_harness.py |
| +++ b/bin/cros_au_test_harness.py |
| @@ -8,6 +8,8 @@ import optparse |
| import os |
| import re |
| import sys |
| +import thread |
| +import time |
| import unittest |
| import urllib |
| @@ -19,6 +21,8 @@ from cros_build_lib import RunCommand |
| from cros_build_lib import RunCommandCaptureOutput |
| from cros_build_lib import Warning |
| +import cros_test_proxy |
| + |
| # VM Constants. |
| _FULL_VDISK_SIZE = 6072 |
| _FULL_STATEFULFS_SIZE = 3074 |
| @@ -87,13 +91,14 @@ class AUTest(object): |
| else: |
| self._UpdateImageReportError(image) |
| - def _UpdateImageReportError(self, image_path, stateful_change='old'): |
| + def _UpdateImageReportError(self, image_path, stateful_change='old', |
| + proxy_port=None): |
| """Calls UpdateImage and reports any error to the console. |
| Still throws the exception. |
| """ |
| try: |
| - self.UpdateImage(image_path, stateful_change) |
| + self.UpdateImage(image_path, stateful_change, proxy_port) |
| except UpdateException as err: |
| # If the update fails, print it out |
| Warning(err.stdout) |
| @@ -116,7 +121,7 @@ class AUTest(object): |
| """Prepares target with base_image_path.""" |
| pass |
| - def UpdateImage(self, image_path, stateful_change='old'): |
| + def UpdateImage(self, image_path, stateful_change='old', proxy_port=None): |
| """Updates target with the image given by the image_path. |
| Args: |
| @@ -129,7 +134,7 @@ class AUTest(object): |
| """ |
| pass |
| - def UpdateUsingPayload(self, update_path, stateful_change='old'): |
| + def UpdateUsingPayload(self, update_path, stateful_change='old', proxy_port=None): |
|
adlr
2010/12/07 02:26:51
80 cols
dgarrett
2010/12/07 03:48:18
Done.
|
| """Updates target with the pre-generated update stored in update_path |
| Args: |
| @@ -183,7 +188,7 @@ class AUTest(object): |
| """ |
| # Just make sure some tests pass on original image. Some old images |
| # don't pass many tests. |
| - self.PrepareBase(image_path=base_image_path) |
| + self.PrepareBase(base_image_path) |
| # TODO(sosa): move to 100% once we start testing using the autotest paired |
| # with the dev channel. |
| percent_passed = self.VerifyImage(10) |
| @@ -206,7 +211,7 @@ class AUTest(object): |
| """ |
| # Just make sure some tests pass on original image. Some old images |
| # don't pass many tests. |
| - self.PrepareBase(image_path=base_image_path) |
| + self.PrepareBase(base_image_path) |
| # TODO(sosa): move to 100% once we start testing using the autotest paired |
| # with the dev channel. |
| percent_passed = self.VerifyImage(10) |
| @@ -224,7 +229,7 @@ class AUTest(object): |
| def testPartialUpdate(self): |
| """Tests what happens if we attempt to update with a truncated payload.""" |
| # Preload with the version we are trying to test. |
| - self.PrepareBase(image_path=target_image_path) |
| + self.PrepareBase(target_image_path) |
| # Image can be updated at: |
| # ~chrome-eng/chromeos/localmirror/autest-images |
| @@ -241,7 +246,7 @@ class AUTest(object): |
| def testCorruptedUpdate(self): |
| """Tests what happens if we attempt to update with a corrupted payload.""" |
| # Preload with the version we are trying to test. |
| - self.PrepareBase(image_path=target_image_path) |
| + self.PrepareBase(target_image_path) |
| # Image can be updated at: |
| # ~chrome-eng/chromeos/localmirror/autest-images |
| @@ -256,6 +261,92 @@ class AUTest(object): |
| expected_msg='zlib inflate() error:-3' |
| self._AttemptUpdateWithPayloadExpectedFailure(payload, expected_msg) |
| + def testInterruptedUpdate(self): |
| + """Tests what happens if we interrupt payload delivery 3 times.""" |
| + |
| + class InterruptionFilter(cros_test_proxy.Filter): |
| + """This filter causes the proxy to interrupte the download 3 times |
|
sosa
2010/12/07 03:44:36
spelling
dgarrett
2010/12/07 04:08:51
Done.
|
| + |
| + It does this by closing the first three connections to transfer |
| + 2M total in the outbound connection after they transfer the |
| + 2M. |
| + """ |
| + def __init__(self): |
|
adlr
2010/12/07 02:26:51
please add a docstring for each method/function
dgarrett
2010/12/07 03:48:18
Done.
|
| + # This value is shared across all conections |
| + self.close_count = 0 |
| + |
| + def setup(self): |
| + # This value is reset for each connection |
| + self.data_size = 0 |
| + |
| + def OutBound(self, data): |
| + # for the first three requests, close the connection after |
| + # 2M are sent. |
| + if self.close_count < 3: |
| + if self.data_size > (2 * 1024 * 1024): |
| + self.close_count += 1 |
| + return None |
| + |
| + self.data_size += len(data) |
| + return data |
| + |
| + |
| + self.PrepareBase(target_image_path) |
| + |
| + proxy_port = 8081 |
|
sosa
2010/12/07 03:44:36
Comment about the default port choices
dgarrett
2010/12/07 04:08:51
Done.
|
| + proxy = cros_test_proxy.CrosTestProxy(port_in=proxy_port, |
| + address_out='127.0.0.1', |
| + port_out=8080, |
| + filter=InterruptionFilter()) |
| + proxy.serve_forever_in_thread() |
| + |
| + # This update is expected to fail... |
| + try: |
| + self._UpdateImageReportError(target_image_path, proxy_port=proxy_port) |
| + finally: |
| + proxy.shutdown() |
| + |
| + def testDelayedUpdate(self): |
| + """Tests what happens if some data is delayed during update delivery""" |
| + |
| + class DelayedFilter(cros_test_proxy.Filter): |
| + """Causes intermittent delays in data transmission. |
|
sosa
2010/12/07 03:44:36
you could probably combine this with the other fil
dgarrett
2010/12/07 04:08:51
I could, but plan to make more changes that will c
|
| + |
| + It does this by inserting 3 20 second days when transmitting |
|
sosa
2010/12/07 03:44:36
delays not days :) ... at least i hope
dgarrett
2010/12/07 04:08:51
Done.
|
| + data after 2M has been sent. |
| + """ |
| + def setup(self): |
| + # These values are reset for each connection |
| + self.data_size = 0 |
| + self.delay_count = 0 |
| + |
| + def OutBound(self, data): |
| + # The first three packets after we reach 2M transferred |
| + # are delayed by 20 seconds |
| + if self.delay_count < 3: |
| + if self.data_size > (2 * 1024 * 1024): |
| + self.delay_count += 1 |
| + time.sleep(20) |
| + |
| + self.data_size += len(data) |
| + return data |
| + |
| + |
| + self.PrepareBase(target_image_path) |
| + |
| + proxy_port = 8081 |
| + proxy = cros_test_proxy.CrosTestProxy(port_in=proxy_port, |
| + address_out='127.0.0.1', |
| + port_out=8080, |
| + filter=DelayedFilter()) |
| + proxy.serve_forever_in_thread() |
| + |
| + # This update is expected to fail... |
| + try: |
| + self._UpdateImageReportError(target_image_path, proxy_port=proxy_port) |
| + finally: |
| + proxy.shutdown() |
| + |
| class RealAUTest(unittest.TestCase, AUTest): |
| """Test harness for updating real images.""" |
| @@ -266,10 +357,14 @@ class RealAUTest(unittest.TestCase, AUTest): |
| """Auto-update to base image to prepare for test.""" |
| self._UpdateImageReportError(image_path) |
| - def UpdateImage(self, image_path, stateful_change='old'): |
| + def UpdateImage(self, image_path, stateful_change='old', proxy_port=None): |
| """Updates a remote image using image_to_live.sh.""" |
| stateful_change_flag = self.GetStatefulChangeFlag(stateful_change) |
| + port_flags = [] |
| + if proxy_port: |
| + port_flags.append('--proxy_port=%s' % proxy_port) |
| + |
| (code, stdout, stderr) = RunCommandCaptureOutput([ |
| '%s/image_to_live.sh' % self.crosutils, |
| '--image=%s' % image_path, |
| @@ -277,22 +372,26 @@ class RealAUTest(unittest.TestCase, AUTest): |
| stateful_change_flag, |
| '--verify', |
| '--src_image=%s' % self.source_image |
| - ]) |
| + ] + port_flags) |
|
sosa
2010/12/07 03:44:36
.extend(port_flags)
dgarrett
2010/12/07 04:08:51
Done.
|
| if code != 0: |
| raise UpdateException(code, stdout) |
| - def UpdateUsingPayload(self, update_path, stateful_change='old'): |
| + def UpdateUsingPayload(self, update_path, stateful_change='old', proxy_port=None): |
|
adlr
2010/12/07 02:26:51
80 cols
dgarrett
2010/12/07 03:48:18
Done.
|
| """Updates a remote image using image_to_live.sh.""" |
| stateful_change_flag = self.GetStatefulChangeFlag(stateful_change) |
| + port_flags = [] |
| + if proxy_port: |
| + port_flags.append('--proxy_port=%s' % proxy_port) |
| + |
| (code, stdout, stderr) = RunCommandCaptureOutput([ |
| '%s/image_to_live.sh' % self.crosutils, |
| '--payload=%s' % update_path, |
| '--remote=%s' % remote, |
| stateful_change_flag, |
| '--verify', |
| - ]) |
| + ] + port_flags) |
|
sosa
2010/12/07 03:44:36
ditto
dgarrett
2010/12/07 04:08:51
Done.
|
| if code != 0: |
| raise UpdateException(code, stdout) |
| @@ -352,12 +451,16 @@ class VirtualAUTest(unittest.TestCase, AUTest): |
| self.assertTrue(os.path.exists(self.vm_image_path)) |
| - def UpdateImage(self, image_path, stateful_change='old'): |
| + def UpdateImage(self, image_path, stateful_change='old', proxy_port=None): |
| """Updates VM image with image_path.""" |
| stateful_change_flag = self.GetStatefulChangeFlag(stateful_change) |
| if self.source_image == base_image_path: |
| self.source_image = self.vm_image_path |
| + port_flags = [] |
|
adlr
2010/12/07 02:26:51
there seems to be code duplication here and in the
dgarrett
2010/12/07 03:48:18
The changes I've added everywhere are identical, b
|
| + if proxy_port: |
| + port_flags.append('--proxy_port=%s' % proxy_port) |
| + |
| (code, stdout, stderr) = RunCommandCaptureOutput([ |
| '%s/cros_run_vm_update' % self.crosutilsbin, |
| '--update_image_path=%s' % image_path, |
| @@ -368,17 +471,21 @@ class VirtualAUTest(unittest.TestCase, AUTest): |
| '--kvm_pid=%s' % _KVM_PID_FILE, |
| stateful_change_flag, |
| '--src_image=%s' % self.source_image, |
| - ]) |
| + ] + port_flags) |
| if code != 0: |
| raise UpdateException(code, stdout) |
| - def UpdateUsingPayload(self, update_path, stateful_change='old'): |
| + def UpdateUsingPayload(self, update_path, stateful_change='old', proxy_port=None): |
|
adlr
2010/12/07 02:26:51
80 cols
dgarrett
2010/12/07 03:48:18
Done.
|
| """Updates a remote image using image_to_live.sh.""" |
| stateful_change_flag = self.GetStatefulChangeFlag(stateful_change) |
| if self.source_image == base_image_path: |
| self.source_image = self.vm_image_path |
| + port_flags = [] |
| + if proxy_port: |
| + port_flags.append('--proxy_port=%s' % proxy_port) |
| + |
| (code, stdout, stderr) = RunCommandCaptureOutput([ |
| '%s/cros_run_vm_update' % self.crosutilsbin, |
| '--payload=%s' % update_path, |
| @@ -389,7 +496,7 @@ class VirtualAUTest(unittest.TestCase, AUTest): |
| '--kvm_pid=%s' % _KVM_PID_FILE, |
| stateful_change_flag, |
| '--src_image=%s' % self.source_image, |
| - ]) |
| + ] + port_flags) |
| if code != 0: |
| raise UpdateException(code, stdout) |