Merge lp:~doanac/uci-engine/pub-pause into lp:uci-engine

Proposed by Andy Doan
Status: Needs review
Proposed branch: lp:~doanac/uci-engine/pub-pause
Merge into: lp:uci-engine
Diff against target: 126 lines (+70/-1)
5 files modified
ci-utils/ci_utils/amqp_utils.py (+13/-0)
lander/bin/lander_process_ticket.py (+5/-0)
lander/bin/lander_service_wrapper.py (+1/-1)
lander/lander/tests/test_process_ticket.py (+19/-0)
lander/lander/tests/test_service_wrapper.py (+32/-0)
To merge this branch: bzr merge lp:~doanac/uci-engine/pub-pause
Reviewer Review Type Date Requested Status
Francis Ginther Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+223414@code.launchpad.net

Commit message

lander: allow a worker to request a 'retry'

Workers like the publisher need to mark a ticket step as needing
to be retried. This adds a function, amqp_utils.progress_retry. When
called by a worker, the lander will pause the ticket and wait until
the ticket is updated to "resume". At this point the lander will resume
execution at this step and see if it can progress

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:589
http://s-jenkins.ubuntu-ci:8080/job/uci-engine-ci/878/
Executed test runs:

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/uci-engine-ci/878/rebuild

review: Approve (continuous-integration)
Revision history for this message
Ursula Junque (ursinha) wrote :

Hi Andy,

I've asked some questions on IRC a while ago but I think they got lost -- I should've asked them here, sorry about that.

Revision history for this message
Joe Talbott (joetalbott) wrote :

This looks okay to me code-wise. I'll leave this MP to you and Ursula to sort out as far as her comments are concerned.

Revision history for this message
Andy Doan (doanac) wrote :

I've responded to Ursula. I'd say we keep it the way I have it, but I'll let you guys decide.

Revision history for this message
Francis Ginther (fginther) wrote :

I think this does what it's intended to do (and there are unit tests to match). The progress_retry() isn't being used anywhere, so this shouldn't regress anything.

Only question is if the name 'progress_retry' was meant to be named 'progress_pause'?

I'll approve as we really can't do much more with it until something else is in place to exercise it.

review: Approve
Revision history for this message
Andy Doan (doanac) wrote :

On Thu, Jul 17, 2014 at 10:32 PM, Francis Ginther <
<email address hidden>> wrote:

> > +def progress_retry(progress_trigger, data=None):
> > + '''Let the engine know the ticket should be paused and retried
> after some
> > + manual acknowledgement has taken place
> > + '''
> > + if data is None:
> > + data = {}
> > + data['state'] = 'RETRY'
>
> It sounds a bit odd to have this method called 'progress_retry' when the
> outcome is to pause the workflow. I think this is what Ursula is pointing
> out.
>

Ah - i get it now. So "retry" in this since is still a manual thing that
takes advantage of our internal "pause" support. ie - the way the step
would get repeated would be for some interaction that puts the ticket
status into "continue"

Unmerged revisions

589. By Andy Doan

lander: allow a worker to request a 'retry'

