Merge lp:~vila/ubuntu-ci-services-itself/1292461-testbed-console-acquisition into lp:ubuntu-ci-services-itself

Proposed by Vincent Ladeuil
Status: Merged
Approved by: Vincent Ladeuil
Approved revision: 390
Merged at revision: 391
Proposed branch: lp:~vila/ubuntu-ci-services-itself/1292461-testbed-console-acquisition
Merge into: lp:ubuntu-ci-services-itself
Diff against target: 132 lines (+43/-20)
2 files modified
test_runner/tstrun/run_worker.py (+40/-18)
test_runner/tstrun/testbed.py (+3/-2)
To merge this branch: bzr merge lp:~vila/ubuntu-ci-services-itself/1292461-testbed-console-acquisition
Reviewer Review Type Date Requested Status
Andy Doan (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+211088@code.launchpad.net

Commit message

Better error handling when setting up the test bed.

Description of the change

This refactors the message handling for the test runner to better isolate the
failures during the testbed setup.

More details in the bug comment.

While I was there I added some more progress reports so we get a better idea
on how the time is spent during the request handling.

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

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

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

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

The handle_request method is starting to get a little complex, but lets deal with that post-phase0

review: Approve
Revision history for this message
Vincent Ladeuil (vila) wrote :

> The handle_request method is starting to get a little complex, but lets deal
> with that post-phase0

Yeah and requires a bit too much care, full agreement.

On the other hand, the plan AIUI is to make it handle even more...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'test_runner/tstrun/run_worker.py'
--- test_runner/tstrun/run_worker.py 2014-03-14 10:37:28 +0000
+++ test_runner/tstrun/run_worker.py 2014-03-14 16:30:25 +0000
@@ -28,31 +28,31 @@
28 super(TestRunnerWorker, self).__init__('test_runner')28 super(TestRunnerWorker, self).__init__('test_runner')
29 self.data_store = None29 self.data_store = None
3030
31 def save_subunit(self, log, package, stream, retval):31 def save_subunit(self, log, package, stream, results):
32 # make this exception-safe since we can already report pass/fail32 # make this exception-safe since we can already report pass/fail
33 # with or without this file33 # with or without this file
34 try:34 try:
35 log.info('saving subunit results for {}'.format(package))35 log.info('Saving subunit results for {}'.format(package))
36 name = 'test-runner.{}-subunit-stream'.format(package)36 name = 'test-runner.{}-subunit-stream'.format(package)
37 url = self.data_store.put_file(name, stream, 'text/plain')37 url = self.data_store.put_file(name, stream, 'text/plain')
38 retval.setdefault('artifacts', []).append({38 results.setdefault('artifacts', []).append({
39 'name': name,39 'name': name,
40 'reference': url,40 'reference': url,
41 'type': 'RESULTS',41 'type': 'RESULTS',
42 })42 })
43 except:43 except:
44 log.exception(44 log.exception(
45 'unable to upload subunit result for {}'.format(package))45 'Unable to upload subunit result for {}'.format(package))
4646
47 def save_testbed_console(self, log, test_bed, retval):47 def save_testbed_console(self, log, test_bed, results):
48 # make this exception-safe since we can already report pass/fail48 # make this exception-safe since we can already report pass/fail
49 # with or without this file49 # with or without this file
50 try:50 try:
51 log.info('saving testbed console}')51 log.info('Saving testbed console')
52 name = 'test-runner.testbed-cloud-init.log'52 name = 'test-runner.testbed-cloud-init.log'
53 console = test_bed.get_cloud_init_console()53 console = test_bed.get_cloud_init_console()
54 url = self.data_store.put_file(name, console, 'text/plain')54 url = self.data_store.put_file(name, console, 'text/plain')
55 retval.setdefault('artifacts', []).append({55 results.setdefault('artifacts', []).append({
56 'name': name,56 'name': name,
57 'reference': url,57 'reference': url,
58 'type': 'LOGS',58 'type': 'LOGS',
@@ -61,29 +61,48 @@
61 log.exception('unable to upload testbed console')61 log.exception('unable to upload testbed console')
6262
63 def handle_request(self, log, params):63 def handle_request(self, log, params):
64 ticket_id = params['ticket_id']
64 progress_queue = params['progress_trigger']65 progress_queue = params['progress_trigger']
65 image_id = params['image_id']66 image_id = params['image_id']
66 package_list = params['package_list']67 package_list = params['package_list']
6768
69 results = {}
70
68 def status_cb(msg):71 def status_cb(msg):
69 log.info(msg)72 log.info(msg)
70 amqp_utils.progress_update(progress_queue, {'message': msg})73 amqp_utils.progress_update(progress_queue, {'message': msg})
7174
72 self.data_store = self._create_data_store(params['ticket_id'])75 self.data_store = self._create_data_store(ticket_id)
73 # The tests will succeed unless they fail ;)
74 notify = amqp_utils.progress_completed
75 results = {}
76 test_bed = None
77 flavors = tstrun.get_auth_config()['tr_flavors']
78 try:76 try:
77 status_cb('Setting up the testbed for ticket {}'.format(ticket_id))
78 flavors = tstrun.get_auth_config()['tr_flavors']
79 test_bed = testbed.TestBed('testbed-{}'.format(progress_queue),79 test_bed = testbed.TestBed('testbed-{}'.format(progress_queue),
80 flavors, image_id, status_cb)80 flavors, image_id, status_cb)
81 except:
82 log.exception(
83 'The testbed creation for {} failed'.format(ticket_id))
84 return amqp_utils.progress_failed, results
85
86 try:
81 test_bed.setup()87 test_bed.setup()
88 except:
89 log.exception(
90 'The testbed setup for {} failed'.format(ticket_id))
91 if test_bed.instance is not None:
92 self.save_testbed_console(log, test_bed, results)
93 test_bed.teardown()
94 return amqp_utils.progress_failed, results
95
96 status_cb('The test bed is ready')
97 # The tests will succeed unless they fail ;)
98 notify = amqp_utils.progress_completed
99 try:
82 for package in package_list:100 for package in package_list:
83 if params.get('cancelled'):101 if params.get('cancelled'):
84 log.error('request has been cancelled, exiting')102 log.error('The request for {} has been cancelled,'
103 ' exiting'.format(ticket_id))
85 return amqp_utils.progress_failed, results104 return amqp_utils.progress_failed, results
86 status_cb('testing %s' % package)105 status_cb('Testing {}'.format(package))
87 # uci-vms shell adt-run ... --- adt-virt-null106 # uci-vms shell adt-run ... --- adt-virt-null
88 return_code, subunit_stream = test_bed.run_test(package)107 return_code, subunit_stream = test_bed.run_test(package)
89 # 0 is success, 8 is skipped and considered a success108 # 0 is success, 8 is skipped and considered a success
@@ -91,11 +110,14 @@
91 # At least one test failed110 # At least one test failed
92 notify = amqp_utils.progress_failed111 notify = amqp_utils.progress_failed
93 self.save_subunit(log, package, subunit_stream, results)112 self.save_subunit(log, package, subunit_stream, results)
113 status_cb('Test completed for ticket {}'.format(ticket_id))
94 return notify, results114 return notify, results
115 except:
116 log.exception(
117 'Exception while handling ticket {}'.format(ticket_id))
118 raise
95 finally:119 finally:
96 if test_bed:120 test_bed.teardown()
97 self.save_testbed_console(log, test_bed, results)
98 test_bed.teardown()
99121
100122
101if __name__ == '__main__':123if __name__ == '__main__':
102124
=== modified file 'test_runner/tstrun/testbed.py'
--- test_runner/tstrun/testbed.py 2014-03-14 10:37:28 +0000
+++ test_runner/tstrun/testbed.py 2014-03-14 16:30:25 +0000
@@ -189,8 +189,9 @@
189 self.instance = self.nova.servers.create(189 self.instance = self.nova.servers.create(
190 name=self.name, flavor=flavor, image=image,190 name=self.name, flavor=flavor, image=image,
191 userdata=self.user_data, keypair=self.nova_ssh_key_name)191 userdata=self.user_data, keypair=self.nova_ssh_key_name)
192 # FIXME: This times out for hpcloud because it requires a floating ip192 # FIXME: This times out for hpcloud (when used for testing from dev
193 # for the instance see http://pad.lv/1288622 -- vila 2014-03-06193 # host) because it requires a floating ip for the instance see
194 # http://pad.lv/1288622 -- vila 2014-03-06
194 self.wait_for_ip()195 self.wait_for_ip()
195 self.wait_for_cloud_init()196 self.wait_for_cloud_init()
196197

Subscribers

People subscribed via source and target branches