Coverage for tests/test_apdbMetricTask.py: 39%
82 statements
« prev ^ index » next coverage.py v7.5.0, created at 2024-04-25 10:33 -0700
« prev ^ index » next coverage.py v7.5.0, created at 2024-04-25 10:33 -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/>.
22import shutil
23import tempfile
24import unittest.mock
26import astropy.units as u
28import lsst.utils.tests
29from lsst.pex.config import Config
30import lsst.daf.butler.tests as butlerTests
31from lsst.pipe.base import Task, Struct, testUtils
33from lsst.verify import Measurement
34from lsst.verify.tasks import ApdbMetricTask
35from lsst.verify.tasks.testUtils import ApdbMetricTestCase
38class DummyTask(ApdbMetricTask):
39 _DefaultName = "NotARealTask"
41 def makeMeasurement(self, _dbHandle, outputDataId):
42 if outputDataId:
43 nChars = len(outputDataId["instrument"])
44 return Measurement(self.config.metricName,
45 nChars * u.dimensionless_unscaled)
46 else:
47 return Measurement(self.config.metricName,
48 0 * u.dimensionless_unscaled)
51class Gen3ApdbTestSuite(ApdbMetricTestCase):
52 @classmethod
53 def makeTask(cls):
54 class MockDbLoader(Task):
55 ConfigClass = Config
57 def run(self, _):
58 return Struct(apdb=unittest.mock.Mock())
60 config = DummyTask.ConfigClass()
61 config.dbLoader.retarget(MockDbLoader)
62 config.connections.package = "verify"
63 config.connections.metric = "DummyApdb"
64 return DummyTask(config=config)
66 @classmethod
67 def setUpClass(cls):
68 super().setUpClass()
70 cls.CAMERA_ID = "NotACam"
71 cls.VISIT_ID = 42
72 cls.CHIP_ID = 5
74 # makeTestRepo called in setUpClass because it's *very* slow
75 cls.root = tempfile.mkdtemp()
76 cls.repo = butlerTests.makeTestRepo(cls.root, {
77 "instrument": [cls.CAMERA_ID],
78 "visit": [cls.VISIT_ID],
79 "detector": [cls.CHIP_ID],
80 })
82 # self.task not visible at class level
83 task = cls.makeTask()
84 connections = task.config.ConnectionsClass(config=task.config)
86 butlerTests.addDatasetType(
87 cls.repo,
88 connections.measurement.name,
89 connections.measurement.dimensions,
90 connections.measurement.storageClass)
91 butlerTests.addDatasetType(
92 cls.repo,
93 connections.dbInfo.name,
94 connections.dbInfo.dimensions,
95 connections.dbInfo.storageClass)
97 @classmethod
98 def tearDownClass(cls):
99 shutil.rmtree(cls.root, ignore_errors=True)
100 super().tearDownClass()
102 def setUp(self):
103 super().setUp()
105 self.connections = self.task.config.ConnectionsClass(
106 config=self.task.config)
108 def _prepareQuantum(self, task):
109 globalId = {
110 "instrument": self.CAMERA_ID,
111 }
112 detectorId = {
113 "instrument": self.CAMERA_ID,
114 "visit": self.VISIT_ID,
115 "detector": self.CHIP_ID,
116 }
118 butler = butlerTests.makeTestCollection(self.repo, uniqueId=self.id())
119 # task.config not persistable if it refers to a local class
120 # We don't actually use the persisted config, so just make a new one
121 info = task.ConfigClass()
122 butler.put(info, "apdb_marker", detectorId)
124 quantum = testUtils.makeQuantum(
125 task, butler, globalId,
126 {"dbInfo": [detectorId], "measurement": globalId})
128 return (butler, quantum, info)
130 def testRunQuantum(self):
131 butler, quantum, input = self._prepareQuantum(self.task)
133 run = testUtils.runTestQuantum(self.task, butler, quantum)
135 # Did output data ID get passed to DummyTask.run?
136 expectedId = lsst.daf.butler.DataCoordinate.standardize(
137 {"instrument": self.CAMERA_ID},
138 universe=butler.dimensions)
139 run.assert_called_once_with(
140 dbInfo=[input],
141 outputDataId=expectedId)
143 def testRunQuantumNone(self):
144 class NoneTask(DummyTask):
145 def run(self, *args, **kwargs):
146 return Struct(measurement=None)
148 config = NoneTask.ConfigClass()
149 config.connections.package = "verify"
150 config.connections.metric = "DummyApdb"
151 task = NoneTask(config=config)
152 butler, quantum, input = self._prepareQuantum(task)
154 with unittest.mock.patch.object(
155 lsst.pipe.base.QuantumContext, "put") as put:
156 testUtils.runTestQuantum(task, butler, quantum, mockRun=False)
157 # Should not attempt to write nonexistent data
158 put.assert_not_called()
161# Hack around unittest's hacky test setup system
162del ApdbMetricTestCase
165class MemoryTester(lsst.utils.tests.MemoryTestCase):
166 pass
169def setup_module(module):
170 lsst.utils.tests.init()
173if __name__ == "__main__": 173 ↛ 174line 173 didn't jump to line 174, because the condition on line 173 was never true
174 lsst.utils.tests.init()
175 unittest.main()