Coverage for tests / test_utils.py: 8%

183 statements  

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

1# This file is part of utils. 

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 program is free software: you can redistribute it and/or modify 

10# it under the terms of the GNU General Public License as published by 

11# the Free Software Foundation, either version 3 of the License, or 

12# (at your option) any later version. 

13# 

14# This program is distributed in the hope that it will be useful, 

15# but WITHOUT ANY WARRANTY; without even the implied warranty of 

16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

17# GNU General Public License for more details. 

18# 

19# You should have received a copy of the GNU General Public License 

20# along with this program. If not, see <https://www.gnu.org/licenses/>. 

21 

22import sys 

23import unittest 

24 

25import numpy as np 

26 

27import lsst.utils.tests 

28 

29# set to True to test plotting and printing by-eye when tests fail 

30display = False 

31 

32 

33class UtilsTestCase(lsst.utils.tests.TestCase): 

34 """Test the utils test case.""" 

35 

36 def setUp(self): 

37 self.large = 100.0 

38 self.epsilon = 1e-8 

39 self.zeros = np.zeros((5, 5), dtype=float) 

40 self.zeros2 = np.zeros((5, 5), dtype=float) 

41 self.epsilons = np.zeros((5, 5), dtype=float) + self.epsilon 

42 self.larges = np.zeros((5, 5), dtype=float) + self.large 

43 self.larges2 = np.zeros((5, 5), dtype=float) + self.large 

44 self.largesOneOff = self.larges.copy() 

45 self.largesOneOff[0] += self.epsilon 

46 self.largesEpsilon = np.zeros((5, 5), dtype=float) + self.large + self.epsilon 

47 self.ranges = np.arange(-12.0, 13.0).reshape(5, 5) 

48 self.rangesEpsilon = self.ranges.copy() 

49 self.rangesEpsilon += np.linspace(-1e-4, 1e-4, 5) 

50 

51 def test_assertFloatsAlmostEqual(self): 

52 # zero scalar tests 

53 self.assertFloatsAlmostEqual(0.0, 0.0) 

54 self.assertFloatsAlmostEqual(0.0, 1e-8, atol=1e-7) 

55 self.assertFloatsAlmostEqual(0.0, 1e-8, atol=1e-7, rtol=None) 

56 self.assertFloatsAlmostEqual(0.0, 1e-8, atol=None, rtol=1e-5, relTo=1e-2) 

57 

58 # zero array vs. scalar tests 

59 self.assertFloatsAlmostEqual(self.zeros, 0.0) 

60 self.assertFloatsAlmostEqual(self.zeros, self.epsilon, atol=1e-7) 

61 self.assertFloatsAlmostEqual(self.zeros, self.epsilon, atol=1e-7, rtol=None) 

62 self.assertFloatsAlmostEqual(self.zeros, self.epsilon, atol=None, rtol=1e-5, relTo=1e-2) 

63 

64 # zero array vs. array tests 

65 self.assertFloatsAlmostEqual(self.zeros, self.zeros2) 

66 self.assertFloatsAlmostEqual(self.zeros, self.zeros2, rtol=None) 

67 self.assertFloatsAlmostEqual(self.zeros, self.zeros2, atol=None) 

68 self.assertFloatsAlmostEqual(self.zeros, self.epsilons, atol=1e-7) 

69 self.assertFloatsAlmostEqual(self.zeros, self.epsilons, atol=1e-7, rtol=None) 

70 self.assertFloatsAlmostEqual(self.zeros, self.epsilons, atol=None, rtol=1e-5, relTo=1e-2) 

71 

72 # invalid value tests 

73 with self.assertRaises(ValueError): 

74 self.assertFloatsAlmostEqual(self.zeros, self.zeros2, atol=None, rtol=None) 

75 

76 # non-zero scalar tests 

77 self.assertFloatsAlmostEqual(self.large, 100.0) 

78 self.assertFloatsAlmostEqual(self.large, self.large + self.epsilon, rtol=1e-7) 

79 self.assertFloatsAlmostEqual(self.large, self.large + self.epsilon, rtol=1e-7, atol=None) 

80 self.assertFloatsAlmostEqual(self.large, self.large + self.epsilon, rtol=1e-7, relTo=100.0) 

81 

82 # Non-zero array vs. scalar tests 

