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