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

89 statements  

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# 

23 

24import argparse 

25import functools 

26import shutil 

27import tempfile 

28import unittest.mock 

29 

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 

35 

36 

37def _getDataIds(): 

38 return [{"visit": 42, "ccd": 0}] 

39 

40 

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 

54 

55 

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) 

60 

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") 

65 

66 self.workspace = WorkspaceGen3(self._testDir) 

67 self.apPipeArgs = pipeline_driver.ApPipeParser().parse_args( 

68 ["--id", "visit = %d" % _getDataIds()[0]["visit"]]) 

69 

70 @staticmethod 

71 def dummyMetadata(): 

72 result = PropertySet() 

73 result.add("lsst.pipe.base.calibrate.cycleCount", 42) 

74 return result 

75 

76 def setUpMockPatch(self, target, **kwargs): 

77 """Create and register a patcher for a test suite. 

78 

79 The patching process is guaranteed to avoid resource leaks or 

80 side effects lasting beyond the test case that calls this method. 

81 

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`. 

90 

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 

103 

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) 

111 

112 mockDb.assert_called_once() 

113 mockFwk().parseAndRun.assert_called_once() 

114 

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!") 

122 

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) 

129 

130 mockDb.assert_called_once() 

131 cmdLineArgs = self._getCmdLineArgs(mockDb.call_args) 

132 self.assertIn("db_url=sqlite:///" + self.workspace.dbLocation, cmdLineArgs) 

133 

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) 

138 

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) 

146 

147 mockDb.assert_called_once() 

148 cmdLineArgs = self._getCmdLineArgs(mockDb.call_args) 

149 self.assertIn("db_url=" + self.apPipeArgs.db, cmdLineArgs) 

150 

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) 

155 

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() 

165 

166 

167class MemoryTester(lsst.utils.tests.MemoryTestCase): 

168 pass 

169 

170 

171def setup_module(module): 

172 lsst.utils.tests.init() 

173 

174 

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()