blob: f0cf5ab38f750183c772848785732b59228d41d7 [file] [log] [blame]
showarded2afea2009-07-07 20:54:07 +00001#!/usr/bin/python
2
3import unittest
Allen Lieb97ee72017-02-10 15:19:16 -08004
showarded2afea2009-07-07 20:54:07 +00005import common
Allen Lieb97ee72017-02-10 15:19:16 -08006from autotest_lib.client.common_lib import control_data
7from autotest_lib.client.common_lib import global_config
showarded2afea2009-07-07 20:54:07 +00008from autotest_lib.frontend import setup_django_environment
9from autotest_lib.frontend.afe import frontend_test_utils
Allen Lieb97ee72017-02-10 15:19:16 -080010from autotest_lib.frontend.afe import model_logic
11from autotest_lib.frontend.afe import models
showarded2afea2009-07-07 20:54:07 +000012
showarda5288b42009-07-28 20:06:08 +000013
14class AclGroupTest(unittest.TestCase,
15 frontend_test_utils.FrontendTestMixin):
16 def setUp(self):
17 self._frontend_common_setup()
18
19
20 def tearDown(self):
21 self._frontend_common_teardown()
22
23
24 def _check_acls(self, host, acl_name_list):
25 actual_acl_names = [acl_group.name for acl_group
26 in host.aclgroup_set.all()]
27 self.assertEquals(set(actual_acl_names), set(acl_name_list))
28
29
30 def test_on_host_membership_change(self):
31 host1, host2 = self.hosts[1:3]
32 everyone_acl = models.AclGroup.objects.get(name='Everyone')
33
34 host1.aclgroup_set.clear()
35 self._check_acls(host1, [])
36 host2.aclgroup_set.add(everyone_acl)
37 self._check_acls(host2, ['Everyone', 'my_acl'])
38
39 models.AclGroup.on_host_membership_change()
40
41 self._check_acls(host1, ['Everyone'])
42 self._check_acls(host2, ['my_acl'])
43
44
showardafd97de2009-10-01 18:45:09 +000045class HostTest(unittest.TestCase,
46 frontend_test_utils.FrontendTestMixin):
47 def setUp(self):
48 self._frontend_common_setup()
49
50
51 def tearDown(self):
52 self._frontend_common_teardown()
53
54
55 def test_add_host_previous_one_time_host(self):
56 # ensure that when adding a host which was previously used as a one-time
57 # host, the status isn't reset, since this can interfere with the
58 # scheduler.
59 host = models.Host.create_one_time_host('othost')
60 self.assertEquals(host.invalid, True)
61 self.assertEquals(host.status, models.Host.Status.READY)
62
63 host.status = models.Host.Status.RUNNING
64 host.save()
65
66 host2 = models.Host.add_object(hostname='othost')
67 self.assertEquals(host2.id, host.id)
68 self.assertEquals(host2.status, models.Host.Status.RUNNING)
69
70
Dan Shib5b8b4f2016-11-02 14:04:02 -070071 def test_check_board_labels_allowed(self):
Shuqian Zhao40e182b2016-10-11 11:55:11 -070072 host = models.Host.create_one_time_host('othost')
73 # First check with host with no board label.
Dan Shib5b8b4f2016-11-02 14:04:02 -070074 self.assertEqual(host.check_board_labels_allowed([host]), None)
Shuqian Zhao40e182b2016-10-11 11:55:11 -070075
76 # Second check with host with board label
77 label = models.Label.add_object(name='board:test')
78 label.host_set.add(host)
79 self.assertRaises(model_logic.ValidationError,
Dan Shib5b8b4f2016-11-02 14:04:02 -070080 host.check_board_labels_allowed, [host],
81 ['board:new_board'])
Shuqian Zhao40e182b2016-10-11 11:55:11 -070082
83
showarded2afea2009-07-07 20:54:07 +000084class SpecialTaskUnittest(unittest.TestCase,
85 frontend_test_utils.FrontendTestMixin):
86 def setUp(self):
87 self._frontend_common_setup()
88
89
90 def tearDown(self):
91 self._frontend_common_teardown()
92
93
showardc0ac3a72009-07-08 21:14:45 +000094 def _create_task(self):
95 return models.SpecialTask.objects.create(
jamesren76fcf192010-04-21 20:39:50 +000096 host=self.hosts[0], task=models.SpecialTask.Task.VERIFY,
97 requested_by=models.User.current_user())
showarded2afea2009-07-07 20:54:07 +000098
showardc0ac3a72009-07-08 21:14:45 +000099
100 def test_execution_path(self):
101 task = self._create_task()
showarded2afea2009-07-07 20:54:07 +0000102 self.assertEquals(task.execution_path(), 'hosts/host1/1-verify')
103
104
showardc0ac3a72009-07-08 21:14:45 +0000105 def test_status(self):
106 task = self._create_task()
107 self.assertEquals(task.status, 'Queued')
108
109 task.update_object(is_active=True)
110 self.assertEquals(task.status, 'Running')
111
showarde60e44e2009-11-13 20:45:38 +0000112 task.update_object(is_active=False, is_complete=True, success=True)
showardc0ac3a72009-07-08 21:14:45 +0000113 self.assertEquals(task.status, 'Completed')
114
showarde60e44e2009-11-13 20:45:38 +0000115 task.update_object(success=False)
116 self.assertEquals(task.status, 'Failed')
117
showardc0ac3a72009-07-08 21:14:45 +0000118
showard97446882009-07-20 22:37:28 +0000119 def test_activate(self):
120 task = self._create_task()
121 task.activate()
122 self.assertTrue(task.is_active)
123 self.assertFalse(task.is_complete)
124
125
126 def test_finish(self):
127 task = self._create_task()
128 task.activate()
showarde60e44e2009-11-13 20:45:38 +0000129 task.finish(True)
showard97446882009-07-20 22:37:28 +0000130 self.assertFalse(task.is_active)
131 self.assertTrue(task.is_complete)
showarde60e44e2009-11-13 20:45:38 +0000132 self.assertTrue(task.success)
showard97446882009-07-20 22:37:28 +0000133
134
showard9bb960b2009-11-19 01:02:11 +0000135 def test_requested_by_from_queue_entry(self):
136 job = self._create_job(hosts=[0])
137 task = models.SpecialTask.objects.create(
138 host=self.hosts[0], task=models.SpecialTask.Task.VERIFY,
139 queue_entry=job.hostqueueentry_set.all()[0])
showardfd8b89f2010-01-20 19:06:30 +0000140 self.assertEquals(task.requested_by.login, 'autotest_system')
showard9bb960b2009-11-19 01:02:11 +0000141
142
showardd1195652009-12-08 22:21:02 +0000143class HostQueueEntryUnittest(unittest.TestCase,
144 frontend_test_utils.FrontendTestMixin):
145 def setUp(self):
146 self._frontend_common_setup()
147
148
149 def tearDown(self):
150 self._frontend_common_teardown()
151
152
153 def test_execution_path(self):
154 entry = self._create_job(hosts=[1]).hostqueueentry_set.all()[0]
155 entry.execution_subdir = 'subdir'
156 entry.save()
157
showardfd8b89f2010-01-20 19:06:30 +0000158 self.assertEquals(entry.execution_path(), '1-autotest_system/subdir')
showardd1195652009-12-08 22:21:02 +0000159
160
jamesrene3656232010-03-02 00:00:30 +0000161class ModelWithInvalidTest(unittest.TestCase,
162 frontend_test_utils.FrontendTestMixin):
163 def setUp(self):
164 self._frontend_common_setup()
165
166
167 def tearDown(self):
168 self._frontend_common_teardown()
169
170
171 def test_model_with_invalid_delete(self):
172 self.assertFalse(self.hosts[0].invalid)
173 self.hosts[0].delete()
174 self.assertTrue(self.hosts[0].invalid)
175 self.assertTrue(models.Host.objects.get(id=self.hosts[0].id))
176
177
178 def test_model_with_invalid_delete_queryset(self):
179 for host in self.hosts:
180 self.assertFalse(host.invalid)
181
182 hosts = models.Host.objects.all()
183 hosts.delete()
184 self.assertEqual(hosts.count(), len(self.hosts))
185
186 for host in hosts:
187 self.assertTrue(host.invalid)
188
189
190 def test_cloned_queryset_delete(self):
191 """
192 Make sure that a cloned queryset maintains the custom delete()
193 """
194 to_delete = ('host1', 'host2')
195
196 for host in self.hosts:
197 self.assertFalse(host.invalid)
198
199 hosts = models.Host.objects.all().filter(hostname__in=to_delete)
200 hosts.delete()
201 all_hosts = models.Host.objects.all()
202 self.assertEqual(all_hosts.count(), len(self.hosts))
203
204 for host in all_hosts:
205 if host.hostname in to_delete:
206 self.assertTrue(
207 host.invalid,
208 '%s.invalid expected to be True' % host.hostname)
209 else:
210 self.assertFalse(
211 host.invalid,
212 '%s.invalid expected to be False' % host.hostname)
213
214
215 def test_normal_delete(self):
216 job = self._create_job(hosts=[1])
217 self.assertEqual(1, models.Job.objects.all().count())
218
219 job.delete()
220 self.assertEqual(0, models.Job.objects.all().count())
221
222
223 def test_normal_delete_queryset(self):
224 self._create_job(hosts=[1])
225 self._create_job(hosts=[2])
226
227 self.assertEqual(2, models.Job.objects.all().count())
228
229 models.Job.objects.all().delete()
230 self.assertEqual(0, models.Job.objects.all().count())
231
232
Shuqian Zhao54a5b672016-05-11 22:12:17 +0000233class KernelTest(unittest.TestCase, frontend_test_utils.FrontendTestMixin):
234 def setUp(self):
235 self._frontend_common_setup()
236
237
238 def tearDown(self):
239 self._frontend_common_teardown()
240
241
242 def test_create_kernels_none(self):
243 self.assertEqual(None, models.Kernel.create_kernels(None))
244
245
246 def test_create_kernels(self):
247 self.god.stub_function(models.Kernel, '_create')
248
249 num_kernels = 3
250 kernel_list = [object() for _ in range(num_kernels)]
251 result = [object() for _ in range(num_kernels)]
252
253 for kernel, response in zip(kernel_list, result):
254 models.Kernel._create.expect_call(kernel).and_return(response)
255 self.assertEqual(result, models.Kernel.create_kernels(kernel_list))
256 self.god.check_playback()
257
258
259 def test_create(self):
260 kernel = models.Kernel._create({'version': 'version'})
261 self.assertEqual(kernel.version, 'version')
262 self.assertEqual(kernel.cmdline, '')
263 self.assertEqual(kernel, models.Kernel._create({'version': 'version'}))
264
265
jamesren4a41e012010-07-16 22:33:48 +0000266class ParameterizedJobTest(unittest.TestCase,
267 frontend_test_utils.FrontendTestMixin):
268 def setUp(self):
269 self._frontend_common_setup()
270
271
272 def tearDown(self):
273 self._frontend_common_teardown()
274
275
276 def test_job(self):
277 global_config.global_config.override_config_value(
278 'AUTOTEST_WEB', 'parameterized_jobs', 'True')
279
280 test = models.Test.objects.create(
281 name='name', author='author', test_class='class',
282 test_category='category',
Aviv Keshet3dd8beb2013-05-13 17:36:04 -0700283 test_type=control_data.CONTROL_TYPE.SERVER, path='path')
jamesren4a41e012010-07-16 22:33:48 +0000284 parameterized_job = models.ParameterizedJob.objects.create(test=test)
285 job = self._create_job(hosts=[1], control_file=None,
286 parameterized_job=parameterized_job)
287
288 self.assertEqual(job, parameterized_job.job())
289
290
291class JobTest(unittest.TestCase, frontend_test_utils.FrontendTestMixin):
292 def setUp(self):
293 self._frontend_common_setup()
294
295
296 def tearDown(self):
297 self._frontend_common_teardown()
298
299
300 def test_check_parameterized_jobs_no_args(self):
301 self.assertRaises(Exception, models.Job.check_parameterized_job,
302 control_file=None, parameterized_job=None)
303
304
305 def test_check_parameterized_jobs_both_args(self):
306 self.assertRaises(Exception, models.Job.check_parameterized_job,
307 control_file=object(), parameterized_job=object())
308
309
310 def test_check_parameterized_jobs_disabled(self):
311 self.assertRaises(Exception, models.Job.check_parameterized_job,
312 control_file=None, parameterized_job=object())
313
314
315 def test_check_parameterized_jobs_enabled(self):
316 global_config.global_config.override_config_value(
317 'AUTOTEST_WEB', 'parameterized_jobs', 'True')
318 self.assertRaises(Exception, models.Job.check_parameterized_job,
319 control_file=object(), parameterized_job=None)
320
321
Jakob Juelich3bb7c802014-09-02 16:31:11 -0700322class SerializationTest(unittest.TestCase,
323 frontend_test_utils.FrontendTestMixin):
324 def setUp(self):
Jakob Juelichf88fa932014-09-03 17:58:04 -0700325 self._frontend_common_setup(fill_data=False)
Jakob Juelich3bb7c802014-09-02 16:31:11 -0700326
327
328 def tearDown(self):
329 self._frontend_common_teardown()
330
331
Jakob Juelichf88fa932014-09-03 17:58:04 -0700332 def _get_example_response(self):
333 return {'hosts': [{'aclgroup_set': [{'description': '',
334 'id': 1,
335 'name': 'Everyone',
336 'users': [{
337 'access_level': 100,
338 'id': 1,
339 'login': 'autotest_system',
340 'reboot_after': 0,
341 'reboot_before': 1,
342 'show_experimental': False}]}],
343 'dirty': True,
344 'hostattribute_set': [],
345 'hostname': '100.107.2.163',
346 'id': 2,
347 'invalid': False,
348 'labels': [{'id': 7,
349 'invalid': False,
350 'kernel_config': '',
351 'name': 'power:battery',
352 'only_if_needed': False,
353 'platform': False},
354 {'id': 9,
355 'invalid': False,
356 'kernel_config': '',
357 'name': 'hw_video_acc_h264',
358 'only_if_needed': False,
359 'platform': False},
360 {'id': 10,
361 'invalid': False,
362 'kernel_config': '',
363 'name': 'hw_video_acc_enc_h264',
364 'only_if_needed': False,
365 'platform': False},
366 {'id': 11,
367 'invalid': False,
368 'kernel_config': '',
369 'name': 'webcam',
370 'only_if_needed': False,
371 'platform': False},
372 {'id': 12,
373 'invalid': False,
374 'kernel_config': '',
375 'name': 'touchpad',
376 'only_if_needed': False,
377 'platform': False},
378 {'id': 13,
379 'invalid': False,
380 'kernel_config': '',
381 'name': 'spring',
382 'only_if_needed': False,
383 'platform': False},
384 {'id': 14,
385 'invalid': False,
386 'kernel_config': '',
387 'name': 'board:daisy',
388 'only_if_needed': False,
389 'platform': True},
390 {'id': 15,
391 'invalid': False,
392 'kernel_config': '',
393 'name': 'board_freq_mem:daisy_1.7GHz',
394 'only_if_needed': False,
395 'platform': False},
396 {'id': 16,
397 'invalid': False,
398 'kernel_config': '',
399 'name': 'bluetooth',
400 'only_if_needed': False,
401 'platform': False},
402 {'id': 17,
403 'invalid': False,
404 'kernel_config': '',
405 'name': 'gpu_family:mali',
406 'only_if_needed': False,
407 'platform': False},
Jakob Juelichf88fa932014-09-03 17:58:04 -0700408 {'id': 19,
409 'invalid': False,
410 'kernel_config': '',
411 'name': 'ec:cros',
412 'only_if_needed': False,
413 'platform': False},
414 {'id': 20,
415 'invalid': False,
416 'kernel_config': '',
417 'name': 'storage:mmc',
418 'only_if_needed': False,
419 'platform': False},
420 {'id': 21,
421 'invalid': False,
422 'kernel_config': '',
423 'name': 'hw_video_acc_vp8',
424 'only_if_needed': False,
425 'platform': False},
426 {'id': 22,
427 'invalid': False,
428 'kernel_config': '',
429 'name': 'video_glitch_detection',
430 'only_if_needed': False,
431 'platform': False},
432 {'id': 23,
433 'invalid': False,
434 'kernel_config': '',
435 'name': 'pool:suites',
436 'only_if_needed': False,
437 'platform': False},
438 {'id': 25,
439 'invalid': False,
440 'kernel_config': '',
441 'name': 'daisy-board-name',
442 'only_if_needed': False,
443 'platform': False}],
444 'leased': False,
Matthew Sartori68186332015-04-27 17:19:53 -0700445 'lock_reason': '',
Jakob Juelichf88fa932014-09-03 17:58:04 -0700446 'lock_time': None,
447 'locked': False,
448 'protection': 0,
449 'shard': {'hostname': '1', 'id': 1},
Allen Lieb97ee72017-02-10 15:19:16 -0800450 'status': 'Ready'}],
Jakob Juelichf88fa932014-09-03 17:58:04 -0700451 'jobs': [{'control_file': 'some control file\n\n\n',
452 'control_type': 2,
453 'created_on': '2014-09-04T13:09:35',
454 'dependency_labels': [{'id': 14,
455 'invalid': False,
456 'kernel_config': '',
457 'name': 'board:daisy',
458 'only_if_needed': False,
459 'platform': True},
460 {'id': 23,
461 'invalid': False,
462 'kernel_config': '',
463 'name': 'pool:suites',
464 'only_if_needed': False,
465 'platform': False},
466 {'id': 25,
467 'invalid': False,
468 'kernel_config': '',
469 'name': 'daisy-board-name',
470 'only_if_needed': False,
471 'platform': False}],
472 'email_list': '',
473 'hostqueueentry_set': [{'aborted': False,
474 'active': False,
475 'complete': False,
476 'deleted': False,
477 'execution_subdir': '',
478 'finished_on': None,
479 'id': 5,
480 'meta_host': {
481 'id': 14,
482 'invalid': False,
483 'kernel_config': '',
484 'name': 'board:daisy',
485 'only_if_needed': False,
486 'platform': True},
Prashanth Balasubramanian8c98ac12014-12-23 11:26:44 -0800487 'host_id': None,
Jakob Juelichf88fa932014-09-03 17:58:04 -0700488 'started_on': None,
489 'status': 'Queued'}],
490 'id': 5,
491 'jobkeyval_set': [{'id': 10,
Fang Dengff361592015-02-02 15:27:34 -0800492 'job_id': 5,
Jakob Juelichf88fa932014-09-03 17:58:04 -0700493 'key': 'suite',
494 'value': 'dummy'},
495 {'id': 11,
Fang Dengff361592015-02-02 15:27:34 -0800496 'job_id': 5,
Jakob Juelichf88fa932014-09-03 17:58:04 -0700497 'key': 'build',
498 'value': 'daisy-release'},
499 {'id': 12,
Fang Dengff361592015-02-02 15:27:34 -0800500 'job_id': 5,
Jakob Juelichf88fa932014-09-03 17:58:04 -0700501 'key': 'experimental',
502 'value': 'False'}],
503 'max_runtime_hrs': 72,
504 'max_runtime_mins': 1440,
505 'name': 'daisy-experimental',
506 'owner': 'autotest',
507 'parse_failed_repair': True,
508 'priority': 40,
509 'reboot_after': 0,
510 'reboot_before': 1,
511 'run_reset': True,
512 'run_verify': False,
513 'shard': {'hostname': '1', 'id': 1},
514 'synch_count': 1,
515 'test_retry': 0,
516 'timeout': 24,
Dan Shic9e17142015-02-19 11:50:55 -0800517 'timeout_mins': 1440,
518 'require_ssp': None},
Jakob Juelichf88fa932014-09-03 17:58:04 -0700519 {'control_file': 'some control file\n\n\n',
520 'control_type': 2,
521 'created_on': '2014-09-04T13:09:35',
522 'dependency_labels': [{'id': 14,
523 'invalid': False,
524 'kernel_config': '',
525 'name': 'board:daisy',
526 'only_if_needed': False,
527 'platform': True},
528 {'id': 23,
529 'invalid': False,
530 'kernel_config': '',
531 'name': 'pool:suites',
532 'only_if_needed': False,
533 'platform': False},
534 {'id': 25,
535 'invalid': False,
536 'kernel_config': '',
537 'name': 'daisy-board-name',
538 'only_if_needed': False,
539 'platform': False}],
540 'email_list': '',
541 'hostqueueentry_set': [{'aborted': False,
542 'active': False,
543 'complete': False,
544 'deleted': False,
545 'execution_subdir': '',
546 'finished_on': None,
547 'id': 7,
548 'meta_host': {
549 'id': 14,
550 'invalid': False,
551 'kernel_config': '',
552 'name': 'board:daisy',
553 'only_if_needed': False,
554 'platform': True},
Prashanth Balasubramanian8c98ac12014-12-23 11:26:44 -0800555 'host_id': None,
Jakob Juelichf88fa932014-09-03 17:58:04 -0700556 'started_on': None,
557 'status': 'Queued'}],
558 'id': 7,
559 'jobkeyval_set': [{'id': 16,
Fang Dengff361592015-02-02 15:27:34 -0800560 'job_id': 7,
Jakob Juelichf88fa932014-09-03 17:58:04 -0700561 'key': 'suite',
562 'value': 'dummy'},
563 {'id': 17,
Fang Dengff361592015-02-02 15:27:34 -0800564 'job_id': 7,
Jakob Juelichf88fa932014-09-03 17:58:04 -0700565 'key': 'build',
566 'value': 'daisy-release'},
567 {'id': 18,
Fang Dengff361592015-02-02 15:27:34 -0800568 'job_id': 7,
Jakob Juelichf88fa932014-09-03 17:58:04 -0700569 'key': 'experimental',
570 'value': 'False'}],
571 'max_runtime_hrs': 72,
572 'max_runtime_mins': 1440,
573 'name': 'daisy-experimental',
574 'owner': 'autotest',
575 'parse_failed_repair': True,
576 'priority': 40,
577 'reboot_after': 0,
578 'reboot_before': 1,
579 'run_reset': True,
580 'run_verify': False,
581 'shard': {'hostname': '1', 'id': 1},
582 'synch_count': 1,
583 'test_retry': 0,
584 'timeout': 24,
Dan Shic9e17142015-02-19 11:50:55 -0800585 'timeout_mins': 1440,
586 'require_ssp': None}]}
Jakob Juelich3bb7c802014-09-02 16:31:11 -0700587
Jakob Juelich3bb7c802014-09-02 16:31:11 -0700588
Jakob Juelichf88fa932014-09-03 17:58:04 -0700589 def test_response(self):
590 heartbeat_response = self._get_example_response()
591 hosts_serialized = heartbeat_response['hosts']
592 jobs_serialized = heartbeat_response['jobs']
Jakob Juelich3bb7c802014-09-02 16:31:11 -0700593
Jakob Juelichf88fa932014-09-03 17:58:04 -0700594 # Persisting is automatically done inside deserialize
595 hosts = [models.Host.deserialize(host) for host in hosts_serialized]
596 jobs = [models.Job.deserialize(job) for job in jobs_serialized]
Jakob Juelich3bb7c802014-09-02 16:31:11 -0700597
Jakob Juelichf88fa932014-09-03 17:58:04 -0700598 generated_heartbeat_response = {
599 'hosts': [host.serialize() for host in hosts],
600 'jobs': [job.serialize() for job in jobs]
601 }
Fang Dengff361592015-02-02 15:27:34 -0800602 example_response = self._get_example_response()
603 # For attribute-like objects, we don't care about its id.
604 for r in [generated_heartbeat_response, example_response]:
605 for job in r['jobs']:
606 for keyval in job['jobkeyval_set']:
607 keyval.pop('id')
608 for host in r['hosts']:
609 for attribute in host['hostattribute_set']:
610 keyval.pop('id')
611 self.assertEqual(generated_heartbeat_response, example_response)
Jakob Juelich3bb7c802014-09-02 16:31:11 -0700612
613
Jakob Juelich116ff0f2014-09-17 18:25:16 -0700614 def test_update(self):
615 job = self._create_job(hosts=[1])
616 serialized = job.serialize(include_dependencies=False)
617 serialized['owner'] = 'some_other_owner'
618
619 job.update_from_serialized(serialized)
620 self.assertEqual(job.owner, 'some_other_owner')
621
622 serialized = job.serialize()
623 self.assertRaises(
624 ValueError,
625 job.update_from_serialized, serialized)
626
627
Jakob Juelichf865d332014-09-29 10:47:49 -0700628 def test_sync_aborted(self):
629 job = self._create_job(hosts=[1])
630 serialized = job.serialize()
631
632 serialized['hostqueueentry_set'][0]['aborted'] = True
633 serialized['hostqueueentry_set'][0]['status'] = 'Running'
634
635 models.Job.deserialize(serialized)
636
637 job = models.Job.objects.get(pk=job.id)
638 self.assertTrue(job.hostqueueentry_set.all()[0].aborted)
639 self.assertEqual(job.hostqueueentry_set.all()[0].status, 'Queued')
Jakob Juelich116ff0f2014-09-17 18:25:16 -0700640
641
showarded2afea2009-07-07 20:54:07 +0000642if __name__ == '__main__':
643 unittest.main()