Coverage for tests / test_utils.py: 29%

54 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-04-15 00:23 +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 lsst.skymap as skyMap 

25import lsst.utils.tests 

26import numpy as np 

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

28from urllib3.response import HTTPResponse 

29 

30 

31class TestTractPatchUtils(lsst.utils.tests.TestCase): 

32 """Test to see if the tract and patch corner calculations are working. 

33 Includes a test case in which the tract spans the RA=360 line to ensure 

34 that RA wrapping is working as expected. 

35 """ 

36 

37 def setUp(self): 

38 

39 # Tract 0, Patch 8 of the following SkyMap spans RA=360. 

40 self.tractIds = [0, 1] 

41 self.patchIds = [8, 0] 

42 skyMapConfig = skyMap.discreteSkyMap.DiscreteSkyMapConfig() 

43 skyMapConfig.raList = [0, 180] 

44 skyMapConfig.decList = [-1, 1] 

45 skyMapConfig.radiusList = [0.1, 0.1] 

46 self.skyMap = skyMap.DiscreteSkyMap(skyMapConfig) 

47 

48 self.tractCorners = [ 

49 [ 

50 (358.8900906668926, -2.1096270745156804), 

51 (361.10981685029367, -2.1096270745156804), 

52 (361.10981685029367, 0.11009493220816949), 

53 (358.8900906668926, 0.11009493220816949), 

54 ], 

55 [ 

56 (181.10981686420706, -0.11000243565052142), 

57 (178.89009065297807, -0.110002449565178), 

58 (178.88933977564471, 2.109719508502047), 

59 (181.1105676789934, 2.1097195571483582), 

60 ], 

61 ] 

62 self.patchCorners = [ 

63 [ 

64 (359.9999537372586, -1.7399434656613333), 

65 (360.37005438077574, -1.7399434656613333), 

66 (360.37005438077574, -1.369927758180603), 

67 (359.9999537372586, -1.369927758180603), 

68 ], 

69 [ 

70 (181.10981695667596, -0.11000252814707863), 

71 (180.73987541079327, -0.1099561458277576), 

72 (180.73992023207617, 0.2600039998656897), 

73 (181.10988418299306, 0.25993833301062175), 

74 ], 

75 ] 

76 

77 def testTractCorners(self): 

78 

79 for i, tractId in enumerate(self.tractIds): 

80 np.testing.assert_array_almost_equal( 

81 getTractCorners(self.skyMap, tractId), 

82 self.tractCorners[i], 

83 ) 

84 

85 def testPatchCorners(self): 

86 

87 for i, (tractId, patchId) in enumerate(zip(self.tractIds, self.patchIds)): 

88 tractInfo = self.skyMap.generateTract(tractId) 

89 np.testing.assert_array_almost_equal(getPatchCorners(tractInfo, patchId), self.patchCorners[i]) 

90 

91 

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

93 """Tests the HTTP retry adapter. 

94 

95 For common server-side HTTP failure scenarios, test the implementation of 

96 a retry adapter to ensure that retry scenarios are being applied, 

97 especially those that are non-standard or application-specific such as 

98 for HTTP POST, which is not retried by default. 

99 """ 

100 

101 def setUp(self): 

102 """For each test, create a set of HTTP status codes the client should 

103 encounter. These include server-side failures (5xx) and client rate 

104 limiting (429) before an eventual success (200). 

105 """ 

106 responses = [] 

107 self.patcher = patch("urllib3.connectionpool.HTTPConnectionPool._get_conn") 

108 self.mock = self.patcher.start() 

109 self.mock_url = "http://mock/api/resource/1" 

110 for code in [500, 503, 429, 200]: 

111 _response = MagicMock(spec=HTTPResponse()) 

112 _response.status = code 

113 _response.connection = MagicMock() 

114 _response.headers = {} 

115 responses.append(_response) 

116 self.mock.return_value.getresponse.side_effect = responses 

117 

118 def tearDown(self): 

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

120 self.patcher.stop() 

121 self.mock = None 

122 

123 def testRetryServerErrorOnGet(self): 

124 """A GET request that fails before succeeding""" 

125 with http_client() as session: 

126 r = session.get(self.mock_url) 

127 assert r.ok 

128 assert len(r.raw.retries.history) == 3 

129 

130 def testRetryServerErrorOnPost(self): 

131 """A POST request that fails before succeeding""" 

132 with http_client() as session: 

133 r = session.post(self.mock_url) 

134 assert r.ok 

135 assert len(r.raw.retries.history) == 3 

136 

137 

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

139 lsst.utils.tests.init() 

140 unittest.main()