blob: 0764272955fea63d335bb1242f3691e24a45c606 [file] [log] [blame]
mblighe8819cd2008-02-15 16:48:40 +00001"""\
2Utility functions for rpc_interface.py. We keep them in a separate file so that
3only RPC interface functions go into that file.
4"""
5
6__author__ = 'showard@google.com (Steve Howard)'
7
8import datetime, xmlrpclib, threading
9from frontend.afe import models
10
11def prepare_for_serialization(objects):
12 """\
13 Do necessary type conversions to values in data to allow for RPC
14 serialization.
15 -convert datetimes to strings
16 """
showard1c8c2212008-04-03 20:33:58 +000017 objects = gather_unique_dicts(objects)
mblighe8819cd2008-02-15 16:48:40 +000018 new_objects = []
19 for data in objects:
20 new_data = {}
21 for key, value in data.iteritems():
22 if isinstance(value, datetime.datetime):
23 new_data[key] = str(value)
24 else:
25 new_data[key] = value
26 new_objects.append(new_data)
27 return new_objects
28
29
30def extra_job_filters(not_yet_run=False, running=False, finished=False):
31 """\
32 Generate a SQL WHERE clause for job status filtering, and return it in
33 a dict of keyword args to pass to query.extra(). No more than one of
34 the parameters should be passed as True.
35 """
36 assert not ((not_yet_run and running) or
37 (not_yet_run and finished) or
38 (running and finished)), ('Cannot specify more than one '
39 'filter to this function')
40 if not_yet_run:
41 where = ['id NOT IN (SELECT job_id FROM host_queue_entries '
42 'WHERE active OR complete)']
43 elif running:
44 where = ['(id IN (SELECT job_id FROM host_queue_entries '
45 'WHERE active OR complete)) AND '
46 '(id IN (SELECT job_id FROM host_queue_entries '
47 'WHERE not complete OR active))']
48 elif finished:
49 where = ['id NOT IN (SELECT job_id FROM host_queue_entries '
50 'WHERE not complete OR active)']
51 else:
52 return None
53 return {'where': where}
54
55
showard8e3aa5e2008-04-08 19:42:32 +000056def extra_host_filters(multiple_labels=[]):
57 """\
58 Generate SQL WHERE clauses for matching hosts in an intersection of
59 labels.
60 """
61 extra_args = {}
62 where_str = ('hosts.id in (select host_id from hosts_labels '
63 'where label_id=%s)')
64 extra_args['where'] = [where_str] * len(multiple_labels)
65 extra_args['params'] = [models.Label.smart_get(label).id
66 for label in multiple_labels]
67 return extra_args
68
69
mblighe8819cd2008-02-15 16:48:40 +000070local_vars = threading.local()
71
72def set_user(user):
73 """\
74 Sets the current request's logged-in user. user should be a
75 afe.models.User object.
76 """
77 local_vars.user = user
78
79
80def get_user():
81 'Get the currently logged-in user as a afe.models.User object.'
82 return local_vars.user
83
84
showard8fd58242008-03-10 21:29:07 +000085class InconsistencyException(Exception):
86 'Raised when a list of objects does not have a consistent value'
87
88
89def get_consistent_value(objects, field):
90 value = getattr(objects[0], field)
91 for obj in objects:
92 this_value = getattr(obj, field)
93 if this_value != value:
94 raise InconsistencyException(objects[0], obj)
95 return value
96
97
mblighe8819cd2008-02-15 16:48:40 +000098def prepare_generate_control_file(tests, kernel, label):
99 test_objects = [models.Test.smart_get(test) for test in tests]
100 # ensure tests are all the same type
showard8fd58242008-03-10 21:29:07 +0000101 try:
102 test_type = get_consistent_value(test_objects, 'test_type')
103 except InconsistencyException, exc:
104 test1, test2 = exc.args
105 raise models.ValidationError(
106 {'tests' : 'You cannot run both server- and client-side '
107 'tests together (tests %s and %s differ' % (
108 test1.name, test2.name)})
109
110 try:
111 synch_type = get_consistent_value(test_objects, 'synch_type')
112 except InconsistencyException, exc:
113 test1, test2 = exc.args
114 raise models.ValidationError(
115 {'tests' : 'You cannot run both synchronous and '
116 'asynchronous tests together (tests %s and %s differ)' % (
117 test1.name, test2.name)})
mblighe8819cd2008-02-15 16:48:40 +0000118
119 is_server = (test_type == models.Test.Types.SERVER)
showard8fd58242008-03-10 21:29:07 +0000120 is_synchronous = (synch_type == models.Test.SynchType.SYNCHRONOUS)
mblighe8819cd2008-02-15 16:48:40 +0000121 if label:
122 label = models.Label.smart_get(label)
123
showard8fd58242008-03-10 21:29:07 +0000124 return is_server, is_synchronous, test_objects, label
showard1385b162008-03-13 15:59:40 +0000125
126
127def gather_unique_dicts(dict_iterable):
128 """\
129 Pick out unique objects (by ID) from an iterable of object dicts.
130 """
131 id_set = set()
132 result = []
133 for obj in dict_iterable:
134 if obj['id'] not in id_set:
135 id_set.add(obj['id'])
136 result.append(obj)
137 return result
showard8e3aa5e2008-04-08 19:42:32 +0000138
139
140def sorted(in_list):
141 new_list = list(in_list)
142 new_list.sort()
143 return new_list