Revision c2d22fed lib/client/gnt_debug.py
b/lib/client/gnt_debug.py | ||
---|---|---|
37 | 37 |
from ganeti import utils |
38 | 38 |
from ganeti import errors |
39 | 39 |
from ganeti import compat |
40 |
from ganeti import ht |
|
40 | 41 |
|
41 | 42 |
|
42 | 43 |
#: Default fields for L{ListLocks} |
... | ... | |
180 | 181 |
return 0 |
181 | 182 |
|
182 | 183 |
|
184 |
def _TestJobDependency(opts): |
|
185 |
"""Tests job dependencies. |
|
186 |
|
|
187 |
""" |
|
188 |
ToStdout("Testing job dependencies") |
|
189 |
|
|
190 |
cl = cli.GetClient() |
|
191 |
|
|
192 |
try: |
|
193 |
SubmitOpCode(opcodes.OpTestDelay(duration=0, depends=[(-1, None)]), cl=cl) |
|
194 |
except errors.GenericError, err: |
|
195 |
if opts.debug: |
|
196 |
ToStdout("Ignoring error: %s", err) |
|
197 |
else: |
|
198 |
raise errors.OpExecError("Submitting plain opcode with relative job ID" |
|
199 |
" did not fail as expected") |
|
200 |
|
|
201 |
# TODO: Test dependencies on errors |
|
202 |
jobs = [ |
|
203 |
[opcodes.OpTestDelay(duration=1)], |
|
204 |
[opcodes.OpTestDelay(duration=1, |
|
205 |
depends=[(-1, [])])], |
|
206 |
[opcodes.OpTestDelay(duration=1, |
|
207 |
depends=[(-2, [constants.JOB_STATUS_SUCCESS])])], |
|
208 |
[opcodes.OpTestDelay(duration=1, |
|
209 |
depends=[])], |
|
210 |
[opcodes.OpTestDelay(duration=1, |
|
211 |
depends=[(-2, [constants.JOB_STATUS_SUCCESS])])], |
|
212 |
] |
|
213 |
|
|
214 |
# Function for checking result |
|
215 |
check_fn = ht.TListOf(ht.TAnd(ht.TIsLength(2), |
|
216 |
ht.TItems([ht.TBool, |
|
217 |
ht.TOr(ht.TNonEmptyString, |
|
218 |
ht.TJobId)]))) |
|
219 |
|
|
220 |
result = cl.SubmitManyJobs(jobs) |
|
221 |
if not check_fn(result): |
|
222 |
raise errors.OpExecError("Job submission doesn't match %s: %s" % |
|
223 |
(check_fn, result)) |
|
224 |
|
|
225 |
# Wait for jobs to finish |
|
226 |
jex = JobExecutor(cl=cl, opts=opts) |
|
227 |
|
|
228 |
for (status, job_id) in result: |
|
229 |
jex.AddJobId(None, status, job_id) |
|
230 |
|
|
231 |
job_results = jex.GetResults() |
|
232 |
if not compat.all(row[0] for row in job_results): |
|
233 |
raise errors.OpExecError("At least one of the submitted jobs failed: %s" % |
|
234 |
job_results) |
|
235 |
|
|
236 |
# Get details about jobs |
|
237 |
data = cl.QueryJobs([job_id for (_, job_id) in result], |
|
238 |
["id", "opexec", "ops"]) |
|
239 |
data_job_id = [job_id for (job_id, _, _) in data] |
|
240 |
data_opexec = [opexec for (_, opexec, _) in data] |
|
241 |
data_op = [[opcodes.OpCode.LoadOpCode(op) for op in ops] |
|
242 |
for (_, _, ops) in data] |
|
243 |
|
|
244 |
assert compat.all(not op.depends or len(op.depends) == 1 |
|
245 |
for ops in data_op |
|
246 |
for op in ops) |
|
247 |
|
|
248 |
# Check resolved job IDs in dependencies |
|
249 |
for (job_idx, res_jobdep) in [(1, data_job_id[0]), |
|
250 |
(2, data_job_id[0]), |
|
251 |
(4, data_job_id[2])]: |
|
252 |
if data_op[job_idx][0].depends[0][0] != res_jobdep: |
|
253 |
raise errors.OpExecError("Job %s's opcode doesn't depend on correct job" |
|
254 |
" ID (%s)" % (job_idx, res_jobdep)) |
|
255 |
|
|
256 |
# Check execution order |
|
257 |
if not (data_opexec[0] <= data_opexec[1] and |
|
258 |
data_opexec[0] <= data_opexec[2] and |
|
259 |
data_opexec[2] <= data_opexec[4]): |
|
260 |
raise errors.OpExecError("Jobs did not run in correct order: %s" % data) |
|
261 |
|
|
262 |
assert len(jobs) == 5 and compat.all(len(ops) == 1 for ops in jobs) |
|
263 |
|
|
264 |
ToStdout("Job dependency tests were successful") |
|
265 |
|
|
266 |
|
|
183 | 267 |
def _TestJobSubmission(opts): |
184 | 268 |
"""Tests submitting jobs. |
185 | 269 |
|
... | ... | |
340 | 424 |
|
341 | 425 |
""" |
342 | 426 |
_TestJobSubmission(opts) |
427 |
_TestJobDependency(opts) |
|
343 | 428 |
|
344 | 429 |
(TM_SUCCESS, |
345 | 430 |
TM_MULTISUCCESS, |
Also available in: Unified diff