Merge lp:~stylesen/lava-scheduler/multinode into lp:lava-scheduler/multinode

Proposed by Senthil Kumaran S
Status: Merged
Approved by: Stevan Radaković
Approved revision: no longer in the source branch.
Merged at revision: 264
Proposed branch: lp:~stylesen/lava-scheduler/multinode
Merge into: lp:lava-scheduler/multinode
Diff against target: 104 lines (+41/-14)
2 files modified
lava_scheduler_app/api.py (+3/-14)
lava_scheduler_app/models.py (+38/-0)
To merge this branch: bzr merge lp:~stylesen/lava-scheduler/multinode
Reviewer Review Type Date Requested Status
Stevan Radaković Approve
Linaro Automation & Validation Pending
Review via email: mp+175729@code.launchpad.net

Description of the change

Check device availability during job submission, irrespective of what mode in which the job gets submitted.

To post a comment you must log in.
Revision history for this message
Stevan Radaković (stevanr) wrote :

Hey Senthil, looking good.

Couple of propositions:

29 + except Exception as e:
30 + raise xmlrpclib.Fault(400, str(e))

I'd really like it better if we had a specialized exception for this one, using generic exception for special kind of problem is not really a good idea (something else goes wrong, or some uncaught exception is thrown, someone may thing there was not enough devices and this wasn't the case). So introducing something like DevicesUnavailableException would be good.

42 +def check_device_availability(json_data):
43 + """Checks whether the number of devices requested in job json is
44 + available.
45 +
46 + Returns True if the requested number of devices are available, else
47 + raises an Exception.
48 + """
49 + requested_devices = utils.requested_device_count(json_data)

Increasing re-usability of methods is always a good idea, so it would be better that this one actually takes the requested_devices as an argument, and actually parse the json_data from the api call (someone who needs this method coming from not api side will not be able to pass json_data etc..)

review: Needs Fixing (code)
Revision history for this message
Senthil Kumaran S (stylesen) wrote :

Hi Stevan,

Thanks for the review.

On Friday 19 July 2013 03:01 PM, Stevan Radaković wrote:
> Couple of propositions:
>
> 29 + except Exception as e:
> 30 + raise xmlrpclib.Fault(400, str(e))
>
> I'd really like it better if we had a specialized exception for this one, using generic exception for special kind of problem is not really a good idea (something else goes wrong, or some uncaught exception is thrown, someone may thing there was not enough devices and this wasn't the case). So introducing something like DevicesUnavailableException would be good.

I fixed this.

> 42 +def check_device_availability(json_data):
> 43 + """Checks whether the number of devices requested in job json is
> 44 + available.
> 45 +
> 46 + Returns True if the requested number of devices are available, else
> 47 + raises an Exception.
> 48 + """
> 49 + requested_devices = utils.requested_device_count(json_data)
>
> Increasing re-usability of methods is always a good idea, so it would be better that this one actually takes the requested_devices as an argument, and actually parse the json_data from the api call (someone who needs this method coming from not api side will not be able to pass json_data etc..)

This is fixed.

I request your to review the latest changes in this MP.

Thank You.
--
Senthil Kumaran
http://www.stylesen.org/
http://www.sasenthilkumaran.com/

Revision history for this message
Stevan Radaković (stevanr) wrote :

Great work.
Thanks

Approve +1

review: Approve
264. By Senthil Kumaran S

Merge changes for improved device unavailability warning.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lava_scheduler_app/api.py'
2--- lava_scheduler_app/api.py 2013-07-03 07:49:32 +0000
3+++ lava_scheduler_app/api.py 2013-07-22 09:37:29 +0000
4@@ -7,6 +7,7 @@
5 Device,
6 DeviceType,
7 JSONDataError,
8+ DevicesUnavailableException,
9 TestJob,
10 )
11 from lava_scheduler_app.views import (
12@@ -28,20 +29,6 @@
13 "'lava_scheduler_app.add_testjob' permission. Contact "
14 "the administrators." % self.user.username)
15 try:
16- requested_devices = utils.requested_device_count(job_data)
17- if requested_devices:
18- all_devices = {}
19- for d in self.all_device_types():
20- all_devices[d['name']] = d['idle'] + d['busy']
21-
22- for board, count in requested_devices.iteritems():
23- if all_devices.get(board, None) and \
24- count <= all_devices[board]:
25- continue
26- else:
27- raise xmlrpclib.Fault(
28- 400, "Required number of device(s) unavailable.")
29-
30 job = TestJob.from_json_and_user(job_data, self.user)
31 except JSONDecodeError as e:
32 raise xmlrpclib.Fault(400, "Decoding JSON failed: %s." % e)
33@@ -51,6 +38,8 @@
34 raise xmlrpclib.Fault(404, "Specified device not found.")
35 except DeviceType.DoesNotExist:
36 raise xmlrpclib.Fault(404, "Specified device type not found.")
37+ except DevicesUnavailableException as e:
38+ raise xmlrpclib.Fault(400, str(e))
39 if isinstance(job, type(list())):
40 return job
41 else:
42
43=== modified file 'lava_scheduler_app/models.py'
44--- lava_scheduler_app/models.py 2013-07-04 05:22:29 +0000
45+++ lava_scheduler_app/models.py 2013-07-22 09:37:29 +0000
46@@ -29,6 +29,10 @@
47 """Error raised when JSON is syntactically valid but ill-formed."""
48
49
50+class DevicesUnavailableException(UserWarning):
51+ """Error raised when required number of devices are unavailable."""
52+
53+
54 class Tag(models.Model):
55
56 name = models.SlugField(unique=True)
57@@ -47,6 +51,38 @@
58 raise ValidationError(e)
59
60
61+def check_device_availability(requested_devices):
62+ """Checks whether the number of devices requested is available.
63+
64+ See utils.requested_device_count() for details of REQUESTED_DEVICES
65+ dictionary format.
66+
67+ Returns True if the requested number of devices are available, else
68+ raises DevicesUnavailableException.
69+ """
70+ device_types = DeviceType.objects.values_list('name').filter(
71+ models.Q(device__status=Device.IDLE) | \
72+ models.Q(device__status=Device.RUNNING)
73+ ).annotate(
74+ num_count=models.Count('name')
75+ ).order_by('name')
76+
77+ if requested_devices:
78+ all_devices = {}
79+ for dt in device_types:
80+ # dt[0] -> device type name
81+ # dt[1] -> device type count
82+ all_devices[dt[0]] = dt[1]
83+
84+ for board, count in requested_devices.iteritems():
85+ if all_devices.get(board, None) and count <= all_devices[board]:
86+ continue
87+ else:
88+ raise DevicesUnavailableException(
89+ "Required number of device(s) unavailable.")
90+ return True
91+
92+
93 class DeviceType(models.Model):
94 """
95 A class of device, for example a pandaboard or a snowball.
96@@ -407,6 +443,8 @@
97
98 @classmethod
99 def from_json_and_user(cls, json_data, user, health_check=False):
100+ requested_devices = utils.requested_device_count(json_data)
101+ check_device_availability(requested_devices)
102 job_data = simplejson.loads(json_data)
103 validate_job_data(job_data)
104 if 'target' in job_data:

Subscribers

People subscribed via source and target branches

to status/vote changes: