Coverage for tests/test_pipeline.py: 17%

94 statements  

« prev     ^ index     » next       coverage.py v7.5.1, created at 2024-05-07 02:48 -0700

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, 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 pipeline_graph = pipeline.to_graph() 

64 pipeline_graph.sort() 

65 task_nodes = list(pipeline_graph.tasks.values()) 

66 self.assertEqual(task_nodes[0].task_class, AddTask) 

67 self.assertEqual(task_nodes[1].task_class, AddTask) 

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

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

70 self.assertEqual(pipeline.task_labels, {"task0", "task1"}) 

71 

72 def testModifySubset(self): 

73 pipeline = makeSimplePipeline(2) 

74 

75 # Test adding labels. 

76 with self.assertRaises(ValueError): 

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

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

79 with self.assertRaises(ValueError): 

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

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

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

83 

84 # Test removing labels. 

85 with self.assertRaises(ValueError): 

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

87 with self.assertRaises(ValueError): 

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

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

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

91 

92 # Test creating new labeled subsets. 

93 with self.assertRaises(ValueError): 

94 # missing task label 

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

96 with self.assertRaises(ValueError): 

97 # duplicate labeled subset 

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

99 

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

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

102 

103 # verify using the subset property interface 

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

105 

106 # Test removing labeled subsets 

107 with self.assertRaises(ValueError): 

108 pipeline.removeLabeledSubset("missing_subset") 

109 

110 pipeline.removeLabeledSubset("newSubset") 

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

112 

113 def testMergingPipelines(self): 

114 pipeline1 = makeSimplePipeline(2) 

115 pipeline2 = makeSimplePipeline(4) 

116 pipeline2.removeTask("task0") 

117 pipeline2.removeTask("task1") 

118 

119 pipeline1.mergePipeline(pipeline2) 

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

121 

122 def testFindingSubset(self): 

123 pipeline = makeSimplePipeline(2) 

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

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

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

127 

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

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

130 

131 with self.assertRaises(ValueError): 

132 pipeline.findSubsetsWithLabel("missing_label") 

133 

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

135 

136 def testParameters(self): 

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

138 pipeline_str = textwrap.dedent( 

139 """ 

140 description: Test Pipeline 

141 parameters: 

142 testValue: 5 

143 tasks: 

144 add: 

145 class: test_pipeline.AddTask 

146 config: 

147 addend: parameters.testValue 

148 """ 

149 ) 

150 # verify that parameters are used in expanding a pipeline 

151 pipeline = Pipeline.fromString(pipeline_str) 

152 pipeline_graph = pipeline.to_graph() 

153 self.assertEqual(pipeline_graph.tasks["add"].config.addend, 5) 

154 

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

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

157 pipeline_graph = pipeline.to_graph() 

158 self.assertEqual(pipeline_graph.tasks["add"].config.addend, 14) 

159 

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

161 with self.assertRaises(ValueError): 

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

163 with self.assertRaises(ValueError): 

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

165 

166 def testSerialization(self): 

167 pipeline = makeSimplePipeline(2) 

168 dump = str(pipeline) 

169 load = Pipeline.fromString(dump) 

170 self.assertEqual(pipeline, load) 

171 

172 

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

174 """Run file leak tests.""" 

175 

176 

177def setup_module(module): 

178 """Configure pytest.""" 

179 lsst.utils.tests.init() 

180 

181 

182if __name__ == "__main__": 

183 lsst.utils.tests.init() 

184 unittest.main()