1c44ae99354228290914326d42ef1e743b5b7e4b8jamesren#!/usr/bin/python
276af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi#pylint: disable-msg=C0111
3c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
4c44ae99354228290914326d42ef1e743b5b7e4b8jamesrenimport datetime
5c44ae99354228290914326d42ef1e743b5b7e4b8jamesrenimport common
6c44ae99354228290914326d42ef1e743b5b7e4b8jamesrenfrom autotest_lib.frontend import setup_django_environment
7c44ae99354228290914326d42ef1e743b5b7e4b8jamesrenfrom autotest_lib.frontend.afe import frontend_test_utils
851599038f08395067097dc265127cfbcf77c427dFang Dengfrom autotest_lib.client.common_lib import host_queue_entry_states
9c44ae99354228290914326d42ef1e743b5b7e4b8jamesrenfrom autotest_lib.client.common_lib.test_utils import mock
10c44ae99354228290914326d42ef1e743b5b7e4b8jamesrenfrom autotest_lib.client.common_lib.test_utils import unittest
11c44ae99354228290914326d42ef1e743b5b7e4b8jamesrenfrom autotest_lib.database import database_connection
12dd855244f44b65d0508345c6fef74846652c8c26jamesrenfrom autotest_lib.frontend.afe import models, model_attributes
1376af802bd80edf50fd34efae25205c3aeaf82f25Dan Shifrom autotest_lib.scheduler import monitor_db
144ec9867f46deb969c154bebf2e64729d56c3a1d3Prashanth Bfrom autotest_lib.scheduler import scheduler_lib
15c44ae99354228290914326d42ef1e743b5b7e4b8jamesrenfrom autotest_lib.scheduler import scheduler_models
16c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
17c44ae99354228290914326d42ef1e743b5b7e4b8jamesren_DEBUG = False
18c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
19c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
20c44ae99354228290914326d42ef1e743b5b7e4b8jamesrenclass BaseSchedulerModelsTest(unittest.TestCase,
21c44ae99354228290914326d42ef1e743b5b7e4b8jamesren                              frontend_test_utils.FrontendTestMixin):
22c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    _config_section = 'AUTOTEST_WEB'
23c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
24c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def _do_query(self, sql):
25c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self._database.execute(sql)
26c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
27c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
28c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def _set_monitor_stubs(self):
29c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        # Clear the instance cache as this is a brand new database.
30c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        scheduler_models.DBObject._clear_instance_cache()
31c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
32c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self._database = (
33c44ae99354228290914326d42ef1e743b5b7e4b8jamesren            database_connection.TranslatingDatabase.get_test_database(
344ec9867f46deb969c154bebf2e64729d56c3a1d3Prashanth B                translators=scheduler_lib._DB_TRANSLATORS))
35c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self._database.connect(db_type='django')
36c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self._database.debug = _DEBUG
37c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
38c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.god.stub_with(scheduler_models, '_db', self._database)
39c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
40c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
41c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def setUp(self):
42c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self._frontend_common_setup()
43c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self._set_monitor_stubs()
44c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
45c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
46c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def tearDown(self):
47c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self._database.disconnect()
48c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self._frontend_common_teardown()
49c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
50c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
51c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def _update_hqe(self, set, where=''):
52c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        query = 'UPDATE afe_host_queue_entries SET ' + set
53c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        if where:
54c44ae99354228290914326d42ef1e743b5b7e4b8jamesren            query += ' WHERE ' + where
55c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self._do_query(query)
56c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
57c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
58c44ae99354228290914326d42ef1e743b5b7e4b8jamesrenclass DelayedCallTaskTest(unittest.TestCase):
59c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def setUp(self):
60c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.god = mock.mock_god()
61c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
62c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
63c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def tearDown(self):
64c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.god.unstub_all()
65c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
66c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
67c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def test_delayed_call(self):
68c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        test_time = self.god.create_mock_function('time')
69c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        test_time.expect_call().and_return(33)
70c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        test_time.expect_call().and_return(34.01)
71c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        test_time.expect_call().and_return(34.99)
72c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        test_time.expect_call().and_return(35.01)
73c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        def test_callback():
74c44ae99354228290914326d42ef1e743b5b7e4b8jamesren            test_callback.calls += 1
75c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        test_callback.calls = 0
76c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        delay_task = scheduler_models.DelayedCallTask(
77c44ae99354228290914326d42ef1e743b5b7e4b8jamesren                delay_seconds=2, callback=test_callback,
78c44ae99354228290914326d42ef1e743b5b7e4b8jamesren                now_func=test_time)  # time 33
79c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(35, delay_task.end_time)
80c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        delay_task.poll()  # activates the task and polls it once, time 34.01
81c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(0, test_callback.calls, "callback called early")
82c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        delay_task.poll()  # time 34.99
83c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(0, test_callback.calls, "callback called early")
84c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        delay_task.poll()  # time 35.01
85c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(1, test_callback.calls)
86c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assert_(delay_task.is_done())
87c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assert_(delay_task.success)
88c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assert_(not delay_task.aborted)
89c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.god.check_playback()
90c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
91c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
92c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def test_delayed_call_abort(self):
93c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        delay_task = scheduler_models.DelayedCallTask(
94c44ae99354228290914326d42ef1e743b5b7e4b8jamesren                delay_seconds=987654, callback=lambda : None)
95c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        delay_task.abort()
96c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assert_(delay_task.aborted)
97c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assert_(delay_task.is_done())
98c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assert_(not delay_task.success)
99c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.god.check_playback()
100c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
101c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
102c44ae99354228290914326d42ef1e743b5b7e4b8jamesrenclass DBObjectTest(BaseSchedulerModelsTest):
103c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def test_compare_fields_in_row(self):
104c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        host = scheduler_models.Host(id=1)
105c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        fields = list(host._fields)
106c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        row_data = [getattr(host, fieldname) for fieldname in fields]
107c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual({}, host._compare_fields_in_row(row_data))
108c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        row_data[fields.index('hostname')] = 'spam'
109c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual({'hostname': ('host1', 'spam')},
110c44ae99354228290914326d42ef1e743b5b7e4b8jamesren                         host._compare_fields_in_row(row_data))
111c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        row_data[fields.index('id')] = 23
112c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual({'hostname': ('host1', 'spam'), 'id': (1, 23)},
113c44ae99354228290914326d42ef1e743b5b7e4b8jamesren                         host._compare_fields_in_row(row_data))
114c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
115c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
116c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def test_compare_fields_in_row_datetime_ignores_microseconds(self):
117c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        datetime_with_us = datetime.datetime(2009, 10, 07, 12, 34, 56, 7890)
118c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        datetime_without_us = datetime.datetime(2009, 10, 07, 12, 34, 56, 0)
119c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        class TestTable(scheduler_models.DBObject):
120c44ae99354228290914326d42ef1e743b5b7e4b8jamesren            _table_name = 'test_table'
121c44ae99354228290914326d42ef1e743b5b7e4b8jamesren            _fields = ('id', 'test_datetime')
122c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        tt = TestTable(row=[1, datetime_without_us])
123c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual({}, tt._compare_fields_in_row([1, datetime_with_us]))
124c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
125c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
126c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def test_always_query(self):
127c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        host_a = scheduler_models.Host(id=2)
128c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(host_a.hostname, 'host2')
129c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self._do_query('UPDATE afe_hosts SET hostname="host2-updated" '
130c44ae99354228290914326d42ef1e743b5b7e4b8jamesren                       'WHERE id=2')
131c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        host_b = scheduler_models.Host(id=2, always_query=True)
132c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assert_(host_a is host_b, 'Cached instance not returned.')
133c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(host_a.hostname, 'host2-updated',
134c44ae99354228290914326d42ef1e743b5b7e4b8jamesren                         'Database was not re-queried')
135c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
136c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        # If either of these are called, a query was made when it shouldn't be.
137c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        host_a._compare_fields_in_row = lambda _: self.fail('eek! a query!')
138c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        host_a._update_fields_from_row = host_a._compare_fields_in_row
139c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        host_c = scheduler_models.Host(id=2, always_query=False)
140c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assert_(host_a is host_c, 'Cached instance not returned')
141c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
142c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
143c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def test_delete(self):
144c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        host = scheduler_models.Host(id=3)
145c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        host.delete()
146c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        host = self.assertRaises(scheduler_models.DBError, scheduler_models.Host, id=3,
147c44ae99354228290914326d42ef1e743b5b7e4b8jamesren                                 always_query=False)
148c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        host = self.assertRaises(scheduler_models.DBError, scheduler_models.Host, id=3,
149c44ae99354228290914326d42ef1e743b5b7e4b8jamesren                                 always_query=True)
150c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
151c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def test_save(self):
152c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        # Dummy Job to avoid creating a one in the HostQueueEntry __init__.
153c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        class MockJob(object):
154c44ae99354228290914326d42ef1e743b5b7e4b8jamesren            def __init__(self, id):
155c44ae99354228290914326d42ef1e743b5b7e4b8jamesren                pass
156c44ae99354228290914326d42ef1e743b5b7e4b8jamesren            def tag(self):
157c44ae99354228290914326d42ef1e743b5b7e4b8jamesren                return 'MockJob'
158c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.god.stub_with(scheduler_models, 'Job', MockJob)
159c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        hqe = scheduler_models.HostQueueEntry(
160c44ae99354228290914326d42ef1e743b5b7e4b8jamesren                new_record=True,
16151599038f08395067097dc265127cfbcf77c427dFang Deng                row=[0, 1, 2, 'Queued', None, 0, 0, 0, '.', None, False, None,
16251599038f08395067097dc265127cfbcf77c427dFang Deng                     None])
163c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        hqe.save()
164c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        new_id = hqe.id
165c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        # Force a re-query and verify that the correct data was stored.
166c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        scheduler_models.DBObject._clear_instance_cache()
167c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        hqe = scheduler_models.HostQueueEntry(id=new_id)
168c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(hqe.id, new_id)
169c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(hqe.job_id, 1)
170c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(hqe.host_id, 2)
171c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(hqe.status, 'Queued')
172c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(hqe.meta_host, None)
173c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(hqe.active, False)
174c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(hqe.complete, False)
175c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(hqe.deleted, False)
176c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(hqe.execution_subdir, '.')
177c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(hqe.atomic_group_id, None)
178c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(hqe.started_on, None)
17951599038f08395067097dc265127cfbcf77c427dFang Deng        self.assertEqual(hqe.finished_on, None)
180c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
181c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
182c44ae99354228290914326d42ef1e743b5b7e4b8jamesrenclass HostTest(BaseSchedulerModelsTest):
183c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def test_cmp_for_sort(self):
184c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        expected_order = [
185c44ae99354228290914326d42ef1e743b5b7e4b8jamesren                'alice', 'Host1', 'host2', 'host3', 'host09', 'HOST010',
186c44ae99354228290914326d42ef1e743b5b7e4b8jamesren                'host10', 'host11', 'yolkfolk']
187c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        hostname_idx = list(scheduler_models.Host._fields).index('hostname')
188c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        row = [None] * len(scheduler_models.Host._fields)
189c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        hosts = []
190c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        for hostname in expected_order:
191c44ae99354228290914326d42ef1e743b5b7e4b8jamesren            row[hostname_idx] = hostname
192c44ae99354228290914326d42ef1e743b5b7e4b8jamesren            hosts.append(scheduler_models.Host(row=row, new_record=True))
193c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
194c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        host1 = hosts[expected_order.index('Host1')]
195c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        host010 = hosts[expected_order.index('HOST010')]
196c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        host10 = hosts[expected_order.index('host10')]
197c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        host3 = hosts[expected_order.index('host3')]
198c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        alice = hosts[expected_order.index('alice')]
199c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(0, scheduler_models.Host.cmp_for_sort(host10, host10))
200c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(1, scheduler_models.Host.cmp_for_sort(host10, host010))
201c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(-1, scheduler_models.Host.cmp_for_sort(host010, host10))
202c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(-1, scheduler_models.Host.cmp_for_sort(host1, host10))
203c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(-1, scheduler_models.Host.cmp_for_sort(host1, host010))
204c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(-1, scheduler_models.Host.cmp_for_sort(host3, host10))
205c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(-1, scheduler_models.Host.cmp_for_sort(host3, host010))
206c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(1, scheduler_models.Host.cmp_for_sort(host3, host1))
207c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(-1, scheduler_models.Host.cmp_for_sort(host1, host3))
208c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(-1, scheduler_models.Host.cmp_for_sort(alice, host3))
209c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(1, scheduler_models.Host.cmp_for_sort(host3, alice))
210c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(0, scheduler_models.Host.cmp_for_sort(alice, alice))
211c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
212c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        hosts.sort(cmp=scheduler_models.Host.cmp_for_sort)
213c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(expected_order, [h.hostname for h in hosts])
214c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
215c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        hosts.reverse()
216c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        hosts.sort(cmp=scheduler_models.Host.cmp_for_sort)
217c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(expected_order, [h.hostname for h in hosts])
218c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
219c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
220c44ae99354228290914326d42ef1e743b5b7e4b8jamesrenclass HostQueueEntryTest(BaseSchedulerModelsTest):
221c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def _create_hqe(self, dependency_labels=(), **create_job_kwargs):
222c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        job = self._create_job(**create_job_kwargs)
223c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        for label in dependency_labels:
224c44ae99354228290914326d42ef1e743b5b7e4b8jamesren            job.dependency_labels.add(label)
225c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        hqes = list(scheduler_models.HostQueueEntry.fetch(where='job_id=%d' % job.id))
226c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(1, len(hqes))
227c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        return hqes[0]
228c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
229c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
230c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def _check_hqe_labels(self, hqe, expected_labels):
231c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        expected_labels = set(expected_labels)
232c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        label_names = set(label.name for label in hqe.get_labels())
233c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(expected_labels, label_names)
234c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
235c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
236c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def test_get_labels_empty(self):
237c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        hqe = self._create_hqe(hosts=[1])
238c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        labels = list(hqe.get_labels())
239c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual([], labels)
240c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
241c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
242c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def test_get_labels_metahost(self):
243c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        hqe = self._create_hqe(metahosts=[2])
244c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self._check_hqe_labels(hqe, ['label2'])
245c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
246c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
247c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def test_get_labels_dependancies(self):
248c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        hqe = self._create_hqe(dependency_labels=(self.label3, self.label4),
249c44ae99354228290914326d42ef1e743b5b7e4b8jamesren                               metahosts=[1])
250c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self._check_hqe_labels(hqe, ['label1', 'label3', 'label4'])
251c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
252c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
25376af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi    def setup_abort_test(self, agent_finished=True):
25476af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi        """Setup the variables for testing abort method.
25576af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi
25676af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi        @param agent_finished: True to mock agent is finished before aborting
25776af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi                               the hqe.
25876af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi        @return hqe, dispatcher: Mock object of hqe and dispatcher to be used
25976af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi                               to test abort method.
26076af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi        """
26176af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi        hqe = self._create_hqe(hosts=[1])
26276af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi        hqe.aborted = True
26376af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi        hqe.complete = False
26476af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi        hqe.status = models.HostQueueEntry.Status.STARTING
265d44a1238e7f6998e854de4f50816c34443fac462Fang Deng        hqe.started_on = datetime.datetime.now()
26676af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi
26776af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi        dispatcher = self.god.create_mock_class(monitor_db.BaseDispatcher,
26876af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi                                                'BaseDispatcher')
26976af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi        agent = self.god.create_mock_class(monitor_db.Agent, 'Agent')
27076af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi        dispatcher.get_agents_for_entry.expect_call(hqe).and_return([agent])
27176af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi        agent.is_done.expect_call().and_return(agent_finished)
27276af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi        return hqe, dispatcher
27376af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi
27476af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi
27576af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi    def test_abort_fail_with_unfinished_agent(self):
27676af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi        """abort should fail if the hqe still has agent not finished.
27776af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi        """
27876af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi        hqe, dispatcher = self.setup_abort_test(agent_finished=False)
27951599038f08395067097dc265127cfbcf77c427dFang Deng        self.assertIsNone(hqe.finished_on)
28076af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi        with self.assertRaises(AssertionError):
28176af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi            hqe.abort(dispatcher)
28276af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi        self.god.check_playback()
28351599038f08395067097dc265127cfbcf77c427dFang Deng        # abort failed, finished_on should not be set
28451599038f08395067097dc265127cfbcf77c427dFang Deng        self.assertIsNone(hqe.finished_on)
28576af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi
28676af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi
28776af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi    def test_abort_success(self):
28876af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi        """abort should succeed if all agents for the hqe are finished.
28976af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi        """
29076af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi        hqe, dispatcher = self.setup_abort_test(agent_finished=True)
29151599038f08395067097dc265127cfbcf77c427dFang Deng        self.assertIsNone(hqe.finished_on)
29276af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi        hqe.abort(dispatcher)
29376af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi        self.god.check_playback()
29451599038f08395067097dc265127cfbcf77c427dFang Deng        self.assertIsNotNone(hqe.finished_on)
29551599038f08395067097dc265127cfbcf77c427dFang Deng
29651599038f08395067097dc265127cfbcf77c427dFang Deng
29751599038f08395067097dc265127cfbcf77c427dFang Deng    def test_set_finished_on(self):
29851599038f08395067097dc265127cfbcf77c427dFang Deng        """Test that finished_on is set when hqe completes."""
29951599038f08395067097dc265127cfbcf77c427dFang Deng        for status in host_queue_entry_states.Status.values:
30051599038f08395067097dc265127cfbcf77c427dFang Deng            hqe = self._create_hqe(hosts=[1])
301d44a1238e7f6998e854de4f50816c34443fac462Fang Deng            hqe.started_on = datetime.datetime.now()
30226ef4260be1cd972a375081232af8bb543b6c5fcJakob Juelich            hqe.job.update_field('shard_id', 3)
30351599038f08395067097dc265127cfbcf77c427dFang Deng            self.assertIsNone(hqe.finished_on)
30451599038f08395067097dc265127cfbcf77c427dFang Deng            hqe.set_status(status)
30551599038f08395067097dc265127cfbcf77c427dFang Deng            if status in host_queue_entry_states.COMPLETE_STATUSES:
30651599038f08395067097dc265127cfbcf77c427dFang Deng                self.assertIsNotNone(hqe.finished_on)
30726ef4260be1cd972a375081232af8bb543b6c5fcJakob Juelich                self.assertIsNone(hqe.job.shard_id)
30851599038f08395067097dc265127cfbcf77c427dFang Deng            else:
30951599038f08395067097dc265127cfbcf77c427dFang Deng                self.assertIsNone(hqe.finished_on)
31026ef4260be1cd972a375081232af8bb543b6c5fcJakob Juelich                self.assertEquals(hqe.job.shard_id, 3)
31176af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi
31276af802bd80edf50fd34efae25205c3aeaf82f25Dan Shi
313c44ae99354228290914326d42ef1e743b5b7e4b8jamesrenclass JobTest(BaseSchedulerModelsTest):
314c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def setUp(self):
315c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        super(JobTest, self).setUp()
316c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
317c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        def _mock_create(**kwargs):
318c44ae99354228290914326d42ef1e743b5b7e4b8jamesren            task = models.SpecialTask(**kwargs)
319c44ae99354228290914326d42ef1e743b5b7e4b8jamesren            task.save()
32016e4d6c48cd5fd3aba9974099023c78a602215a7Alex Miller            self._tasks.append(task)
321c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.god.stub_with(models.SpecialTask.objects, 'create', _mock_create)
322c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
323c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
32407e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi    def _test_pre_job_tasks_helper(self,
32507e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi                            reboot_before=model_attributes.RebootBefore.ALWAYS):
326c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        """
327c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        Calls HQE._do_schedule_pre_job_tasks() and returns the created special
328c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        task
329c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        """
33016e4d6c48cd5fd3aba9974099023c78a602215a7Alex Miller        self._tasks = []
331c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        queue_entry = scheduler_models.HostQueueEntry.fetch('id = 1')[0]
33207e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi        queue_entry.job.reboot_before = reboot_before
333c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        queue_entry._do_schedule_pre_job_tasks()
33416e4d6c48cd5fd3aba9974099023c78a602215a7Alex Miller        return self._tasks
335c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
336c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
337c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def test_job_request_abort(self):
338c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        django_job = self._create_job(hosts=[5, 6], atomic_group=1)
339c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        job = scheduler_models.Job(django_job.id)
340c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        job.request_abort()
341c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        django_hqes = list(models.HostQueueEntry.objects.filter(job=job.id))
342c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        for hqe in django_hqes:
343c44ae99354228290914326d42ef1e743b5b7e4b8jamesren            self.assertTrue(hqe.aborted)
344c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
345c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
346c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def test__atomic_and_has_started__on_atomic(self):
347c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self._create_job(hosts=[5, 6], atomic_group=1)
348c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        job = scheduler_models.Job.fetch('id = 1')[0]
349c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertFalse(job._atomic_and_has_started())
350c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
351c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self._update_hqe("status='Pending'")
352c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertFalse(job._atomic_and_has_started())
353c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self._update_hqe("status='Verifying'")
354c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertFalse(job._atomic_and_has_started())
355c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertFalse(job._atomic_and_has_started())
356c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self._update_hqe("status='Failed'")
357c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertFalse(job._atomic_and_has_started())
358c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self._update_hqe("status='Stopped'")
359c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertFalse(job._atomic_and_has_started())
360c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
361c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self._update_hqe("status='Starting'")
362c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertTrue(job._atomic_and_has_started())
363c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self._update_hqe("status='Completed'")
364c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertTrue(job._atomic_and_has_started())
365c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self._update_hqe("status='Aborted'")
366c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
367c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
368c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def test__atomic_and_has_started__not_atomic(self):
369c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self._create_job(hosts=[1, 2])
370c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        job = scheduler_models.Job.fetch('id = 1')[0]
371c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertFalse(job._atomic_and_has_started())
372c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self._update_hqe("status='Starting'")
373c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertFalse(job._atomic_and_has_started())
374c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
375c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
37616e4d6c48cd5fd3aba9974099023c78a602215a7Alex Miller    def _check_special_tasks(self, tasks, task_types):
37716e4d6c48cd5fd3aba9974099023c78a602215a7Alex Miller        self.assertEquals(len(tasks), len(task_types))
37816e4d6c48cd5fd3aba9974099023c78a602215a7Alex Miller        for task, (task_type, queue_entry_id) in zip(tasks, task_types):
37916e4d6c48cd5fd3aba9974099023c78a602215a7Alex Miller            self.assertEquals(task.task, task_type)
38016e4d6c48cd5fd3aba9974099023c78a602215a7Alex Miller            self.assertEquals(task.host.id, 1)
38116e4d6c48cd5fd3aba9974099023c78a602215a7Alex Miller            if queue_entry_id:
38216e4d6c48cd5fd3aba9974099023c78a602215a7Alex Miller                self.assertEquals(task.queue_entry.id, queue_entry_id)
383c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
384c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
385c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def test_run_asynchronous(self):
386c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self._create_job(hosts=[1, 2])
387c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
38816e4d6c48cd5fd3aba9974099023c78a602215a7Alex Miller        tasks = self._test_pre_job_tasks_helper()
389c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
39007e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi        self._check_special_tasks(tasks, [(models.SpecialTask.Task.RESET, 1)])
391c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
392c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
393c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def test_run_asynchronous_skip_verify(self):
394c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        job = self._create_job(hosts=[1, 2])
395c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        job.run_verify = False
396c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        job.save()
397c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
39816e4d6c48cd5fd3aba9974099023c78a602215a7Alex Miller        tasks = self._test_pre_job_tasks_helper()
399c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
40007e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi        self._check_special_tasks(tasks, [(models.SpecialTask.Task.RESET, 1)])
401c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
402c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
403c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def test_run_synchronous_verify(self):
404c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self._create_job(hosts=[1, 2], synchronous=True)
405c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
40616e4d6c48cd5fd3aba9974099023c78a602215a7Alex Miller        tasks = self._test_pre_job_tasks_helper()
407c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
40807e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi        self._check_special_tasks(tasks, [(models.SpecialTask.Task.RESET, 1)])
409c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
410c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
411c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def test_run_synchronous_skip_verify(self):
412c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        job = self._create_job(hosts=[1, 2], synchronous=True)
413c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        job.run_verify = False
414c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        job.save()
415c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
41616e4d6c48cd5fd3aba9974099023c78a602215a7Alex Miller        tasks = self._test_pre_job_tasks_helper()
417c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
41807e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi        self._check_special_tasks(tasks, [(models.SpecialTask.Task.RESET, 1)])
41907e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi
42007e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi
42107e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi    def test_run_asynchronous_do_not_reset(self):
42207e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi        job = self._create_job(hosts=[1, 2])
42307e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi        job.run_reset = False
42407e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi        job.run_verify = False
42507e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi        job.save()
42607e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi
42707e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi        tasks = self._test_pre_job_tasks_helper()
42807e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi
42916e4d6c48cd5fd3aba9974099023c78a602215a7Alex Miller        self.assertEquals(tasks, [])
430c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
431c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
43207e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi    def test_run_synchronous_do_not_reset_no_RebootBefore(self):
43307e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi        job = self._create_job(hosts=[1, 2], synchronous=True)
43407e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi        job.reboot_before = model_attributes.RebootBefore.NEVER
43507e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi        job.save()
43607e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi
43707e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi        tasks = self._test_pre_job_tasks_helper(
43807e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi                            reboot_before=model_attributes.RebootBefore.NEVER)
43907e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi
4406ee996fd9252ae7d0c56d2daa6cf085c3e02358cAlex Miller        self._check_special_tasks(tasks, [(models.SpecialTask.Task.VERIFY, 1)])
44107e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi
44207e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi
44307e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi    def test_run_asynchronous_do_not_reset(self):
44407e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi        job = self._create_job(hosts=[1, 2], synchronous=False)
44507e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi        job.reboot_before = model_attributes.RebootBefore.NEVER
44607e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi        job.save()
44707e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi
44807e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi        tasks = self._test_pre_job_tasks_helper(
44907e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi                            reboot_before=model_attributes.RebootBefore.NEVER)
45007e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi
4516ee996fd9252ae7d0c56d2daa6cf085c3e02358cAlex Miller        self._check_special_tasks(tasks, [(models.SpecialTask.Task.VERIFY, 1)])
45207e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi
45307e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi
454c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def test_run_atomic_group_already_started(self):
455c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self._create_job(hosts=[5, 6], atomic_group=1, synchronous=True)
456c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self._update_hqe("status='Starting', execution_subdir=''")
457c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
458c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        job = scheduler_models.Job.fetch('id = 1')[0]
459c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        queue_entry = scheduler_models.HostQueueEntry.fetch('id = 1')[0]
460c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        assert queue_entry.job is job
461c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual(None, job.run(queue_entry))
462c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
463c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.god.check_playback()
464c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
465c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
466c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def test_reboot_before_always(self):
467c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        job = self._create_job(hosts=[1])
468dd855244f44b65d0508345c6fef74846652c8c26jamesren        job.reboot_before = model_attributes.RebootBefore.ALWAYS
469c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        job.save()
470c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
47116e4d6c48cd5fd3aba9974099023c78a602215a7Alex Miller        tasks = self._test_pre_job_tasks_helper()
472c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
47316e4d6c48cd5fd3aba9974099023c78a602215a7Alex Miller        self._check_special_tasks(tasks, [
47407e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi                (models.SpecialTask.Task.RESET, None)
47516e4d6c48cd5fd3aba9974099023c78a602215a7Alex Miller            ])
476c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
477c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
47807e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi    def _test_reboot_before_if_dirty_helper(self):
479c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        job = self._create_job(hosts=[1])
480dd855244f44b65d0508345c6fef74846652c8c26jamesren        job.reboot_before = model_attributes.RebootBefore.IF_DIRTY
481c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        job.save()
482c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
48316e4d6c48cd5fd3aba9974099023c78a602215a7Alex Miller        tasks = self._test_pre_job_tasks_helper()
48407e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi        task_types = [(models.SpecialTask.Task.RESET, None)]
48516e4d6c48cd5fd3aba9974099023c78a602215a7Alex Miller
48616e4d6c48cd5fd3aba9974099023c78a602215a7Alex Miller        self._check_special_tasks(tasks, task_types)
487c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
488c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
489c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def test_reboot_before_if_dirty(self):
490c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        models.Host.smart_get(1).update_object(dirty=True)
49107e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi        self._test_reboot_before_if_dirty_helper()
492c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
493c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
494c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def test_reboot_before_not_dirty(self):
495c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        models.Host.smart_get(1).update_object(dirty=False)
49607e09aff0baf871b33e5479e337e5e3e0523b729Dan Shi        self._test_reboot_before_if_dirty_helper()
497c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
498c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
499c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    def test_next_group_name(self):
500c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        django_job = self._create_job(metahosts=[1])
501c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        job = scheduler_models.Job(id=django_job.id)
502c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual('group0', job._next_group_name())
503c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
504c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        for hqe in django_job.hostqueueentry_set.filter():
505c44ae99354228290914326d42ef1e743b5b7e4b8jamesren            hqe.execution_subdir = 'my_rack.group0'
506c44ae99354228290914326d42ef1e743b5b7e4b8jamesren            hqe.save()
507c44ae99354228290914326d42ef1e743b5b7e4b8jamesren        self.assertEqual('my_rack.group1', job._next_group_name('my/rack'))
508c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
509c44ae99354228290914326d42ef1e743b5b7e4b8jamesren
510c44ae99354228290914326d42ef1e743b5b7e4b8jamesrenif __name__ == '__main__':
511c44ae99354228290914326d42ef1e743b5b7e4b8jamesren    unittest.main()
512