Coverage for tests/test_cliCmdRemoveRuns.py: 15%
79 statements
« prev ^ index » next coverage.py v7.5.0, created at 2024-04-30 09:54 +0000
« prev ^ index » next coverage.py v7.5.0, created at 2024-04-30 09:54 +0000
1# This file is part of daf_butler.
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"""Unit tests for daf_butler CLI remove-runs subcommand.
29"""
32import os
33import unittest
35from lsst.daf.butler import DatasetType
36from lsst.daf.butler.cli import butler
37from lsst.daf.butler.cli.cmd._remove_runs import (
38 abortedMsg,
39 didRemoveDatasetsMsg,
40 didRemoveRunsMsg,
41 mustBeUnlinkedMsg,
42 noRunCollectionsMsg,
43 removedRunsMsg,
44 willRemoveDatasetsMsg,
45 willRemoveRunsMsg,
46 willUnlinkMsg,
47)
48from lsst.daf.butler.cli.utils import LogCliRunner, clickResultMsg
49from lsst.daf.butler.tests.utils import MetricTestRepo
51TESTDIR = os.path.abspath(os.path.dirname(__file__))
54class RemoveCollectionTest(unittest.TestCase):
55 """Test the butler remove-runs command."""
57 def setUp(self):
58 self.runner = LogCliRunner()
60 def test_removeRuns(self):
61 with self.runner.isolated_filesystem():
62 root = "repo"
63 repo = MetricTestRepo(root, configFile=os.path.join(TESTDIR, "config/basic/butler.yaml"))
64 # Add a dataset type that will have no datasets to make sure it
65 # isn't printed.
66 repo.butler.registry.registerDatasetType(
67 DatasetType("no_datasets", repo.butler.dimensions.empty, "StructuredDataDict")
68 )
70 # Execute remove-runs but say no, check for expected outputs.
71 result = self.runner.invoke(butler.cli, ["remove-runs", root, "ingest*"], input="no")
72 self.assertEqual(result.exit_code, 0, clickResultMsg(result))
73 self.assertIn(willRemoveRunsMsg, result.output)
74 self.assertIn(abortedMsg, result.output)
75 self.assertNotIn("no_datasets", result.output)
76 self.assertIn(
77 "ingest/run",
78 list(repo.butler.registry.queryCollections()),
79 )
81 # Add the run to a CHAINED collection.
82 parentCollection = "aParentCollection"
83 result = self.runner.invoke(
84 butler.cli, f"collection-chain {root} {parentCollection} ingest/run".split()
85 )
86 self.assertEqual(result.exit_code, 0, clickResultMsg(result))
87 result = self.runner.invoke(butler.cli, ["query-collections", root])
88 self.assertEqual(result.exit_code, 0, clickResultMsg(result))
89 self.assertIn(parentCollection, result.output)
91 # Execute remove-runs but say no, check for expected outputs
92 # including the CHAINED collection.
93 result = self.runner.invoke(butler.cli, ["remove-runs", root, "ingest*"], input="no")
94 self.assertEqual(result.exit_code, 0, clickResultMsg(result))
95 self.assertIn(willRemoveRunsMsg, result.output)
96 self.assertIn(willRemoveDatasetsMsg, result.output)
97 self.assertIn(
98 willUnlinkMsg.format(run="ingest/run", parents=f'"{parentCollection}"'), result.output
99 )
100 self.assertIn(abortedMsg, result.output)
101 self.assertNotIn("no_datasets", result.output)
102 result = self.runner.invoke(butler.cli, ["query-collections", root])
103 self.assertEqual(result.exit_code, 0, clickResultMsg(result))
104 self.assertIn("ingest/run", result.output)
105 self.assertIn(parentCollection, result.output)
107 # Do the same remove-runs command, but say yes.
108 result = self.runner.invoke(butler.cli, ["remove-runs", root, "ingest*"], input="yes")
109 self.assertEqual(result.exit_code, 0, clickResultMsg(result))
110 self.assertIn(willRemoveRunsMsg, result.output)
111 self.assertIn(willRemoveDatasetsMsg, result.output)
112 self.assertIn(removedRunsMsg, result.output)
113 result = self.runner.invoke(butler.cli, ["query-collections", root])
114 self.assertEqual(result.exit_code, 0, clickResultMsg(result))
115 self.assertNotIn("ingest/run", result.output)
116 self.assertIn(parentCollection, result.output)
118 # Now they've been deleted, try again and check for "none found".
119 result = self.runner.invoke(butler.cli, ["remove-runs", root, "ingest*"])
120 self.assertEqual(result.exit_code, 0, clickResultMsg(result))
121 self.assertIn(noRunCollectionsMsg, result.output)
123 # Remake the repo and check --no-confirm option.
124 root = "repo1"
125 MetricTestRepo(root, configFile=os.path.join(TESTDIR, "config/basic/butler.yaml"))
127 # Add the run to a CHAINED collection.
128 parentCollection = "parent"
129 result = self.runner.invoke(
130 butler.cli, f"collection-chain {root} {parentCollection} ingest/run".split()
131 )
132 self.assertEqual(result.exit_code, 0, clickResultMsg(result))
133 result = self.runner.invoke(butler.cli, ["query-collections", root])
134 self.assertEqual(result.exit_code, 0, clickResultMsg(result))
135 self.assertIn("ingest/run", result.output)
136 self.assertIn(parentCollection, result.output)
138 # Execute remove-runs with --no-confirm, should fail because there
139 # is a parent CHAINED collection.
140 result = self.runner.invoke(butler.cli, ["remove-runs", root, "ingest*", "--no-confirm"])
141 self.assertNotEqual(result.exit_code, 0, clickResultMsg(result))
142 self.assertIn(
143 mustBeUnlinkedMsg.format(run="ingest/run", parents=f'"{parentCollection}"'), result.output
144 )
145 result = self.runner.invoke(butler.cli, ["query-collections", root])
146 self.assertEqual(result.exit_code, 0, clickResultMsg(result))
147 self.assertIn("ingest/run", result.output)
148 self.assertIn(parentCollection, result.output)
150 # Execute remove-runs with --no-confirm and --force
151 result = self.runner.invoke(
152 butler.cli, ["remove-runs", root, "ingest*", "--no-confirm", "--force"]
153 )
154 self.assertEqual(result.exit_code, 0, clickResultMsg(result))
155 self.assertIn(didRemoveRunsMsg, result.output)
156 self.assertIn(didRemoveDatasetsMsg, result.output)
157 result = self.runner.invoke(butler.cli, ["query-collections", root])
158 self.assertEqual(result.exit_code, 0, clickResultMsg(result))
159 self.assertNotIn("ingest/run", result.output)
160 self.assertIn(parentCollection, result.output)
162 # Execute cmd looking for a non-existant collection
163 result = self.runner.invoke(butler.cli, ["remove-runs", root, "foo"])
164 self.assertEqual(result.exit_code, 0, clickResultMsg(result))
165 self.assertIn(noRunCollectionsMsg, result.output)
168if __name__ == "__main__":
169 unittest.main()