Home | History | Annotate | Download | only in site_utils
      1 #!/usr/bin/python
      2 #
      3 # Copyright (c) 20123 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 """Tool for preprocessing control files to build a suite to control files map.
      8 
      9 Given an autotest root directory, this tool will bucket tests accroding to
     10 their suite.Data will be written to stdout (or, optionally a file), eg:
     11 
     12 {'suite1': ['path/to/test1/control', 'path/to/test2/control'],
     13  'suite2': ['path/to/test4/control', 'path/to/test5/control']}
     14 
     15 This is intended for use only with Chrome OS test suites that leverage the
     16 dynamic suite infrastructure in server/cros/dynamic_suite.py. It is invoked
     17 at build time to generate said suite to control files map, which dynamic_suite
     18 consults at run time to determine which tests belong to a suite.
     19 """
     20 
     21 
     22 import collections, json, os, sys
     23 
     24 import common
     25 from autotest_lib.server.cros.dynamic_suite import suite
     26 from autotest_lib.site_utils import suite_preprocessor
     27 
     28 
     29 # A set of SUITES that we choose not to preprocess as they might have tests
     30 # added later.
     31 SUITE_BLACKLIST = set(['au'])
     32 
     33 
     34 def _get_control_files_to_process(autotest_dir):
     35     """Find all control files in autotest_dir that have 'SUITE='
     36 
     37     @param autotest_dir: The directory to search for control files.
     38     @return: All control files in autotest_dir that have a suite attribute.
     39     """
     40     fs_getter = suite.Suite.create_fs_getter(autotest_dir)
     41     predicate = lambda t: hasattr(t, 'suite')
     42     return suite.Suite.find_and_parse_tests(fs_getter, predicate,
     43                                             add_experimental=True)
     44 
     45 
     46 def get_suite_control_files(autotest_dir, external_autotest_dirs=None):
     47     """
     48     Partition all control files in autotest_dir based on suite.
     49 
     50     @param autotest_dir: Directory to walk looking for control files.
     51     @param external_autotest_dirs: A list of directories under which to search
     52             for extra Autotest tests. Defaults to None.
     53 
     54     @return suite_control_files: A dictionary mapping suite->[control files]
     55                                  as described in this files docstring.
     56     @raise ValueError: If autotest_dir doesn't exist.
     57     """
     58     if not os.path.exists(autotest_dir):
     59         raise ValueError('Could not find directory: %s, failed to map suites to'
     60                        ' their control files.' % autotest_dir)
     61 
     62     suite_control_files = collections.defaultdict(list)
     63     for d in [autotest_dir] + (external_autotest_dirs or []):
     64         d = d.rstrip('/')
     65         for test in _get_control_files_to_process(d):
     66             for suite_name in test.suite_tag_parts:
     67                 if suite_name in SUITE_BLACKLIST:
     68                     continue
     69 
     70                 suite_control_files[suite_name].append(
     71                     test.path.replace('%s/' % d, ''))
     72     return suite_control_files
     73 
     74 
     75 def main():
     76     """
     77     Main function.
     78     """
     79     options = suite_preprocessor.parse_options()
     80 
     81     if options.extra_autotest_dirs:
     82         extra_autotest_dirs = options.extra_autotest_dirs.split(',')
     83     else:
     84         extra_autotest_dirs = None
     85 
     86     suite_control_files = get_suite_control_files(options.autotest_dir,
     87                                                   extra_autotest_dirs)
     88     if options.output_file:
     89         with open(options.output_file, 'w') as file_obj:
     90             json.dump(suite_control_files, file_obj)
     91     else:
     92         print suite_control_files
     93 
     94 
     95 if __name__ == '__main__':
     96     sys.exit(main())
     97