media/webrtc/trunk/build/android/pylib/device_stats_monitor.py

Wed, 31 Dec 2014 13:27:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 13:27:57 +0100
branch
TOR_BUG_3246
changeset 6
8bccb770b82d
permissions
-rw-r--r--

Ignore runtime configuration files generated during quality assurance.

     1 # Copyright (c) 2012 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.
     5 """Utilities for iotop/top style profiling for android."""
     7 import collections
     8 import json
     9 import os
    10 import subprocess
    11 import sys
    12 import urllib
    14 import constants
    15 import io_stats_parser
    18 class DeviceStatsMonitor(object):
    19   """Class for collecting device stats such as IO/CPU usage.
    21   Args:
    22       adb: Instance of AndroidComannds.
    23       hz: Frequency at which to sample device stats.
    24   """
    26   DEVICE_PATH = constants.TEST_EXECUTABLE_DIR + '/device_stats_monitor'
    27   PROFILE_PATH = (constants.DEVICE_PERF_OUTPUT_DIR +
    28       '/device_stats_monitor.profile')
    29   RESULT_VIEWER_PATH = os.path.abspath(os.path.join(
    30       os.path.dirname(os.path.realpath(__file__)), 'device_stats_monitor.html'))
    32   def __init__(self, adb, hz, build_type):
    33     self._adb = adb
    34     host_path = os.path.abspath(os.path.join(
    35         constants.CHROME_DIR, 'out', build_type, 'device_stats_monitor'))
    36     self._adb.PushIfNeeded(host_path, DeviceStatsMonitor.DEVICE_PATH)
    37     self._hz = hz
    39   def Start(self):
    40     """Starts device stats monitor on the device."""
    41     self._adb.SetFileContents(DeviceStatsMonitor.PROFILE_PATH, '')
    42     self._process = subprocess.Popen(
    43         ['adb', 'shell', '%s --hz=%d %s' % (
    44             DeviceStatsMonitor.DEVICE_PATH, self._hz,
    45             DeviceStatsMonitor.PROFILE_PATH)])
    47   def StopAndCollect(self, output_path):
    48     """Stops monitoring and saves results.
    50     Args:
    51       output_path: Path to save results.
    53     Returns:
    54       String of URL to load results in browser.
    55     """
    56     assert self._process
    57     self._adb.KillAll(DeviceStatsMonitor.DEVICE_PATH)
    58     self._process.wait()
    59     profile = self._adb.GetFileContents(DeviceStatsMonitor.PROFILE_PATH)
    61     results = collections.defaultdict(list)
    62     last_io_stats = None
    63     last_cpu_stats = None
    64     for line in profile:
    65       if ' mmcblk0 ' in line:
    66         stats = io_stats_parser.ParseIoStatsLine(line)
    67         if last_io_stats:
    68           results['sectors_read'].append(stats.num_sectors_read -
    69                                          last_io_stats.num_sectors_read)
    70           results['sectors_written'].append(stats.num_sectors_written -
    71                                             last_io_stats.num_sectors_written)
    72         last_io_stats = stats
    73       elif line.startswith('cpu '):
    74         stats = self._ParseCpuStatsLine(line)
    75         if last_cpu_stats:
    76           results['user'].append(stats.user - last_cpu_stats.user)
    77           results['nice'].append(stats.nice - last_cpu_stats.nice)
    78           results['system'].append(stats.system - last_cpu_stats.system)
    79           results['idle'].append(stats.idle - last_cpu_stats.idle)
    80           results['iowait'].append(stats.iowait - last_cpu_stats.iowait)
    81           results['irq'].append(stats.irq - last_cpu_stats.irq)
    82           results['softirq'].append(stats.softirq- last_cpu_stats.softirq)
    83         last_cpu_stats = stats
    84     units = {
    85       'sectors_read': 'sectors',
    86       'sectors_written': 'sectors',
    87       'user': 'jiffies',
    88       'nice': 'jiffies',
    89       'system': 'jiffies',
    90       'idle': 'jiffies',
    91       'iowait': 'jiffies',
    92       'irq': 'jiffies',
    93       'softirq': 'jiffies',
    94     }
    95     with open(output_path, 'w') as f:
    96       f.write('display(%d, %s, %s);' % (self._hz, json.dumps(results), units))
    97     return 'file://%s?results=file://%s' % (
    98         DeviceStatsMonitor.RESULT_VIEWER_PATH, urllib.quote(output_path))
   101   @staticmethod
   102   def _ParseCpuStatsLine(line):
   103     """Parses a line of cpu stats into a CpuStats named tuple."""
   104     # Field definitions: http://www.linuxhowtos.org/System/procstat.htm
   105     cpu_stats = collections.namedtuple('CpuStats',
   106                                        ['device',
   107                                         'user',
   108                                         'nice',
   109                                         'system',
   110                                         'idle',
   111                                         'iowait',
   112                                         'irq',
   113                                         'softirq',
   114                                        ])
   115     fields = line.split()
   116     return cpu_stats._make([fields[0]] + [int(f) for f in fields[1:8]])

mercurial