Change UMA proto product field to be an int32.
[chromium-blink-merge.git] / tools / perf / measurements / page_cycler_unittest.py
blob7f32c92b68d348d34591b1bdcaecedda8da52c0c
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.
5 import unittest
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."""
21 def __init__(self):
22 pass
24 def Start(self, page, tab):
25 pass
27 def Stop(self, page, tab):
28 pass
30 def AddResults(self, tab, results):
31 pass
33 def AddSummaryResults(self, tab, results):
34 pass
37 class FakePage(object):
38 """Used to mock loading a page."""
39 def __init__(self, url):
40 self.url = url
41 self.is_file = url.startswith('file://')
44 class FakeTab(object):
45 """Used to mock a browser tab."""
46 def __init__(self):
47 self.clear_cache_calls = 0
48 self.navigated_urls = []
49 def ClearCache(self, force=False):
50 assert force
51 self.clear_cache_calls += 1
52 def EvaluateJavaScript(self, _):
53 return 1
54 def Navigate(self, url):
55 self.navigated_urls.append(url)
56 def WaitForJavaScriptExpression(self, _, __):
57 pass
58 @property
59 def browser(self):
60 return FakeBrowser()
62 class FakeBrowser(object):
63 _iteration = 0
65 @property
66 def cpu_stats(self):
67 FakeBrowser._iteration += 1
68 return {
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}
76 @property
77 def platform(self):
78 return FakePlatform()
80 @property
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):
89 def GetOSName(self):
90 return 'fake'
91 def CanMonitorPower(self):
92 return False
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(
117 mock_memory_metric)
119 real_memory_module = page_cycler.memory
120 try:
121 page_cycler.memory = mock_memory_module
122 browser = FakeBrowser()
123 cycler.WillStartBrowser(options.browser_options.platform)
124 cycler.DidStartBrowser(browser)
125 finally:
126 page_cycler.memory = real_memory_module
128 return cycler
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'],
149 True)
151 url_name = 'http://fakepage.com'
152 page = FakePage(url_name)
153 tab = FakeTab()
155 for i in range(5):
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')]
178 tab = FakeTab()
179 for i in range(3):
180 for page in pages:
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')]
202 tab = FakeTab()
204 for i in range(2):
205 for page in pages:
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')]
233 tab = FakeTab()
235 self.assertEqual([], tab.navigated_urls)
236 for page in pages * 2:
237 cycler.WillNavigateToPage(page, tab)
238 self.assertEqual(
239 ['http://fakeserver:99999/nonexistent.html'], tab.navigated_urls)