OLD | NEW |
1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """Provides a variety of device interactions based on adb. | 5 """Provides a variety of device interactions based on adb. |
6 | 6 |
7 Eventually, this will be based on adb_wrapper. | 7 Eventually, this will be based on adb_wrapper. |
8 """ | 8 """ |
9 # pylint: disable=unused-argument | 9 # pylint: disable=unused-argument |
10 | 10 |
| 11 import collections |
| 12 import itertools |
11 import logging | 13 import logging |
12 import multiprocessing | 14 import multiprocessing |
13 import os | 15 import os |
14 import re | 16 import re |
15 import sys | 17 import sys |
16 import tempfile | 18 import tempfile |
17 import time | 19 import time |
18 import zipfile | 20 import zipfile |
19 | 21 |
20 import pylib.android_commands | 22 import pylib.android_commands |
(...skipping 1278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1299 @decorators.WithTimeoutAndRetriesFromInstance() | 1301 @decorators.WithTimeoutAndRetriesFromInstance() |
1300 def GetMemoryUsageForPid(self, pid, timeout=None, retries=None): | 1302 def GetMemoryUsageForPid(self, pid, timeout=None, retries=None): |
1301 """Gets the memory usage for the given PID. | 1303 """Gets the memory usage for the given PID. |
1302 | 1304 |
1303 Args: | 1305 Args: |
1304 pid: PID of the process. | 1306 pid: PID of the process. |
1305 timeout: timeout in seconds | 1307 timeout: timeout in seconds |
1306 retries: number of retries | 1308 retries: number of retries |
1307 | 1309 |
1308 Returns: | 1310 Returns: |
1309 A 2-tuple containing: | 1311 A dict containing memory usage statistics for the PID. May include: |
1310 - A dict containing the overall memory usage statistics for the PID. | 1312 Size, Rss, Pss, Shared_Clean, Shared_Dirty, Private_Clean, |
1311 - A dict containing memory usage statistics broken down by mapping. | 1313 Private_Dirty, VmHWM |
1312 | 1314 |
1313 Raises: | 1315 Raises: |
1314 CommandTimeoutError on timeout. | 1316 CommandTimeoutError on timeout. |
1315 """ | 1317 """ |
1316 return self.old_interface.GetMemoryUsageForPid(pid) | 1318 result = collections.defaultdict(int) |
| 1319 |
| 1320 try: |
| 1321 result.update(self._GetMemoryUsageForPidFromSmaps(pid)) |
| 1322 except device_errors.CommandFailedError: |
| 1323 logging.exception('Error getting memory usage from smaps') |
| 1324 |
| 1325 try: |
| 1326 result.update(self._GetMemoryUsageForPidFromStatus(pid)) |
| 1327 except device_errors.CommandFailedError: |
| 1328 logging.exception('Error getting memory usage from status') |
| 1329 |
| 1330 return result |
| 1331 |
| 1332 def _GetMemoryUsageForPidFromSmaps(self, pid): |
| 1333 SMAPS_COLUMNS = ( |
| 1334 'Size', 'Rss', 'Pss', 'Shared_Clean', 'Shared_Dirty', 'Private_Clean', |
| 1335 'Private_Dirty') |
| 1336 |
| 1337 showmap_out = self.RunShellCommand( |
| 1338 ['showmap', str(pid)], as_root=True, check_return=True) |
| 1339 if not showmap_out: |
| 1340 raise device_errors.CommandFailedError('No output from showmap') |
| 1341 |
| 1342 split_totals = showmap_out[-1].split() |
| 1343 if (not split_totals |
| 1344 or len(split_totals) != 9 |
| 1345 or split_totals[-1] != 'TOTAL'): |
| 1346 raise device_errors.CommandFailedError( |
| 1347 'Invalid output from showmap: %s' % '\n'.join(showmap_out)) |
| 1348 |
| 1349 return dict(itertools.izip(SMAPS_COLUMNS, (int(n) for n in split_totals))) |
| 1350 |
| 1351 def _GetMemoryUsageForPidFromStatus(self, pid): |
| 1352 for line in self.ReadFile( |
| 1353 '/proc/%s/status' % str(pid), as_root=True).splitlines(): |
| 1354 if line.startswith('VmHWM:'): |
| 1355 return {'VmHWM': int(line.split()[1])} |
| 1356 else: |
| 1357 raise device_errors.CommandFailedError( |
| 1358 'Could not find memory peak value for pid %s', str(pid)) |
1317 | 1359 |
1318 @decorators.WithTimeoutAndRetriesFromInstance() | 1360 @decorators.WithTimeoutAndRetriesFromInstance() |
1319 def GetLogcatMonitor(self, timeout=None, retries=None, *args, **kwargs): | 1361 def GetLogcatMonitor(self, timeout=None, retries=None, *args, **kwargs): |
1320 """Returns a new LogcatMonitor associated with this device. | 1362 """Returns a new LogcatMonitor associated with this device. |
1321 | 1363 |
1322 Parameters passed to this function are passed directly to | 1364 Parameters passed to this function are passed directly to |
1323 |logcat_monitor.LogcatMonitor| and are documented there. | 1365 |logcat_monitor.LogcatMonitor| and are documented there. |
1324 | 1366 |
1325 Args: | 1367 Args: |
1326 timeout: timeout in seconds | 1368 timeout: timeout in seconds |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1379 from which DeviceUtils instances can be constructed. If None, | 1421 from which DeviceUtils instances can be constructed. If None, |
1380 all attached devices will be used. | 1422 all attached devices will be used. |
1381 async: If true, returns a Parallelizer that runs operations | 1423 async: If true, returns a Parallelizer that runs operations |
1382 asynchronously. | 1424 asynchronously. |
1383 | 1425 |
1384 Returns: | 1426 Returns: |
1385 A Parallelizer operating over |devices|. | 1427 A Parallelizer operating over |devices|. |
1386 """ | 1428 """ |
1387 if not devices: | 1429 if not devices: |
1388 devices = adb_wrapper.AdbWrapper.GetDevices() | 1430 devices = adb_wrapper.AdbWrapper.GetDevices() |
| 1431 if not devices: |
| 1432 raise device_errors.NoDevicesError() |
1389 devices = [d if isinstance(d, cls) else cls(d) for d in devices] | 1433 devices = [d if isinstance(d, cls) else cls(d) for d in devices] |
1390 if async: | 1434 if async: |
1391 return parallelizer.Parallelizer(devices) | 1435 return parallelizer.Parallelizer(devices) |
1392 else: | 1436 else: |
1393 return parallelizer.SyncParallelizer(devices) | 1437 return parallelizer.SyncParallelizer(devices) |
OLD | NEW |