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 |