• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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