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