Coverage for tests/test_pipeline.py: 20%

87 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-11-30 12:09 +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 def testMergingPipelines(self): 

92 pipeline1 = makeSimplePipeline(2) 

93 pipeline2 = makeSimplePipeline(4) 

94 pipeline2.removeTask("task0") 

95 pipeline2.removeTask("task1") 

96 

97 pipeline1.mergePipeline(pipeline2) 

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

99 

100 def testFindingSubset(self): 

101 pipeline = makeSimplePipeline(2) 

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

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

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

105 

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

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

108 

109 with self.assertRaises(ValueError): 

110 pipeline.findSubsetsWithLabel("missing_label") 

111 

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

113 

114 def testParameters(self): 

115 """Test that parameters can be set and used to format""" 

116 pipeline_str = textwrap.dedent( 

117 """ 

118 description: Test Pipeline 

119 parameters: 

120 testValue: 5 

121 tasks: 

122 add: 

123 class: test_pipeline.AddTask 

124 config: 

125 addend: parameters.testValue 

126 """ 

127 ) 

128 # verify that parameters are used in expanding a pipeline 

129 pipeline = Pipeline.fromString(pipeline_str) 

130 expandedPipeline = list(pipeline.toExpandedPipeline()) 

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

132 

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

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

135 expandedPipeline = list(pipeline.toExpandedPipeline()) 

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

137 

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

139 with self.assertRaises(ValueError): 

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

141 with self.assertRaises(ValueError): 

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

143 

144 def testSerialization(self): 

145 pipeline = makeSimplePipeline(2) 

146 dump = str(pipeline) 

147 load = Pipeline.fromString(dump) 

148 self.assertEqual(pipeline, load) 

149 

150 def test_initOutputNames(self): 

151 """Test for PipelineDatasetTypes.initOutputNames method.""" 

152 pipeline = makeSimplePipeline(3) 

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

154 expected = { 

155 "packages", 

156 "add_init_output1", 

157 "add_init_output2", 

158 "add_init_output3", 

159 "task0_config", 

160 "task1_config", 

161 "task2_config", 

162 } 

163 self.assertEqual(dsType, expected) 

164 

165 

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

167 """Run file leak tests.""" 

168 

169 

170def setup_module(module): 

171 """Configure pytest.""" 

172 lsst.utils.tests.init() 

173 

174 

175if __name__ == "__main__": 

176 lsst.utils.tests.init() 

177 unittest.main()