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.
7 from telemetry
.testing
import test_page_test_results
8 from telemetry
.timeline
import model
as model_module
9 from telemetry
.web_perf
import timeline_interaction_record
as tir_module
11 from metrics
import timeline
14 def _GetInteractionRecord(start
, end
):
15 return tir_module
.TimelineInteractionRecord("test-record", start
, end
)
18 class LoadTimesTimelineMetric(unittest
.TestCase
):
19 def GetResults(self
, metric
, model
, renderer_thread
, interaction_records
):
20 results
= test_page_test_results
.TestPageTestResults(self
)
21 metric
.AddResults(model
, renderer_thread
, interaction_records
, results
)
24 def testSanitizing(self
):
25 model
= model_module
.TimelineModel()
26 renderer_main
= model
.GetOrCreateProcess(1).GetOrCreateThread(2)
27 renderer_main
.name
= 'CrRendererMain'
31 renderer_main
.BeginSlice('cat1', 'x.y', 10, 0)
32 renderer_main
.EndSlice(20, 20)
33 model
.FinalizeImport()
35 metric
= timeline
.LoadTimesTimelineMetric()
36 results
= self
.GetResults(
37 metric
, model
=model
, renderer_thread
=renderer_main
,
38 interaction_records
=[_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)
46 def testTimelineBetweenRange(self
):
47 model
= model_module
.TimelineModel()
48 renderer_main
= model
.GetOrCreateProcess(1).GetOrCreateThread(2)
49 renderer_main
.name
= 'CrRendererMain'
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()
60 metric
= timeline
.LoadTimesTimelineMetric()
61 results
= self
.GetResults(
62 metric
, model
=model
, renderer_thread
=renderer_main
,
63 interaction_records
=[_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)
72 def testCounterSanitizing(self
):
73 model
= model_module
.TimelineModel()
74 renderer_main
= model
.GetOrCreateProcess(1).GetOrCreateThread(2)
75 renderer_main
.name
= 'CrRendererMain'
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()
83 metric
= timeline
.LoadTimesTimelineMetric()
84 results
= self
.GetResults(
85 metric
, model
=model
, renderer_thread
=renderer_main
,
86 interaction_records
=[_GetInteractionRecord(0, float('inf'))])
87 results
.AssertHasPageSpecificScalarValue(
88 'cat_x_y', 'count', 3)
89 results
.AssertHasPageSpecificScalarValue(
90 'cat_x_y_avg', 'count', 1.5)
93 class ThreadTimesTimelineMetricUnittest(unittest
.TestCase
):
94 def GetResults(self
, metric
, model
, renderer_thread
, interaction_record
):
95 results
= test_page_test_results
.TestPageTestResults(self
)
96 metric
.AddResults(model
, renderer_thread
, interaction_record
,
100 def testResults(self
):
101 model
= model_module
.TimelineModel()
102 renderer_main
= model
.GetOrCreateProcess(1).GetOrCreateThread(2)
103 renderer_main
.name
= 'CrRendererMain'
105 metric
= timeline
.ThreadTimesTimelineMetric()
106 metric
.details_to_report
= timeline
.ReportMainThreadOnly
107 results
= self
.GetResults(metric
, model
, renderer_main
.parent
,
108 [_GetInteractionRecord(1,2)])
110 # Test that all result thread categories exist
111 for name
in timeline
.TimelineThreadCategories
.values():
112 results
.GetPageSpecificValueNamed(
113 timeline
.ThreadCpuTimeResultName(name
, 'frame'))
116 model
= model_module
.TimelineModel()
117 renderer_main
= model
.GetOrCreateProcess(1).GetOrCreateThread(2)
118 renderer_main
.name
= 'CrRendererMain'
120 # Create two frame swaps (Results times should be divided by two) for
121 # an interaction that lasts 20 milliseconds.
122 cc_main
= model
.GetOrCreateProcess(1).GetOrCreateThread(3)
123 cc_main
.name
= 'Compositor'
124 cc_main
.BeginSlice('cc_cat', timeline
.FrameTraceName
, 10, 10)
125 cc_main
.EndSlice(11, 11)
126 cc_main
.BeginSlice('cc_cat', timeline
.FrameTraceName
, 12, 12)
127 cc_main
.EndSlice(13, 13)
131 renderer_main
.BeginSlice('cat1', 'X', 10, 0)
132 renderer_main
.BeginSlice('cat2', 'Y', 15, 5)
133 renderer_main
.EndSlice(16, 5.5)
134 renderer_main
.EndSlice(30, 19.5)
135 renderer_main
.BeginSlice('cat1', 'Z', 31, 20)
136 renderer_main
.BeginSlice('cat1', 'Z', 33, 21)
137 model
.FinalizeImport()
139 # Exclude 'Z' using an action-range.
140 metric
= timeline
.ThreadTimesTimelineMetric()
141 metric
.details_to_report
= timeline
.ReportMainThreadOnly
142 results
= self
.GetResults(metric
, model
, renderer_main
.parent
,
143 [_GetInteractionRecord(10, 30)])
145 # Test for the results we expect.
146 main_thread
= "renderer_main"
147 cc_thread
= 'renderer_compositor'
149 (timeline
.ThreadMeanFrameTimeResultName(cc_thread
), 'ms', 10.0),
150 (timeline
.ThreadTasksResultName(main_thread
, 'frame'), 'tasks', 0.5),
151 (timeline
.ThreadTasksResultName(main_thread
, 'second'), 'tasks', 50.0),
152 (timeline
.ThreadTasksResultName(cc_thread
, 'frame'), 'tasks', 1.0),
153 (timeline
.ThreadTasksResultName(cc_thread
, 'second'), 'tasks', 100.0),
154 (timeline
.ThreadCpuTimeResultName(main_thread
, 'frame'), 'ms', 9.75),
155 (timeline
.ThreadCpuTimeResultName(main_thread
, 'second'), '%', 97.5),
156 (timeline
.ThreadCpuTimeResultName(cc_thread
, 'frame'), 'ms', 1.0),
157 (timeline
.ThreadCpuTimeResultName(cc_thread
, 'second'), '%', 10.0),
158 (timeline
.ThreadDetailResultName(main_thread
, 'frame', 'cat1'),
160 (timeline
.ThreadDetailResultName(main_thread
, 'second', 'cat1'),
162 (timeline
.ThreadDetailResultName(main_thread
, 'frame', 'cat2'),
164 (timeline
.ThreadDetailResultName(main_thread
, 'second', 'cat2'),
166 (timeline
.ThreadDetailResultName(main_thread
, 'frame', 'idle'), 'ms', 0),
167 (timeline
.ThreadDetailResultName(main_thread
, 'second', 'idle'), '%', 0)
169 for name
, unit
, value
in assert_results
:
170 results
.AssertHasPageSpecificScalarValue(name
, unit
, value
)
172 def testOverheadIsRemoved(self
):
173 model
= model_module
.TimelineModel()
174 renderer_main
= model
.GetOrCreateProcess(1).GetOrCreateThread(2)
175 renderer_main
.name
= 'CrRendererMain'
177 # Create one frame swap.
178 cc_main
= model
.GetOrCreateProcess(1).GetOrCreateThread(3)
179 cc_main
.name
= 'Compositor'
180 cc_main
.BeginSlice('cc_cat', timeline
.FrameTraceName
, 10, 10)
181 cc_main
.EndSlice(11, 11)
185 overhead_category
= timeline
.OverheadTraceCategory
186 overhead_name
= timeline
.OverheadTraceName
187 renderer_main
.BeginSlice('cat1', 'X', 10, 0)
188 renderer_main
.BeginSlice(overhead_category
, overhead_name
, 15, 5)
189 renderer_main
.EndSlice(16, 6)
190 renderer_main
.EndSlice(30, 10)
191 model
.FinalizeImport()
193 # Include everything in an action-range.
194 metric
= timeline
.ThreadTimesTimelineMetric()
195 metric
.details_to_report
= timeline
.ReportMainThreadOnly
196 results
= self
.GetResults(metric
, model
, renderer_main
.parent
,
197 [_GetInteractionRecord(10, 30)])
199 # Test a couple specific results.
201 (timeline
.ThreadCpuTimeResultName('renderer_main', 'frame') , 'ms', 9.0),
202 (timeline
.ThreadCpuTimeResultName('renderer_main', 'second') , '%', 45.0),
204 for name
, unit
, value
in assert_results
:
205 results
.AssertHasPageSpecificScalarValue(name
, unit
, value
)