Coverage for tests/test_apdbMetricTask.py: 37%

83 statements  

« prev     ^ index     » next       coverage.py v7.5.1, created at 2024-05-15 02:06 -0700

1# This file is part of verify. 

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 shutil 

23import tempfile 

24import unittest.mock 

25 

26import astropy.units as u 

27 

28import lsst.utils.tests 

29from lsst.pex.config import Config 

30import lsst.dax.apdb as daxApdb 

31import lsst.daf.butler.tests as butlerTests 

32from lsst.pipe.base import Struct, testUtils 

33 

34from lsst.verify import Measurement 

35from lsst.verify.tasks import ApdbMetricTask 

36from lsst.verify.tasks.testUtils import ApdbMetricTestCase 

37 

38 

39class DummyTask(ApdbMetricTask): 

40 _DefaultName = "NotARealTask" 

41 

42 def makeMeasurement(self, _dbHandle, outputDataId): 

43 if outputDataId: 

44 nChars = len(outputDataId["instrument"]) 

45 return Measurement(self.config.metricName, 

46 nChars * u.dimensionless_unscaled) 

47 else: 

48 return Measurement(self.config.metricName, 

49 0 * u.dimensionless_unscaled) 

50 

51 

52class Gen3ApdbTestSuite(ApdbMetricTestCase): 

53 @classmethod 

54 def makeTask(cls): 

55 config = DummyTask.ConfigClass() 

56 config.doReadMarker = False 

57 config.apdb_config_url = cls.config_file.name 

58 config.connections.package = "verify" 

59 config.connections.metric = "DummyApdb" 

60 return DummyTask(config=config) 

61 

62 @classmethod 

63 def setUpClass(cls): 

64 super().setUpClass() 

65 

66 apdb_config = daxApdb.ApdbSql.init_database(db_url="sqlite://") 

67 cls.config_file = tempfile.NamedTemporaryFile() 

68 cls.addClassCleanup(cls.config_file.close) 

69 apdb_config.save(cls.config_file.name) 

70 

71 cls.CAMERA_ID = "NotACam" 

72 cls.VISIT_ID = 42 

73 cls.CHIP_ID = 5 

74 

75 # makeTestRepo called in setUpClass because it's *very* slow 

76 cls.root = tempfile.mkdtemp() 

77 cls.addClassCleanup(shutil.rmtree, cls.root, ignore_errors=True) 

78 cls.repo = butlerTests.makeTestRepo(cls.root, { 

79 "instrument": [cls.CAMERA_ID], 

80 "visit": [cls.VISIT_ID], 

81 "detector": [cls.CHIP_ID], 

82 }) 

83 

84 # self.task not visible at class level 

85 task = cls.makeTask() 

86 connections = task.config.ConnectionsClass(config=task.config) 

87 

88 butlerTests.addDatasetType( 

89 cls.repo, 

90 connections.measurement.name, 

91 connections.measurement.dimensions, 

92 connections.measurement.storageClass) 

93 butlerTests.addDatasetType( 

94 cls.repo, 

95 connections.dbInfo.name, 

96 connections.dbInfo.dimensions, 

97 connections.dbInfo.storageClass) 

98 

99 def setUp(self): 

100 super().setUp() 

101 

102 self.connections = self.task.config.ConnectionsClass( 

103 config=self.task.config) 

104 

105 def _prepareQuantum(self, task): 

106 globalId = { 

107 "instrument": self.CAMERA_ID, 

108 } 

109 detectorId = { 

110 "instrument": self.CAMERA_ID, 

111 "visit": self.VISIT_ID, 

112 "detector": self.CHIP_ID, 

113 } 

114 

115 butler = butlerTests.makeTestCollection(self.repo, uniqueId=self.id()) 

116 info = Config() 

117 butler.put(info, "apdb_marker", detectorId) 

118 

119 quantum = testUtils.makeQuantum( 

120 task, butler, globalId, 

121 {"dbInfo": [detectorId], "measurement": globalId}) 

122 

123 return (butler, quantum, info) 

124 

125 def testRunQuantum(self): 

126 butler, quantum, input = self._prepareQuantum(self.task) 

127 

128 run = testUtils.runTestQuantum(self.task, butler, quantum) 

129 

130 # Did output data ID get passed to DummyTask.run? 

131 expectedId = lsst.daf.butler.DataCoordinate.standardize( 

132 {"instrument": self.CAMERA_ID}, 

133 universe=butler.dimensions) 

134 run.assert_called_once_with( 

135 dbInfo=[input], 

136 outputDataId=expectedId) 

137 

138 def testRunQuantumNone(self): 

139 class NoneTask(DummyTask): 

140 def run(self, *args, **kwargs): 

141 return Struct(measurement=None) 

142 

143 config = NoneTask.ConfigClass() 

144 config.doReadMarker = False 

145 config.apdb_config_url = self.config_file.name 

146 config.connections.package = "verify" 

147 config.connections.metric = "DummyApdb" 

148 task = NoneTask(config=config) 

149 butler, quantum, input = self._prepareQuantum(task) 

150 

151 with unittest.mock.patch.object( 

152 lsst.pipe.base.QuantumContext, "put") as put: 

153 testUtils.runTestQuantum(task, butler, quantum, mockRun=False) 

154 # Should not attempt to write nonexistent data 

155 put.assert_not_called() 

156 

157 

158# Hack around unittest's hacky test setup system 

159del ApdbMetricTestCase 

160 

161 

162class MemoryTester(lsst.utils.tests.MemoryTestCase): 

163 pass 

164 

165 

166def setup_module(module): 

167 lsst.utils.tests.init() 

168 

169 

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

171 lsst.utils.tests.init() 

172 unittest.main()