| OLD | NEW |
| 1 # Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 # These tests access private methods in the speedindex module. | 5 # These tests access private methods in the speedindex module. |
| 6 # pylint: disable=W0212 | 6 # pylint: disable=W0212 |
| 7 | 7 |
| 8 import json | 8 import json |
| 9 import os | 9 import os |
| 10 import unittest | 10 import unittest |
| 11 | 11 |
| 12 from telemetry.core import bitmap | 12 from telemetry.core import bitmap |
| 13 from telemetry.timeline import inspector_timeline_data | |
| 14 from telemetry.timeline import model | 13 from telemetry.timeline import model |
| 14 from telemetry.value import trace as trace_value_module |
| 15 from metrics import speedindex | 15 from metrics import speedindex |
| 16 | 16 |
| 17 # Sample timeline data in the json format provided by devtools. | 17 # Sample timeline data in the json format provided by devtools. |
| 18 # The sample events will be used in several tests below. | 18 # The sample events will be used in several tests below. |
| 19 |
| 19 _TEST_DIR = os.path.join(os.path.dirname(__file__), 'unittest_data') | 20 _TEST_DIR = os.path.join(os.path.dirname(__file__), 'unittest_data') |
| 20 _SAMPLE_DATA = json.load(open(os.path.join(_TEST_DIR, 'sample_timeline.json'))) | 21 |
| 21 _SAMPLE_TIMELINE_DATA = inspector_timeline_data.InspectorTimelineData( | 22 def _GetSampleEvents(): |
| 22 _SAMPLE_DATA) | 23 with open(os.path.join(_TEST_DIR, 'sample_timeline.json') as f: |
| 23 _SAMPLE_EVENTS = model.TimelineModel( | 24 data = json.load(f) |
| 24 timeline_data=_SAMPLE_TIMELINE_DATA).GetAllEvents() | 25 builder = trace_value_module.TraceValueBuilder() |
| 26 builder.AddEventsTo(trace_value_module.INSPECTOR_TRACE_PART, data) |
| 27 model = model.TimelineModel(builder.AsValue()) |
| 28 return model.GetAllEvents() |
| 25 | 29 |
| 26 | 30 |
| 27 class FakeTimelineModel(object): | 31 class FakeTimelineModel(object): |
| 28 | 32 |
| 29 def __init__(self): | 33 def __init__(self): |
| 30 self._events = [] | 34 self._events = [] |
| 31 | 35 |
| 32 def SetAllEvents(self, events): | 36 def SetAllEventsOnFake(self, events): |
| 33 self._events = events | 37 self._events = events |
| 34 | 38 |
| 35 def GetAllEvents(self, recursive=True): | 39 def GetAllEvents(self, recursive=True): |
| 36 assert recursive == True | 40 assert recursive == True |
| 37 return self._events | 41 return self._events |
| 38 | 42 |
| 39 | 43 |
| 40 class FakeVideo(object): | 44 class FakeVideo(object): |
| 41 | 45 |
| 42 def __init__(self, frames): | 46 def __init__(self, frames): |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 | 91 |
| 88 def Highlight(self, _): | 92 def Highlight(self, _): |
| 89 pass | 93 pass |
| 90 | 94 |
| 91 | 95 |
| 92 class IncludedPaintEventsTest(unittest.TestCase): | 96 class IncludedPaintEventsTest(unittest.TestCase): |
| 93 def testNumberPaintEvents(self): | 97 def testNumberPaintEvents(self): |
| 94 impl = speedindex.PaintRectSpeedIndexImpl() | 98 impl = speedindex.PaintRectSpeedIndexImpl() |
| 95 # In the sample data, there's one event that occurs before the layout event, | 99 # In the sample data, there's one event that occurs before the layout event, |
| 96 # and one paint event that's not a leaf paint event. | 100 # and one paint event that's not a leaf paint event. |
| 97 events = impl._IncludedPaintEvents(_SAMPLE_EVENTS) | 101 events = impl._IncludedPaintEvents(_GetSampleEvents()) |
| 98 self.assertEqual(len(events), 5) | 102 self.assertEqual(len(events), 5) |
| 99 | 103 |
| 100 | 104 |
| 101 class SpeedIndexImplTest(unittest.TestCase): | 105 class SpeedIndexImplTest(unittest.TestCase): |
| 102 def testAdjustedAreaDict(self): | 106 def testAdjustedAreaDict(self): |
| 103 impl = speedindex.PaintRectSpeedIndexImpl() | 107 impl = speedindex.PaintRectSpeedIndexImpl() |
| 104 paint_events = impl._IncludedPaintEvents(_SAMPLE_EVENTS) | 108 paint_events = impl._IncludedPaintEvents(_GetSampleEvents()) |
| 105 viewport = 1000, 1000 | 109 viewport = 1000, 1000 |
| 106 time_area_dict = impl._TimeAreaDict(paint_events, viewport) | 110 time_area_dict = impl._TimeAreaDict(paint_events, viewport) |
| 107 self.assertEqual(len(time_area_dict), 4) | 111 self.assertEqual(len(time_area_dict), 4) |
| 108 # The event that ends at time 100 is a fullscreen; it's discounted by half. | 112 # The event that ends at time 100 is a fullscreen; it's discounted by half. |
| 109 self.assertEqual(time_area_dict[100], 500000) | 113 self.assertEqual(time_area_dict[100], 500000) |
| 110 self.assertEqual(time_area_dict[300], 100000) | 114 self.assertEqual(time_area_dict[300], 100000) |
| 111 self.assertEqual(time_area_dict[400], 200000) | 115 self.assertEqual(time_area_dict[400], 200000) |
| 112 self.assertEqual(time_area_dict[800], 200000) | 116 self.assertEqual(time_area_dict[800], 200000) |
| 113 | 117 |
| 114 def testVideoCompleteness(self): | 118 def testVideoCompleteness(self): |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 viewport = 1000, 1000 | 173 viewport = 1000, 1000 |
| 170 # Add up the parts of the speed index for each time interval. | 174 # Add up the parts of the speed index for each time interval. |
| 171 # Each part is the time interval multiplied by the proportion of the | 175 # Each part is the time interval multiplied by the proportion of the |
| 172 # total area value that is not yet painted for that interval. | 176 # total area value that is not yet painted for that interval. |
| 173 parts = [] | 177 parts = [] |
| 174 parts.append(100 * 1.0) | 178 parts.append(100 * 1.0) |
| 175 parts.append(200 * 0.5) | 179 parts.append(200 * 0.5) |
| 176 parts.append(100 * 0.4) | 180 parts.append(100 * 0.4) |
| 177 parts.append(400 * 0.2) | 181 parts.append(400 * 0.2) |
| 178 expected = sum(parts) # 330.0 | 182 expected = sum(parts) # 330.0 |
| 179 tab.timeline_model.SetAllEvents(_SAMPLE_EVENTS) | 183 tab.timeline_model.SetAllEventsOnFake(_GetSampleEvents()) |
| 180 tab.SetEvaluateJavaScriptResult(viewport) | 184 tab.SetEvaluateJavaScriptResult(viewport) |
| 181 actual = impl.CalculateSpeedIndex(tab) | 185 actual = impl.CalculateSpeedIndex(tab) |
| 182 self.assertEqual(actual, expected) | 186 self.assertEqual(actual, expected) |
| 183 | 187 |
| 184 | 188 |
| 185 class WPTComparisonTest(unittest.TestCase): | 189 class WPTComparisonTest(unittest.TestCase): |
| 186 """Compare the speed index results with results given by webpagetest.org. | 190 """Compare the speed index results with results given by webpagetest.org. |
| 187 | 191 |
| 188 Given the same timeline data, both this speedindex metric and webpagetest.org | 192 Given the same timeline data, both this speedindex metric and webpagetest.org |
| 189 should both return the same results. Fortunately, webpagetest.org also | 193 should both return the same results. Fortunately, webpagetest.org also |
| 190 provides timeline data in json format along with the speed index results. | 194 provides timeline data in json format along with the speed index results. |
| 191 """ | 195 """ |
| 192 | 196 |
| 193 def _TestJsonTimelineExpectation(self, filename, viewport, expected): | 197 def _TestJsonTimelineExpectation(self, filename, viewport, expected): |
| 194 """Check whether the result for some timeline data is as expected. | 198 """Check whether the result for some timeline data is as expected. |
| 195 | 199 |
| 196 Args: | 200 Args: |
| 197 filename: Filename of a json file which contains a | 201 filename: Filename of a json file which contains a |
| 198 expected: The result expected based on the WPT result. | 202 expected: The result expected based on the WPT result. |
| 199 """ | 203 """ |
| 200 tab = FakeTab() | 204 tab = FakeTab() |
| 201 impl = speedindex.PaintRectSpeedIndexImpl() | 205 impl = speedindex.PaintRectSpeedIndexImpl() |
| 202 file_path = os.path.join(_TEST_DIR, filename) | 206 file_path = os.path.join(_TEST_DIR, filename) |
| 203 with open(file_path) as json_file: | 207 with open(file_path) as json_file: |
| 204 raw_events = json.load(json_file) | 208 raw_events = json.load(json_file) |
| 205 timeline_data = inspector_timeline_data.InspectorTimelineData(raw_events) | 209 builder = trace_value_module.TraceValueBuilder() |
| 206 tab.timeline_model.SetAllEvents( | 210 builder.AddEventsTo(trace_value_module.INSPECTOR_TRACE_PART, raw_events) |
| 207 model.TimelineModel(timeline_data=timeline_data).GetAllEvents()) | 211 all_events = model.TimelineModel(builder.AsValue()).GetAllEvents() |
| 212 tab.timeline_model.SetAllEventsOnFake() |
| 208 tab.SetEvaluateJavaScriptResult(viewport) | 213 tab.SetEvaluateJavaScriptResult(viewport) |
| 209 actual = impl.CalculateSpeedIndex(tab) | 214 actual = impl.CalculateSpeedIndex(tab) |
| 210 # The result might differ by 1 or more milliseconds due to rounding, | 215 # The result might differ by 1 or more milliseconds due to rounding, |
| 211 # so compare to the nearest 10 milliseconds. | 216 # so compare to the nearest 10 milliseconds. |
| 212 self.assertAlmostEqual(actual, expected, places=-1) | 217 self.assertAlmostEqual(actual, expected, places=-1) |
| 213 | 218 |
| 214 def testCern(self): | 219 def testCern(self): |
| 215 # Page: http://info.cern.ch/hypertext/WWW/TheProject.html | 220 # Page: http://info.cern.ch/hypertext/WWW/TheProject.html |
| 216 # This page has only one paint event. | 221 # This page has only one paint event. |
| 217 self._TestJsonTimelineExpectation( | 222 self._TestJsonTimelineExpectation( |
| 218 'cern_repeat_timeline.json', (1014, 650), 379.0) | 223 'cern_repeat_timeline.json', (1014, 650), 379.0) |
| 219 | 224 |
| 220 def testBaidu(self): | 225 def testBaidu(self): |
| 221 # Page: http://www.baidu.com/ | 226 # Page: http://www.baidu.com/ |
| 222 # This page has several paint events, but no nested paint events. | 227 # This page has several paint events, but no nested paint events. |
| 223 self._TestJsonTimelineExpectation( | 228 self._TestJsonTimelineExpectation( |
| 224 'baidu_repeat_timeline.json', (1014, 650), 1761.43) | 229 'baidu_repeat_timeline.json', (1014, 650), 1761.43) |
| 225 | 230 |
| 226 def test2ch(self): | 231 def test2ch(self): |
| 227 # Page: http://2ch.net/ | 232 # Page: http://2ch.net/ |
| 228 # This page has several paint events, including nested paint events. | 233 # This page has several paint events, including nested paint events. |
| 229 self._TestJsonTimelineExpectation( | 234 self._TestJsonTimelineExpectation( |
| 230 '2ch_repeat_timeline.json', (997, 650), 674.58) | 235 '2ch_repeat_timeline.json', (997, 650), 674.58) |
| 231 | 236 |
| 232 | 237 |
| 233 if __name__ == "__main__": | 238 if __name__ == "__main__": |
| 234 unittest.main() | 239 unittest.main() |
| OLD | NEW |