Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright 2012 The Chromium Authors. All rights reserved. | 1 # Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import fnmatch | 5 import fnmatch |
| 6 import inspect | 6 import inspect |
| 7 import os | 7 import os |
| 8 import re | 8 import re |
| 9 import sys | |
| 9 | 10 |
| 10 from telemetry import decorators | 11 from telemetry import decorators |
| 11 from telemetry.core import camel_case | 12 from telemetry.core import camel_case |
| 13 from telemetry.core import environment | |
| 12 from telemetry.core import util | 14 from telemetry.core import util |
| 13 from telemetry.page import page_set | 15 from telemetry.page import page_set |
| 16 from telemetry.page import profile_creator | |
| 17 | |
| 18 config = environment.Environment([util.GetBaseDir()]) | |
|
nednguyen
2014/09/04 03:31:37
Why do we need a global?
| |
| 14 | 19 |
| 15 | 20 |
| 16 @decorators.Cache | 21 @decorators.Cache |
| 17 def DiscoverModules(start_dir, top_level_dir, pattern='*'): | 22 def DiscoverModules(start_dir, top_level_dir, pattern='*'): |
| 18 """Discover all modules in |start_dir| which match |pattern|. | 23 """Discover all modules in |start_dir| which match |pattern|. |
| 19 | 24 |
| 20 Args: | 25 Args: |
| 21 start_dir: The directory to recursively search. | 26 start_dir: The directory to recursively search. |
| 22 top_level_dir: The top level of the package, for importing. | 27 top_level_dir: The top level of the package, for importing. |
| 23 pattern: Unix shell-style pattern for filtering the filenames to import. | 28 pattern: Unix shell-style pattern for filtering the filenames to import. |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 126 | 131 |
| 127 | 132 |
| 128 def IsPageSetFile(file_path): | 133 def IsPageSetFile(file_path): |
| 129 root_name, ext_name = os.path.splitext(file_path) | 134 root_name, ext_name = os.path.splitext(file_path) |
| 130 if 'unittest' in root_name or 'page_sets/data' in root_name: | 135 if 'unittest' in root_name or 'page_sets/data' in root_name: |
| 131 return False | 136 return False |
| 132 if ext_name != '.py': | 137 if ext_name != '.py': |
| 133 return False | 138 return False |
| 134 module = util.GetPythonPageSetModule(file_path) | 139 module = util.GetPythonPageSetModule(file_path) |
| 135 return bool(DiscoverClassesInModule(module, page_set.PageSet)) | 140 return bool(DiscoverClassesInModule(module, page_set.PageSet)) |
| 141 | |
| 142 | |
| 143 @decorators.Cache | |
| 144 def GetValidSubclassesOfClasses(base_classes, base_dir=None): | |
|
nednguyen
2014/09/04 03:31:37
Please add docstring for this function and the one
| |
| 145 classes = [] | |
| 146 for base_class in base_classes: | |
| 147 paths = config.base_paths if base_dir is None else [base_dir] | |
| 148 for base_dir in paths: | |
| 149 classes += DiscoverClasses(base_dir, base_dir, base_class, | |
| 150 index_by_class_name=True).values() | |
| 151 return [cls for cls in classes | |
| 152 if not issubclass(cls, profile_creator.ProfileCreator)] | |
| 153 | |
| 154 | |
| 155 def MatchName(base_classes, input_name, exact_matches=True, base_dir=None): | |
| 156 def _Matches(input_string, search_string): | |
| 157 if search_string.startswith(input_string): | |
| 158 return True | |
| 159 for part in search_string.split('.'): | |
| 160 if part.startswith(input_string): | |
| 161 return True | |
| 162 return False | |
| 163 | |
| 164 # Exact matching. | |
| 165 if exact_matches: | |
| 166 # Don't add aliases to search dict, only allow exact matching for them. | |
| 167 if input_name in config.test_aliases: | |
| 168 exact_match = config.test_aliases[input_name] | |
| 169 else: | |
| 170 exact_match = input_name | |
| 171 | |
| 172 for test_class in GetValidSubclassesOfClasses(base_classes, base_dir): | |
| 173 if exact_match == test_class.Name(): | |
| 174 return [test_class] | |
| 175 | |
| 176 # Fuzzy matching. | |
| 177 return [test_class for test_class in GetValidSubclassesOfClasses(base_classes, | |
| 178 base_dir) | |
| 179 if _Matches(input_name, test_class.Name())] | |
| 180 | |
| 181 | |
| 182 def PrintAvailableClasses(base_classes, class_list=None, | |
| 183 output_stream=sys.stdout): | |
|
nednguyen
2014/09/04 03:31:37
Can we split this function to two functions: one t
| |
| 184 if class_list is None: | |
| 185 class_list = GetValidSubclassesOfClasses(base_classes) | |
| 186 | |
| 187 if not class_list: | |
| 188 sys.stderr.write('No tests found!\n') | |
| 189 return | |
| 190 | |
| 191 # Align the class names to the longest one. | |
| 192 format_string = ' %%-%ds %%s' % max(len(cls.Name()) for cls in class_list) | |
| 193 | |
| 194 output = [] | |
| 195 for base_class in base_classes: | |
| 196 classes = [cls for cls in class_list if issubclass(cls, base_class)] | |
| 197 if classes: | |
| 198 output.append('Available %ss are:' % base_class.Name()) | |
| 199 sorted_classes = sorted(classes, key=lambda c: c.Name()) | |
| 200 formatted_classes = map( | |
| 201 lambda c: format_string % (c.Name(), c.Description()), sorted_classes) | |
| 202 output.extend(formatted_classes) | |
| 203 output.append('') | |
| 204 output_stream.write('\n'.join(output)) | |
| OLD | NEW |