Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Side by Side Diff: build/android/pylib/device/device_utils.py

Issue 1077173002: [Android] Tune DeviceUtils commands that are prone to large outputs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase and fix SingleQuote Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
(...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 if not output: 568 if not output:
569 return '' 569 return ''
570 elif len(output) == 1: 570 elif len(output) == 1:
571 return output[0] 571 return output[0]
572 else: 572 else:
573 msg = 'one line of output was expected, but got: %s' 573 msg = 'one line of output was expected, but got: %s'
574 raise device_errors.CommandFailedError(msg % output, str(self)) 574 raise device_errors.CommandFailedError(msg % output, str(self))
575 else: 575 else:
576 return output 576 return output
577 577
578 def _RunPipedShellCommand(self, script, **kwargs):
579 PIPESTATUS_LEADER = 'PIPESTATUS: '
580
581 script += '; echo "%s${PIPESTATUS[@]}"' % PIPESTATUS_LEADER
582 kwargs['check_return'] = True
583 output = self.RunShellCommand(script, **kwargs)
584 pipestatus_line = output[-1]
585
586 if not pipestatus_line.startswith(PIPESTATUS_LEADER):
587 logging.error('Pipe exit statuses of shell script missing.')
588 raise device_errors.AdbShellCommandFailedError(
589 script, output, status=None,
590 device_serial=self.adb.GetDeviceSerial())
591
592 output = output[:-1]
593 statuses = [
594 int(s) for s in pipestatus_line[len(PIPESTATUS_LEADER):].split()]
595 if any(statuses):
596 raise device_errors.AdbShellCommandFailedError(
597 script, output, status=statuses,
598 device_serial=self.adb.GetDeviceSerial())
599 return output
600
578 @decorators.WithTimeoutAndRetriesFromInstance() 601 @decorators.WithTimeoutAndRetriesFromInstance()
579 def KillAll(self, process_name, signum=device_signal.SIGKILL, as_root=False, 602 def KillAll(self, process_name, signum=device_signal.SIGKILL, as_root=False,
580 blocking=False, quiet=False, timeout=None, retries=None): 603 blocking=False, quiet=False, timeout=None, retries=None):
581 """Kill all processes with the given name on the device. 604 """Kill all processes with the given name on the device.
582 605
583 Args: 606 Args:
584 process_name: A string containing the name of the process to kill. 607 process_name: A string containing the name of the process to kill.
585 signum: An integer containing the signal number to send to kill. Defaults 608 signum: An integer containing the signal number to send to kill. Defaults
586 to SIGKILL (9). 609 to SIGKILL (9).
587 as_root: A boolean indicating whether the kill should be executed with 610 as_root: A boolean indicating whether the kill should be executed with
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after
1023 ls_out = self.RunShellCommand(['ls', '-l', device_path], as_root=as_root, 1046 ls_out = self.RunShellCommand(['ls', '-l', device_path], as_root=as_root,
1024 check_return=True) 1047 check_return=True)
1025 for line in ls_out: 1048 for line in ls_out:
1026 m = self._LS_RE.match(line) 1049 m = self._LS_RE.match(line)
1027 if m and m.group('name') == posixpath.basename(device_path): 1050 if m and m.group('name') == posixpath.basename(device_path):
1028 size = int(m.group('size')) 1051 size = int(m.group('size'))
1029 break 1052 break
1030 else: 1053 else:
1031 logging.warning('Could not determine size of %s.', device_path) 1054 logging.warning('Could not determine size of %s.', device_path)
1032 1055
1033 if size is None or size <= self._MAX_ADB_OUTPUT_LENGTH: 1056 if 0 < size <= self._MAX_ADB_OUTPUT_LENGTH:
1034 return _JoinLines(self.RunShellCommand( 1057 return _JoinLines(self.RunShellCommand(
1035 ['cat', device_path], as_root=as_root, check_return=True)) 1058 ['cat', device_path], as_root=as_root, check_return=True))
1036 elif as_root and self.NeedsSU(): 1059 elif as_root and self.NeedsSU():
1037 with device_temp_file.DeviceTempFile(self.adb) as device_temp: 1060 with device_temp_file.DeviceTempFile(self.adb) as device_temp:
1038 self.RunShellCommand(['cp', device_path, device_temp.name], 1061 self.RunShellCommand(['cp', device_path, device_temp.name],
1039 as_root=True, check_return=True) 1062 as_root=True, check_return=True)
1040 return self._ReadFileWithPull(device_temp.name) 1063 return self._ReadFileWithPull(device_temp.name)
1041 else: 1064 else:
1042 return self._ReadFileWithPull(device_path) 1065 return self._ReadFileWithPull(device_path)
1043 1066
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
1359 1382
1360 Returns: 1383 Returns:
1361 A dict mapping process name to PID for each process that contained the 1384 A dict mapping process name to PID for each process that contained the
1362 provided |process_name|. 1385 provided |process_name|.
1363 1386
1364 Raises: 1387 Raises:
1365 CommandTimeoutError on timeout. 1388 CommandTimeoutError on timeout.
1366 DeviceUnreachableError on missing device. 1389 DeviceUnreachableError on missing device.
1367 """ 1390 """
1368 procs_pids = {} 1391 procs_pids = {}
1369 for line in self.RunShellCommand('ps', check_return=True): 1392 try:
1393 ps_output = self._RunPipedShellCommand(
1394 'ps | grep -F %s' % cmd_helper.SingleQuote(process_name))
1395 except device_errors.AdbShellCommandFailedError as e:
1396 if e.status and isinstance(e.status, list) and not e.status[0]:
1397 # If ps succeeded but grep failed, there were no processes with the
1398 # given name.
1399 return procs_pids
1400 else:
1401 raise
1402
1403 for line in ps_output:
1370 try: 1404 try:
1371 ps_data = line.split() 1405 ps_data = line.split()
1372 if process_name in ps_data[-1]: 1406 if process_name in ps_data[-1]:
1373 procs_pids[ps_data[-1]] = ps_data[1] 1407 procs_pids[ps_data[-1]] = ps_data[1]
1374 except IndexError: 1408 except IndexError:
1375 pass 1409 pass
1376 return procs_pids 1410 return procs_pids
1377 1411
1378 @decorators.WithTimeoutAndRetriesFromInstance() 1412 @decorators.WithTimeoutAndRetriesFromInstance()
1379 def TakeScreenshot(self, host_path=None, timeout=None, retries=None): 1413 def TakeScreenshot(self, host_path=None, timeout=None, retries=None):
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1431 except device_errors.CommandFailedError: 1465 except device_errors.CommandFailedError:
1432 logging.exception('Error getting memory usage from status') 1466 logging.exception('Error getting memory usage from status')
1433 1467
1434 return result 1468 return result
1435 1469
1436 def _GetMemoryUsageForPidFromSmaps(self, pid): 1470 def _GetMemoryUsageForPidFromSmaps(self, pid):
1437 SMAPS_COLUMNS = ( 1471 SMAPS_COLUMNS = (
1438 'Size', 'Rss', 'Pss', 'Shared_Clean', 'Shared_Dirty', 'Private_Clean', 1472 'Size', 'Rss', 'Pss', 'Shared_Clean', 'Shared_Dirty', 'Private_Clean',
1439 'Private_Dirty') 1473 'Private_Dirty')
1440 1474
1441 showmap_out = self.RunShellCommand( 1475 showmap_out = self._RunPipedShellCommand(
1442 ['showmap', str(pid)], as_root=True, check_return=True) 1476 'showmap %d | grep TOTAL' % int(pid), as_root=True)
1443 if not showmap_out:
1444 raise device_errors.CommandFailedError('No output from showmap')
1445 1477
1446 split_totals = showmap_out[-1].split() 1478 split_totals = showmap_out[-1].split()
1447 if (not split_totals 1479 if (not split_totals
1448 or len(split_totals) != 9 1480 or len(split_totals) != 9
1449 or split_totals[-1] != 'TOTAL'): 1481 or split_totals[-1] != 'TOTAL'):
1450 raise device_errors.CommandFailedError( 1482 raise device_errors.CommandFailedError(
1451 'Invalid output from showmap: %s' % '\n'.join(showmap_out)) 1483 'Invalid output from showmap: %s' % '\n'.join(showmap_out))
1452 1484
1453 return dict(itertools.izip(SMAPS_COLUMNS, (int(n) for n in split_totals))) 1485 return dict(itertools.izip(SMAPS_COLUMNS, (int(n) for n in split_totals)))
1454 1486
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1543 """Returns client cache.""" 1575 """Returns client cache."""
1544 if client_name not in self._client_caches: 1576 if client_name not in self._client_caches:
1545 self._client_caches[client_name] = {} 1577 self._client_caches[client_name] = {}
1546 return self._client_caches[client_name] 1578 return self._client_caches[client_name]
1547 1579
1548 def _ClearCache(self): 1580 def _ClearCache(self):
1549 """Clears all caches.""" 1581 """Clears all caches."""
1550 for client in self._client_caches: 1582 for client in self._client_caches:
1551 self._client_caches[client].clear() 1583 self._client_caches[client].clear()
1552 self._cache.clear() 1584 self._cache.clear()
OLDNEW
« no previous file with comments | « build/android/pylib/device/device_errors.py ('k') | build/android/pylib/device/device_utils_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698