Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: chrome/test/functional/media/ui_perf_test_utils.py

Issue 9666032: Cleanup deprecated PyAuto media tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Update year. Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # Copyright (c) 2011 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 """Module for performance testing using the psutil library.
6
7 Ref: http://code.google.com/p/psutil/wiki/Documentation
8
9 Most part of this module is from chrome/test/perf/startup_test.cc and
10 chrome/test/ui/ui_perf_test.[h,cc] So, we try to preserve the original C++ code
11 here in case when there is change in original C++ code, it is easy to update
12 this.
13 """
14
15 # Standard library imports.
16 import logging
17 import re
18 import time
19
20 # Third-party imports.
21 import psutil
22
23
24 class UIPerfTestUtils:
25 """Static utility functions for performance testing."""
26
27 @staticmethod
28 def ConvertDataListToString(data_list):
29 """Convert data array to string that can be used for results on BuildBot.
30
31 Full accuracy of the results coming from the psutil library is not needed
32 for Perf on BuildBot. For now, we show 5 digits here. This function goes
33 through the elements in the data_list and does the conversion as well as
34 adding a prefix and suffix.
35
36 Args:
37 data_list: data list contains measured data from perf test.
38
39 Returns:
40 a string that can be used for perf result shown on Buildbot.
41 """
42 output = '['
43 for data in data_list:
44 output += ('%.5f' % data) + ', '
45 # Remove the last ', '.
46 if output.endswith(', '):
47 output = output[:-2]
48 output += ']'
49 return output
50
51 @staticmethod
52 def GetResultStringForPerfBot(measurement, modifier, trace, values, units):
53 """Get a result string in a format that can be displayed on the PerfBot.
54
55 The following are acceptable (it can be shown in PerfBot) format:
56 <*>RESULT <graph_name>: <trace_name>= <value> <units>
57 <*>RESULT <graph_name>: <trace_name>= {<mean>, <std deviation>} <units>
58 <*>RESULT <graph_name>: <trace_name>= [<value>,value,value,...,] <units>
59
60 Args:
61 measurement: measurement string (such as a parameter list).
62 modifier: modifier string (such as a file name).
63 trace: trace string used for PerfBot graph name (such as 't' or 't_ref').
64 values: list of values that displayed as "[value1,value2....]".
65 units: units of values such as "sec" or "msec".
66
67 Returns:
68 An output string that contains all information, or the empty string if
69 there is no information available.
70 """
71 if not values:
72 return ''
73 output_string = '%sRESULT %s%s: %s= %s %s' % (
74 '', measurement, modifier, trace,
75 UIPerfTestUtils.ConvertDataListToString(values), units)
76 return output_string
77
78 @staticmethod
79 def FindProcesses(process_name):
80 """Find processes for a given process name.
81
82 Args:
83 process_name: a process name string to find.
84
85 Returns:
86 a list of psutil process instances that are associated with the given
87 process name.
88 """
89 target_process_list = []
90 for pid in psutil.get_pid_list():
91 try:
92 p = psutil.Process(pid)
93 # Exact match does not work
94 if process_name in p.name:
95 target_process_list.append(p)
96 except psutil.NoSuchProcess:
97 # Do nothing since the process is already terminated
98 pass
99 return target_process_list
100
101 @staticmethod
102 def GetResourceInfo(process, start_time):
103 """Get resource information coming from psutil.
104
105 This calls corresponding functions in psutil and parses the results.
106
107 TODO(imasaki@chromium.org): Modify this function so that it's not
108 hard-coded to return 7 pieces of information. Instead, you have the
109 caller somehow indicate the number and types of information it needs.
110 Then the function finds and returns the requested info.
111
112 Args:
113 start_time: the time when the program starts (used for recording
114 measured_time).
115 process: psutil's Process instance.
116
117 Returns:
118 a process info tuple: measured_time, cpu_time in percent,
119 user cpu time, system cpu time, resident memory size,
120 virtual memory size, and memory usage. None is returned if the
121 resource info cannot be identified.
122 """
123 try:
124 measured_time = time.time()
125 cpu_percent = process.get_cpu_percent(interval=1.0)
126 memory_percent = process.get_memory_percent()
127 m1 = re.search(r'cputimes\(user=(\S+),\s+system=(\S+)\)',
128 str(process.get_cpu_times()))
129 m2 = re.search(r'meminfo\(rss=(\S+),\s+vms=(\S+)\)',
130 str(process.get_memory_info()))
131
132 cputimes_user = float(m1.group(1))
133 cputimes_system = float(m1.group(2))
134
135 # Convert Bytes to MBytes.
136 memory_rss = float(m2.group(1)) / 1000000
137 memory_vms = float(m2.group(2)) / 1000000
138
139 return (measured_time - start_time, cpu_percent, cputimes_user,
140 cputimes_system, memory_rss, memory_vms, memory_percent)
141
142 except psutil.NoSuchProcess:
143 # Do nothing since the process is already terminated.
144 # This may happen due to race condition.
145 return None
146
147 @staticmethod
148 def IsChromeRendererProcess(process):
149 """Check whether the given process is a Chrome Renderer process.
150
151 Args:
152 process: a psutil's Process instance.
153
154 Returns:
155 True if process is a Chrome renderer process. False otherwise.
156 """
157 for line in process.cmdline:
158 if 'type=renderer' in line:
159 return True
160 return False
161
162 @staticmethod
163 def GetChromeRendererProcessInfo(start_time):
164 """Get Chrome renderer process information by psutil.
165
166 Returns:
167 a renderer process info tuple: measured_time, cpu_time in
168 percent, user cpu time, system cpu time, resident memory size, virtual
169 memory size, and memory usage. Or returns an empty list if the Chrome
170 renderer process is not found or more than one renderer process exists.
171 In this case, an error message is written to the log.
172 """
173 chrome_process_list = UIPerfTestUtils.FindProcesses('chrome')
174 chrome_process_info_list = []
175 for p in chrome_process_list:
176 if UIPerfTestUtils.IsChromeRendererProcess(p):
177 # Return the first renderer process's resource info.
178 resource_info = UIPerfTestUtils.GetResourceInfo(p, start_time)
179 if resource_info is not None:
180 chrome_process_info_list.append(resource_info)
181 if not chrome_process_info_list:
182 logging.error('Chrome renderer process does not exist')
183 return []
184 if len(chrome_process_info_list) > 1:
185 logging.error('More than one Chrome renderer processes exists')
186 return []
187 return chrome_process_info_list[0]
188
189 @staticmethod
190 def _GetMaxDataLength(chrome_renderer_process_infos):
191 """Get max data length of process render info.
192
193 This method is necessary since reach run may have different data length.
194 So, you have to get maximum to prevent data from missing.
195
196 Args:
197 measured_data_list : measured_data_list that
198 contain a list of measured data (CPU and memory) at certain intervals
199 over several runs. Each run contains several time data.
200 info -> 0th run -> 0th time -> time stamp, CPU data and memory data
201 -> 1th time -> time stamp, CPU data and memory data
202 .....
203 -> 1th run -> 0th time -> time stamp, CPU data and memory data
204 each run may have different number of measurement.
205
206 Returns:
207 max data length among all runs.
208 """
209 maximum = len(chrome_renderer_process_infos[0])
210 for info in chrome_renderer_process_infos:
211 if maximum < len(info):
212 maximum = len(info)
213 return maximum
214
215 @staticmethod
216 def PrintMeasuredData(measured_data_list, measured_data_name_list,
217 measured_data_unit_list, parameter_string, trace_list,
218 remove_first_result=True, show_time_index=False,
219 reference_build=False, display_filter=None):
220 """Calculate statistics over all results and print them in the format that
221 can be shown on BuildBot.
222
223 Args:
224 measured_data_list: measured_data_list that contains a list of measured
225 data at certain intervals over several runs. Each run should contain
226 the timestamp of the measured time as well.
227 info -> 0th run -> 0th time -> list of measured data
228 (defined in measured_data_name_list)
229 -> 1st time -> list of measured data
230 .....
231 -> 1st run -> 0th time -> list of measured data
232 each run may have different number of measurement.
233 measured_data_name_list: a list of the names for an element of
234 measured_data_list (such as 'measured-time','cpu'). The size of this
235 list should be same as the size of measured_data_unit_list.
236 measured_data_unit_list: a list of the names of the units for an element
237 of measured_data_list. The size of this list should be same as the size
238 of measured_data_name_list.
239 parameter_string: a string that contains all parameters used.
240 (currently not used).
241 trace_list: a list of trace names used for legends in perf graph
242 (for example, ['t','c']). Generally, a trace name is one letter.
243 remove_first_result: a boolean for removing the first result
244 (the first result contains browser startup time).
245 show_time_index: a boolean for showing time index (such as '0' or '1' in
246 'procutil-0' or 'procutil-1') if it is true. Time index is necessary
247 when the same kind of data is measured over a period of time.
248 For example, 'procutil-0' is the first result and 'procutil-1' is the
249 second result. If this is false, the results are aggregated into one
250 result (such as 'procutil', which includes the results from
251 'procutil-0' and 'procutil-1').
252 reference_build: a boolean for indicating this result is computed with
253 reference build binaries. '_ref' is added in trace in the case of
254 reference build.
255 display_filter: a list of names that you want to display in the results.
256 The names should be in |measured_data_name_list|.
257 Returns:
258 An output string that contains all information, or the empty string
259 if there is no information to output.
260 """
261 output_string = ''
262 for measured_data_index in range(len(measured_data_name_list)):
263 if not display_filter or (display_filter and (
264 measured_data_name_list[measured_data_index] in display_filter)):
265 max_data_length = UIPerfTestUtils._GetMaxDataLength(
266 measured_data_list)
267 trace_name = trace_list[measured_data_index]
268 if reference_build:
269 trace_name += '_ref'
270 if show_time_index:
271 for time_index in range(max_data_length):
272 psutil_data = []
273 UIPerfTestUtils._AppendPsUtilData(psutil_data, measured_data_list,
274 remove_first_result, time_index,
275 measured_data_index)
276 name = '%s-%s' % (measured_data_name_list[measured_data_index],
277 str(time_index))
278 output_string += UIPerfTestUtils._GenerateOutputString(
279 name, output_string, trace_name, psutil_data,
280 measured_data_unit_list[measured_data_index])
281 else:
282 psutil_data = []
283 for time_index in range(max_data_length):
284 UIPerfTestUtils._AppendPsUtilData(psutil_data, measured_data_list,
285 remove_first_result, time_index,
286 measured_data_index)
287 name = measured_data_name_list[measured_data_index]
288 output_string += UIPerfTestUtils._GenerateOutputString(
289 name, output_string, trace_name, psutil_data,
290 measured_data_unit_list[measured_data_index])
291 return output_string
292
293 @staticmethod
294 def _AppendPsUtilData(psutil_data, measured_data_list,
295 remove_first_result, time_index, measured_data_index):
296 """Append data measured by psutil to a list.
297
298 Args:
299 psutil_data: a list of data measured by psutil.
300 measured_data_list: current data measured by psutil, which will be
301 appended to |psutil_data|.
302 remove_first_result: a boolean indicating whether or not to remove
303 the first result.
304 time_index: a integer that shows time-wise index for measured data
305 (For example, '0' or '1' in 'procutil-0' or 'procutil-1').
306 measured_data_index: the loop index for |measured_data_list|.
307 """
308 for counter in range(len(measured_data_list)):
309 if not remove_first_result or counter > 0:
310 data_length_for_each = (len(measured_data_list[counter]))
311 if (data_length_for_each > time_index):
312 data = measured_data_list[counter][time_index][measured_data_index]
313 psutil_data.append(data)
314
315 @staticmethod
316 def _GenerateOutputString(name, output_string, trace_name, psutil_data,
317 measured_data_unit):
318 """Generates the output string that will be used for perf result.
319
320 Args:
321 name: a string for the graph name.
322 output_string: the whole string for displaying results.
323 trace_name: the name for legend in the performance graph.
324 psutil_data: the measured list of data measured by psutil.
325 measured_data_unit: the measurement unit name.
326
327 Returns:
328 a string for performance results that are used for PerfBot if there
329 is any result. Otherwise, returns an empty string.
330 """
331 output_string_line = UIPerfTestUtils.GetResultStringForPerfBot(
332 '', name, trace_name, psutil_data, measured_data_unit)
333 if output_string_line:
334 return output_string_line + '\n'
335 else:
336 return ''
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698