Index: tools/telemetry/telemetry/core/discover.py |
diff --git a/tools/telemetry/telemetry/core/discover.py b/tools/telemetry/telemetry/core/discover.py |
index 9e8118a731fd59e29f834043096b5438750eb694..9ef13cf8bd366e904ac37cce3a374dc558643b01 100644 |
--- a/tools/telemetry/telemetry/core/discover.py |
+++ b/tools/telemetry/telemetry/core/discover.py |
@@ -6,11 +6,16 @@ import fnmatch |
import inspect |
import os |
import re |
+import sys |
from telemetry import decorators |
from telemetry.core import camel_case |
+from telemetry.core import environment |
from telemetry.core import util |
from telemetry.page import page_set |
+from telemetry.page import profile_creator |
+ |
+config = environment.Environment([util.GetBaseDir()]) |
nednguyen
2014/09/04 03:31:37
Why do we need a global?
|
@decorators.Cache |
@@ -133,3 +138,67 @@ def IsPageSetFile(file_path): |
return False |
module = util.GetPythonPageSetModule(file_path) |
return bool(DiscoverClassesInModule(module, page_set.PageSet)) |
+ |
+ |
+@decorators.Cache |
+def GetValidSubclassesOfClasses(base_classes, base_dir=None): |
nednguyen
2014/09/04 03:31:37
Please add docstring for this function and the one
|
+ classes = [] |
+ for base_class in base_classes: |
+ paths = config.base_paths if base_dir is None else [base_dir] |
+ for base_dir in paths: |
+ classes += DiscoverClasses(base_dir, base_dir, base_class, |
+ index_by_class_name=True).values() |
+ return [cls for cls in classes |
+ if not issubclass(cls, profile_creator.ProfileCreator)] |
+ |
+ |
+def MatchName(base_classes, input_name, exact_matches=True, base_dir=None): |
+ def _Matches(input_string, search_string): |
+ if search_string.startswith(input_string): |
+ return True |
+ for part in search_string.split('.'): |
+ if part.startswith(input_string): |
+ return True |
+ return False |
+ |
+ # Exact matching. |
+ if exact_matches: |
+ # Don't add aliases to search dict, only allow exact matching for them. |
+ if input_name in config.test_aliases: |
+ exact_match = config.test_aliases[input_name] |
+ else: |
+ exact_match = input_name |
+ |
+ for test_class in GetValidSubclassesOfClasses(base_classes, base_dir): |
+ if exact_match == test_class.Name(): |
+ return [test_class] |
+ |
+ # Fuzzy matching. |
+ return [test_class for test_class in GetValidSubclassesOfClasses(base_classes, |
+ base_dir) |
+ if _Matches(input_name, test_class.Name())] |
+ |
+ |
+def PrintAvailableClasses(base_classes, class_list=None, |
+ output_stream=sys.stdout): |
nednguyen
2014/09/04 03:31:37
Can we split this function to two functions: one t
|
+ if class_list is None: |
+ class_list = GetValidSubclassesOfClasses(base_classes) |
+ |
+ if not class_list: |
+ sys.stderr.write('No tests found!\n') |
+ return |
+ |
+ # Align the class names to the longest one. |
+ format_string = ' %%-%ds %%s' % max(len(cls.Name()) for cls in class_list) |
+ |
+ output = [] |
+ for base_class in base_classes: |
+ classes = [cls for cls in class_list if issubclass(cls, base_class)] |
+ if classes: |
+ output.append('Available %ss are:' % base_class.Name()) |
+ sorted_classes = sorted(classes, key=lambda c: c.Name()) |
+ formatted_classes = map( |
+ lambda c: format_string % (c.Name(), c.Description()), sorted_classes) |
+ output.extend(formatted_classes) |
+ output.append('') |
+ output_stream.write('\n'.join(output)) |