Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(396)

Unified Diff: tools/telemetry/telemetry/web_perf/metrics/rendering_stats_unittest.py

Issue 1647513002: Delete tools/telemetry. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tools/telemetry/telemetry/web_perf/metrics/rendering_stats_unittest.py
diff --git a/tools/telemetry/telemetry/web_perf/metrics/rendering_stats_unittest.py b/tools/telemetry/telemetry/web_perf/metrics/rendering_stats_unittest.py
deleted file mode 100644
index 0609bbd52af225c4166760a51b5cec1c42a8f81d..0000000000000000000000000000000000000000
--- a/tools/telemetry/telemetry/web_perf/metrics/rendering_stats_unittest.py
+++ /dev/null
@@ -1,543 +0,0 @@
-# Copyright 2014 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 random
-import unittest
-
-from telemetry.timeline import async_slice
-from telemetry.timeline import bounds
-from telemetry.timeline import model
-from telemetry.util import perf_tests_helper
-from telemetry.util import statistics
-from telemetry.web_perf.metrics import rendering_stats
-
-
-class MockTimer(object):
- """A mock timer class which can generate random durations.
-
- An instance of this class is used as a global timer to generate random
- durations for stats and consistent timestamps for all mock trace events.
- The unit of time is milliseconds.
- """
-
- def __init__(self):
- self.milliseconds = 0
-
- def Advance(self, low=0.1, high=1):
- delta = random.uniform(low, high)
- self.milliseconds += delta
- return delta
-
- def AdvanceAndGet(self, low=0.1, high=1):
- self.Advance(low, high)
- return self.milliseconds
-
-
-class ReferenceRenderingStats(object):
- """ Stores expected data for comparison with actual RenderingStats """
-
- def __init__(self):
- self.frame_timestamps = []
- self.frame_times = []
- self.approximated_pixel_percentages = []
- self.checkerboarded_pixel_percentages = []
-
- def AppendNewRange(self):
- self.frame_timestamps.append([])
- self.frame_times.append([])
- self.approximated_pixel_percentages.append([])
- self.checkerboarded_pixel_percentages.append([])
-
-
-class ReferenceInputLatencyStats(object):
- """ Stores expected data for comparison with actual input latency stats """
-
- def __init__(self):
- self.input_event_latency = []
- self.input_event = []
-
-
-def AddSurfaceFlingerStats(mock_timer, thread, first_frame,
- ref_stats=None):
- """ Adds a random surface flinger stats event.
-
- thread: The timeline model thread to which the event will be added.
- first_frame: Is this the first frame within the bounds of an action?
- ref_stats: A ReferenceRenderingStats object to record expected values.
- """
- # Create randonm data and timestap for impl thread rendering stats.
- data = {'frame_count': 1,
- 'refresh_period': 16.6666}
- timestamp = mock_timer.AdvanceAndGet()
-
- # Add a slice with the event data to the given thread.
- thread.PushCompleteSlice(
- 'SurfaceFlinger', 'vsync_before',
- timestamp, duration=0.0, thread_timestamp=None, thread_duration=None,
- args={'data': data})
-
- if not ref_stats:
- return
-
- # Add timestamp only if a frame was output
- if data['frame_count'] == 1:
- if not first_frame:
- # Add frame_time if this is not the first frame in within the bounds of an
- # action.
- prev_timestamp = ref_stats.frame_timestamps[-1][-1]
- ref_stats.frame_times[-1].append(timestamp - prev_timestamp)
- ref_stats.frame_timestamps[-1].append(timestamp)
-
-
-def AddDisplayRenderingStats(mock_timer, thread, first_frame,
- ref_stats=None):
- """ Adds a random display rendering stats event.
-
- thread: The timeline model thread to which the event will be added.
- first_frame: Is this the first frame within the bounds of an action?
- ref_stats: A ReferenceRenderingStats object to record expected values.
- """
- # Create randonm data and timestap for main thread rendering stats.
- data = {'frame_count': 1}
- timestamp = mock_timer.AdvanceAndGet()
-
- # Add a slice with the event data to the given thread.
- thread.PushCompleteSlice(
- 'benchmark', 'BenchmarkInstrumentation::DisplayRenderingStats',
- timestamp, duration=0.0, thread_timestamp=None, thread_duration=None,
- args={'data': data})
-
- if not ref_stats:
- return
-
- # Add timestamp only if a frame was output
- if not first_frame:
- # Add frame_time if this is not the first frame in within the bounds of an
- # action.
- prev_timestamp = ref_stats.frame_timestamps[-1][-1]
- ref_stats.frame_times[-1].append(timestamp - prev_timestamp)
- ref_stats.frame_timestamps[-1].append(timestamp)
-
-
-def AddImplThreadRenderingStats(mock_timer, thread, first_frame,
- ref_stats=None):
- """ Adds a random impl thread rendering stats event.
-
- thread: The timeline model thread to which the event will be added.
- first_frame: Is this the first frame within the bounds of an action?
- ref_stats: A ReferenceRenderingStats object to record expected values.
- """
- # Create randonm data and timestap for impl thread rendering stats.
- data = {'frame_count': 1,
- 'visible_content_area': random.uniform(0, 100),
- 'approximated_visible_content_area': random.uniform(0, 5),
- 'checkerboarded_visible_content_area': random.uniform(0, 5)}
- timestamp = mock_timer.AdvanceAndGet()
-
- # Add a slice with the event data to the given thread.
- thread.PushCompleteSlice(
- 'benchmark', 'BenchmarkInstrumentation::ImplThreadRenderingStats',
- timestamp, duration=0.0, thread_timestamp=None, thread_duration=None,
- args={'data': data})
-
- if not ref_stats:
- return
-
- # Add timestamp only if a frame was output
- if data['frame_count'] == 1:
- if not first_frame:
- # Add frame_time if this is not the first frame in within the bounds of an
- # action.
- prev_timestamp = ref_stats.frame_timestamps[-1][-1]
- ref_stats.frame_times[-1].append(timestamp - prev_timestamp)
- ref_stats.frame_timestamps[-1].append(timestamp)
-
- ref_stats.approximated_pixel_percentages[-1].append(
- round(statistics.DivideIfPossibleOrZero(
- data['approximated_visible_content_area'],
- data['visible_content_area']) * 100.0, 3))
-
- ref_stats.checkerboarded_pixel_percentages[-1].append(
- round(statistics.DivideIfPossibleOrZero(
- data['checkerboarded_visible_content_area'],
- data['visible_content_area']) * 100.0, 3))
-
-def AddInputLatencyStats(mock_timer, start_thread, end_thread,
- ref_latency_stats=None):
- """ Adds a random input latency stats event.
-
- start_thread: The start thread on which the async slice is added.
- end_thread: The end thread on which the async slice is ended.
- ref_latency_stats: A ReferenceInputLatencyStats object for expected values.
- """
-
- original_comp_time = mock_timer.AdvanceAndGet(2, 4) * 1000.0
- ui_comp_time = mock_timer.AdvanceAndGet(2, 4) * 1000.0
- begin_comp_time = mock_timer.AdvanceAndGet(2, 4) * 1000.0
- forward_comp_time = mock_timer.AdvanceAndGet(2, 4) * 1000.0
- end_comp_time = mock_timer.AdvanceAndGet(10, 20) * 1000.0
-
- data = {rendering_stats.ORIGINAL_COMP_NAME: {'time': original_comp_time},
- rendering_stats.UI_COMP_NAME: {'time': ui_comp_time},
- rendering_stats.BEGIN_COMP_NAME: {'time': begin_comp_time},
- rendering_stats.END_COMP_NAME: {'time': end_comp_time}}
-
- timestamp = mock_timer.AdvanceAndGet(2, 4)
-
- tracing_async_slice = async_slice.AsyncSlice(
- 'benchmark', 'InputLatency', timestamp)
-
- async_sub_slice = async_slice.AsyncSlice(
- 'benchmark', rendering_stats.GESTURE_SCROLL_UPDATE_EVENT_NAME, timestamp)
- async_sub_slice.args = {'data': data}
- async_sub_slice.parent_slice = tracing_async_slice
- async_sub_slice.start_thread = start_thread
- async_sub_slice.end_thread = end_thread
-
- tracing_async_slice.sub_slices.append(async_sub_slice)
- tracing_async_slice.start_thread = start_thread
- tracing_async_slice.end_thread = end_thread
- start_thread.AddAsyncSlice(tracing_async_slice)
-
- # Add scroll update latency info.
- scroll_update_data = {
- rendering_stats.BEGIN_SCROLL_UPDATE_COMP_NAME: {'time': begin_comp_time},
- rendering_stats.FORWARD_SCROLL_UPDATE_COMP_NAME:
- {'time': forward_comp_time},
- rendering_stats.END_COMP_NAME: {'time': end_comp_time}
- }
-
- scroll_async_slice = async_slice.AsyncSlice(
- 'benchmark', 'InputLatency', timestamp)
-
- scroll_async_sub_slice = async_slice.AsyncSlice(
- 'benchmark', rendering_stats.MAIN_THREAD_SCROLL_UPDATE_EVENT_NAME,
- timestamp)
- scroll_async_sub_slice.args = {'data': scroll_update_data}
- scroll_async_sub_slice.parent_slice = scroll_async_slice
- scroll_async_sub_slice.start_thread = start_thread
- scroll_async_sub_slice.end_thread = end_thread
-
- scroll_async_slice.sub_slices.append(scroll_async_sub_slice)
- scroll_async_slice.start_thread = start_thread
- scroll_async_slice.end_thread = end_thread
- start_thread.AddAsyncSlice(scroll_async_slice)
-
- # Also add some dummy frame statistics so we can feed the resulting timeline
- # to RenderingStats.
- AddImplThreadRenderingStats(mock_timer, end_thread, False)
-
- if not ref_latency_stats:
- return
-
- ref_latency_stats.input_event.append(async_sub_slice)
- ref_latency_stats.input_event.append(scroll_async_sub_slice)
- ref_latency_stats.input_event_latency.append((
- rendering_stats.GESTURE_SCROLL_UPDATE_EVENT_NAME,
- (data[rendering_stats.END_COMP_NAME]['time'] -
- data[rendering_stats.ORIGINAL_COMP_NAME]['time']) / 1000.0))
- scroll_update_time = (
- scroll_update_data[rendering_stats.END_COMP_NAME]['time'] -
- scroll_update_data[rendering_stats.BEGIN_SCROLL_UPDATE_COMP_NAME]['time'])
- ref_latency_stats.input_event_latency.append((
- rendering_stats.MAIN_THREAD_SCROLL_UPDATE_EVENT_NAME,
- scroll_update_time / 1000.0))
-
-
-class RenderingStatsUnitTest(unittest.TestCase):
-
- def testHasRenderingStats(self):
- timeline = model.TimelineModel()
- timer = MockTimer()
-
- # A process without rendering stats
- process_without_stats = timeline.GetOrCreateProcess(pid=1)
- thread_without_stats = process_without_stats.GetOrCreateThread(tid=11)
- process_without_stats.FinalizeImport()
- self.assertFalse(rendering_stats.HasRenderingStats(thread_without_stats))
-
- # A process with rendering stats, but no frames in them
- process_without_frames = timeline.GetOrCreateProcess(pid=2)
- thread_without_frames = process_without_frames.GetOrCreateThread(tid=21)
- process_without_frames.FinalizeImport()
- self.assertFalse(rendering_stats.HasRenderingStats(thread_without_frames))
-
- # A process with rendering stats and frames in them
- process_with_frames = timeline.GetOrCreateProcess(pid=3)
- thread_with_frames = process_with_frames.GetOrCreateThread(tid=31)
- AddImplThreadRenderingStats(timer, thread_with_frames, True, None)
- process_with_frames.FinalizeImport()
- self.assertTrue(rendering_stats.HasRenderingStats(thread_with_frames))
-
- def testBothSurfaceFlingerAndDisplayStats(self):
- timeline = model.TimelineModel()
- timer = MockTimer()
-
- ref_stats = ReferenceRenderingStats()
- ref_stats.AppendNewRange()
- surface_flinger = timeline.GetOrCreateProcess(pid=4)
- surface_flinger.name = 'SurfaceFlinger'
- surface_flinger_thread = surface_flinger.GetOrCreateThread(tid=41)
- renderer = timeline.GetOrCreateProcess(pid=2)
- browser = timeline.GetOrCreateProcess(pid=3)
- browser_main = browser.GetOrCreateThread(tid=31)
- browser_main.BeginSlice('webkit.console', 'ActionA',
- timer.AdvanceAndGet(2, 4), '')
-
- # Create SurfaceFlinger stats and display rendering stats.
- for i in xrange(0, 10):
- first = (i == 0)
- AddSurfaceFlingerStats(timer, surface_flinger_thread, first, ref_stats)
- timer.Advance(2, 4)
-
- for i in xrange(0, 10):
- first = (i == 0)
- AddDisplayRenderingStats(timer, browser_main, first, None)
- timer.Advance(5, 10)
-
- browser_main.EndSlice(timer.AdvanceAndGet())
- timer.Advance(2, 4)
-
- browser.FinalizeImport()
- renderer.FinalizeImport()
- timeline_markers = timeline.FindTimelineMarkers(['ActionA'])
- timeline_ranges = [bounds.Bounds.CreateFromEvent(marker)
- for marker in timeline_markers]
- stats = rendering_stats.RenderingStats(
- renderer, browser, surface_flinger, timeline_ranges)
-
- # Compare rendering stats to reference - Only SurfaceFlinger stats should
- # count
- self.assertEquals(stats.frame_timestamps, ref_stats.frame_timestamps)
- self.assertEquals(stats.frame_times, ref_stats.frame_times)
-
- def testBothDisplayAndImplStats(self):
- timeline = model.TimelineModel()
- timer = MockTimer()
-
- ref_stats = ReferenceRenderingStats()
- ref_stats.AppendNewRange()
- renderer = timeline.GetOrCreateProcess(pid=2)
- browser = timeline.GetOrCreateProcess(pid=3)
- browser_main = browser.GetOrCreateThread(tid=31)
- browser_main.BeginSlice('webkit.console', 'ActionA',
- timer.AdvanceAndGet(2, 4), '')
-
- # Create main, impl, and display rendering stats.
- for i in xrange(0, 10):
- first = (i == 0)
- AddImplThreadRenderingStats(timer, browser_main, first, None)
- timer.Advance(2, 4)
-
- for i in xrange(0, 10):
- first = (i == 0)
- AddDisplayRenderingStats(timer, browser_main, first, ref_stats)
- timer.Advance(5, 10)
-
- browser_main.EndSlice(timer.AdvanceAndGet())
- timer.Advance(2, 4)
-
- browser.FinalizeImport()
- renderer.FinalizeImport()
- timeline_markers = timeline.FindTimelineMarkers(['ActionA'])
- timeline_ranges = [bounds.Bounds.CreateFromEvent(marker)
- for marker in timeline_markers]
- stats = rendering_stats.RenderingStats(
- renderer, browser, None, timeline_ranges)
-
- # Compare rendering stats to reference - Only display stats should count
- self.assertEquals(stats.frame_timestamps, ref_stats.frame_timestamps)
- self.assertEquals(stats.frame_times, ref_stats.frame_times)
-
- def testRangeWithoutFrames(self):
- timer = MockTimer()
- timeline = model.TimelineModel()
-
- # Create a renderer process, with a main thread and impl thread.
- renderer = timeline.GetOrCreateProcess(pid=2)
- renderer_main = renderer.GetOrCreateThread(tid=21)
- renderer_compositor = renderer.GetOrCreateThread(tid=22)
-
- # Create 10 main and impl rendering stats events for Action A.
- renderer_main.BeginSlice('webkit.console', 'ActionA',
- timer.AdvanceAndGet(2, 4), '')
- for i in xrange(0, 10):
- first = (i == 0)
- AddImplThreadRenderingStats(timer, renderer_compositor, first, None)
- renderer_main.EndSlice(timer.AdvanceAndGet(2, 4))
- timer.Advance(2, 4)
-
- # Create 5 main and impl rendering stats events not within any action.
- for i in xrange(0, 5):
- first = (i == 0)
- AddImplThreadRenderingStats(timer, renderer_compositor, first, None)
-
- # Create Action B without any frames. This should trigger
- # NotEnoughFramesError when the RenderingStats object is created.
- renderer_main.BeginSlice('webkit.console', 'ActionB',
- timer.AdvanceAndGet(2, 4), '')
- renderer_main.EndSlice(timer.AdvanceAndGet(2, 4))
-
- renderer.FinalizeImport()
-
- timeline_markers = timeline.FindTimelineMarkers(['ActionA', 'ActionB'])
- timeline_ranges = [bounds.Bounds.CreateFromEvent(marker)
- for marker in timeline_markers]
-
- stats = rendering_stats.RenderingStats(
- renderer, None, None, timeline_ranges)
- self.assertEquals(0, len(stats.frame_timestamps[1]))
-
- def testFromTimeline(self):
- timeline = model.TimelineModel()
-
- # Create a browser process and a renderer process, and a main thread and
- # impl thread for each.
- browser = timeline.GetOrCreateProcess(pid=1)
- browser_compositor = browser.GetOrCreateThread(tid=12)
- renderer = timeline.GetOrCreateProcess(pid=2)
- renderer_main = renderer.GetOrCreateThread(tid=21)
- renderer_compositor = renderer.GetOrCreateThread(tid=22)
-
- timer = MockTimer()
- renderer_ref_stats = ReferenceRenderingStats()
- browser_ref_stats = ReferenceRenderingStats()
-
- # Create 10 main and impl rendering stats events for Action A.
- renderer_main.BeginSlice('webkit.console', 'ActionA',
- timer.AdvanceAndGet(2, 4), '')
- renderer_ref_stats.AppendNewRange()
- browser_ref_stats.AppendNewRange()
- for i in xrange(0, 10):
- first = (i == 0)
- AddImplThreadRenderingStats(
- timer, renderer_compositor, first, renderer_ref_stats)
- AddImplThreadRenderingStats(
- timer, browser_compositor, first, browser_ref_stats)
- renderer_main.EndSlice(timer.AdvanceAndGet(2, 4))
-
- # Create 5 main and impl rendering stats events not within any action.
- for i in xrange(0, 5):
- first = (i == 0)
- AddImplThreadRenderingStats(timer, renderer_compositor, first, None)
- AddImplThreadRenderingStats(timer, browser_compositor, first, None)
-
- # Create 10 main and impl rendering stats events for Action B.
- renderer_main.BeginSlice('webkit.console', 'ActionB',
- timer.AdvanceAndGet(2, 4), '')
- renderer_ref_stats.AppendNewRange()
- browser_ref_stats.AppendNewRange()
- for i in xrange(0, 10):
- first = (i == 0)
- AddImplThreadRenderingStats(
- timer, renderer_compositor, first, renderer_ref_stats)
- AddImplThreadRenderingStats(
- timer, browser_compositor, first, browser_ref_stats)
- renderer_main.EndSlice(timer.AdvanceAndGet(2, 4))
-
- # Create 10 main and impl rendering stats events for Action A.
- renderer_main.BeginSlice('webkit.console', 'ActionA',
- timer.AdvanceAndGet(2, 4), '')
- renderer_ref_stats.AppendNewRange()
- browser_ref_stats.AppendNewRange()
- for i in xrange(0, 10):
- first = (i == 0)
- AddImplThreadRenderingStats(
- timer, renderer_compositor, first, renderer_ref_stats)
- AddImplThreadRenderingStats(
- timer, browser_compositor, first, browser_ref_stats)
- renderer_main.EndSlice(timer.AdvanceAndGet(2, 4))
- timer.Advance(2, 4)
-
- browser.FinalizeImport()
- renderer.FinalizeImport()
-
- timeline_markers = timeline.FindTimelineMarkers(
- ['ActionA', 'ActionB', 'ActionA'])
- timeline_ranges = [bounds.Bounds.CreateFromEvent(marker)
- for marker in timeline_markers]
- stats = rendering_stats.RenderingStats(
- renderer, browser, None, timeline_ranges)
-
- # Compare rendering stats to reference.
- self.assertEquals(stats.frame_timestamps,
- browser_ref_stats.frame_timestamps)
- self.assertEquals(stats.frame_times, browser_ref_stats.frame_times)
- self.assertEquals(stats.approximated_pixel_percentages,
- renderer_ref_stats.approximated_pixel_percentages)
- self.assertEquals(stats.checkerboarded_pixel_percentages,
- renderer_ref_stats.checkerboarded_pixel_percentages)
-
- def testInputLatencyFromTimeline(self):
- timeline = model.TimelineModel()
-
- # Create a browser process and a renderer process.
- browser = timeline.GetOrCreateProcess(pid=1)
- browser_main = browser.GetOrCreateThread(tid=11)
- renderer = timeline.GetOrCreateProcess(pid=2)
- renderer_main = renderer.GetOrCreateThread(tid=21)
-
- timer = MockTimer()
- ref_latency = ReferenceInputLatencyStats()
-
- # Create 10 input latency stats events for Action A.
- renderer_main.BeginSlice('webkit.console', 'ActionA',
- timer.AdvanceAndGet(2, 4), '')
- for _ in xrange(0, 10):
- AddInputLatencyStats(timer, browser_main, renderer_main, ref_latency)
- renderer_main.EndSlice(timer.AdvanceAndGet(2, 4))
-
- # Create 5 input latency stats events not within any action.
- timer.Advance(2, 4)
- for _ in xrange(0, 5):
- AddInputLatencyStats(timer, browser_main, renderer_main, None)
-
- # Create 10 input latency stats events for Action B.
- renderer_main.BeginSlice('webkit.console', 'ActionB',
- timer.AdvanceAndGet(2, 4), '')
- for _ in xrange(0, 10):
- AddInputLatencyStats(timer, browser_main, renderer_main, ref_latency)
- renderer_main.EndSlice(timer.AdvanceAndGet(2, 4))
-
- # Create 10 input latency stats events for Action A.
- renderer_main.BeginSlice('webkit.console', 'ActionA',
- timer.AdvanceAndGet(2, 4), '')
- for _ in xrange(0, 10):
- AddInputLatencyStats(timer, browser_main, renderer_main, ref_latency)
- renderer_main.EndSlice(timer.AdvanceAndGet(2, 4))
-
- browser.FinalizeImport()
- renderer.FinalizeImport()
-
- latency_events = []
-
- timeline_markers = timeline.FindTimelineMarkers(
- ['ActionA', 'ActionB', 'ActionA'])
- timeline_ranges = [bounds.Bounds.CreateFromEvent(marker)
- for marker in timeline_markers]
- for timeline_range in timeline_ranges:
- if timeline_range.is_empty:
- continue
- latency_events.extend(rendering_stats.GetLatencyEvents(
- browser, timeline_range))
-
- self.assertEquals(latency_events, ref_latency.input_event)
- event_latency_result = rendering_stats.ComputeEventLatencies(latency_events)
- self.assertEquals(event_latency_result,
- ref_latency.input_event_latency)
-
- stats = rendering_stats.RenderingStats(
- renderer, browser, None, timeline_ranges)
- self.assertEquals(
- perf_tests_helper.FlattenList(stats.input_event_latency),
- [latency for name, latency in ref_latency.input_event_latency
- if name != rendering_stats.MAIN_THREAD_SCROLL_UPDATE_EVENT_NAME])
- self.assertEquals(
- perf_tests_helper.FlattenList(stats.main_thread_scroll_latency),
- [latency for name, latency in ref_latency.input_event_latency
- if name == rendering_stats.MAIN_THREAD_SCROLL_UPDATE_EVENT_NAME])
- self.assertEquals(
- perf_tests_helper.FlattenList(stats.gesture_scroll_update_latency),
- [latency for name, latency in ref_latency.input_event_latency
- if name == rendering_stats.GESTURE_SCROLL_UPDATE_EVENT_NAME])

Powered by Google App Engine
This is Rietveld 408576698