Coverage for tests/test_pipeline.py: 15%
103 statements
« prev ^ index » next coverage.py v7.5.1, created at 2024-05-18 09:56 +0000
« prev ^ index » next coverage.py v7.5.1, created at 2024-05-18 09:56 +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/>.
28"""Simple unit test for Pipeline.
29"""
31import pickle
32import textwrap
33import unittest
35import lsst.utils.tests
36from lsst.pipe.base import LabelSpecifier, Pipeline, TaskDef
37from lsst.pipe.base.pipelineIR import LabeledSubset
38from lsst.pipe.base.tests.simpleQGraph import AddTask, makeSimplePipeline
41class PipelineTestCase(unittest.TestCase):
42 """A test case for TaskDef and Pipeline."""
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)
54 def testEmpty(self):
55 """Creating empty pipeline."""
56 pipeline = Pipeline("test")
57 self.assertEqual(len(pipeline), 0)
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"})
72 def testModifySubset(self):
73 pipeline = makeSimplePipeline(2)
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"})
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())
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"})
100 taskLabels = {"task0", "task1"}
101 pipeline.addLabeledSubset("newSubset", "test description", taskLabels)
103 # verify using the subset property interface
104 self.assertEqual(pipeline.subsets["newSubset"], taskLabels)
106 # Test removing labeled subsets
107 with self.assertRaises(ValueError):
108 pipeline.removeLabeledSubset("missing_subset")
110 pipeline.removeLabeledSubset("newSubset")
111 self.assertNotIn("newSubset", pipeline.subsets.keys())
113 pipeline.addLabeledSubset("testSubset", "Test subset description", taskLabels)
114 taskSubset = {"task0"}
115 pipelineDrop = pipeline.subsetFromLabels(LabelSpecifier(taskSubset), pipeline.PipelineSubsetCtrl.DROP)
116 pipelineEdit = pipeline.subsetFromLabels(LabelSpecifier(taskSubset), pipeline.PipelineSubsetCtrl.EDIT)
118 # Test subsetting from labels
119 self.assertNotIn(taskLabels - taskSubset, set(pipelineDrop.task_labels))
120 self.assertNotIn("testSubset", pipelineDrop.subsets.keys())
121 self.assertNotIn(taskLabels - taskSubset, set(pipelineEdit.task_labels))
122 self.assertIn("testSubset", pipelineEdit.subsets.keys())
123 self.assertEqual(pipelineEdit.subsets["testSubset"], taskSubset)
125 def testMergingPipelines(self):
126 pipeline1 = makeSimplePipeline(2)
127 pipeline2 = makeSimplePipeline(4)
128 pipeline2.removeTask("task0")
129 pipeline2.removeTask("task1")
131 pipeline1.mergePipeline(pipeline2)
132 self.assertEqual(pipeline1._pipelineIR.tasks.keys(), {"task0", "task1", "task2", "task3"})
134 def testFindingSubset(self):
135 pipeline = makeSimplePipeline(2)
136 pipeline._pipelineIR.labeled_subsets["test1"] = LabeledSubset("test1", set(), None)
137 pipeline._pipelineIR.labeled_subsets["test2"] = LabeledSubset("test2", set(), None)
138 pipeline._pipelineIR.labeled_subsets["test3"] = LabeledSubset("test3", set(), None)
140 pipeline.addLabelToSubset("test1", "task0")
141 pipeline.addLabelToSubset("test3", "task0")
143 with self.assertRaises(ValueError):
144 pipeline.findSubsetsWithLabel("missing_label")
146 self.assertEqual(pipeline.findSubsetsWithLabel("task0"), {"test1", "test3"})
148 def testParameters(self):
149 """Test that parameters can be set and used to format."""
150 pipeline_str = textwrap.dedent(
151 """
152 description: Test Pipeline
153 parameters:
154 testValue: 5
155 tasks:
156 add:
157 class: test_pipeline.AddTask
158 config:
159 addend: parameters.testValue
160 """
161 )
162 # verify that parameters are used in expanding a pipeline
163 pipeline = Pipeline.fromString(pipeline_str)
164 pipeline_graph = pipeline.to_graph()
165 self.assertEqual(pipeline_graph.tasks["add"].config.addend, 5)
167 # verify that a parameter can be overridden on the "command line"
168 pipeline.addConfigOverride("parameters", "testValue", 14)
169 pipeline_graph = pipeline.to_graph()
170 self.assertEqual(pipeline_graph.tasks["add"].config.addend, 14)
172 # verify that parameters does not support files or python overrides
173 with self.assertRaises(ValueError):
174 pipeline.addConfigFile("parameters", "fakeFile")
175 with self.assertRaises(ValueError):
176 pipeline.addConfigPython("parameters", "fakePythonString")
178 def testSerialization(self):
179 pipeline = makeSimplePipeline(2)
180 dump = str(pipeline)
181 load = Pipeline.fromString(dump)
182 self.assertEqual(pipeline, load)
185class MyMemoryTestCase(lsst.utils.tests.MemoryTestCase):
186 """Run file leak tests."""
189def setup_module(module):
190 """Configure pytest."""
191 lsst.utils.tests.init()
194if __name__ == "__main__":
195 lsst.utils.tests.init()
196 unittest.main()