Workers like the publisher need to mark a ticket step as needing
to be retried. This adds a function, amqp_utils.progress_retry. When
called by a worker, the lander will pause the ticket and wait until
the ticket is updated to "resume". At this point the lander will resume
execution at this step and see if it can progress

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'ci-utils/ci_utils/amqp_utils.py'
--- ci-utils/ci_utils/amqp_utils.py 2014-06-16 13:18:53 +0000
+++ ci-utils/ci_utils/amqp_utils.py 2014-06-17 14:51:54 +0000
@@ -199,3 +199,16 @@
199 data['result'] = 'FAILED'199 data['result'] = 'FAILED'
200 data['exit'] = True200 data['exit'] = True
201 return send(progress_trigger, json.dumps(data))201 return send(progress_trigger, json.dumps(data))
202
203
204def progress_retry(progress_trigger, data=None):
205 '''Let the engine know the ticket should be paused and retried after some
206 manual acknowledgement has taken place
207 '''
208 if data is None:
209 data = {}
210 data['state'] = 'RETRY'
211 data['result'] = 'PASSED'
212 data['pause'] = {}
213 data['exit'] = True
214 return send(progress_trigger, json.dumps(data))
202215
=== modified file 'lander/bin/lander_process_ticket.py'
--- lander/bin/lander_process_ticket.py 2014-06-16 13:18:53 +0000
+++ lander/bin/lander_process_ticket.py 2014-06-17 14:51:54 +0000
@@ -34,6 +34,11 @@
34 rc = subprocess.call(34 rc = subprocess.call(
35 [cmd, '--service', step['name'], '--results-file', results_file])35 [cmd, '--service', step['name'], '--results-file', results_file])
36 logger.debug('Step completed with rc=%d', rc)36 logger.debug('Step completed with rc=%d', rc)
37
38 # load the result to see if the step requested a "retry", which means
39 # we are basically pausing this step
40 wflow = workflow.load(results_file)
41 _handle_pause(results_file, wflow, wflow.get_step(step['name']))
37 return rc42 return rc
3843
3944
4045
=== modified file 'lander/bin/lander_service_wrapper.py'
--- lander/bin/lander_service_wrapper.py 2014-06-11 19:16:37 +0000
+++ lander/bin/lander_service_wrapper.py 2014-06-17 14:51:54 +0000
@@ -68,7 +68,6 @@
68 if state == 'STATUS':68 if state == 'STATUS':
69 self.started_cb()69 self.started_cb()
70 elif state == 'COMPLETED':70 elif state == 'COMPLETED':
71 self.ticket.process_artifacts(data)
72 if data['result'] == 'PASSED':71 if data['result'] == 'PASSED':
73 self.completed_cb(True)72 self.completed_cb(True)
74 else:73 else:
@@ -76,6 +75,7 @@
7675
77 msg.channel.basic_ack(msg.delivery_tag)76 msg.channel.basic_ack(msg.delivery_tag)
78 if data.get('exit'):77 if data.get('exit'):
78 self.ticket.process_artifacts(data)
79 self.data = data79 self.data = data
80 # this will kick us out of the run-forever worker loop80 # this will kick us out of the run-forever worker loop
81 msg.channel.basic_cancel(msg.consumer_tag)81 msg.channel.basic_cancel(msg.consumer_tag)
8282
=== modified file 'lander/lander/tests/test_process_ticket.py'
--- lander/lander/tests/test_process_ticket.py 2014-06-10 16:21:15 +0000
+++ lander/lander/tests/test_process_ticket.py 2014-06-17 14:51:54 +0000
@@ -116,3 +116,22 @@
116 lander_process_ticket.main(args)116 lander_process_ticket.main(args)
117 self.assertEqual(1, do_step.call_count)117 self.assertEqual(1, do_step.call_count)
118 self.assertEqual(1, ticket_api.TicketApi().pause_ticket.call_count)118 self.assertEqual(1, ticket_api.TicketApi().pause_ticket.call_count)
119
120 @mock.patch('lander.ticket_api')
121 @mock.patch('subprocess.call')
122 def test_run_retry(self, subprocess, ticket_api):
123 subprocess.return_value = 0
124 data = {
125 'ticket_id': 10,
126 'ts_url': 'foo',
127 'steps': [
128 {'name': 'step1', 'pause': {}},
129 ],
130 }
131 wflow = workflow._Workflow(data)
132 with open(self.tmpfile, 'w') as f:
133 wflow.save(f)
134 with self.assertRaises(SystemExit):
135 step = wflow.get_step('step1')
136 lander_process_ticket._do_step(step, self.tmpfile)
137 self.assertEqual(1, ticket_api.TicketApi().pause_ticket.call_count)
119138
=== modified file 'lander/lander/tests/test_service_wrapper.py'
--- lander/lander/tests/test_service_wrapper.py 2014-06-10 16:21:15 +0000
+++ lander/lander/tests/test_service_wrapper.py 2014-06-17 14:51:54 +0000
@@ -432,6 +432,38 @@
432 self.assertEqual('FAILED', data['result'])432 self.assertEqual('FAILED', data['result'])
433 self.assertEqual(err_msg, data['error'])433 self.assertEqual(err_msg, data['error'])
434434
435 @mock.patch('lander.ticket_api.TicketApi')
436 @mock.patch('ci_utils.amqp_utils.send')
437 @mock.patch('ci_utils.amqp_utils.connection')
438 def testRunnerRetry(self, connection, send, api):
439 '''Ensure we generate the proper response if we get a retry msg.'''
440 api().get_full_ticket.return_value = {}
441 # mock the run-forever logic to ensure we return what we expect
442 state = {'state': 'RETRY', 'result': 'PASSED',
443 'foo': 'bar', 'exit': True, 'name': 'test_runner'}
444
445 def amqp():
446 def run_forever(channel, queue, callback):
447 m = mock.Mock()
448 m.body = json.dumps({'state': 'WAITING'})
449 callback(m)
450 m.body = json.dumps(state)
451 callback(m)
452 return run_forever
453
454 args = self.base_args + ['--service', 'test_runner']
455 args = lander_service_wrapper._get_parser().parse_args(args)
456
457 with mock.patch('ci_utils.amqp_utils._run_forever', new_callable=amqp):
458 rc = lander_service_wrapper.main(args)
459 self.assertEqual(0, rc)
460
461 api().set_testing_waiting.assert_called_once()
462 self.assertEqual(0, api().set_testing_complete.call_count)
463
464 data = lander.workflow.load(self.results).get_step('test_runner')
465 self.assertEqual(state, data)
466
435 @mock.patch('lander_service_wrapper._patch')467 @mock.patch('lander_service_wrapper._patch')
436 def testPPAFreeSucceeds(self, patch):468 def testPPAFreeSucceeds(self, patch):
437 '''ensure we can free a PPA'''469 '''ensure we can free a PPA'''

Subscribers

People subscribed via source and target branches