Coverage for tests / test_utils.py: 29%

54 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-04-22 09:32 +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/>. 

20 

21import unittest 

22from unittest.mock import MagicMock, patch 

23 

24import numpy as np 

25from urllib3.response import HTTPResponse 

26 

27import lsst.skymap as skyMap 

28import lsst.utils.tests 

29from lsst.analysis.tools.utils import getPatchCorners, getTractCorners, http_client 

30 

31 

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 """ 

37 

38 def setUp(self): 

39 

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) 

48 

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 ] 

77 

78 def testTractCorners(self): 

79 

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 ) 

85 

86 def testPatchCorners(self): 

87 

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]) 

91 

92 

93class TestHttpSessionAdapters(lsst.utils.tests.TestCase): 

94 """Tests the HTTP retry adapter. 

95 

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 """ 

101 

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 

118 

119 def tearDown(self): 

120 """After each test, reset the patched mock object state.""" 

121 self.patcher.stop() 

122 self.mock = None 

123 

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 

130 

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 

137 

138 

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()