# Copyright 2013 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import unittest from measurements import page_cycler from telemetry.core import browser_options from telemetry.page import page_measurement_results from telemetry.unittest import simple_mock # Allow testing protected members in the unit test. # pylint: disable=W0212 # Used instead of simple_mock.MockObject so that the precise order and # number of calls need not be specified. class MockMemoryMetric(object): def __init__(self): pass def Start(self, page, tab): pass def Stop(self, page, tab): pass def AddResults(self, tab, results): pass def AddSummaryResults(self, tab, results): pass # Used to mock loading a page. class FakePage(object): def __init__(self, url): self.url = url # Used to mock a browser tab. class FakeTab(object): def __init__(self): self.clear_cache_calls = 0 def ClearCache(self): self.clear_cache_calls += 1 def EvaluateJavaScript(self, _): return 1 def WaitForJavaScriptExpression(self, _, __): pass class PageCyclerUnitTest(unittest.TestCase): # TODO(tonyg): Remove this backfill when we can assume python 2.7 everywhere. def assertIn(self, first, second, _=None): self.assertTrue(first in second, msg="'%s' not found in '%s'" % (first, second)) def setupCycler(self, args, setup_memory_module=False): cycler = page_cycler.PageCycler() options = browser_options.BrowserFinderOptions() parser = options.CreateParser() cycler.AddCommandLineOptions(parser) parser.parse_args(args) cycler.CustomizeBrowserOptions(options) if setup_memory_module: # Mock out memory metrics; the real ones require a real browser. mock_memory_metric = MockMemoryMetric() mock_memory_module = simple_mock.MockObject() mock_memory_module.ExpectCall( 'MemoryMetric').WithArgs(simple_mock.DONT_CARE).WillReturn( mock_memory_metric) real_memory_module = page_cycler.memory try: page_cycler.memory = mock_memory_module cycler.DidStartBrowser(None) finally: page_cycler.memory = real_memory_module return cycler def testOptionsColdLoadNoArgs(self): cycler = self.setupCycler([]) self.assertEquals(cycler._cold_run_start_index, 10) def testOptionsColdLoadPagesetRepeat(self): cycler = self.setupCycler(['--pageset-repeat=20', '--page-repeat=2']) self.assertEquals(cycler._cold_run_start_index, 40) def testOptionsColdLoadRequested(self): cycler = self.setupCycler(['--pageset-repeat=21', '--page-repeat=2', '--cold-load-percent=40']) self.assertEquals(cycler._cold_run_start_index, 26) def testIncompatibleOptions(self): exception_seen = False try: self.setupCycler(['--pageset-repeat=20s', '--page-repeat=2s', '--cold-load-percent=40']) except Exception as e: exception_seen = True self.assertEqual('--cold-load-percent is incompatible with ' 'timed repeat', e.args[0]) self.assertTrue(exception_seen) def testCacheHandled(self): cycler = self.setupCycler(['--pageset-repeat=5', '--cold-load-percent=50'], True) url_name = "http://fakepage.com" page = FakePage(url_name) tab = FakeTab() results = page_measurement_results.PageMeasurementResults() for i in range(5): cycler.WillNavigateToPage(page, tab) self.assertEqual(max(0, i - 2), tab.clear_cache_calls, "Iteration %d tab.clear_cache_calls %d" % (i, tab.clear_cache_calls)) results.WillMeasurePage(page) cycler.MeasurePage(page, tab, results) values = results.page_specific_values_for_current_page results.DidMeasurePage() self.assertEqual(1, len(values)) self.assertEqual(values[0].page, page) chart_name = 'cold_times' if i == 0 or i > 2 else 'warm_times' self.assertEqual(values[0].name, '%s.page_load_time' % chart_name) self.assertEqual(values[0].units, 'ms') cycler.DidNavigateToPage(page, tab) def testColdWarm(self): cycler = self.setupCycler(['--pageset-repeat=3'], True) pages = [FakePage("http://fakepage1.com"), FakePage("http://fakepage2.com")] tab = FakeTab() results = page_measurement_results.PageMeasurementResults() for i in range(3): for page in pages: cycler.WillNavigateToPage(page, tab) results.WillMeasurePage(page) cycler.MeasurePage(page, tab, results) values = results.page_specific_values_for_current_page results.DidMeasurePage() self.assertEqual(1, len(values)) self.assertEqual(values[0].page, page) chart_name = 'cold_times' if i == 0 else 'warm_times' self.assertEqual(values[0].name, '%s.page_load_time' % chart_name) cycler.DidNavigateToPage(page, tab)