Coverage for tests/test_generic_workflow.py: 13%
195 statements
« prev ^ index » next coverage.py v6.5.0, created at 2023-02-15 02:49 -0800
« prev ^ index » next coverage.py v6.5.0, created at 2023-02-15 02:49 -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
25import lsst.ctrl.bps.generic_workflow as gw
26import networkx
27import networkx.algorithms.isomorphism as iso
30class TestGenericWorkflowJob(unittest.TestCase):
31 def testEquality(self):
32 job1 = gw.GenericWorkflowJob("job1")
33 job2 = gw.GenericWorkflowJob("job1")
34 self.assertEqual(job1, job2)
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)
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)
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()))
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()))
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()))
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()))
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)
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")
108 def testSaveInvalidFormat(self):
109 gwf = gw.GenericWorkflow("mytest")
110 stream = io.BytesIO()
111 with self.assertRaises(RuntimeError):
112 gwf.save(stream, "badformat")
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 )
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)
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)
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)
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")
188 gwf.del_job("job2")
190 self.assertListEqual([("job1", "job3")], list(gwf.edges()))
191 self.assertEqual(Counter({"label1": 1, "label2": 1}), gwf.job_counts)
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")
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")
222 gwf.add_workflow_source(gwf2)
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 )
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")
255 self.assertListEqual([job3], gwf.get_jobs_by_label("label2"))
258if __name__ == "__main__": 258 ↛ 259line 258 didn't jump to line 259, because the condition on line 258 was never true
259 unittest.main()