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