133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# Copyright 2014 The Chromium Authors. All rights reserved.
233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# Use of this source code is governed by a BSD-style license that can be
333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# found in the LICENSE file.
433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckimport mock
533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckimport unittest
633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckfrom telemetry.internal.platform import android_platform_backend
833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckfrom telemetry.internal.platform.tracing_agent import display_tracing_agent
933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckfrom telemetry.timeline import tracing_config
1033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
1133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# pylint: disable=super-init-not-called, abstract-method, unused-argument
1233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckclass FakeAndroidPlatformBackend(
1333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    android_platform_backend.AndroidPlatformBackend):
1433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def __init__(self):
1533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self._device = 0
1633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self._raw_display_frame_rate_measurements = []
1733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self._surface_stats_collector = None
1833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
1933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  @property
2033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def surface_stats_collector(self):
2133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    return self._surface_stats_collector
2233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
2333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def IsDisplayTracingSupported(self):
2433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    return True
2533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
2633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
2733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckclass DisplayTracingAgentTest(unittest.TestCase):
2833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def setUp(self):
2933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self._config = tracing_config.TracingConfig()
3033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self._config.enable_platform_display_trace = True
3133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self._platform_backend = FakeAndroidPlatformBackend()
3233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self._agent = display_tracing_agent.DisplayTracingAgent(
3333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        self._platform_backend)
3433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
3533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def stopAndCollect(self):
3633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self._agent.StopAgentTracing()
3733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self._agent.CollectAgentTraceData(mock.MagicMock())
3833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
3933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  @mock.patch(
4033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      'devil.android.perf.surface_stats_collector.SurfaceStatsCollector')
4133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def testStartAndStopTracing(self, MockSurfaceStatsCollector):
4233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self._agent.StartAgentTracing(self._config, 10)
4333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    # Second start tracing will raise error.
4433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    with self.assertRaises(AssertionError):
4533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      self._agent.StartAgentTracing(self._config, 10)
4633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self._platform_backend.surface_stats_collector.Stop.return_value = (0, [])
4733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.stopAndCollect()
4833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
4933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    # Can start and stop tracing multiple times.
5033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self._agent.StartAgentTracing(self._config, 10)
5133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self._platform_backend.surface_stats_collector.Stop.return_value = (0, [])
5233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.stopAndCollect()
5333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
5433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  @mock.patch(
5533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      'devil.android.perf.surface_stats_collector.SurfaceStatsCollector')
5633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def testExceptionRaisedInStopTracing(self, MockSurfaceStatsCollector):
5733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self._agent.StartAgentTracing(self._config, 10)
5833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self._platform_backend.surface_stats_collector.Stop.side_effect = Exception(
5933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        'Raise error when stopping tracing.')
6033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    with self.assertRaises(Exception):
6133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      self.stopAndCollect()
6233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    # Tracing is stopped even if there is exception. And the agent can start
6333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    # tracing again.
6433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self._agent.StartAgentTracing(self._config, 10)
6533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self._platform_backend.surface_stats_collector.Stop.side_effect = None
6633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self._platform_backend.surface_stats_collector.Stop.return_value = (0, [])
6733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.stopAndCollect()
68