From fd9cce5babbe6f4341793c2cd21753a9fe773244 Mon Sep 17 00:00:00 2001 From: aiolos Date: Mon, 3 Aug 2015 14:41:10 -0700 Subject: [PATCH] Revert of Create classes_util API, change discover to return a list instead of a dict. (patchset #1 id:1 of https://codereview.chromium.org/1262623007/) Reason for revert: Landed even though the patch failed. Original issue's description: > Reland of Create classes_util API, change discover to return a list instead of a dict. (patchset #1 id:1 of https://codereview.chromium.org/1263063003/) > > Reason for revert: > The telemetry tests aren't broken. The perf_unittests are because they don't pick tests in a deterministic way. Reverting after a change to make them deterministic. > > Original issue's description: > > Revert of Create classes_util API, change discover to return a list instead of a dict. (patchset #5 id:120001 of https://codereview.chromium.org/1244223002/) > > > > Reason for revert: > > This appears to break the XP telemetry tests. Details on the bug. > > > > Original issue's description: > > > Create classes_util API, change discover to return a list instead of a dict. > > > > > > BUG=498968 > > > CQ_EXTRA_TRYBOTS=tryserver.chromium.perf:linux_perf_bisect;tryserver.chromium.perf:mac_perf_bisect;tryserver.chromium.perf:win_perf_bisect;tryserver.chromium.perf:android_nexus5_perf_bisect > > > > > > Committed: https://crrev.com/e6cbec4747aa7fe3c96b1cdb89de21ae77b30ab0 > > > Cr-Commit-Position: refs/heads/master@{#341129} > > > > TBR=dtu@chromium.org,bengr@chromium.org,aiolos@chromium.org > > NOPRESUBMIT=true > > NOTREECHECKS=true > > NOTRY=true > > BUG=498968 > > > > Committed: https://crrev.com/c85e3e1af7e170d5f8ec2b012df6e9337d2352bb > > Cr-Commit-Position: refs/heads/master@{#341218} > > TBR=dtu@chromium.org,bengr@chromium.org,avi@chromium.org > BUG=498968 > > Committed: https://crrev.com/2c1531af216c026be0b4aed672dc89d264f95a72 > Cr-Commit-Position: refs/heads/master@{#341603} TBR=dtu@chromium.org,bengr@chromium.org,avi@chromium.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=498968 Review URL: https://codereview.chromium.org/1272433002 Cr-Commit-Position: refs/heads/master@{#341621} --- .../test/gpu/gpu_tests/gpu_test_base_unittest.py | 14 +- content/test/gpu/page_sets/__init__.py | 5 +- .../chrome_proxy_pagesets/__init__.py | 6 +- tools/chrome_proxy/live_tests/pagesets/__init__.py | 5 +- tools/perf/benchmarks/benchmark_smoke_unittest.py | 6 +- tools/perf/benchmarks/benchmark_unittest.py | 7 +- tools/perf/benchmarks/skpicture_printer.py | 6 +- tools/perf/measurements/measurement_smoke_test.py | 10 +- tools/perf/page_sets/__init__.py | 6 +- tools/perf/profile_creators/profile_generator.py | 4 +- tools/telemetry/telemetry/benchmark_runner.py | 7 +- tools/telemetry/telemetry/core/discover.py | 44 +++-- .../telemetry/telemetry/core/discover_unittest.py | 198 +++++++++++---------- tools/telemetry/telemetry/core/platform.py | 6 +- .../internal/platform/profiler/profiler_finder.py | 7 +- .../platform/tracing_controller_backend.py | 7 +- .../telemetry/internal/util/find_dependencies.py | 8 +- tools/telemetry/telemetry/record_wpr.py | 8 +- .../telemetry/testing/story_set_smoke_test.py | 8 +- tools/telemetry/telemetry/util/classes_util.py | 27 --- tools/telemetry/telemetry/value/__init__.py | 8 +- 21 files changed, 202 insertions(+), 195 deletions(-) rewrite tools/telemetry/telemetry/core/discover_unittest.py (68%) delete mode 100644 tools/telemetry/telemetry/util/classes_util.py diff --git a/content/test/gpu/gpu_tests/gpu_test_base_unittest.py b/content/test/gpu/gpu_tests/gpu_test_base_unittest.py index f1ddf36065f6..969202527980 100644 --- a/content/test/gpu/gpu_tests/gpu_test_base_unittest.py +++ b/content/test/gpu/gpu_tests/gpu_test_base_unittest.py @@ -5,10 +5,10 @@ import os import unittest from telemetry import benchmark +from telemetry.core import discover from telemetry.core import util from telemetry.story import story_set as story_set_module from telemetry.testing import fakes -from telemetry.util import classes_util util.AddDirToPythonPath(util.GetTelemetryDir(), 'third_party', 'mock') import mock # pylint: disable=import-error @@ -23,8 +23,10 @@ def _GetGpuDir(*subdirs): class NoOverridesTest(unittest.TestCase): def testValidatorBase(self): - all_validators = classes_util.DiscoverClasses( - _GetGpuDir('gpu_tests'), _GetGpuDir(), gpu_test_base.ValidatorBase) + all_validators = discover.DiscoverClasses( + _GetGpuDir('gpu_tests'), _GetGpuDir(), + gpu_test_base.ValidatorBase, + index_by_class_name=True).values() self.assertGreater(len(all_validators), 0) for validator in all_validators: self.assertEquals(gpu_test_base.ValidatorBase.ValidateAndMeasurePage, @@ -33,8 +35,10 @@ class NoOverridesTest(unittest.TestCase): % validator.__name__) def testPageBase(self): - all_pages = classes_util.DiscoverClasses( - _GetGpuDir(), _GetGpuDir(), gpu_test_base.PageBase) + all_pages = discover.DiscoverClasses( + _GetGpuDir(), _GetGpuDir(), + gpu_test_base.PageBase, + index_by_class_name=True).values() self.assertGreater(len(all_pages), 0) for page in all_pages: self.assertEquals(gpu_test_base.PageBase.RunNavigateSteps, diff --git a/content/test/gpu/page_sets/__init__.py b/content/test/gpu/page_sets/__init__.py index 7d6dd796b8ec..ccb12f67bfc8 100644 --- a/content/test/gpu/page_sets/__init__.py +++ b/content/test/gpu/page_sets/__init__.py @@ -4,13 +4,14 @@ import os import sys +from telemetry.core import discover from telemetry.story import story_set -from telemetry.util import classes_util # Import all submodules' StorySet classes. start_dir = os.path.dirname(os.path.abspath(__file__)) top_level_dir = os.path.dirname(start_dir) base_class = story_set.StorySet -for cls in classes_util.DiscoverClasses(start_dir, top_level_dir, base_class): +for cls in discover.DiscoverClasses( + start_dir, top_level_dir, base_class).values(): setattr(sys.modules[__name__], cls.__name__, cls) diff --git a/tools/chrome_proxy/integration_tests/chrome_proxy_pagesets/__init__.py b/tools/chrome_proxy/integration_tests/chrome_proxy_pagesets/__init__.py index c5699ad3ace0..799c2462114f 100644 --- a/tools/chrome_proxy/integration_tests/chrome_proxy_pagesets/__init__.py +++ b/tools/chrome_proxy/integration_tests/chrome_proxy_pagesets/__init__.py @@ -6,9 +6,8 @@ import inspect import os import sys +from telemetry.core import discover from telemetry import story -from telemetry.util import classes_util - import video @@ -16,7 +15,8 @@ import video start_dir = os.path.dirname(os.path.abspath(__file__)) top_level_dir = os.path.abspath(os.path.join(start_dir, os.pardir, os.pardir)) base_class = story.StorySet -for cls in classes_util.DiscoverClasses(start_dir, top_level_dir, base_class): +for cls in discover.DiscoverClasses( + start_dir, top_level_dir, base_class).values(): setattr(sys.modules[__name__], cls.__name__, cls) # DiscoverClasses makes the assumption that there is exactly one matching diff --git a/tools/chrome_proxy/live_tests/pagesets/__init__.py b/tools/chrome_proxy/live_tests/pagesets/__init__.py index a67d12d383c4..45ce4af9df80 100644 --- a/tools/chrome_proxy/live_tests/pagesets/__init__.py +++ b/tools/chrome_proxy/live_tests/pagesets/__init__.py @@ -6,14 +6,15 @@ import inspect import os import sys +from telemetry.core import discover from telemetry import story -from telemetry.util import classes_util # Import all submodules' StorySet classes. start_dir = os.path.dirname(os.path.abspath(__file__)) top_level_dir = os.path.abspath(os.path.join(start_dir, os.pardir, os.pardir)) base_class = story.StorySet -for cls in classes_util.DiscoverClasses(start_dir, top_level_dir, base_class): +for cls in discover.DiscoverClasses( + start_dir, top_level_dir, base_class).values(): setattr(sys.modules[__name__], cls.__name__, cls) diff --git a/tools/perf/benchmarks/benchmark_smoke_unittest.py b/tools/perf/benchmarks/benchmark_smoke_unittest.py index b8ccb0cbb122..69ffa268fbfa 100644 --- a/tools/perf/benchmarks/benchmark_smoke_unittest.py +++ b/tools/perf/benchmarks/benchmark_smoke_unittest.py @@ -104,11 +104,11 @@ def load_tests(loader, standard_tests, pattern): benchmarks_dir = os.path.dirname(__file__) top_level_dir = os.path.dirname(benchmarks_dir) - # Using the default of |one_class_per_module=True| means that if a module - # has multiple benchmarks, only the first one is returned. + # Using the default of |index_by_class_name=False| means that if a module + # has multiple benchmarks, only the last one is returned. all_benchmarks = discover.DiscoverClasses( benchmarks_dir, top_level_dir, benchmark_module.Benchmark, - one_class_per_module=True) + index_by_class_name=False).values() for benchmark in all_benchmarks: if sys.modules[benchmark.__module__] in _BLACK_LIST_TEST_MODULES: continue diff --git a/tools/perf/benchmarks/benchmark_unittest.py b/tools/perf/benchmarks/benchmark_unittest.py index d5d039c547f4..9fe848d1a185 100644 --- a/tools/perf/benchmarks/benchmark_unittest.py +++ b/tools/perf/benchmarks/benchmark_unittest.py @@ -11,9 +11,9 @@ import unittest from core import perf_benchmark from telemetry import benchmark as benchmark_module +from telemetry.core import discover from telemetry.internal.browser import browser_options from telemetry.testing import progress_reporter -from telemetry.util import classes_util def _GetPerfDir(*subdirs): @@ -22,8 +22,9 @@ def _GetPerfDir(*subdirs): def _GetAllPerfBenchmarks(): - return classes_util.DiscoverClasses( - _GetPerfDir('benchmarks'), _GetPerfDir(), benchmark_module.Benchmark) + return discover.DiscoverClasses( + _GetPerfDir('benchmarks'), _GetPerfDir(), benchmark_module.Benchmark, + index_by_class_name=True).values() def _BenchmarkOptionsTestGenerator(benchmark): def testBenchmarkOptions(self): # pylint: disable=W0613 diff --git a/tools/perf/benchmarks/skpicture_printer.py b/tools/perf/benchmarks/skpicture_printer.py index 2ed7b5a5de53..0247320f3135 100644 --- a/tools/perf/benchmarks/skpicture_printer.py +++ b/tools/perf/benchmarks/skpicture_printer.py @@ -5,15 +5,15 @@ from core import perf_benchmark from telemetry import benchmark +from telemetry.core import discover from telemetry import story -from telemetry.util import classes_util from measurements import skpicture_printer def _MatchPageSetName(story_set_name, story_set_base_dir): - story_sets = classes_util.DiscoverClasses( - story_set_base_dir, story_set_base_dir, story.StorySet) + story_sets = discover.DiscoverClasses(story_set_base_dir, story_set_base_dir, + story.StorySet).values() for s in story_sets: if story_set_name == s.Name(): return s diff --git a/tools/perf/measurements/measurement_smoke_test.py b/tools/perf/measurements/measurement_smoke_test.py index a8c8477844b3..bedd0ba05582 100644 --- a/tools/perf/measurements/measurement_smoke_test.py +++ b/tools/perf/measurements/measurement_smoke_test.py @@ -8,10 +8,10 @@ import os import unittest from telemetry import benchmark as benchmark_module +from telemetry.core import discover from telemetry.internal.browser import browser_options from telemetry.page import page_test from telemetry.testing import options_for_unittests -from telemetry.util import classes_util from telemetry.web_perf import timeline_based_measurement @@ -23,14 +23,14 @@ def _GetAllPossiblePageTestInstances(): # Get all page test instances from measurement classes that are directly # constructable - all_measurement_classes = classes_util.DiscoverClasses( + all_measurement_classes = discover.DiscoverClasses( measurements_dir, top_level_dir, page_test.PageTest, - directly_constructable=True) + index_by_class_name=True, directly_constructable=True).values() for measurement_class in all_measurement_classes: page_test_instances.append(measurement_class()) - all_benchmarks_classes = classes_util.DiscoverClasses( - benchmarks_dir, top_level_dir, benchmark_module.Benchmark) + all_benchmarks_classes = discover.DiscoverClasses( + benchmarks_dir, top_level_dir, benchmark_module.Benchmark).values() # Get all page test instances from defined benchmarks. # Note: since this depends on the command line options, there is no guaranteed diff --git a/tools/perf/page_sets/__init__.py b/tools/perf/page_sets/__init__.py index d585f3271d79..65daf2f00485 100644 --- a/tools/perf/page_sets/__init__.py +++ b/tools/perf/page_sets/__init__.py @@ -6,14 +6,14 @@ import inspect import os import sys +from telemetry.core import discover from telemetry import story -from telemetry.util import classes_util # Import all submodules' PageSet classes. start_dir = os.path.dirname(os.path.abspath(__file__)) top_level_dir = os.path.dirname(start_dir) base_class = story.StorySet -for cls in classes_util.DiscoverClasses( - start_dir, top_level_dir, base_class): +for cls in discover.DiscoverClasses( + start_dir, top_level_dir, base_class).values(): setattr(sys.modules[__name__], cls.__name__, cls) diff --git a/tools/perf/profile_creators/profile_generator.py b/tools/perf/profile_creators/profile_generator.py index dc683828d711..4c52665525fd 100644 --- a/tools/perf/profile_creators/profile_generator.py +++ b/tools/perf/profile_creators/profile_generator.py @@ -13,11 +13,11 @@ import sys import tempfile from profile_creators import profile_extender +from telemetry.core import discover from telemetry.core import util from telemetry.internal.browser import browser_finder from telemetry.internal.browser import browser_options from telemetry.internal import story_runner -from telemetry.util import classes_util def _DiscoverProfileExtenderClasses(): @@ -25,7 +25,7 @@ def _DiscoverProfileExtenderClasses(): os.pardir, 'perf', 'profile_creators')) base_dir = os.path.abspath(os.path.join(profile_extenders_dir, os.pardir)) - profile_extenders_unfiltered = classes_util.DiscoverClassesByClassName( + profile_extenders_unfiltered = discover.DiscoverClasses( profile_extenders_dir, base_dir, profile_extender.ProfileExtender) # Remove 'extender' suffix from keys. diff --git a/tools/telemetry/telemetry/benchmark_runner.py b/tools/telemetry/telemetry/benchmark_runner.py index 78253600c17f..eecb9458d711 100644 --- a/tools/telemetry/telemetry/benchmark_runner.py +++ b/tools/telemetry/telemetry/benchmark_runner.py @@ -14,11 +14,11 @@ import os import sys from telemetry import benchmark +from telemetry.core import discover from telemetry import decorators from telemetry.internal.browser import browser_finder from telemetry.internal.browser import browser_options from telemetry.internal.util import command_line -from telemetry.util import classes_util def PrintBenchmarkList(benchmarks, possible_browser, output_pipe=sys.stdout): @@ -264,9 +264,10 @@ def _MatchingCommands(string): def _Benchmarks(environment): benchmarks = [] for search_dir in environment.benchmark_dirs: - benchmarks += classes_util.DiscoverClasses(search_dir, + benchmarks += discover.DiscoverClasses(search_dir, environment.top_level_dir, - benchmark.Benchmark) + benchmark.Benchmark, + index_by_class_name=True).values() return benchmarks def _MatchBenchmarkName(input_benchmark_name, environment, exact_matches=True): diff --git a/tools/telemetry/telemetry/core/discover.py b/tools/telemetry/telemetry/core/discover.py index 53393200acea..546aa6372327 100644 --- a/tools/telemetry/telemetry/core/discover.py +++ b/tools/telemetry/telemetry/core/discover.py @@ -7,9 +7,12 @@ import inspect import os import re +from telemetry import decorators +from telemetry.internal.util import camel_case from telemetry.internal.util import classes as classes_module +@decorators.Cache def DiscoverModules(start_dir, top_level_dir, pattern='*'): """Discover all modules in |start_dir| which match |pattern|. @@ -46,8 +49,12 @@ def DiscoverModules(start_dir, top_level_dir, pattern='*'): modules.append(module) return modules + +# TODO(dtu): Normalize all discoverable classes to have corresponding module +# and class names, then always index by class name. +@decorators.Cache def DiscoverClasses(start_dir, top_level_dir, base_class, pattern='*', - one_class_per_module=False, directly_constructable=False): + index_by_class_name=True, directly_constructable=False): """Discover all classes in |start_dir| which subclass |base_class|. Base classes that contain subclasses are ignored by default. @@ -57,21 +64,24 @@ def DiscoverClasses(start_dir, top_level_dir, base_class, pattern='*', top_level_dir: The top level of the package, for importing. base_class: The base class to search for. pattern: Unix shell-style pattern for filtering the filenames to import. - one_class_per_module: If True, will only include the first class found in - each module. + index_by_class_name: If True, use class name converted to + lowercase_with_underscores instead of module name in return dict keys. directly_constructable: If True, will only return classes that can be constructed without arguments - Returns: A list of classes. + Returns: + dict of {module_name: class} or {underscored_class_name: class} """ modules = DiscoverModules(start_dir, top_level_dir, pattern) - classes = [] + classes = {} for module in modules: - classes.extend(DiscoverClassesInModule( - module, base_class, one_class_per_module, directly_constructable)) + new_classes = DiscoverClassesInModule( + module, base_class, index_by_class_name, directly_constructable) + classes = dict(classes.items() + new_classes.items()) return classes -def DiscoverClassesInModule(module, base_class, one_class_per_module=False, +@decorators.Cache +def DiscoverClassesInModule(module, base_class, index_by_class_name=False, directly_constructable=False): """Discover all classes in |module| which subclass |base_class|. @@ -80,12 +90,13 @@ def DiscoverClassesInModule(module, base_class, one_class_per_module=False, Args: module: The module to search. base_class: The base class to search for. - one_class_per_module: If True, will only include the first class found in - each module. + index_by_class_name: If True, use class name converted to + lowercase_with_underscores instead of module name in return dict keys. - Returns: A list of classes. + Returns: + dict of {module_name: class} or {underscored_class_name: class} """ - classes = [] + classes = {} for _, obj in inspect.getmembers(module): # Ensure object is a class. if not inspect.isclass(obj): @@ -104,11 +115,14 @@ def DiscoverClassesInModule(module, base_class, one_class_per_module=False, if obj.__module__ != module.__name__: continue + if index_by_class_name: + key_name = camel_case.ToUnderscore(obj.__name__) + else: + key_name = module.__name__.split('.')[-1] if (not directly_constructable or classes_module.IsDirectlyConstructable(obj)): - classes.append(obj) - if one_class_per_module: - return classes + classes[key_name] = obj + return classes diff --git a/tools/telemetry/telemetry/core/discover_unittest.py b/tools/telemetry/telemetry/core/discover_unittest.py dissimilarity index 68% index c39dd2d92d05..c124d4507851 100644 --- a/tools/telemetry/telemetry/core/discover_unittest.py +++ b/tools/telemetry/telemetry/core/discover_unittest.py @@ -1,95 +1,103 @@ -# Copyright 2013 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -import os -import unittest - -from telemetry.core import discover -from telemetry.core import util - - -class DiscoverTest(unittest.TestCase): - def setUp(self): - self._base_dir = util.GetUnittestDataDir() - self._start_dir = os.path.join(self._base_dir, 'discoverable_classes') - self._base_class = Exception - - def testDiscoverClassesWithDefaults(self): - classes = discover.DiscoverClasses( - self._start_dir, self._base_dir, self._base_class) - - actual_classes = list(cls.__name__ for cls in classes) - expected_classes = [ - 'DummyException', 'DummyExceptionImpl1', 'DummyExceptionImpl2', - 'DummyExceptionWithParameterImpl1', 'DummyExceptionWithParameterImpl2' - ] - self.assertItemsEqual(actual_classes, expected_classes) - - - def testDiscoverClassesOneClassPerModule(self): - classes = discover.DiscoverClasses( - self._start_dir, self._base_dir, self._base_class, - one_class_per_module=True) - - actual_classes = list(cls.__name__ for cls in classes) - expected_classes = ['DummyExceptionImpl1', 'DummyException', - 'DummyExceptionWithParameterImpl2'] - self.assertItemsEqual(actual_classes, expected_classes) - - def testDiscoverDirectlyConstructableClasses(self): - classes = discover.DiscoverClasses( - self._start_dir, self._base_dir, self._base_class, - directly_constructable=True) - - actual_classes = list(cls.__name__ for cls in classes) - expected_classes = [ - 'DummyException', 'DummyExceptionImpl1', 'DummyExceptionImpl2' - ] - self.assertItemsEqual(actual_classes, expected_classes) - - def testDiscoverOneDirectlyConstructableClassPerModule(self): - classes = discover.DiscoverClasses( - self._start_dir, self._base_dir, self._base_class, - directly_constructable=True, one_class_per_module=True) - - actual_classes = list(cls.__name__ for cls in classes) - expected_classes = ['DummyException', 'DummyExceptionImpl1'] - self.assertItemsEqual(actual_classes, expected_classes) - - def testDiscoverClassesWithPattern(self): - classes = discover.DiscoverClasses( - self._start_dir, self._base_dir, self._base_class, - pattern='another*') - - actual_classes = list(cls.__name__ for cls in classes) - expected_classes = ['DummyExceptionImpl1', 'DummyExceptionImpl2', - 'DummyExceptionWithParameterImpl1'] - self.assertItemsEqual(actual_classes, expected_classes) - - def testDiscoverOneClassPerModuleWithPattern(self): - classes = discover.DiscoverClasses( - self._start_dir, self._base_dir, self._base_class, - pattern='another*', one_class_per_module=True) - - actual_classes = list(cls.__name__ for cls in classes) - expected_classes = ['DummyExceptionImpl1'] - self.assertItemsEqual(actual_classes, expected_classes) - - def testDiscoverDirectlyConstructableClassesWithPattern(self): - classes = discover.DiscoverClasses( - self._start_dir, self._base_dir, self._base_class, - pattern='another*', directly_constructable=True) - - actual_classes = list(cls.__name__ for cls in classes) - expected_classes = ['DummyExceptionImpl1', 'DummyExceptionImpl2'] - self.assertItemsEqual(actual_classes, expected_classes) - - def testDiscoverOneDirectlyConstructableClassPerModuleWithPattern(self): - classes = discover.DiscoverClasses( - self._start_dir, self._base_dir, self._base_class, - pattern='another*', directly_constructable=True, - one_class_per_module=True) - - actual_classes = list(cls.__name__ for cls in classes) - expected_classes = ['DummyExceptionImpl1'] - self.assertItemsEqual(actual_classes, expected_classes) +# Copyright 2013 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +import os +import unittest + +from telemetry.core import discover +from telemetry.core import util + + +class DiscoverTest(unittest.TestCase): + def setUp(self): + self._base_dir = util.GetUnittestDataDir() + self._start_dir = os.path.join(self._base_dir, 'discoverable_classes') + self._base_class = Exception + + + def testDiscoverClassesWithIndexByModuleName(self): + classes = discover.DiscoverClasses( + self._start_dir, self._base_dir, self._base_class, + index_by_class_name=False) + + actual_classes = dict( + (name, cls.__name__) for name, cls in classes.iteritems()) + expected_classes = { + 'another_discover_dummyclass': 'DummyExceptionWithParameterImpl1', + 'discover_dummyclass': 'DummyException', + 'parameter_discover_dummyclass': 'DummyExceptionWithParameterImpl2' + } + self.assertEqual(actual_classes, expected_classes) + + def testDiscoverDirectlyConstructableClassesWithIndexByClassName(self): + classes = discover.DiscoverClasses( + self._start_dir, self._base_dir, self._base_class, + directly_constructable=True) + + actual_classes = dict( + (name, cls.__name__) for name, cls in classes.iteritems()) + expected_classes = { + 'dummy_exception': 'DummyException', + 'dummy_exception_impl1': 'DummyExceptionImpl1', + 'dummy_exception_impl2': 'DummyExceptionImpl2', + } + self.assertEqual(actual_classes, expected_classes) + + def testDiscoverClassesWithIndexByClassName(self): + classes = discover.DiscoverClasses( + self._start_dir, self._base_dir, self._base_class) + + actual_classes = dict( + (name, cls.__name__) for name, cls in classes.iteritems()) + expected_classes = { + 'dummy_exception': 'DummyException', + 'dummy_exception_impl1': 'DummyExceptionImpl1', + 'dummy_exception_impl2': 'DummyExceptionImpl2', + 'dummy_exception_with_parameter_impl1': + 'DummyExceptionWithParameterImpl1', + 'dummy_exception_with_parameter_impl2': + 'DummyExceptionWithParameterImpl2' + } + self.assertEqual(actual_classes, expected_classes) + + + def testDiscoverClassesWithPatternAndIndexByModule(self): + classes = discover.DiscoverClasses( + self._start_dir, self._base_dir, self._base_class, + pattern='another*', index_by_class_name=False) + + actual_classes = dict( + (name, cls.__name__) for name, cls in classes.iteritems()) + expected_classes = { + 'another_discover_dummyclass': 'DummyExceptionWithParameterImpl1' + } + self.assertEqual(actual_classes, expected_classes) + + def testDiscoverDirectlyConstructableClassesWithPatternAndIndexByClassName( + self): + classes = discover.DiscoverClasses( + self._start_dir, self._base_dir, self._base_class, + pattern='another*', directly_constructable=True) + + actual_classes = dict( + (name, cls.__name__) for name, cls in classes.iteritems()) + expected_classes = { + 'dummy_exception_impl1': 'DummyExceptionImpl1', + 'dummy_exception_impl2': 'DummyExceptionImpl2', + } + self.assertEqual(actual_classes, expected_classes) + + def testDiscoverClassesWithPatternAndIndexByClassName(self): + classes = discover.DiscoverClasses( + self._start_dir, self._base_dir, self._base_class, + pattern='another*') + + actual_classes = dict( + (name, cls.__name__) for name, cls in classes.iteritems()) + expected_classes = { + 'dummy_exception_impl1': 'DummyExceptionImpl1', + 'dummy_exception_impl2': 'DummyExceptionImpl2', + 'dummy_exception_with_parameter_impl1': + 'DummyExceptionWithParameterImpl1', + } + self.assertEqual(actual_classes, expected_classes) diff --git a/tools/telemetry/telemetry/core/platform.py b/tools/telemetry/telemetry/core/platform.py index 2b2ba3e1be67..a9566a945439 100644 --- a/tools/telemetry/telemetry/core/platform.py +++ b/tools/telemetry/telemetry/core/platform.py @@ -4,11 +4,11 @@ import logging as real_logging import os +from telemetry.core import discover from telemetry.core import network_controller from telemetry.core import tracing_controller from telemetry.core import util from telemetry.internal.platform import platform_backend as platform_backend_module -from telemetry.util import classes_util _host_platform = None @@ -39,9 +39,9 @@ def GetHostPlatform(): def _IterAllPlatformBackendClasses(): platform_dir = os.path.dirname( os.path.realpath(platform_backend_module.__file__)) - return classes_util.DiscoverClasses( + return discover.DiscoverClasses( platform_dir, util.GetTelemetryDir(), - platform_backend_module.PlatformBackend) + platform_backend_module.PlatformBackend).itervalues() def GetPlatformForDevice(device, finder_options, logging=real_logging): diff --git a/tools/telemetry/telemetry/internal/platform/profiler/profiler_finder.py b/tools/telemetry/telemetry/internal/platform/profiler/profiler_finder.py index 58afd7577f72..33c31e56bd82 100644 --- a/tools/telemetry/telemetry/internal/platform/profiler/profiler_finder.py +++ b/tools/telemetry/telemetry/internal/platform/profiler/profiler_finder.py @@ -4,15 +4,16 @@ import os +from telemetry.core import discover from telemetry.internal.platform import profiler from telemetry.core import util -from telemetry.util import classes_util def _DiscoverProfilers(): profiler_dir = os.path.dirname(__file__) - return classes_util.DiscoverClasses( - profiler_dir, util.GetTelemetryDir(), profiler.Profiler) + return discover.DiscoverClasses(profiler_dir, util.GetTelemetryDir(), + profiler.Profiler, + index_by_class_name=True).values() def FindProfiler(name): diff --git a/tools/telemetry/telemetry/internal/platform/tracing_controller_backend.py b/tools/telemetry/telemetry/internal/platform/tracing_controller_backend.py index ee318bd7a34e..96cceae715ef 100644 --- a/tools/telemetry/telemetry/internal/platform/tracing_controller_backend.py +++ b/tools/telemetry/telemetry/internal/platform/tracing_controller_backend.py @@ -4,20 +4,21 @@ import os +from telemetry.core import discover from telemetry.core import util from telemetry.internal.platform import tracing_agent from telemetry.internal.platform.tracing_agent import chrome_tracing_agent from telemetry.timeline import trace_data as trace_data_module from telemetry.timeline import tracing_category_filter from telemetry.timeline import tracing_options -from telemetry.util import classes_util def _IterAllTracingAgentClasses(): tracing_agent_dir = os.path.join( os.path.dirname(os.path.realpath(__file__)), 'tracing_agent') - return classes_util.DiscoverClasses( - tracing_agent_dir, util.GetTelemetryDir(), tracing_agent.TracingAgent) + return discover.DiscoverClasses( + tracing_agent_dir, util.GetTelemetryDir(), + tracing_agent.TracingAgent).itervalues() class TracingControllerBackend(object): diff --git a/tools/telemetry/telemetry/internal/util/find_dependencies.py b/tools/telemetry/telemetry/internal/util/find_dependencies.py index b9592449f0d7..6f40196fb2fa 100644 --- a/tools/telemetry/telemetry/internal/util/find_dependencies.py +++ b/tools/telemetry/telemetry/internal/util/find_dependencies.py @@ -12,12 +12,11 @@ import sys import zipfile from telemetry import benchmark +from telemetry.core import discover from telemetry.internal.util import bootstrap from telemetry.internal.util import command_line from telemetry.internal.util import path from telemetry.internal.util import path_set -from telemetry.util import classes_util - DEPS_FILE = 'bootstrap_deps' @@ -62,9 +61,10 @@ def FindPageSetDependencies(base_dir): # Add base_dir to path so our imports relative to base_dir will work. sys.path.append(base_dir) - tests = classes_util.DiscoverClasses(base_dir, base_dir, benchmark.Benchmark) + tests = discover.DiscoverClasses(base_dir, base_dir, benchmark.Benchmark, + index_by_class_name=True) - for test_class in tests: + for test_class in tests.itervalues(): test_obj = test_class() # Ensure the test's default options are set if needed. diff --git a/tools/telemetry/telemetry/record_wpr.py b/tools/telemetry/telemetry/record_wpr.py index 6f1d2bd193bd..9a668f997626 100644 --- a/tools/telemetry/telemetry/record_wpr.py +++ b/tools/telemetry/telemetry/record_wpr.py @@ -8,13 +8,13 @@ import sys from telemetry import benchmark from telemetry import story +from telemetry.core import discover from telemetry.core import util from telemetry.internal.browser import browser_options from telemetry.internal.results import results_options from telemetry.internal import story_runner from telemetry.internal.util import command_line from telemetry.page import page_test -from telemetry.util import classes_util from telemetry.util import wpr_modes @@ -71,13 +71,15 @@ def _GetSubclasses(base_dir, cls): Returns: dict of {underscored_class_name: benchmark class} """ - return classes_util.DiscoverClassesByClassName(base_dir, base_dir, cls) + return discover.DiscoverClasses(base_dir, base_dir, cls, + index_by_class_name=True) def _MaybeGetInstanceOfClass(target, base_dir, cls): if isinstance(target, cls): return target - return classes_util.MaybeGetInstanceOfClass(target, base_dir, base_dir, cls) + classes = _GetSubclasses(base_dir, cls) + return classes[target]() if target in classes else None def _PrintAllImpl(all_items, item_name, output_stream): diff --git a/tools/telemetry/telemetry/testing/story_set_smoke_test.py b/tools/telemetry/telemetry/testing/story_set_smoke_test.py index d0a8d575bf6e..008773f5f7ea 100644 --- a/tools/telemetry/telemetry/testing/story_set_smoke_test.py +++ b/tools/telemetry/telemetry/testing/story_set_smoke_test.py @@ -6,10 +6,10 @@ import logging import os import unittest +from telemetry.core import discover from telemetry.internal.browser import browser_credentials from telemetry import page from telemetry import story as story_module -from telemetry.util import classes_util from telemetry.wpr import archive_info @@ -23,9 +23,9 @@ class StorySetSmokeTest(unittest.TestCase): def GetAllStorySetClasses(self, story_sets_dir, top_level_dir): # We can't test page sets that aren't directly constructable since we # don't know what arguments to put for the constructor. - return classes_util.DiscoverClasses(story_sets_dir, top_level_dir, - story_module.StorySet, - directly_constructable=True) + return discover.DiscoverClasses(story_sets_dir, top_level_dir, + story_module.StorySet, + directly_constructable=True).values() def CheckArchive(self, story_set): """Verify that all URLs of pages in story_set have an associated archive.""" diff --git a/tools/telemetry/telemetry/util/classes_util.py b/tools/telemetry/telemetry/util/classes_util.py deleted file mode 100644 index 1496d896311f..000000000000 --- a/tools/telemetry/telemetry/util/classes_util.py +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright 2015 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -from telemetry.core import discover -from telemetry.internal.util import camel_case - - -def DiscoverClasses(start_dir, top_level_dir, base_class, - directly_constructable=False): - return discover.DiscoverClasses(start_dir, top_level_dir, base_class, - directly_constructable=directly_constructable) - -def DiscoverClassesByClassName( - start_dir, top_level_dir, base_class, directly_constructable=False): - classes_dict = {} - classes = discover.DiscoverClasses( - start_dir, top_level_dir, base_class, - directly_constructable=directly_constructable) - for class_obj in classes: - classes_dict[camel_case.ToUnderscore(class_obj.__name__)] = class_obj - return classes_dict - -def MaybeGetInstanceOfClass(target, start_dir, top_level_dir, cls): - classes = DiscoverClassesByClassName( - start_dir, top_level_dir, cls, directly_constructable=True) - return classes[target]() if target in classes else None diff --git a/tools/telemetry/telemetry/value/__init__.py b/tools/telemetry/telemetry/value/__init__.py index e180dd304b11..a2ab23e29165 100644 --- a/tools/telemetry/telemetry/value/__init__.py +++ b/tools/telemetry/telemetry/value/__init__.py @@ -22,9 +22,8 @@ Merge* family of methods for this kind of aggregation. """ import os +from telemetry.core import discover from telemetry.core import util -from telemetry.util import classes_util - # When combining a pair of Values togehter, it is sometimes ambiguous whether # the values should be concatenated, or one should be picked as representative. @@ -249,8 +248,9 @@ class Value(object): page_dict: a dictionary mapping IDs to page objects. """ value_dir = os.path.dirname(__file__) - value_classes = classes_util.DiscoverClassesByClassName( - value_dir, util.GetTelemetryDir(), Value) + value_classes = discover.DiscoverClasses( + value_dir, util.GetTelemetryDir(), + Value, index_by_class_name=True) value_json_types = dict((value_classes[x].GetJSONTypeName(), x) for x in value_classes) -- 2.11.4.GIT