Coverage for tests/test_cliScript.py: 28%

69 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-06-09 02:48 -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 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 saving of log output for a task, enabled by default. 

98config.saveLogOutput=True 

99 

100# amount to add 

101config.addend=100 

102 

103# name for connection input 

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

105 

106# name for connection output 

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

108 

109# name for connection output2 

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

111 

112# name for connection initout 

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

114 

115# Template parameter used to format corresponding field template parameter 

116config.connections.in_tmpl='_in' 

117 

118# Template parameter used to format corresponding field template parameter 

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

120 ), 

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

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

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

124 ] 

125 

126 for showInfo in testdata: 

127 runner = LogCliRunner() 

128 result = runner.invoke( 

129 pipetaskCli, 

130 [ 

131 "build", 

132 "--task", 

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

134 "--config", 

135 "task:addend=100", 

136 "--show", 

137 showInfo.show, 

138 ], 

139 ) 

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

141 if showInfo.expectedOutput is not None: 

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

143 

144 def testMissingOption(self): 

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

146 

147 @click.command() 

148 @opt.pipeline_build_options() 

149 def cli(**kwargs): 

150 script.build(**kwargs) 

151 

152 runner = click.testing.CliRunner() 

153 result = runner.invoke(cli) 

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

155 # than are defined by pipeline_build_options. 

156 self.assertNotEqual(result.exit_code, 0) 

157 

158 

159class QgraphTestCase(unittest.TestCase): 

160 def testMissingOption(self): 

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

162 fails.""" 

163 

164 @click.command() 

165 @opt.pipeline_build_options() 

166 def cli(**kwargs): 

167 script.qgraph(**kwargs) 

168 

169 runner = click.testing.CliRunner() 

170 result = runner.invoke(cli) 

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

172 # than are defined by pipeline_build_options. 

173 self.assertNotEqual(result.exit_code, 0) 

174 

175 

176class RunTestCase(unittest.TestCase): 

177 def testMissingOption(self): 

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

179 fails.""" 

180 

181 @click.command() 

182 @opt.pipeline_build_options() 

183 def cli(**kwargs): 

184 script.run(**kwargs) 

185 

186 runner = click.testing.CliRunner() 

187 result = runner.invoke(cli) 

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

189 # than are defined by pipeline_build_options. 

190 self.assertNotEqual(result.exit_code, 0) 

191 

192 

193if __name__ == "__main__": 

194 lsst.utils.tests.init() 

195 unittest.main()