83 self.assertFloatsAlmostEqual(self.larges, self.large) 

84 self.assertFloatsAlmostEqual(self.larges, self.large + self.epsilon, rtol=1e-7) 

85 self.assertFloatsAlmostEqual(self.larges, self.large + self.epsilon, rtol=1e-7, atol=None) 

86 self.assertFloatsAlmostEqual(self.larges, self.large + self.epsilon, rtol=1e-7, relTo=100.0) 

87 

88 # Non-zero array vs. array tests 

89 self.assertFloatsAlmostEqual(self.larges, self.larges2) 

90 self.assertFloatsAlmostEqual(self.larges, self.largesEpsilon, rtol=1e-7) 

91 self.assertFloatsAlmostEqual(self.larges, self.largesEpsilon, rtol=1e-7, atol=None) 

92 self.assertFloatsAlmostEqual(self.larges, self.largesEpsilon, rtol=1e-7, relTo=100.0) 

93 self.assertFloatsAlmostEqual(self.larges, self.largesOneOff, atol=1e-7) 

94 self.assertFloatsAlmostEqual(self.ranges, self.rangesEpsilon, rtol=1e-3, atol=1e-4) 

95 

96 # Test that it raises appropriately 

97 with self.assertRaises(AssertionError): 

98 self.assertFloatsAlmostEqual(self.large, 0.0) 

99 with self.assertRaises(AssertionError): 

100 self.assertFloatsAlmostEqual(self.large, 0.0, rtol=1e-2) 

101 with self.assertRaises(AssertionError): 

102 self.assertFloatsAlmostEqual(self.large, 0.0, rtol=1e-2, atol=None) 

103 with self.assertRaises(AssertionError): 

104 self.assertFloatsAlmostEqual(self.large, 0.0, atol=1e-2) 

105 with self.assertRaises(AssertionError): 

106 self.assertFloatsAlmostEqual(self.large, 0.0, atol=1e-2, rtol=None) 

107 

108 with self.assertRaises(AssertionError): 

109 self.assertFloatsAlmostEqual(self.larges, 0.0) 

110 with self.assertRaises(AssertionError): 

111 self.assertFloatsAlmostEqual(self.larges, 0.0, rtol=1e-2) 

112 with self.assertRaises(AssertionError): 

113 self.assertFloatsAlmostEqual(self.larges, 0.0, rtol=1e-2, atol=None) 

114 with self.assertRaises(AssertionError): 

115 self.assertFloatsAlmostEqual(self.larges, 0.0, atol=1e-2) 

116 with self.assertRaises(AssertionError): 

117 self.assertFloatsAlmostEqual(self.larges, 0.0, atol=1e-2, rtol=None) 

118 

119 with self.assertRaises(AssertionError): 

120 self.assertFloatsAlmostEqual(0.0, self.larges) 

121 with self.assertRaises(AssertionError): 

122 self.assertFloatsAlmostEqual(0.0, self.larges, rtol=1e-2) 

123 with self.assertRaises(AssertionError): 

124 self.assertFloatsAlmostEqual(0.0, self.larges, rtol=1e-2, atol=None) 

125 with self.assertRaises(AssertionError): 

126 self.assertFloatsAlmostEqual(0.0, self.larges, atol=1e-2) 

127 with self.assertRaises(AssertionError): 

128 self.assertFloatsAlmostEqual(0.0, self.larges, atol=1e-2, rtol=None) 

129 

130 with self.assertRaises(AssertionError): 

131 self.assertFloatsAlmostEqual(self.larges, self.largesEpsilon, rtol=1e-16) 

132 with self.assertRaises(AssertionError): 

133 self.assertFloatsAlmostEqual(self.larges, self.largesEpsilon, rtol=1e-16, atol=None) 

134 with self.assertRaises(AssertionError): 

135 self.assertFloatsAlmostEqual(self.larges, self.largesEpsilon, rtol=1e-16, relTo=100.0) 

136 with self.assertRaises(AssertionError): 

137 self.assertFloatsAlmostEqual(self.larges, self.largesOneOff, atol=1e-16) 

138 with self.assertRaises(AssertionError): 

139 self.assertFloatsAlmostEqual(self.larges, self.largesOneOff, atol=1e-16, rtol=None) 

140 with self.assertRaises(AssertionError): 

