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.
6 from telemetry
.core
import exceptions
7 from telemetry
.core
import wpr_modes
8 from telemetry
import decorators
9 from telemetry
.page
import page
10 from telemetry
.unittest_util
import options_for_unittests
11 from telemetry
.unittest_util
import page_test_test_case
13 from measurements
import smoothness
14 from metrics
import power
17 class FakeTracingController(object):
19 self
.category_filter
= None
20 def Start(self
, _options
, category_filter
, _timeout
):
21 self
.category_filter
= category_filter
23 class FakePlatform(object):
25 self
.tracing_controller
= FakeTracingController()
26 def CanMonitorPower(self
):
30 class FakeBrowser(object):
32 self
.platform
= FakePlatform()
35 class AnimatedPage(page
.Page
):
36 def __init__(self
, page_set
):
37 super(AnimatedPage
, self
).__init
__(
38 url
='file://animated_page.html',
39 page_set
=page_set
, base_dir
=page_set
.base_dir
)
41 def RunPageInteractions(self
, action_runner
):
42 action_runner
.Wait(.2)
45 class FakeTab(object):
47 self
.browser
= FakeBrowser()
49 def ExecuteJavaScript(self
, js
):
52 class SmoothnessUnitTest(page_test_test_case
.PageTestTestCase
):
53 """Smoke test for smoothness measurement
55 Runs smoothness measurement on a simple page and verifies
56 that all metrics were added to the results. The test is purely functional,
57 i.e. it only checks if the metrics are present and non-zero.
59 def testSyntheticDelayConfiguration(self
):
60 test_page
= page
.Page('http://dummy', None)
61 test_page
.synthetic_delays
= {
62 'cc.BeginMainFrame': { 'target_duration': 0.012 },
63 'cc.DrawAndSwap': { 'target_duration': 0.012, 'mode': 'alternating' },
64 'gpu.PresentingFrame': { 'target_duration': 0.012 }
68 measurement
= smoothness
.Smoothness()
69 measurement
.WillStartBrowser(tab
.browser
.platform
)
70 measurement
.WillNavigateToPage(test_page
, tab
)
71 measurement
.WillRunActions(test_page
, tab
)
73 expected_category_filter
= set([
74 'DELAY(cc.BeginMainFrame;0.012000;static)',
75 'DELAY(cc.DrawAndSwap;0.012000;alternating)',
76 'DELAY(gpu.PresentingFrame;0.012000;static)',
79 tracing_controller
= tab
.browser
.platform
.tracing_controller
80 actual_category_filter
= (
81 tracing_controller
.category_filter
.included_categories
)
83 # FIXME: Put blink.console into the expected above and remove these two
84 # remove entries when the blink.console change has rolled into chromium.
85 actual_category_filter
.remove('webkit.console')
86 actual_category_filter
.remove('blink.console')
88 if expected_category_filter
!= actual_category_filter
:
89 sys
.stderr
.write("Expected category filter: %s\n" %
90 repr(expected_category_filter
))
91 sys
.stderr
.write("Actual category filter filter: %s\n" %
92 repr(actual_category_filter
))
93 self
.assertEquals(expected_category_filter
, actual_category_filter
)
96 self
._options
= options_for_unittests
.GetCopy()
97 self
._options
.browser_options
.wpr_mode
= wpr_modes
.WPR_OFF
99 def testSmoothness(self
):
100 ps
= self
.CreatePageSetFromFileInUnittestDataDir('scrollable_page.html')
101 measurement
= smoothness
.Smoothness()
102 results
= self
.RunMeasurement(measurement
, ps
, options
=self
._options
)
103 self
.assertEquals(0, len(results
.failures
))
105 frame_times
= results
.FindAllPageSpecificValuesNamed('frame_times')
106 self
.assertEquals(len(frame_times
), 1)
107 self
.assertGreater(frame_times
[0].GetRepresentativeNumber(), 0)
109 mean_frame_time
= results
.FindAllPageSpecificValuesNamed('mean_frame_time')
110 self
.assertEquals(len(mean_frame_time
), 1)
111 self
.assertGreater(mean_frame_time
[0].GetRepresentativeNumber(), 0)
113 frame_time_discrepancy
= results
.FindAllPageSpecificValuesNamed(
114 'frame_time_discrepancy')
115 self
.assertEquals(len(frame_time_discrepancy
), 1)
116 self
.assertGreater(frame_time_discrepancy
[0].GetRepresentativeNumber(), 0)
118 percentage_smooth
= results
.FindAllPageSpecificValuesNamed(
120 self
.assertEquals(len(percentage_smooth
), 1)
121 self
.assertGreaterEqual(percentage_smooth
[0].GetRepresentativeNumber(), 0)
123 mean_input_event_latency
= results
.FindAllPageSpecificValuesNamed(
124 'mean_input_event_latency')
125 if mean_input_event_latency
:
126 self
.assertEquals(len(mean_input_event_latency
), 1)
128 mean_input_event_latency
[0].GetRepresentativeNumber(), 0)
130 @decorators.Enabled('android') # SurfaceFlinger is android-only
131 def testSmoothnessSurfaceFlingerMetricsCalculated(self
):
132 ps
= self
.CreatePageSetFromFileInUnittestDataDir('scrollable_page.html')
133 measurement
= smoothness
.Smoothness()
134 results
= self
.RunMeasurement(measurement
, ps
, options
=self
._options
)
135 self
.assertEquals(0, len(results
.failures
))
137 avg_surface_fps
= results
.FindAllPageSpecificValuesNamed('avg_surface_fps')
138 self
.assertEquals(1, len(avg_surface_fps
))
139 self
.assertGreater(avg_surface_fps
[0].GetRepresentativeNumber
, 0)
141 jank_count
= results
.FindAllPageSpecificValuesNamed('jank_count')
142 self
.assertEquals(1, len(jank_count
))
143 self
.assertGreater(jank_count
[0].GetRepresentativeNumber(), -1)
145 max_frame_delay
= results
.FindAllPageSpecificValuesNamed('max_frame_delay')
146 self
.assertEquals(1, len(max_frame_delay
))
147 self
.assertGreater(max_frame_delay
[0].GetRepresentativeNumber
, 0)
149 frame_lengths
= results
.FindAllPageSpecificValuesNamed('frame_lengths')
150 self
.assertEquals(1, len(frame_lengths
))
151 self
.assertGreater(frame_lengths
[0].GetRepresentativeNumber
, 0)
153 @decorators.Disabled('mac', 'chromeos') # http://crbug.com/403903
154 def testSmoothnessForPageWithNoGesture(self
):
155 ps
= self
.CreateEmptyPageSet()
156 ps
.AddUserStory(AnimatedPage(ps
))
158 measurement
= smoothness
.Smoothness()
159 results
= self
.RunMeasurement(measurement
, ps
, options
=self
._options
)
160 self
.assertEquals(0, len(results
.failures
))
162 percentage_smooth
= results
.FindAllPageSpecificValuesNamed(
164 self
.assertEquals(len(percentage_smooth
), 1)
165 self
.assertGreaterEqual(percentage_smooth
[0].GetRepresentativeNumber(), 0)
167 def testCleanUpTrace(self
):
168 self
.TestTracingCleanedUp(smoothness
.Smoothness
, self
._options
)
170 def testCleanUpPowerMetric(self
):
171 class FailPage(page
.Page
):
172 def __init__(self
, page_set
):
173 # pylint: disable=bad-super-call
174 super(FailPage
, self
).__init
__(
175 url
='file://blank.html',
176 page_set
=page_set
, base_dir
=page_set
.base_dir
)
177 def RunPageInteractions(self
, _
):
178 raise exceptions
.IntentionalException
180 class FakePowerMetric(power
.PowerMetric
):
183 def Start(self
, _1
, _2
):
184 self
.start_called
= True
185 def Stop(self
, _1
, _2
):
186 self
.stop_called
= True
188 ps
= self
.CreateEmptyPageSet()
189 ps
.AddUserStory(FailPage(ps
))
191 class BuggyMeasurement(smoothness
.Smoothness
):
193 # Inject fake power metric.
194 def WillStartBrowser(self
, platform
):
195 self
.fake_power
= self
._power
_metric
= FakePowerMetric(platform
)
197 measurement
= BuggyMeasurement()
199 self
.RunMeasurement(measurement
, ps
)
200 except exceptions
.IntentionalException
:
203 self
.assertTrue(measurement
.fake_power
.start_called
)
204 self
.assertTrue(measurement
.fake_power
.stop_called
)