Coverage for tests / test_cliCmdTestIngest.py: 53%
57 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-30 08:52 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-30 08:52 +0000
1# This file is part of obs_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 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 ingest-raws command."""
24import unittest
26import lsst.obs.base
27from lsst.daf.butler import Butler
28from lsst.daf.butler.cli.butler import cli as butlerCli
29from lsst.daf.butler.cli.utils import LogCliRunner, clickResultMsg
30from lsst.daf.butler.tests import CliCmdTestBase
31from lsst.obs.base.cli.cmd import ingest_raws
32from lsst.obs.base.cli.cmd.commands import fits_re
33from lsst.obs.base.ingest import RawIngestConfig
36class IngestRawsTestCase(CliCmdTestBase, unittest.TestCase):
37 """Test the ingest-raws command-line tool."""
39 mockFuncName = "lsst.obs.base.cli.cmd.commands.script.ingestRaws"
41 @staticmethod
42 def defaultExpected():
43 return dict(
44 config={},
45 config_file=None,
46 ingest_task="lsst.obs.base.RawIngestTask",
47 locations=(),
48 output_run=None,
49 processes=1,
50 regex=fits_re,
51 transfer="auto",
52 track_file_attrs=True,
53 update_records=False,
54 fail_fast=False,
55 skip_existing=True,
56 search_indexes=True,
57 )
59 @staticmethod
60 def command():
61 return ingest_raws
63 def test_repoAndOutput(self):
64 """Test the most basic required arguments, repo and output run."""
65 self.run_test(
66 ["ingest-raws", "repo", "resources", "--output-run", "out"],
67 self.makeExpected(repo="repo", locations=("resources",), output_run="out"),
68 )
70 def test_configMulti(self):
71 """Test config overrides."""
72 self.run_test(
73 [
74 "ingest-raws",
75 "repo",
76 "resources",
77 "--output-run",
78 "out",
79 "-c",
80 "foo=1",
81 "--config",
82 "bar=2",
83 "--config",
84 "baz=3",
85 ],
86 self.makeExpected(
87 repo="repo",
88 locations=("resources",),
89 output_run="out",
90 config={"foo": "1", "bar": "2", "baz": "3"},
91 ),
92 )
94 def test_configFile(self):
95 """Test config file override."""
96 configFile = "path/to/file.txt"
97 self.run_test(
98 ["ingest-raws", "repo", "resources", "--output-run", "out", "--config-file", configFile],
99 self.makeExpected(
100 repo="repo", locations=("resources",), output_run="out", config_file=configFile
101 ),
102 withTempFile=configFile,
103 )
105 def test_transfer(self):
106 """Test the transfer argument."""
107 self.run_test(
108 ["ingest-raws", "repo", "resources", "--output-run", "out", "--transfer", "symlink"],
109 self.makeExpected(repo="repo", locations=("resources",), output_run="out", transfer="symlink"),
110 )
112 def test_ingestTask(self):
113 """Test the ingest task argument."""
114 self.run_test(
115 ["ingest-raws", "repo", "resources", "--output-run", "out", "--ingest-task", "foo.bar.baz"],
116 self.makeExpected(
117 repo="repo", locations=("resources",), output_run="out", ingest_task="foo.bar.baz"
118 ),
119 )
121 def test_locations(self):
122 """Test that the locations argument accepts multiple inputs and splits
123 commas.
124 """
125 self.run_test(
126 ["ingest-raws", "repo", "in/directory/,in/another/dir/", "other/file.fits"],
127 self.makeExpected(repo="repo", locations=("in/directory/", "in/another/dir/", "other/file.fits")),
128 )
130 def test_no_skip(self):
131 """Test that no skip does appear."""
132 self.run_test(
133 ["ingest-raws", "repo", "in/directory/", "--no-skip-existing"],
134 self.makeExpected(repo="repo", locations=("in/directory/",), skip_existing=False),
135 )
138class PatchRawIngestTask(lsst.obs.base.RawIngestTask):
139 """Ingest task with run() method disabled."""
141 init_args = []
143 def __init__(self, *args, **kwargs):
144 self.init_args.append((args, kwargs))
145 super().__init__(*args, **kwargs)
147 def run(self, *args, **kwargs):
148 pass
151class RawIngestMockTest(unittest.TestCase):
152 """Run ingest tests with mock."""
154 def setUp(self):
155 self.runner = LogCliRunner()
157 def test(self):
158 """Verify config gets applied properly."""
159 with self.runner.isolated_filesystem():
160 result = self.runner.invoke(butlerCli, ["create", "repo"])
161 self.assertEqual(result.exit_code, 0, clickResultMsg(result))
162 with unittest.mock.patch("lsst.obs.base.RawIngestTask", new=PatchRawIngestTask) as mock:
163 # Call, override the name parameter of the config and set
164 # fail-fast.
165 result = self.runner.invoke(
166 butlerCli,
167 ["ingest-raws", "repo", "resources", "--config", "transfer=hardlink", "--fail-fast"],
168 )
169 self.assertEqual(result.exit_code, 0, clickResultMsg(result))
170 # Verify the mock class was initialized exactly once:
171 self.assertEqual(len(mock.init_args), 1)
172 # Verify that the task was initialized with a 'butler' kwarg
173 # that received a butler instance:
174 self.assertIsInstance(mock.init_args[0][1]["butler"], Butler)
175 expectedConfig = RawIngestConfig()
176 # Verify that the task was initialized with a 'config' kwarg
177 # that received an expected config:
178 expectedConfig.update(transfer="hardlink")
179 # Verfiy that --failfast caused the config's failFast
180 # parameter to be set to True.
181 expectedConfig.update(failFast=True)
182 self.assertEqual(mock.init_args[0][1]["config"], expectedConfig)
185if __name__ == "__main__": 185 ↛ 186line 185 didn't jump to line 186 because the condition on line 185 was never true
186 unittest.main()