Coverage for tests / test_panda_service.py: 26%

103 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-04-18 08:49 +0000

1# This file is part of ctrl_bps_panda. 

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 ctrl_bps_panda panda_service module.""" 

29 

30import logging 

31import unittest 

32 

33from idds.common.constants import WorkStatus 

34 

35from lsst.ctrl.bps import BpsConfig, WmsStates 

36from lsst.ctrl.bps.panda import panda_service 

37 

38_LOG = logging.getLogger(__name__) 

39 

40 

41class MockClient: 

42 """Mock idds client.""" 

43 

44 def __init__(self): 

45 _LOG.debug("Called mock client init") 

46 

47 def get_requests(self, request_id, with_detail): 

48 _LOG.debug("Called mock client get_requests with %s", request_id) 

49 status = None 

50 match request_id: 

51 case "1000": # GetRequestsFailure 

52 requests = (1, "PanDA error message") 

53 case "1001": 

54 status = WorkStatus.Finished 

55 case "1002": 

56 status = WorkStatus.SubFinished 

57 case "1003": 

58 status = WorkStatus.Failed 

59 case "1004": 

60 status = WorkStatus.Cancelled 

61 case "1005": 

62 status = WorkStatus.Suspended 

63 case "1006": 

64 status = WorkStatus.Running 

65 case "1007": 

66 status = WorkStatus.Transforming 

67 case "1008": 

68 requests = (0, [True, [False, "An unknown IDDS exception occurred."]]) 

69 case _: # Unknown ID 

70 requests = (0, [True, []]) 

71 

72 if status: 

73 workflow_name = "FAKE_WORKFLOW_NAME_20250515T213417Z" 

74 requests = ( 

75 0, 

76 [ 

77 True, 

78 [ 

79 { 

80 "name": workflow_name, 

81 "request_id": request_id, 

82 "status": { 

83 "attributes": { 

84 "_value_": status.value, 

85 "_name_": status.name, 

86 "_sort_order_": status.value, 

87 } 

88 }, 

89 } 

90 ], 

91 ], 

92 ) 

93 

94 return requests 

95 

96 

97class TestPanDAService(unittest.TestCase): 

98 """Test PanDAService class methods.""" 

99 

100 def setUp(self): 

101 config = BpsConfig({}, wms_service_class_fqn="lsst.ctrl.bps.panda.PanDAService") 

102 self.service = panda_service.PanDAService(config) 

103 

104 @unittest.mock.patch("lsst.ctrl.bps.panda.panda_service.get_idds_client") 

105 def testGetStatusGetRequestsFailure(self, mock_get): 

106 mock_get.return_value = MockClient() 

107 status, message = self.service.get_status("1000") 

108 

109 self.assertEqual(status, WmsStates.UNKNOWN) 

110 self.assertEqual( 

111 message, "Error getting workflow status for id 1000: ret = (1, 'PanDA error message')" 

112 ) 

113 

114 @unittest.mock.patch("lsst.ctrl.bps.panda.panda_service.get_idds_client") 

115 def testGetStatusUnknownID(self, mock_get): 

116 mock_get.return_value = MockClient() 

117 status, message = self.service.get_status("9999") 

118 

119 self.assertEqual(status, WmsStates.UNKNOWN) 

120 self.assertEqual(message, "No records found for workflow id '9999'. Hint: double check the id") 

121 

122 @unittest.mock.patch("lsst.ctrl.bps.panda.panda_service.get_idds_client") 

123 def testGetStatusFinished(self, mock_get): 

124 mock_get.return_value = MockClient() 

125 status, message = self.service.get_status("1001") 

126 

127 self.assertEqual(status, WmsStates.SUCCEEDED) 

128 self.assertEqual(message, "") 

129 

130 @unittest.mock.patch("lsst.ctrl.bps.panda.panda_service.get_idds_client") 

131 def testGetStatusSubFinished(self, mock_get): 

132 mock_get.return_value = MockClient() 

133 status, message = self.service.get_status("1002") 

134 

135 self.assertEqual(status, WmsStates.FAILED) 

136 self.assertEqual(message, "") 

137 

138 @unittest.mock.patch("lsst.ctrl.bps.panda.panda_service.get_idds_client") 

139 def testGetStatusFailed(self, mock_get): 

140 mock_get.return_value = MockClient() 

141 status, message = self.service.get_status("1003") 

142 

143 self.assertEqual(status, WmsStates.FAILED) 

144 self.assertEqual(message, "") 

145 

146 @unittest.mock.patch("lsst.ctrl.bps.panda.panda_service.get_idds_client") 

147 def testGetStatusCancelled(self, mock_get): 

148 mock_get.return_value = MockClient() 

149 status, message = self.service.get_status("1004") 

150 

151 self.assertEqual(status, WmsStates.DELETED) 

152 self.assertEqual(message, "") 

153 

154 @unittest.mock.patch("lsst.ctrl.bps.panda.panda_service.get_idds_client") 

155 def testGetStatusSuspended(self, mock_get): 

156 mock_get.return_value = MockClient() 

157 status, message = self.service.get_status("1005") 

158 

159 self.assertEqual(status, WmsStates.HELD) 

160 self.assertEqual(message, "") 

161 

162 @unittest.mock.patch("lsst.ctrl.bps.panda.panda_service.get_idds_client") 

163 def testGetStatusRunning(self, mock_get): 

164 mock_get.return_value = MockClient() 

165 status, message = self.service.get_status("1006") 

166 

167 self.assertEqual(status, WmsStates.RUNNING) 

168 self.assertEqual(message, "") 

169 

170 @unittest.mock.patch("lsst.ctrl.bps.panda.panda_service.get_idds_client") 

171 def testGetStatusTransforming(self, mock_get): 

172 mock_get.return_value = MockClient() 

173 status, message = self.service.get_status("1007") 

174 

175 self.assertEqual(status, WmsStates.RUNNING) 

176 self.assertEqual(message, "") 

177 

178 @unittest.mock.patch("lsst.ctrl.bps.panda.panda_service.get_idds_client") 

179 def testGetStatusUnknownIDDSException(self, mock_get): 

180 # Test example unknown IDDS exception similar to what occurs 

181 # if give path to ctrl_bps_panda's get_status. 

182 mock_get.return_value = MockClient() 

183 status, message = self.service.get_status("1008") 

184 

185 self.assertEqual(status, WmsStates.UNKNOWN) 

186 self.assertEqual( 

187 message, 

188 "Error getting workflow status for id 1008: ret = " 

189 "(0, [True, [False, 'An unknown IDDS exception occurred.']])", 

190 ) 

191 

192 

193if __name__ == "__main__": 193 ↛ 194line 193 didn't jump to line 194 because the condition on line 193 was never true

194 unittest.main()