Rewrote the zombie metric to get serials.
Added ability to get the serial number of phone from pid, by parsing
output of ps, also simplified output dictionary.
Bug: None
Test: see tests/zombie_metric_test.py
Change-Id: Ibfc921c6e41dfa81593fa8a8bd4c79c3c5e232e5
diff --git a/tools/lab/metrics/zombie_metric.py b/tools/lab/metrics/zombie_metric.py
index 1eaad2f..6224c09 100644
--- a/tools/lab/metrics/zombie_metric.py
+++ b/tools/lab/metrics/zombie_metric.py
@@ -18,53 +18,38 @@
class ZombieMetric(Metric):
-
- COMMAND = "ps axo pid=,stat=,comm= | awk '$2~/^Z { print }'"
- # Fields for response dictionary
- ADB_ZOMBIES = 'adb_zombies'
- FASTBOOT_ZOMBIES = 'fastboot_zombies'
- OTHER_ZOMBIES = 'other_zombies'
+ COMMAND = 'ps -eo pid,stat,comm,args | awk \'$2~/^Z/ { print }\''
def gather_metric(self):
- """finds PIDs and command names for zombie processes
+ """Gathers the pids, process names, and serial numbers of processes.
+
+ If process does not have serial, None is returned instead.
Returns:
- A dict with the following fields:
- adb_zombies: list of zombie processes w/ 'adb' in command name
- fastboot_zombies: list of zombie processes w/ 'fastboot'
- in command name
- other_zombies: list of zombie processes w/o 'adb'or 'fastboot
- in command name
- all elements in list are formatted as (PID, state, name) tuples
+ A dictionary where the keys are the pids of the processes, and the
+ value is a tuple of (process name, serial number|None)
"""
- # Initialize empty lists
- adb_zombies, fastboot_zombies, other_zombies = [], [], []
- # Run shell command
- result = self._shell.run(self.COMMAND)
- """Example stdout:
- 30797 Z+ adb <defunct>
- 30798 Z+ adb <defunct>
- """
- # Split output into lines
- output = result.stdout.splitlines()
- for ln in output:
- # Get first two parts of output
- pid, state = ln.split()[:2]
- # Rest of line will be the command name, may have spaces
- name = ' '.join(ln.split()[2:])
- # Create zombie and append to proper list
- zombie = (int(pid), state, name)
- if 'adb' in name:
- adb_zombies.append(zombie)
- elif 'fastboot' in name:
- fastboot_zombies.append(zombie)
- else:
- other_zombies.append(zombie)
+ response = {}
+ result = self._shell.run(self.COMMAND).stdout
+ # Example stdout:
+ # 30797 Z+ adb <defunct> adb -s AHDLSERIAL0001
+ # 30798 Z+ adb <defunct> /usr/bin/adb
- # Create response dictionary
- response = {
- self.ADB_ZOMBIES: adb_zombies,
- self.FASTBOOT_ZOMBIES: fastboot_zombies,
- self.OTHER_ZOMBIES: other_zombies
- }
+ output = result.splitlines()
+ for ln in output:
+ spl_ln = ln.split()
+ # spl_ln looks like ['1xx', 'Z+', 'adb', '<defunct'>, ...]
+ pid, state, name = spl_ln[:3]
+
+ if '-s' in spl_ln:
+ # Finds the '-s' flag, the index after that is the serial.
+ sn_idx = spl_ln.index('-s')
+ if sn_idx + 1 >= len(spl_ln):
+ sn = None
+ else:
+ sn = spl_ln[sn_idx + 1]
+ response[pid] = (name, sn)
+ else:
+ response[pid] = (name, None)
+
return response
diff --git a/tools/lab/tests/zombie_metric_test.py b/tools/lab/tests/zombie_metric_test.py
index 185effe..4395c55 100755
--- a/tools/lab/tests/zombie_metric_test.py
+++ b/tools/lab/tests/zombie_metric_test.py
@@ -23,35 +23,45 @@
class ZombieMetricTest(unittest.TestCase):
"""Class for testing ZombieMetric."""
- def test_return_one_process(self):
+ def test_gather_metric_oob(self):
+ stdout_string = '30888 Z+ adb -s'
+ FAKE_RESULT = fake.FakeResult(stdout=stdout_string)
+ fake_shell = fake.MockShellCommand(fake_result=FAKE_RESULT)
+ metric_obj = zombie_metric.ZombieMetric(shell=fake_shell)
+
+ expected_result = {'30888': ('adb', None)}
+ self.assertEqual(expected_result, metric_obj.gather_metric())
+
+ def test_gather_metric_no_serial(self):
stdout_string = '30888 Z+ adb <defunct>'
FAKE_RESULT = fake.FakeResult(stdout=stdout_string)
fake_shell = fake.MockShellCommand(fake_result=FAKE_RESULT)
metric_obj = zombie_metric.ZombieMetric(shell=fake_shell)
- expected_result = {
- zombie_metric.ZombieMetric.ADB_ZOMBIES: [(30888, 'Z+',
- 'adb <defunct>')],
- zombie_metric.ZombieMetric.FASTBOOT_ZOMBIES: [],
- zombie_metric.ZombieMetric.OTHER_ZOMBIES: []
- }
+ expected_result = {'30888': ('adb', None)}
self.assertEqual(expected_result, metric_obj.gather_metric())
- def test_return_one_of_each(self):
- stdout_string = ('30888 Z+ adb <defunct>\n'
- '12345 Z+ fastboot\n'
- '99999 Z+ random\n')
+ def test_gather_metric_with_serial(self):
+ stdout_string = ('12345 Z+ fastboot -s M4RKY_M4RK\n'
+ '99999 Z+ adb -s OR3G4N0\n')
FAKE_RESULT = fake.FakeResult(stdout=stdout_string)
fake_shell = fake.MockShellCommand(fake_result=FAKE_RESULT)
metric_obj = zombie_metric.ZombieMetric(shell=fake_shell)
expected_result = {
- zombie_metric.ZombieMetric.ADB_ZOMBIES: [(30888, 'Z+',
- 'adb <defunct>')],
- zombie_metric.ZombieMetric.FASTBOOT_ZOMBIES: [(12345, 'Z+',
- 'fastboot')],
- zombie_metric.ZombieMetric.OTHER_ZOMBIES: [(99999, 'Z+', 'random')]
+ '12345': ('fastboot', 'M4RKY_M4RK'),
+ '99999': ('adb', 'OR3G4N0')
}
+ self.assertEquals(metric_obj.gather_metric(), expected_result)
+
+ def test_gather_metric_adb_fastboot_no_s(self):
+ stdout_string = ('12345 Z+ fastboot\n' '99999 Z+ adb\n')
+ FAKE_RESULT = fake.FakeResult(stdout=stdout_string)
+ fake_shell = fake.MockShellCommand(fake_result=FAKE_RESULT)
+ metric_obj = zombie_metric.ZombieMetric(shell=fake_shell)
+
+ expected_result = {'12345': ('fastboot', None), '99999': ('adb', None)}
+ self.assertEquals(metric_obj.gather_metric(), expected_result)
if __name__ == '__main__':