Coverage for tests / test_htcondor_service.py: 38%

88 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-01-24 01:18 -0800

1# This file is part of ctrl_bps_htcondor. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (https://www.lsst.org). 

6# See the COPYRIGHT file at the top-level directory of this distribution 

7# for details of code ownership. 

8# 

9# This software is dual licensed under the GNU General Public License and also 

10# under a 3-clause BSD license. Recipients may choose which of these licenses 

11# to use; please see the files gpl-3.0.txt and/or bsd_license.txt, 

12# respectively. If you choose the GPL option then the following text applies 

13# (but note that there is still no warranty even if you opt for BSD instead): 

14# 

15# This program is free software: you can redistribute it and/or modify 

16# it under the terms of the GNU General Public License as published by 

17# the Free Software Foundation, either version 3 of the License, or 

18# (at your option) any later version. 

19# 

20# This program is distributed in the hope that it will be useful, 

21# but WITHOUT ANY WARRANTY; without even the implied warranty of 

22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

23# GNU General Public License for more details. 

24# 

25# You should have received a copy of the GNU General Public License 

26# along with this program. If not, see <https://www.gnu.org/licenses/>. 

27 

28"""Unit tests for the HTCondor WMS service class and related functions.""" 

29 

30import logging 

31import unittest 

32 

33import htcondor 

34 

35from lsst.ctrl.bps import ( 

36 BpsConfig, 

37 WmsStates, 

38) 

39from lsst.ctrl.bps.htcondor import htcondor_service 

40from lsst.ctrl.bps.htcondor.htcondor_config import HTC_DEFAULTS_URI 

41 

42logger = logging.getLogger("lsst.ctrl.bps.htcondor") 

43 

44LOCATE_SUCCESS = """[ 

45 CondorPlatform = "$CondorPlatform: X86_64-CentOS_7.9 $"; 

46 MyType = "Scheduler"; 

47 Machine = "testmachine"; 

48 Name = "testmachine"; 

49 CondorVersion = "$CondorVersion: 23.0.3 2024-04-04 $"; 

50 MyAddress = "<127.0.0.1:9618?addrs=127.0.0.1-9618+snip>" 

51 ] 

52""" 

53 

54PING_SUCCESS = """[ 

55 AuthCommand = 60011; 

56 AuthMethods = "FS_REMOTE"; 

57 Command = 60040; 

58 AuthorizationSucceeded = true; 

59 ValidCommands = "60002,60003,60011,60014,60045,60046,60047,60048,60049,60050,60052,523"; 

60 TriedAuthentication = true; 

61 RemoteVersion = "$CondorVersion: 10.9.0 2023-09-28 BuildID: 678228 PackageID: 10.9.0-1 $"; 

62 MyRemoteUserName = "testuser@testmachine"; 

63 Authentication = "YES"; 

64 ] 

65""" 

66 

67 

68class HTCondorServiceTestCase(unittest.TestCase): 

69 """Test selected methods of the HTCondor WMS service class.""" 

70 

71 def setUp(self): 

72 config = BpsConfig({}, wms_service_class_fqn="lsst.ctrl.bps.htcondor.HTCondorService") 

73 self.service = htcondor_service.HTCondorService(config) 

74 

75 def tearDown(self): 

76 pass 

77 

78 def testDefaults(self): 

79 self.assertEqual(self.service.defaults["memoryLimit"], 491520) 

80 

81 def testDefaultsPath(self): 

82 self.assertEqual(self.service.defaults_uri, HTC_DEFAULTS_URI) 

83 self.assertFalse(self.service.defaults_uri.isdir()) 

84 

85 @unittest.mock.patch.object(htcondor.SecMan, "ping", return_value=PING_SUCCESS) 

86 @unittest.mock.patch.object(htcondor.Collector, "locate", return_value=LOCATE_SUCCESS) 

87 def testPingSuccess(self, mock_locate, mock_ping): 

88 status, message = self.service.ping(None) 

89 self.assertEqual(status, 0) 

90 self.assertEqual(message, "") 

91 

92 def testPingFailure(self): 

93 with unittest.mock.patch("htcondor.Collector.locate") as locate_mock: 

94 locate_mock.side_effect = htcondor.HTCondorLocateError() 

