Coverage for tests/test_cliScript.py: 24%

70 statements  

« prev     ^ index     » next       coverage.py v7.3.0, created at 2023-08-25 09:44 +0000

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

21 

22import os 

23import tempfile 

24import unittest 

25 

26import click 

27import lsst.utils.tests 

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

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

30from lsst.ctrl.mpexec.showInfo import ShowInfo 

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

32from lsst.pipe.base import Pipeline 

33 

34 

35class BuildTestCase(unittest.TestCase): 

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

37 funcitonality. 

38 """ 

39 

40 @staticmethod 

41 def buildArgs(**kwargs): 

42 defaultArgs = dict( 

43 log_level=(), 

44 order_pipeline=False, 

45 pipeline=None, 

46 pipeline_actions=(), 

47 pipeline_dot=None, 

48 save_pipeline=None, 

49 show=ShowInfo([]), 

50 ) 

51 defaultArgs.update(kwargs) 

52 return defaultArgs 

53 

54 def testMakeEmptyPipeline(self): 

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

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

57 self.assertIsInstance(pipeline, Pipeline) 

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

59 

60 def testSavePipeline(self): 

61 """Test pipeline serialization.""" 

62 with tempfile.TemporaryDirectory() as tempdir: 

63 # make empty pipeline and store it in a file 

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

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

66 self.assertIsInstance(pipeline, Pipeline) 

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

68 # read pipeline from a file 

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

70 self.assertIsInstance(pipeline, Pipeline) 

71 self.assertIsInstance(pipeline, Pipeline) 

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

73 

74 def testShowPipeline(self): 

75 """Test showing the pipeline.""" 

76 

77 class ShowInfoCmp: 

78 def __init__(self, show, expectedOutput): 

79 self.show = show 

80 self.expectedOutput = expectedOutput 

81 

82 def __repr__(self): 

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

84 

85 testdata = [ 

86 ShowInfoCmp( 

87 "pipeline", 

88 """description: anonymous 

89tasks: 

90 task: 

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

92 config: 

93 - addend: '100'""", 

94 ), 

95 ShowInfoCmp( 

96 "config", 

97 """### Configuration for task `task' 

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

99config.saveLogOutput=True 

100 

101# amount to add 

102config.addend=100 

103 

104# name for connection input 

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

106 

107# name for connection output 

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

109 

110# name for connection output2 

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

112 

113# name for connection initout 

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

115 

116# Template parameter used to format corresponding field template parameter 

117config.connections.in_tmpl='_in' 

118 

119# Template parameter used to format corresponding field template parameter 

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

121 ), 

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

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

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

125 ] 

126 

127 for showInfo in testdata: 

128 runner = LogCliRunner() 

129 result = runner.invoke( 

130 pipetaskCli, 

131 [ 

132 "build", 

133 "--task", 

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

135 "--config", 

136 "task:addend=100", 

137 "--show", 

138 showInfo.show, 

139 ], 

140 ) 

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

142 if showInfo.expectedOutput is not None: 

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

144 

145 def testMissingOption(self): 

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

147 

148 @click.command() 

149 @opt.pipeline_build_options() 

150 def cli(**kwargs): 

151 script.build(**kwargs) 

152 

153 runner = click.testing.CliRunner() 

154 result = runner.invoke(cli) 

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

156 # than are defined by pipeline_build_options. 

157 self.assertNotEqual(result.exit_code, 0) 

158 

159 

160class QgraphTestCase(unittest.TestCase): 

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

162 

163 def testMissingOption(self): 

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

165 fails. 

166 """ 

167 

168 @click.command() 

169 @opt.pipeline_build_options() 

170 def cli(**kwargs): 

171 script.qgraph(**kwargs) 

172 

173 runner = click.testing.CliRunner() 

174 result = runner.invoke(cli) 

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

176 # than are defined by pipeline_build_options. 

177 self.assertNotEqual(result.exit_code, 0) 

178 

179 

180class RunTestCase(unittest.TestCase): 

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

182 

183 def testMissingOption(self): 

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

185 fails. 

186 """ 

187 

188 @click.command() 

189 @opt.pipeline_build_options() 

190 def cli(**kwargs): 

191 script.run(**kwargs) 

192 

193 runner = click.testing.CliRunner() 

194 result = runner.invoke(cli) 

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

196 # than are defined by pipeline_build_options. 

197 self.assertNotEqual(result.exit_code, 0) 

198 

199 

200if __name__ == "__main__": 

201 lsst.utils.tests.init() 

202 unittest.main()