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.
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',
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
):
45 super(Endure
, self
).__init
__('RunEndure')
46 # Browser object, saved so that browser.memory_stats can be accessed.
49 # Dictionary of trace name to lists of y-values, for making summary 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
59 def AddCommandLineArgs(cls
, parser
):
60 group
= optparse
.OptionGroup(parser
, 'Endure options')
61 group
.add_option('--perf-stats-interval',
62 dest
='perf_stats_interval',
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."""
89 trace_name
= '%s.%s' % (chart_name
, trace_name
)
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
,
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
] = {
105 'chart_name': chart_name
,
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')
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',
146 self
._iterations
_elapsed
,
148 results
.AddSummaryValue(scalar
.ScalarValue(None, 'total_time', 'seconds',
149 time
.time() - self
._start
_time
,
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
)))