Change UMA proto product field to be an int32.
[chromium-blink-merge.git] / tools / perf / measurements / endure.py
blobd3ca6c8cf9b0656e90a5cc1411383882d1726dd8
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
3 # found in the LICENSE file.
5 import optparse
6 import time
8 from metrics import v8_object_stats
9 from telemetry.page import page_test
10 from telemetry.value import scalar
12 # V8 statistics counter names. These can be retrieved using
13 # v8_object_stats.V8ObjectStatsMetric.GetV8StatsTable.
14 _V8_BYTES_COMMITTED = [
15 'V8.MemoryNewSpaceBytesCommitted',
16 'V8.MemoryOldPointerSpaceBytesCommitted',
17 'V8.MemoryOldDataSpaceBytesCommitted',
18 'V8.MemoryCodeSpaceBytesCommitted',
19 'V8.MemoryMapSpaceBytesCommitted',
20 'V8.MemoryCellSpaceBytesCommitted',
21 'V8.MemoryPropertyCellSpaceBytesCommitted',
22 'V8.MemoryLoSpaceBytesCommitted',
24 _V8_BYTES_USED = [
25 'V8.MemoryNewSpaceBytesUsed',
26 'V8.MemoryOldPointerSpaceBytesUsed',
27 'V8.MemoryOldDataSpaceBytesUsed',
28 'V8.MemoryCodeSpaceBytesUsed',
29 'V8.MemoryMapSpaceBytesUsed',
30 'V8.MemoryCellSpaceBytesUsed',
31 'V8.MemoryPropertyCellSpaceBytesUsed',
32 'V8.MemoryLoSpaceBytesUsed',
34 _V8_MEMORY_ALLOCATED = [
35 'V8.OsMemoryAllocated',
39 # NOTE(chrishenry): This measurement does NOT work anymore. The
40 # feature it depends on has been removed from telemetry. The benchmark
41 # has been disabled on bot.
42 class Endure(page_test.PageTest):
44 def __init__(self):
45 super(Endure, self).__init__('RunEndure')
46 # Browser object, saved so that browser.memory_stats can be accessed.
47 self._browser = None
49 # Dictionary of trace name to lists of y-values, for making summary values.
50 self._y_values = {}
52 # Number of page repetitions since the start of the test.
53 self._iterations_elapsed = 0
55 # Start time of the test, used to report total time.
56 self._start_time = None
58 @classmethod
59 def AddCommandLineArgs(cls, parser):
60 group = optparse.OptionGroup(parser, 'Endure options')
61 group.add_option('--perf-stats-interval',
62 dest='perf_stats_interval',
63 default=1,
64 type='int',
65 help='Number of iterations per sampling of statistics.')
66 parser.add_option_group(group)
68 def DidStartBrowser(self, browser):
69 """Initializes the measurement after the browser is started."""
70 self._browser = browser
71 self._start_time = time.time()
73 def CustomizeBrowserOptions(self, options):
74 """Adds extra command-line options to the browser."""
75 v8_object_stats.V8ObjectStatsMetric.CustomizeBrowserOptions(options)
77 def ValidateAndMeasurePage(self, page, tab, results):
78 """Takes a sample and adds a result if enough time has passed."""
79 self._iterations_elapsed += 1
80 if self._iterations_elapsed % int(self.options.perf_stats_interval) == 0:
81 self._SampleStats(tab, results)
83 def _SampleStats(self, tab, results):
84 """Records information and add it to the results."""
86 def AddPoint(trace_name, units_y, value_y, chart_name=None):
87 """Adds one data point to the results object."""
88 if chart_name:
89 trace_name = '%s.%s' % (chart_name, trace_name)
90 else:
91 assert '.' not in trace_name, (
92 'Trace names cannot contain "." with an empty chart_name since this'
93 ' is used to delimit chart_name.trace_name.')
94 results.AddValue(scalar.ScalarValue(
95 results.current_page, trace_name + '_X', 'iterations',
96 self._iterations_elapsed, important=False))
97 results.AddValue(scalar.ScalarValue(
98 results.current_page, trace_name + '_Y', units_y, value_y,
99 important=False))
101 # Save the value so that summary stats can be calculated.
102 if trace_name not in self._y_values:
103 self._y_values[trace_name] = {
104 'units': units_y,
105 'chart_name': chart_name,
106 'values': [],
108 self._y_values[trace_name]['values'].append(value_y)
110 # DOM nodes and event listeners.
111 dom_stats = tab.dom_stats
112 dom_node_count = dom_stats['node_count']
113 event_listener_count = dom_stats['event_listener_count']
114 AddPoint('dom_nodes', 'count', dom_node_count, chart_name='object_counts')
115 AddPoint('event_listeners', 'count', event_listener_count,
116 chart_name='object_counts')
118 # Browser and renderer virtual memory stats.
119 memory_stats = self._browser.memory_stats
120 def BrowserVMStats(statistic_name):
121 """Get VM stats from the Browser object in KB."""
122 return memory_stats[statistic_name].get('VM', 0) / 1024.0
123 AddPoint('browser_vm', 'KB', BrowserVMStats('Browser'),
124 chart_name='vm_stats')
125 AddPoint('renderer_vm', 'KB', BrowserVMStats('Renderer'),
126 chart_name='vm_stats')
127 AddPoint('gpu_vm', 'KB', BrowserVMStats('Gpu'), chart_name='vm_stats')
129 # V8 counter stats.
130 def V8StatsSum(counters):
131 """Given a list of V8 counter names, get the sum of the values in KB."""
132 stats = v8_object_stats.V8ObjectStatsMetric.GetV8StatsTable(tab, counters)
133 return sum(stats.values()) / 1024.0
134 AddPoint('v8_memory_committed', 'KB', V8StatsSum(_V8_BYTES_COMMITTED),
135 chart_name='v8_counter_stats')
136 AddPoint('v8_memory_used', 'KB', V8StatsSum(_V8_BYTES_USED),
137 chart_name='v8_counter_stats')
138 AddPoint('v8_memory_allocated', 'KB', V8StatsSum(_V8_MEMORY_ALLOCATED),
139 chart_name='v8_counter_stats')
141 def DidRunTest(self, browser, results):
142 """Adds summary results (single number for one test run)."""
143 # Report test run length.
144 results.AddSummaryValue(scalar.ScalarValue(None, 'total_iterations',
145 'iterations',
146 self._iterations_elapsed,
147 important=False))
148 results.AddSummaryValue(scalar.ScalarValue(None, 'total_time', 'seconds',
149 time.time() - self._start_time,
150 important=False))
152 # Add summary stats which could be monitored for anomalies.
153 for trace_name in self._y_values:
154 units = self._y_values[trace_name]['units']
155 chart_name = self._y_values[trace_name]['chart_name']
156 values = self._y_values[trace_name]['values']
157 value_name = '%s.%s_max' % (chart_name, trace_name)
158 results.AddSummaryValue(
159 scalar.ScalarValue(None, value_name, units, max(values)))