| Index: tools/perf/metrics/rendering_stats_unittest.py
|
| diff --git a/tools/perf/metrics/rendering_stats_unittest.py b/tools/perf/metrics/rendering_stats_unittest.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..ec18597b8ce059b7e527be493b62c15cc01aae9c
|
| --- /dev/null
|
| +++ b/tools/perf/metrics/rendering_stats_unittest.py
|
| @@ -0,0 +1,192 @@
|
| +# 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 random
|
| +import unittest
|
| +
|
| +from metrics.rendering_stats import RenderingStats
|
| +from telemetry.core.timeline import model
|
| +
|
| +
|
| +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 Get(self):
|
| + return self.milliseconds
|
| +
|
| + def Advance(self, low=0, high=1):
|
| + delta = random.uniform(low, high)
|
| + self.milliseconds += delta
|
| + return delta
|
| +
|
| +
|
| +class ReferenceRenderingStats(object):
|
| + """ Stores expected data for comparison with actual RenderingStats """
|
| + def __init__(self):
|
| + self.frame_timestamps = []
|
| + self.frame_times = []
|
| + self.paint_time = []
|
| + self.painted_pixel_count = []
|
| + self.record_time = []
|
| + self.recorded_pixel_count = []
|
| + self.rasterize_time = []
|
| + self.rasterized_pixel_count = []
|
| +
|
| +
|
| +def AddMainThreadRenderingStats(mock_timer, thread, first_frame,
|
| + ref_stats = None):
|
| + """ Adds a random main 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 main thread rendering stats.
|
| + data = { 'frame_count': 0,
|
| + 'paint_time': 0.0,
|
| + 'painted_pixel_count': 0,
|
| + 'record_time': mock_timer.Advance(2, 4) / 1000.0,
|
| + 'recorded_pixel_count': 3000*3000 }
|
| + timestamp = mock_timer.Get()
|
| +
|
| + # Add a slice with the event data to the given thread.
|
| + thread.PushCompleteSlice(
|
| + 'benchmark', 'BenchmarkInstrumentation::MainThreadRenderingStats',
|
| + timestamp, 0.0, {'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]
|
| + ref_stats.frame_times.append(round(timestamp - prev_timestamp, 2))
|
| + ref_stats.frame_timestamps.append(timestamp)
|
| +
|
| + ref_stats.paint_time.append(data['paint_time'] * 1000.0)
|
| + ref_stats.painted_pixel_count.append(data['painted_pixel_count'])
|
| + ref_stats.record_time.append(data['record_time'] * 1000.0)
|
| + ref_stats.recorded_pixel_count.append(data['recorded_pixel_count'])
|
| +
|
| +
|
| +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,
|
| + 'rasterize_time': mock_timer.Advance(5, 10) / 1000.0,
|
| + 'rasterized_pixel_count': 1280*720 }
|
| + timestamp = mock_timer.Get()
|
| +
|
| + # Add a slice with the event data to the given thread.
|
| + thread.PushCompleteSlice(
|
| + 'benchmark', 'BenchmarkInstrumentation::ImplThreadRenderingStats',
|
| + timestamp, 0.0, {'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]
|
| + ref_stats.frame_times.append(round(timestamp - prev_timestamp, 2))
|
| + ref_stats.frame_timestamps.append(timestamp)
|
| +
|
| + ref_stats.rasterize_time.append(data['rasterize_time'] * 1000.0)
|
| + ref_stats.rasterized_pixel_count.append(data['rasterized_pixel_count'])
|
| +
|
| +
|
| +class RenderingStatsUnitTest(unittest.TestCase):
|
| + 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_main = browser.GetOrCreateThread(tid = 11)
|
| + 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()
|
| + ref_stats = ReferenceRenderingStats()
|
| +
|
| + # Create 10 main and impl rendering stats events for Action A.
|
| + timer.Advance()
|
| + renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '')
|
| + for i in xrange(0, 10):
|
| + first = (i == 0)
|
| + AddMainThreadRenderingStats(timer, renderer_main, first, ref_stats)
|
| + AddImplThreadRenderingStats(timer, renderer_compositor, first, ref_stats)
|
| + AddMainThreadRenderingStats(timer, browser_main, first, None)
|
| + AddImplThreadRenderingStats(timer, browser_compositor, first, None)
|
| + renderer_main.EndSlice(timer.Get())
|
| +
|
| + # Create 5 main and impl rendering stats events not within any action.
|
| + for i in xrange(0, 5):
|
| + first = (i == 0)
|
| + AddMainThreadRenderingStats(timer, renderer_main, first, None)
|
| + AddImplThreadRenderingStats(timer, renderer_compositor, first, None)
|
| + AddMainThreadRenderingStats(timer, browser_main, first, None)
|
| + AddImplThreadRenderingStats(timer, browser_compositor, first, None)
|
| +
|
| + # Create 10 main and impl rendering stats events for Action B.
|
| + timer.Advance()
|
| + renderer_main.BeginSlice('webkit.console', 'ActionB', timer.Get(), '')
|
| + for i in xrange(0, 10):
|
| + first = (i == 0)
|
| + AddMainThreadRenderingStats(timer, renderer_main, first, ref_stats)
|
| + AddImplThreadRenderingStats(timer, renderer_compositor, first, ref_stats)
|
| + AddMainThreadRenderingStats(timer, browser_main, first, None)
|
| + AddImplThreadRenderingStats(timer, browser_compositor, first, None)
|
| + renderer_main.EndSlice(timer.Get())
|
| +
|
| + # Create 10 main and impl rendering stats events for Action A.
|
| + timer.Advance()
|
| + renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '')
|
| + for i in xrange(0, 10):
|
| + first = (i == 0)
|
| + AddMainThreadRenderingStats(timer, renderer_main, first, ref_stats)
|
| + AddImplThreadRenderingStats(timer, renderer_compositor, first, ref_stats)
|
| + AddMainThreadRenderingStats(timer, browser_main, first, None)
|
| + AddImplThreadRenderingStats(timer, browser_compositor, first, None)
|
| + renderer_main.EndSlice(timer.Get())
|
| +
|
| + renderer_main.FinalizeImport()
|
| + renderer_compositor.FinalizeImport()
|
| +
|
| + timeline_markers = timeline.FindTimelineMarkers(
|
| + ['ActionA', 'ActionB', 'ActionA'])
|
| + stats = RenderingStats(renderer, timeline_markers)
|
| +
|
| + # Compare rendering stats to reference.
|
| + self.assertEquals(stats.frame_timestamps, ref_stats.frame_timestamps)
|
| + self.assertEquals(stats.frame_times, ref_stats.frame_times)
|
| + self.assertEquals(stats.rasterize_time, ref_stats.rasterize_time)
|
| + self.assertEquals(stats.rasterized_pixel_count,
|
| + ref_stats.rasterized_pixel_count)
|
| + self.assertEquals(stats.paint_time, ref_stats.paint_time)
|
| + self.assertEquals(stats.painted_pixel_count, ref_stats.painted_pixel_count)
|
| + self.assertEquals(stats.record_time, ref_stats.record_time)
|
| + self.assertEquals(stats.recorded_pixel_count,
|
| + ref_stats.recorded_pixel_count)
|
|
|