def ValidateAndMeasurePage(self, page, tab, results): """On the last tab, cycle through each tab that was opened and then record a single histogram for the tab switching metric.""" browser = tab.browser if len(browser.tabs) != len(page.story_set.stories): return if browser.tabs < 2: raise Exception('Should have at least two tabs for tab switching') # Measure power usage of tabs after quiescence. util.WaitFor(tab.HasReachedQuiescence, 60) if browser.platform.CanMonitorPower(): self._power_metric.Start(page, tab) time.sleep(TabSwitching.SAMPLE_TIME) self._power_metric.Stop(page, tab) self._power_metric.AddResults(tab, results,) histogram_name = 'MPArch.RWH_TabSwitchPaintDuration' histogram_type = histogram_util.BROWSER_HISTOGRAM display_name = 'MPArch_RWH_TabSwitchPaintDuration' first_histogram = histogram_util.GetHistogram( histogram_type, histogram_name, tab) prev_histogram = first_histogram for tab_to_switch in browser.tabs: tab_to_switch.Activate() def _IsDone(): # pylint: disable=W0640 cur_histogram = histogram_util.GetHistogram( histogram_type, histogram_name, tab_to_switch) diff_histogram = histogram_util.SubtractHistogram( cur_histogram, prev_histogram) # TODO(deanliao): Add SubtractHistogramRawValue to process histogram # object instead of JSON string. diff_histogram_count = json.loads(diff_histogram).get('count', 0) return diff_histogram_count > 0 util.WaitFor(_IsDone, 30) # We need to get histogram again instead of getting cur_histogram as # variables modified inside inner function cannot be retrieved. However, # inner function can see external scope's variables. prev_histogram = histogram_util.GetHistogram( histogram_type, histogram_name, tab_to_switch) last_histogram = prev_histogram total_diff_histogram = histogram_util.SubtractHistogram(last_histogram, first_histogram) results.AddSummaryValue( histogram.HistogramValue(None, display_name, 'ms', raw_value_json=total_diff_histogram, important=False)) keychain_metric.KeychainMetric().AddResults(tab, results)
def ValidateAndMeasurePage(self, page, tab, results): """On the last tab, cycle through each tab that was opened and then record a single histogram for the tab switching metric.""" if len(tab.browser.tabs) != len(page.page_set.pages): return # Measure power usage of tabs after quiescence. util.WaitFor(tab.HasReachedQuiescence, 60) if tab.browser.platform.CanMonitorPower(): self._power_metric.Start(page, tab) time.sleep(TabSwitching.SAMPLE_TIME) self._power_metric.Stop(page, tab) self._power_metric.AddResults( tab, results, ) histogram_name = 'MPArch.RWH_TabSwitchPaintDuration' histogram_type = histogram_util.BROWSER_HISTOGRAM display_name = 'MPArch_RWH_TabSwitchPaintDuration' first_histogram = histogram_util.GetHistogram(histogram_type, histogram_name, tab) prev_histogram = first_histogram for i in xrange(len(tab.browser.tabs)): t = tab.browser.tabs[i] t.Activate() def _IsDone(): cur_histogram = histogram_util.GetHistogram( histogram_type, histogram_name, tab) diff_histogram = histogram_util.SubtractHistogram( cur_histogram, prev_histogram) return diff_histogram util.WaitFor(_IsDone, 30) prev_histogram = histogram_util.GetHistogram( histogram_type, histogram_name, tab) last_histogram = histogram_util.GetHistogram(histogram_type, histogram_name, tab) diff_histogram = histogram_util.SubtractHistogram( last_histogram, first_histogram) results.AddSummaryValue( histogram.HistogramValue(None, display_name, 'ms', raw_value_json=diff_histogram, important=False)) keychain_metric.KeychainMetric().AddResults(tab, results)
def _GetTabSwitchHistogram(browser): """Gets MPArch.RWH_TabSwitchPaintDuration histogram. Catches exceptions to handle devtools context lost cases. Any tab context can be used to get the TabSwitchPaintDuration histogram. browser.tabs[-1] is the last valid context. Ex: If the browser opens A, B, ..., I, J tabs, E, F, G tabs have valid contexts (not discarded), then browser.tab[0] is tab E, browser.tab[-1] is tab G. In the tab switching benchmark, the tabs are opened and switched to in 1, 2, ..., n order. The tabs are discarded in roughly 1, 2, ..., n order (LRU order). The chance of discarding the last valid context is lower than discarding the first valid context. Args: browser: Gets histogram from this browser. Returns: A json serialization of a histogram or None if get histogram failed. """ histogram_name = 'MPArch.RWH_TabSwitchPaintDuration' histogram_type = histogram_util.BROWSER_HISTOGRAM try: return histogram_util.GetHistogram(histogram_type, histogram_name, browser.tabs[-1]) except (exceptions.DevtoolsTargetCrashException, KeyError): logging.warning('GetHistogram: Devtools context lost.') except exceptions.TimeoutException: logging.warning('GetHistogram: Timed out getting histogram.') return None
def _GetMaxDetachedContextAge(tab, data_start): data = histogram_util.GetHistogram(_TYPE, _NAME, tab) delta = histogram_util.SubtractHistogram(data, data_start) if not 'buckets' in delta: return buckets = json.loads(delta)['buckets'] if buckets: return max(x.get('high', x['low']) for x in buckets)
def AddResults(self, tab, results): for h in HISTOGRAMS_TO_RECORD: result = json.loads(histogram_util.GetHistogram( h['type'], h['name'], tab)) if 'sum' in result: # For all the histograms logged here, there's a single entry so sum # is the exact value for that entry. results.AddValue(scalar.ScalarValue( results.current_page, h['display_name'], h['units'], result['sum']))
def Start(self, page, tab): self._started = True for h in HISTOGRAMS_TO_RECORD: histogram_data = histogram_util.GetHistogram( h['type'], h['name'], tab) # Histogram data may not be available if not histogram_data: continue self._histogram_start[h['name']] = histogram_data
def _IsDone(): # pylint: disable=W0640 cur_histogram = histogram_util.GetHistogram( histogram_type, histogram_name, tab_to_switch) diff_histogram = histogram_util.SubtractHistogram( cur_histogram, prev_histogram) # TODO(deanliao): Add SubtractHistogramRawValue to process histogram # object instead of JSON string. diff_histogram_count = json.loads(diff_histogram).get('count', 0) return diff_histogram_count > 0
def Start(self, page, tab): """Start the per-page preparation for this metric. Here, this consists of recording the start value of all the histograms. """ for h in _HISTOGRAMS: histogram_data = histogram_util.GetHistogram( h['type'], h['name'], tab) # Histogram data may not be available if not histogram_data: continue self._histogram_start[h['name']] = histogram_data
def Stop(self, page, tab): assert self._started, 'Must call Start() first' for h in HISTOGRAMS_TO_RECORD: # Histogram data may not be available if h['name'] not in self._histogram_start: continue histogram_data = histogram_util.GetHistogram( h['type'], h['name'], tab) if not histogram_data: continue self._histogram_delta[h['name']] = histogram_util.SubtractHistogram( histogram_data, self._histogram_start[h['name']])
def Stop(self, page, tab): """Prepare the results for this page. The results are the differences between the current histogram values and the values when Start() was called. """ assert self._histogram_start, 'Must call Start() first' for h in _HISTOGRAMS: # Histogram data may not be available if h['name'] not in self._histogram_start: continue histogram_data = histogram_util.GetHistogram( h['type'], h['name'], tab) self._histogram_delta[h['name']] = histogram_util.SubtractHistogram( histogram_data, self._histogram_start[h['name']])
def Start(self, page, tab): """Start the per-page preparation for this metric. Here, this consists of recording the start value of all the histograms. """ if not self._browser.supports_memory_metrics: logging.warning('Memory metrics not supported.') return for h in _HISTOGRAMS: histogram_data = histogram_util.GetHistogram( h['type'], h['name'], tab) # Histogram data may not be available if not histogram_data: continue self._histogram_start[h['name']] = histogram_data
def AddResultsForQuicTransaction(self, tab, results): histogram_type = histogram_util.BROWSER_HISTOGRAM # This histogram should be synchronously created when the Navigate occurs. # Verify that histogram DataReductionProxy.Quic.ProxyStatus has no samples # in bucket >=1. fail_counts_proxy_status = histogram_util.GetHistogramSum( histogram_type, 'DataReductionProxy.Quic.ProxyStatus', tab) if fail_counts_proxy_status != 0: raise ChromeProxyMetricException, ( 'fail_counts_proxy_status is %d.' % fail_counts_proxy_status) # Verify that histogram DataReductionProxy.Quic.ProxyStatus has at least 1 # sample. This sample must be in bucket 0 (QUIC_PROXY_STATUS_AVAILABLE). success_counts_proxy_status = histogram_util.GetHistogramCount( histogram_type, 'DataReductionProxy.Quic.ProxyStatus', tab) if success_counts_proxy_status <= 0: raise ChromeProxyMetricException, ( 'success_counts_proxy_status is %d.' % success_counts_proxy_status) # Navigate to one more page to ensure that established QUIC connection # is used for the next request. Give 1 second extra headroom for the QUIC # connection to be established. time.sleep(1) tab.Navigate('http://check.googlezip.net/test.html') proxy_usage_histogram_json = histogram_util.GetHistogram(histogram_type, 'Net.QuicAlternativeProxy.Usage', tab) proxy_usage_histogram = json.loads(proxy_usage_histogram_json) # Bucket ALTERNATIVE_PROXY_USAGE_NO_RACE should have at least one sample. if proxy_usage_histogram['buckets'][0]['count'] <= 0: raise ChromeProxyMetricException, ( 'Number of samples in ALTERNATIVE_PROXY_USAGE_NO_RACE bucket is %d.' % proxy_usage_histogram['buckets'][0]['count']) results.AddValue(scalar.ScalarValue( results.current_page, 'fail_counts_proxy_status', 'count', fail_counts_proxy_status)) results.AddValue(scalar.ScalarValue( results.current_page, 'success_counts_proxy_status', 'count', success_counts_proxy_status))
def ValidateAndMeasurePage(self, page, tab, results): tab.WaitForDocumentReadyStateToBeComplete() super(SessionRestore, self).ValidateAndMeasurePage(page, tab, results) # Record CPU usage from browser start to when the foreground page is loaded. self._cpu_metric.Stop(None, None) self._cpu_metric.AddResults(tab, results, 'cpu_utilization') for h in _HISTOGRAMS: histogram_data = histogram_util.GetHistogram( histogram_util.BROWSER_HISTOGRAM, h['name'], tab) results.AddValue( histogram.HistogramValue(page, h['display_name'], 'ms', raw_value_json=histogram_data, important=False))
def _IsDone(): cur_histogram = histogram_util.GetHistogram( histogram_type, histogram_name, tab) diff_histogram = histogram_util.SubtractHistogram( cur_histogram, prev_histogram) return diff_histogram
def DidNavigateToPage(self, page, tab): self._data_start = histogram_util.GetHistogram(_TYPE, _NAME, tab)
def _GetTabSwitchHistogram(cls, tab_to_switch): histogram_name = 'MPArch.RWH_TabSwitchPaintDuration' histogram_type = histogram_util.BROWSER_HISTOGRAM return histogram_util.GetHistogram( histogram_type, histogram_name, tab_to_switch)