| 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 sys | 9 import sys |
| 10 import unittest | 10 import unittest |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 global board | 26 global board |
| 27 global remote | 27 global remote |
| 28 global target_image_path | 28 global target_image_path |
| 29 global vm_graphics_flag | 29 global vm_graphics_flag |
| 30 | 30 |
| 31 | 31 |
| 32 _VERIFY_SUITE = 'suite_Smoke' | 32 _VERIFY_SUITE = 'suite_Smoke' |
| 33 | 33 |
| 34 class AUTest(object): | 34 class AUTest(object): |
| 35 """Abstract interface that defines an Auto Update test.""" | 35 """Abstract interface that defines an Auto Update test.""" |
| 36 source_image = '' |
| 37 use_delta_updates = False |
| 36 | 38 |
| 37 def setUp(self): | 39 def setUp(self): |
| 38 unittest.TestCase.setUp(self) | 40 unittest.TestCase.setUp(self) |
| 39 # Set these up as they are used often. | 41 # Set these up as they are used often. |
| 40 self.crosutils = os.path.join(os.path.dirname(__file__), '..') | 42 self.crosutils = os.path.join(os.path.dirname(__file__), '..') |
| 41 self.crosutilsbin = os.path.join(os.path.dirname(__file__)) | 43 self.crosutilsbin = os.path.join(os.path.dirname(__file__)) |
| 42 | 44 |
| 43 def GetStatefulChangeFlag(self, stateful_change): | 45 def GetStatefulChangeFlag(self, stateful_change): |
| 44 """Returns the flag to pass to image_to_vm for the stateful change.""" | 46 """Returns the flag to pass to image_to_vm for the stateful change.""" |
| 45 stateful_change_flag = '' | 47 stateful_change_flag = '' |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 This test checks that we can update by updating the stateful partition | 124 This test checks that we can update by updating the stateful partition |
| 123 rather than wiping it. | 125 rather than wiping it. |
| 124 """ | 126 """ |
| 125 # Just make sure some tests pass on original image. Some old images | 127 # Just make sure some tests pass on original image. Some old images |
| 126 # don't pass many tests. | 128 # don't pass many tests. |
| 127 self.PrepareBase() | 129 self.PrepareBase() |
| 128 # TODO(sosa): move to 100% once we start testing using the autotest paired | 130 # TODO(sosa): move to 100% once we start testing using the autotest paired |
| 129 # with the dev channel. | 131 # with the dev channel. |
| 130 percent_passed = self.VerifyImage(10) | 132 percent_passed = self.VerifyImage(10) |
| 131 | 133 |
| 134 if self.use_delta_updates: self.source_image = base_image_path |
| 135 |
| 132 # Update to - all tests should pass on new image. | 136 # Update to - all tests should pass on new image. |
| 133 Info('Updating from base image on vm to target image.') | 137 Info('Updating from base image on vm to target image.') |
| 134 self.UpdateImage(target_image_path) | 138 self.UpdateImage(target_image_path) |
| 135 self.VerifyImage(100) | 139 self.VerifyImage(100) |
| 136 | 140 |
| 141 if self.use_delta_updates: self.source_image = target_image_path |
| 142 |
| 137 # Update from - same percentage should pass that originally passed. | 143 # Update from - same percentage should pass that originally passed. |
| 138 Info('Updating from updated image on vm back to base image.') | 144 Info('Updating from updated image on vm back to base image.') |
| 139 self.UpdateImage(base_image_path) | 145 self.UpdateImage(base_image_path) |
| 140 self.VerifyImage(percent_passed) | 146 self.VerifyImage(percent_passed) |
| 141 | 147 |
| 142 # TODO(sosa): Re-enable once we have a good way of checking for version | 148 # TODO(sosa): Re-enable once we have a good way of checking for version |
| 143 # compatibility. | 149 # compatibility. |
| 144 def testFullUpdateWipeStateful(self): | 150 def testFullUpdateWipeStateful(self): |
| 145 """Tests if we can update after cleaning the stateful partition. | 151 """Tests if we can update after cleaning the stateful partition. |
| 146 | 152 |
| 147 This test checks that we can update successfully after wiping the | 153 This test checks that we can update successfully after wiping the |
| 148 stateful partition. | 154 stateful partition. |
| 149 """ | 155 """ |
| 150 # Just make sure some tests pass on original image. Some old images | 156 # Just make sure some tests pass on original image. Some old images |
| 151 # don't pass many tests. | 157 # don't pass many tests. |
| 152 self.PrepareBase() | 158 self.PrepareBase() |
| 153 # TODO(sosa): move to 100% once we start testing using the autotest paired | 159 # TODO(sosa): move to 100% once we start testing using the autotest paired |
| 154 # with the dev channel. | 160 # with the dev channel. |
| 155 percent_passed = self.VerifyImage(10) | 161 percent_passed = self.VerifyImage(10) |
| 156 | 162 |
| 163 if self.use_delta_updates: self.source_image = base_image_path |
| 164 |
| 157 # Update to - all tests should pass on new image. | 165 # Update to - all tests should pass on new image. |
| 158 Info('Updating from base image on vm to target image and wiping stateful.') | 166 Info('Updating from base image on vm to target image and wiping stateful.') |
| 159 self.UpdateImage(target_image_path, 'clean') | 167 self.UpdateImage(target_image_path, 'clean') |
| 160 self.VerifyImage(100) | 168 self.VerifyImage(100) |
| 161 | 169 |
| 170 if self.use_delta_updates: self.source_image = target_image_path |
| 171 |
| 162 # Update from - same percentage should pass that originally passed. | 172 # Update from - same percentage should pass that originally passed. |
| 163 Info('Updating from updated image back to base image and wiping stateful.') | 173 Info('Updating from updated image back to base image and wiping stateful.') |
| 164 self.UpdateImage(base_image_path, 'clean') | 174 self.UpdateImage(base_image_path, 'clean') |
| 165 self.VerifyImage(percent_passed) | 175 self.VerifyImage(percent_passed) |
| 166 | 176 |
| 167 | 177 |
| 168 class RealAUTest(unittest.TestCase, AUTest): | 178 class RealAUTest(unittest.TestCase, AUTest): |
| 169 """Test harness for updating real images.""" | 179 """Test harness for updating real images.""" |
| 170 | 180 |
| 171 def setUp(self): | 181 def setUp(self): |
| 172 AUTest.setUp(self) | 182 AUTest.setUp(self) |
| 173 | 183 |
| 174 def PrepareBase(self): | 184 def PrepareBase(self): |
| 175 """Auto-update to base image to prepare for test.""" | 185 """Auto-update to base image to prepare for test.""" |
| 176 self.UpdateImage(base_image_path) | 186 self.UpdateImage(base_image_path) |
| 177 | 187 |
| 178 def UpdateImage(self, image_path, stateful_change='old'): | 188 def UpdateImage(self, image_path, stateful_change='old'): |
| 179 """Updates a remote image using image_to_live.sh.""" | 189 """Updates a remote image using image_to_live.sh.""" |
| 180 stateful_change_flag = self.GetStatefulChangeFlag(stateful_change) | 190 stateful_change_flag = self.GetStatefulChangeFlag(stateful_change) |
| 181 | 191 |
| 182 RunCommand([ | 192 RunCommand([ |
| 183 '%s/image_to_live.sh' % self.crosutils, | 193 '%s/image_to_live.sh' % self.crosutils, |
| 184 '--image=%s' % image_path, | 194 '--image=%s' % image_path, |
| 185 '--remote=%s' % remote, | 195 '--remote=%s' % remote, |
| 186 stateful_change_flag, | 196 stateful_change_flag, |
| 187 '--verify', | 197 '--verify', |
| 198 '--src_image=%s' % self.source_image, |
| 188 ], enter_chroot=False) | 199 ], enter_chroot=False) |
| 189 | 200 |
| 190 | 201 |
| 191 def VerifyImage(self, percent_required_to_pass): | 202 def VerifyImage(self, percent_required_to_pass): |
| 192 """Verifies an image using run_remote_tests.sh with verification suite.""" | 203 """Verifies an image using run_remote_tests.sh with verification suite.""" |
| 193 output = RunCommand([ | 204 output = RunCommand([ |
| 194 '%s/run_remote_tests.sh' % self.crosutils, | 205 '%s/run_remote_tests.sh' % self.crosutils, |
| 195 '--remote=%s' % remote, | 206 '--remote=%s' % remote, |
| 196 _VERIFY_SUITE, | 207 _VERIFY_SUITE, |
| 197 ], error_ok=True, enter_chroot=False, redirect_stdout=True) | 208 ], error_ok=True, enter_chroot=False, redirect_stdout=True) |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 stateful_change_flag = self.GetStatefulChangeFlag(stateful_change) | 254 stateful_change_flag = self.GetStatefulChangeFlag(stateful_change) |
| 244 | 255 |
| 245 RunCommand(['%s/cros_run_vm_update' % self.crosutilsbin, | 256 RunCommand(['%s/cros_run_vm_update' % self.crosutilsbin, |
| 246 '--update_image_path=%s' % image_path, | 257 '--update_image_path=%s' % image_path, |
| 247 '--vm_image_path=%s' % self.vm_image_path, | 258 '--vm_image_path=%s' % self.vm_image_path, |
| 248 '--snapshot', | 259 '--snapshot', |
| 249 vm_graphics_flag, | 260 vm_graphics_flag, |
| 250 '--persist', | 261 '--persist', |
| 251 '--kvm_pid=%s' % _KVM_PID_FILE, | 262 '--kvm_pid=%s' % _KVM_PID_FILE, |
| 252 stateful_change_flag, | 263 stateful_change_flag, |
| 264 '--src_image=%s' % self.source_image, |
| 253 ], enter_chroot=False) | 265 ], enter_chroot=False) |
| 254 | 266 |
| 255 def VerifyImage(self, percent_required_to_pass): | 267 def VerifyImage(self, percent_required_to_pass): |
| 256 """Runs vm smoke suite to verify image.""" | 268 """Runs vm smoke suite to verify image.""" |
| 257 # image_to_live already verifies lsb-release matching. This is just | 269 # image_to_live already verifies lsb-release matching. This is just |
| 258 # for additional steps. | 270 # for additional steps. |
| 259 output = RunCommand(['%s/cros_run_vm_test' % self.crosutilsbin, | 271 output = RunCommand(['%s/cros_run_vm_test' % self.crosutilsbin, |
| 260 '--image_path=%s' % self.vm_image_path, | 272 '--image_path=%s' % self.vm_image_path, |
| 261 '--snapshot', | 273 '--snapshot', |
| 262 '--persist', | 274 '--persist', |
| (...skipping 12 matching lines...) Expand all Loading... |
| 275 parser.add_option('-t', '--target_image', | 287 parser.add_option('-t', '--target_image', |
| 276 help='path to the target image.') | 288 help='path to the target image.') |
| 277 parser.add_option('-r', '--board', | 289 parser.add_option('-r', '--board', |
| 278 help='board for the images.') | 290 help='board for the images.') |
| 279 parser.add_option('-p', '--type', default='vm', | 291 parser.add_option('-p', '--type', default='vm', |
| 280 help='type of test to run: [vm, real]. Default: vm.') | 292 help='type of test to run: [vm, real]. Default: vm.') |
| 281 parser.add_option('-m', '--remote', | 293 parser.add_option('-m', '--remote', |
| 282 help='Remote address for real test.') | 294 help='Remote address for real test.') |
| 283 parser.add_option('--no_graphics', action='store_true', | 295 parser.add_option('--no_graphics', action='store_true', |
| 284 help='Disable graphics for the vm test.') | 296 help='Disable graphics for the vm test.') |
| 297 parser.add_option('--no_delta', action='store_false', default=True, |
| 298 dest='delta', |
| 299 help='Disable using delta updates.') |
| 285 # Set the usage to include flags. | 300 # Set the usage to include flags. |
| 286 parser.set_usage(parser.format_help()) | 301 parser.set_usage(parser.format_help()) |
| 287 # Parse existing sys.argv so we can pass rest to unittest.main. | 302 # Parse existing sys.argv so we can pass rest to unittest.main. |
| 288 (options, sys.argv) = parser.parse_args(sys.argv) | 303 (options, sys.argv) = parser.parse_args(sys.argv) |
| 289 | 304 |
| 290 base_image_path = options.base_image | 305 base_image_path = options.base_image |
| 291 target_image_path = options.target_image | 306 target_image_path = options.target_image |
| 292 board = options.board | 307 board = options.board |
| 293 | 308 |
| 294 if not base_image_path: | 309 if not base_image_path: |
| 295 parser.error('Need path to base image for vm.') | 310 parser.error('Need path to base image for vm.') |
| 296 elif not os.path.exists(base_image_path): | 311 elif not os.path.exists(base_image_path): |
| 297 Die('%s does not exist' % base_image_path) | 312 Die('%s does not exist' % base_image_path) |
| 298 | 313 |
| 299 if not target_image_path: | 314 if not target_image_path: |
| 300 parser.error('Need path to target image to update with.') | 315 parser.error('Need path to target image to update with.') |
| 301 elif not os.path.exists(target_image_path): | 316 elif not os.path.exists(target_image_path): |
| 302 Die('%s does not exist' % target_image_path) | 317 Die('%s does not exist' % target_image_path) |
| 303 | 318 |
| 304 if not board: | 319 if not board: |
| 305 parser.error('Need board to convert base image to vm.') | 320 parser.error('Need board to convert base image to vm.') |
| 306 | 321 |
| 322 # Communicate flags to tests. |
| 307 vm_graphics_flag = '' | 323 vm_graphics_flag = '' |
| 308 if options.no_graphics: vm_graphics_flag = '--no_graphics' | 324 if options.no_graphics: vm_graphics_flag = '--no_graphics' |
| 309 | 325 |
| 326 AUTest.use_delta_updates = options.delta |
| 327 |
| 310 # Only run the test harness we care about. | 328 # Only run the test harness we care about. |
| 311 if options.type == 'vm': | 329 if options.type == 'vm': |
| 312 suite = unittest.TestLoader().loadTestsFromTestCase(VirtualAUTest) | 330 suite = unittest.TestLoader().loadTestsFromTestCase(VirtualAUTest) |
| 313 test_result = unittest.TextTestRunner(verbosity=2).run(suite) | 331 test_result = unittest.TextTestRunner(verbosity=2).run(suite) |
| 314 elif options.type == 'real': | 332 elif options.type == 'real': |
| 315 if not options.remote: | 333 if not options.remote: |
| 316 parser.error('Real tests require a remote test machine.') | 334 parser.error('Real tests require a remote test machine.') |
| 317 else: | 335 else: |
| 318 remote = options.remote | 336 remote = options.remote |
| 319 | 337 |
| 320 suite = unittest.TestLoader().loadTestsFromTestCase(RealAUTest) | 338 suite = unittest.TestLoader().loadTestsFromTestCase(RealAUTest) |
| 321 test_result = unittest.TextTestRunner(verbosity=2).run(suite) | 339 test_result = unittest.TextTestRunner(verbosity=2).run(suite) |
| 322 else: | 340 else: |
| 323 parser.error('Could not parse harness type %s.' % options.type) | 341 parser.error('Could not parse harness type %s.' % options.type) |
| 324 | 342 |
| 325 if not test_result.wasSuccessful(): | 343 if not test_result.wasSuccessful(): |
| 326 Die('Test harness was not successful') | 344 Die('Test harness was not successful') |
| OLD | NEW |