#!/usr/bin/python
#
# Copyright (c) 2012 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.

"""Tool for enumerating the tests in a given suite.

Given an autotest root directory and a suite name (e.g., bvt, regression), this
tool will print out the name of each test in that suite, one per line.

Example:
$ ./site_utils/suite_enumerator.py -a /usr/local/autotest bvt 2>/dev/null
login_LoginSuccess
logging_CrashSender
login_BadAuthentication

This is intended for use only with Chrome OS test suits that leverage the
dynamic suite infrastructure in server/cros/dynamic_suite.py.
"""

import logging
import optparse, os, sys

# Silence messages relating to imports of missing, unneeded
# modules.
logging.basicConfig(level=logging.INFO)

import common
import autotest_lib.client.common_lib.cros as cros_lib
import autotest_lib.server.cros.dynamic_suite.suite as suite_lib


def parse_options():
    """Parse command line for arguments including autotest directory, suite
    name, if to list stable tests only, and if to list all available suites.
    """
    usage = "usage: %prog [options] suite_name"
    parser = optparse.OptionParser(usage=usage)
    parser.add_option('-a', '--autotest_dir', dest='autotest_dir',
                      default=os.path.abspath(
                          os.path.join(os.path.dirname(__file__),
                                       os.pardir)),
                      help='Directory under which to search for tests.'\
                           ' (e.g. /usr/local/autotest)')
    parser.add_option('-l', '--listall',
                      action='store_true', default=False,
                      help='Print a listing of all suites. Ignores all args.')
    options, args = parser.parse_args()
    return parser, options, args


def main():
    """Entry point to run the suite enumerator command."""
    parser, options, args = parse_options()
    if options.listall:
        if args:
            print 'Cannot use suite_name with --listall'
            parser.print_help()
    elif not args or len(args) != 1:
        parser.print_help()
        return

    fs_getter = suite_lib.create_fs_getter(options.autotest_dir)
    devserver = cros_lib.dev_server.ImageServer('')
    if options.listall:
        for suite in suite_lib.list_all_suites('', devserver, fs_getter):
            print suite
        return

    suite = suite_lib.Suite.create_from_name(args[0], {}, '', devserver,
                                             fs_getter)
    # If in test list, print firmware_FAFTSetup before other tests
    # NOTE: the test.name value can be *different* from the directory
    # name that appears in test.path
    PRETEST_LIST = ['firmware_FAFTSetup',]
    for test in filter(lambda test: test.name in \
                              PRETEST_LIST, suite.tests):
        print test.path
    for test in filter(lambda test: test.name not in \
                       PRETEST_LIST, suite.tests):
        print test.path

    # Check if test_suites/control.suite_name exists.
    control_path = os.path.join(options.autotest_dir, 'test_suites',
                                'control.' + args[0])
    if not os.path.exists(control_path):
        print >> sys.stderr, ('Warning! control file is missing: %s' %
                              control_path)


if __name__ == "__main__":
    sys.exit(main())
