Coverage for tests / test_utils.py: 29%
54 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-05-04 17:42 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-05-04 17:42 +0000
1#
2# Developed for the LSST Data Management System.
3# This product includes software developed by the LSST Project
4# (https://www.lsst.org).
5# See the COPYRIGHT file at the top-level directory of this distribution
6# for details of code ownership.
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program. If not, see <https://www.gnu.org/licenses/>.
21import unittest
22from unittest.mock import MagicMock, patch
24import numpy as np
25from urllib3.response import HTTPResponse
27import lsst.skymap as skyMap
28import lsst.utils.tests
29from lsst.analysis.tools.utils import getPatchCorners, getTractCorners, http_client
32class TestTractPatchUtils(lsst.utils.tests.TestCase):
33 """Test to see if the tract and patch corner calculations are working.
34 Includes a test case in which the tract spans the RA=360 line to ensure
35 that RA wrapping is working as expected.
36 """
38 def setUp(self):
40 # Tract 0, Patch 8 of the following SkyMap spans RA=360.
41 self.tractIds = [0, 1]
42 self.patchIds = [8, 0]
43 skyMapConfig = skyMap.discreteSkyMap.DiscreteSkyMapConfig()
44 skyMapConfig.raList = [0, 180]
45 skyMapConfig.decList = [-1, 1]
46 skyMapConfig.radiusList = [0.1, 0.1]
47 self.skyMap = skyMap.DiscreteSkyMap(skyMapConfig)
49 self.tractCorners = [
50 [
51 (358.8900906668926, -2.1096270745156804),
52 (361.10981685029367, -2.1096270745156804),
53 (361.10981685029367, 0.11009493220816949),
54 (358.8900906668926, 0.11009493220816949),
55 ],
56 [
57 (181.10981686420706, -0.11000243565052142),
58 (178.89009065297807, -0.110002449565178),
59 (178.88933977564471, 2.109719508502047),
60 (181.1105676789934, 2.1097195571483582),
61 ],
62 ]
63 self.patchCorners = [
64 [
65 (359.9999537372586, -1.7399434656613333),
66 (360.37005438077574, -1.7399434656613333),
67 (360.37005438077574, -1.369927758180603),
68 (359.9999537372586, -1.369927758180603),
69 ],
70 [
71 (181.10981695667596, -0.11000252814707863),
72 (180.73987541079327, -0.1099561458277576),
73 (180.73992023207617, 0.2600039998656897),
74 (181.10988418299306, 0.25993833301062175),
75 ],
76 ]
78 def testTractCorners(self):
80 for i, tractId in enumerate(self.tractIds):
81 np.testing.assert_array_almost_equal(
82 getTractCorners(self.skyMap, tractId),
83 self.tractCorners[i],
84 )
86 def testPatchCorners(self):
88 for i, (tractId, patchId) in enumerate(zip(self.tractIds, self.patchIds)):
89 tractInfo = self.skyMap.generateTract(tractId)
90 np.testing.assert_array_almost_equal(getPatchCorners(tractInfo, patchId), self.patchCorners[i])
93class TestHttpSessionAdapters(lsst.utils.tests.TestCase):
94 """Tests the HTTP retry adapter.
96 For common server-side HTTP failure scenarios, test the implementation of
97 a retry adapter to ensure that retry scenarios are being applied,
98 especially those that are non-standard or application-specific such as
99 for HTTP POST, which is not retried by default.
100 """
102 def setUp(self):
103 """For each test, create a set of HTTP status codes the client should
104 encounter. These include server-side failures (5xx) and client rate
105 limiting (429) before an eventual success (200).
106 """
107 responses = []
108 self.patcher = patch("urllib3.connectionpool.HTTPConnectionPool._get_conn")
109 self.mock = self.patcher.start()
110 self.mock_url = "http://mock/api/resource/1"
111 for code in [500, 503, 429, 200]:
112 _response = MagicMock(spec=HTTPResponse())
113 _response.status = code
114 _response.connection = MagicMock()
115 _response.headers = {}
116 responses.append(_response)
117 self.mock.return_value.getresponse.side_effect = responses
119 def tearDown(self):
120 """After each test, reset the patched mock object state."""
121 self.patcher.stop()
122 self.mock = None
124 def testRetryServerErrorOnGet(self):
125 """A GET request that fails before succeeding"""
126 with http_client() as session:
127 r = session.get(self.mock_url)
128 assert r.ok
129 assert len(r.raw.retries.history) == 3
131 def testRetryServerErrorOnPost(self):
132 """A POST request that fails before succeeding"""
133 with http_client() as session:
134 r = session.post(self.mock_url)
135 assert r.ok
136 assert len(r.raw.retries.history) == 3
139if __name__ == "__main__": 139 ↛ 140line 139 didn't jump to line 140 because the condition on line 139 was never true
140 lsst.utils.tests.init()
141 unittest.main()