OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/python |
| 2 |
| 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 |
| 5 # found in the LICENSE file. |
| 6 |
| 7 import optparse |
| 8 import os |
| 9 import sys |
| 10 import unittest |
| 11 |
| 12 sys.path.append(os.path.join(os.path.dirname(__file__), '../lib')) |
| 13 from cros_build_lib import RunCommand, Info, Warning |
| 14 |
| 15 _KVM_PID_FILE = '/tmp/harness_pid' |
| 16 _SCRIPTS_DIR = os.path.join(os.path.dirname(__file__), '..') |
| 17 _FULL_VDISK_SIZE = 6072 |
| 18 _FULL_STATEFULFS_SIZE = 2048 |
| 19 |
| 20 global base_image_path |
| 21 global target_image_path |
| 22 |
| 23 _VERIFY_SUITE = 'suite_Smoke' |
| 24 |
| 25 class AUTest(object): |
| 26 """Abstract interface that defines an Auto Update test.""" |
| 27 |
| 28 def PrepareBase(self): |
| 29 """Prepares target with base_image_path.""" |
| 30 pass |
| 31 |
| 32 def UpdateImage(self, image_path, stateful_change='old'): |
| 33 """Updates target with the image given by the image_path. |
| 34 |
| 35 Args: |
| 36 image_path: Path to the image to update with. This image must be a test |
| 37 image. |
| 38 stateful_change: How to modify the stateful partition. Values are: |
| 39 'old': Don't modify stateful partition. Just update normally. |
| 40 'clean': Uses clobber-state to wipe the stateful partition with the |
| 41 exception of code needed for ssh. |
| 42 """ |
| 43 pass |
| 44 |
| 45 def VerifyImage(self): |
| 46 """Verifies the image is correct.""" |
| 47 pass |
| 48 |
| 49 def testFullUpdateKeepStateful(self): |
| 50 # Prepare and verify the base image has been prepared correctly. |
| 51 self.PrepareBase() |
| 52 self.VerifyImage() |
| 53 |
| 54 # Update to. |
| 55 Info('Updating from base image on vm to target image.') |
| 56 self.UpdateImage(target_image_path) |
| 57 self.VerifyImage() |
| 58 |
| 59 # Update from. |
| 60 Info('Updating from updated image on vm back to base image.') |
| 61 self.UpdateImage(base_image_path) |
| 62 self.VerifyImage() |
| 63 |
| 64 def testFullUpdateWipeStateful(self): |
| 65 # Prepare and verify the base image has been prepared correctly. |
| 66 self.PrepareBase() |
| 67 self.VerifyImage() |
| 68 |
| 69 # Update to. |
| 70 Info('Updating from base image on vm to target image and wiping stateful.') |
| 71 self.UpdateImage(target_image_path, 'clean') |
| 72 self.VerifyImage() |
| 73 |
| 74 # Update from. |
| 75 Info('Updating from updated image back to base image and wiping stateful.') |
| 76 self.UpdateImage(base_image_path, 'clean') |
| 77 self.VerifyImage() |
| 78 |
| 79 |
| 80 class VirtualAUTest(unittest.TestCase, AUTest): |
| 81 """Test harness for updating virtual machines.""" |
| 82 vm_image_path = None |
| 83 |
| 84 def _KillExistingVM(self, pid_file): |
| 85 if os.path.exists(pid_file): |
| 86 Warning('Existing %s found. Deleting and killing process' % |
| 87 pid_file) |
| 88 pid = RunCommand(['sudo', 'cat', pid_file], redirect_stdout=True, |
| 89 enter_chroot=False) |
| 90 if pid: |
| 91 RunCommand(['sudo', 'kill', pid.strip()], error_ok=True, |
| 92 enter_chroot=False) |
| 93 RunCommand(['sudo', 'rm', pid_file], enter_chroot=False) |
| 94 |
| 95 def setUp(self): |
| 96 """Unit test overriden method. Is called before every test.""" |
| 97 |
| 98 self._KillExistingVM(_KVM_PID_FILE) |
| 99 |
| 100 def PrepareBase(self): |
| 101 """Creates an update-able VM based on base image.""" |
| 102 |
| 103 self.vm_image_path = ('%s/chromiumos_qemu_image.bin' % os.path.dirname( |
| 104 base_image_path)) |
| 105 if not os.path.exists(self.vm_image_path): |
| 106 Info('Qemu image not found, creating one.') |
| 107 RunCommand(['%s/image_to_vm.sh' % _SCRIPTS_DIR, |
| 108 '--full', |
| 109 '--from %s' % os.path.dirname(base_image_path), |
| 110 '--vdisk_size %s' % _FULL_VDISK_SIZE, |
| 111 '--statefulfs_size %s' % _FULL_STATEFULFS_SIZE, |
| 112 '--test_image'], enter_chroot=True) |
| 113 else: |
| 114 Info('Using existing VM image') |
| 115 |
| 116 self.assertTrue(os.path.exists(self.vm_image_path)) |
| 117 |
| 118 def UpdateImage(self, image_path, stateful_change='old'): |
| 119 """Updates VM image with image_path.""" |
| 120 |
| 121 stateful_change_flag = '' |
| 122 if stateful_change: |
| 123 stateful_change_flag = '--stateful_flags=%s' % stateful_change |
| 124 |
| 125 RunCommand(['%s/cros_run_vm_update' % os.path.dirname(__file__), |
| 126 '--update_image_path=%s' % image_path, |
| 127 '--vm_image_path=%s' % self.vm_image_path, |
| 128 '--snapshot', |
| 129 '--persist', |
| 130 '--kvm_pid=%s' % _KVM_PID_FILE, |
| 131 stateful_change_flag, |
| 132 ], enter_chroot=False) |
| 133 |
| 134 def VerifyImage(self): |
| 135 """Runs vm smoke suite to verify image.""" |
| 136 |
| 137 # image_to_live already verifies lsb-release matching. This is just |
| 138 # for additional steps. |
| 139 |
| 140 # TODO(sosa): Compare output with results of base image. |
| 141 RunCommand(['%s/cros_run_vm_test' % os.path.dirname(__file__), |
| 142 '--image_path=%s' % self.vm_image_path, |
| 143 '--snapshot', |
| 144 '--persist', |
| 145 '--kvm_pid=%s' % _KVM_PID_FILE, |
| 146 '--test_case=%s' % _VERIFY_SUITE, |
| 147 ], error_ok=True, enter_chroot=False) |
| 148 |
| 149 |
| 150 if __name__ == '__main__': |
| 151 parser = optparse.OptionParser() |
| 152 parser.add_option('-b', '--base_image', |
| 153 help='path to the base image.') |
| 154 parser.add_option('-t', '--target_image', |
| 155 help='path to the target image') |
| 156 # Set the usage to include flags. |
| 157 parser.set_usage(parser.format_help()) |
| 158 # Parse existing sys.argv so we can pass rest to unittest.main. |
| 159 (options, sys.argv) = parser.parse_args(sys.argv) |
| 160 |
| 161 base_image_path = options.base_image |
| 162 target_image_path = options.target_image |
| 163 |
| 164 if not base_image_path: |
| 165 parser.error('Need path to base image for vm.') |
| 166 |
| 167 if not target_image_path: |
| 168 parser.error('Need path to target image to update with.') |
| 169 |
| 170 unittest.main() |
OLD | NEW |