#!/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()
