timeline_unittest.py revision a02191e04bc25c4935f804f2c080ae28663d096d
1# Copyright 2013 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import unittest
6
7from metrics import test_page_measurement_results
8from metrics import timeline
9from telemetry.core.timeline import model as model_module
10from telemetry.web_perf import timeline_interaction_record as tir_module
11
12def _GetInteractionRecord(start, end):
13  return tir_module.TimelineInteractionRecord("test-record",
14                                                               start, end)
15
16
17
18class LoadTimesTimelineMetric(unittest.TestCase):
19  def GetResults(self, metric, model, renderer_thread, interaction_record):
20    results = test_page_measurement_results.TestPageMeasurementResults(self)
21    metric.AddResults(model, renderer_thread, interaction_record, results)
22    return results
23
24  def testSanitizing(self):
25    model = model_module.TimelineModel()
26    renderer_main = model.GetOrCreateProcess(1).GetOrCreateThread(2)
27    renderer_main.name = 'CrRendererMain'
28
29    # [      X       ]
30    #      [  Y  ]
31    renderer_main.BeginSlice('cat1', 'x.y', 10, 0)
32    renderer_main.EndSlice(20, 20)
33    model.FinalizeImport()
34
35    metric = timeline.LoadTimesTimelineMetric()
36    results = self.GetResults(
37      metric, model=model, renderer_thread=renderer_main,
38      interaction_record=_GetInteractionRecord(0, float('inf')))
39    results.AssertHasPageSpecificScalarValue(
40      'CrRendererMain|x_y', 'ms', 10)
41    results.AssertHasPageSpecificScalarValue(
42      'CrRendererMain|x_y_max', 'ms', 10)
43    results.AssertHasPageSpecificScalarValue(
44      'CrRendererMain|x_y_avg', 'ms', 10)
45
46  def testTimelineBetweenRange(self):
47    model = model_module.TimelineModel()
48    renderer_main = model.GetOrCreateProcess(1).GetOrCreateThread(2)
49    renderer_main.name = 'CrRendererMain'
50
51    #   [          X         ]    [       Z      ]
52    #           [  Y  ]               [   T    ]
53    #   [ interaction record ]
54    renderer_main.BeginSlice('cat1', 'x.y', 10, 0)
55    renderer_main.EndSlice(20, 20)
56    renderer_main.BeginSlice('cat1', 'z.t', 30, 0)
57    renderer_main.EndSlice(35, 35)
58    model.FinalizeImport()
59
60    metric = timeline.LoadTimesTimelineMetric()
61    results = self.GetResults(metric, model=model,
62                              renderer_thread=renderer_main,
63                              interaction_record=_GetInteractionRecord(10, 20))
64    results.AssertHasPageSpecificScalarValue(
65      'CrRendererMain|x_y', 'ms', 10)
66    results.AssertHasPageSpecificScalarValue(
67      'CrRendererMain|x_y_max', 'ms', 10)
68    results.AssertHasPageSpecificScalarValue(
69      'CrRendererMain|x_y_avg', 'ms', 10)
70
71
72  def testCounterSanitizing(self):
73    model = model_module.TimelineModel()
74    renderer_main = model.GetOrCreateProcess(1).GetOrCreateThread(2)
75    renderer_main.name = 'CrRendererMain'
76
77    x_counter = renderer_main.parent.GetOrCreateCounter('cat', 'x.y')
78    x_counter.samples += [1, 2]
79    x_counter.series_names += ['a']
80    x_counter.timestamps += [0, 1]
81    model.FinalizeImport()
82
83    metric = timeline.LoadTimesTimelineMetric()
84    results = self.GetResults(
85      metric, model=model, renderer_thread=renderer_main,
86      interaction_record=_GetInteractionRecord(0, float('inf')))
87    results.AssertHasPageSpecificScalarValue(
88      'cat_x_y', 'count', 3)
89    results.AssertHasPageSpecificScalarValue(
90      'cat_x_y_avg', 'count', 1.5)
91
92
93class ThreadTimesTimelineMetricUnittest(unittest.TestCase):
94  def GetResults(self, metric, model, renderer_thread, interaction_record):
95    results = test_page_measurement_results.TestPageMeasurementResults(self)
96    metric.AddResults(model, renderer_thread, interaction_record,
97                                results)
98    return results
99
100  def testResults(self):
101    model = model_module.TimelineModel()
102    renderer_main = model.GetOrCreateProcess(1).GetOrCreateThread(2)
103    renderer_main.name = 'CrRendererMain'
104
105    metric = timeline.ThreadTimesTimelineMetric()
106    metric.details_to_report = timeline.ReportMainThreadOnly
107    results = self.GetResults(metric, model, renderer_main.parent,
108                              _GetInteractionRecord(1,2))
109
110    # Test that all result thread categories exist
111    for name in timeline.TimelineThreadCategories.values():
112      results.GetPageSpecificValueNamed(timeline.ThreadCpuTimeResultName(name))
113
114  def testBasic(self):
115    model = model_module.TimelineModel()
116    renderer_main = model.GetOrCreateProcess(1).GetOrCreateThread(2)
117    renderer_main.name = 'CrRendererMain'
118
119    # Create two frame swaps (Results times should be divided by two)
120    cc_main = model.GetOrCreateProcess(1).GetOrCreateThread(3)
121    cc_main.name = 'Compositor'
122    cc_main.BeginSlice('cc_cat', timeline.FrameTraceName, 10, 10)
123    cc_main.EndSlice(11, 11)
124    cc_main.BeginSlice('cc_cat', timeline.FrameTraceName, 12, 12)
125    cc_main.EndSlice(13, 13)
126
127    # [      X       ]   [ Z ]
128    #      [  Y  ]
129    renderer_main.BeginSlice('cat1', 'X', 10, 0)
130    renderer_main.BeginSlice('cat2', 'Y', 15, 5)
131    renderer_main.EndSlice(16, 5.5)
132    renderer_main.EndSlice(30, 19.5)
133    renderer_main.BeginSlice('cat1', 'Z', 31, 20)
134    renderer_main.BeginSlice('cat1', 'Z', 33, 21)
135    model.FinalizeImport()
136
137    # Exclude 'Z' using an action-range.
138    metric = timeline.ThreadTimesTimelineMetric()
139    metric.details_to_report = timeline.ReportMainThreadOnly
140    results = self.GetResults(metric, model, renderer_main.parent,
141                              _GetInteractionRecord(10, 30))
142
143
144    # Test a couple specific results.
145    assert_results = {
146      timeline.ThreadCpuTimeResultName('renderer_main') : 9.75,
147      timeline.ThreadDetailResultName('renderer_main','cat1') : 9.5,
148      timeline.ThreadDetailResultName('renderer_main','cat2') : 0.5,
149      timeline.ThreadDetailResultName('renderer_main','idle') : 0
150    }
151    for name, value in assert_results.iteritems():
152      results.AssertHasPageSpecificScalarValue(name, 'ms', value)
153
154  def testOverheadIsRemoved(self):
155    model = model_module.TimelineModel()
156    renderer_main = model.GetOrCreateProcess(1).GetOrCreateThread(2)
157    renderer_main.name = 'CrRendererMain'
158
159    # Create one frame swap.
160    cc_main = model.GetOrCreateProcess(1).GetOrCreateThread(3)
161    cc_main.name = 'Compositor'
162    cc_main.BeginSlice('cc_cat', timeline.FrameTraceName, 10, 10)
163    cc_main.EndSlice(11, 11)
164
165    # [      X       ]
166    #    [Overhead]
167    overhead_category = timeline.OverheadTraceCategory
168    overhead_name = timeline.OverheadTraceName
169    renderer_main.BeginSlice('cat1', 'X', 10, 0)
170    renderer_main.BeginSlice(overhead_category, overhead_name, 15, 5)
171    renderer_main.EndSlice(16, 6)
172    renderer_main.EndSlice(30, 10)
173    model.FinalizeImport()
174
175    # Include everything in an action-range.
176    metric = timeline.ThreadTimesTimelineMetric()
177    metric.details_to_report = timeline.ReportMainThreadOnly
178    results = self.GetResults(metric, model, renderer_main.parent,
179                              _GetInteractionRecord(10, 30))
180
181    # Test a couple specific results.
182    assert_results = {
183      timeline.ThreadCpuTimeResultName('renderer_main') : 9.0,
184    }
185    for name, value in assert_results.iteritems():
186      results.AssertHasPageSpecificScalarValue(name, 'ms', value)
187