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.

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

mercurial