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. 4import unittest 5 6from measurements import page_cycler 7from telemetry.core import browser_options 8from telemetry.page import page_measurement_results 9from telemetry.unittest import simple_mock 10 11# Allow testing protected members in the unit test. 12# pylint: disable=W0212 13 14# Used instead of simple_mock.MockObject so that the precise order and 15# number of calls need not be specified. 16class MockMemoryMetric(object): 17 def __init__(self): 18 pass 19 20 def Start(self, page, tab): 21 pass 22 23 def Stop(self, page, tab): 24 pass 25 26 def AddResults(self, tab, results): 27 pass 28 29 def AddSummaryResults(self, tab, results): 30 pass 31 32# Used to mock loading a page. 33class FakePage(object): 34 def __init__(self, url): 35 self.url = url 36 37# Used to mock a browser tab. 38class FakeTab(object): 39 def __init__(self): 40 self.clear_cache_calls = 0 41 def ClearCache(self): 42 self.clear_cache_calls += 1 43 def EvaluateJavaScript(self, _): 44 return 1 45 def WaitForJavaScriptExpression(self, _, __): 46 pass 47 48class PageCyclerUnitTest(unittest.TestCase): 49 50 # TODO(tonyg): Remove this backfill when we can assume python 2.7 everywhere. 51 def assertIn(self, first, second, _=None): 52 self.assertTrue(first in second, 53 msg="'%s' not found in '%s'" % (first, second)) 54 55 def setupCycler(self, args, setup_memory_module=False): 56 cycler = page_cycler.PageCycler() 57 options = browser_options.BrowserFinderOptions() 58 parser = options.CreateParser() 59 cycler.AddCommandLineOptions(parser) 60 parser.parse_args(args) 61 cycler.CustomizeBrowserOptions(options) 62 63 if setup_memory_module: 64 # Mock out memory metrics; the real ones require a real browser. 65 mock_memory_metric = MockMemoryMetric() 66 67 mock_memory_module = simple_mock.MockObject() 68 mock_memory_module.ExpectCall( 69 'MemoryMetric').WithArgs(simple_mock.DONT_CARE).WillReturn( 70 mock_memory_metric) 71 72 real_memory_module = page_cycler.memory 73 try: 74 page_cycler.memory = mock_memory_module 75 cycler.DidStartBrowser(None) 76 finally: 77 page_cycler.memory = real_memory_module 78 79 return cycler 80 81 def testOptionsColdLoadNoArgs(self): 82 cycler = self.setupCycler([]) 83 84 self.assertEquals(cycler._cold_run_start_index, 10) 85 86 def testOptionsColdLoadPagesetRepeat(self): 87 cycler = self.setupCycler(['--pageset-repeat=20', '--page-repeat=2']) 88 89 self.assertEquals(cycler._cold_run_start_index, 40) 90 91 def testOptionsColdLoadRequested(self): 92 cycler = self.setupCycler(['--pageset-repeat=21', '--page-repeat=2', 93 '--cold-load-percent=40']) 94 95 self.assertEquals(cycler._cold_run_start_index, 26) 96 97 def testIncompatibleOptions(self): 98 exception_seen = False 99 try: 100 self.setupCycler(['--pageset-repeat=20s', '--page-repeat=2s', 101 '--cold-load-percent=40']) 102 except Exception as e: 103 exception_seen = True 104 self.assertEqual('--cold-load-percent is incompatible with ' 105 'timed repeat', e.args[0]) 106 107 self.assertTrue(exception_seen) 108 109 def testCacheHandled(self): 110 cycler = self.setupCycler(['--pageset-repeat=5', 111 '--cold-load-percent=50'], 112 True) 113 114 url_name = "http://fakepage.com" 115 page = FakePage(url_name) 116 tab = FakeTab() 117 results = page_measurement_results.PageMeasurementResults() 118 119 for i in range(5): 120 cycler.WillNavigateToPage(page, tab) 121 self.assertEqual(max(0, i - 2), tab.clear_cache_calls, 122 "Iteration %d tab.clear_cache_calls %d" % 123 (i, tab.clear_cache_calls)) 124 results.WillMeasurePage(page) 125 cycler.MeasurePage(page, tab, results) 126 127 values = results.page_specific_values_for_current_page 128 results.DidMeasurePage() 129 130 self.assertEqual(1, len(values)) 131 self.assertEqual(values[0].page, page) 132 133 chart_name = 'cold_times' if i == 0 or i > 2 else 'warm_times' 134 self.assertEqual(values[0].name, '%s.page_load_time' % chart_name) 135 self.assertEqual(values[0].units, 'ms') 136 137 cycler.DidNavigateToPage(page, tab) 138 139 def testColdWarm(self): 140 cycler = self.setupCycler(['--pageset-repeat=3'], True) 141 pages = [FakePage("http://fakepage1.com"), FakePage("http://fakepage2.com")] 142 tab = FakeTab() 143 results = page_measurement_results.PageMeasurementResults() 144 for i in range(3): 145 for page in pages: 146 cycler.WillNavigateToPage(page, tab) 147 results.WillMeasurePage(page) 148 cycler.MeasurePage(page, tab, results) 149 150 values = results.page_specific_values_for_current_page 151 results.DidMeasurePage() 152 153 self.assertEqual(1, len(values)) 154 self.assertEqual(values[0].page, page) 155 156 chart_name = 'cold_times' if i == 0 else 'warm_times' 157 self.assertEqual(values[0].name, '%s.page_load_time' % chart_name) 158 159 cycler.DidNavigateToPage(page, tab) 160