141 self.assertFloatsAlmostEqual(self.ranges, self.rangesEpsilon, rtol=1e-15, atol=1e-4) 

142 

143 if display: 

144 # should see failures on the center row of the 5x5 image, but not 

145 # the very center point. 

146 nonzeroCenter = self.zeros.copy() 

147 nonzeroCenter[2, :] = 1e-5 

148 with self.assertRaises(AssertionError): 

149 self.assertFloatsAlmostEqual(self.zeros, nonzeroCenter, rtol=1e-6, plotOnFailure=True) 

150 

151 with self.assertRaises(AssertionError) as cm: 

152 self.assertFloatsAlmostEqual(10, 0, msg="This is an error message.") 

153 self.assertIn("This is an error message.", str(cm.exception)) 

154 self.assertIn("10 != 0; diff=10/10=1.0 with rtol=", str(cm.exception)) 

155 

156 def test_assertFloatsNotEqual(self): 

157 # zero scalar tests 

158 self.assertFloatsNotEqual(0.0, 1.0) 

159 self.assertFloatsNotEqual(0.0, 1e-8, atol=1e-9) 

160 self.assertFloatsNotEqual(0.0, 1e-8, atol=1e-9, rtol=None) 

161 self.assertFloatsNotEqual(0.0, 1e-8, atol=None, rtol=1e-7, relTo=1e-2) 

162 

163 # zero array vs. scalar tests 

164 self.assertFloatsNotEqual(self.zeros, 1.0) 

165 self.assertFloatsNotEqual(self.zeros, self.epsilon, atol=1e-9) 

166 self.assertFloatsNotEqual(self.zeros, self.epsilon, atol=1e-9, rtol=None) 

167 self.assertFloatsNotEqual(self.zeros, self.epsilon, atol=None, rtol=1e-7, relTo=1e-2) 

168 

169 # zero array vs. array tests 

170 self.assertFloatsNotEqual(self.zeros, self.larges) 

171 self.assertFloatsNotEqual(self.zeros, self.epsilon, atol=1e-9, rtol=None) 

172 self.assertFloatsNotEqual(self.zeros, self.epsilon, atol=None, rtol=1e-5, relTo=1e-5) 

173 self.assertFloatsNotEqual(self.zeros, self.epsilons, atol=1e-9) 

174 self.assertFloatsNotEqual(self.zeros, self.epsilons, atol=1e-9, rtol=None) 

175 self.assertFloatsNotEqual(self.zeros, self.epsilons, atol=None, rtol=1e-7, relTo=1e-2) 

176 

177 # invalid value tests 

178 with self.assertRaises(ValueError): 

179 self.assertFloatsNotEqual(self.zeros, self.zeros2, atol=None, rtol=None) 

180 

181 # non-zero scalar tests 

182 self.assertFloatsNotEqual(self.large, 1.0) 

183 self.assertFloatsNotEqual(self.large, self.large + self.epsilon, atol=1e-9) 

184 self.assertFloatsNotEqual(self.large, self.large + self.epsilon, rtol=1e-11, atol=None) 

185 self.assertFloatsNotEqual(self.large, self.large + self.epsilon, rtol=1e-12, relTo=1.0) 

186 

187 # Non-zero array vs. scalar tests 

188 self.assertFloatsNotEqual(self.larges, self.large + self.epsilon, atol=1e-9) 

189 self.assertFloatsNotEqual(self.larges, self.large + self.epsilon, atol=1e-9, rtol=None) 

190 self.assertFloatsNotEqual(self.larges, self.large + self.epsilon, rtol=1e-11, atol=None) 

191 self.assertFloatsNotEqual(self.larges, self.large + self.epsilon, rtol=1e-12, relTo=1.0) 

192 

193 # Non-zero array vs. array tests 

194 self.assertFloatsNotEqual(self.larges, self.zeros) 

195 self.assertFloatsNotEqual(self.larges, self.largesEpsilon, rtol=1e-12) 

196 self.assertFloatsNotEqual(self.larges, self.largesEpsilon, rtol=1e-12, atol=None) 

197 self.assertFloatsNotEqual(self.larges, self.largesEpsilon, rtol=1e-11, relTo=100.0) 

198 self.assertFloatsNotEqual(self.larges, self.largesOneOff, atol=1e-9) 

