OLD | NEW |
1 # Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 import collections | 5 import collections |
6 import page_sets | 6 import page_sets |
7 import re | 7 import re |
8 | 8 |
9 from measurements import timeline_controller | 9 from measurements import timeline_controller |
10 from metrics import speedindex | 10 from metrics import speedindex |
11 from telemetry import benchmark | 11 from telemetry import benchmark |
12 from telemetry.core import util | 12 from telemetry.core import util |
13 from telemetry.page import page_test | 13 from telemetry.page import page_test |
14 from telemetry.timeline import async_slice as async_slice_module | 14 from telemetry.timeline import async_slice as async_slice_module |
15 from telemetry.timeline import slice as slice_module | 15 from telemetry.timeline import slice as slice_module |
16 from telemetry.value import scalar | 16 from telemetry.value import scalar |
17 | 17 |
| 18 |
18 class _ServiceWorkerTimelineMetric(object): | 19 class _ServiceWorkerTimelineMetric(object): |
19 def AddResultsOfCounters(self, process, counter_regex_string, results): | 20 def AddResultsOfCounters(self, process, counter_regex_string, results): |
20 counter_filter = re.compile(counter_regex_string) | 21 counter_filter = re.compile(counter_regex_string) |
21 for counter_name, counter in process.counters.iteritems(): | 22 for counter_name, counter in process.counters.iteritems(): |
22 if not counter_filter.search(counter_name): | 23 if not counter_filter.search(counter_name): |
23 continue | 24 continue |
24 | 25 |
25 total = sum(counter.totals) | 26 total = sum(counter.totals) |
26 | 27 |
27 # Results objects cannot contain the '.' character, so remove that here. | 28 # Results objects cannot contain the '.' character, so remove that here. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 full_name = thread_name + '|' + sanitized_event_name | 76 full_name = thread_name + '|' + sanitized_event_name |
76 results.AddValue(scalar.ScalarValue( | 77 results.AddValue(scalar.ScalarValue( |
77 results.current_page, full_name, 'ms', total)) | 78 results.current_page, full_name, 'ms', total)) |
78 results.AddValue(scalar.ScalarValue( | 79 results.AddValue(scalar.ScalarValue( |
79 results.current_page, full_name + '_max', 'ms', biggest_jank)) | 80 results.current_page, full_name + '_max', 'ms', biggest_jank)) |
80 results.AddValue(scalar.ScalarValue( | 81 results.AddValue(scalar.ScalarValue( |
81 results.current_page, full_name + '_avg', 'ms', total / len(times))) | 82 results.current_page, full_name + '_avg', 'ms', total / len(times))) |
82 | 83 |
83 | 84 |
84 class _ServiceWorkerMeasurement(page_test.PageTest): | 85 class _ServiceWorkerMeasurement(page_test.PageTest): |
| 86 """Measure Speed Index and TRACE_EVENTs""" |
| 87 |
85 def __init__(self, *args, **kwargs): | 88 def __init__(self, *args, **kwargs): |
86 super(_ServiceWorkerMeasurement, self).__init__(*args, **kwargs) | 89 super(_ServiceWorkerMeasurement, self).__init__(*args, **kwargs) |
87 self._timeline_controller = timeline_controller.TimelineController() | 90 self._timeline_controller = timeline_controller.TimelineController() |
88 self._speed_index = speedindex.SpeedIndexMetric() | 91 self._speed_index = speedindex.SpeedIndexMetric() |
89 self._page_open_times = collections.defaultdict(int) | 92 self._page_open_times = collections.defaultdict(int) |
90 | 93 |
91 def CustomizeBrowserOptions(self, options): | 94 def CustomizeBrowserOptions(self, options): |
92 options.AppendExtraBrowserArgs([ | 95 options.AppendExtraBrowserArgs([ |
93 '--enable-experimental-web-platform-features' | 96 '--enable-experimental-web-platform-features' |
94 ]) | 97 ]) |
95 | 98 |
96 def WillNavigateToPage(self, page, tab): | 99 def WillNavigateToPage(self, page, tab): |
97 self._timeline_controller.SetUp(page, tab) | 100 self._timeline_controller.SetUp(page, tab) |
98 self._timeline_controller.Start(tab) | 101 self._timeline_controller.Start(tab) |
99 self._speed_index.Start(page, tab) | 102 self._speed_index.Start(page, tab) |
100 | 103 |
101 def ValidateAndMeasurePage(self, page, tab, results): | 104 def ValidateAndMeasurePage(self, page, tab, results): |
102 tab.WaitForJavaScriptExpression( | 105 tab.WaitForDocumentReadyStateToBeComplete(40) |
103 '(window.done == null) ? ' + | |
104 '(document.readyState == "complete") : window.done', 40) | |
105 self._timeline_controller.Stop(tab) | 106 self._timeline_controller.Stop(tab) |
106 | 107 |
107 # Measure JavaScript-land | |
108 json = tab.EvaluateJavaScript('window.results || {}') | |
109 for key, value in json.iteritems(): | |
110 results.AddValue(scalar.ScalarValue( | |
111 results.current_page, key, value['units'], value['value'])) | |
112 | |
113 # Retrieve TRACE_EVENTs | 108 # Retrieve TRACE_EVENTs |
114 timeline_metric = _ServiceWorkerTimelineMetric() | 109 timeline_metric = _ServiceWorkerTimelineMetric() |
115 browser_process = self._timeline_controller.model.browser_process | 110 browser_process = self._timeline_controller.model.browser_process |
116 filter_text = '(RegisterServiceWorker|'\ | 111 filter_text = '(RegisterServiceWorker|'\ |
117 'UnregisterServiceWorker|'\ | 112 'UnregisterServiceWorker|'\ |
118 'ProcessAllocate|'\ | 113 'ProcessAllocate|'\ |
119 'FindRegistrationForDocument|'\ | 114 'FindRegistrationForDocument|'\ |
120 'DispatchFetchEvent)' | 115 'DispatchFetchEvent)' |
121 timeline_metric.AddResultsOfEvents( | 116 timeline_metric.AddResultsOfEvents( |
122 browser_process, 'IOThread', filter_text , results) | 117 browser_process, 'IOThread', filter_text , results) |
123 | 118 |
124 # Record Speed Index | 119 # Record Speed Index |
125 def SpeedIndexIsFinished(): | 120 def SpeedIndexIsFinished(): |
126 return self._speed_index.IsFinished(tab) | 121 return self._speed_index.IsFinished(tab) |
127 util.WaitFor(SpeedIndexIsFinished, 60) | 122 util.WaitFor(SpeedIndexIsFinished, 60) |
128 self._speed_index.Stop(page, tab) | 123 self._speed_index.Stop(page, tab) |
129 # Distinguish the first and second load from the subsequent loads | 124 # Distinguish the first and second load from the subsequent loads |
130 url = str(page) | 125 url = str(page) |
131 chart_prefix = 'page_load' | 126 chart_prefix = 'page_load' |
132 self._page_open_times[url] += 1 | 127 self._page_open_times[url] += 1 |
133 if self._page_open_times[url] == 1: | 128 if self._page_open_times[url] == 1: |
134 chart_prefix += '_1st' | 129 chart_prefix += '_1st' |
135 elif self._page_open_times[url] == 2: | 130 elif self._page_open_times[url] == 2: |
136 chart_prefix += '_2nd' | 131 chart_prefix += '_2nd' |
137 else: | 132 else: |
138 chart_prefix += '_later' | 133 chart_prefix += '_later' |
139 self._speed_index.AddResults(tab, results, chart_prefix) | 134 self._speed_index.AddResults(tab, results, chart_prefix) |
140 | 135 |
| 136 |
| 137 class _ServiceWorkerMicroBenchmarkMeasurement(page_test.PageTest): |
| 138 """Measure JS land values and TRACE_EVENTs""" |
| 139 |
| 140 def __init__(self, *args, **kwargs): |
| 141 super(_ServiceWorkerMicroBenchmarkMeasurement, self).__init__(*args, |
| 142 **kwargs) |
| 143 self._timeline_controller = timeline_controller.TimelineController() |
| 144 |
| 145 def CustomizeBrowserOptions(self, options): |
| 146 options.AppendExtraBrowserArgs([ |
| 147 '--enable-experimental-web-platform-features' |
| 148 ]) |
| 149 |
| 150 def WillNavigateToPage(self, page, tab): |
| 151 self._timeline_controller.SetUp(page, tab) |
| 152 self._timeline_controller.Start(tab) |
| 153 |
| 154 def ValidateAndMeasurePage(self, page, tab, results): |
| 155 tab.WaitForJavaScriptExpression('window.done', 40) |
| 156 self._timeline_controller.Stop(tab) |
| 157 |
| 158 # Measure JavaScript-land |
| 159 json = tab.EvaluateJavaScript('window.results || {}') |
| 160 for key, value in json.iteritems(): |
| 161 results.AddValue(scalar.ScalarValue( |
| 162 results.current_page, key, value['units'], value['value'])) |
| 163 |
| 164 # Retrieve TRACE_EVENTs |
| 165 timeline_metric = _ServiceWorkerTimelineMetric() |
| 166 browser_process = self._timeline_controller.model.browser_process |
| 167 filter_text = '(RegisterServiceWorker|'\ |
| 168 'UnregisterServiceWorker|'\ |
| 169 'ProcessAllocate|'\ |
| 170 'FindRegistrationForDocument|'\ |
| 171 'DispatchFetchEvent)' |
| 172 timeline_metric.AddResultsOfEvents( |
| 173 browser_process, 'IOThread', filter_text , results) |
| 174 |
| 175 |
141 @benchmark.Enabled('android') | 176 @benchmark.Enabled('android') |
142 class ServiceWorkerPerfTest(benchmark.Benchmark): | 177 class ServiceWorkerPerfTest(benchmark.Benchmark): |
143 """Performance test on pages controlled by ServiceWorker""" | 178 """Performance test on public applications using ServiceWorker""" |
144 test = _ServiceWorkerMeasurement | 179 test = _ServiceWorkerMeasurement |
145 page_set = page_sets.ServiceWorkerPageSet | 180 page_set = page_sets.ServiceWorkerPageSet |
| 181 |
| 182 |
| 183 @benchmark.Enabled('android') |
| 184 class ServiceWorkerMicroBenchmarkPerfTest(benchmark.Benchmark): |
| 185 """Service Worker performance test using a micro benchmark page set""" |
| 186 test = _ServiceWorkerMicroBenchmarkMeasurement |
| 187 page_set = page_sets.ServiceWorkerMicroBenchmarkPageSet |
OLD | NEW |