Coverage for tests/test_pipeline.py: 17%
98 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-03-26 02:50 -0700
« prev ^ index » next coverage.py v7.4.4, created at 2024-03-26 02:50 -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/>.
28"""Simple unit test for Pipeline.
29"""
31import pickle
32import textwrap
33import unittest
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
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 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")
71 def testModifySubset(self):
72 pipeline = makeSimplePipeline(2)
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"})
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())
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"})
99 taskLabels = {"task0", "task1"}
100 pipeline.addLabeledSubset("newSubset", "test description", taskLabels)
102 # verify using the subset property interface
103 self.assertEqual(pipeline.subsets["newSubset"], taskLabels)
105 # Test removing labeled subsets
106 with self.assertRaises(ValueError):
107 pipeline.removeLabeledSubset("missing_subset")
109 pipeline.removeLabeledSubset("newSubset")
110 self.assertNotIn("newSubset", pipeline.subsets.keys())
112 def testMergingPipelines(self):
113 pipeline1 = makeSimplePipeline(2)
114 pipeline2 = makeSimplePipeline(4)
115 pipeline2.removeTask("task0")
116 pipeline2.removeTask("task1")
118 pipeline1.mergePipeline(pipeline2)
119 self.assertEqual(pipeline1._pipelineIR.tasks.keys(), {"task0", "task1", "task2", "task3"})
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)
127 pipeline.addLabelToSubset("test1", "task0")
128 pipeline.addLabelToSubset("test3", "task0")
130 with self.assertRaises(ValueError):
131 pipeline.findSubsetsWithLabel("missing_label")
133 self.assertEqual(pipeline.findSubsetsWithLabel("task0"), {"test1", "test3"})
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)
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)
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")
165 def testSerialization(self):
166 pipeline = makeSimplePipeline(2)
167 dump = str(pipeline)
168 load = Pipeline.fromString(dump)
169 self.assertEqual(pipeline, load)
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)
187class MyMemoryTestCase(lsst.utils.tests.MemoryTestCase):
188 """Run file leak tests."""
191def setup_module(module):
192 """Configure pytest."""
193 lsst.utils.tests.init()
196if __name__ == "__main__":
197 lsst.utils.tests.init()
198 unittest.main()