diff --git a/neutron/agent/linux/external_process.py b/neutron/agent/linux/external_process.py index 4e4946228d9..68df4baebbc 100644 --- a/neutron/agent/linux/external_process.py +++ b/neutron/agent/linux/external_process.py @@ -21,6 +21,7 @@ from oslo_concurrency import lockutils from oslo_config import cfg from oslo_log import log as logging from oslo_utils import fileutils +import psutil import six from neutron._i18n import _, _LW, _LE @@ -146,12 +147,9 @@ class ProcessManager(MonitoredProcess): pid = self.pid if not pid: return - - cmdline = '/proc/%s/cmdline' % pid try: - with open(cmdline, "r") as f: - return f.readline() - except IOError: + return ' '.join(psutil.Process(pid).cmdline()) + except (psutil.NoSuchProcess, psutil.AccessDenied): return diff --git a/neutron/tests/functional/requirements.txt b/neutron/tests/functional/requirements.txt index 62285e9e900..626432ab3db 100644 --- a/neutron/tests/functional/requirements.txt +++ b/neutron/tests/functional/requirements.txt @@ -4,5 +4,4 @@ # of appearance. Changing the order has an impact on the overall integration # process, which may cause wedges in the gate later. -psutil>=1.1.1,<2.0.0 psycopg2 diff --git a/neutron/tests/unit/agent/linux/test_external_process.py b/neutron/tests/unit/agent/linux/test_external_process.py index 962a5c360cf..83d0148645f 100644 --- a/neutron/tests/unit/agent/linux/test_external_process.py +++ b/neutron/tests/unit/agent/linux/test_external_process.py @@ -16,6 +16,7 @@ import mock import os.path from oslo_utils import fileutils +import psutil from neutron.agent.linux import external_process as ep from neutron.tests import base @@ -285,22 +286,19 @@ class TestProcessManager(base.BaseTestCase): self.assertFalse(manager.active) def test_cmdline(self): - mock_open = self.useFixture( - tools.OpenFixture('/proc/4/cmdline', TEST_CMDLINE % 'uuid') - ).mock_open - with mock.patch.object(ep.ProcessManager, 'pid') as pid: - pid.__get__ = mock.Mock(return_value=4) - manager = ep.ProcessManager(self.conf, 'uuid') - self.assertEqual(TEST_CMDLINE % 'uuid', manager.cmdline) - mock_open.assert_called_once_with('/proc/4/cmdline', 'r') + with mock.patch.object(psutil, 'Process') as proc: + proc().cmdline.return_value = (TEST_CMDLINE % 'uuid').split(' ') + with mock.patch.object(ep.ProcessManager, 'pid') as pid: + pid.__get__ = mock.Mock(return_value=4) + manager = ep.ProcessManager(self.conf, 'uuid') + self.assertEqual(TEST_CMDLINE % 'uuid', manager.cmdline) + proc().cmdline.assert_called_once_with() def test_cmdline_none(self): - mock_open = self.useFixture( - tools.OpenFixture('/proc/4/cmdline', TEST_CMDLINE % 'uuid') - ).mock_open - mock_open.side_effect = IOError() - with mock.patch.object(ep.ProcessManager, 'pid') as pid: - pid.__get__ = mock.Mock(return_value=4) - manager = ep.ProcessManager(self.conf, 'uuid') - self.assertIsNone(manager.cmdline) - mock_open.assert_called_once_with('/proc/4/cmdline', 'r') + with mock.patch.object(psutil, 'Process') as proc: + proc.side_effect = psutil.NoSuchProcess(4) + with mock.patch.object(ep.ProcessManager, 'pid') as pid: + pid.__get__ = mock.Mock(return_value=4) + manager = ep.ProcessManager(self.conf, 'uuid') + self.assertIsNone(manager.cmdline) + proc.assert_called_once_with(4) diff --git a/requirements.txt b/requirements.txt index 6926d5658f0..503e7416a1f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -44,6 +44,7 @@ oslo.utils>=3.20.0 # Apache-2.0 oslo.versionedobjects>=1.17.0 # Apache-2.0 osprofiler>=1.4.0 # Apache-2.0 ovs>=2.6.1 # Apache-2.0 +psutil>=3.2.2 # BSD pyroute2>=0.4.12 # Apache-2.0 (+ dual licensed GPL2) weakrefmethod>=1.0.2;python_version=='2.7' # PSF