95 status, message = self.service.ping(None) 

96 self.assertEqual(status, 1) 

97 self.assertEqual(message, "Could not locate Schedd service.") 

98 

99 @unittest.mock.patch.object(htcondor.Collector, "locate", return_value=LOCATE_SUCCESS) 

100 def testPingPermission(self, mock_locate): 

101 with unittest.mock.patch("htcondor.SecMan.ping") as ping_mock: 

102 ping_mock.side_effect = htcondor.HTCondorIOError() 

103 status, message = self.service.ping(None) 

104 self.assertEqual(status, 1) 

105 self.assertEqual(message, "Permission problem with Schedd service.") 

106 

107 @unittest.mock.patch("lsst.ctrl.bps.htcondor.htcondor_service._get_status_from_id") 

108 @unittest.mock.patch("lsst.ctrl.bps.htcondor.htcondor_service._locate_schedds") 

109 @unittest.mock.patch("lsst.ctrl.bps.htcondor.htcondor_service._wms_id_type") 

110 def testGetStatusLocal(self, mock_type, mock_locate, mock_status): 

111 mock_type.return_value = htcondor_service.WmsIdType.LOCAL 

112 mock_locate.return_value = {} 

113 mock_status.return_value = (WmsStates.RUNNING, "") 

114 

115 fake_id = "100" 

116 state, message = self.service.get_status(fake_id) 

117 

118 mock_type.assert_called_once_with(fake_id) 

119 mock_locate.assert_called_once_with(locate_all=False) 

120 mock_status.assert_called_once_with(fake_id, 1, schedds={}) 

121 

122 self.assertEqual(state, WmsStates.RUNNING) 

123 self.assertEqual(message, "") 

124 

125 @unittest.mock.patch("lsst.ctrl.bps.htcondor.htcondor_service._get_status_from_id") 

126 @unittest.mock.patch("lsst.ctrl.bps.htcondor.htcondor_service._locate_schedds") 

127 @unittest.mock.patch("lsst.ctrl.bps.htcondor.htcondor_service._wms_id_type") 

128 def testGetStatusGlobal(self, mock_type, mock_locate, mock_status): 

129 mock_type.return_value = htcondor_service.WmsIdType.GLOBAL 

130 mock_locate.return_value = {} 

131 fake_message = "" 

132 mock_status.return_value = (WmsStates.RUNNING, fake_message) 

133 

134 fake_id = "100" 

135 state, message = self.service.get_status(fake_id, 2) 

136 

137 mock_type.assert_called_once_with(fake_id) 

138 mock_locate.assert_called_once_with(locate_all=True) 

139 mock_status.assert_called_once_with(fake_id, 2, schedds={}) 

140 

141 self.assertEqual(state, WmsStates.RUNNING) 

142 self.assertEqual(message, fake_message) 

143 

144 @unittest.mock.patch("lsst.ctrl.bps.htcondor.htcondor_service._get_status_from_path") 

145 @unittest.mock.patch("lsst.ctrl.bps.htcondor.htcondor_service._wms_id_type") 

146 def testGetStatusPath(self, mock_type, mock_status): 

147 fake_message = "fake message" 

148 mock_type.return_value = htcondor_service.WmsIdType.PATH 

149 mock_status.return_value = (WmsStates.FAILED, fake_message) 

150 

151 fake_id = "/fake/path" 

152 state, message = self.service.get_status(fake_id) 

153 

154 mock_type.assert_called_once_with(fake_id) 

155 mock_status.assert_called_once_with(fake_id) 

156 

157 self.assertEqual(state, WmsStates.FAILED) 

158 self.assertEqual(message, fake_message) 

159 

160 @unittest.mock.patch("lsst.ctrl.bps.htcondor.htcondor_service._wms_id_type") 

161 def testGetStatusUnknownType(self, mock_type): 

162 mock_type.return_value = htcondor_service.WmsIdType.UNKNOWN 

163 

164 fake_id = "100.0" 

165 state, message = self.service.get_status(fake_id) 

166 

167 mock_type.assert_called_once_with(fake_id) 

168 

169 self.assertEqual(state, WmsStates.UNKNOWN) 

170 self.assertEqual(message, "Invalid job id")