Hide keyboard shortcuts

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

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.pipe.base import PipelineTaskConfig, PipelineTaskConnections 

30from lsst.pipe.base.configOverrides import ConfigOverrides 

31from lsst.pipe.base import connectionTypes 

32 

33from lsst.ctrl.mpexec import TaskFactory 

34 

35 

36class FakeConnections(PipelineTaskConnections, dimensions=set()): 

37 initInput = connectionTypes.InitInput(name="fakeInitInput", doc="", storageClass="SourceCatalog") 

38 initOutput = connectionTypes.InitOutput(name="fakeInitOutput", doc="", storageClass="SourceCatalog") 

39 input = connectionTypes.Input(name="fakeInput", doc="", storageClass="SourceCatalog", dimensions=set()) 

40 output = connectionTypes.Output(name="fakeOutput", doc="", storageClass="SourceCatalog", dimensions=set()) 

41 

42 

43class FakeConfig(PipelineTaskConfig, pipelineConnections=FakeConnections): 

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

45 

46 

47def mockTaskClass(): 

48 """A class placeholder that records calls to __call__. 

49 """ 

50 mock = unittest.mock.Mock(__name__="_TaskMock", _DefaultName="FakeTask", ConfigClass=FakeConfig) 

51 return mock 

52 

53 

54class TaskFactoryTestCase(unittest.TestCase): 

55 

56 @classmethod 

57 def setUpClass(cls): 

58 super().setUpClass() 

59 

60 tmp = tempfile.mkdtemp() 

61 cls.addClassCleanup(shutil.rmtree, tmp, ignore_errors=True) 

62 cls.repo = butlerTests.makeTestRepo(tmp) 

63 butlerTests.addDatasetType(cls.repo, "fakeInitInput", set(), "SourceCatalog") 

64 butlerTests.addDatasetType(cls.repo, "fakeInitOutput", set(), "SourceCatalog") 

65 butlerTests.addDatasetType(cls.repo, "fakeInput", set(), "SourceCatalog") 

66 butlerTests.addDatasetType(cls.repo, "fakeOutput", set(), "SourceCatalog") 

67 

68 def setUp(self): 

69 super().setUp() 

70 

71 self.factory = TaskFactory() 

72 self.constructor = mockTaskClass() 

73 

74 @staticmethod 

75 def _alteredConfig(): 

76 config = FakeConfig() 

77 config.widget = 42.0 

78 return config 

79 

80 @staticmethod 

81 def _overrides(): 

82 overrides = ConfigOverrides() 

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

84 return overrides 

85 

86 @staticmethod 

87 def _dummyCatalog(): 

88 schema = afwTable.SourceTable.makeMinimalSchema() 

89 return afwTable.SourceCatalog(schema) 

90 

91 def _tempButler(self): 

92 butler = butlerTests.makeTestCollection(self.repo, uniqueId=self.id()) 

93 catalog = self._dummyCatalog() 

94 butler.put(catalog, "fakeInitInput") 

95 butler.put(catalog, "fakeInitOutput") 

96 butler.put(catalog, "fakeInput") 

97 butler.put(catalog, "fakeOutput") 

98 return butler 

99 

100 def testOnlyMandatoryArg(self): 

101 self.factory.makeTask(taskClass=self.constructor, label=None, config=None, 

102 overrides=None, butler=None) 

103 self.constructor.assert_called_with(config=FakeConfig(), initInputs=None, name=None) 

104 

105 def testAllArgs(self): 

106 butler = self._tempButler() 

107 self.factory.makeTask(taskClass=self.constructor, label="no-name", config=self._alteredConfig(), 

108 overrides=self._overrides(), butler=butler) 

109 catalog = butler.get("fakeInitInput") # Copies of _dummyCatalog are identical but not equal 

110 # When config passed in, overrides ignored 

111 self.constructor.assert_called_with(config=self._alteredConfig(), 

112 initInputs={'initInput': catalog}, 

113 name="no-name") 

114 

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

116 

117 def testNameConfig(self): 

118 self.factory.makeTask(taskClass=self.constructor, label="no-name", config=self._alteredConfig(), 

119 overrides=None, butler=None) 

120 self.constructor.assert_called_with(config=self._alteredConfig(), initInputs=None, name="no-name") 

121 

122 def testNameOverrides(self): 

123 self.factory.makeTask(taskClass=self.constructor, label="no-name", config=None, 

124 overrides=self._overrides(), butler=None) 

125 config = FakeConfig() 

126 self._overrides().applyTo(config) 

127 self.constructor.assert_called_with(config=config, initInputs=None, name="no-name") 

128 

129 def testNameButler(self): 

130 butler = self._tempButler() 

131 self.factory.makeTask(taskClass=self.constructor, label="no-name", config=None, 

132 overrides=None, butler=butler) 

133 catalog = butler.get("fakeInitInput") # Copies of _dummyCatalog are identical but not equal 

134 self.constructor.assert_called_with(config=FakeConfig(), 

135 initInputs={'initInput': catalog}, 

136 name="no-name") 

137 

138 def testConfigOverrides(self): 

139 self.factory.makeTask(taskClass=self.constructor, label=None, config=self._alteredConfig(), 

140 overrides=self._overrides(), butler=None) 

141 # When config passed in, overrides ignored 

142 self.constructor.assert_called_with(config=self._alteredConfig(), initInputs=None, name=None) 

143 

144 def testConfigButler(self): 

145 butler = self._tempButler() 

146 self.factory.makeTask(taskClass=self.constructor, label=None, config=self._alteredConfig(), 

147 overrides=None, butler=butler) 

148 catalog = butler.get("fakeInitInput") # Copies of _dummyCatalog are identical but not equal 

149 self.constructor.assert_called_with(config=self._alteredConfig(), 

150 initInputs={'initInput': catalog}, 

151 name=None) 

152 

153 def testOverridesButler(self): 

154 butler = self._tempButler() 

155 self.factory.makeTask(taskClass=self.constructor, label=None, config=None, 

156 overrides=self._overrides(), butler=butler) 

157 config = FakeConfig() 

158 self._overrides().applyTo(config) 

159 catalog = butler.get("fakeInitInput") # Copies of _dummyCatalog are identical but not equal 

160 self.constructor.assert_called_with(config=config, 

161 initInputs={'initInput': catalog}, 

162 name=None)