beeps | 5cb8f91 | 2013-07-09 21:45:45 -0700 | [diff] [blame] | 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 | |
Chris Sosa | 0ea1502 | 2014-04-17 15:43:20 -0700 | [diff] [blame] | 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 | |
Alex Miller | 9a1987a | 2013-08-21 15:51:16 -0700 | [diff] [blame] | 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 | |
Dan Shi | 7b271d0 | 2016-04-25 23:09:58 -0700 | [diff] [blame] | 46 | def get_suite_control_files(autotest_dir, external_autotest_dirs=None): |
beeps | 5cb8f91 | 2013-07-09 21:45:45 -0700 | [diff] [blame] | 47 | """ |
| 48 | Partition all control files in autotest_dir based on suite. |
| 49 | |
| 50 | @param autotest_dir: Directory to walk looking for control files. |
Dan Shi | 7b271d0 | 2016-04-25 23:09:58 -0700 | [diff] [blame] | 51 | @param external_autotest_dirs: A list of directories under which to search |
| 52 | for extra Autotest tests. Defaults to None. |
| 53 | |
beeps | 5cb8f91 | 2013-07-09 21:45:45 -0700 | [diff] [blame] | 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): |
Dan Shi | 7b271d0 | 2016-04-25 23:09:58 -0700 | [diff] [blame] | 59 | raise ValueError('Could not find directory: %s, failed to map suites to' |
beeps | 5cb8f91 | 2013-07-09 21:45:45 -0700 | [diff] [blame] | 60 | ' their control files.' % autotest_dir) |
| 61 | |
beeps | 5cb8f91 | 2013-07-09 21:45:45 -0700 | [diff] [blame] | 62 | suite_control_files = collections.defaultdict(list) |
Dan Shi | 7b271d0 | 2016-04-25 23:09:58 -0700 | [diff] [blame] | 63 | for d in [autotest_dir] + (external_autotest_dirs or []): |
| 64 | d = d.rstrip('/') |
| 65 | for test in _get_control_files_to_process(d): |
Allen Li | f20e17d | 2017-01-03 18:24:19 -0800 | [diff] [blame] | 66 | for suite_name in test.suite_tag_parts: |
Dan Shi | 7b271d0 | 2016-04-25 23:09:58 -0700 | [diff] [blame] | 67 | if suite_name in SUITE_BLACKLIST: |
| 68 | continue |
beeps | 5cb8f91 | 2013-07-09 21:45:45 -0700 | [diff] [blame] | 69 | |
Dan Shi | 7b271d0 | 2016-04-25 23:09:58 -0700 | [diff] [blame] | 70 | suite_control_files[suite_name].append( |
| 71 | test.path.replace('%s/' % d, '')) |
beeps | 5cb8f91 | 2013-07-09 21:45:45 -0700 | [diff] [blame] | 72 | return suite_control_files |
| 73 | |
| 74 | |
| 75 | def main(): |
| 76 | """ |
| 77 | Main function. |
| 78 | """ |
| 79 | options = suite_preprocessor.parse_options() |
| 80 | |
Dan Shi | 7b271d0 | 2016-04-25 23:09:58 -0700 | [diff] [blame] | 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) |
beeps | 5cb8f91 | 2013-07-09 21:45:45 -0700 | [diff] [blame] | 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()) |