Merge "windows: fix terminating processes" into stable/ussuri

This commit is contained in:
Zuul 2020-10-12 17:08:35 +00:00 committed by Gerrit Code Review
commit 2ea7ff89d9
2 changed files with 39 additions and 2 deletions

View File

@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import ctypes
import io
import os
@ -38,6 +39,8 @@ LOG = logging.getLogger(__name__)
subprocess = eventlet.patcher.original('subprocess')
subprocess.threading = eventlet.patcher.original('threading')
ERROR_KEY_DELETED = 0x03FA
def create_process(cmd, run_as_root=False, addl_env=None,
tpool_proxy=True):
@ -71,8 +74,16 @@ def _get_wmi_process(pid):
if not pid:
return None
conn = wmi.WMI()
processes = conn.Win32_Process(ProcessId=pid)
try:
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:
return processes[0]
return None

View File

@ -26,6 +26,13 @@ from neutron.agent.windows import utils
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
class WindowsUtilsTestCase(base.BaseTestCase):
@mock.patch('os.environ', {mock.sentinel.key0: mock.sentinel.val0})
@ -87,6 +94,25 @@ class WindowsUtilsTestCase(base.BaseTestCase):
if 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)
@mock.patch.object(utils, '_get_wmi_process')
def test_kill_process(self, process_exists, mock_get_process):