| #!/usr/bin/python |
| |
| # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| # |
| # A python wrapper to call autotest ebuild. |
| |
| import commands, logging, optparse, os, subprocess, sys |
| |
| |
| def run(cmd): |
| return subprocess.call(cmd, stdout=sys.stdout, stderr=sys.stderr) |
| |
| |
| class MyOptionParser(optparse.OptionParser): |
| """Override python's builtin OptionParser to accept any undefined args.""" |
| |
| help = False |
| |
| def _process_args(self, largs, rargs, values): |
| # see /usr/lib64/python2.6/optparse.py line 1414-1463 |
| while rargs: |
| arg = rargs[0] |
| # We handle bare "--" explicitly, and bare "-" is handled by the |
| # standard arg handler since the short arg case ensures that the |
| # len of the opt string is greater than 1. |
| if arg == "--": |
| del rargs[0] |
| return |
| elif arg[0:2] == "--": |
| # process a single long option (possibly with value(s)) |
| try: |
| self._process_long_opt(rargs, values) |
| except optparse.BadOptionError: |
| largs.append(arg) |
| elif arg[:1] == "-" and len(arg) > 1: |
| # process a cluster of short options (possibly with |
| # value(s) for the last one only) |
| try: |
| self._process_short_opts(rargs, values) |
| except optparse.BadOptionError: |
| largs.append(arg) |
| elif self.allow_interspersed_args: |
| largs.append(arg) |
| del rargs[0] |
| else: |
| return # stop now, leave this arg in rargs |
| |
| def print_help(self, file=None): |
| optparse.OptionParser.print_help(self, file) |
| MyOptionParser.help = True |
| |
| |
| parser = MyOptionParser() |
| parser.allow_interspersed_args = True |
| |
| DEFAULT_BOARD = os.environ.get('DEFAULT_BOARD', '') |
| |
| parser.add_option('--args', dest='args', action='store', |
| default='', |
| help='The arguments to pass to the test control file.') |
| parser.add_option('--autox', dest='autox', action='store_true', |
| default=True, |
| help='Build autox along with autotest [default].') |
| parser.add_option('--noautox', dest='autox', action='store_false', |
| help='Don\'t build autox along with autotest.') |
| parser.add_option('--board', dest='board', action='store', |
| default=DEFAULT_BOARD, |
| help='The board for which you are building autotest.') |
| parser.add_option('--build', dest='build', action='store', |
| help='Only prebuild client tests, do not run tests.') |
| parser.add_option('--buildcheck', dest='buildcheck', action='store_true', |
| default=True, |
| help='Fail if tests fail to build [default].') |
| parser.add_option('--nobuildcheck', dest='buildcheck', action='store_false', |
| help='Ignore test build failures.') |
| parser.add_option('--jobs', dest='jobs', action='store', type=int, |
| default=-1, |
| help='How many packages to build in parallel at maximum.') |
| parser.add_option('--noprompt', dest='noprompt', action='store_true', |
| help='Prompt user when building all tests.') |
| |
| |
| AUTOSERV='../third_party/autotest/files/server/autoserv' |
| AUTOTEST_CLIENT='../third_party/autotest/files/client/bin/autotest_client' |
| |
| def parse_args_and_help(): |
| |
| def nop(_): |
| pass |
| |
| sys_exit = sys.exit |
| sys.exit = nop |
| options, args = parser.parse_args() |
| sys.exit = sys_exit |
| |
| if not args and not options.build: |
| parser.print_help() |
| |
| if MyOptionParser.help: |
| if options.build: |
| print |
| print 'Options inherited from autotest_client, which is used in build', |
| print 'only mode.' |
| run([AUTOTEST_CLIENT, '--help']) |
| else: |
| print |
| print 'Options inherited from autoserv:' |
| run([AUTOSERV, '--help']) |
| sys.exit(0) |
| return options, args |
| |
| |
| def assert_inside_chroot(common_sh): |
| status, output = commands.getstatusoutput('/bin/bash -c ". %s && ' |
| 'assert_inside_chroot"' % common_sh) |
| if status is not 0: |
| print >> sys.stderr, output |
| sys.exit(status) |
| |
| |
| def set_common_env(common_sh, env_var): |
| env_value = commands.getoutput('/bin/bash -c \'. %s && echo $%s\'' % |
| (common_sh, env_var)) |
| os.environ[env_var] = env_value |
| |
| |
| def die(common_sh, msg): |
| output = commands.getoutput('/bin/bash -c \'. %s && die "%s"\'' % |
| (common_sh, msg)) |
| print >> sys.stderr, output |
| sys.exit(1) |
| |
| |
| def build_autotest(options): |
| environ = os.environ |
| if options.jobs != -1: |
| emerge_jobs = '--jobs=%d' % options.jobs |
| else: |
| emerge_jobs = '' |
| |
| # Decide on USE flags based on options |
| use_flag = environ.get('USE', '') |
| if not options.autox: |
| use_flag = use_flag + ' -autox' |
| if options.buildcheck: |
| use_flag = use_flag + ' buildcheck' |
| |
| board_blacklist_file = ('%s/src/overlays/overlay-%s/autotest-blacklist' % |
| (os.environ['GCLIENT_ROOT'], options.board)) |
| if os.path.exists(board_blacklist_file): |
| blacklist = [line.strip() |
| for line in open(board_blacklist_file).readlines()] |
| else: |
| blacklist = [] |
| |
| all_tests = ('compilebench,dbench,disktest,fsx,hackbench,iperf,ltp,netperf2,' |
| 'netpipe,unixbench') |
| site_tests = '../third_party/autotest/files/client/site_tests' |
| for site_test in os.listdir(site_tests): |
| test_path = os.path.join(site_tests, site_test) |
| test_py = os.path.join(test_path, '%s.py' % site_test) |
| if (os.path.exists(test_path) and os.path.isdir(test_path) and |
| os.path.exists(test_py) and os.path.isfile(test_py) and |
| site_test not in blacklist): |
| all_tests += ',' + site_test |
| |
| if 'all' == options.build.lower(): |
| if options.noprompt is not True: |
| print 'You want to pre-build all client tests and it may take a long', |
| print 'time to finish.' |
| print 'Are you sure you want to continue?(N/y)', |
| answer = sys.stdin.readline() |
| if 'y' != answer[0].lower(): |
| print 'Use --build to specify tests you like to pre-compile. ' |
| print 'E.g.: ./autotest --build=disktest,hardware_SAT' |
| sys.exit(0) |
| test_list = all_tests |
| else: |
| test_list = options.build |
| |
| environ['FEATURES'] = ('%s -buildpkg -collision-protect' % |
| environ.get('FEATURES', '')) |
| environ['TEST_LIST'] = test_list |
| environ['USE'] = use_flag |
| emerge_cmd = ['emerge-%s' % options.board, |
| 'chromeos-base/autotest'] |
| if emerge_jobs: |
| emerge_cmd.append(emerge_jobs) |
| return run(emerge_cmd) |
| |
| |
| def run_autoserv(options, args): |
| environ = os.environ |
| |
| environ['AUTOSERV_TEST_ARGS'] = options.args |
| environ['AUTOSERV_ARGS'] = ' '.join(args) |
| environ['FEATURES'] = ('%s -buildpkg -digest noauto' % |
| environ.get('FEATURES', '')) |
| ebuild_cmd = [ './autotest_run.sh', '--board=%s' % options.board] |
| run(ebuild_cmd) |
| |
| |
| def main(): |
| me = sys.argv[0] |
| common_sh = os.path.join(os.path.dirname(me), 'common.sh') |
| |
| assert_inside_chroot(common_sh) |
| set_common_env(common_sh, 'GCLIENT_ROOT') |
| |
| options, args = parse_args_and_help() |
| |
| if not options.board: |
| die(common_sh, 'Missing --board argument.') |
| |
| if options.build: |
| status = build_autotest(options) |
| if status: |
| die(common_sh, 'build_autotest failed.') |
| else: |
| ssh_key_file = os.path.join(os.path.dirname(me), |
| 'mod_for_test_scripts/ssh_keys/testing_rsa') |
| os.chmod(ssh_key_file, 0400) |
| run_autoserv(options, args) |
| |
| |
| if __name__ == '__main__': |
| main() |