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
.core
import browser_options
8 from telemetry
.page
import page_runner
9 from telemetry
.results
import page_test_results
10 from telemetry
.unittest
import simple_mock
12 from measurements
import page_cycler
15 # Allow testing protected members in the unit test.
16 # pylint: disable=W0212
18 class MockMemoryMetric(object):
19 """Used instead of simple_mock.MockObject so that the precise order and
20 number of calls need not be specified."""
24 def Start(self
, page
, tab
):
27 def Stop(self
, page
, tab
):
30 def AddResults(self
, tab
, results
):
33 def AddSummaryResults(self
, tab
, results
):
37 class FakePage(object):
38 """Used to mock loading a page."""
39 def __init__(self
, url
):
41 self
.is_file
= url
.startswith('file://')
44 class FakeTab(object):
45 """Used to mock a browser tab."""
47 self
.clear_cache_calls
= 0
48 self
.navigated_urls
= []
49 def ClearCache(self
, force
=False):
51 self
.clear_cache_calls
+= 1
52 def EvaluateJavaScript(self
, _
):
54 def Navigate(self
, url
):
55 self
.navigated_urls
.append(url
)
56 def WaitForJavaScriptExpression(self
, _
, __
):
62 class FakeBrowser(object):
67 FakeBrowser
._iteration
+= 1
69 'Browser': {'CpuProcessTime': FakeBrowser
._iteration
,
70 'TotalTime': FakeBrowser
._iteration
* 2},
71 'Renderer': {'CpuProcessTime': FakeBrowser
._iteration
,
72 'TotalTime': FakeBrowser
._iteration
* 3},
73 'Gpu': {'CpuProcessTime': FakeBrowser
._iteration
,
74 'TotalTime': FakeBrowser
._iteration
* 4}
81 def http_server(self
):
82 class FakeHttpServer(object):
83 def UrlOf(self
, url_path
):
84 return 'http://fakeserver:99999/%s' % url_path
85 return FakeHttpServer()
88 class FakePlatform(object):
91 def CanMonitorPower(self
):
95 class PageCyclerUnitTest(unittest
.TestCase
):
97 def SetUpCycler(self
, args
, setup_memory_module
=False):
98 cycler
= page_cycler
.PageCycler()
99 options
= browser_options
.BrowserFinderOptions()
100 options
.browser_options
.platform
= FakePlatform()
101 parser
= options
.CreateParser()
102 page_runner
.AddCommandLineArgs(parser
)
103 cycler
.AddCommandLineArgs(parser
)
104 cycler
.SetArgumentDefaults(parser
)
105 parser
.parse_args(args
)
106 page_runner
.ProcessCommandLineArgs(parser
, options
)
107 cycler
.ProcessCommandLineArgs(parser
, options
)
108 cycler
.CustomizeBrowserOptions(options
.browser_options
)
110 if setup_memory_module
:
111 # Mock out memory metrics; the real ones require a real browser.
112 mock_memory_metric
= MockMemoryMetric()
114 mock_memory_module
= simple_mock
.MockObject()
115 mock_memory_module
.ExpectCall(
116 'MemoryMetric').WithArgs(simple_mock
.DONT_CARE
).WillReturn(
119 real_memory_module
= page_cycler
.memory
121 page_cycler
.memory
= mock_memory_module
122 browser
= FakeBrowser()
123 cycler
.WillStartBrowser(options
.browser_options
.platform
)
124 cycler
.DidStartBrowser(browser
)
126 page_cycler
.memory
= real_memory_module
130 def testOptionsColdLoadNoArgs(self
):
131 cycler
= self
.SetUpCycler([])
133 self
.assertEquals(cycler
._cold
_run
_start
_index
, 5)
135 def testOptionsColdLoadPagesetRepeat(self
):
136 cycler
= self
.SetUpCycler(['--pageset-repeat=20', '--page-repeat=2'])
138 self
.assertEquals(cycler
._cold
_run
_start
_index
, 20)
140 def testOptionsColdLoadRequested(self
):
141 cycler
= self
.SetUpCycler(['--pageset-repeat=21', '--page-repeat=2',
142 '--cold-load-percent=40'])
144 self
.assertEquals(cycler
._cold
_run
_start
_index
, 26)
146 def testCacheHandled(self
):
147 cycler
= self
.SetUpCycler(['--pageset-repeat=5',
148 '--cold-load-percent=50'],
151 url_name
= 'http://fakepage.com'
152 page
= FakePage(url_name
)
156 results
= page_test_results
.PageTestResults()
157 results
.WillRunPage(page
)
158 cycler
.WillNavigateToPage(page
, tab
)
159 self
.assertEqual(max(0, i
- 2), tab
.clear_cache_calls
,
160 'Iteration %d tab.clear_cache_calls %d' %
161 (i
, tab
.clear_cache_calls
))
162 cycler
.ValidateAndMeasurePage(page
, tab
, results
)
163 results
.DidRunPage(page
)
165 values
= results
.all_page_specific_values
166 self
.assertGreater(len(values
), 2)
168 self
.assertEqual(values
[0].page
, page
)
169 chart_name
= 'cold_times' if i
== 0 or i
> 2 else 'warm_times'
170 self
.assertEqual(values
[0].name
, '%s.page_load_time' % chart_name
)
171 self
.assertEqual(values
[0].units
, 'ms')
173 cycler
.DidNavigateToPage(page
, tab
)
175 def testColdWarm(self
):
176 cycler
= self
.SetUpCycler(['--pageset-repeat=3'], True)
177 pages
= [FakePage('http://fakepage1.com'), FakePage('http://fakepage2.com')]
181 results
= page_test_results
.PageTestResults()
182 results
.WillRunPage(page
)
183 cycler
.WillNavigateToPage(page
, tab
)
184 cycler
.ValidateAndMeasurePage(page
, tab
, results
)
185 results
.DidRunPage(page
)
187 values
= results
.all_page_specific_values
188 self
.assertGreater(len(values
), 2)
190 self
.assertEqual(values
[0].page
, page
)
192 chart_name
= 'cold_times' if i
== 0 or i
> 1 else 'warm_times'
193 self
.assertEqual(values
[0].name
, '%s.page_load_time' % chart_name
)
194 self
.assertEqual(values
[0].units
, 'ms')
196 cycler
.DidNavigateToPage(page
, tab
)
198 def testResults(self
):
199 cycler
= self
.SetUpCycler([], True)
201 pages
= [FakePage('http://fakepage1.com'), FakePage('http://fakepage2.com')]
206 results
= page_test_results
.PageTestResults()
207 results
.WillRunPage(page
)
208 cycler
.WillNavigateToPage(page
, tab
)
209 cycler
.ValidateAndMeasurePage(page
, tab
, results
)
210 results
.DidRunPage(page
)
212 values
= results
.all_page_specific_values
213 self
.assertEqual(4, len(values
))
215 self
.assertEqual(values
[0].page
, page
)
216 chart_name
= 'cold_times' if i
== 0 else 'warm_times'
217 self
.assertEqual(values
[0].name
, '%s.page_load_time' % chart_name
)
218 self
.assertEqual(values
[0].units
, 'ms')
220 for value
, expected
in zip(values
[1:], ['gpu', 'renderer', 'browser']):
221 self
.assertEqual(value
.page
, page
)
222 self
.assertEqual(value
.name
,
223 'cpu_utilization.cpu_utilization_%s' % expected
)
224 self
.assertEqual(value
.units
, '%')
226 cycler
.DidNavigateToPage(page
, tab
)
228 def testLegacyPagesAvoidCrossRenderNavigation(self
):
229 # For legacy page cyclers with file URLs, verify that WillNavigateToPage
230 # does an initial navigate to avoid paying for a cross-renderer navigation.
231 cycler
= self
.SetUpCycler([], True)
232 pages
= [FakePage('file://fakepage1.com'), FakePage('file://fakepage2.com')]
235 self
.assertEqual([], tab
.navigated_urls
)
236 for page
in pages
* 2:
237 cycler
.WillNavigateToPage(page
, tab
)
239 ['http://fakeserver:99999/nonexistent.html'], tab
.navigated_urls
)