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

92 statements  

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

32 

33 

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

39 

40 

41class FakeConfig(PipelineTaskConfig, pipelineConnections=FakeConnections): 

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

43 

44 

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 

49 

50 

51class TaskFactoryTestCase(unittest.TestCase): 

52 @classmethod 

53 def setUpClass(cls): 

54 super().setUpClass() 

55 

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

63 

64 def setUp(self): 

65 super().setUp() 

66 

67 self.factory = TaskFactory() 

68 self.constructor = mockTaskClass() 

69 

70 @staticmethod 

71 def _alteredConfig(): 

72 config = FakeConfig() 

73 config.widget = 42.0 

74 return config 

75 

76 @staticmethod 

77 def _overrides(): 

78 overrides = ConfigOverrides() 

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

80 return overrides 

81 

82 @staticmethod 

83 def _dummyCatalog(): 

84 schema = afwTable.SourceTable.makeMinimalSchema() 

85 return afwTable.SourceCatalog(schema) 

86 

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 

95 

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) 

101 

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 ) 

116 

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

118 # enough coverage. 

119 

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

129 

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

137 

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 ) 

147 

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) 

158 

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 ) 

172 

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)