1# Copyright (c) 2012 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 5import re 6 7import android_commands 8import math 9 10# Valid values of result type. 11RESULT_TYPES = {'unimportant': 'RESULT ', 12 'default': '*RESULT ', 13 'informational': ''} 14 15 16def _EscapePerfResult(s): 17 """Escapes |s| for use in a perf result.""" 18 # Colons (:) and equal signs (=) are not allowed, and we chose an arbitrary 19 # limit of 40 chars. 20 return re.sub(':|=', '_', s[:40]) 21 22 23def PrintPerfResult(measurement, trace, values, units, result_type='default', 24 print_to_stdout=True): 25 """Prints numerical data to stdout in the format required by perf tests. 26 27 The string args may be empty but they must not contain any colons (:) or 28 equals signs (=). 29 30 Args: 31 measurement: A description of the quantity being measured, e.g. "vm_peak". 32 trace: A description of the particular data point, e.g. "reference". 33 values: A list of numeric measured values. 34 units: A description of the units of measure, e.g. "bytes". 35 result_type: A tri-state that accepts values of ['unimportant', 'default', 36 'informational']. 'unimportant' prints RESULT, 'default' prints *RESULT 37 and 'informational' prints nothing. 38 print_to_stdout: If True, prints the output in stdout instead of returning 39 the output to caller. 40 41 Returns: 42 String of the formated perf result. 43 """ 44 assert result_type in RESULT_TYPES, 'result type: %s is invalid' % result_type 45 46 assert isinstance(values, list) 47 assert len(values) 48 assert '/' not in measurement 49 avg = None 50 sd = None 51 if len(values) > 1: 52 try: 53 value = '[%s]' % ','.join([str(v) for v in values]) 54 avg = sum([float(v) for v in values]) / len(values) 55 sqdiffs = [(float(v) - avg) ** 2 for v in values] 56 variance = sum(sqdiffs) / (len(values) - 1) 57 sd = math.sqrt(variance) 58 except ValueError: 59 value = ", ".join(values) 60 else: 61 value = values[0] 62 63 trace_name = _EscapePerfResult(trace) 64 output = '%s%s: %s%s%s %s' % ( 65 RESULT_TYPES[result_type], 66 _EscapePerfResult(measurement), 67 trace_name, 68 # Do not show equal sign if the trace is empty. Usually it happens when 69 # measurement is enough clear to describe the result. 70 '= ' if trace_name else '', 71 value, 72 units) 73 if avg: 74 output += '\nAvg %s: %f%s' % (measurement, avg, units) 75 if sd: 76 output += '\nSd %s: %f%s' % (measurement, sd, units) 77 if print_to_stdout: 78 print output 79 return output 80 81 82class PerfTestSetup(object): 83 """Provides methods for setting up a device for perf testing.""" 84 _DROP_CACHES = '/proc/sys/vm/drop_caches' 85 _SCALING_GOVERNOR = '/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor' 86 87 def __init__(self, adb): 88 self._adb = adb 89 num_cpus = self._adb.GetFileContents('/sys/devices/system/cpu/online', 90 log_result=False) 91 assert num_cpus, 'Unable to find /sys/devices/system/cpu/online' 92 self._num_cpus = int(num_cpus[0].split('-')[-1]) 93 self._original_scaling_governor = None 94 95 def DropRamCaches(self): 96 """Drops the filesystem ram caches for performance testing.""" 97 if not self._adb.IsRootEnabled(): 98 self._adb.EnableAdbRoot() 99 self._adb.RunShellCommand('sync') 100 self._adb.RunShellCommand('echo 3 > ' + PerfTestSetup._DROP_CACHES) 101 102 def SetUp(self): 103 """Sets up performance tests.""" 104 if not self._original_scaling_governor: 105 self._original_scaling_governor = self._adb.GetFileContents( 106 PerfTestSetup._SCALING_GOVERNOR % 0, 107 log_result=False)[0] 108 self._SetScalingGovernorInternal('performance') 109 self.DropRamCaches() 110 111 def TearDown(self): 112 """Tears down performance tests.""" 113 if self._original_scaling_governor: 114 self._SetScalingGovernorInternal(self._original_scaling_governor) 115 self._original_scaling_governor = None 116 117 def _SetScalingGovernorInternal(self, value): 118 for cpu in range(self._num_cpus): 119 self._adb.RunShellCommand( 120 ('echo %s > ' + PerfTestSetup._SCALING_GOVERNOR) % (value, cpu)) 121