Home | History | Annotate | Download | only in metrics
      1 # Copyright 2014 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 
      5 import unittest
      6 
      7 from telemetry.results import page_test_results
      8 from telemetry.page import page as page_module
      9 from telemetry.web_perf.metrics import smoothness
     10 
     11 
     12 class _MockRenderingStats(object):
     13 
     14   stats = ['frame_timestamps', 'frame_times', 'paint_times',
     15            'painted_pixel_counts', 'record_times',
     16            'recorded_pixel_counts', 'rasterize_times',
     17            'rasterized_pixel_counts', 'approximated_pixel_percentages',
     18            'input_event_latency', 'frame_queueing_durations',
     19            'scroll_update_latency', 'gesture_scroll_update_latency']
     20 
     21   def __init__(self, **kwargs):
     22     self.errors = {}
     23     for stat in self.stats:
     24       value = kwargs[stat] if stat in kwargs else None
     25       setattr(self, stat, value)
     26 
     27 
     28 #pylint: disable=W0212
     29 class SmoothnessMetricUnitTest(unittest.TestCase):
     30 
     31   def setUp(self):
     32     self.metric = smoothness.SmoothnessMetric()
     33     self.page = page_module.Page('file://blank.html')
     34     self.good_timestamps = [[10, 20], [30, 40, 50]]
     35     self.not_enough_frames_timestamps = [[10], [20, 30, 40]]
     36 
     37   def testPopulateResultsFromStats(self):
     38     stats = _MockRenderingStats()
     39     for stat in _MockRenderingStats.stats:
     40       # Just set fake data for all of the relevant arrays of stats typically
     41       # found in a RenderingStats object.
     42       setattr(stats, stat, [[10, 20], [30, 40, 50]])
     43     results = page_test_results.PageTestResults()
     44     results.WillRunPage(self.page)
     45     self.metric._PopulateResultsFromStats(results, stats)
     46     current_page_run = results.current_page_run
     47     self.assertTrue(current_page_run.ok)
     48     self.assertEquals(11, len(current_page_run.values))
     49 
     50   def testHasEnoughFrames(self):
     51     # This list will pass since every sub-array has at least 2 frames.
     52     has_enough_frames = self.metric._HasEnoughFrames(self.good_timestamps)
     53     self.assertTrue(has_enough_frames)
     54 
     55   def testHasEnoughFramesWithNotEnoughFrames(self):
     56     # This list will fail since the first sub-array only has a single frame.
     57     has_enough_frames = self.metric._HasEnoughFrames(
     58         self.not_enough_frames_timestamps)
     59     self.assertFalse(has_enough_frames)
     60 
     61   def testComputeLatencyMetric(self):
     62     stats = _MockRenderingStats(frame_timestamps=self.good_timestamps,
     63                                input_event_latency=[[10, 20], [30, 40, 50]])
     64     mean_value, discrepancy_value = self.metric._ComputeLatencyMetric(
     65         self.page, stats, 'input_event_latency', stats.input_event_latency)
     66     self.assertEquals(30, mean_value.value)
     67     self.assertEquals(60, discrepancy_value.value)
     68 
     69   def testComputeLatencyMetricWithMissingData(self):
     70     stats = _MockRenderingStats(frame_timestamps=self.good_timestamps,
     71                                input_event_latency=[[], []])
     72     value = self.metric._ComputeLatencyMetric(
     73         self.page, stats, 'input_event_latency', stats.input_event_latency)
     74     self.assertEquals((), value)
     75 
     76   def testComputeLatencyMetricWithNotEnoughFrames(self):
     77     stats = _MockRenderingStats(
     78         frame_timestamps=self.not_enough_frames_timestamps,
     79         input_event_latency=[[], []])
     80     mean_value, discrepancy_value = self.metric._ComputeLatencyMetric(
     81         self.page, stats, 'input_event_latency', stats.input_event_latency)
     82     self.assertEquals(None, mean_value.value)
     83     self.assertEquals(smoothness.NOT_ENOUGH_FRAMES_MESSAGE,
     84                       mean_value.none_value_reason)
     85     self.assertEquals(None, discrepancy_value.value)
     86     self.assertEquals(smoothness.NOT_ENOUGH_FRAMES_MESSAGE,
     87                       discrepancy_value.none_value_reason)
     88 
     89   def testComputeGestureScrollUpdateLatency(self):
     90     stats = _MockRenderingStats(
     91         frame_timestamps=self.good_timestamps,
     92         gesture_scroll_update_latency=[[10, 20], [30, 40, 50]])
     93     gesture_value = self.metric._ComputeFirstGestureScrollUpdateLatency(
     94         self.page, stats)[0]
     95     self.assertEquals(10, gesture_value.value)
     96 
     97   def testComputeGestureScrollUpdateLatencyWithMissingData(self):
     98     stats = _MockRenderingStats(
     99         frame_timestamps=self.good_timestamps,
    100         gesture_scroll_update_latency=[[], []])
    101     value = self.metric._ComputeFirstGestureScrollUpdateLatency(
    102         self.page, stats)
    103     self.assertEquals((), value)
    104 
    105   def testComputeGestureScrollUpdateLatencyWithNotEnoughFrames(self):
    106     stats = _MockRenderingStats(
    107         frame_timestamps=self.not_enough_frames_timestamps,
    108         gesture_scroll_update_latency=[[10, 20], [30, 40, 50]])
    109     gesture_value = self.metric._ComputeFirstGestureScrollUpdateLatency(
    110         self.page, stats)[0]
    111     self.assertEquals(None, gesture_value.value)
    112     self.assertEquals(smoothness.NOT_ENOUGH_FRAMES_MESSAGE,
    113                       gesture_value.none_value_reason)
    114 
    115   def testComputeQueueingDuration(self):
    116     stats = _MockRenderingStats(frame_timestamps=self.good_timestamps,
    117                                frame_queueing_durations=[[10, 20], [30, 40]])
    118     list_of_scalar_values = self.metric._ComputeQueueingDuration(self.page,
    119                                                                 stats)
    120     self.assertEquals([10, 20, 30, 40], list_of_scalar_values.values)
    121 
    122   def testComputeQueueingDurationWithMissingData(self):
    123     stats = _MockRenderingStats(frame_timestamps=self.good_timestamps,
    124                                frame_queueing_durations=[[], []])
    125     list_of_scalar_values = self.metric._ComputeQueueingDuration(
    126         self.page, stats)
    127     self.assertEquals(None, list_of_scalar_values.values)
    128     self.assertEquals('No frame queueing durations recorded.',
    129                       list_of_scalar_values.none_value_reason)
    130 
    131   def testComputeQueueingDurationWithMissingDataAndErrorValue(self):
    132     stats = _MockRenderingStats(frame_timestamps=self.good_timestamps,
    133                                frame_queueing_durations=[[], []])
    134     stats.errors['frame_queueing_durations'] = (
    135         'Current chrome version does not support the queueing delay metric.')
    136     list_of_scalar_values = self.metric._ComputeQueueingDuration(
    137         self.page, stats)
    138     self.assertEquals(None, list_of_scalar_values.values)
    139     self.assertEquals(
    140         'Current chrome version does not support the queueing delay metric.',
    141         list_of_scalar_values.none_value_reason)
    142 
    143   def testComputeQueueingDurationWithNotEnoughFrames(self):
    144     stats = _MockRenderingStats(
    145         frame_timestamps=self.not_enough_frames_timestamps,
    146         frame_queueing_durations=[[10, 20], [30, 40, 50]])
    147     list_of_scalar_values = self.metric._ComputeQueueingDuration(self.page,
    148                                                                 stats)
    149     self.assertEquals(None, list_of_scalar_values.values)
    150     self.assertEquals(smoothness.NOT_ENOUGH_FRAMES_MESSAGE,
    151                       list_of_scalar_values.none_value_reason)
    152 
    153   def testComputeFrameTimeMetric(self):
    154     stats = _MockRenderingStats(frame_timestamps=self.good_timestamps,
    155                                frame_times=[[10, 20], [30, 40, 50]])
    156     frame_times_value, mean_frame_time_value, mostly_smooth_value = (
    157         self.metric._ComputeFrameTimeMetric(self.page, stats))
    158     self.assertEquals([10, 20, 30, 40, 50], frame_times_value.values)
    159     self.assertEquals(30, mean_frame_time_value.value)
    160     self.assertEquals(0, mostly_smooth_value.value)
    161 
    162   def testComputeFrameTimeMetricWithNotEnoughFrames(self):
    163     stats = _MockRenderingStats(
    164         frame_timestamps=self.not_enough_frames_timestamps,
    165         frame_times=[[10, 20], [30, 40, 50]])
    166     frame_times_value, mean_frame_time_value, mostly_smooth_value = (
    167         self.metric._ComputeFrameTimeMetric(self.page, stats))
    168     self.assertEquals(None, frame_times_value.values)
    169     self.assertEquals(smoothness.NOT_ENOUGH_FRAMES_MESSAGE,
    170                       frame_times_value.none_value_reason)
    171     self.assertEquals(None, mean_frame_time_value.value)
    172     self.assertEquals(smoothness.NOT_ENOUGH_FRAMES_MESSAGE,
    173                       mean_frame_time_value.none_value_reason)
    174     self.assertEquals(None, mostly_smooth_value.value)
    175     self.assertEquals(smoothness.NOT_ENOUGH_FRAMES_MESSAGE,
    176                       mostly_smooth_value.none_value_reason)
    177 
    178   def testComputeFrameTimeDiscrepancy(self):
    179     stats = _MockRenderingStats(frame_timestamps=self.good_timestamps)
    180     jank_value = self.metric._ComputeFrameTimeDiscrepancy(self.page, stats)
    181     self.assertEquals(10, jank_value.value)
    182 
    183   def testComputeFrameTimeDiscrepancyWithNotEnoughFrames(self):
    184     stats = _MockRenderingStats(
    185         frame_timestamps=self.not_enough_frames_timestamps)
    186     jank_value = self.metric._ComputeFrameTimeDiscrepancy(self.page, stats)
    187     self.assertEquals(None, jank_value.value)
    188     self.assertEquals(smoothness.NOT_ENOUGH_FRAMES_MESSAGE,
    189                       jank_value.none_value_reason)
    190 
    191   def testComputeMeanPixelsApproximated(self):
    192     stats = _MockRenderingStats(
    193         frame_timestamps=self.good_timestamps,
    194         approximated_pixel_percentages=[[10, 20], [30, 40, 50]])
    195     mean_pixels_value = self.metric._ComputeMeanPixelsApproximated(
    196         self.page, stats)
    197     self.assertEquals(30, mean_pixels_value.value)
    198 
    199   def testComputeMeanPixelsApproximatedWithNotEnoughFrames(self):
    200     stats = _MockRenderingStats(
    201         frame_timestamps=self.not_enough_frames_timestamps,
    202         approximated_pixel_percentages=[[10, 20], [30, 40, 50]])
    203     mean_pixels_value = self.metric._ComputeMeanPixelsApproximated(
    204         self.page, stats)
    205     self.assertEquals(None, mean_pixels_value.value)
    206     self.assertEquals(smoothness.NOT_ENOUGH_FRAMES_MESSAGE,
    207                       mean_pixels_value.none_value_reason)
    208