OLD | NEW |
| (Empty) |
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. | |
4 | |
5 import optparse | |
6 import time | |
7 | |
8 from metrics import v8_object_stats | |
9 from telemetry.page import page_test | |
10 from telemetry.value import scalar | |
11 | |
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', | |
23 ] | |
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', | |
33 ] | |
34 _V8_MEMORY_ALLOCATED = [ | |
35 'V8.OsMemoryAllocated', | |
36 ] | |
37 | |
38 | |
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): | |
43 | |
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 | |
48 | |
49 # Dictionary of trace name to lists of y-values, for making summary values. | |
50 self._y_values = {} | |
51 | |
52 # Number of page repetitions since the start of the test. | |
53 self._iterations_elapsed = 0 | |
54 | |
55 # Start time of the test, used to report total time. | |
56 self._start_time = None | |
57 | |
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) | |
67 | |
68 def DidStartBrowser(self, browser): | |
69 """Initializes the measurement after the browser is started.""" | |
70 self._browser = browser | |
71 self._start_time = time.time() | |
72 | |
73 def CustomizeBrowserOptions(self, options): | |
74 """Adds extra command-line options to the browser.""" | |
75 v8_object_stats.V8ObjectStatsMetric.CustomizeBrowserOptions(options) | |
76 | |
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) | |
82 | |
83 def _SampleStats(self, tab, results): | |
84 """Records information and add it to the results.""" | |
85 | |
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)) | |
100 | |
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': [], | |
107 } | |
108 self._y_values[trace_name]['values'].append(value_y) | |
109 | |
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') | |
117 | |
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') | |
128 | |
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') | |
140 | |
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)) | |
151 | |
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))) | |
OLD | NEW |