| 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 |