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.
10 from telemetry import decorators
11 from telemetry.core.platform import linux_based_platform_backend
12 from telemetry.core.platform import platform_backend
13 from telemetry.core.platform import posix_platform_backend
14 from telemetry.core.platform.power_monitor import msr_power_monitor
15 from telemetry.util import cloud_storage
16 from telemetry.util import support_binaries
19 _POSSIBLE_PERFHOST_APPLICATIONS = [
25 class LinuxPlatformBackend(
26 posix_platform_backend.PosixPlatformBackend,
27 linux_based_platform_backend.LinuxBasedPlatformBackend):
29 super(LinuxPlatformBackend, self).__init__()
30 self._power_monitor = msr_power_monitor.MsrPowerMonitor(self)
32 def StartRawDisplayFrameRateMeasurement(self):
33 raise NotImplementedError()
35 def StopRawDisplayFrameRateMeasurement(self):
36 raise NotImplementedError()
38 def GetRawDisplayFrameRateMeasurements(self):
39 raise NotImplementedError()
41 def IsThermallyThrottled(self):
42 raise NotImplementedError()
44 def HasBeenThermallyThrottled(self):
45 raise NotImplementedError()
51 def GetOSVersionName(self):
52 if not os.path.exists('/etc/lsb-release'):
53 raise NotImplementedError('Unknown Linux OS version')
57 for line in self.GetFileContents('/etc/lsb-release').splitlines():
58 key, _, value = line.partition('=')
59 if key == 'DISTRIB_CODENAME':
60 codename = value.strip()
61 elif key == 'DISTRIB_RELEASE':
63 version = float(value)
66 if codename and version:
68 return platform_backend.OSVersion(codename, version)
70 def CanFlushIndividualFilesFromSystemCache(self):
73 def FlushEntireSystemCache(self):
74 p = subprocess.Popen(['/sbin/sysctl', '-w', 'vm.drop_caches=3'])
76 assert p.returncode == 0, 'Failed to flush system cache'
78 def CanLaunchApplication(self, application):
79 if application == 'ipfw' and not self._IsIpfwKernelModuleInstalled():
81 return super(LinuxPlatformBackend, self).CanLaunchApplication(application)
83 def InstallApplication(self, application):
84 if application == 'ipfw':
86 elif application == 'avconv':
87 self._InstallBinary(application, fallback_package='libav-tools')
88 elif application in _POSSIBLE_PERFHOST_APPLICATIONS:
89 self._InstallBinary(application)
91 raise NotImplementedError(
92 'Please teach Telemetry how to install ' + application)
94 def CanMonitorPower(self):
95 return self._power_monitor.CanMonitorPower()
97 def CanMeasurePerApplicationPower(self):
98 return self._power_monitor.CanMeasurePerApplicationPower()
100 def StartMonitoringPower(self, browser):
101 self._power_monitor.StartMonitoringPower(browser)
103 def StopMonitoringPower(self):
104 return self._power_monitor.StopMonitoringPower()
106 def ReadMsr(self, msr_number, start=0, length=64):
107 cmd = ['/usr/sbin/rdmsr', '-d', str(msr_number)]
108 (out, err) = subprocess.Popen(cmd,
109 stdout=subprocess.PIPE,
110 stderr=subprocess.PIPE).communicate()
116 raise OSError('Cannot interpret rdmsr output: %s' % out)
117 return result >> start & ((1 << length) - 1)
119 def _IsIpfwKernelModuleInstalled(self):
120 return 'ipfw_mod' in subprocess.Popen(
121 ['lsmod'], stdout=subprocess.PIPE).communicate()[0]
123 def _InstallIpfw(self):
124 ipfw_bin = support_binaries.FindPath('ipfw', self.GetOSName())
125 ipfw_mod = support_binaries.FindPath('ipfw_mod.ko', self.GetOSName())
128 changed = cloud_storage.GetIfChanged(
129 ipfw_bin, cloud_storage.INTERNAL_BUCKET)
130 changed |= cloud_storage.GetIfChanged(
131 ipfw_mod, cloud_storage.INTERNAL_BUCKET)
132 except cloud_storage.CloudStorageError, e:
133 logging.error(str(e))
134 logging.error('You may proceed by manually building and installing'
135 'dummynet for your kernel. See: '
136 'http://info.iet.unipi.it/~luigi/dummynet/')
139 if changed or not self.CanLaunchApplication('ipfw'):
140 if not self._IsIpfwKernelModuleInstalled():
141 subprocess.check_call(['sudo', 'insmod', ipfw_mod])
142 os.chmod(ipfw_bin, 0755)
143 subprocess.check_call(['sudo', 'cp', ipfw_bin, '/usr/local/sbin'])
145 assert self.CanLaunchApplication('ipfw'), 'Failed to install ipfw. ' \
146 'ipfw provided binaries are not supported for linux kernel < 3.13. ' \
147 'You may proceed by manually building and installing dummynet for ' \
148 'your kernel. See: http://info.iet.unipi.it/~luigi/dummynet/'
150 def _InstallBinary(self, bin_name, fallback_package=None):
151 bin_path = support_binaries.FindPath(bin_name, self.GetOSName())
153 raise Exception('Could not find the binary package %s' % bin_name)
154 os.environ['PATH'] += os.pathsep + os.path.dirname(bin_path)
157 cloud_storage.GetIfChanged(bin_path, cloud_storage.INTERNAL_BUCKET)
158 os.chmod(bin_path, 0755)
159 except cloud_storage.CloudStorageError, e:
160 logging.error(str(e))
162 raise Exception('You may proceed by manually installing %s via:\n'
163 'sudo apt-get install %s' %
164 (bin_name, fallback_package))
166 assert self.CanLaunchApplication(bin_name), 'Failed to install ' + bin_name