Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / tools / telemetry / telemetry / core / platform / linux_platform_backend.py
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
5 import logging
6 import os
7 import platform
8 import subprocess
9 import sys
10
11 from telemetry import decorators
12 from telemetry.core.platform import linux_based_platform_backend
13 from telemetry.core.platform import platform_backend
14 from telemetry.core.platform import posix_platform_backend
15 from telemetry.core.platform.power_monitor import msr_power_monitor
16 from telemetry.util import cloud_storage
17 from telemetry.util import support_binaries
18
19
20 _POSSIBLE_PERFHOST_APPLICATIONS = [
21   'perfhost_precise',
22   'perfhost_trusty',
23 ]
24
25
26 class LinuxPlatformBackend(
27     posix_platform_backend.PosixPlatformBackend,
28     linux_based_platform_backend.LinuxBasedPlatformBackend):
29   def __init__(self):
30     super(LinuxPlatformBackend, self).__init__()
31     self._power_monitor = msr_power_monitor.MsrPowerMonitor(self)
32
33   def StartRawDisplayFrameRateMeasurement(self):
34     raise NotImplementedError()
35
36   def StopRawDisplayFrameRateMeasurement(self):
37     raise NotImplementedError()
38
39   def GetRawDisplayFrameRateMeasurements(self):
40     raise NotImplementedError()
41
42   def IsThermallyThrottled(self):
43     raise NotImplementedError()
44
45   def HasBeenThermallyThrottled(self):
46     raise NotImplementedError()
47
48   @decorators.Cache
49   def GetArchName(self):
50     return platform.machine()
51
52   def GetOSName(self):
53     return 'linux'
54
55   @decorators.Cache
56   def GetOSVersionName(self):
57     if not os.path.exists('/etc/lsb-release'):
58       raise NotImplementedError('Unknown Linux OS version')
59
60     codename = None
61     version = None
62     for line in self.GetFileContents('/etc/lsb-release').splitlines():
63       key, _, value = line.partition('=')
64       if key == 'DISTRIB_CODENAME':
65         codename = value.strip()
66       elif key == 'DISTRIB_RELEASE':
67         try:
68           version = float(value)
69         except ValueError:
70           version = 0
71       if codename and version:
72         break
73     return platform_backend.OSVersion(codename, version)
74
75   def CanFlushIndividualFilesFromSystemCache(self):
76     return True
77
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'
82
83   def CanLaunchApplication(self, application):
84     if application == 'ipfw' and not self._IsIpfwKernelModuleInstalled():
85       return False
86     return super(LinuxPlatformBackend, self).CanLaunchApplication(application)
87
88   def InstallApplication(self, application):
89     if application == 'ipfw':
90       self._InstallIpfw()
91     elif application == 'avconv':
92       self._InstallBinary(application, fallback_package='libav-tools')
93     elif application in _POSSIBLE_PERFHOST_APPLICATIONS:
94       self._InstallBinary(application)
95     else:
96       raise NotImplementedError(
97           'Please teach Telemetry how to install ' + application)
98
99   def CanMonitorPower(self):
100     return self._power_monitor.CanMonitorPower()
101
102   def CanMeasurePerApplicationPower(self):
103     return self._power_monitor.CanMeasurePerApplicationPower()
104
105   def StartMonitoringPower(self, browser):
106     self._power_monitor.StartMonitoringPower(browser)
107
108   def StopMonitoringPower(self):
109     return self._power_monitor.StopMonitoringPower()
110
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)
123
124   def _IsIpfwKernelModuleInstalled(self):
125     return 'ipfw_mod' in subprocess.Popen(
126         ['lsmod'], stdout=subprocess.PIPE).communicate()[0]
127
128   def _InstallIpfw(self):
129     ipfw_bin = support_binaries.FindPath(
130         'ipfw', self.GetArchName(), self.GetOSName())
131     ipfw_mod = support_binaries.FindPath(
132         'ipfw_mod.ko', self.GetArchName(), self.GetOSName())
133
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)
145
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'])
152
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/'
157
158   def _InstallBinary(self, bin_name, fallback_package=None):
159     bin_path = support_binaries.FindPath(
160         bin_name, self.GetArchName(), self.GetOSName())
161     if not bin_path:
162       raise Exception('Could not find the binary package %s' % bin_name)
163     os.environ['PATH'] += os.pathsep + os.path.dirname(bin_path)
164
165     try:
166       cloud_storage.GetIfChanged(bin_path, cloud_storage.INTERNAL_BUCKET)
167       os.chmod(bin_path, 0755)
168     except cloud_storage.CloudStorageError, e:
169       logging.error(str(e))
170       if fallback_package:
171         raise Exception('You may proceed by manually installing %s via:\n'
172                         'sudo apt-get install %s' %
173                         (bin_name, fallback_package))
174
175     assert self.CanLaunchApplication(bin_name), 'Failed to install ' + bin_name