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 # A python wrapper to call autotest ebuild. | |
8 | |
9 import commands, logging, optparse, os, subprocess, sys | |
10 | |
11 | |
12 def run(cmd): | |
13 return subprocess.call(cmd, stdout=sys.stdout, stderr=sys.stderr) | |
14 | |
15 | |
16 class MyOptionParser(optparse.OptionParser): | |
17 """Override python's builtin OptionParser to accept any undefined args.""" | |
18 | |
19 help = False | |
20 | |
21 def _process_args(self, largs, rargs, values): | |
22 # see /usr/lib64/python2.6/optparse.py line 1414-1463 | |
23 while rargs: | |
24 arg = rargs[0] | |
25 # We handle bare "--" explicitly, and bare "-" is handled by the | |
26 # standard arg handler since the short arg case ensures that the | |
27 # len of the opt string is greater than 1. | |
28 if arg == "--": | |
29 del rargs[0] | |
30 return | |
31 elif arg[0:2] == "--": | |
32 # process a single long option (possibly with value(s)) | |
33 try: | |
34 self._process_long_opt(rargs, values) | |
35 except optparse.BadOptionError: | |
36 largs.append(arg) | |
37 elif arg[:1] == "-" and len(arg) > 1: | |
38 # process a cluster of short options (possibly with | |
39 # value(s) for the last one only) | |
40 try: | |
41 self._process_short_opts(rargs, values) | |
42 except optparse.BadOptionError: | |
43 largs.append(arg) | |
44 elif self.allow_interspersed_args: | |
45 largs.append(arg) | |
46 del rargs[0] | |
47 else: | |
48 return # stop now, leave this arg in rargs | |
49 | |
50 def print_help(self, file=None): | |
51 optparse.OptionParser.print_help(self, file) | |
52 MyOptionParser.help = True | |
53 | |
54 | |
55 parser = MyOptionParser() | |
56 parser.allow_interspersed_args = True | |
57 | |
58 DEFAULT_BOARD = os.environ.get('DEFAULT_BOARD', '') | |
59 | |
60 parser.add_option('--args', dest='args', action='store', | |
61 default='', | |
62 help='The arguments to pass to the test control file.') | |
63 parser.add_option('--autox', dest='autox', action='store_true', | |
64 default=True, | |
65 help='Build autox along with autotest [default].') | |
66 parser.add_option('--noautox', dest='autox', action='store_false', | |
67 help='Don\'t build autox along with autotest.') | |
68 parser.add_option('--board', dest='board', action='store', | |
69 default=DEFAULT_BOARD, | |
70 help='The board for which you are building autotest.') | |
71 parser.add_option('--build', dest='build', action='store', | |
72 help='Only prebuild client tests, do not run tests.') | |
73 parser.add_option('--buildcheck', dest='buildcheck', action='store_true', | |
74 default=True, | |
75 help='Fail if tests fail to build [default].') | |
76 parser.add_option('--nobuildcheck', dest='buildcheck', action='store_false', | |
77 help='Ignore test build failures.') | |
78 parser.add_option('--jobs', dest='jobs', action='store', type=int, | |
79 default=-1, | |
80 help='How many packages to build in parallel at maximum.') | |
81 parser.add_option('--noprompt', dest='noprompt', action='store_true', | |
82 help='Prompt user when building all tests.') | |
83 | |
84 | |
85 AUTOSERV='../third_party/autotest/files/server/autoserv' | |
86 AUTOTEST_CLIENT='../third_party/autotest/files/client/bin/autotest_client' | |
87 | |
88 def parse_args_and_help(): | |
89 | |
90 def nop(_): | |
91 pass | |
92 | |
93 sys_exit = sys.exit | |
94 sys.exit = nop | |
95 options, args = parser.parse_args() | |
96 sys.exit = sys_exit | |
97 | |
98 if not args and not options.build: | |
99 parser.print_help() | |
100 | |
101 if MyOptionParser.help: | |
102 if options.build: | |
103 print | |
104 print 'Options inherited from autotest_client, which is used in build', | |
105 print 'only mode.' | |
106 run([AUTOTEST_CLIENT, '--help']) | |
107 else: | |
108 print | |
109 print 'Options inherited from autoserv:' | |
110 run([AUTOSERV, '--help']) | |
111 sys.exit(0) | |
112 return options, args | |
113 | |
114 | |
115 def assert_inside_chroot(common_sh): | |
116 status, output = commands.getstatusoutput('/bin/bash -c ". %s && ' | |
117 'assert_inside_chroot"' % common_sh) | |
118 if status is not 0: | |
119 print >> sys.stderr, output | |
120 sys.exit(status) | |
121 | |
122 | |
123 def set_common_env(common_sh, env_var): | |
124 env_value = commands.getoutput('/bin/bash -c \'. %s && echo $%s\'' % | |
125 (common_sh, env_var)) | |
126 os.environ[env_var] = env_value | |
127 | |
128 | |
129 def die(common_sh, msg): | |
130 output = commands.getoutput('/bin/bash -c \'. %s && die "%s"\'' % | |
131 (common_sh, msg)) | |
132 print >> sys.stderr, output | |
133 sys.exit(1) | |
134 | |
135 | |
136 def build_autotest(options): | |
137 environ = os.environ | |
138 if options.jobs != -1: | |
139 emerge_jobs = '--jobs=%d' % options.jobs | |
140 else: | |
141 emerge_jobs = '' | |
142 | |
143 # Decide on USE flags based on options | |
144 use_flag = environ.get('USE', '') | |
145 if not options.autox: | |
146 use_flag = use_flag + ' -autox' | |
147 if options.buildcheck: | |
148 use_flag = use_flag + ' buildcheck' | |
149 | |
150 board_blacklist_file = ('%s/src/overlays/overlay-%s/autotest-blacklist' % | |
151 (os.environ['GCLIENT_ROOT'], options.board)) | |
152 if os.path.exists(board_blacklist_file): | |
153 blacklist = [line.strip() | |
154 for line in open(board_blacklist_file).readlines()] | |
155 else: | |
156 blacklist = [] | |
157 | |
158 all_tests = ('compilebench,dbench,disktest,fsx,hackbench,iperf,ltp,netperf2,' | |
159 'netpipe,unixbench') | |
160 site_tests = '../third_party/autotest/files/client/site_tests' | |
161 for site_test in os.listdir(site_tests): | |
162 test_path = os.path.join(site_tests, site_test) | |
163 test_py = os.path.join(test_path, '%s.py' % site_test) | |
164 if (os.path.exists(test_path) and os.path.isdir(test_path) and | |
165 os.path.exists(test_py) and os.path.isfile(test_py) and | |
166 site_test not in blacklist): | |
167 all_tests += ',' + site_test | |
168 | |
169 if 'all' == options.build.lower(): | |
170 if options.noprompt is not True: | |
171 print 'You want to pre-build all client tests and it may take a long', | |
172 print 'time to finish.' | |
173 print 'Are you sure you want to continue?(N/y)', | |
174 answer = sys.stdin.readline() | |
175 if 'y' != answer[0].lower(): | |
176 print 'Use --build to specify tests you like to pre-compile. ' | |
177 print 'E.g.: ./autotest --build=disktest,hardware_SAT' | |
178 sys.exit(0) | |
179 test_list = all_tests | |
180 else: | |
181 test_list = options.build | |
182 | |
183 environ['FEATURES'] = ('%s -buildpkg -collision-protect' % | |
184 environ.get('FEATURES', '')) | |
185 environ['TEST_LIST'] = test_list | |
186 environ['USE'] = use_flag | |
187 emerge_cmd = ['emerge-%s' % options.board, | |
188 'chromeos-base/autotest'] | |
189 if emerge_jobs: | |
190 emerge_cmd.append(emerge_jobs) | |
191 return run(emerge_cmd) | |
192 | |
193 | |
194 def run_autoserv(options, args): | |
195 environ = os.environ | |
196 | |
197 environ['AUTOSERV_TEST_ARGS'] = options.args | |
198 environ['AUTOSERV_ARGS'] = ' '.join(args) | |
199 environ['FEATURES'] = ('%s -buildpkg -digest noauto' % | |
200 environ.get('FEATURES', '')) | |
201 ebuild_cmd = [ './autotest_run.sh', '--board=%s' % options.board] | |
202 run(ebuild_cmd) | |
203 | |
204 | |
205 def main(): | |
206 me = sys.argv[0] | |
207 common_sh = os.path.join(os.path.dirname(me), 'common.sh') | |
208 | |
209 assert_inside_chroot(common_sh) | |
210 set_common_env(common_sh, 'GCLIENT_ROOT') | |
211 | |
212 options, args = parse_args_and_help() | |
213 | |
214 if not options.board: | |
215 die(common_sh, 'Missing --board argument.') | |
216 | |
217 if options.build: | |
218 status = build_autotest(options) | |
219 if status: | |
220 die(common_sh, 'build_autotest failed.') | |
221 else: | |
222 ssh_key_file = os.path.join(os.path.dirname(me), | |
223 'mod_for_test_scripts/ssh_keys/testing_rsa') | |
224 os.chmod(ssh_key_file, 0400) | |
225 run_autoserv(options, args) | |
226 | |
227 | |
228 if __name__ == '__main__': | |
229 main() | |
OLD | NEW |