Coverage for tests/test_cliScript.py: 24%

70 statements  

« prev     ^ index     » next       coverage.py v7.5.1, created at 2024-05-08 02:55 -0700

1# This file is part of ctrl_mpexec. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (https://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 <https://www.gnu.org/licenses/>. 

27 

28import os 

29import tempfile 

30import unittest 

31 

32import click 

33import lsst.utils.tests 

34from lsst.ctrl.mpexec.cli import opt, script 

35from lsst.ctrl.mpexec.cli.pipetask import cli as pipetaskCli 

36from lsst.ctrl.mpexec.showInfo import ShowInfo 

37from lsst.daf.butler.cli.utils import LogCliRunner, clickResultMsg 

38from lsst.pipe.base import Pipeline 

39 

40 

41class BuildTestCase(unittest.TestCase): 

42 """Test a few of the inputs to the build script function to test basic 

43 funcitonality. 

44 """ 

45 

46 @staticmethod 

47 def buildArgs(**kwargs): 

48 defaultArgs = dict( 

49 log_level=(), 

50 order_pipeline=False, 

51 pipeline=None, 

52 pipeline_actions=(), 

53 pipeline_dot=None, 

54 save_pipeline=None, 

55 show=ShowInfo([]), 

56 ) 

57 defaultArgs.update(kwargs) 

58 return defaultArgs 

59 

60 def testMakeEmptyPipeline(self): 

61 """Test building a pipeline with default arguments.""" 

62 pipeline = script.build(**self.buildArgs()) 

63 self.assertIsInstance(pipeline, Pipeline) 

64 self.assertEqual(len(pipeline), 0) 

65 

66 def testSavePipeline(self): 

67 """Test pipeline serialization.""" 

68 with tempfile.TemporaryDirectory() as tempdir: 

69 # make empty pipeline and store it in a file 

70 filename = os.path.join(tempdir, "pipeline_file.yaml") 

71 pipeline = script.build(**self.buildArgs(save_pipeline=filename)) 

72 self.assertIsInstance(pipeline, Pipeline) 

73 self.assertTrue(os.path.isfile(filename)) 

74 # read pipeline from a file 

75 pipeline = script.build(**self.buildArgs(pipeline=filename)) 

76 self.assertIsInstance(pipeline, Pipeline) 

77 self.assertIsInstance(pipeline, Pipeline) 

78 self.assertEqual(len(pipeline), 0) 

79 

80 def testShowPipeline(self): 

81 """Test showing the pipeline.""" 

82 

83 class ShowInfoCmp: 

84 def __init__(self, show, expectedOutput): 

85 self.show = show 

86 self.expectedOutput = expectedOutput 

87 

88 def __repr__(self): 

89 return f"ShowInfoCmp({self.show}, {self.expectedOutput}" 

90 

91 testdata = [ 

92 ShowInfoCmp( 

93 "pipeline", 

94 """description: anonymous 

95tasks: 

96 task: 

97 class: lsst.pipe.base.tests.simpleQGraph.AddTask 

98 config: 

99 - addend: '100'""", 

100 ), 

101 ShowInfoCmp( 

102 "config", 

103 """### Configuration for task `task' 

104# Flag to enable/disable saving of log output for a task, enabled by default. 

105config.saveLogOutput=True 

106 

107# amount to add 

108config.addend=100 

109 

110# name for connection input 

111config.connections.input='add_dataset{in_tmpl}' 

112 

113# name for connection output 

114config.connections.output='add_dataset{out_tmpl}' 

115 

116# name for connection output2 

117config.connections.output2='add2_dataset{out_tmpl}' 

118 

119# name for connection initout 

120config.connections.initout='add_init_output{out_tmpl}' 

121 

122# Template parameter used to format corresponding field template parameter 

123config.connections.in_tmpl='_in' 

124 

125# Template parameter used to format corresponding field template parameter 

126config.connections.out_tmpl='_out'""", 

127 ), 

128 # history will contain machine-specific paths, TBD how to verify 

129 ShowInfoCmp("history=task::addend", None), 

130 ShowInfoCmp("tasks", "### Subtasks for task `lsst.pipe.base.tests.simpleQGraph.AddTask'"), 

131 ] 

132 

133 for showInfo in testdata: 

134 runner = LogCliRunner() 

135 result = runner.invoke( 

136 pipetaskCli, 

137 [ 

138 "build", 

139 "--task", 

140 "lsst.pipe.base.tests.simpleQGraph.AddTask:task", 

141 "--config", 

142 "task:addend=100", 

143 "--show", 

144 showInfo.show, 

145 ], 

146 ) 

147 self.assertEqual(result.exit_code, 0, clickResultMsg(result)) 

148 if showInfo.expectedOutput is not None: 

149 self.assertIn(showInfo.expectedOutput, result.output, msg=f"for {showInfo}") 

150 

151 def testMissingOption(self): 

152 """Test that the build script fails if options are missing.""" 

153 

154 @click.command() 

155 @opt.pipeline_build_options() 

156 def cli(**kwargs): 

157 script.build(**kwargs) 

158 

159 runner = click.testing.CliRunner() 

160 result = runner.invoke(cli) 

161 # The cli call should fail, because script.build takes more options 

162 # than are defined by pipeline_build_options. 

163 self.assertNotEqual(result.exit_code, 0) 

164 

165 

166class QgraphTestCase(unittest.TestCase): 

167 """Test pipetask qgraph command-line.""" 

168 

169 def testMissingOption(self): 

170 """Test that if options for the qgraph script are missing that it 

171 fails. 

172 """ 

173 

174 @click.command() 

175 @opt.pipeline_build_options() 

176 def cli(**kwargs): 

177 script.qgraph(**kwargs) 

178 

179 runner = click.testing.CliRunner() 

180 result = runner.invoke(cli) 

181 # The cli call should fail, because qgraph.build takes more options 

182 # than are defined by pipeline_build_options. 

183 self.assertNotEqual(result.exit_code, 0) 

184 

185 

186class RunTestCase(unittest.TestCase): 

187 """Test pipetask run command-line.""" 

188 

189 def testMissingOption(self): 

190 """Test that if options for the run script are missing that it 

191 fails. 

192 """ 

193 

194 @click.command() 

195 @opt.pipeline_build_options() 

196 def cli(**kwargs): 

197 script.run(**kwargs) 

198 

199 runner = click.testing.CliRunner() 

200 result = runner.invoke(cli) 

201 # The cli call should fail, because qgraph.run takes more options 

202 # than are defined by pipeline_build_options. 

203 self.assertNotEqual(result.exit_code, 0) 

204 

205 

206if __name__ == "__main__": 

207 lsst.utils.tests.init() 

208 unittest.main()