Coverage for tests/test_pipeline.py: 17%

98 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-04-05 10:02 +0000

1# This file is part of pipe_base. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (http://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 software is dual licensed under the GNU General Public License and also 

10# under a 3-clause BSD license. Recipients may choose which of these licenses 

11# to use; please see the files gpl-3.0.txt and/or bsd_license.txt, 

12# respectively. If you choose the GPL option then the following text applies 

13# (but note that there is still no warranty even if you opt for BSD instead): 

14# 

15# This program is free software: you can redistribute it and/or modify 

16# it under the terms of the GNU General Public License as published by 

17# the Free Software Foundation, either version 3 of the License, or 

18# (at your option) any later version. 

19# 

20# This program is distributed in the hope that it will be useful, 

21# but WITHOUT ANY WARRANTY; without even the implied warranty of 

22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

23# GNU General Public License for more details. 

24# 

25# You should have received a copy of the GNU General Public License 

26# along with this program. If not, see <http://www.gnu.org/licenses/>. 

27 

28"""Simple unit test for Pipeline. 

29""" 

30 

31import pickle 

32import textwrap 

33import unittest 

34 

35import lsst.utils.tests 

36from lsst.pipe.base import Pipeline, PipelineDatasetTypes, TaskDef 

37from lsst.pipe.base.pipelineIR import LabeledSubset 

38from lsst.pipe.base.tests.simpleQGraph import AddTask, makeSimplePipeline 

39 

40 

41class PipelineTestCase(unittest.TestCase): 

42 """A test case for TaskDef and Pipeline.""" 

43 

44 def testTaskDef(self): 

45 """Tests for TaskDef structure.""" 

46 task1 = TaskDef(taskClass=AddTask, config=AddTask.ConfigClass()) 

47 self.assertIn("Add", task1.taskName) 

48 self.assertIsInstance(task1.config, AddTask.ConfigClass) 

49 self.assertIsNotNone(task1.taskClass) 

50 self.assertEqual(task1.label, "add_task") 

51 task1a = pickle.loads(pickle.dumps(task1)) 

52 self.assertEqual(task1, task1a) 

53 

54 def testEmpty(self): 

55 """Creating empty pipeline.""" 

56 pipeline = Pipeline("test") 

57 self.assertEqual(len(pipeline), 0) 

58 

59 def testInitial(self): 

60 """Testing constructor with initial data.""" 

61 pipeline = makeSimplePipeline(2) 

62 self.assertEqual(len(pipeline), 2) 

63 expandedPipeline = list(pipeline.toExpandedPipeline()) 

64 self.assertEqual(expandedPipeline[0].taskName, "lsst.pipe.base.tests.simpleQGraph.AddTask") 

65 self.assertEqual(expandedPipeline[1].taskName, "lsst.pipe.base.tests.simpleQGraph.AddTask") 

66 self.assertEqual(expandedPipeline[0].taskClass, AddTask) 

67 self.assertEqual(expandedPipeline[1].taskClass, AddTask) 

68 self.assertEqual(expandedPipeline[0].label, "task0") 

69 self.assertEqual(expandedPipeline[1].label, "task1") 

70 

71 def testModifySubset(self): 

72 pipeline = makeSimplePipeline(2) 

73 

74 # Test adding labels. 

75 with self.assertRaises(ValueError): 

76 pipeline.addLabelToSubset("test", "new_label") 

77 pipeline._pipelineIR.labeled_subsets["test"] = LabeledSubset("test", set(), None) 

78 with self.assertRaises(ValueError): 

79 pipeline.addLabelToSubset("test", "missing_label") 

80 pipeline.addLabelToSubset("test", "task0") 

81 self.assertEqual(pipeline._pipelineIR.labeled_subsets["test"].subset, {"task0"}) 

82 

83 # Test removing labels. 

84 with self.assertRaises(ValueError): 

85 pipeline.addLabelToSubset("missing_subset", "task0") 

86 with self.assertRaises(ValueError): 

87 pipeline.addLabelToSubset("test", "missing_label") 

88 pipeline.removeLabelFromSubset("test", "task0") 

89 self.assertEqual(pipeline._pipelineIR.labeled_subsets["test"].subset, set()) 

90 

91 # Test creating new labeled subsets. 

92 with self.assertRaises(ValueError): 

93 # missing task label 

94 pipeline.addLabeledSubset("newSubset", "test description", {"missing_task_label"}) 

