Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(244)

Side by Side Diff: bin/cros_au_test_harness.py

Issue 3619009: Add ability to test machines with au test harness. (Closed) Base URL: http://git.chromium.org/git/crosutils.git
Patch Set: Add todo and disable test Created 10 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | bin/cros_run_vm_update » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
11 11
12 sys.path.append(os.path.join(os.path.dirname(__file__), '../lib')) 12 sys.path.append(os.path.join(os.path.dirname(__file__), '../lib'))
13 from cros_build_lib import RunCommand, Info, Warning, ReinterpretPathForChroot 13 from cros_build_lib import RunCommand, Info, Warning, ReinterpretPathForChroot
14 14
15 _KVM_PID_FILE = '/tmp/harness_pid' 15 _KVM_PID_FILE = '/tmp/harness_pid'
16 _SCRIPTS_DIR = os.path.join(os.path.dirname(__file__), '..')
17 _FULL_VDISK_SIZE = 6072 16 _FULL_VDISK_SIZE = 6072
18 _FULL_STATEFULFS_SIZE = 2048 17 _FULL_STATEFULFS_SIZE = 2048
19 18
19 # Globals to communicate options to unit tests.
20 global base_image_path 20 global base_image_path
21 global board 21 global board
22 global remote
22 global target_image_path 23 global target_image_path
23 24
24 _VERIFY_SUITE = 'suite_Smoke' 25 _VERIFY_SUITE = 'suite_Smoke'
25 26
26 class AUTest(object): 27 class AUTest(object):
27 """Abstract interface that defines an Auto Update test.""" 28 """Abstract interface that defines an Auto Update test."""
28 29
30 def setUp(self):
31 unittest.TestCase.setUp(self)
32 # Set these up as they are used often.
33 self.crosutils = os.path.join(os.path.dirname(__file__), '..')
34 self.crosutilsbin = os.path.join(os.path.dirname(__file__))
35
36 def GetStatefulChangeFlag(self, stateful_change):
37 """Returns the flag to pass to image_to_vm for the stateful change."""
38 stateful_change_flag = ''
39 if stateful_change:
40 stateful_change_flag = '--stateful_update_flag=%s' % stateful_change
41
42 return stateful_change_flag
43
29 def PrepareBase(self): 44 def PrepareBase(self):
30 """Prepares target with base_image_path.""" 45 """Prepares target with base_image_path."""
31 pass 46 pass
32 47
33 def UpdateImage(self, image_path, stateful_change='old'): 48 def UpdateImage(self, image_path, stateful_change='old'):
34 """Updates target with the image given by the image_path. 49 """Updates target with the image given by the image_path.
35 50
36 Args: 51 Args:
37 image_path: Path to the image to update with. This image must be a test 52 image_path: Path to the image to update with. This image must be a test
38 image. 53 image.
39 stateful_change: How to modify the stateful partition. Values are: 54 stateful_change: How to modify the stateful partition. Values are:
40 'old': Don't modify stateful partition. Just update normally. 55 'old': Don't modify stateful partition. Just update normally.
41 'clean': Uses clobber-state to wipe the stateful partition with the 56 'clean': Uses clobber-state to wipe the stateful partition with the
42 exception of code needed for ssh. 57 exception of code needed for ssh.
43 """ 58 """
44 pass 59 pass
45 60
46 def VerifyImage(self): 61 def VerifyImage(self):
47 """Verifies the image is correct.""" 62 """Verifies the image is correct."""
48 pass 63 pass
49 64
50 def testFullUpdateKeepStateful(self): 65 def testFullUpdateKeepStateful(self):
66 """Tests if we can update normally.
67
68 This test checks that we can update by updating the stateful partition
69 rather than wiping it.
70 """
51 # Prepare and verify the base image has been prepared correctly. 71 # Prepare and verify the base image has been prepared correctly.
52 self.PrepareBase() 72 self.PrepareBase()
53 self.VerifyImage() 73 self.VerifyImage()
54 74
55 # Update to. 75 # Update to.
56 Info('Updating from base image on vm to target image.') 76 Info('Updating from base image on vm to target image.')
57 self.UpdateImage(target_image_path) 77 self.UpdateImage(target_image_path)
58 self.VerifyImage() 78 self.VerifyImage()
59 79
60 # Update from. 80 # Update from.
61 Info('Updating from updated image on vm back to base image.') 81 Info('Updating from updated image on vm back to base image.')
62 self.UpdateImage(base_image_path) 82 self.UpdateImage(base_image_path)
63 self.VerifyImage() 83 self.VerifyImage()
64 84
65 def testFullUpdateWipeStateful(self): 85 # TODO(sosa): Re-enable once we have a good way of checking for version
86 # compatability.
87 def NotestFullUpdateWipeStateful(self):
88 """Tests if we can update after cleaning the stateful partition.
89
90 This test checks that we can update successfully after wiping the
91 stateful partition.
92 """
66 # Prepare and verify the base image has been prepared correctly. 93 # Prepare and verify the base image has been prepared correctly.
67 self.PrepareBase() 94 self.PrepareBase()
68 self.VerifyImage() 95 self.VerifyImage()
69 96
70 # Update to. 97 # Update to.
71 Info('Updating from base image on vm to target image and wiping stateful.') 98 Info('Updating from base image on vm to target image and wiping stateful.')
72 self.UpdateImage(target_image_path, 'clean') 99 self.UpdateImage(target_image_path, 'clean')
73 self.VerifyImage() 100 self.VerifyImage()
74 101
75 # Update from. 102 # Update from.
76 Info('Updating from updated image back to base image and wiping stateful.') 103 Info('Updating from updated image back to base image and wiping stateful.')
77 self.UpdateImage(base_image_path, 'clean') 104 self.UpdateImage(base_image_path, 'clean')
78 self.VerifyImage() 105 self.VerifyImage()
79 106
80 107
108 class RealAUTest(unittest.TestCase, AUTest):
109 """Test harness for updating real images."""
110
111 def setUp(self):
112 AUTest.setUp(self)
113
114 def UpdateImage(self, image_path, stateful_change='old'):
115 """Updates a remote image using image_to_live.sh."""
116 stateful_change_flag = self.GetStatefulChangeFlag(stateful_change)
117
118 RunCommand([
119 '%s/image_to_live.sh' % self.crosutils,
120 '--image=%s' % image_path,
121 '--remote=%s' % remote,
122 stateful_change_flag,
123 '--verify',
124 ], enter_chroot=False)
125
126
127 def NotVerifyImage(self):
128 """Verifies an image using run_remote_tests.sh with verification suite."""
129 RunCommand([
130 '%s/run_remote_tests.sh' % self.crosutils,
131 '--remote=%s' % remote,
132 _VERIFY_SUITE,
133 ], error_ok=False, enter_chroot=False)
134
135
81 class VirtualAUTest(unittest.TestCase, AUTest): 136 class VirtualAUTest(unittest.TestCase, AUTest):
82 """Test harness for updating virtual machines.""" 137 """Test harness for updating virtual machines."""
83 vm_image_path = None 138 vm_image_path = None
84 139
85 def _KillExistingVM(self, pid_file): 140 def _KillExistingVM(self, pid_file):
86 if os.path.exists(pid_file): 141 if os.path.exists(pid_file):
87 Warning('Existing %s found. Deleting and killing process' % 142 Warning('Existing %s found. Deleting and killing process' %
88 pid_file) 143 pid_file)
89 pid = RunCommand(['sudo', 'cat', pid_file], redirect_stdout=True, 144 pid = RunCommand(['sudo', 'cat', pid_file], redirect_stdout=True,
90 enter_chroot=False) 145 enter_chroot=False)
91 if pid: 146 if pid:
92 RunCommand(['sudo', 'kill', pid.strip()], error_ok=True, 147 RunCommand(['sudo', 'kill', pid.strip()], error_ok=True,
93 enter_chroot=False) 148 enter_chroot=False)
94 RunCommand(['sudo', 'rm', pid_file], enter_chroot=False) 149 RunCommand(['sudo', 'rm', pid_file], enter_chroot=False)
95 150
96 def setUp(self): 151 def setUp(self):
97 """Unit test overriden method. Is called before every test.""" 152 """Unit test overriden method. Is called before every test."""
98 153 AUTest.setUp(self)
99 self._KillExistingVM(_KVM_PID_FILE) 154 self._KillExistingVM(_KVM_PID_FILE)
100 155
101 def PrepareBase(self): 156 def PrepareBase(self):
102 """Creates an update-able VM based on base image.""" 157 """Creates an update-able VM based on base image."""
103 158
104 self.vm_image_path = ('%s/chromiumos_qemu_image.bin' % os.path.dirname( 159 self.vm_image_path = ('%s/chromiumos_qemu_image.bin' % os.path.dirname(
105 base_image_path)) 160 base_image_path))
106 if not os.path.exists(self.vm_image_path): 161 if not os.path.exists(self.vm_image_path):
107 Info('Qemu image not found, creating one.') 162 Info('Qemu image not found, creating one.')
108 RunCommand(['%s/image_to_vm.sh' % _SCRIPTS_DIR, 163 RunCommand(['%s/image_to_vm.sh' % self.crosutils,
109 '--full', 164 '--full',
110 '--from %s' % ReinterpretPathForChroot( 165 '--from %s' % ReinterpretPathForChroot(
111 os.path.dirname(base_image_path)), 166 os.path.dirname(base_image_path)),
112 '--vdisk_size %s' % _FULL_VDISK_SIZE, 167 '--vdisk_size %s' % _FULL_VDISK_SIZE,
113 '--statefulfs_size %s' % _FULL_STATEFULFS_SIZE, 168 '--statefulfs_size %s' % _FULL_STATEFULFS_SIZE,
114 '--board %s' % board, 169 '--board %s' % board,
115 '--test_image'], enter_chroot=True) 170 '--test_image'], enter_chroot=True)
116 else: 171 else:
117 Info('Using existing VM image') 172 Info('Using existing VM image')
118 173
119 self.assertTrue(os.path.exists(self.vm_image_path)) 174 self.assertTrue(os.path.exists(self.vm_image_path))
120 175
121 def UpdateImage(self, image_path, stateful_change='old'): 176 def UpdateImage(self, image_path, stateful_change='old'):
122 """Updates VM image with image_path.""" 177 """Updates VM image with image_path."""
178 stateful_change_flag = self.GetStatefulChangeFlag(stateful_change)
123 179
124 stateful_change_flag = '' 180 RunCommand(['%s/cros_run_vm_update' % self.crosutilsbin,
125 if stateful_change:
126 stateful_change_flag = '--stateful_flags=%s' % stateful_change
127
128 RunCommand(['%s/cros_run_vm_update' % os.path.dirname(__file__),
129 '--update_image_path=%s' % image_path, 181 '--update_image_path=%s' % image_path,
130 '--vm_image_path=%s' % self.vm_image_path, 182 '--vm_image_path=%s' % self.vm_image_path,
131 '--snapshot', 183 '--snapshot',
132 '--persist', 184 '--persist',
133 '--kvm_pid=%s' % _KVM_PID_FILE, 185 '--kvm_pid=%s' % _KVM_PID_FILE,
134 stateful_change_flag, 186 stateful_change_flag,
135 ], enter_chroot=False) 187 ], enter_chroot=False)
136 188
137 def VerifyImage(self): 189 def VerifyImage(self):
138 """Runs vm smoke suite to verify image.""" 190 """Runs vm smoke suite to verify image."""
139
140 # image_to_live already verifies lsb-release matching. This is just 191 # image_to_live already verifies lsb-release matching. This is just
141 # for additional steps. 192 # for additional steps.
142 193 RunCommand(['%s/cros_run_vm_test' % self.crosutilsbin,
143 # TODO(sosa): Compare output with results of base image.
144 RunCommand(['%s/cros_run_vm_test' % os.path.dirname(__file__),
145 '--image_path=%s' % self.vm_image_path, 194 '--image_path=%s' % self.vm_image_path,
146 '--snapshot', 195 '--snapshot',
147 '--persist', 196 '--persist',
148 '--kvm_pid=%s' % _KVM_PID_FILE, 197 '--kvm_pid=%s' % _KVM_PID_FILE,
149 '--test_case=%s' % _VERIFY_SUITE, 198 '--test_case=%s' % _VERIFY_SUITE,
150 ], error_ok=True, enter_chroot=False) 199 ], error_ok=False, enter_chroot=False)
151 200
152 201
153 if __name__ == '__main__': 202 if __name__ == '__main__':
154 parser = optparse.OptionParser() 203 parser = optparse.OptionParser()
155 parser.add_option('-b', '--base_image', 204 parser.add_option('-b', '--base_image',
156 help='path to the base image.') 205 help='path to the base image.')
157 parser.add_option('-t', '--target_image', 206 parser.add_option('-t', '--target_image',
158 help='path to the target image') 207 help='path to the target image.')
159 parser.add_option('-r', '--board', 208 parser.add_option('-r', '--board',
160 help='board for the images') 209 help='board for the images.')
210 parser.add_option('-p', '--type', default='vm',
211 help='type of test to run: [vm, real]. Default: vm.')
212 parser.add_option('-m', '--remote',
213 help='Remote address for real test.')
161 # Set the usage to include flags. 214 # Set the usage to include flags.
162 parser.set_usage(parser.format_help()) 215 parser.set_usage(parser.format_help())
163 # Parse existing sys.argv so we can pass rest to unittest.main. 216 # Parse existing sys.argv so we can pass rest to unittest.main.
164 (options, sys.argv) = parser.parse_args(sys.argv) 217 (options, sys.argv) = parser.parse_args(sys.argv)
165 218
166 base_image_path = options.base_image 219 base_image_path = options.base_image
167 target_image_path = options.target_image 220 target_image_path = options.target_image
168 board = options.board 221 board = options.board
169 222
170 if not base_image_path: 223 if not base_image_path:
171 parser.error('Need path to base image for vm.') 224 parser.error('Need path to base image for vm.')
172 225
173 if not target_image_path: 226 if not target_image_path:
174 parser.error('Need path to target image to update with.') 227 parser.error('Need path to target image to update with.')
175 228
176 if not board: 229 if not board:
177 parser.error('Need board to convert base image to vm.') 230 parser.error('Need board to convert base image to vm.')
178 231
179 unittest.main() 232 # Only run the test harness we care about.
233 if options.type == 'vm':
234 suite = unittest.TestLoader().loadTestsFromTestCase(VirtualAUTest)
235 unittest.TextTestRunner(verbosity=2).run(suite)
236 elif options.type == 'real':
237 if not options.remote:
238 parser.error('Real tests require a remote test machine.')
239 else:
240 remote = options.remote
241
242 suite = unittest.TestLoader().loadTestsFromTestCase(RealAUTest)
243 unittest.TextTestRunner(verbosity=2).run(suite)
244 else:
245 parser.error('Could not parse harness type %s.' % options.type)
OLDNEW
« no previous file with comments | « no previous file | bin/cros_run_vm_update » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698