Coverage for tests/test_cliCmdPurge.py: 27%
59 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-08-06 02:30 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-08-06 02:30 +0000
1# This file is part of ctrl_mpexec.
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 program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <http://www.gnu.org/licenses/>.
22"""Unit tests for ctrl_mpexec CLI purge subcommand.
23"""
26import os
27import unittest
29from lsst.ctrl.mpexec.cli.pipetask import cli as pipetask_cli
30from lsst.daf.butler.cli.butler import cli as butler_cli
31from lsst.daf.butler.cli.utils import LogCliRunner, clickResultMsg
32from lsst.daf.butler.tests.utils import MetricTestRepo, makeTestTempDir, removeTestTempDir
34TESTDIR = os.path.abspath(os.path.dirname(__file__))
37class PurgeTest(unittest.TestCase):
38 """Test executing "pipetask purge" commands."""
40 def setUp(self):
41 self.runner = LogCliRunner()
43 # this creates a repo with collections:
44 # Name Type
45 # ---------- ------
46 # ingest TAGGED
47 # ingest/run RUN
48 self.root = makeTestTempDir(TESTDIR)
49 self.testRepo = MetricTestRepo(
50 self.root,
51 configFile=os.path.join(TESTDIR, "config/metricTestRepoButler.yaml"),
52 )
54 def tearDown(self):
55 removeTestTempDir(self.root)
57 def test_singleChain_yesNo(self):
58 """Test removing a chain with one child, and the yes/no
59 confirmation.
60 """
61 # add the collection ingest/run to a CHAINED collection called "in"
62 result = self.runner.invoke(butler_cli, ["collection-chain", self.root, "in", "ingest/run"])
63 self.assertEqual(result.exit_code, 0, clickResultMsg(result))
65 # purge the CHAINED collection called "in", but say "no", check for
66 # expected outputs.
67 result = self.runner.invoke(pipetask_cli, ["purge", "-b", self.root, "in"], input="no")
68 self.assertEqual(result.exit_code, 0, clickResultMsg(result))
69 self.assertIn("Will remove:\n runs: ingest/run\n chains: in\n others: \n", result.output)
70 self.assertIn("Aborted.", result.output)
72 # purge the CHAINED collection called "in", and say "yes", check for
73 # expected outputs.
74 result = self.runner.invoke(pipetask_cli, ["purge", "-b", self.root, "in"], input="yes")
75 self.assertEqual(result.exit_code, 0, clickResultMsg(result))
76 self.assertIn("Will remove:\n runs: ingest/run\n chains: in\n others: \n", result.output)
77 self.assertIn("Done.", result.output)
79 def test_granparentChain_noConfirm(self):
80 """Test removing a chain with children and grandchildren, and the
81 --no-confirm option.
82 """
83 # add the collection ingest/run to a CHAINED collection called "ing"
84 result = self.runner.invoke(butler_cli, ["collection-chain", self.root, "ing", "ingest/run"])
85 self.assertEqual(result.exit_code, 0, clickResultMsg(result))
87 # add the CHAINED collectin "ing" a CHAINED collection called "in"
88 result = self.runner.invoke(butler_cli, ["collection-chain", self.root, "in", "ing"])
89 self.assertEqual(result.exit_code, 0, clickResultMsg(result))
91 # purge the CHAINED collection called "in" with --no-confirm and check
92 # for expected outputs.
93 result = self.runner.invoke(
94 pipetask_cli,
95 ["purge", "-b", self.root, "in", "--recursive", "--no-confirm"],
96 )
97 self.assertEqual(result.exit_code, 0, clickResultMsg(result))
98 self.assertIn("Removed:\n runs: ingest/run\n chains: in, ing\n others: \n", result.output)
100 def test_topParentWithParent(self):
101 """Test that purging a chain with a parent fails."""
102 # add the collection ingest/run to a CHAINED collection called "ing"
103 result = self.runner.invoke(butler_cli, ["collection-chain", self.root, "ing", "ingest/run"])
104 self.assertEqual(result.exit_code, 0, clickResultMsg(result))
106 # add the CHAINED collectin "ing" a CHAINED collection called "in"
107 result = self.runner.invoke(butler_cli, ["collection-chain", self.root, "in", "ing"])
108 self.assertEqual(result.exit_code, 0, clickResultMsg(result))
110 # purge the CHAINED collection called "ing" and check for expected
111 # outputs.
112 result = self.runner.invoke(
113 pipetask_cli,
114 ["purge", "-b", self.root, "ing"],
115 )
116 self.assertEqual(result.exit_code, 1, clickResultMsg(result))
117 self.assertIn(
118 'The passed-in collection "ing" must not be contained in other collections but '
119 'is contained in collection(s) "in".',
120 result.output,
121 )
123 def test_childWithMultipleParents(self):
124 """Test that a child chain with multiple parents fails."""
125 # add the collection ingest/run to a CHAINED collection called "ing"
126 result = self.runner.invoke(butler_cli, ["collection-chain", self.root, "ing", "ingest/run"])
127 self.assertEqual(result.exit_code, 0, clickResultMsg(result))
129 # add the collectin ingest/run to a CHAINED collection called "foo"
130 result = self.runner.invoke(butler_cli, ["collection-chain", self.root, "foo", "ingest/run"])
131 self.assertEqual(result.exit_code, 0, clickResultMsg(result))
133 # purge the CHAINED collection called "ing" and check for expected
134 # outputs.
135 result = self.runner.invoke(
136 pipetask_cli,
137 ["purge", "-b", self.root, "ing"],
138 )
139 self.assertEqual(result.exit_code, 1, clickResultMsg(result))
140 self.assertIn(
141 'Collection "ingest/run" is in multiple chained collections:',
142 result.output,
143 )
144 self.assertIn('"foo"', result.output)
145 self.assertIn('"ing"', result.output)
147 def test_notFound_notChained(self):
148 """Test for failure when the top level collection is not found,
149 and when a top level connection is not a CHAINED collection.
150 """
151 # Test purging a collection that does not exist.
152 result = self.runner.invoke(
153 pipetask_cli,
154 ["purge", "-b", self.root, "notACollection"],
155 )
156 self.assertEqual(result.exit_code, 1, clickResultMsg(result))
157 self.assertIn(
158 'The passed-in collection "notACollection" was not found.',
159 result.output,
160 )
162 # Test purging a collection that is not a CHAINED collection.
163 result = self.runner.invoke(
164 pipetask_cli,
165 ["purge", "-b", self.root, "ingest/run"],
166 )
167 self.assertEqual(result.exit_code, 1, clickResultMsg(result))
168 self.assertIn(
169 'The passed-in collection must be a CHAINED collection; "ingest/run" is a RUN collection.',
170 result.output,
171 )
174if __name__ == "__main__":
175 unittest.main()