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_measurement_results
9 from telemetry.page import page_runner
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):
43 class FakeTab(object):
44 """Used to mock a browser tab."""
46 self.clear_cache_calls = 0
47 def ClearCache(self, force=False):
49 self.clear_cache_calls += 1
50 def EvaluateJavaScript(self, _):
52 def WaitForJavaScriptExpression(self, _, __):
56 class FakeBrowser(object):
61 FakeBrowser._iteration += 1
63 'Browser': {'CpuProcessTime': FakeBrowser._iteration,
64 'TotalTime': FakeBrowser._iteration * 2},
65 'Renderer': {'CpuProcessTime': FakeBrowser._iteration,
66 'TotalTime': FakeBrowser._iteration * 3},
67 'Gpu': {'CpuProcessTime': FakeBrowser._iteration,
68 'TotalTime': FakeBrowser._iteration * 4}
72 class PageCyclerUnitTest(unittest.TestCase):
74 def SetUpCycler(self, args, setup_memory_module=False):
75 cycler = page_cycler.PageCycler()
76 options = browser_options.BrowserFinderOptions()
77 parser = options.CreateParser()
78 page_runner.AddCommandLineArgs(parser)
79 cycler.AddCommandLineArgs(parser)
80 cycler.SetArgumentDefaults(parser)
81 parser.parse_args(args)
82 page_runner.ProcessCommandLineArgs(parser, options)
83 cycler.ProcessCommandLineArgs(parser, options)
84 cycler.CustomizeBrowserOptions(options)
86 if setup_memory_module:
87 # Mock out memory metrics; the real ones require a real browser.
88 mock_memory_metric = MockMemoryMetric()
90 mock_memory_module = simple_mock.MockObject()
91 mock_memory_module.ExpectCall(
92 'MemoryMetric').WithArgs(simple_mock.DONT_CARE).WillReturn(
95 real_memory_module = page_cycler.memory
97 page_cycler.memory = mock_memory_module
98 cycler.DidStartBrowser(FakeBrowser())
100 page_cycler.memory = real_memory_module
104 def testOptionsColdLoadNoArgs(self):
105 cycler = self.SetUpCycler([])
107 self.assertEquals(cycler._cold_run_start_index, 5)
109 def testOptionsColdLoadPagesetRepeat(self):
110 cycler = self.SetUpCycler(['--pageset-repeat=20', '--page-repeat=2'])
112 self.assertEquals(cycler._cold_run_start_index, 20)
114 def testOptionsColdLoadRequested(self):
115 cycler = self.SetUpCycler(['--pageset-repeat=21', '--page-repeat=2',
116 '--cold-load-percent=40'])
118 self.assertEquals(cycler._cold_run_start_index, 26)
120 def testCacheHandled(self):
121 cycler = self.SetUpCycler(['--pageset-repeat=5',
122 '--cold-load-percent=50'],
125 url_name = 'http://fakepage.com'
126 page = FakePage(url_name)
128 results = page_measurement_results.PageMeasurementResults()
131 cycler.WillNavigateToPage(page, tab)
132 self.assertEqual(max(0, i - 2), tab.clear_cache_calls,
133 'Iteration %d tab.clear_cache_calls %d' %
134 (i, tab.clear_cache_calls))
135 results.WillMeasurePage(page)
136 cycler.MeasurePage(page, tab, results)
138 values = results.page_specific_values_for_current_page
139 results.DidMeasurePage()
141 self.assertGreater(len(values), 2)
143 self.assertEqual(values[0].page, page)
144 chart_name = 'cold_times' if i == 0 or i > 2 else 'warm_times'
145 self.assertEqual(values[0].name, '%s.page_load_time' % chart_name)
146 self.assertEqual(values[0].units, 'ms')
148 cycler.DidNavigateToPage(page, tab)
150 def testColdWarm(self):
151 cycler = self.SetUpCycler(['--pageset-repeat=3'], True)
152 pages = [FakePage('http://fakepage1.com'), FakePage('http://fakepage2.com')]
154 results = page_measurement_results.PageMeasurementResults()
157 cycler.WillNavigateToPage(page, tab)
158 results.WillMeasurePage(page)
159 cycler.MeasurePage(page, tab, results)
161 values = results.page_specific_values_for_current_page
162 results.DidMeasurePage()
164 self.assertGreater(len(values), 2)
166 self.assertEqual(values[0].page, page)
168 chart_name = 'cold_times' if i == 0 or i > 1 else 'warm_times'
169 self.assertEqual(values[0].name, '%s.page_load_time' % chart_name)
170 self.assertEqual(values[0].units, 'ms')
172 cycler.DidNavigateToPage(page, tab)
174 def testResults(self):
175 cycler = self.SetUpCycler([], True)
177 pages = [FakePage('http://fakepage1.com'), FakePage('http://fakepage2.com')]
179 results = page_measurement_results.PageMeasurementResults()
183 cycler.WillNavigateToPage(page, tab)
184 results.WillMeasurePage(page)
185 cycler.MeasurePage(page, tab, results)
187 values = results.page_specific_values_for_current_page
188 results.DidMeasurePage()
190 self.assertEqual(4, len(values))
192 self.assertEqual(values[0].page, page)
193 chart_name = 'cold_times' if i == 0 else 'warm_times'
194 self.assertEqual(values[0].name, '%s.page_load_time' % chart_name)
195 self.assertEqual(values[0].units, 'ms')
197 for value, expected in zip(values[1:], ['gpu', 'renderer', 'browser']):
198 self.assertEqual(value.page, page)
199 self.assertEqual(value.name,
200 'cpu_utilization.cpu_utilization_%s' % expected)
201 self.assertEqual(value.units, '%')
204 cycler.DidNavigateToPage(page, tab)