199 self.assertFloatsNotEqual(self.larges, self.largesOneOff, atol=1e-9, rtol=None) 

200 self.assertFloatsNotEqual(self.ranges, self.rangesEpsilon) 

201 

202 with self.assertRaises(AssertionError) as cm: 

203 self.assertFloatsNotEqual(10, 10, msg="This is an error message.") 

204 self.assertIn("This is an error message.", str(cm.exception)) 

205 self.assertIn("10 == 10; diff=0/10=0.0 with rtol=", str(cm.exception)) 

206 

207 def test_assertFloatsEqual(self): 

208 self.assertFloatsEqual(0, 0) 

209 self.assertFloatsEqual(0.0, 0.0) 

210 self.assertFloatsEqual(1, 1) 

211 self.assertFloatsEqual(1.0, 1.0) 

212 self.assertFloatsEqual(self.zeros, self.zeros2) 

213 self.assertFloatsEqual(self.zeros, 0) 

214 self.assertFloatsEqual(self.zeros, 0.0) 

215 self.assertFloatsEqual(self.larges, self.large) 

216 with self.assertRaises(AssertionError): 

217 self.assertFloatsEqual(self.larges, 0.0) 

218 with self.assertRaises(AssertionError): 

219 self.assertFloatsEqual(self.larges, self.largesEpsilon) 

220 with self.assertRaises(AssertionError): 

221 self.assertFloatsEqual(self.larges, self.zeros) 

222 with self.assertRaises(AssertionError): 

223 self.assertFloatsEqual(self.larges, self.largesEpsilon) 

224 

225 def test_notfinite(self): 

226 with self.assertRaises(AssertionError): 

227 self.assertFloatsAlmostEqual(np.nan, 0.0) 

228 with self.assertRaises(AssertionError): 

229 self.assertFloatsAlmostEqual(0.0, np.inf) 

230 self.assertFloatsEqual(np.nan, np.nan, ignoreNaNs=True) 

231 self.assertFloatsEqual(np.nan, np.array([np.nan, np.nan]), ignoreNaNs=True) 

232 self.assertFloatsEqual(np.array([np.nan, np.nan]), np.nan, ignoreNaNs=True) 

233 self.assertFloatsEqual(np.array([np.nan, np.nan]), np.array([np.nan, np.nan]), ignoreNaNs=True) 

234 self.assertFloatsEqual(np.array([np.nan, 0.5]), np.array([np.nan, 0.5]), ignoreNaNs=True) 

235 self.assertFloatsEqual(0.5, np.array([0.5, 0.5]), ignoreNaNs=True) 

236 self.assertFloatsEqual(np.array([0.5, 0.5]), 0.5, ignoreNaNs=True) 

237 with self.assertRaises(AssertionError): 

238 self.assertFloatsEqual(np.array([np.nan, 0.5]), np.array([0.5, np.nan]), ignoreNaNs=True) 

239 with self.assertRaises(AssertionError): 

240 self.assertFloatsEqual(0.5, np.array([0.5, np.nan]), ignoreNaNs=True) 

241 with self.assertRaises(AssertionError): 

242 self.assertFloatsEqual(np.nan, np.array([0.5, np.nan]), ignoreNaNs=True) 

243 with self.assertRaises(AssertionError): 

244 self.assertFloatsEqual(np.array([0.5, np.nan]), 0.5, ignoreNaNs=True) 

245 with self.assertRaises(AssertionError): 

246 self.assertFloatsEqual(np.array([0.5, np.nan]), np.nan, ignoreNaNs=True) 

247 with self.assertRaises(AssertionError): 

248 self.assertFloatsEqual(np.array([np.nan, 1.0]), np.array([np.nan, 0.5]), ignoreNaNs=True) 

249 

250 

251class TestMemory(lsst.utils.tests.MemoryTestCase): 

252 """Test for file descriptor leaks. 

253 

254 Verify that setting ignore_regexps doesn't cause anything to fail. 

255 """ 

256 

257 ignore_regexps = [r"\.extension$"] 

258 

259 

260def setup_module(module): 

261 """Initialize the pytest environment.""" 

262 lsst.utils.tests.init() 

263 

264 

265if __name__ == "__main__": 

266 setup_module(sys.modules[__name__]) 

267 unittest.main()