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

Side by Side Diff: bin/au_test_harness/cros_au_test_harness.py

Issue 6717011: Remove au_test_harness code and change symlinks to point to new location (Closed) Base URL: http://git.chromium.org/git/crosutils.git@master
Patch Set: Created 9 years, 9 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 | « bin/au_test_harness/au_worker.py ('k') | bin/au_test_harness/cros_test_proxy.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/python
2
3 # Copyright (c) 2011 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 """This module runs a suite of Auto Update tests.
8
9 The tests can be run on either a virtual machine or actual device depending
10 on parameters given. Specific tests can be run by invoking --test_prefix.
11 Verbose is useful for many of the tests if you want to see individual commands
12 being run during the update process.
13 """
14
15 import optparse
16 import os
17 import re
18 import sys
19 import unittest
20
21 sys.path.append(os.path.join(os.path.dirname(__file__), '../lib'))
22 import cros_build_lib as cros_lib
23
24 import au_test
25 import au_worker
26 import dummy_au_worker
27 import dev_server_wrapper
28 import parallel_test_job
29 import public_key_manager
30 import update_exception
31
32 def _PrepareTestSuite(options, use_dummy_worker=False):
33 """Returns a prepared test suite given by the options and test class."""
34 au_test.AUTest.ProcessOptions(options, use_dummy_worker)
35 test_loader = unittest.TestLoader()
36 test_loader.testMethodPrefix = options.test_prefix
37 return test_loader.loadTestsFromTestCase(au_test.AUTest)
38
39
40 def _PregenerateUpdates(options):
41 """Determines all deltas that will be generated and generates them.
42
43 This method effectively pre-generates the dev server cache for all tests.
44
45 Args:
46 options: options from parsed parser.
47 Returns:
48 Dictionary of Update Identifiers->Relative cache locations.
49 Raises:
50 update_exception.UpdateException if we fail to generate an update.
51 """
52 def _GenerateVMUpdate(target, src, private_key_path):
53 """Generates an update using the devserver."""
54 command = ['./enter_chroot.sh',
55 '--',
56 'sudo',
57 'start_devserver',
58 '--pregenerate_update',
59 '--exit',
60 ]
61 # Add actual args to command.
62 command.append('--image=%s' % cros_lib.ReinterpretPathForChroot(target))
63 if src: command.append('--src_image=%s' %
64 cros_lib.ReinterpretPathForChroot(src))
65 if options.type == 'vm': command.append('--for_vm')
66 if private_key_path:
67 command.append('--private_key=%s' %
68 cros_lib.ReinterpretPathForChroot(private_key_path))
69
70 return cros_lib.RunCommandCaptureOutput(command, combine_stdout_stderr=True,
71 print_cmd=True)
72
73 # Use dummy class to mock out updates that would be run as part of a test.
74 test_suite = _PrepareTestSuite(options, use_dummy_worker=True)
75 test_result = unittest.TextTestRunner(verbosity=0).run(test_suite)
76 if not test_result.wasSuccessful():
77 raise update_exception.UpdateException(1,
78 'Error finding updates to generate.')
79
80 cros_lib.Info('The following delta updates are required.')
81 update_ids = []
82 jobs = []
83 args = []
84 modified_images = set()
85 for target, srcs in dummy_au_worker.DummyAUWorker.delta_list.items():
86 modified_images.add(target)
87 for src_key in srcs:
88 (src, _ , key) = src_key.partition('+')
89 if src: modified_images.add(src)
90 # TODO(sosa): Add private key as part of caching name once devserver can
91 # handle it its own cache.
92 update_id = dev_server_wrapper.GenerateUpdateId(target, src, key)
93 print >> sys.stderr, 'AU: %s' % update_id
94 update_ids.append(update_id)
95 jobs.append(_GenerateVMUpdate)
96 args.append((target, src, key))
97
98 # Always add the base image path. This is only useful for non-delta updates.
99 modified_images.add(options.base_image)
100
101 # Add public key to all images we are using.
102 if options.public_key:
103 cros_lib.Info('Adding public keys to images for testing.')
104 for image in modified_images:
105 manager = public_key_manager.PublicKeyManager(image, options.public_key)
106 manager.AddKeyToImage()
107 au_test.AUTest.public_key_managers.append(manager)
108
109 raw_results = parallel_test_job.RunParallelJobs(options.jobs, jobs, args,
110 print_status=True)
111 results = []
112
113 # Looking for this line in the output.
114 key_line_re = re.compile('^PREGENERATED_UPDATE=([\w/.]+)')
115 for result in raw_results:
116 (return_code, output, _) = result
117 if return_code != 0:
118 cros_lib.Warning(output)
119 raise update_exception.UpdateException(return_code,
120 'Failed to generate all updates.')
121 else:
122 for line in output.splitlines():
123 match = key_line_re.search(line)
124 if match:
125 # Convert blah/blah/update.gz -> update/blah/blah.
126 path_to_update_gz = match.group(1).rstrip()
127 (path_to_update_dir, _, _) = path_to_update_gz.rpartition(
128 '/update.gz')
129 results.append('/'.join(['update', path_to_update_dir]))
130 break
131
132 # Make sure all generation of updates returned cached locations.
133 if len(raw_results) != len(results):
134 raise update_exception.UpdateException(
135 1, 'Insufficient number cache directories returned.')
136
137 # Build the dictionary from our id's and returned cache paths.
138 cache_dictionary = {}
139 for index, id in enumerate(update_ids):
140 cache_dictionary[id] = results[index]
141
142 return cache_dictionary
143
144
145 def _RunTestsInParallel(options):
146 """Runs the tests given by the options in parallel."""
147 threads = []
148 args = []
149 test_suite = _PrepareTestSuite(options)
150 for test in test_suite:
151 test_name = test.id()
152 test_case = unittest.TestLoader().loadTestsFromName(test_name)
153 threads.append(unittest.TextTestRunner(verbosity=2).run)
154 args.append(test_case)
155
156 results = parallel_test_job.RunParallelJobs(options.jobs, threads, args,
157 print_status=False)
158 for test_result in results:
159 if not test_result.wasSuccessful():
160 cros_lib.Die('Test harness was not successful')
161
162
163 def _CleanPreviousWork(options):
164 """Cleans up previous work from the devserver cache and local image cache."""
165 cros_lib.Info('Cleaning up previous work.')
166 # Wipe devserver cache.
167 cros_lib.RunCommandCaptureOutput(
168 ['sudo', 'start_devserver', '--clear_cache', '--exit', ],
169 enter_chroot=True, print_cmd=False, combine_stdout_stderr=True)
170
171 # Clean previous vm images if they exist.
172 if options.type == 'vm':
173 target_vm_image_path = '%s/chromiumos_qemu_image.bin' % os.path.dirname(
174 options.target_image)
175 base_vm_image_path = '%s/chromiumos_qemu_image.bin' % os.path.dirname(
176 options.base_image)
177 if os.path.exists(target_vm_image_path): os.remove(target_vm_image_path)
178 if os.path.exists(base_vm_image_path): os.remove(base_vm_image_path)
179
180
181 def main():
182 parser = optparse.OptionParser()
183 parser.add_option('-b', '--base_image',
184 help='path to the base image.')
185 parser.add_option('-r', '--board',
186 help='board for the images.')
187 parser.add_option('--clean', default=False, dest='clean', action='store_true',
188 help='Clean all previous state')
189 parser.add_option('--no_delta', action='store_false', default=True,
190 dest='delta',
191 help='Disable using delta updates.')
192 parser.add_option('--no_graphics', action='store_true',
193 help='Disable graphics for the vm test.')
194 parser.add_option('-j', '--jobs', default=8, type=int,
195 help='Number of simultaneous jobs')
196 parser.add_option('--public_key', default=None,
197 help='Public key to use on images and updates.')
198 parser.add_option('--private_key', default=None,
199 help='Private key to use on images and updates.')
200 parser.add_option('-q', '--quick_test', default=False, action='store_true',
201 help='Use a basic test to verify image.')
202 parser.add_option('-m', '--remote',
203 help='Remote address for real test.')
204 parser.add_option('-t', '--target_image',
205 help='path to the target image.')
206 parser.add_option('--test_results_root', default=None,
207 help='Root directory to store test results. Should '
208 'be defined relative to chroot root.')
209 parser.add_option('--test_prefix', default='test',
210 help='Only runs tests with specific prefix i.e. '
211 'testFullUpdateWipeStateful.')
212 parser.add_option('-p', '--type', default='vm',
213 help='type of test to run: [vm, real]. Default: vm.')
214 parser.add_option('--verbose', default=True, action='store_true',
215 help='Print out rather than capture output as much as '
216 'possible.')
217 (options, leftover_args) = parser.parse_args()
218
219 if leftover_args: parser.error('Found unsupported flags: %s' % leftover_args)
220
221 assert options.target_image and os.path.exists(options.target_image), \
222 'Target image path does not exist'
223 if not options.base_image:
224 cros_lib.Info('Base image not specified. Using target as base image.')
225 options.base_image = options.target_image
226
227 if options.private_key or options.public_key:
228 error_msg = ('Could not find %s key. Both private and public keys must be '
229 'specified if either is specified.')
230 assert options.private_key and os.path.exists(options.private_key), \
231 error_msg % 'private'
232 assert options.public_key and os.path.exists(options.public_key), \
233 error_msg % 'public'
234
235 # Clean up previous work if requested.
236 if options.clean: _CleanPreviousWork(options)
237
238 # Make sure we have a log directory.
239 if options.test_results_root and not os.path.exists(
240 options.test_results_root):
241 os.makedirs(options.test_results_root)
242
243 # Pre-generate update modifies images by adding public keys to them.
244 # Wrap try to make sure we clean this up before we're done.
245 try:
246 # Generate cache of updates to use during test harness.
247 update_cache = _PregenerateUpdates(options)
248 au_worker.AUWorker.SetUpdateCache(update_cache)
249
250 my_server = dev_server_wrapper.DevServerWrapper(
251 au_test.AUTest.test_results_root)
252 my_server.start()
253 try:
254 if options.type == 'vm':
255 _RunTestsInParallel(options)
256 else:
257 # TODO(sosa) - Take in a machine pool for a real test.
258 # Can't run in parallel with only one remote device.
259 test_suite = _PrepareTestSuite(options)
260 test_result = unittest.TextTestRunner(verbosity=2).run(test_suite)
261 if not test_result.wasSuccessful(): cros_lib.Die('Test harness failed.')
262
263 finally:
264 my_server.Stop()
265
266 finally:
267 # Un-modify any target images we modified. We don't need to un-modify
268 # non-targets because they aren't important for archival steps.
269 if options.public_key:
270 cros_lib.Info('Cleaning up. Removing keys added as part of testing.')
271 target_directory = os.path.dirname(options.target_image)
272 for key_manager in au_test.AUTest.public_key_managers:
273 if key_manager.image_path.startswith(target_directory):
274 key_manager.RemoveKeyFromImage()
275
276
277 if __name__ == '__main__':
278 main()
OLDNEW
« no previous file with comments | « bin/au_test_harness/au_worker.py ('k') | bin/au_test_harness/cros_test_proxy.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698