Home | History | Annotate | Download | only in measurements
      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.
      4 import sys
      5 
      6 from measurements import smoothness
      7 from metrics import power
      8 from telemetry.core import exceptions
      9 from telemetry.core import wpr_modes
     10 from telemetry.page import page
     11 from telemetry.page import page_test
     12 from telemetry.unittest import options_for_unittests
     13 from telemetry.unittest import page_test_test_case
     14 from telemetry.unittest import test
     15 
     16 class FakeTracingController(object):
     17   def __init__(self):
     18     self.category_filter = None
     19   def Start(self, _options, category_filter, _timeout):
     20     self.category_filter = category_filter
     21 
     22 
     23 class FakePlatform(object):
     24   def __init__(self):
     25     self.tracing_controller = FakeTracingController()
     26   def IsRawDisplayFrameRateSupported(self):
     27     return False
     28   def CanMonitorPower(self):
     29     return False
     30 
     31 
     32 class FakeBrowser(object):
     33   def __init__(self):
     34     self.platform = FakePlatform()
     35 
     36 
     37 class AnimatedPage(page.Page):
     38   def __init__(self, page_set):
     39     super(AnimatedPage, self).__init__(
     40       url='file://animated_page.html',
     41       page_set=page_set, base_dir=page_set.base_dir)
     42 
     43   def RunSmoothness(self, action_runner):
     44     action_runner.Wait(.2)
     45 
     46 
     47 class FakeTab(object):
     48   def __init__(self):
     49     self.browser = FakeBrowser()
     50 
     51   def ExecuteJavaScript(self, js):
     52     pass
     53 
     54 class SmoothnessUnitTest(page_test_test_case.PageTestTestCase):
     55   """Smoke test for smoothness measurement
     56 
     57      Runs smoothness measurement on a simple page and verifies
     58      that all metrics were added to the results. The test is purely functional,
     59      i.e. it only checks if the metrics are present and non-zero.
     60   """
     61   def testSyntheticDelayConfiguration(self):
     62     test_page = page.Page('http://dummy', None)
     63     test_page.synthetic_delays = {
     64         'cc.BeginMainFrame': { 'target_duration': 0.012 },
     65         'cc.DrawAndSwap': { 'target_duration': 0.012, 'mode': 'alternating' },
     66         'gpu.PresentingFrame': { 'target_duration': 0.012 }
     67     }
     68 
     69     tab = FakeTab()
     70     measurement = smoothness.Smoothness()
     71     measurement.WillStartBrowser(tab.browser.platform)
     72     measurement.WillNavigateToPage(test_page, tab)
     73     measurement.WillRunActions(test_page, tab)
     74 
     75     expected_category_filter = set([
     76         'DELAY(cc.BeginMainFrame;0.012000;static)',
     77         'DELAY(cc.DrawAndSwap;0.012000;alternating)',
     78         'DELAY(gpu.PresentingFrame;0.012000;static)',
     79         'benchmark'
     80     ])
     81     tracing_controller = tab.browser.platform.tracing_controller
     82     actual_category_filter = (
     83       tracing_controller.category_filter.included_categories)
     84 
     85     # FIXME: Put blink.console into the expected above and remove these two
     86     # remove entries when the blink.console change has rolled into chromium.
     87     actual_category_filter.remove('webkit.console')
     88     actual_category_filter.remove('blink.console')
     89 
     90     if expected_category_filter != actual_category_filter:
     91       sys.stderr.write("Expected category filter: %s\n" %
     92                        repr(expected_category_filter))
     93       sys.stderr.write("Actual category filter filter: %s\n" %
     94                        repr(actual_category_filter))
     95     self.assertEquals(expected_category_filter, actual_category_filter)
     96 
     97   def setUp(self):
     98     self._options = options_for_unittests.GetCopy()
     99     self._options.browser_options.wpr_mode = wpr_modes.WPR_OFF
    100 
    101   def testSmoothness(self):
    102     ps = self.CreatePageSetFromFileInUnittestDataDir('scrollable_page.html')
    103     measurement = smoothness.Smoothness()
    104     results = self.RunMeasurement(measurement, ps, options=self._options)
    105     self.assertEquals(0, len(results.failures))
    106 
    107     frame_times = results.FindAllPageSpecificValuesNamed('frame_times')
    108     self.assertEquals(len(frame_times), 1)
    109     self.assertGreater(frame_times[0].GetRepresentativeNumber(), 0)
    110 
    111     mean_frame_time = results.FindAllPageSpecificValuesNamed('mean_frame_time')
    112     self.assertEquals(len(mean_frame_time), 1)
    113     self.assertGreater(mean_frame_time[0].GetRepresentativeNumber(), 0)
    114 
    115     jank = results.FindAllPageSpecificValuesNamed('jank')
    116     self.assertEquals(len(jank), 1)
    117     self.assertGreater(jank[0].GetRepresentativeNumber(), 0)
    118 
    119     mostly_smooth = results.FindAllPageSpecificValuesNamed('mostly_smooth')
    120     self.assertEquals(len(mostly_smooth), 1)
    121     self.assertGreaterEqual(mostly_smooth[0].GetRepresentativeNumber(), 0)
    122 
    123     mean_input_event_latency = results.FindAllPageSpecificValuesNamed(
    124         'mean_input_event_latency')
    125     if mean_input_event_latency:
    126       self.assertEquals(len(mean_input_event_latency), 1)
    127       self.assertGreater(
    128           mean_input_event_latency[0].GetRepresentativeNumber(), 0)
    129 
    130   @test.Disabled('mac', 'chromeos')  # http://crbug.com/403903
    131   def testSmoothnessForPageWithNoGesture(self):
    132     ps = self.CreateEmptyPageSet()
    133     ps.AddPage(AnimatedPage(ps))
    134 
    135     measurement = smoothness.Smoothness()
    136     results = self.RunMeasurement(measurement, ps, options=self._options)
    137     self.assertEquals(0, len(results.failures))
    138 
    139     mostly_smooth = results.FindAllPageSpecificValuesNamed('mostly_smooth')
    140     self.assertEquals(len(mostly_smooth), 1)
    141     self.assertGreaterEqual(mostly_smooth[0].GetRepresentativeNumber(), 0)
    142 
    143   def testCleanUpTrace(self):
    144     self.TestTracingCleanedUp(smoothness.Smoothness, self._options)
    145 
    146   def testCleanUpPowerMetric(self):
    147     class FailPage(page.Page):
    148       def __init__(self, page_set):
    149         super(FailPage, self).__init__(
    150             url='file://blank.html',
    151             page_set=page_set, base_dir=page_set.base_dir)
    152       def RunSmoothness(self, _):
    153         raise exceptions.IntentionalException
    154 
    155     class FakePowerMetric(power.PowerMetric):
    156       start_called = False
    157       stop_called = True
    158       def Start(self, _1, _2):
    159         self.start_called = True
    160       def Stop(self, _1, _2):
    161         self.stop_called = True
    162 
    163     ps = self.CreateEmptyPageSet()
    164     ps.AddPage(FailPage(ps))
    165 
    166     class BuggyMeasurement(smoothness.Smoothness):
    167       fake_power = None
    168       # Inject fake power metric.
    169       def WillStartBrowser(self, platform):
    170         self.fake_power = self._power_metric = FakePowerMetric(platform)
    171 
    172     measurement = BuggyMeasurement()
    173     try:
    174       self.RunMeasurement(measurement, ps)
    175     except page_test.TestNotSupportedOnPlatformFailure:
    176       pass
    177 
    178     self.assertTrue(measurement.fake_power.start_called)
    179     self.assertTrue(measurement.fake_power.stop_called)
    180