Coverage for tests/test_graphSkeleton.py: 100%
28 statements
« prev ^ index » next coverage.py v7.15.0, created at 2026-07-09 09:08 +0000
« prev ^ index » next coverage.py v7.15.0, created at 2026-07-09 09:08 +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# (https://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 <https://www.gnu.org/licenses/>.
28"""Unit tests for QuantumGraphSkeleton."""
30import unittest
32from lsst.daf.butler import DataCoordinate, DimensionUniverse
33from lsst.pipe.base.quantum_graph_skeleton import DatasetKey, QuantumGraphSkeleton
36class RemoveUnanchoredQuantaTestCase(unittest.TestCase):
37 """Tests for ``QuantumGraphSkeleton.remove_unanchored_quanta``.
39 Graph:
40 source1 -> d1 -> anchor1 (band 1: anchored)
41 source2 -> d2 -> anchor2 (band 2: anchored)
42 source3 -> d3 (band 3: unanchored)
43 source4 -> d4 (band 4: unanchored)
44 """
46 def setUp(self):
47 universe = DimensionUniverse()
48 self.skeleton = QuantumGraphSkeleton(["source", "anchor"])
49 for i in range(1, 5):
50 data_id = DataCoordinate.standardize({"band": i}, universe=universe)
51 source_quantum = self.skeleton.add_quantum_node("source", data_id)
52 dataset = self.skeleton.add_dataset_node(f"d{i}", data_id)
53 self.skeleton.add_output_edge(source_quantum, dataset)
54 if i <= 2:
55 anchor_quantum = self.skeleton.add_quantum_node("anchor", data_id)
56 self.skeleton.add_input_edge(anchor_quantum, dataset)
58 def test_remove_unanchored(self):
59 """Unanchored source quanta and their descendants are removed."""
60 removed = self.skeleton.remove_unanchored_quanta("source", "anchor")
61 self.assertEqual(removed, {"source": 2})
62 self.assertEqual(len(self.skeleton.get_quanta("source")), 2)
63 self.assertEqual(len(self.skeleton.get_quanta("anchor")), 2)
64 self.assertNotIn(DatasetKey("d3", (3,)), self.skeleton)
65 self.assertNotIn(DatasetKey("d4", (4,)), self.skeleton)
67 # Second call on an already-pruned skeleton is a no-op.
68 removed = self.skeleton.remove_unanchored_quanta("source", "anchor")
69 self.assertEqual(removed, {})
71 def test_task_dropped_when_all_unanchored(self):
72 """Task is dropped when all its quanta are removed."""
73 removed = self.skeleton.remove_unanchored_quanta("source", "nonexistent")
74 self.assertEqual(removed["source"], 4)
75 self.assertFalse(self.skeleton.has_task("source"))
78if __name__ == "__main__":
79 unittest.main()