Merge "Adds Windows service CRUD methods"
This commit is contained in:
commit
e40bb953d2
@ -138,6 +138,31 @@ class BaseOSUtils(object):
|
|||||||
"""Set the username and password for a given service."""
|
"""Set the username and password for a given service."""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def create_service(self, service_name, display_name, path, start_mode,
|
||||||
|
username=None, password=None):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def delete_service(self, service_name):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def get_service_status(self, service_name):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def check_service_exists(self, service_name):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def get_service_start_mode(self, service_name):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def set_service_start_mode(self, service_name, start_mode):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def start_service(self, service_name):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def stop_service(self, service_name, wait=False):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
def get_service_username(self, service_name):
|
def get_service_username(self, service_name):
|
||||||
"""Retrieve the username under which a service runs."""
|
"""Retrieve the username under which a service runs."""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
@ -367,6 +367,31 @@ class WindowsUtils(base.BaseOSUtils):
|
|||||||
SERVICE_START_MODE_MANUAL = "Manual"
|
SERVICE_START_MODE_MANUAL = "Manual"
|
||||||
SERVICE_START_MODE_DISABLED = "Disabled"
|
SERVICE_START_MODE_DISABLED = "Disabled"
|
||||||
|
|
||||||
|
_SERVICE_START_TYPE_MAP = {
|
||||||
|
SERVICE_START_MODE_AUTOMATIC:
|
||||||
|
win32service.SERVICE_AUTO_START,
|
||||||
|
SERVICE_START_MODE_MANUAL:
|
||||||
|
win32service.SERVICE_DEMAND_START,
|
||||||
|
SERVICE_START_MODE_DISABLED:
|
||||||
|
win32service.SERVICE_DISABLED}
|
||||||
|
|
||||||
|
_SERVICE_STATUS_MAP = {
|
||||||
|
win32service.SERVICE_CONTINUE_PENDING:
|
||||||
|
SERVICE_STATUS_CONTINUE_PENDING,
|
||||||
|
win32service.SERVICE_PAUSE_PENDING:
|
||||||
|
SERVICE_STATUS_PAUSE_PENDING,
|
||||||
|
win32service.SERVICE_PAUSED:
|
||||||
|
SERVICE_STATUS_PAUSED,
|
||||||
|
win32service.SERVICE_RUNNING:
|
||||||
|
SERVICE_STATUS_RUNNING,
|
||||||
|
win32service.SERVICE_START_PENDING:
|
||||||
|
SERVICE_STATUS_START_PENDING,
|
||||||
|
win32service.SERVICE_STOP_PENDING:
|
||||||
|
SERVICE_STATUS_STOP_PENDING,
|
||||||
|
win32service.SERVICE_STOPPED:
|
||||||
|
SERVICE_STATUS_STOPPED,
|
||||||
|
}
|
||||||
|
|
||||||
ComputerNamePhysicalDnsHostname = 5
|
ComputerNamePhysicalDnsHostname = 5
|
||||||
|
|
||||||
_config_key = 'SOFTWARE\\Cloudbase Solutions\\Cloudbase-Init\\'
|
_config_key = 'SOFTWARE\\Cloudbase Solutions\\Cloudbase-Init\\'
|
||||||
@ -865,13 +890,8 @@ class WindowsUtils(base.BaseOSUtils):
|
|||||||
else:
|
else:
|
||||||
raise ex
|
raise ex
|
||||||
|
|
||||||
def _get_service(self, service_name):
|
|
||||||
conn = wmi.WMI(moniker='//./root/cimv2')
|
|
||||||
service_list = conn.Win32_Service(Name=service_name)
|
|
||||||
if len(service_list):
|
|
||||||
return service_list[0]
|
|
||||||
|
|
||||||
def check_service_exists(self, service_name):
|
def check_service_exists(self, service_name):
|
||||||
|
LOG.debug("Checking if service exists: %s", service_name)
|
||||||
try:
|
try:
|
||||||
with self._get_service_handle(service_name):
|
with self._get_service_handle(service_name):
|
||||||
return True
|
return True
|
||||||
@ -882,57 +902,110 @@ class WindowsUtils(base.BaseOSUtils):
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
def get_service_status(self, service_name):
|
def get_service_status(self, service_name):
|
||||||
service = self._get_service(service_name)
|
LOG.debug("Getting service status for: %s", service_name)
|
||||||
return service.State
|
with self._get_service_handle(
|
||||||
|
service_name, win32service.SERVICE_QUERY_STATUS) as hs:
|
||||||
|
service_status = win32service.QueryServiceStatusEx(hs)
|
||||||
|
state = service_status['CurrentState']
|
||||||
|
|
||||||
|
return self._SERVICE_STATUS_MAP.get(
|
||||||
|
state, WindowsUtils.SERVICE_STATUS_UNKNOWN)
|
||||||
|
|
||||||
def get_service_start_mode(self, service_name):
|
def get_service_start_mode(self, service_name):
|
||||||
service = self._get_service(service_name)
|
LOG.debug("Getting service start mode for: %s", service_name)
|
||||||
return service.StartMode
|
with self._get_service_handle(
|
||||||
|
service_name, win32service.SERVICE_QUERY_CONFIG) as hs:
|
||||||
|
service_config = win32service.QueryServiceConfig(hs)
|
||||||
|
|
||||||
|
start_type = service_config[1]
|
||||||
|
return [k for k, v in self._SERVICE_START_TYPE_MAP.items()
|
||||||
|
if v == start_type][0]
|
||||||
|
|
||||||
def set_service_start_mode(self, service_name, start_mode):
|
def set_service_start_mode(self, service_name, start_mode):
|
||||||
# TODO(alexpilotti): Handle the "Delayed Start" case
|
# TODO(alexpilotti): Handle the "Delayed Start" case
|
||||||
service = self._get_service(service_name)
|
LOG.debug("Setting service start mode for: %s", service_name)
|
||||||
(ret_val,) = service.ChangeStartMode(start_mode)
|
start_type = self._get_win32_start_type(start_mode)
|
||||||
if ret_val != 0:
|
|
||||||
raise exception.CloudbaseInitException(
|
with self._get_service_handle(
|
||||||
'Setting service %(service_name)s start mode failed with '
|
service_name, win32service.SERVICE_CHANGE_CONFIG) as hs:
|
||||||
'return value: %(ret_val)d' % {'service_name': service_name,
|
win32service.ChangeServiceConfig(
|
||||||
'ret_val': ret_val})
|
hs, win32service.SERVICE_NO_CHANGE,
|
||||||
|
start_type, win32service.SERVICE_NO_CHANGE,
|
||||||
|
None, None, False, None, None, None, None)
|
||||||
|
|
||||||
def start_service(self, service_name):
|
def start_service(self, service_name):
|
||||||
LOG.debug('Starting service %s', service_name)
|
LOG.debug('Starting service %s', service_name)
|
||||||
service = self._get_service(service_name)
|
with self._get_service_handle(
|
||||||
(ret_val,) = service.StartService()
|
service_name, win32service.SERVICE_START) as hs:
|
||||||
if ret_val != 0:
|
win32service.StartService(hs, service_name)
|
||||||
raise exception.CloudbaseInitException(
|
|
||||||
'Starting service %(service_name)s failed with return value: '
|
|
||||||
'%(ret_val)d' % {'service_name': service_name,
|
|
||||||
'ret_val': ret_val})
|
|
||||||
|
|
||||||
def stop_service(self, service_name):
|
def stop_service(self, service_name, wait=False):
|
||||||
LOG.debug('Stopping service %s', service_name)
|
LOG.debug('Stopping service %s', service_name)
|
||||||
service = self._get_service(service_name)
|
with self._get_service_handle(
|
||||||
(ret_val,) = service.StopService()
|
service_name,
|
||||||
if ret_val != 0:
|
win32service.SERVICE_STOP |
|
||||||
raise exception.CloudbaseInitException(
|
win32service.SERVICE_QUERY_STATUS) as hs:
|
||||||
'Stopping service %(service_name)s failed with return value:'
|
win32service.ControlService(hs, win32service.SERVICE_CONTROL_STOP)
|
||||||
' %(ret_val)d' % {'service_name': service_name,
|
if wait:
|
||||||
'ret_val': ret_val})
|
while True:
|
||||||
|
service_status = win32service.QueryServiceStatusEx(hs)
|
||||||
|
state = service_status['CurrentState']
|
||||||
|
if state == win32service.SERVICE_STOPPED:
|
||||||
|
return
|
||||||
|
time.sleep(.1)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def _get_service_control_manager(
|
||||||
|
scm_access=win32service.SC_MANAGER_CONNECT):
|
||||||
|
hscm = win32service.OpenSCManager(None, None, scm_access)
|
||||||
|
try:
|
||||||
|
yield hscm
|
||||||
|
finally:
|
||||||
|
win32service.CloseServiceHandle(hscm)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def _get_service_handle(service_name,
|
def _get_service_handle(service_name,
|
||||||
service_access=win32service.SERVICE_QUERY_CONFIG,
|
service_access=win32service.SERVICE_QUERY_CONFIG,
|
||||||
scm_access=win32service.SC_MANAGER_CONNECT):
|
scm_access=win32service.SC_MANAGER_CONNECT):
|
||||||
hscm = win32service.OpenSCManager(None, None, scm_access)
|
with WindowsUtils._get_service_control_manager(scm_access) as hscm:
|
||||||
hs = None
|
|
||||||
try:
|
|
||||||
hs = win32service.OpenService(hscm, service_name, service_access)
|
hs = win32service.OpenService(hscm, service_name, service_access)
|
||||||
yield hs
|
try:
|
||||||
finally:
|
yield hs
|
||||||
if hs:
|
finally:
|
||||||
win32service.CloseServiceHandle(hs)
|
win32service.CloseServiceHandle(hs)
|
||||||
win32service.CloseServiceHandle(hscm)
|
|
||||||
|
@staticmethod
|
||||||
|
def _get_win32_start_type(start_mode):
|
||||||
|
start_type = WindowsUtils._SERVICE_START_TYPE_MAP.get(start_mode)
|
||||||
|
if not start_type:
|
||||||
|
raise exception.InvalidStateException(
|
||||||
|
"Invalid service start mode: %s" % start_mode)
|
||||||
|
return start_type
|
||||||
|
|
||||||
|
def create_service(self, service_name, display_name, path, start_mode,
|
||||||
|
username=None, password=None):
|
||||||
|
LOG.debug('Creating service %s', service_name)
|
||||||
|
start_type = self._get_win32_start_type(start_mode)
|
||||||
|
|
||||||
|
with WindowsUtils._get_service_control_manager(
|
||||||
|
scm_access=win32service.SC_MANAGER_CREATE_SERVICE) as hscm:
|
||||||
|
hs = win32service.CreateService(
|
||||||
|
hscm, service_name, display_name,
|
||||||
|
win32service.SERVICE_ALL_ACCESS,
|
||||||
|
win32service.SERVICE_WIN32_OWN_PROCESS,
|
||||||
|
start_type,
|
||||||
|
win32service.SERVICE_ERROR_NORMAL,
|
||||||
|
path, None, False, None,
|
||||||
|
username, password)
|
||||||
|
win32service.CloseServiceHandle(hs)
|
||||||
|
|
||||||
|
def delete_service(self, service_name):
|
||||||
|
LOG.debug('Deleting service %s', service_name)
|
||||||
|
with self._get_service_handle(
|
||||||
|
service_name, win32service.SERVICE_ALL_ACCESS) as hs:
|
||||||
|
win32service.DeleteService(hs)
|
||||||
|
|
||||||
def set_service_credentials(self, service_name, username, password):
|
def set_service_credentials(self, service_name, username, password):
|
||||||
LOG.debug('Setting service credentials: %s', service_name)
|
LOG.debug('Setting service credentials: %s', service_name)
|
||||||
|
@ -879,16 +879,6 @@ class TestWindowsUtils(testutils.CloudbaseInitTestBase):
|
|||||||
ret_vals = [[1], [7]]
|
ret_vals = [[1], [7]]
|
||||||
self._test_wait_for_boot_completion(ret_vals=ret_vals)
|
self._test_wait_for_boot_completion(ret_vals=ret_vals)
|
||||||
|
|
||||||
def test_get_service(self):
|
|
||||||
conn = self._wmi_mock.WMI
|
|
||||||
conn.return_value.Win32_Service.return_value = ['fake name']
|
|
||||||
|
|
||||||
response = self._winutils._get_service('fake name')
|
|
||||||
|
|
||||||
conn.assert_called_with(moniker='//./root/cimv2')
|
|
||||||
conn.return_value.Win32_Service.assert_called_with(Name='fake name')
|
|
||||||
self.assertEqual('fake name', response)
|
|
||||||
|
|
||||||
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
|
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
|
||||||
'._get_service_handle')
|
'._get_service_handle')
|
||||||
def test_check_service(self, mock_get_service_handle):
|
def test_check_service(self, mock_get_service_handle):
|
||||||
@ -934,6 +924,48 @@ class TestWindowsUtils(testutils.CloudbaseInitTestBase):
|
|||||||
close_service.assert_has_calls([mock.call(mock.sentinel.hs),
|
close_service.assert_has_calls([mock.call(mock.sentinel.hs),
|
||||||
mock.call(mock.sentinel.hscm)])
|
mock.call(mock.sentinel.hscm)])
|
||||||
|
|
||||||
|
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
|
||||||
|
'._get_service_control_manager')
|
||||||
|
def test_create_service(self, mock_get_service_control_manager):
|
||||||
|
mock_hs = mock.MagicMock()
|
||||||
|
mock_service_name = "fake name"
|
||||||
|
mock_start_mode = "Automatic"
|
||||||
|
mock_display_name = mock.sentinel.mock_display_name
|
||||||
|
mock_path = mock.sentinel.path
|
||||||
|
mock_get_service_control_manager.return_value = mock_hs
|
||||||
|
with self.snatcher:
|
||||||
|
self._winutils.create_service(mock_service_name,
|
||||||
|
mock_display_name,
|
||||||
|
mock_path,
|
||||||
|
mock_start_mode)
|
||||||
|
self.assertEqual(["Creating service fake name"],
|
||||||
|
self.snatcher.output)
|
||||||
|
|
||||||
|
mock_get_service_control_manager.assert_called_once_with(
|
||||||
|
scm_access=self._win32service_mock.SC_MANAGER_CREATE_SERVICE)
|
||||||
|
self._win32service_mock.CreateService.assert_called_once_with(
|
||||||
|
mock_hs.__enter__(), mock_service_name, mock_display_name,
|
||||||
|
self._win32service_mock.SERVICE_ALL_ACCESS,
|
||||||
|
self._win32service_mock.SERVICE_WIN32_OWN_PROCESS,
|
||||||
|
self._win32service_mock.SERVICE_AUTO_START,
|
||||||
|
self._win32service_mock.SERVICE_ERROR_NORMAL,
|
||||||
|
mock_path, None, False, None, None, None)
|
||||||
|
|
||||||
|
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
|
||||||
|
'._get_service_handle')
|
||||||
|
def test_delete_service(self, mock_get_service_handle):
|
||||||
|
mock_hs = mock.MagicMock()
|
||||||
|
fake_service_name = "fake name"
|
||||||
|
mock_get_service_handle.return_value = mock_hs
|
||||||
|
with self.snatcher:
|
||||||
|
self._winutils.delete_service(fake_service_name)
|
||||||
|
self.assertEqual(["Deleting service fake name"],
|
||||||
|
self.snatcher.output)
|
||||||
|
self._win32service_mock.DeleteService.assert_called_once_with(
|
||||||
|
mock_hs.__enter__())
|
||||||
|
mock_get_service_handle.assert_called_once_with(
|
||||||
|
fake_service_name, self._win32service_mock.SERVICE_ALL_ACCESS)
|
||||||
|
|
||||||
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
|
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
|
||||||
'._get_service_handle')
|
'._get_service_handle')
|
||||||
def test_set_service_credentials(self, mock_get_service):
|
def test_set_service_credentials(self, mock_get_service):
|
||||||
@ -1037,96 +1069,100 @@ class TestWindowsUtils(testutils.CloudbaseInitTestBase):
|
|||||||
service_username=".\\username")
|
service_username=".\\username")
|
||||||
|
|
||||||
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
|
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
|
||||||
'._get_service')
|
'._get_service_handle')
|
||||||
def test_get_service_status(self, mock_get_service):
|
def test_get_service_status(self, mock_get_service_handle):
|
||||||
mock_service = mock.MagicMock()
|
mock_hs = mock.MagicMock()
|
||||||
mock_get_service.return_value = mock_service
|
fake_service_name = "fake name"
|
||||||
|
fake_status = {'CurrentState': 'fake-status'}
|
||||||
|
mock_get_service_handle.return_value = mock_hs
|
||||||
|
expected_log = ["Getting service status for: %s" % fake_service_name]
|
||||||
|
self._win32service_mock.QueryServiceStatusEx.return_value = fake_status
|
||||||
|
with self.snatcher:
|
||||||
|
response = self._winutils.get_service_status(fake_service_name)
|
||||||
|
|
||||||
response = self._winutils.get_service_status('fake name')
|
self._win32service_mock.QueryServiceStatusEx.assert_called_once_with(
|
||||||
|
mock_hs.__enter__())
|
||||||
self.assertEqual(mock_service.State, response)
|
mock_get_service_handle.assert_called_once_with(
|
||||||
|
fake_service_name, self._win32service_mock.SERVICE_QUERY_STATUS)
|
||||||
|
self.assertEqual(self.snatcher.output, expected_log)
|
||||||
|
self.assertEqual("Unknown", response)
|
||||||
|
|
||||||
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
|
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
|
||||||
'._get_service')
|
'._get_service_handle')
|
||||||
def test_get_service_start_mode(self, mock_get_service):
|
def test_get_service_start_mode(self, mock_get_service_handle):
|
||||||
mock_service = mock.MagicMock()
|
mock_hs = mock.MagicMock()
|
||||||
mock_get_service.return_value = mock_service
|
fake_service_name = "fake name"
|
||||||
|
mock_mode = self._win32service_mock.SERVICE_AUTO_START
|
||||||
|
fake_status = ['', mock_mode]
|
||||||
|
mock_get_service_handle.return_value = mock_hs
|
||||||
|
expected_mode = "Automatic"
|
||||||
|
expected_log = [
|
||||||
|
"Getting service start mode for: %s" % fake_service_name]
|
||||||
|
self._win32service_mock.QueryServiceConfig.return_value = fake_status
|
||||||
|
|
||||||
response = self._winutils.get_service_start_mode('fake name')
|
with self.snatcher:
|
||||||
|
response = self._winutils.get_service_start_mode(fake_service_name)
|
||||||
|
|
||||||
self.assertEqual(mock_service.StartMode, response)
|
self._win32service_mock.QueryServiceConfig.assert_called_once_with(
|
||||||
|
mock_hs.__enter__())
|
||||||
|
mock_get_service_handle.assert_called_once_with(
|
||||||
|
fake_service_name, self._win32service_mock.SERVICE_QUERY_CONFIG)
|
||||||
|
self.assertEqual(self.snatcher.output, expected_log)
|
||||||
|
self.assertEqual(expected_mode, response)
|
||||||
|
|
||||||
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
|
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
|
||||||
'._get_service')
|
'._get_service_handle')
|
||||||
def _test_set_service_start_mode(self, mock_get_service, ret_val):
|
def test_set_service_start_mode(self, mock_get_service_handle):
|
||||||
mock_service = mock.MagicMock()
|
mock_hs = mock.MagicMock()
|
||||||
mock_get_service.return_value = mock_service
|
fake_service_name = "fake name"
|
||||||
mock_service.ChangeStartMode.return_value = (ret_val,)
|
fake_start_mode = "Automatic"
|
||||||
|
mock_get_service_handle.return_value = mock_hs
|
||||||
if ret_val != 0:
|
with self.snatcher:
|
||||||
self.assertRaises(exception.CloudbaseInitException,
|
self._winutils.set_service_start_mode(fake_service_name,
|
||||||
self._winutils.set_service_start_mode,
|
fake_start_mode)
|
||||||
'fake name', 'fake mode')
|
self.assertEqual(["Setting service start mode for: fake name"],
|
||||||
else:
|
self.snatcher.output)
|
||||||
self._winutils.set_service_start_mode('fake name', 'fake mode')
|
self._win32service_mock.ChangeServiceConfig.assert_called_once_with(
|
||||||
|
mock_hs.__enter__(),
|
||||||
mock_service.ChangeStartMode.assert_called_once_with('fake mode')
|
self._win32service_mock.SERVICE_NO_CHANGE,
|
||||||
|
self._win32service_mock.SERVICE_AUTO_START,
|
||||||
def test_set_service_start_mode(self):
|
self._win32service_mock.SERVICE_NO_CHANGE,
|
||||||
self._test_set_service_start_mode(ret_val=0)
|
None, None, False, None, None, None, None)
|
||||||
|
mock_get_service_handle.assert_called_once_with(
|
||||||
def test_set_service_start_mode_exception(self):
|
fake_service_name,
|
||||||
self._test_set_service_start_mode(ret_val=1)
|
self._win32service_mock.SERVICE_CHANGE_CONFIG)
|
||||||
|
|
||||||
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
|
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
|
||||||
'._get_service')
|
'._get_service_handle')
|
||||||
def _test_start_service(self, mock_get_service, ret_val):
|
def test_start_service(self, mock_get_service_handle):
|
||||||
mock_service = mock.MagicMock()
|
mock_hs = mock.MagicMock()
|
||||||
mock_get_service.return_value = mock_service
|
fake_service_name = "fake name"
|
||||||
mock_service.StartService.return_value = (ret_val,)
|
mock_get_service_handle.return_value = mock_hs
|
||||||
|
with self.snatcher:
|
||||||
if ret_val != 0:
|
self._winutils.start_service(fake_service_name)
|
||||||
self.assertRaises(exception.CloudbaseInitException,
|
|
||||||
self._winutils.start_service,
|
|
||||||
'fake name')
|
|
||||||
else:
|
|
||||||
with self.snatcher:
|
|
||||||
self._winutils.start_service('fake name')
|
|
||||||
self.assertEqual(["Starting service fake name"],
|
self.assertEqual(["Starting service fake name"],
|
||||||
self.snatcher.output)
|
self.snatcher.output)
|
||||||
|
self._win32service_mock.StartService.assert_called_once_with(
|
||||||
mock_service.StartService.assert_called_once_with()
|
mock_hs.__enter__(), fake_service_name)
|
||||||
|
mock_get_service_handle.assert_called_once_with(
|
||||||
def test_start_service(self):
|
fake_service_name, self._win32service_mock.SERVICE_START)
|
||||||
self._test_set_service_start_mode(ret_val=0)
|
|
||||||
|
|
||||||
def test_start_service_exception(self):
|
|
||||||
self._test_set_service_start_mode(ret_val=1)
|
|
||||||
|
|
||||||
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
|
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
|
||||||
'._get_service')
|
'._get_service_handle')
|
||||||
def _test_stop_service(self, mock_get_service, ret_val):
|
def test_stop_service(self, mock_get_service_handle):
|
||||||
mock_service = mock.MagicMock()
|
mock_hs = mock.MagicMock()
|
||||||
mock_get_service.return_value = mock_service
|
fake_service_name = "fake name"
|
||||||
mock_service.StopService.return_value = (ret_val,)
|
mock_get_service_handle.return_value = mock_hs
|
||||||
|
with self.snatcher:
|
||||||
if ret_val != 0:
|
self._winutils.stop_service(fake_service_name)
|
||||||
self.assertRaises(exception.CloudbaseInitException,
|
|
||||||
self._winutils.stop_service,
|
|
||||||
'fake name')
|
|
||||||
else:
|
|
||||||
with self.snatcher:
|
|
||||||
self._winutils.stop_service('fake name')
|
|
||||||
self.assertEqual(["Stopping service fake name"],
|
self.assertEqual(["Stopping service fake name"],
|
||||||
self.snatcher.output)
|
self.snatcher.output)
|
||||||
|
self._win32service_mock.ControlService.assert_called_once_with(
|
||||||
mock_service.StopService.assert_called_once_with()
|
mock_hs.__enter__(),
|
||||||
|
self._win32service_mock.SERVICE_CONTROL_STOP)
|
||||||
def test_stop_service(self):
|
mock_get_service_handle.assert_called_once_with(
|
||||||
self._test_stop_service(ret_val=0)
|
fake_service_name, self._win32service_mock.SERVICE_STOP |
|
||||||
|
self._win32service_mock.SERVICE_QUERY_STATUS)
|
||||||
def test_stop_service_exception(self):
|
|
||||||
self._test_stop_service(ret_val=1)
|
|
||||||
|
|
||||||
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
|
@mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'
|
||||||
'.stop_service')
|
'.stop_service')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user