Coverage for tests/test_taskFactory.py: 40%

91 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2022-12-06 10:03 +0000

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/>. 

21 

22import shutil 

23import tempfile 

24import unittest 

25 

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 

31 

32# Storage class to use for tests of fakes. 

33_FAKE_STORAGE_CLASS = "StructuredDataDict" 

34 

35 

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 ) 

45 

46 

47class FakeConfig(PipelineTaskConfig, pipelineConnections=FakeConnections): 

48 widget = pexConfig.Field(dtype=float, doc="") 

49 

50 

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 

55 

56 

57class TaskFactoryTestCase(unittest.TestCase): 

58 @classmethod 

59 def setUpClass(cls): 

60 super().setUpClass() 

61 

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) 

69 

70 def setUp(self): 

71 super().setUp() 

72 

73 self.factory = TaskFactory() 

74 self.constructor = mockTaskClass() 

75 

76 @staticmethod 

77 def _alteredConfig(): 

78 config = FakeConfig() 

79 config.widget = 42.0 

80 return config 

81 

82 @staticmethod 

83 def _overrides(): 

84 overrides = ConfigOverrides() 

85 overrides.addValueOverride("widget", -1.0) 

86 return overrides 

87 

88 @staticmethod 

89 def _dummyCatalog(): 

90 return {} 

91 

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 

100 

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) 

106 

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 ) 

121 

122 # Can't test all 14 remaining combinations, but the 6 pairs should be 

123 # enough coverage. 

124 

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") 

134 

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") 

142 

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 ) 

152 

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) 

163 

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 ) 

177 

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)