Update sdk/platform-tools to version 26.0.0.
[android_tools.git] / sdk / platform-tools / systrace / catapult / telemetry / telemetry / internal / platform / linux_platform_backend.py
blob5532d59de4f6a059ff23b018744f121ed60a83c3
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 logging
6 import os
7 import platform
8 import subprocess
9 import sys
11 from py_utils import cloud_storage # pylint: disable=import-error
13 from telemetry.internal.util import binary_manager
14 from telemetry.core import os_version
15 from telemetry.core import util
16 from telemetry import decorators
17 from telemetry.internal.platform import linux_based_platform_backend
18 from telemetry.internal.platform import posix_platform_backend
19 from telemetry.internal.platform.power_monitor import msr_power_monitor
22 _POSSIBLE_PERFHOST_APPLICATIONS = [
23 'perfhost_precise',
24 'perfhost_trusty',
28 class LinuxPlatformBackend(
29 posix_platform_backend.PosixPlatformBackend,
30 linux_based_platform_backend.LinuxBasedPlatformBackend):
31 def __init__(self):
32 super(LinuxPlatformBackend, self).__init__()
33 self._power_monitor = msr_power_monitor.MsrPowerMonitorLinux(self)
35 @classmethod
36 def IsPlatformBackendForHost(cls):
37 return sys.platform.startswith('linux') and not util.IsRunningOnCrosDevice()
39 def IsThermallyThrottled(self):
40 raise NotImplementedError()
42 def HasBeenThermallyThrottled(self):
43 raise NotImplementedError()
45 @decorators.Cache
46 def GetArchName(self):
47 return platform.machine()
49 def GetOSName(self):
50 return 'linux'
52 @decorators.Cache
53 def GetOSVersionName(self):
54 if not os.path.exists('/etc/lsb-release'):
55 raise NotImplementedError('Unknown Linux OS version')
57 codename = None
58 version = None
59 for line in self.GetFileContents('/etc/lsb-release').splitlines():
60 key, _, value = line.partition('=')
61 if key == 'DISTRIB_CODENAME':
62 codename = value.strip()
63 elif key == 'DISTRIB_RELEASE':
64 try:
65 version = float(value)
66 except ValueError:
67 version = 0
68 if codename and version:
69 break
70 return os_version.OSVersion(codename, version)
72 def CanFlushIndividualFilesFromSystemCache(self):
73 return True
75 def SupportFlushEntireSystemCache(self):
76 return self.HasRootAccess()
78 def FlushEntireSystemCache(self):
79 p = subprocess.Popen(['/sbin/sysctl', '-w', 'vm.drop_caches=3'])
80 p.wait()
81 assert p.returncode == 0, 'Failed to flush system cache'
83 def CanLaunchApplication(self, application):
84 if application == 'ipfw' and not self._IsIpfwKernelModuleInstalled():
85 return False
86 return super(LinuxPlatformBackend, self).CanLaunchApplication(application)
88 def InstallApplication(self, application):
89 if application == 'ipfw':
90 self._InstallIpfw()
91 elif application == 'avconv':
92 self._InstallBinary(application)
93 elif application in _POSSIBLE_PERFHOST_APPLICATIONS:
94 self._InstallBinary(application)
95 else:
96 raise NotImplementedError(
97 'Please teach Telemetry how to install ' + application)
99 def CanMonitorPower(self):
100 return self._power_monitor.CanMonitorPower()
102 def CanMeasurePerApplicationPower(self):
103 return self._power_monitor.CanMeasurePerApplicationPower()
105 def StartMonitoringPower(self, browser):
106 self._power_monitor.StartMonitoringPower(browser)
108 def StopMonitoringPower(self):
109 return self._power_monitor.StopMonitoringPower()
111 def ReadMsr(self, msr_number, start=0, length=64):
112 cmd = ['rdmsr', '-d', str(msr_number)]
113 (out, err) = subprocess.Popen(cmd,
114 stdout=subprocess.PIPE,
115 stderr=subprocess.PIPE).communicate()
116 if err:
117 raise OSError(err)
118 try:
119 result = int(out)
120 except ValueError:
121 raise OSError('Cannot interpret rdmsr output: %s' % out)
122 return result >> start & ((1 << length) - 1)
124 def _IsIpfwKernelModuleInstalled(self):
125 return 'ipfw_mod' in subprocess.Popen(
126 ['lsmod'], stdout=subprocess.PIPE).communicate()[0]
128 def _InstallIpfw(self):
129 ipfw_bin = binary_manager.FindPath(
130 'ipfw', self.GetArchName(), self.GetOSName())
131 ipfw_mod = binary_manager.FindPath(
132 'ipfw_mod.ko', self.GetArchName(), self.GetOSName())
134 try:
135 changed = cloud_storage.GetIfChanged(
136 ipfw_bin, cloud_storage.INTERNAL_BUCKET)
137 changed |= cloud_storage.GetIfChanged(
138 ipfw_mod, cloud_storage.INTERNAL_BUCKET)
139 except cloud_storage.CloudStorageError, e:
140 logging.error(str(e))
141 logging.error('You may proceed by manually building and installing'
142 'dummynet for your kernel. See: '
143 'http://info.iet.unipi.it/~luigi/dummynet/')
144 sys.exit(1)
146 if changed or not self.CanLaunchApplication('ipfw'):
147 if not self._IsIpfwKernelModuleInstalled():
148 subprocess.check_call(['/usr/bin/sudo', 'insmod', ipfw_mod])
149 os.chmod(ipfw_bin, 0755)
150 subprocess.check_call(
151 ['/usr/bin/sudo', 'cp', ipfw_bin, '/usr/local/sbin'])
153 assert self.CanLaunchApplication('ipfw'), 'Failed to install ipfw. ' \
154 'ipfw provided binaries are not supported for linux kernel < 3.13. ' \
155 'You may proceed by manually building and installing dummynet for ' \
156 'your kernel. See: http://info.iet.unipi.it/~luigi/dummynet/'
158 def _InstallBinary(self, bin_name):
159 bin_path = binary_manager.FetchPath(
160 bin_name, self.GetArchName(), self.GetOSName())
161 os.environ['PATH'] += os.pathsep + os.path.dirname(bin_path)
162 assert self.CanLaunchApplication(bin_name), 'Failed to install ' + bin_name