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