blob: a13b6d4655150783bf9279791a2fbcb64779ab75 [file] [log] [blame]
jamesrenc3940222010-02-19 21:57:37 +00001#!/usr/bin/python
2
3import unittest
4import common
5from autotest_lib.frontend import setup_django_environment
jamesren62758242010-04-28 18:08:25 +00006from autotest_lib.frontend import setup_test_environment
jamesrenc3940222010-02-19 21:57:37 +00007from autotest_lib.frontend.afe import model_logic, models as afe_models
jamesren62758242010-04-28 18:08:25 +00008from autotest_lib.frontend.planner import planner_test_utils, model_attributes
jamesren4be631f2010-04-08 23:01:22 +00009from autotest_lib.frontend.planner import models, rpc_utils, failure_actions
jamesren62758242010-04-28 18:08:25 +000010from autotest_lib.frontend.tko import models as tko_models
jamesren8d0d3d52010-03-25 20:39:13 +000011from autotest_lib.client.common_lib import utils, host_queue_entry_states
jamesrenc3940222010-02-19 21:57:37 +000012
13
14class RpcUtilsTest(unittest.TestCase,
15 planner_test_utils.PlannerTestMixin):
16 def setUp(self):
17 self._planner_common_setup()
18
19
20 def tearDown(self):
21 self._planner_common_teardown()
22
23
24 def test_create_plan_label(self):
25 label, group = self._create_label_helper()
26
27 label.delete()
28 group.invalid = True
29 group.save()
30
31 label, group = self._create_label_helper()
32
33 self.assertRaises(model_logic.ValidationError,
34 rpc_utils.create_plan_label, self._plan)
35
36
37 def _create_label_helper(self):
38 label = rpc_utils.create_plan_label(self._plan)
39 group = afe_models.AtomicGroup.objects.get(
40 name=rpc_utils.PLANNER_ATOMIC_GROUP_NAME)
41 self.assertFalse(group.invalid)
42 self.assertEqual(label.atomic_group, group)
43
44 return (label, group)
45
46
47 def test_lazy_load(self):
48 self.god.stub_function(utils, 'read_file')
49
50 DUMMY_PATH_1 = object()
51 DUMMY_PATH_2 = object()
52 DUMMY_FILE_1 = object()
53 DUMMY_FILE_2 = object()
54
55 utils.read_file.expect_call(DUMMY_PATH_1).and_return(DUMMY_FILE_1)
56 self.assertEqual(DUMMY_FILE_1, rpc_utils.lazy_load(DUMMY_PATH_1))
57 self.god.check_playback()
58
59 # read_file should not be called again for this path
60 self.assertEqual(DUMMY_FILE_1, rpc_utils.lazy_load(DUMMY_PATH_1))
61 self.god.check_playback()
62
63 # new file; read_file must be called again
64 utils.read_file.expect_call(DUMMY_PATH_2).and_return(DUMMY_FILE_2)
65 self.assertEqual(DUMMY_FILE_2, rpc_utils.lazy_load(DUMMY_PATH_2))
66 self.god.check_playback()
67
68
jamesren8d0d3d52010-03-25 20:39:13 +000069 def test_update_hosts_table(self):
70 label = self.labels[3]
71 default_hosts = set(self._plan.hosts.all())
72
73 rpc_utils.update_hosts_table(self._plan)
74 self.assertEqual(default_hosts, set(self._plan.hosts.all()))
75 self.assertEqual(set(), self._get_added_by_label_hosts())
76
77 self._plan.host_labels.add(label)
78 rpc_utils.update_hosts_table(self._plan)
79 self.assertEqual(default_hosts.union(label.host_set.all()),
80 set(self._plan.hosts.all()))
81 self.assertEqual(set(label.host_set.all()),
82 self._get_added_by_label_hosts())
83
84 self._plan.host_labels.remove(label)
85 rpc_utils.update_hosts_table(self._plan)
86 self.assertEqual(default_hosts, set(self._plan.hosts.all()))
87 self.assertEqual(set(), self._get_added_by_label_hosts())
88
89
90 def _get_added_by_label_hosts(self):
91 return set(host.host for host in models.Host.objects.filter(
92 plan=self._plan, added_by_label=True))
93
94
95 def test_compute_next_test_config(self):
96 self._setup_active_plan()
97 test_config = models.TestConfig.objects.create(
98 plan=self._plan, alias='config2', control_file=self._control,
99 execution_order=2, estimated_runtime=1)
100
101 self.assertEqual(1, self._afe_job.hostqueueentry_set.count())
102 self.assertEqual(
103 None, rpc_utils.compute_next_test_config(self._plan,
104 self._planner_host))
105 self.assertFalse(self._planner_host.complete)
106
107 hqe = self._afe_job.hostqueueentry_set.all()[0]
108 hqe.status = host_queue_entry_states.Status.COMPLETED
109 hqe.save()
110
111 self.assertEqual(
jamesrendbeebf82010-04-08 22:58:26 +0000112 test_config,
jamesren8d0d3d52010-03-25 20:39:13 +0000113 rpc_utils.compute_next_test_config(self._plan,
114 self._planner_host))
115 self.assertFalse(self._planner_host.complete)
116
117 afe_job = self._create_job(hosts=(1,))
118 planner_job = models.Job.objects.create(plan=self._plan,
119 test_config=test_config,
120 afe_job=afe_job)
121
122 self.assertEqual(
123 None, rpc_utils.compute_next_test_config(self._plan,
124 self._planner_host))
125 self.assertFalse(self._planner_host.complete)
126
127 hqe = afe_job.hostqueueentry_set.all()[0]
128 hqe.status = host_queue_entry_states.Status.COMPLETED
129 hqe.save()
130
131 self.assertEqual(
132 None, rpc_utils.compute_next_test_config(self._plan,
133 self._planner_host))
134 self.assertTrue(self._planner_host.complete)
135
136
jamesren62758242010-04-28 18:08:25 +0000137 def test_process_failure(self):
138 self._setup_active_plan()
139 tko_test = tko_models.Test.objects.create(job=self._tko_job,
140 machine=self._tko_machine,
141 kernel=self._tko_kernel,
142 status=self._running_status)
143 failure = models.TestRun.objects.create(
144 plan=self._plan,
145 test_job=self._planner_job,
146 tko_test=tko_test,
147 host=self._planner_host,
148 status=model_attributes.TestRunStatus.FAILED,
149 finalized=True, seen=False, triaged=False)
150 host_action = failure_actions.HostAction.UNBLOCK
151 test_action = failure_actions.TestAction.SKIP
152 labels = ['label1', 'label2']
153 keyvals = {'key1': 'value1',
154 'key2': 'value2'}
155 bugs = ['bug1', 'bug2']
156 reason = 'overriden reason'
157 invalidate = True
158
159 self.god.stub_function(rpc_utils, '_process_host_action')
160 self.god.stub_function(rpc_utils, '_process_test_action')
161
162 rpc_utils._process_host_action.expect_call(self._planner_host,
163 host_action)
164 rpc_utils._process_test_action.expect_call(self._planner_job,
165 test_action)
166
167 rpc_utils.process_failure(
168 failure_id=failure.id, host_action=host_action,
169 test_action=test_action, labels=labels, keyvals=keyvals,
170 bugs=bugs, reason=reason, invalidate=invalidate)
171 failure = models.TestRun.objects.get(id=failure.id)
172
173 self.assertEqual(
174 set(failure.tko_test.testlabel_set.all()),
175 set(tko_models.TestLabel.objects.filter(name__in=labels)))
176 self.assertEqual(
177 set(failure.tko_test.job.jobkeyval_set.all()),
178 set(tko_models.JobKeyval.objects.filter(
179 key__in=keyvals.iterkeys())))
180 self.assertEqual(set(failure.bugs.all()),
181 set(models.Bug.objects.filter(external_uid__in=bugs)))
182 self.assertEqual(failure.tko_test.reason, reason)
183 self.assertEqual(failure.invalidated, invalidate)
184 self.assertTrue(failure.seen)
185 self.assertTrue(failure.triaged)
186 self.god.check_playback()
187
188
jamesren4be631f2010-04-08 23:01:22 +0000189 def _replace_site_process_host_action(self, replacement):
190 self.god.stub_function(utils, 'import_site_function')
191 utils.import_site_function.expect_any_call().and_return(replacement)
192
193
194 def _remove_site_process_host_action(self):
195 def _site_process_host_action_dummy(host, action):
196 return False
197 self._replace_site_process_host_action(_site_process_host_action_dummy)
198
199
200 def test_process_host_action_block(self):
201 self._remove_site_process_host_action()
202 host = models.Host.objects.create(plan=self._plan, host=self.hosts[0],
203 blocked=False)
204 assert not host.blocked
205
jamesren62758242010-04-28 18:08:25 +0000206 rpc_utils._process_host_action(host, failure_actions.HostAction.BLOCK)
jamesren4be631f2010-04-08 23:01:22 +0000207 host = models.Host.objects.get(id=host.id)
208
209 self.assertTrue(host.blocked)
210 self.god.check_playback()
211
212
213 def test_process_host_action_unblock(self):
214 self._remove_site_process_host_action()
215 host = models.Host.objects.create(plan=self._plan, host=self.hosts[0],
216 blocked=True)
217 assert host.blocked
218
jamesren62758242010-04-28 18:08:25 +0000219 rpc_utils._process_host_action(host, failure_actions.HostAction.UNBLOCK)
jamesren4be631f2010-04-08 23:01:22 +0000220 host = models.Host.objects.get(id=host.id)
221
222 self.assertFalse(host.blocked)
223 self.god.check_playback()
224
225
226 def test_process_host_action_site(self):
227 self._remove_site_process_host_action
228 action = object()
229 failure_actions.HostAction.values.append(action)
230 host = models.Host.objects.create(plan=self._plan, host=self.hosts[0])
231
jamesren62758242010-04-28 18:08:25 +0000232 self.assertRaises(AssertionError, rpc_utils._process_host_action,
jamesren4be631f2010-04-08 23:01:22 +0000233 host, action)
234 self.god.check_playback()
235
236 self._called = False
237 def _site_process_host_action(host, action):
238 self._called = True
239 return True
240 self._replace_site_process_host_action(_site_process_host_action)
241
jamesren62758242010-04-28 18:08:25 +0000242 rpc_utils._process_host_action(host, action)
jamesren4be631f2010-04-08 23:01:22 +0000243
244 self.assertTrue(self._called)
245 self.god.check_playback()
246
247
248 def test_process_test_action_skip(self):
249 self._setup_active_plan()
250 planner_job = self._planner_job
251 assert not planner_job.requires_rerun
252
jamesren62758242010-04-28 18:08:25 +0000253 rpc_utils._process_test_action(planner_job,
254 failure_actions.TestAction.SKIP)
jamesren4be631f2010-04-08 23:01:22 +0000255 planner_job = models.Job.objects.get(id=planner_job.id)
256
257 self.assertFalse(planner_job.requires_rerun)
258
259
260 def test_process_test_action_rerun(self):
261 self._setup_active_plan()
262 planner_job = self._planner_job
263 assert not planner_job.requires_rerun
264
jamesren62758242010-04-28 18:08:25 +0000265 rpc_utils._process_test_action(planner_job,
266 failure_actions.TestAction.RERUN)
jamesren4be631f2010-04-08 23:01:22 +0000267 planner_job = models.Job.objects.get(id=planner_job.id)
268
269 self.assertTrue(planner_job.requires_rerun)
270
271
jamesren9a6f5f62010-05-05 22:55:54 +0000272 def test_set_additional_parameters(self):
273 hostname_regex = 'host[0-9]'
274 param_type = model_attributes.AdditionalParameterType.VERIFY
275 param_values = {'key1': 'value1',
276 'key2': []}
277
278 additional_parameters = {'hostname_regex': hostname_regex,
279 'param_type': param_type,
280 'param_values': param_values}
281
282 rpc_utils.set_additional_parameters(self._plan, [additional_parameters])
283
284 additional_parameters_query = (
285 models.AdditionalParameter.objects.filter(plan=self._plan))
286 self.assertEqual(additional_parameters_query.count(), 1)
287
288 additional_parameter = additional_parameters_query[0]
289 self.assertEqual(additional_parameter.hostname_regex, hostname_regex)
290 self.assertEqual(additional_parameter.param_type, param_type)
291 self.assertEqual(additional_parameter.application_order, 0)
292
293 values_query = additional_parameter.additionalparametervalue_set.all()
294 self.assertEqual(values_query.count(), 2)
295
296 value_query1 = values_query.filter(key='key1')
297 value_query2 = values_query.filter(key='key2')
298 self.assertEqual(value_query1.count(), 1)
299 self.assertEqual(value_query2.count(), 1)
300
301 self.assertEqual(value_query1[0].value, repr('value1'))
302 self.assertEqual(value_query2[0].value, repr([]))
303
304
305 def test_get_wrap_arguments(self):
306 hostname_regex = '.*'
307 param_type = model_attributes.AdditionalParameterType.VERIFY
308
309 additional_param = models.AdditionalParameter.objects.create(
310 plan=self._plan, hostname_regex=hostname_regex,
311 param_type=param_type, application_order=0)
312 models.AdditionalParameterValue.objects.create(
313 additional_parameter=additional_param,
314 key='key1', value=repr('value1'))
315 models.AdditionalParameterValue.objects.create(
316 additional_parameter=additional_param,
317 key='key2', value=repr([]))
318
319 actual = rpc_utils.get_wrap_arguments(self._plan, 'host', param_type)
320 expected = {'key1': repr('value1'),
321 'key2': repr([])}
322
323 self.assertEqual(actual, expected)
324
jamesren2e48bcb2010-05-18 20:41:36 +0000325
326 def test_compute_passed_incomplete(self):
327 self._setup_active_plan()
328 self._planner_host.complete = False
329 self._planner_host.save()
330 self.assertEqual(rpc_utils.compute_passed(self._planner_host), None)
331
332
333 def test_compute_passed_good(self):
334 self._setup_active_plan()
335 tko_test = self._tko_job.test_set.create(kernel=self._tko_kernel,
336 status=self._good_status,
337 machine=self._tko_machine)
338 self._plan.testrun_set.create(test_job=self._planner_job,
339 tko_test=tko_test,
340 host=self._planner_host)
341 self._planner_host.complete = True
342 self._planner_host.save()
343
344 self.assertEqual(rpc_utils.compute_passed(self._planner_host), True)
345
346
347 def test_compute_passed_bad(self):
348 self._setup_active_plan()
349 tko_test = self._tko_job.test_set.create(kernel=self._tko_kernel,
350 status=self._fail_status,
351 machine=self._tko_machine)
352 self._plan.testrun_set.create(test_job=self._planner_job,
353 tko_test=tko_test,
354 host=self._planner_host)
355 self._planner_host.complete = True
356 self._planner_host.save()
357
358 self.assertEqual(rpc_utils.compute_passed(self._planner_host), False)
359
360
jamesrenc3940222010-02-19 21:57:37 +0000361if __name__ == '__main__':
362 unittest.main()