Prashanth B | f66d51b | 2014-05-06 12:42:25 -0700 | [diff] [blame^] | 1 | #!/usr/bin/python |
| 2 | #pylint: disable-msg=C0111 |
| 3 | |
| 4 | # Copyright (c) 2014 The Chromium OS Authors. All rights reserved. |
| 5 | # Use of this source code is governed by a BSD-style license that can be |
| 6 | # found in the LICENSE file. |
| 7 | |
| 8 | import mock |
| 9 | |
| 10 | import common |
| 11 | |
| 12 | from autotest_lib.client.common_lib.test_utils import unittest |
| 13 | from autotest_lib.frontend import setup_django_environment |
| 14 | from autotest_lib.frontend.afe import frontend_test_utils |
| 15 | from autotest_lib.frontend.afe import models |
| 16 | from autotest_lib.scheduler import rdb |
| 17 | from autotest_lib.scheduler import rdb_lib |
| 18 | from autotest_lib.scheduler import rdb_testing_utils |
| 19 | |
| 20 | |
| 21 | class QueryManagerTests(rdb_testing_utils.AbstractBaseRDBTester, |
| 22 | unittest.TestCase): |
| 23 | """Verify scheduler behavior when pending jobs are already given hosts.""" |
| 24 | |
| 25 | _config_section = 'AUTOTEST_WEB' |
| 26 | |
| 27 | |
| 28 | def testPendingQueueEntries(self): |
| 29 | """Test retrieval of pending queue entries.""" |
| 30 | job = self.create_job(deps=set(['a'])) |
| 31 | |
| 32 | # Check that we don't pull the job we just created with only_hostless. |
| 33 | jobs_with_hosts = self.job_query_manager.get_pending_queue_entries( |
| 34 | only_hostless=True) |
| 35 | self.assertTrue(len(jobs_with_hosts) == 0) |
| 36 | |
| 37 | # Check that only_hostless=False pulls new jobs, as always. |
| 38 | jobs_without_hosts = self.job_query_manager.get_pending_queue_entries( |
| 39 | only_hostless=False) |
| 40 | self.assertTrue(jobs_without_hosts[0].id == job.id and |
| 41 | jobs_without_hosts[0].host_id is None) |
| 42 | |
| 43 | |
| 44 | def testHostQueries(self): |
| 45 | """Verify that the host query manager maintains its data structures.""" |
| 46 | # Create a job and use the host_query_managers internal datastructures |
| 47 | # to retrieve its job info. |
| 48 | job = self.create_job( |
| 49 | deps=rdb_testing_utils.DEFAULT_DEPS, |
| 50 | acls=rdb_testing_utils.DEFAULT_ACLS) |
| 51 | queue_entries = self._dispatcher._refresh_pending_queue_entries() |
| 52 | job_manager = rdb_lib.JobQueryManager(queue_entries) |
| 53 | job_info = job_manager.get_job_info(queue_entries[0]) |
| 54 | default_dep_ids = set([label.id for label in self.db_helper.get_labels( |
| 55 | name__in=rdb_testing_utils.DEFAULT_DEPS)]) |
| 56 | default_acl_ids = set([acl.id for acl in self.db_helper.get_acls( |
| 57 | name__in=rdb_testing_utils.DEFAULT_ACLS)]) |
| 58 | self.assertTrue(set(job_info['deps']) == default_dep_ids) |
| 59 | self.assertTrue(set(job_info['acls']) == default_acl_ids) |
| 60 | |
| 61 | |
| 62 | def testNewJobsWithHosts(self): |
| 63 | """Test that we handle inactive hqes with unleased hosts correctly.""" |
| 64 | # Create a job and assign it an unleased host, then check that the |
| 65 | # HQE becomes active and the host remains assigned to it. |
| 66 | job = self.create_job(deps=['a']) |
| 67 | host = self.db_helper.create_host('h1', deps=['a']) |
| 68 | self.db_helper.add_host_to_job(host, job.id) |
| 69 | |
| 70 | queue_entries = self._dispatcher._refresh_pending_queue_entries() |
| 71 | self._dispatcher._schedule_new_jobs() |
| 72 | |
| 73 | host = self.db_helper.get_host(hostname='h1')[0] |
| 74 | self.assertTrue(host.leased == True and |
| 75 | host.status == models.Host.Status.READY) |
| 76 | hqes = list(self.db_helper.get_hqes(host_id=host.id)) |
| 77 | self.assertTrue(len(hqes) == 1 and hqes[0].active and |
| 78 | hqes[0].status == models.HostQueueEntry.Status.QUEUED) |
| 79 | |
| 80 | |
| 81 | def testNewJobsWithInvalidHost(self): |
| 82 | """Test handling of inactive hqes assigned invalid, unleased hosts.""" |
| 83 | # Create a job and assign it an unleased host, then check that the |
| 84 | # HQE becomes DOES NOT become active, because we validate the |
| 85 | # assignment again. |
| 86 | job = self.create_job(deps=['a']) |
| 87 | host = self.db_helper.create_host('h1', deps=['b']) |
| 88 | self.db_helper.add_host_to_job(host, job.id) |
| 89 | |
| 90 | queue_entries = self._dispatcher._refresh_pending_queue_entries() |
| 91 | self._dispatcher._schedule_new_jobs() |
| 92 | |
| 93 | host = self.db_helper.get_host(hostname='h1')[0] |
| 94 | self.assertTrue(host.leased == False and |
| 95 | host.status == models.Host.Status.READY) |
| 96 | hqes = list(self.db_helper.get_hqes(host_id=host.id)) |
| 97 | self.assertTrue(len(hqes) == 1 and not hqes[0].active and |
| 98 | hqes[0].status == models.HostQueueEntry.Status.QUEUED) |
| 99 | |
| 100 | |
| 101 | def testNewJobsWithLeasedHost(self): |
| 102 | """Test handling of inactive hqes assigned leased hosts.""" |
| 103 | # Create a job and assign it a leased host, then check that the |
| 104 | # HQE does not become active through the scheduler, and that the |
| 105 | # host gets released. |
| 106 | job = self.create_job(deps=['a']) |
| 107 | host = self.db_helper.create_host('h1', deps=['b']) |
| 108 | self.db_helper.add_host_to_job(host, job.id) |
| 109 | host.leased = 1 |
| 110 | host.save() |
| 111 | |
| 112 | rdb.batch_acquire_hosts = mock.MagicMock() |
| 113 | queue_entries = self._dispatcher._refresh_pending_queue_entries() |
| 114 | self._dispatcher._schedule_new_jobs() |
| 115 | self.assertTrue(rdb.batch_acquire_hosts.call_count == 0) |
| 116 | host = self.db_helper.get_host(hostname='h1')[0] |
| 117 | self.assertTrue(host.leased == True and |
| 118 | host.status == models.Host.Status.READY) |
| 119 | hqes = list(self.db_helper.get_hqes(host_id=host.id)) |
| 120 | self.assertTrue(len(hqes) == 1 and not hqes[0].active and |
| 121 | hqes[0].status == models.HostQueueEntry.Status.QUEUED) |
| 122 | self.host_scheduler._release_hosts() |
| 123 | self.assertTrue(self.db_helper.get_host(hostname='h1')[0].leased == 0) |
| 124 | |
| 125 | |
| 126 | def testSpecialTaskOrdering(self): |
| 127 | """Test priority ordering of special tasks.""" |
| 128 | |
| 129 | # Create 2 special tasks, one with and one without an hqe. |
| 130 | # Then assign the same host to another active hqe and make |
| 131 | # sure we don't try scheduling either of these special tasks. |
| 132 | host = self.db_helper.create_host('h1', deps=['a']) |
| 133 | task1 = self.db_helper.create_special_task(host_id=host.id) |
| 134 | job = self.create_job(deps=['a']) |
| 135 | self.db_helper.add_host_to_job(host, job.id) |
| 136 | hqe = self.db_helper.get_hqes(job=job.id)[0] |
| 137 | task2 = self.db_helper.create_special_task(job.id) |
| 138 | tasks = self.job_query_manager.get_prioritized_special_tasks() |
| 139 | self.assertTrue(tasks[0].queue_entry_id is None and |
| 140 | tasks[1].queue_entry_id == hqe.id) |
| 141 | |
| 142 | job2 = self.create_job(deps=['a']) |
| 143 | self.db_helper.add_host_to_job(host, job2.id) |
| 144 | hqe2 = self.db_helper.get_hqes(job=job2.id)[0] |
| 145 | hqe2.status = models.HostQueueEntry.Status.RUNNING |
| 146 | hqe2.save() |
| 147 | tasks = self.job_query_manager.get_prioritized_special_tasks() |
| 148 | self.assertTrue(tasks == []) |
| 149 | |
| 150 | |