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 |