@@ -50,12 +50,16 @@ class TestWindowsUtils(testutils.CloudbaseInitTestBase):
50
50
51
51
def setUp (self ):
52
52
self ._pywintypes_mock = mock .MagicMock ()
53
+ self ._pywintypes_mock .error = fake .FakeError
53
54
self ._pywintypes_mock .com_error = fake .FakeComError
54
55
self ._win32com_mock = mock .MagicMock ()
55
56
self ._win32process_mock = mock .MagicMock ()
56
57
self ._win32security_mock = mock .MagicMock ()
57
58
self ._win32net_mock = mock .MagicMock ()
58
59
self ._win32netcon_mock = mock .MagicMock ()
60
+ self ._win32service_mock = mock .MagicMock ()
61
+ self ._winerror_mock = mock .MagicMock ()
62
+ self ._winerror_mock .ERROR_SERVICE_DOES_NOT_EXIST = 0x424
59
63
self ._wmi_mock = mock .MagicMock ()
60
64
self ._wmi_mock .x_wmi = WMIError
61
65
self ._moves_mock = mock .MagicMock ()
@@ -73,6 +77,8 @@ def setUp(self):
73
77
'win32security' : self ._win32security_mock ,
74
78
'win32net' : self ._win32net_mock ,
75
79
'win32netcon' : self ._win32netcon_mock ,
80
+ 'win32service' : self ._win32service_mock ,
81
+ 'winerror' : self ._winerror_mock ,
76
82
'wmi' : self ._wmi_mock ,
77
83
'six.moves' : self ._moves_mock ,
78
84
'six.moves.xmlrpc_client' : self ._xmlrpc_client_mock ,
@@ -884,14 +890,152 @@ def test_get_service(self):
884
890
self .assertEqual ('fake name' , response )
885
891
886
892
@mock .patch ('cloudbaseinit.osutils.windows.WindowsUtils'
887
- '._get_service' )
888
- def test_check_service_exists (self , mock_get_service ):
889
- mock_get_service .return_value = 'not None'
893
+ '._get_service_handle' )
894
+ def test_check_service (self , mock_get_service_handle ):
895
+ mock_context_manager = mock .MagicMock ()
896
+ mock_context_manager .__enter__ .return_value = "fake name"
897
+ mock_get_service_handle .return_value = mock_context_manager
898
+
899
+ self .assertTrue (self ._winutils .check_service_exists ("fake_name" ))
900
+
901
+ @mock .patch ('cloudbaseinit.osutils.windows.WindowsUtils'
902
+ '._get_service_handle' )
903
+ def test_check_service_fail (self , mock_get_service_handle ):
904
+ exc = self ._pywintypes_mock .error ("ERROR_SERVICE_DOES_NOT_EXIST" )
905
+ exc .winerror = self ._winerror_mock .ERROR_SERVICE_DOES_NOT_EXIST
906
+
907
+ exc2 = self ._pywintypes_mock .error ("NOT ERROR_SERVICE_DOES_NOT_EXIST" )
908
+ exc2 .winerror = None
909
+
910
+ mock_context_manager = mock .MagicMock ()
911
+ mock_context_manager .__enter__ .side_effect = [exc , exc2 ]
912
+ mock_get_service_handle .return_value = mock_context_manager
913
+
914
+ self .assertFalse (self ._winutils .check_service_exists ("fake_name" ))
915
+ self .assertRaises (self ._pywintypes_mock .error ,
916
+ self ._winutils .check_service_exists ,
917
+ "fake_name" )
918
+
919
+ def test_get_service_handle (self ):
920
+ open_scm = self ._win32service_mock .OpenSCManager
921
+ open_scm .return_value = mock .sentinel .hscm
922
+ open_service = self ._win32service_mock .OpenService
923
+ open_service .return_value = mock .sentinel .hs
924
+ close_service = self ._win32service_mock .CloseServiceHandle
925
+ args = ("fake_name" , mock .sentinel .service_access ,
926
+ mock .sentinel .scm_access )
927
+
928
+ with self ._winutils ._get_service_handle (* args ) as hs :
929
+ self .assertIs (hs , mock .sentinel .hs )
930
+
931
+ open_scm .assert_called_with (None , None , mock .sentinel .scm_access )
932
+ open_service .assert_called_with (mock .sentinel .hscm , "fake_name" ,
933
+ mock .sentinel .service_access )
934
+ close_service .assert_has_calls ([mock .call (mock .sentinel .hs ),
935
+ mock .call (mock .sentinel .hscm )])
936
+
937
+ @mock .patch ('cloudbaseinit.osutils.windows.WindowsUtils'
938
+ '._get_service_handle' )
939
+ def test_set_service_credentials (self , mock_get_service ):
940
+ self ._win32service_mock .SERVICE_CHANGE_CONFIG = mock .sentinel .change
941
+ self ._win32service_mock .SERVICE_NO_CHANGE = mock .sentinel .no_change
942
+ mock_change_service = self ._win32service_mock .ChangeServiceConfig
943
+ mock_context_manager = mock .MagicMock ()
944
+ mock_context_manager .__enter__ .return_value = mock .sentinel .hs
945
+ mock_get_service .return_value = mock_context_manager
946
+
947
+ self ._winutils .set_service_credentials (
948
+ mock .sentinel .service , mock .sentinel .user , mock .sentinel .password )
949
+
950
+ mock_get_service .assert_called_with (mock .sentinel .service ,
951
+ mock .sentinel .change )
952
+ mock_change_service .assert_called_with (
953
+ mock .sentinel .hs , mock .sentinel .no_change , mock .sentinel .no_change ,
954
+ mock .sentinel .no_change , None , None , False , None ,
955
+ mock .sentinel .user , mock .sentinel .password , None )
956
+
957
+ @mock .patch ('cloudbaseinit.osutils.windows.WindowsUtils'
958
+ '._get_service_handle' )
959
+ def test_get_service_username (self , mock_get_service ):
960
+ mock_context_manager = mock .MagicMock ()
961
+ mock_context_manager .__enter__ .return_value = mock .sentinel .hs
962
+ mock_get_service .return_value = mock_context_manager
963
+ mock_query_service = self ._win32service_mock .QueryServiceConfig
964
+ mock_query_service .return_value = [mock .sentinel .value ] * 8
965
+
966
+ response = self ._winutils .get_service_username (mock .sentinel .service )
967
+
968
+ mock_get_service .assert_called_with (mock .sentinel .service )
969
+ mock_query_service .assert_called_with (mock .sentinel .hs )
970
+ self .assertIs (response , mock .sentinel .value )
971
+
972
+ @mock .patch ('cloudbaseinit.osutils.windows.WindowsUtils'
973
+ '.set_service_credentials' )
974
+ @mock .patch ('cloudbaseinit.osutils.windows.WindowsUtils'
975
+ '.set_user_password' )
976
+ @mock .patch ('cloudbaseinit.osutils.windows.WindowsUtils'
977
+ '.generate_random_password' )
978
+ @mock .patch ('cloudbaseinit.osutils.windows.WindowsUtils'
979
+ '.get_service_username' )
980
+ @mock .patch ('cloudbaseinit.osutils.windows.WindowsUtils'
981
+ '.check_service_exists' )
982
+ def _test_reset_service_password (self , mock_service_exists ,
983
+ mock_get_username , mock_generate_password ,
984
+ mock_set_password , mock_set_credentials ,
985
+ service_exists , service_username ):
986
+ mock_service_exists .return_value = service_exists
987
+ mock_get_username .return_value = service_username
988
+ mock_generate_password .return_value = mock .sentinel .password
989
+
990
+ with self .snatcher :
991
+ response = self ._winutils .reset_service_password ()
890
992
891
- response = self ._winutils .check_service_exists ('fake name' )
993
+ if not service_exists :
994
+ self .assertEqual (
995
+ ["Service does not exist: %s" % self ._winutils ._service_name ],
996
+ self .snatcher .output )
997
+ self .assertFalse (response )
998
+ return
999
+
1000
+ if "\\ " not in service_username :
1001
+ self .assertEqual (
1002
+ ["Skipping password reset, service running as a built-in "
1003
+ "account: %s" % service_username ], self .snatcher .output )
1004
+ self .assertFalse (response )
1005
+ return
892
1006
1007
+ domain , username = service_username .split ('\\ ' )
1008
+ if domain != "." :
1009
+ self .assertEqual (
1010
+ ["Skipping password reset, service running as a domain "
1011
+ "account: %s" % service_username ], self .snatcher .output )
1012
+ self .assertFalse (response )
1013
+ return
1014
+
1015
+ mock_set_password .assert_called_once_with (username ,
1016
+ mock .sentinel .password )
1017
+ mock_set_credentials .assert_called_once_with (
1018
+ self ._winutils ._service_name , service_username ,
1019
+ mock .sentinel .password )
1020
+ self .assertEqual (mock_generate_password .call_count , 1 )
893
1021
self .assertTrue (response )
894
1022
1023
+ def test_reset_service_password (self ):
1024
+ self ._test_reset_service_password (
1025
+ service_exists = True , service_username = "EXAMPLE.COM\\ username" )
1026
+
1027
+ def test_reset_service_password_no_service (self ):
1028
+ self ._test_reset_service_password (service_exists = False ,
1029
+ service_username = None )
1030
+
1031
+ def test_reset_service_password_built_in_account (self ):
1032
+ self ._test_reset_service_password (service_exists = True ,
1033
+ service_username = "username" )
1034
+
1035
+ def test_reset_service_password_domain_account (self ):
1036
+ self ._test_reset_service_password (service_exists = True ,
1037
+ service_username = ".\\ username" )
1038
+
895
1039
@mock .patch ('cloudbaseinit.osutils.windows.WindowsUtils'
896
1040
'._get_service' )
897
1041
def test_get_service_status (self , mock_get_service ):
0 commit comments