Coverage for tests/test_taskFactory.py: 43%
Shortcuts on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# This file is part of ctrl_mpexec.
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
26import lsst.afw.table as afwTable
27import lsst.daf.butler.tests as butlerTests
28import lsst.pex.config as pexConfig
29from lsst.ctrl.mpexec import TaskFactory
30from lsst.pipe.base import PipelineTaskConfig, PipelineTaskConnections, connectionTypes
31from lsst.pipe.base.configOverrides import ConfigOverrides
34class FakeConnections(PipelineTaskConnections, dimensions=set()):
35 initInput = connectionTypes.InitInput(name="fakeInitInput", doc="", storageClass="SourceCatalog")
36 initOutput = connectionTypes.InitOutput(name="fakeInitOutput", doc="", storageClass="SourceCatalog")
37 input = connectionTypes.Input(name="fakeInput", doc="", storageClass="SourceCatalog", dimensions=set())
38 output = connectionTypes.Output(name="fakeOutput", doc="", storageClass="SourceCatalog", dimensions=set())
41class FakeConfig(PipelineTaskConfig, pipelineConnections=FakeConnections):
42 widget = pexConfig.Field(dtype=float, doc="")
45def mockTaskClass():
46 """A class placeholder that records calls to __call__."""
47 mock = unittest.mock.Mock(__name__="_TaskMock", _DefaultName="FakeTask", ConfigClass=FakeConfig)
48 return mock
51class TaskFactoryTestCase(unittest.TestCase):
52 @classmethod
53 def setUpClass(cls):
54 super().setUpClass()
56 tmp = tempfile.mkdtemp()
57 cls.addClassCleanup(shutil.rmtree, tmp, ignore_errors=True)
58 cls.repo = butlerTests.makeTestRepo(tmp)
59 butlerTests.addDatasetType(cls.repo, "fakeInitInput", set(), "SourceCatalog")
60 butlerTests.addDatasetType(cls.repo, "fakeInitOutput", set(), "SourceCatalog")
61 butlerTests.addDatasetType(cls.repo, "fakeInput", set(), "SourceCatalog")
62 butlerTests.addDatasetType(cls.repo, "fakeOutput", set(), "SourceCatalog")
64 def setUp(self):
65 super().setUp()
67 self.factory = TaskFactory()
68 self.constructor = mockTaskClass()
70 @staticmethod
71 def _alteredConfig():
72 config = FakeConfig()
73 config.widget = 42.0
74 return config
76 @staticmethod
77 def _overrides():
78 overrides = ConfigOverrides()
79 overrides.addValueOverride("widget", -1.0)
80 return overrides
82 @staticmethod
83 def _dummyCatalog():
84 schema = afwTable.SourceTable.makeMinimalSchema()
85 return afwTable.SourceCatalog(schema)
87 def _tempButler(self):
88 butler = butlerTests.makeTestCollection(self.repo, uniqueId=self.id())
89 catalog = self._dummyCatalog()
90 butler.put(catalog, "fakeInitInput")
91 butler.put(catalog, "fakeInitOutput")
92 butler.put(catalog, "fakeInput")
93 butler.put(catalog, "fakeOutput")
94 return butler
96 def testOnlyMandatoryArg(self):
97 self.factory.makeTask(
98 taskClass=self.constructor, label=None, config=None, overrides=None, butler=None
99 )
100 self.constructor.assert_called_with(config=FakeConfig(), initInputs=None, name=None)
102 def testAllArgs(self):
103 butler = self._tempButler()
104 self.factory.makeTask(
105 taskClass=self.constructor,
106 label="no-name",
107 config=self._alteredConfig(),
108 overrides=self._overrides(),
109 butler=butler,
110 )
111 catalog = butler.get("fakeInitInput") # Copies of _dummyCatalog are identical but not equal
112 # When config passed in, overrides ignored
113 self.constructor.assert_called_with(
114 config=self._alteredConfig(), initInputs={"initInput": catalog}, name="no-name"
115 )
117 # Can't test all 14 remaining combinations, but the 6 pairs should be
118 # enough coverage.
120 def testNameConfig(self):
121 self.factory.makeTask(
122 taskClass=self.constructor,
123 label="no-name",
124 config=self._alteredConfig(),
125 overrides=None,
126 butler=None,
127 )
128 self.constructor.assert_called_with(config=self._alteredConfig(), initInputs=None, name="no-name")
130 def testNameOverrides(self):
131 self.factory.makeTask(
132 taskClass=self.constructor, label="no-name", config=None, overrides=self._overrides(), butler=None
133 )
134 config = FakeConfig()
135 self._overrides().applyTo(config)
136 self.constructor.assert_called_with(config=config, initInputs=None, name="no-name")
138 def testNameButler(self):
139 butler = self._tempButler()
140 self.factory.makeTask(
141 taskClass=self.constructor, label="no-name", config=None, overrides=None, butler=butler
142 )
143 catalog = butler.get("fakeInitInput") # Copies of _dummyCatalog are identical but not equal
144 self.constructor.assert_called_with(
145 config=FakeConfig(), initInputs={"initInput": catalog}, name="no-name"
146 )
148 def testConfigOverrides(self):
149 self.factory.makeTask(
150 taskClass=self.constructor,
151 label=None,
152 config=self._alteredConfig(),
153 overrides=self._overrides(),
154 butler=None,
155 )
156 # When config passed in, overrides ignored
157 self.constructor.assert_called_with(config=self._alteredConfig(), initInputs=None, name=None)
159 def testConfigButler(self):
160 butler = self._tempButler()
161 self.factory.makeTask(
162 taskClass=self.constructor,
163 label=None,
164 config=self._alteredConfig(),
165 overrides=None,
166 butler=butler,
167 )
168 catalog = butler.get("fakeInitInput") # Copies of _dummyCatalog are identical but not equal
169 self.constructor.assert_called_with(
170 config=self._alteredConfig(), initInputs={"initInput": catalog}, name=None
171 )
173 def testOverridesButler(self):
174 butler = self._tempButler()
175 self.factory.makeTask(
176 taskClass=self.constructor, label=None, config=None, overrides=self._overrides(), butler=butler
177 )
178 config = FakeConfig()
179 self._overrides().applyTo(config)
180 catalog = butler.get("fakeInitInput") # Copies of _dummyCatalog are identical but not equal
181 self.constructor.assert_called_with(config=config, initInputs={"initInput": catalog}, name=None)