Coverage for tests/test_generic_workflow.py: 13%

195 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2023-02-07 02:51 -0800

1# This file is part of ctrl_bps. 

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

21import io 

22import unittest 

23from collections import Counter 

24 

25import lsst.ctrl.bps.generic_workflow as gw 

26import networkx 

27import networkx.algorithms.isomorphism as iso 

28 

29 

30class TestGenericWorkflowJob(unittest.TestCase): 

31 def testEquality(self): 

32 job1 = gw.GenericWorkflowJob("job1") 

33 job2 = gw.GenericWorkflowJob("job1") 

34 self.assertEqual(job1, job2) 

35 

36 

37class TestGenericWorkflow(unittest.TestCase): 

38 def testAddJobDuplicate(self): 

39 job1 = gw.GenericWorkflowJob("job1") 

40 gwf = gw.GenericWorkflow("mytest") 

41 gwf.add_job(job1) 

42 with self.assertRaises(RuntimeError): 

43 gwf.add_job(job1) 

44 

45 def testAddJobValid(self): 

46 job1 = gw.GenericWorkflowJob("job1") 

47 gwf = gw.GenericWorkflow("mytest") 

48 gwf.add_job(job1) 

49 self.assertEqual(1, gwf.number_of_nodes()) 

50 self.assertListEqual(["job1"], list(gwf)) 

51 getjob = gwf.get_job("job1") 

52 self.assertEqual(job1, getjob) 

53 

54 def testAddJobRelationshipsSingle(self): 

55 job1 = gw.GenericWorkflowJob("job1") 

56 job2 = gw.GenericWorkflowJob("job2") 

57 gwf = gw.GenericWorkflow("mytest") 

58 gwf.add_job(job1) 

59 gwf.add_job(job2) 

60 gwf.add_job_relationships("job1", "job2") 

61 self.assertListEqual([("job1", "job2")], list(gwf.edges())) 

62 

63 def testAddJobRelationshipsMultiChild(self): 

64 job1 = gw.GenericWorkflowJob("job1") 

65 job2 = gw.GenericWorkflowJob("job2") 

66 job3 = gw.GenericWorkflowJob("job3") 

67 gwf = gw.GenericWorkflow("mytest") 

68 gwf.add_job(job1) 

69 gwf.add_job(job2) 

70 gwf.add_job(job3) 

71 gwf.add_job_relationships("job1", ["job2", "job3"]) 

72 self.assertListEqual([("job1", "job2"), ("job1", "job3")], list(gwf.edges())) 

73 

74 def testAddJobRelationshipsMultiParents(self): 

75 job1 = gw.GenericWorkflowJob("job1") 

76 job2 = gw.GenericWorkflowJob("job2") 

77 job3 = gw.GenericWorkflowJob("job3") 

78 gwf = gw.GenericWorkflow("mytest") 

79 gwf.add_job(job1) 

80 gwf.add_job(job2) 

81 gwf.add_job(job3) 

82 gwf.add_job_relationships(["job1", "job2"], "job3") 

83 self.assertListEqual([("job1", "job3"), ("job2", "job3")], list(gwf.edges())) 

84 

85 def testAddJobRelationshipsNone(self): 

86 job1 = gw.GenericWorkflowJob("job1") 

87 gwf = gw.GenericWorkflow("mytest") 

88 gwf.add_job(job1) 

89 gwf.add_job_relationships(None, "job1") 

90 self.assertListEqual([], list(gwf.edges())) 

91 gwf.add_job_relationships("job1", None) 

92 self.assertListEqual([], list(gwf.edges())) 

93 

94 def testGetJobExists(self): 

95 job1 = gw.GenericWorkflowJob("job1") 

96 gwf = gw.GenericWorkflow("mytest") 

97 gwf.add_job(job1) 

98 job2 = gwf.get_job("job1") 

99 self.assertIs(job1, job2) 

100 

101 def testGetJobError(self): 

102 job1 = gw.GenericWorkflowJob("job1") 

103 gwf = gw.GenericWorkflow("mytest") 

104 gwf.add_job(job1) 

105 with self.assertRaises(KeyError): 

106 _ = gwf.get_job("job_not_there") 

107 

108 def testSaveInvalidFormat(self): 

109 gwf = gw.GenericWorkflow("mytest") 

110 stream = io.BytesIO() 

111 with self.assertRaises(RuntimeError): 

112 gwf.save(stream, "badformat") 

113 

114 def testSavePickle(self): 

115 gwf = gw.GenericWorkflow("mytest") 

116 job1 = gw.GenericWorkflowJob("job1") 

117 job2 = gw.GenericWorkflowJob("job2") 

118 gwf.add_job(job1) 

119 gwf.add_job(job2) 

120 gwf.add_job_relationships("job1", "job2") 

121 stream = io.BytesIO() 

122 gwf.save(stream, "pickle") 

123 stream.seek(0) 

124 gwf2 = gw.GenericWorkflow.load(stream, "pickle") 

125 self.assertTrue( 

126 networkx.is_isomorphic(gwf, gwf2, node_match=iso.categorical_node_match("data", None)) 

127 ) 

128 

129 def testLabels(self): 

130 job1 = gw.GenericWorkflowJob("job1") 

131 job1.label = "label1" 

132 job2 = gw.GenericWorkflowJob("job2") 

133 job2.label = "label1" 

134 job3 = gw.GenericWorkflowJob("job3") 

135 job3.label = "label2" 

136 gwf = gw.GenericWorkflow("mytest") 

137 gwf.add_job(job1) 

