Coverage for tests / test_panda_service.py: 26%
103 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-30 08:55 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-30 08:55 +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/>.
28"""Unit tests for ctrl_bps_panda panda_service module."""
30import logging
31import unittest
33from idds.common.constants import WorkStatus
35from lsst.ctrl.bps import BpsConfig, WmsStates
36from lsst.ctrl.bps.panda import panda_service
38_LOG = logging.getLogger(__name__)
41class MockClient:
42 """Mock idds client."""
44 def __init__(self):
45 _LOG.debug("Called mock client init")
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, []])
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 )
94 return requests
97class TestPanDAService(unittest.TestCase):
98 """Test PanDAService class methods."""
100 def setUp(self):
101 config = BpsConfig({}, wms_service_class_fqn="lsst.ctrl.bps.panda.PanDAService")
102 self.service = panda_service.PanDAService(config)
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")
109 self.assertEqual(status, WmsStates.UNKNOWN)
110 self.assertEqual(
111 message, "Error getting workflow status for id 1000: ret = (1, 'PanDA error message')"
112 )
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")
119 self.assertEqual(status, WmsStates.UNKNOWN)
120 self.assertEqual(message, "No records found for workflow id '9999'. Hint: double check the id")
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")
127 self.assertEqual(status, WmsStates.SUCCEEDED)
128 self.assertEqual(message, "")
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")
135 self.assertEqual(status, WmsStates.FAILED)
136 self.assertEqual(message, "")
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")
143 self.assertEqual(status, WmsStates.FAILED)
144 self.assertEqual(message, "")
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")
151 self.assertEqual(status, WmsStates.DELETED)
152 self.assertEqual(message, "")
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")
159 self.assertEqual(status, WmsStates.HELD)
160 self.assertEqual(message, "")
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")
167 self.assertEqual(status, WmsStates.RUNNING)
168 self.assertEqual(message, "")
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")
175 self.assertEqual(status, WmsStates.RUNNING)
176 self.assertEqual(message, "")
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")
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 )
193if __name__ == "__main__": 193 ↛ 194line 193 didn't jump to line 194 because the condition on line 193 was never true
194 unittest.main()