diff --git a/avocado/utils/process.py b/avocado/utils/process.py index d68431e969e2a0f31564d596ad328a34f438d2d3..7d60cb3f10e4cf2b44cf8728912a89a4c74163b3 100644 --- a/avocado/utils/process.py +++ b/avocado/utils/process.py @@ -135,6 +135,22 @@ def safe_kill(pid, signal): # pylint: disable=W0621 return False +def get_parent_pid(pid): + """ + Returns the parent PID for the given process + + TODO: this is currently Linux specific, and needs to implement + similar features for other platforms. + + :param pid: The PID of child process + :returns: The parent PID + :rtype: int + """ + with open('/proc/%d/stat' % pid, 'rb') as proc_stat: + parent_pid = proc_stat.read().split(b' ')[-49] + return int(parent_pid) + + def kill_process_tree(pid, sig=signal.SIGKILL, send_sigcont=True): """ Signal a process and all of its children. diff --git a/selftests/unit/test_utils_process.py b/selftests/unit/test_utils_process.py index 4577e04e807753e582efb200f61d9f7efe5823fd..45e258199963a0f3887ae4c1669d2fbf976ff1d6 100644 --- a/selftests/unit/test_utils_process.py +++ b/selftests/unit/test_utils_process.py @@ -10,6 +10,7 @@ except ImportError: import mock +from .. import recent_mock from avocado.utils import astring from avocado.utils import gdb from avocado.utils import process @@ -278,6 +279,14 @@ class MiscProcessTests(unittest.TestCase): [u"avok\xe1do_test_runner", u"arguments"]) + @unittest.skipUnless(recent_mock(), + "mock library version cannot (easily) patch open()") + def test_get_parent_pid(self): + stat = b'18405 (bash) S 24139 18405 18405 34818 8056 4210688 9792 170102 0 7 11 4 257 84 20 0 1 0 44336493 235409408 4281 18446744073709551615 94723230367744 94723231442728 140723100226000 0 0 0 65536 3670020 1266777851 0 0 0 17 1 0 0 0 0 0 94723233541456 94723233588580 94723248717824 140723100229613 140723100229623 140723100229623 140723100233710 0' + with mock.patch('avocado.utils.process.open', + return_value=io.BytesIO(stat)): + self.assertTrue(process.get_parent_pid(0), 24139) + class CmdResultTests(unittest.TestCase):