Index: telemetry/telemetry/story/expectations.py |
diff --git a/telemetry/telemetry/story/expectations.py b/telemetry/telemetry/story/expectations.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1d5292718b64be49c27488e87cf9ad0d90acc435 |
--- /dev/null |
+++ b/telemetry/telemetry/story/expectations.py |
@@ -0,0 +1,165 @@ |
+# Copyright 2017 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 logging |
+ |
+ |
+class StoryExpectations(object): |
+ """An object that contains disabling expectations for benchmarks and stories. |
+ |
+ Example Usage: |
+ class FooBenchmarkExpectations(expectations.StoryExpectations): |
+ def SetExpectations(self): |
+ self.DisableBenchmark([expectations.ALL_WIN], 'crbug.com/123') |
+ self.DisableBenchmark([expectations.ALL_MOBILE], 'Desktop Benchmark') |
+ self.DisableStory('story_name1', [expectations.ALL_MAC], 'crbug.com/456') |
+ self.DisableStory('story_name2', [expectations.ALL], 'crbug.com/789') |
+ ... |
+ """ |
+ def __init__(self): |
+ self._disabled_platforms = [] |
+ self._expectations = {} |
+ self._frozen = False |
+ self.SetExpectations() |
+ self._Freeze() |
+ |
+ def SetExpectations(self): |
+ """Sets the Expectations for test disabling |
+ |
+ Override in subclasses to disable tests.""" |
+ pass |
+ |
+ def _Freeze(self): |
+ self._frozen = True |
+ |
+ def DisableBenchmark(self, conditions, reason): |
+ """Disable benchmark under conditions pased to method. |
charliea (OOO until 10-5)
2017/05/15 21:15:41
s/pased/passed
charliea (OOO until 10-5)
2017/05/15 21:15:42
supernit suggestion: use "given" instead of "passe
rnephew (Reviews Here)
2017/05/15 21:36:06
Done.
rnephew (Reviews Here)
2017/05/15 21:36:06
Done.
|
+ |
+ Example: |
+ DisableBenchmark([expectations.ALL_MOBILE], 'Desktop benchmark') |
+ DisableBenchmark([expectations.ALL_WIN], 'crbug.com/123') |
+ |
+ Args: |
+ conditions: List of _TestCondition subclasses. |
+ reason: Reason for disabling the benchmark. |
+ """ |
+ assert reason, 'A reason for disabling must be given.' |
+ assert not self._frozen, ('Cannot disable benchmark on a frozen ' |
+ 'StoryExpectation object.') |
+ for condition in conditions: |
+ assert isinstance(condition, _TestCondition) |
+ |
+ self._disabled_platforms.append((conditions, reason)) |
+ |
+ def IsBenchmarkDisabled(self, platform): |
+ """Returns if the benchmark has been disabled for the platform. |
charliea (OOO until 10-5)
2017/05/15 21:15:41
I think that you can collapse this whole thing dow
rnephew (Reviews Here)
2017/05/15 21:36:06
Done.
|
+ |
+ Args: |
+ platform: A platform object. |
+ |
+ Returns: |
+ Reason if disabled, None otherwise. |
+ """ |
+ for conditions, reason in self._disabled_platforms: |
+ for condition in conditions: |
+ if condition.ShouldDisable(platform): |
+ logging.info('Benchmark disabled on %s due to %s.', |
+ condition, reason) |
+ return reason |
+ return None |
+ |
+ def DisableStory(self, story_name, conditions, reason): |
+ """Disable story under given conditions. |
charliea (OOO until 10-5)
2017/05/15 21:15:41
supernit: s/Disables story under given conditions.
rnephew (Reviews Here)
2017/05/15 21:36:06
Done.
|
+ |
+ Example: |
+ DisableStory('story_name', [expectations.ALL_WIN], 'crbug.com/123') |
+ |
+ Args: |
+ story_name: Name of the story to disable passed as a string. |
+ conditions: List of _TestCondition subclasses. |
+ reason: Reason for disabling the story. |
+ """ |
+ assert reason, 'A reason for disabling must be given.' |
+ assert len(story_name) < 50, ( |
+ "Story name exceeds limit of 50 characters. This limit is in place to " |
+ "encourage Telemetry benchmark owners to use short, simple story names " |
+ "(e.g. 'google_search_images', not " |
+ "'http://www.google.com/images/1234/abc')." |
+ |
+ ) |
+ assert not self._frozen, ('Cannot disable stories on a frozen ' |
+ 'StoryExpectation object.') |
+ for condition in conditions: |
+ assert isinstance(condition, _TestCondition) |
+ if not self._expectations.get(story_name): |
+ self._expectations[story_name] = [] |
+ self._expectations[story_name].append((conditions, reason)) |
+ |
+ def IsStoryDisabled(self, story, platform): |
+ """Returns if the story has been disabled for the current platform. |
charliea (OOO until 10-5)
2017/05/15 21:15:42
See notes for IsBenchmarkDisabled
rnephew (Reviews Here)
2017/05/15 21:36:06
Done.
|
+ |
+ Args: |
+ story: Story object that contains a display_name property. |
+ platform: A platform object. |
+ |
+ Returns: |
+ Reason if disabled, None otherwise. |
+ """ |
+ |
charliea (OOO until 10-5)
2017/05/15 21:15:42
supernit: delete empty first line
rnephew (Reviews Here)
2017/05/15 21:36:06
Done.
|
+ for conditions, reason in self._expectations.get(story.display_name, []): |
+ for condition in conditions: |
+ if condition.ShouldDisable(platform): |
+ logging.info('%s is disabled on %s due to %s.', |
+ story.display_name, condition, reason) |
+ return reason |
+ return None |
+ |
+ |
+class _TestCondition(object): |
+ def ShouldDisable(self, platform): |
+ raise NotImplementedError |
+ |
+ def __str__(self): |
+ raise NotImplementedError |
+ |
+ |
+class _TestConditionByPlatformList(_TestCondition): |
+ def __init__(self, platforms, name): |
+ self._platforms = platforms |
+ self._name = name |
+ |
+ def ShouldDisable(self, platform): |
+ return platform.GetOSName() in self._platforms |
+ |
+ def __str__(self): |
+ return self._name |
+ |
+ |
+class _AllTestCondition(_TestCondition): |
+ def ShouldDisable(self, _): |
+ return True |
+ |
+ def __str__(self): |
+ return 'All Platforms' |
+ |
+ |
+class _NoBattOrTestCondition(_TestCondition): |
+ # Example use case for NO_BATTOR test condition: |
+ # If a trace is too long to be processed if it contains power data. |
+ def ShouldDisable(self, platform): |
+ return not platform.HasBattOrConnected() |
+ |
+ def __str__(self): |
+ return 'Platforms with no BattOr' |
+ |
+ |
+ALL = _AllTestCondition() |
+ALL_MAC = _TestConditionByPlatformList(['mac'], 'Mac Platforms') |
+ALL_WIN = _TestConditionByPlatformList(['win'], 'Win Platforms') |
+ALL_LINUX = _TestConditionByPlatformList(['linux'], 'Linux Platforms') |
+ALL_ANDROID = _TestConditionByPlatformList(['android'], 'Android Platforms') |
+ALL_DESKTOP = _TestConditionByPlatformList( |
+ ['mac', 'linux', 'win'], 'Desktop Platforms') |
+ALL_MOBILE = _TestConditionByPlatformList(['android'], 'Mobile Platforms') |
+NO_BATTOR = _NoBattOrTestCondition() |