Merge "windows: fix terminating processes" into stable/queens
This commit is contained in:
commit
0400d27992
|
@ -13,6 +13,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import ctypes
|
||||||
import io
|
import io
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
@ -37,6 +38,8 @@ LOG = logging.getLogger(__name__)
|
||||||
subprocess = eventlet.patcher.original('subprocess')
|
subprocess = eventlet.patcher.original('subprocess')
|
||||||
subprocess.threading = eventlet.patcher.original('threading')
|
subprocess.threading = eventlet.patcher.original('threading')
|
||||||
|
|
||||||
|
ERROR_KEY_DELETED = 0x03FA
|
||||||
|
|
||||||
|
|
||||||
def create_process(cmd, run_as_root=False, addl_env=None,
|
def create_process(cmd, run_as_root=False, addl_env=None,
|
||||||
tpool_proxy=True):
|
tpool_proxy=True):
|
||||||
|
@ -70,8 +73,16 @@ def _get_wmi_process(pid):
|
||||||
if not pid:
|
if not pid:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
conn = wmi.WMI()
|
try:
|
||||||
processes = conn.Win32_Process(ProcessId=pid)
|
conn = wmi.WMI()
|
||||||
|
processes = conn.Win32_Process(ProcessId=pid)
|
||||||
|
except wmi.x_wmi as exc:
|
||||||
|
hresult = exc.com_error.hresult
|
||||||
|
err_code = ctypes.c_uint(hresult).value & 0xFFFF
|
||||||
|
if err_code == ERROR_KEY_DELETED:
|
||||||
|
return None
|
||||||
|
raise
|
||||||
|
|
||||||
if processes:
|
if processes:
|
||||||
return processes[0]
|
return processes[0]
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -26,6 +26,13 @@ from neutron.common import exceptions
|
||||||
from neutron.tests import base
|
from neutron.tests import base
|
||||||
|
|
||||||
|
|
||||||
|
class x_wmi(Exception):
|
||||||
|
def __init__(self, info='', com_error=None):
|
||||||
|
super(x_wmi, self).__init__(info)
|
||||||
|
self.info = info
|
||||||
|
self.com_error = com_error
|
||||||
|
|
||||||
|
|
||||||
@ddt.ddt
|
@ddt.ddt
|
||||||
class WindowsUtilsTestCase(base.BaseTestCase):
|
class WindowsUtilsTestCase(base.BaseTestCase):
|
||||||
@mock.patch('os.environ', {mock.sentinel.key0: mock.sentinel.val0})
|
@mock.patch('os.environ', {mock.sentinel.key0: mock.sentinel.val0})
|
||||||
|
@ -87,6 +94,25 @@ class WindowsUtilsTestCase(base.BaseTestCase):
|
||||||
if pid:
|
if pid:
|
||||||
mock_conn.Win32_Process.assert_called_once_with(ProcessId=pid)
|
mock_conn.Win32_Process.assert_called_once_with(ProcessId=pid)
|
||||||
|
|
||||||
|
@ddt.data({},
|
||||||
|
{"hresult": 0xff,
|
||||||
|
"expect_exc": True})
|
||||||
|
@ddt.unpack
|
||||||
|
@mock.patch.object(utils, 'wmi', create=True)
|
||||||
|
def test_get_wmi_process_exc(self, mock_wmi, expect_exc=False,
|
||||||
|
hresult=0x800703FA):
|
||||||
|
mock_conn = mock_wmi.WMI.return_value
|
||||||
|
mock_wmi.x_wmi = x_wmi
|
||||||
|
com_error = mock.Mock(hresult=hresult)
|
||||||
|
exc = x_wmi(com_error=com_error)
|
||||||
|
mock_conn.Win32_Process.side_effect = exc
|
||||||
|
|
||||||
|
if expect_exc:
|
||||||
|
self.assertRaises(
|
||||||
|
x_wmi, utils._get_wmi_process, mock.sentinel.pid)
|
||||||
|
else:
|
||||||
|
self.assertIsNone(utils._get_wmi_process(mock.sentinel.pid))
|
||||||
|
|
||||||
@ddt.data(True, False)
|
@ddt.data(True, False)
|
||||||
@mock.patch.object(utils, '_get_wmi_process')
|
@mock.patch.object(utils, '_get_wmi_process')
|
||||||
def test_kill_process(self, process_exists, mock_get_process):
|
def test_kill_process(self, process_exists, mock_get_process):
|
||||||
|
|
Loading…
Reference in New Issue