138 gwf.add_job(job2) 

139 gwf.add_job(job3) 

140 gwf.add_job_relationships(["job1", "job2"], "job3") 

141 self.assertListEqual(["label1", "label2"], gwf.labels) 

142 

143 def testRegenerateLabels(self): 

144 job1 = gw.GenericWorkflowJob("job1") 

145 job1.label = "label1" 

146 job2 = gw.GenericWorkflowJob("job2") 

147 job2.label = "label1" 

148 job3 = gw.GenericWorkflowJob("job3") 

149 job3.label = "label2" 

150 gwf = gw.GenericWorkflow("mytest") 

151 gwf.add_job(job1) 

152 gwf.add_job(job2) 

153 gwf.add_job(job3) 

154 gwf.add_job_relationships(["job1", "job2"], "job3") 

155 job1.label = "label1b" 

156 job2.label = "label1b" 

157 job3.label = "label2b" 

158 gwf.regenerate_labels() 

159 self.assertListEqual(["label1b", "label2b"], gwf.labels) 

160 

161 def testJobCounts(self): 

162 job1 = gw.GenericWorkflowJob("job1") 

163 job1.label = "label1" 

164 job2 = gw.GenericWorkflowJob("job2") 

165 job2.label = "label1" 

166 job3 = gw.GenericWorkflowJob("job3") 

167 job3.label = "label2" 

168 gwf = gw.GenericWorkflow("mytest") 

169 gwf.add_job(job1) 

170 gwf.add_job(job2) 

171 gwf.add_job(job3) 

172 gwf.add_job_relationships(["job1", "job2"], "job3") 

173 self.assertEqual(Counter({"label1": 2, "label2": 1}), gwf.job_counts) 

174 

175 def testDelJob(self): 

176 job1 = gw.GenericWorkflowJob("job1") 

177 job1.label = "label1" 

178 job2 = gw.GenericWorkflowJob("job2") 

179 job2.label = "label1" 

180 job3 = gw.GenericWorkflowJob("job3") 

181 job3.label = "label2" 

182 gwf = gw.GenericWorkflow("mytest") 

183 gwf.add_job(job1) 

184 gwf.add_job(job2) 

185 gwf.add_job(job3) 

186 gwf.add_job_relationships(["job1", "job2"], "job3") 

187 

188 gwf.del_job("job2") 

189 

190 self.assertListEqual([("job1", "job3")], list(gwf.edges())) 

191 self.assertEqual(Counter({"label1": 1, "label2": 1}), gwf.job_counts) 

192 

193 def testAddWorkflowSource(self): 

194 job1 = gw.GenericWorkflowJob("job1") 

195 job1.label = "label1" 

196 job2 = gw.GenericWorkflowJob("job2") 

197 job2.label = "label1" 

198 job3 = gw.GenericWorkflowJob("job3") 

199 job3.label = "label2" 

200 gwf = gw.GenericWorkflow("mytest") 

201 gwf.add_job(job1) 

202 gwf.add_job(job2) 

203 gwf.add_job(job3) 

204 gwf.add_job_relationships(["job1", "job2"], "job3") 

205 

206 srcjob1 = gw.GenericWorkflowJob("srcjob1") 

207 srcjob1.label = "srclabel1" 

208 srcjob2 = gw.GenericWorkflowJob("srcjob2") 

209 srcjob2.label = "srclabel1" 

210 srcjob3 = gw.GenericWorkflowJob("srcjob3") 

211 srcjob3.label = "srclabel2" 

212 srcjob4 = gw.GenericWorkflowJob("srcjob4") 

213 srcjob4.label = "srclabel2" 

214 gwf2 = gw.GenericWorkflow("mytest2") 

215 gwf2.add_job(srcjob1) 

216 gwf2.add_job(srcjob2) 

217 gwf2.add_job(srcjob3) 

218 gwf2.add_job(srcjob4) 

219 gwf2.add_job_relationships("srcjob1", "srcjob3") 

220 gwf2.add_job_relationships("srcjob2", "srcjob4") 

221 

222 gwf.add_workflow_source(gwf2) 

223 

224 self.assertEqual(Counter({"srclabel1": 2, "srclabel2": 2, "label1": 2, "label2": 1}), gwf.job_counts) 

225 self.assertListEqual(["srclabel1", "srclabel2", "label1", "label2"], gwf.labels) 

226 self.assertListEqual( 

227 sorted( 

228 [ 

229 ("srcjob1", "srcjob3"), 

230 ("srcjob2", "srcjob4"), 

231 ("srcjob3", "job1"), 

232 ("srcjob3", "job2"), 

233 ("srcjob4", "job1"), 

234 ("srcjob4", "job2"), 

235 ("job1", "job3"), 

236 ("job2", "job3"), 

237 ] 

238 ), 

239 sorted(list(gwf.edges())), 

240 ) 

241 

242 def testGetJobsByLabel(self): 

243 job1 = gw.GenericWorkflowJob("job1") 

244 job1.label = "label1" 

245 job2 = gw.GenericWorkflowJob("job2") 

246 job2.label = "label1" 

247 job3 = gw.GenericWorkflowJob("job3") 

248 job3.label = "label2" 

249 gwf = gw.GenericWorkflow("mytest") 

250 gwf.add_job(job1) 

251 gwf.add_job(job2) 

252 gwf.add_job(job3) 

253 gwf.add_job_relationships(["job1", "job2"], "job3") 

254 

255 self.assertListEqual([job3], gwf.get_jobs_by_label("label2")) 

256 

257 

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

259 unittest.main()