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

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

Powered by Google App Engine
This is Rietveld 408576698