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. 4 5import logging 6import os 7import subprocess 8import sys 9 10from telemetry import decorators 11from telemetry.core.platform import platform_backend 12from telemetry.core.platform import posix_platform_backend 13from telemetry.core.platform import proc_supporting_platform_backend 14from telemetry.page import cloud_storage 15from telemetry.util import support_binaries 16 17 18class LinuxPlatformBackend( 19 posix_platform_backend.PosixPlatformBackend, 20 proc_supporting_platform_backend.ProcSupportingPlatformBackend): 21 22 def StartRawDisplayFrameRateMeasurement(self): 23 raise NotImplementedError() 24 25 def StopRawDisplayFrameRateMeasurement(self): 26 raise NotImplementedError() 27 28 def GetRawDisplayFrameRateMeasurements(self): 29 raise NotImplementedError() 30 31 def IsThermallyThrottled(self): 32 raise NotImplementedError() 33 34 def HasBeenThermallyThrottled(self): 35 raise NotImplementedError() 36 37 def GetOSName(self): 38 return 'linux' 39 40 @decorators.Cache 41 def GetOSVersionName(self): 42 if not os.path.exists('/etc/lsb-release'): 43 raise NotImplementedError('Unknown Linux OS version') 44 45 codename = None 46 version = None 47 with open('/etc/lsb-release') as f: 48 for line in f.readlines(): 49 key, _, value = line.partition('=') 50 if key == 'DISTRIB_CODENAME': 51 codename = value.strip() 52 elif key == 'DISTRIB_RELEASE': 53 version = float(value) 54 if codename and version: 55 break 56 return platform_backend.OSVersion(codename, version) 57 58 def CanFlushIndividualFilesFromSystemCache(self): 59 return True 60 61 def FlushEntireSystemCache(self): 62 p = subprocess.Popen(['/sbin/sysctl', '-w', 'vm.drop_caches=3']) 63 p.wait() 64 assert p.returncode == 0, 'Failed to flush system cache' 65 66 def CanLaunchApplication(self, application): 67 if application == 'ipfw' and not self._IsIpfwKernelModuleInstalled(): 68 return False 69 return super(LinuxPlatformBackend, self).CanLaunchApplication(application) 70 71 def InstallApplication(self, application): 72 if application == 'ipfw': 73 self._InstallIpfw() 74 elif application == 'avconv': 75 self._InstallBinary(application, 'libav-tools') 76 elif application == 'perfhost': 77 self._InstallBinary(application, 'linux-tools') 78 else: 79 raise NotImplementedError( 80 'Please teach Telemetry how to install ' + application) 81 82 def _IsIpfwKernelModuleInstalled(self): 83 return 'ipfw_mod' in subprocess.Popen( 84 ['lsmod'], stdout=subprocess.PIPE).communicate()[0] 85 86 def _InstallIpfw(self): 87 ipfw_bin = support_binaries.FindPath('ipfw', self.GetOSName()) 88 ipfw_mod = support_binaries.FindPath('ipfw_mod.ko', self.GetOSName()) 89 90 try: 91 changed = cloud_storage.GetIfChanged( 92 ipfw_bin, cloud_storage.INTERNAL_BUCKET) 93 changed |= cloud_storage.GetIfChanged( 94 ipfw_mod, cloud_storage.INTERNAL_BUCKET) 95 except cloud_storage.CloudStorageError, e: 96 logging.error(e) 97 logging.error('You may proceed by manually installing dummynet. See: ' 98 'http://info.iet.unipi.it/~luigi/dummynet/') 99 sys.exit(1) 100 101 if changed or not self.CanLaunchApplication('ipfw'): 102 if not self._IsIpfwKernelModuleInstalled(): 103 subprocess.check_call(['sudo', 'insmod', ipfw_mod]) 104 os.chmod(ipfw_bin, 0755) 105 subprocess.check_call(['sudo', 'cp', ipfw_bin, '/usr/local/sbin']) 106 107 assert self.CanLaunchApplication('ipfw'), 'Failed to install ipfw' 108 109 def _InstallBinary(self, bin_name, fallback_package=None): 110 bin_path = support_binaries.FindPath(bin_name, self.GetOSName()) 111 os.environ['PATH'] += os.pathsep + os.path.dirname(bin_path) 112 113 try: 114 cloud_storage.GetIfChanged(bin_path, cloud_storage.INTERNAL_BUCKET) 115 os.chmod(bin_path, 0755) 116 except cloud_storage.CloudStorageError, e: 117 logging.error(e) 118 if fallback_package: 119 logging.error('You may proceed by manually installing %s via:\n' 120 'sudo apt-get install %s' % (bin_name, fallback_package)) 121 sys.exit(1) 122 123 assert self.CanLaunchApplication(bin_name), 'Failed to install ' + bin_name 124