# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import logging
+import os
import subprocess
+import sys
+from telemetry import decorators
+from telemetry.core import util
+from telemetry.core.platform import platform_backend
from telemetry.core.platform import posix_platform_backend
-from telemetry.core.platform import proc_util
+from telemetry.core.platform import proc_supporting_platform_backend
+from telemetry.page import cloud_storage
-class LinuxPlatformBackend(posix_platform_backend.PosixPlatformBackend):
+class LinuxPlatformBackend(
+ posix_platform_backend.PosixPlatformBackend,
+ proc_supporting_platform_backend.ProcSupportingPlatformBackend):
def StartRawDisplayFrameRateMeasurement(self):
raise NotImplementedError()
def HasBeenThermallyThrottled(self):
raise NotImplementedError()
- def GetSystemCommitCharge(self):
- meminfo_contents = self._GetFileContents('/proc/meminfo')
- return proc_util.GetSystemCommitCharge(meminfo_contents)
-
- def GetCpuStats(self, pid):
- stats = self._GetFileContents('/proc/%s/stat' % pid).split()
- return proc_util.GetCpuStats(stats)
-
- def GetCpuTimestamp(self):
- timer_list = self._GetFileContents('/proc/timer_list')
- return proc_util.GetTimestampJiffies(timer_list)
-
- def GetMemoryStats(self, pid):
- status = self._GetFileContents('/proc/%s/status' % pid)
- stats = self._GetFileContents('/proc/%s/stat' % pid).split()
- return proc_util.GetMemoryStats(status, stats)
-
- def GetIOStats(self, pid):
- io_contents = self._GetFileContents('/proc/%s/io' % pid)
- return proc_util.GetIOStats(io_contents)
-
def GetOSName(self):
return 'linux'
+ @decorators.Cache
+ def GetOSVersionName(self):
+ if not os.path.exists('/etc/lsb-release'):
+ raise NotImplementedError('Unknown Linux OS version')
+
+ codename = None
+ version = None
+ for line in open('/etc/lsb-release', 'r').readlines():
+ key, _, value = line.partition('=')
+ if key == 'DISTRIB_CODENAME':
+ codename = value.strip()
+ elif key == 'DISTRIB_RELEASE':
+ version = float(value)
+ if codename and version:
+ break
+ return platform_backend.OSVersion(codename, version)
+
def CanFlushIndividualFilesFromSystemCache(self):
return True
p = subprocess.Popen(['/sbin/sysctl', '-w', 'vm.drop_caches=3'])
p.wait()
assert p.returncode == 0, 'Failed to flush system cache'
+
+ def CanLaunchApplication(self, application):
+ if application == 'ipfw' and not self._IsIpfwKernelModuleInstalled():
+ return False
+ return super(LinuxPlatformBackend, self).CanLaunchApplication(application)
+
+ def InstallApplication(self, application):
+ if application == 'ipfw':
+ self._InstallIpfw()
+ elif application == 'avconv':
+ self._InstallAvconv()
+ else:
+ raise NotImplementedError(
+ 'Please teach Telemetry how to install ' + application)
+
+ def _IsIpfwKernelModuleInstalled(self):
+ return 'ipfw_mod' in subprocess.Popen(
+ ['lsmod'], stdout=subprocess.PIPE).communicate()[0]
+
+ def _InstallIpfw(self):
+ ipfw_bin = os.path.join(util.GetTelemetryDir(), 'bin', 'ipfw')
+ ipfw_mod = os.path.join(util.GetTelemetryDir(), 'bin', 'ipfw_mod.ko')
+
+ try:
+ changed = cloud_storage.GetIfChanged(
+ ipfw_bin, cloud_storage.INTERNAL_BUCKET)
+ changed |= cloud_storage.GetIfChanged(
+ ipfw_mod, cloud_storage.INTERNAL_BUCKET)
+ except cloud_storage.CloudStorageError, e:
+ logging.error(e)
+ logging.error('You may proceed by manually installing dummynet. See: '
+ 'http://info.iet.unipi.it/~luigi/dummynet/')
+ sys.exit(1)
+
+ if changed or not self.CanLaunchApplication('ipfw'):
+ if not self._IsIpfwKernelModuleInstalled():
+ subprocess.check_call(['sudo', 'insmod', ipfw_mod])
+ os.chmod(ipfw_bin, 0755)
+ subprocess.check_call(['sudo', 'cp', ipfw_bin, '/usr/local/sbin'])
+
+ assert self.CanLaunchApplication('ipfw'), 'Failed to install ipfw'
+
+ def _InstallAvconv(self):
+ telemetry_bin_dir = os.path.join(util.GetTelemetryDir(), 'bin')
+ avconv_bin = os.path.join(telemetry_bin_dir, 'avconv')
+ os.environ['PATH'] += os.pathsep + telemetry_bin_dir
+
+ try:
+ cloud_storage.GetIfChanged(avconv_bin, cloud_storage.INTERNAL_BUCKET)
+ except cloud_storage.CloudStorageError, e:
+ logging.error(e)
+ logging.error('You may proceed by manually installing avconv via:\n'
+ 'sudo apt-get install libav-tools')
+ sys.exit(1)
+
+ assert self.CanLaunchApplication('avconv'), 'Failed to install avconv'