Coverage for tests/test_taskFactory.py: 43%
91 statements
« prev ^ index » next coverage.py v6.4.1, created at 2022-06-14 02:53 -0700
« prev ^ index » next coverage.py v6.4.1, created at 2022-06-14 02:53 -0700
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.daf.butler.tests as butlerTests
27import lsst.pex.config as pexConfig
28from lsst.ctrl.mpexec import TaskFactory
29from lsst.pipe.base import PipelineTaskConfig, PipelineTaskConnections, connectionTypes
30from lsst.pipe.base.configOverrides import ConfigOverrides
32# Storage class to use for tests of fakes.
33_FAKE_STORAGE_CLASS = "StructuredDataDict"
36class FakeConnections(PipelineTaskConnections, dimensions=set()):
37 initInput = connectionTypes.InitInput(name="fakeInitInput", doc="", storageClass=_FAKE_STORAGE_CLASS)
38 initOutput = connectionTypes.InitOutput(name="fakeInitOutput", doc="", storageClass=_FAKE_STORAGE_CLASS)
39 input = connectionTypes.Input(
40 name="fakeInput", doc="", storageClass=_FAKE_STORAGE_CLASS, dimensions=set()
41 )
42 output = connectionTypes.Output(
43 name="fakeOutput", doc="", storageClass=_FAKE_STORAGE_CLASS, dimensions=set()
44 )
47class FakeConfig(PipelineTaskConfig, pipelineConnections=FakeConnections):
48 widget = pexConfig.Field(dtype=float, doc="")
51def mockTaskClass():
52 """A class placeholder that records calls to __call__."""
53 mock = unittest.mock.Mock(__name__="_TaskMock", _DefaultName="FakeTask", ConfigClass=FakeConfig)
54 return mock
57class TaskFactoryTestCase(unittest.TestCase):
58 @classmethod
59 def setUpClass(cls):
60 super().setUpClass()
62 tmp = tempfile.mkdtemp()
63 cls.addClassCleanup(shutil.rmtree, tmp, ignore_errors=True)
64 cls.repo = butlerTests.makeTestRepo(tmp)
65 butlerTests.addDatasetType(cls.repo, "fakeInitInput", set(), _FAKE_STORAGE_CLASS)
66 butlerTests.addDatasetType(cls.repo, "fakeInitOutput", set(), _FAKE_STORAGE_CLASS)
67 butlerTests.addDatasetType(cls.repo, "fakeInput", set(), _FAKE_STORAGE_CLASS)
68 butlerTests.addDatasetType(cls.repo, "fakeOutput", set(), _FAKE_STORAGE_CLASS)
70 def setUp(self):
71 super().setUp()
73 self.factory = TaskFactory()
74 self.constructor = mockTaskClass()
76 @staticmethod
77 def _alteredConfig():
78 config = FakeConfig()
79 config.widget = 42.0
80 return config
82 @staticmethod
83 def _overrides():
84 overrides = ConfigOverrides()
85 overrides.addValueOverride("widget", -1.0)
86 return overrides
88 @staticmethod
89 def _dummyCatalog():
90 return {}
92 def _tempButler(self):
93 butler = butlerTests.makeTestCollection(self.repo, uniqueId=self.id())
94 catalog = self._dummyCatalog()
95 butler.put(catalog, "fakeInitInput")
96 butler.put(catalog, "fakeInitOutput")
97 butler.put(catalog, "fakeInput")
98 butler.put(catalog, "fakeOutput")
99 return butler
101 def testOnlyMandatoryArg(self):
102 self.factory.makeTask(
103 taskClass=self.constructor, label=None, config=None, overrides=None, butler=None
104 )
105 self.constructor.assert_called_with(config=FakeConfig(), initInputs=None, name=None)
107 def testAllArgs(self):
108 butler = self._tempButler()
109 self.factory.makeTask(
110 taskClass=self.constructor,
111 label="no-name",
112 config=self._alteredConfig(),
113 overrides=self._overrides(),
114 butler=butler,
115 )
116 catalog = butler.get("fakeInitInput") # Copies of _dummyCatalog are identical but not equal
117 # When config passed in, overrides ignored
118 self.constructor.assert_called_with(
119 config=self._alteredConfig(), initInputs={"initInput": catalog}, name="no-name"
120 )
122 # Can't test all 14 remaining combinations, but the 6 pairs should be
123 # enough coverage.
125 def testNameConfig(self):
126 self.factory.makeTask(
127 taskClass=self.constructor,
128 label="no-name",
129 config=self._alteredConfig(),
130 overrides=None,
131 butler=None,
132 )
133 self.constructor.assert_called_with(config=self._alteredConfig(), initInputs=None, name="no-name")
135 def testNameOverrides(self):
136 self.factory.makeTask(
137 taskClass=self.constructor, label="no-name", config=None, overrides=self._overrides(), butler=None
138 )
139 config = FakeConfig()
140 self._overrides().applyTo(config)
141 self.constructor.assert_called_with(config=config, initInputs=None, name="no-name")
143 def testNameButler(self):
144 butler = self._tempButler()
145 self.factory.makeTask(
146 taskClass=self.constructor, label="no-name", config=None, overrides=None, butler=butler
147 )
148 catalog = butler.get("fakeInitInput") # Copies of _dummyCatalog are identical but not equal
149 self.constructor.assert_called_with(
150 config=FakeConfig(), initInputs={"initInput": catalog}, name="no-name"
151 )
153 def testConfigOverrides(self):
154 self.factory.makeTask(
155 taskClass=self.constructor,
156 label=None,
157 config=self._alteredConfig(),
158 overrides=self._overrides(),
159 butler=None,
160 )
161 # When config passed in, overrides ignored
162 self.constructor.assert_called_with(config=self._alteredConfig(), initInputs=None, name=None)
164 def testConfigButler(self):
165 butler = self._tempButler()
166 self.factory.makeTask(
167 taskClass=self.constructor,
168 label=None,
169 config=self._alteredConfig(),
170 overrides=None,
171 butler=butler,
172 )
173 catalog = butler.get("fakeInitInput") # Copies of _dummyCatalog are identical but not equal
174 self.constructor.assert_called_with(
175 config=self._alteredConfig(), initInputs={"initInput": catalog}, name=None
176 )
178 def testOverridesButler(self):
179 butler = self._tempButler()
180 self.factory.makeTask(
181 taskClass=self.constructor, label=None, config=None, overrides=self._overrides(), butler=butler
182 )
183 config = FakeConfig()
184 self._overrides().applyTo(config)
185 catalog = butler.get("fakeInitInput") # Copies of _dummyCatalog are identical but not equal
186 self.constructor.assert_called_with(config=config, initInputs={"initInput": catalog}, name=None)