Coverage for tests/test_cliScript.py: 29%

72 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2023-01-13 02:55 -0800

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 @staticmethod 

40 def buildArgs(**kwargs): 

41 defaultArgs = dict( 

42 log_level=(), 

43 order_pipeline=False, 

44 pipeline=None, 

45 pipeline_actions=(), 

46 pipeline_dot=None, 

47 save_pipeline=None, 

48 show=ShowInfo([]), 

49 ) 

50 defaultArgs.update(kwargs) 

51 return defaultArgs 

52 

53 def testMakeEmptyPipeline(self): 

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

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

56 self.assertIsInstance(pipeline, Pipeline) 

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

58 

59 def testSavePipeline(self): 

60 """Test pipeline serialization.""" 

61 with tempfile.TemporaryDirectory() as tempdir: 

62 # make empty pipeline and store it in a file 

63 filename = os.path.join(tempdir, "pipeline") 

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

65 self.assertIsInstance(pipeline, Pipeline) 

66 

67 # read pipeline from a file 

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

69 self.assertIsInstance(pipeline, Pipeline) 

70 self.assertIsInstance(pipeline, Pipeline) 

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

72 

73 def testShowPipeline(self): 

74 """Test showing the pipeline.""" 

75 

76 class ShowInfoCmp: 

77 def __init__(self, show, expectedOutput): 

78 self.show = show 

79 self.expectedOutput = expectedOutput 

80 

81 def __repr__(self): 

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

83 

84 testdata = [ 

85 ShowInfoCmp( 

86 "pipeline", 

87 """description: anonymous 

88tasks: 

89 task: 

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

91 config: 

92 - addend: '100'""", 

93 ), 

94 ShowInfoCmp( 

95 "config", 

96 """### Configuration for task `task' 

97# Flag to enable/disable metadata saving for a task, enabled by default. 

98config.saveMetadata=True 

99 

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

101config.saveLogOutput=True 

102 

103# amount to add 

104config.addend=100 

105 

106# name for connection input 

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

108 

109# name for connection output 

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

111 

112# name for connection output2 

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

114 

115# name for connection initout 

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

117 

118# Template parameter used to format corresponding field template parameter 

119config.connections.in_tmpl='_in' 

120 

121# Template parameter used to format corresponding field template parameter 

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

123 ), 

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

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

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

127 ] 

128 

129 for showInfo in testdata: 

130 runner = LogCliRunner() 

131 result = runner.invoke( 

132 pipetaskCli, 

133 [ 

134 "build", 

135 "--task", 

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

137 "--config", 

138 "task:addend=100", 

139 "--show", 

140 showInfo.show, 

141 ], 

142 ) 

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

144 if showInfo.expectedOutput is not None: 

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

146 

147 def testMissingOption(self): 

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

149 

150 @click.command() 

151 @opt.pipeline_build_options() 

152 def cli(**kwargs): 

153 script.build(**kwargs) 

154 

155 runner = click.testing.CliRunner() 

156 result = runner.invoke(cli) 

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

158 # than are defined by pipeline_build_options. 

159 self.assertNotEqual(result.exit_code, 0) 

160 

161 

162class QgraphTestCase(unittest.TestCase): 

163 def testMissingOption(self): 

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

165 fails.""" 

166 

167 @click.command() 

168 @opt.pipeline_build_options() 

169 def cli(**kwargs): 

170 script.qgraph(**kwargs) 

171 

172 runner = click.testing.CliRunner() 

173 result = runner.invoke(cli) 

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

175 # than are defined by pipeline_build_options. 

176 self.assertNotEqual(result.exit_code, 0) 

177 

178 

179class RunTestCase(unittest.TestCase): 

180 def testMissingOption(self): 

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

182 fails.""" 

183 

184 @click.command() 

185 @opt.pipeline_build_options() 

186 def cli(**kwargs): 

187 script.run(**kwargs) 

188 

189 runner = click.testing.CliRunner() 

190 result = runner.invoke(cli) 

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

192 # than are defined by pipeline_build_options. 

193 self.assertNotEqual(result.exit_code, 0) 

194 

195 

196if __name__ == "__main__": 196 ↛ 197line 196 didn't jump to line 197, because the condition on line 196 was never true

197 lsst.utils.tests.init() 

198 unittest.main()