95 with self.assertRaises(ValueError): 

96 # duplicate labeled subset 

97 pipeline.addLabeledSubset("test", "test description", {"missing_task_label"}) 

98 

99 taskLabels = {"task0", "task1"} 

100 pipeline.addLabeledSubset("newSubset", "test description", taskLabels) 

101 

102 # verify using the subset property interface 

103 self.assertEqual(pipeline.subsets["newSubset"], taskLabels) 

104 

105 # Test removing labeled subsets 

106 with self.assertRaises(ValueError): 

107 pipeline.removeLabeledSubset("missing_subset") 

108 

109 pipeline.removeLabeledSubset("newSubset") 

110 self.assertNotIn("newSubset", pipeline.subsets.keys()) 

111 

112 def testMergingPipelines(self): 

113 pipeline1 = makeSimplePipeline(2) 

114 pipeline2 = makeSimplePipeline(4) 

115 pipeline2.removeTask("task0") 

116 pipeline2.removeTask("task1") 

117 

118 pipeline1.mergePipeline(pipeline2) 

119 self.assertEqual(pipeline1._pipelineIR.tasks.keys(), {"task0", "task1", "task2", "task3"}) 

120 

121 def testFindingSubset(self): 

122 pipeline = makeSimplePipeline(2) 

123 pipeline._pipelineIR.labeled_subsets["test1"] = LabeledSubset("test1", set(), None) 

124 pipeline._pipelineIR.labeled_subsets["test2"] = LabeledSubset("test2", set(), None) 

125 pipeline._pipelineIR.labeled_subsets["test3"] = LabeledSubset("test3", set(), None) 

126 

127 pipeline.addLabelToSubset("test1", "task0") 

128 pipeline.addLabelToSubset("test3", "task0") 

129 

130 with self.assertRaises(ValueError): 

131 pipeline.findSubsetsWithLabel("missing_label") 

132 

133 self.assertEqual(pipeline.findSubsetsWithLabel("task0"), {"test1", "test3"}) 

134 

135 def testParameters(self): 

136 """Test that parameters can be set and used to format.""" 

137 pipeline_str = textwrap.dedent( 

138 """ 

139 description: Test Pipeline 

140 parameters: 

141 testValue: 5 

142 tasks: 

143 add: 

144 class: test_pipeline.AddTask 

145 config: 

146 addend: parameters.testValue 

147 """ 

148 ) 

149 # verify that parameters are used in expanding a pipeline 

150 pipeline = Pipeline.fromString(pipeline_str) 

151 expandedPipeline = list(pipeline.toExpandedPipeline()) 

152 self.assertEqual(expandedPipeline[0].config.addend, 5) 

153 

154 # verify that a parameter can be overridden on the "command line" 

155 pipeline.addConfigOverride("parameters", "testValue", 14) 

156 expandedPipeline = list(pipeline.toExpandedPipeline()) 

157 self.assertEqual(expandedPipeline[0].config.addend, 14) 

158 

159 # verify that parameters does not support files or python overrides 

160 with self.assertRaises(ValueError): 

161 pipeline.addConfigFile("parameters", "fakeFile") 

162 with self.assertRaises(ValueError): 

163 pipeline.addConfigPython("parameters", "fakePythonString") 

164 

165 def testSerialization(self): 

166 pipeline = makeSimplePipeline(2) 

167 dump = str(pipeline) 

168 load = Pipeline.fromString(dump) 

169 self.assertEqual(pipeline, load) 

170 

171 def test_initOutputNames(self): 

172 """Test for PipelineDatasetTypes.initOutputNames method.""" 

173 pipeline = makeSimplePipeline(3) 

174 dsType = set(PipelineDatasetTypes.initOutputNames(pipeline)) 

175 expected = { 

176 "packages", 

177 "add_init_output1", 

178 "add_init_output2", 

179 "add_init_output3", 

180 "task0_config", 

181 "task1_config", 

182 "task2_config", 

183 } 

184 self.assertEqual(dsType, expected) 

185 

186 

187class MyMemoryTestCase(lsst.utils.tests.MemoryTestCase): 

188 """Run file leak tests.""" 

189 

190 

191def setup_module(module): 

192 """Configure pytest.""" 

193 lsst.utils.tests.init() 

194 

195 

196if __name__ == "__main__": 

197 lsst.utils.tests.init() 

198 unittest.main()