Coverage for tests/test_driver.py: 42%
Shortcuts on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1#
2# This file is part of ap_verify.
3#
4# Developed for the LSST Data Management System.
5# This product includes software developed by the LSST Project
6# (http://www.lsst.org).
7# See the COPYRIGHT file at the top-level directory of this distribution
8# for details of code ownership.
9#
10# This program is free software: you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation, either version 3 of the License, or
13# (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program. If not, see <http://www.gnu.org/licenses/>.
22#
24import argparse
25import functools
26import shutil
27import tempfile
28import unittest.mock
30from lsst.daf.base import PropertySet
31from lsst.pipe.base import DataIdContainer
32import lsst.utils.tests
33from lsst.ap.verify import pipeline_driver
34from lsst.ap.verify.workspace import WorkspaceGen3
37def _getDataIds():
38 return [{"visit": 42, "ccd": 0}]
41def patchApPipeGen3(method):
42 """Shortcut decorator for consistently patching AP code.
43 """
44 @functools.wraps(method)
45 def wrapper(self, *args, **kwargs):
46 parsedCmd = argparse.Namespace()
47 parsedCmd.id = DataIdContainer()
48 parsedCmd.id.idList = _getDataIds()
49 dbPatcher = unittest.mock.patch("lsst.ap.verify.pipeline_driver.makeApdb")
50 execPatcher = unittest.mock.patch("lsst.ctrl.mpexec.CmdLineFwk")
51 patchedMethod = execPatcher(dbPatcher(method))
52 return patchedMethod(self, *args, **kwargs)
53 return wrapper
56class PipelineDriverTestSuiteGen3(lsst.utils.tests.TestCase):
57 def setUp(self):
58 self._testDir = tempfile.mkdtemp()
59 self.addCleanup(shutil.rmtree, self._testDir, ignore_errors=True)
61 # Fake Butler to avoid Workspace initialization overhead
62 self.setUpMockPatch("lsst.daf.butler.Registry",
63 **{"queryDatasets.return_value": []})
64 self.setUpMockPatch("lsst.daf.butler.Butler")
66 self.workspace = WorkspaceGen3(self._testDir)
67 self.apPipeArgs = pipeline_driver.ApPipeParser().parse_args(
68 ["--id", "visit = %d" % _getDataIds()[0]["visit"]])
70 @staticmethod
71 def dummyMetadata():
72 result = PropertySet()
73 result.add("lsst.pipe.base.calibrate.cycleCount", 42)
74 return result
76 def setUpMockPatch(self, target, **kwargs):
77 """Create and register a patcher for a test suite.
79 The patching process is guaranteed to avoid resource leaks or
80 side effects lasting beyond the test case that calls this method.
82 Parameters
83 ----------
84 target : `str`
85 The target to patch. Must obey all restrictions listed
86 for the ``target`` parameter of `unittest.mock.patch`.
87 kwargs : any
88 Any keyword arguments that are allowed for `unittest.mock.patch`,
89 particularly optional attributes for a `unittest.mock.Mock`.
91 Returns
92 -------
93 mock : `unittest.mock.Mock`
94 Object representing the same type of entity as ``target``. For
95 example, if ``target`` is the name of a class, this method shall
96 return a replacement class (rather than a replacement object of
97 that class).
98 """
99 patcher = unittest.mock.patch(target, **kwargs)
100 mock = patcher.start()
101 self.addCleanup(patcher.stop)
102 return mock
104 @unittest.skip("Fix test in DM-27117")
105 # Mock up CmdLineFwk to avoid doing any processing.
106 @patchApPipeGen3
107 def testrunApPipeGen3Steps(self, mockDb, mockFwk):
108 """Test that runApPipeGen3 runs the entire pipeline.
109 """
110 pipeline_driver.runApPipeGen3(self.workspace, self.apPipeArgs)
112 mockDb.assert_called_once()
113 mockFwk().parseAndRun.assert_called_once()
115 def _getCmdLineArgs(self, parseAndRunArgs):
116 if parseAndRunArgs[0]:
117 return parseAndRunArgs[0][0]
118 elif "args" in parseAndRunArgs[1]:
119 return parseAndRunArgs[1]["args"]
120 else:
121 self.fail("No command-line args passed to parseAndRun!")
123 @unittest.skip("Fix test in DM-27117")
124 @patchApPipeGen3
125 def testrunApPipeGen3WorkspaceDb(self, mockDb, mockFwk):
126 """Test that runApPipeGen3 places a database in the workspace location by default.
127 """
128 pipeline_driver.runApPipeGen3(self.workspace, self.apPipeArgs)
130 mockDb.assert_called_once()
131 cmdLineArgs = self._getCmdLineArgs(mockDb.call_args)
132 self.assertIn("db_url=sqlite:///" + self.workspace.dbLocation, cmdLineArgs)
134 mockParse = mockFwk().parseAndRun
135 mockParse.assert_called_once()
136 cmdLineArgs = self._getCmdLineArgs(mockParse.call_args)
137 self.assertIn("diaPipe:apdb.db_url=sqlite:///" + self.workspace.dbLocation, cmdLineArgs)
139 @unittest.skip("Fix test in DM-27117")
140 @patchApPipeGen3
141 def testrunApPipeGen3WorkspaceCustom(self, mockDb, mockFwk):
142 """Test that runApPipeGen3 places a database in the specified location.
143 """
144 self.apPipeArgs.db = "postgresql://somebody@pgdb.misc.org/custom_db"
145 pipeline_driver.runApPipeGen3(self.workspace, self.apPipeArgs)
147 mockDb.assert_called_once()
148 cmdLineArgs = self._getCmdLineArgs(mockDb.call_args)
149 self.assertIn("db_url=" + self.apPipeArgs.db, cmdLineArgs)
151 mockParse = mockFwk().parseAndRun
152 mockParse.assert_called_once()
153 cmdLineArgs = self._getCmdLineArgs(mockParse.call_args)
154 self.assertIn("diaPipe:apdb.db_url=" + self.apPipeArgs.db, cmdLineArgs)
156 @unittest.skip("Fix test in DM-27117")
157 @patchApPipeGen3
158 def testrunApPipeGen3Reuse(self, _mockDb, mockFwk):
159 """Test that runApPipeGen3 does not run the pipeline at all (not even with
160 --skip-existing) if --skip-pipeline is provided.
161 """
162 skipArgs = pipeline_driver.ApPipeParser().parse_args(["--skip-pipeline"])
163 pipeline_driver.runApPipeGen3(self.workspace, skipArgs)
164 mockFwk().parseAndRun.assert_not_called()
167class MemoryTester(lsst.utils.tests.MemoryTestCase):
168 pass
171def setup_module(module):
172 lsst.utils.tests.init()
175if __name__ == "__main__": 175 ↛ 176line 175 didn't jump to line 176, because the condition on line 175 was never true
176 lsst.utils.tests.init()
177 unittest.main()