Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(32)

Side by Side Diff: tools/perf/metrics/speedindex_unittest.py

Issue 805393003: [Telemetry] Remove old paint-rect speed index implementation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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.image_processing import histogram 12 from telemetry.image_processing import histogram
13 from telemetry.image_processing import rgba_color 13 from telemetry.image_processing import rgba_color
14 from telemetry.timeline import inspector_timeline_data
15 from telemetry.timeline import model
16 from metrics import speedindex 14 from metrics import speedindex
17 15
18 # Sample timeline data in the json format provided by devtools.
19 # The sample events will be used in several tests below.
20 _TEST_DIR = os.path.join(os.path.dirname(__file__), 'unittest_data')
21 _SAMPLE_DATA = json.load(open(os.path.join(_TEST_DIR, 'sample_timeline.json')))
22 _SAMPLE_TIMELINE_DATA = inspector_timeline_data.InspectorTimelineData(
23 _SAMPLE_DATA)
24 _SAMPLE_EVENTS = model.TimelineModel(
25 timeline_data=_SAMPLE_TIMELINE_DATA).GetAllEvents()
26
27 16
28 class FakeImageUtil(object): 17 class FakeImageUtil(object):
29 # pylint: disable=W0613 18 # pylint: disable=W0613
30 def GetColorHistogram(self, image, ignore_color=None, tolerance=None): 19 def GetColorHistogram(self, image, ignore_color=None, tolerance=None):
31 return image.ColorHistogram() 20 return image.ColorHistogram()
32 21
33 class FakeTimelineModel(object):
34 def __init__(self):
35 self._events = []
36
37 def SetAllEvents(self, events):
38 self._events = events
39
40 def GetAllEvents(self, recursive=True):
41 assert recursive == True
42 return self._events
43
44 22
45 class FakeVideo(object): 23 class FakeVideo(object):
46 def __init__(self, frames): 24 def __init__(self, frames):
47 self._frames = frames 25 self._frames = frames
48 26
49 def GetVideoFrameIter(self): 27 def GetVideoFrameIter(self):
50 for frame in self._frames: 28 for frame in self._frames:
51 yield frame 29 yield frame
52 30
53 class FakeBitmap(object): 31 class FakeBitmap(object):
54 def __init__(self, r, g, b): 32 def __init__(self, r, g, b):
55 self._histogram = histogram.ColorHistogram(r, g, b, rgba_color.WHITE) 33 self._histogram = histogram.ColorHistogram(r, g, b, rgba_color.WHITE)
56 34
57 # pylint: disable=W0613 35 # pylint: disable=W0613
58 def ColorHistogram(self, ignore_color=None, tolerance=None): 36 def ColorHistogram(self, ignore_color=None, tolerance=None):
59 return self._histogram 37 return self._histogram
60 38
61 39
62 class FakeTab(object): 40 class FakeTab(object):
63 def __init__(self, video_capture_result=None): 41 def __init__(self, video_capture_result=None):
64 self._timeline_model = FakeTimelineModel()
65 self._javascript_result = None 42 self._javascript_result = None
66 self._video_capture_result = FakeVideo(video_capture_result) 43 self._video_capture_result = FakeVideo(video_capture_result)
67 44
68 @property 45 @property
69 def timeline_model(self):
70 return self._timeline_model
71
72 @property
73 def video_capture_supported(self): 46 def video_capture_supported(self):
74 return self._video_capture_result is not None 47 return self._video_capture_result is not None
75 48
76 def SetEvaluateJavaScriptResult(self, result): 49 def SetEvaluateJavaScriptResult(self, result):
77 self._javascript_result = result 50 self._javascript_result = result
78 51
79 def EvaluateJavaScript(self, _): 52 def EvaluateJavaScript(self, _):
80 return self._javascript_result 53 return self._javascript_result
81 54
82 def StartVideoCapture(self, min_bitrate_mbps=1): 55 def StartVideoCapture(self, min_bitrate_mbps=1):
83 assert self.video_capture_supported 56 assert self.video_capture_supported
84 assert min_bitrate_mbps > 0 57 assert min_bitrate_mbps > 0
85 58
86 def StopVideoCapture(self): 59 def StopVideoCapture(self):
87 assert self.video_capture_supported 60 assert self.video_capture_supported
88 return self._video_capture_result 61 return self._video_capture_result
89 62
90 def Highlight(self, _): 63 def Highlight(self, _):
91 pass 64 pass
92 65
93 66
94 class IncludedPaintEventsTest(unittest.TestCase):
95 def testNumberPaintEvents(self):
96 impl = speedindex.PaintRectSpeedIndexImpl()
97 # In the sample data, there's one event that occurs before the layout event,
98 # and one paint event that's not a leaf paint event.
99 events = impl._IncludedPaintEvents(_SAMPLE_EVENTS)
100 self.assertEqual(len(events), 5)
101
102
103 class SpeedIndexImplTest(unittest.TestCase): 67 class SpeedIndexImplTest(unittest.TestCase):
104 def testAdjustedAreaDict(self):
105 impl = speedindex.PaintRectSpeedIndexImpl()
106 paint_events = impl._IncludedPaintEvents(_SAMPLE_EVENTS)
107 viewport = 1000, 1000
108 time_area_dict = impl._TimeAreaDict(paint_events, viewport)
109 self.assertEqual(len(time_area_dict), 4)
110 # The event that ends at time 100 is a fullscreen; it's discounted by half.
111 self.assertEqual(time_area_dict[100], 500000)
112 self.assertEqual(time_area_dict[300], 100000)
113 self.assertEqual(time_area_dict[400], 200000)
114 self.assertEqual(time_area_dict[800], 200000)
115 68
116 def testVideoCompleteness(self): 69 def testVideoCompleteness(self):
117 frames = [ 70 frames = [
118 (0.0, FakeBitmap([ 0, 0, 0,10], [ 0, 0, 0,10], [ 0, 0, 0,10])), 71 (0.0, FakeBitmap([ 0, 0, 0,10], [ 0, 0, 0,10], [ 0, 0, 0,10])),
119 (0.1, FakeBitmap([10, 0, 0, 0], [10, 0, 0, 0], [10, 0, 0, 0])), 72 (0.1, FakeBitmap([10, 0, 0, 0], [10, 0, 0, 0], [10, 0, 0, 0])),
120 (0.2, FakeBitmap([ 0, 0, 2, 8], [ 0, 0, 4, 6], [ 0, 0, 1, 9])), 73 (0.2, FakeBitmap([ 0, 0, 2, 8], [ 0, 0, 4, 6], [ 0, 0, 1, 9])),
121 (0.3, FakeBitmap([ 0, 3, 2, 5], [ 2, 1, 0, 7], [ 0, 3, 0, 7])), 74 (0.3, FakeBitmap([ 0, 3, 2, 5], [ 2, 1, 0, 7], [ 0, 3, 0, 7])),
122 (0.4, FakeBitmap([ 0, 0, 1, 0], [ 0, 0, 1, 0], [ 0, 0, 1, 0])), 75 (0.4, FakeBitmap([ 0, 0, 1, 0], [ 0, 0, 1, 0], [ 0, 0, 1, 0])),
123 (0.5, FakeBitmap([ 0, 4, 6, 0], [ 0, 4, 6, 0], [ 0, 4, 6, 0])), 76 (0.5, FakeBitmap([ 0, 4, 6, 0], [ 0, 4, 6, 0], [ 0, 4, 6, 0])),
124 ] 77 ]
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 self.assertEqual(time_completeness[0], (0.0, 1.0)) 110 self.assertEqual(time_completeness[0], (0.0, 1.0))
158 self.assertEqual(time_completeness[1], (0.1, 1.0)) 111 self.assertEqual(time_completeness[1], (0.1, 1.0))
159 self.assertEqual(time_completeness[2], (0.2, 0.0)) 112 self.assertEqual(time_completeness[2], (0.2, 0.0))
160 self.assertEqual(time_completeness[3], (0.3, 1.0)) 113 self.assertEqual(time_completeness[3], (0.3, 1.0))
161 114
162 def assertTimeCompleteness(self, time_completeness, time, completeness): 115 def assertTimeCompleteness(self, time_completeness, time, completeness):
163 self.assertEqual(time_completeness[0], time) 116 self.assertEqual(time_completeness[0], time)
164 self.assertAlmostEqual(time_completeness[1], completeness) 117 self.assertAlmostEqual(time_completeness[1], completeness)
165 118
166 119
167 class SpeedIndexTest(unittest.TestCase):
168 def testWithSampleData(self):
169 tab = FakeTab()
170 impl = speedindex.PaintRectSpeedIndexImpl()
171 viewport = 1000, 1000
172 # Add up the parts of the speed index for each time interval.
173 # Each part is the time interval multiplied by the proportion of the
174 # total area value that is not yet painted for that interval.
175 parts = []
176 parts.append(100 * 1.0)
177 parts.append(200 * 0.5)
178 parts.append(100 * 0.4)
179 parts.append(400 * 0.2)
180 expected = sum(parts) # 330.0
181 tab.timeline_model.SetAllEvents(_SAMPLE_EVENTS)
182 tab.SetEvaluateJavaScriptResult(viewport)
183 actual = impl.CalculateSpeedIndex(tab)
184 self.assertEqual(actual, expected)
185
186
187 class WPTComparisonTest(unittest.TestCase):
188 """Compare the speed index results with results given by webpagetest.org.
189
190 Given the same timeline data, both this speedindex metric and webpagetest.org
191 should both return the same results. Fortunately, webpagetest.org also
192 provides timeline data in json format along with the speed index results.
193 """
194
195 def _TestJsonTimelineExpectation(self, filename, viewport, expected):
196 """Check whether the result for some timeline data is as expected.
197
198 Args:
199 filename: Filename of a json file which contains a
200 expected: The result expected based on the WPT result.
201 """
202 tab = FakeTab()
203 impl = speedindex.PaintRectSpeedIndexImpl()
204 file_path = os.path.join(_TEST_DIR, filename)
205 with open(file_path) as json_file:
206 raw_events = json.load(json_file)
207 timeline_data = inspector_timeline_data.InspectorTimelineData(raw_events)
208 tab.timeline_model.SetAllEvents(
209 model.TimelineModel(timeline_data=timeline_data).GetAllEvents())
210 tab.SetEvaluateJavaScriptResult(viewport)
211 actual = impl.CalculateSpeedIndex(tab)
212 # The result might differ by 1 or more milliseconds due to rounding,
213 # so compare to the nearest 10 milliseconds.
214 self.assertAlmostEqual(actual, expected, places=-1)
215
216 def testCern(self):
217 # Page: http://info.cern.ch/hypertext/WWW/TheProject.html
218 # This page has only one paint event.
219 self._TestJsonTimelineExpectation(
220 'cern_repeat_timeline.json', (1014, 650), 379.0)
221
222 def testBaidu(self):
223 # Page: http://www.baidu.com/
224 # This page has several paint events, but no nested paint events.
225 self._TestJsonTimelineExpectation(
226 'baidu_repeat_timeline.json', (1014, 650), 1761.43)
227
228 def test2ch(self):
229 # Page: http://2ch.net/
230 # This page has several paint events, including nested paint events.
231 self._TestJsonTimelineExpectation(
232 '2ch_repeat_timeline.json', (997, 650), 674.58)
233
234
235 if __name__ == "__main__": 120 if __name__ == "__main__":
236 unittest.main() 121 unittest.main()
OLDNEW
« tools/perf/metrics/speedindex.py ('K') | « tools/perf/metrics/speedindex.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698