• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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