Beispiel #1
0
 def setup_job(self):
     mock_graph = mock.Mock(autospec=True)
     mock_graph.get_action_map.return_value = {}
     mock_graph.action_map = {}
     self.job = mock.Mock(autospec=True)
     self.job.allow_overlap = False
     self.job.max_runtime = datetime.timedelta(days=1)
     self.job_scheduler = JobScheduler(job=self.job)
Beispiel #2
0
class TestJobSchedulerGetRunsToSchedule(TestCase):
    @setup
    def setup_job(self):
        self.scheduler = mock.Mock()
        run_collection = mock.Mock(has_pending=False)
        node_pool = mock.Mock()
        self.job = job.Job(
            "jobname",
            self.scheduler,
            run_collection=run_collection,
            node_pool=node_pool,
        )
        self.job_scheduler = JobScheduler(self.job)
        self.job.runs.get_pending.return_value = False
        self.scheduler.queue_overlapping = True

    def test_get_runs_to_schedule_no_queue_with_pending(self):
        self.scheduler.queue_overlapping = False
        self.job.runs.has_pending = True
        job_runs = self.job_scheduler.get_runs_to_schedule(False)
        assert_length(job_runs, 0)

    def test_get_runs_to_schedule_queue_with_pending(self):
        job_runs = list(self.job_scheduler.get_runs_to_schedule(False))

        self.job.runs.get_newest.assert_called_with(include_manual=False)
        self.job.scheduler.next_run_time.assert_called_once_with(
            self.job.runs.get_newest.return_value.run_time,
        )
        assert_length(job_runs, 1)
        # This should return a JobRun which has the job attached as an observer
        job_runs[0].attach.assert_any_call(True, self.job)

    def test_get_runs_to_schedule_no_pending(self):
        job_runs = list(self.job_scheduler.get_runs_to_schedule(False))

        self.job.runs.get_newest.assert_called_with(include_manual=False)
        self.job.scheduler.next_run_time.assert_called_once_with(
            self.job.runs.get_newest.return_value.run_time,
        )
        assert_length(job_runs, 1)
        # This should return a JobRun which has the job attached as an observer
        job_runs[0].attach.assert_any_call(True, self.job)

    def test_get_runs_to_schedule_no_last_run(self):
        self.job.runs.get_newest.return_value = None

        job_runs = list(self.job_scheduler.get_runs_to_schedule(False))
        self.job.scheduler.next_run_time.assert_called_once_with(None)
        assert_length(job_runs, 1)
        # This should return a JobRun which has the job attached as an observer
        job_runs[0].attach.assert_any_call(True, self.job)

    def test_get_runs_to_schedule_ignore_last(self):
        job_runs = list(self.job_scheduler.get_runs_to_schedule(True))
        self.job.scheduler.next_run_time.assert_called_once_with(None)
        assert_length(job_runs, 1)
        self.scheduler.next_run_time.assert_called_once_with(None)
class TestJobSchedulerGetRunsToSchedule(TestCase):
    @setup
    def setup_job(self):
        self.scheduler = mock.Mock()
        run_collection = mock.Mock(has_pending=False)
        node_pool = mock.Mock()
        self.job = job.Job(
            "jobname",
            self.scheduler,
            run_collection=run_collection,
            node_pool=node_pool,
        )
        self.job_scheduler = JobScheduler(self.job)
        self.job.runs.get_pending.return_value = False
        self.scheduler.queue_overlapping = True

    def test_get_runs_to_schedule_no_queue_with_pending(self):
        self.scheduler.queue_overlapping = False
        self.job.runs.has_pending = True
        job_runs = self.job_scheduler.get_runs_to_schedule(False)
        assert_length(job_runs, 0)

    def test_get_runs_to_schedule_queue_with_pending(self):
        job_runs = list(self.job_scheduler.get_runs_to_schedule(False))

        self.job.runs.get_newest.assert_called_with(include_manual=False)
        self.job.scheduler.next_run_time.assert_called_once_with(
            self.job.runs.get_newest.return_value.run_time,
        )
        assert_length(job_runs, 1)
        # This should return a JobRun which has the job attached as an observer
        job_runs[0].attach.assert_any_call(True, self.job)

    def test_get_runs_to_schedule_no_pending(self):
        job_runs = list(self.job_scheduler.get_runs_to_schedule(False))

        self.job.runs.get_newest.assert_called_with(include_manual=False)
        self.job.scheduler.next_run_time.assert_called_once_with(
            self.job.runs.get_newest.return_value.run_time,
        )
        assert_length(job_runs, 1)
        # This should return a JobRun which has the job attached as an observer
        job_runs[0].attach.assert_any_call(True, self.job)

    def test_get_runs_to_schedule_no_last_run(self):
        self.job.runs.get_newest.return_value = None

        job_runs = list(self.job_scheduler.get_runs_to_schedule(False))
        self.job.scheduler.next_run_time.assert_called_once_with(None)
        assert_length(job_runs, 1)
        # This should return a JobRun which has the job attached as an observer
        job_runs[0].attach.assert_any_call(True, self.job)

    def test_get_runs_to_schedule_ignore_last(self):
        job_runs = list(self.job_scheduler.get_runs_to_schedule(True))
        self.job.scheduler.next_run_time.assert_called_once_with(None)
        assert_length(job_runs, 1)
        self.scheduler.next_run_time.assert_called_once_with(None)
 def setup_job(self):
     self.scheduler = mock.Mock()
     run_collection = mock.Mock(has_pending=False)
     node_pool = mock.Mock()
     self.job = job.Job(
         "jobname",
         self.scheduler,
         run_collection=run_collection,
         node_pool=node_pool,
     )
     self.job_scheduler = JobScheduler(self.job)
     self.job.runs.get_pending.return_value = False
     self.scheduler.queue_overlapping = True
 def setup_job(self):
     self.scheduler = mock.Mock()
     run_collection = mock.Mock()
     node_pool = mock.Mock()
     self.job = job.Job(
         "jobname",
         self.scheduler,
         run_collection=run_collection,
         node_pool=node_pool,
     )
     self.job_scheduler = JobScheduler(self.job)
     self.manual_run = mock.Mock()
     self.job.build_new_runs = mock.Mock(return_value=[self.manual_run])
Beispiel #6
0
class JobSchedulerManualStartTestCase(testingutils.MockTimeTestCase):

    now = datetime.datetime.now()

    @setup
    def setup_job(self):
        self.scheduler = mock.Mock()
        run_collection = mock.Mock()
        node_pool = mock.Mock()
        self.job = job.Job(
            "jobname",
            self.scheduler,
            run_collection=run_collection,
            node_pool=node_pool,
        )
        self.job_scheduler = JobScheduler(self.job)
        self.manual_run = mock.Mock()
        self.job.build_new_runs = mock.Mock(return_value=[self.manual_run])

    def test_manual_start(self):
        manual_runs = self.job_scheduler.manual_start()

        self.job.build_new_runs.assert_called_with(self.now, manual=True)
        assert_length(manual_runs, 1)
        self.manual_run.start.assert_called_once_with()

    def test_manual_start_default_with_timezone(self):
        self.job.time_zone = mock.Mock()
        with mock.patch(
            'tron.core.job_scheduler.timeutils.current_time',
            autospec=True,
        ) as mock_current:
            manual_runs = self.job_scheduler.manual_start()
            mock_current.assert_called_with(tz=self.job.time_zone)
            self.job.build_new_runs.assert_called_with(
                mock_current.return_value,
                manual=True,
            )
        assert_length(manual_runs, 1)
        self.manual_run.start.assert_called_once_with()

    def test_manual_start_with_run_time(self):
        run_time = datetime.datetime(2012, 3, 14, 15, 9, 26)
        manual_runs = self.job_scheduler.manual_start(run_time)

        self.job.build_new_runs.assert_called_with(run_time, manual=True)
        assert_length(manual_runs, 1)
        self.manual_run.start.assert_called_once_with()
class JobSchedulerManualStartTestCase(testingutils.MockTimeTestCase):

    now = datetime.datetime.now()

    @setup
    def setup_job(self):
        self.scheduler = mock.Mock()
        run_collection = mock.Mock()
        node_pool = mock.Mock()
        self.job = job.Job(
            "jobname",
            self.scheduler,
            run_collection=run_collection,
            node_pool=node_pool,
        )
        self.job_scheduler = JobScheduler(self.job)
        self.manual_run = mock.Mock()
        self.job.build_new_runs = mock.Mock(return_value=[self.manual_run])

    def test_manual_start(self):
        manual_runs = self.job_scheduler.manual_start()

        self.job.build_new_runs.assert_called_with(self.now, manual=True)
        assert_length(manual_runs, 1)
        self.manual_run.start.assert_called_once_with()

    def test_manual_start_default_with_timezone(self):
        self.job.time_zone = mock.Mock()
        with mock.patch(
            'tron.core.job_scheduler.timeutils.current_time',
            autospec=True,
        ) as mock_current:
            manual_runs = self.job_scheduler.manual_start()
            mock_current.assert_called_with(tz=self.job.time_zone)
            self.job.build_new_runs.assert_called_with(
                mock_current.return_value,
                manual=True,
            )
        assert_length(manual_runs, 1)
        self.manual_run.start.assert_called_once_with()

    def test_manual_start_with_run_time(self):
        run_time = datetime.datetime(2012, 3, 14, 15, 9, 26)
        manual_runs = self.job_scheduler.manual_start(run_time)

        self.job.build_new_runs.assert_called_with(run_time, manual=True)
        assert_length(manual_runs, 1)
        self.manual_run.start.assert_called_once_with()
Beispiel #8
0
 def setup_job(self):
     self.scheduler = scheduler.ConstantScheduler()
     mock_graph = mock.Mock(autospec=True)
     mock_graph.get_action_map.return_value = {}
     mock_graph.action_map = {}
     self.job = mock.Mock(autospec=True)
     self.job.allow_overlap = False
     self.job.max_runtime = datetime.timedelta(days=1)
     self.job_scheduler = JobScheduler(job=self.job)
Beispiel #9
0
 def _make_job_scheduler(self, job_name, enabled=True):
     scheduler = mock.Mock()
     run_collection = mock.Mock()
     node_pool = mock.Mock()
     new_job = job.Job(
         job_name,
         scheduler,
         run_collection=run_collection,
         node_pool=node_pool,
         enabled=enabled,
     )
     return new_job, JobScheduler(new_job)
Beispiel #10
0
 def setup_job(self):
     self.scheduler = mock.Mock()
     run_collection = mock.Mock(has_pending=False)
     node_pool = mock.Mock()
     self.job = job.Job(
         "jobname",
         self.scheduler,
         run_collection=run_collection,
         node_pool=node_pool,
     )
     self.job_scheduler = JobScheduler(self.job)
     self.job.runs.get_pending.return_value = False
     self.scheduler.queue_overlapping = True
Beispiel #11
0
 def setup_job(self):
     self.scheduler = mock.Mock()
     run_collection = mock.Mock()
     node_pool = mock.Mock()
     self.job = job.Job(
         "jobname",
         self.scheduler,
         run_collection=run_collection,
         node_pool=node_pool,
     )
     self.job_scheduler = JobScheduler(self.job)
     self.manual_run = mock.Mock()
     self.job.build_new_runs = mock.Mock(return_value=[self.manual_run])
class TestJobSchedulerGetRunsToSchedule(TestCase):
    @setup
    def setup_job(self):
        self.scheduler = mock.Mock()
        run_collection = mock.Mock(has_pending=False)
        node_pool = mock.Mock()
        self.job = job.Job(
            "jobname",
            self.scheduler,
            run_collection=run_collection,
            node_pool=node_pool,
        )
        self.job_scheduler = JobScheduler(self.job)
        self.job.runs.get_pending.return_value = False
        self.scheduler.queue_overlapping = True

    def test_get_runs_to_schedule_with_pending(self):
        self.scheduler.queue_overlapping = False
        self.job.runs.has_pending = True
        job_runs = self.job_scheduler.get_runs_to_schedule(None)
        assert_length(job_runs, 0)

    def test_get_runs_to_schedule_guess(self):
        job_runs = list(self.job_scheduler.get_runs_to_schedule(None))

        assert self.job.scheduler.next_run_time.call_args_list == [mock.call(None)]
        assert_length(job_runs, 1)
        # This should return a JobRun which has the job attached as an observer
        job_runs[0].attach.assert_any_call(True, self.job)

    def test_get_runs_to_schedule_given(self):
        now = datetime.datetime.now()
        job_runs = list(self.job_scheduler.get_runs_to_schedule(now))

        assert self.job.scheduler.next_run_time.call_count == 0
        assert_length(job_runs, 1)
        # This should return a JobRun which has the job attached as an observer
        job_runs[0].attach.assert_any_call(True, self.job)
Beispiel #13
0
 def setup_job(self):
     self.scheduler = mock.Mock(autospec=True)
     self.scheduler.next_run_time.return_value = 0
     mock_run = mock.Mock()
     mock_run.seconds_until_run_time.return_value = 0
     run_collection = mock.Mock(
         has_pending=False,
         autospec=True,
         return_value=[mock_run],
     )
     mock_build_new_run = mock.Mock()
     run_collection.build_new_run.return_value = mock_build_new_run
     mock_build_new_run.seconds_until_run_time.return_value = 0
     node_pool = mock.Mock()
     self.job = job.Job(
         name="jobname",
         scheduler=self.scheduler,
         run_collection=run_collection,
         node_pool=node_pool,
     )
     self.job_scheduler = JobScheduler(self.job)
     self.original_build_new_runs = self.job.build_new_runs
     self.job.build_new_runs = mock.Mock(return_value=[mock_run])
Beispiel #14
0
 def setup_job(self):
     self.scheduler = mock.Mock(autospec=True)
     self.scheduler.next_run_time.return_value = 0
     mock_run = mock.Mock()
     mock_run.seconds_until_run_time.return_value = 0
     run_collection = mock.Mock(
         has_pending=False,
         autospec=True,
         return_value=[mock_run],
     )
     mock_build_new_run = mock.Mock()
     run_collection.build_new_run.return_value = mock_build_new_run
     mock_build_new_run.seconds_until_run_time.return_value = 0
     node_pool = mock.Mock()
     self.job = job.Job(
         name="jobname",
         scheduler=self.scheduler,
         run_collection=run_collection,
         node_pool=node_pool,
     )
     self.job_scheduler = JobScheduler(self.job)
     self.original_build_new_runs = self.job.build_new_runs
     self.job.build_new_runs = mock.Mock(return_value=[mock_run])
Beispiel #15
0
class TestJobScheduler(TestCase):
    @setup
    def setup_job(self):
        mock_graph = mock.Mock(autospec=True)
        mock_graph.get_action_map.return_value = {}
        mock_graph.action_map = {}
        self.job = mock.Mock(autospec=True)
        self.job.allow_overlap = False
        self.job.max_runtime = datetime.timedelta(days=1)
        self.job_scheduler = JobScheduler(job=self.job)

    def test_restore_state_sets_job_runs(self):
        self.job.enabled = False
        mock_runs = [mock.Mock(), mock.Mock()]
        mock_action_runner = mock.Mock()
        job_state_data = {'runs': mock_runs, 'enabled': True}

        self.job_scheduler._set_callback = lambda x: x

        self.job.runs.runs = collections.deque()
        self.job.runs.get_scheduled.return_value = [mock.Mock()]
        self.job.get_job_runs_from_state.return_value = mock_runs

        with mock.patch(
                'tron.core.job_scheduler.recovery.launch_recovery_actionruns_for_job_runs',
                autospec=True,
        ) as mock_launch_recovery:
            mock_launch_recovery.return_value = mock.Mock(autospec=True)
            self.job_scheduler.restore_state(job_state_data,
                                             mock_action_runner)
            assert self.job.runs.runs == collections.deque(mock_runs)
            mock_launch_recovery.assert_called_once_with(
                job_runs=mock_runs, master_action_runner=mock_action_runner)
            calls = [mock.call(mock_runs[i]) for i in range(0, len(mock_runs))]
            self.job.watch.assert_has_calls(calls)

    def test_create_and_schedule_runs_specific_time(self):
        self.job_scheduler.get_runs_to_schedule = mock.Mock(
            return_value=[mock.Mock()])
        self.job_scheduler._set_callback = mock.Mock()
        self.job_scheduler.create_and_schedule_runs(next_run_time='a_datetime')
        assert self.job_scheduler.get_runs_to_schedule.call_args_list == [
            mock.call('a_datetime')
        ]

    def test_create_and_schedule_runs_guess(self):
        self.job_scheduler.get_runs_to_schedule = mock.Mock(
            return_value=[mock.Mock()])
        self.job_scheduler._set_callback = mock.Mock()
        self.job_scheduler.create_and_schedule_runs(next_run_time=None)
        assert self.job_scheduler.get_runs_to_schedule.call_args_list == [
            mock.call(None)
        ]

    def test_disable(self):
        self.job_scheduler.disable()
        assert self.job_scheduler.job.enabled is False
        self.job_scheduler.job.runs.cancel_pending.assert_called_once()

    def test_schedule_reconfigured(self):
        pending_run = mock.Mock()
        pending_run.run_time = 'a_run_time'
        self.job.runs.get_pending.return_value = [pending_run]
        self.job_scheduler.create_and_schedule_runs = mock.Mock()

        self.job_scheduler.schedule_reconfigured()

        assert self.job.runs.remove_pending.call_count == 1
        assert self.job_scheduler.create_and_schedule_runs.call_args_list == [
            mock.call(next_run_time='a_run_time', )
        ]

    def test_schedule(self):
        self.job.enabled = True
        last_run = mock.Mock()
        last_run.run_time = 'a_run_time'
        self.job.runs.get_newest = mock.Mock(return_value=last_run)
        self.job_scheduler.create_and_schedule_runs = mock.Mock()

        self.job_scheduler.schedule()

        self.job.scheduler.next_run_time.assert_called_once_with('a_run_time')
        assert self.job_scheduler.create_and_schedule_runs.call_args_list == [
            mock.call(
                next_run_time=self.job.scheduler.next_run_time.return_value),
        ]

    def test_run_job(self):
        self.job_scheduler.schedule = mock.Mock(autospec=True)
        self.job.scheduler.schedule_on_complete = False
        self.job.runs.get_active = lambda n: []
        job_run = mock.Mock(autospec=True)
        job_run.is_cancelled = False
        self.job_scheduler.run_job(job_run)
        job_run.start.assert_called_once()
        self.job_scheduler.schedule.assert_called_once()

    def test_run_job_job_disabled(self):
        self.job_scheduler.schedule = MagicMock()
        job_run = MagicMock()
        self.job.enabled = False
        self.job_scheduler.run_job(job_run)
        assert_length(self.job_scheduler.schedule.mock_calls, 0)
        assert_length(job_run.start.mock_calls, 0)
        assert_length(job_run.cancel.mock_calls, 1)

    def test_run_job_cancelled(self):
        self.job_scheduler.schedule = MagicMock()
        job_run = MagicMock(is_scheduled=False)
        self.job_scheduler.run_job(job_run)
        assert_length(job_run.start.mock_calls, 0)
        assert_length(self.job_scheduler.schedule.mock_calls, 1)

    def test_run_job_already_running_queuing(self):
        self.job_scheduler.schedule = mock.Mock(autospec=True)
        self.job.runs.get_active = lambda s: [mock.Mock(autospec=True)]
        job_run = mock.Mock(autospec=True)
        job_run.is_cancelled = False
        self.job_scheduler.run_job(job_run)
        assert not job_run.start.called
        job_run.queue.assert_called_once()
        assert not self.job_scheduler.schedule.called

    def test_run_job_already_running_cancel(self):
        self.job_scheduler.schedule = mock.Mock(autospec=True)
        self.job.runs.get_active = lambda s: [mock.Mock(autospec=True)]
        self.job.queueing = False
        job_run = mock.Mock(autospec=True)
        job_run.is_cancelled = False
        self.job_scheduler.run_job(job_run)
        assert not job_run.start.called
        job_run.cancel.assert_called_once()
        self.job_scheduler.schedule.assert_called_once()

    def test_run_job_already_running_allow_overlap(self):
        self.job_scheduler.schedule = mock.Mock()
        self.job.runs.get_active = lambda s: [mock.Mock()]
        self.job.allow_overlap = True
        job_run = MagicMock(is_cancelled=False)
        self.job_scheduler.run_job(job_run)
        job_run.start.assert_called_with()

    def test_run_job_has_starting_queueing(self):
        self.job_scheduler.schedule = mock.Mock(autospec=True)
        self.job.runs.get_active = lambda s: [mock.Mock(autospec=True)]
        job_run = mock.Mock(autospec=True)
        job_run.is_cancelled = False
        self.job_scheduler.run_job(job_run)
        assert not job_run.start.called
        job_run.queue.assert_called_once()
        assert not self.job_scheduler.schedule.called

    def test_run_job_schedule_on_complete(self):
        self.job_scheduler.schedule = MagicMock()
        self.job.scheduler.schedule_on_complete = True
        self.job.runs.get_active = lambda s: []
        job_run = MagicMock(is_cancelled=False)
        self.job_scheduler.run_job(job_run)
        assert_length(job_run.start.mock_calls, 1)
        assert_length(self.job_scheduler.schedule.mock_calls, 0)
Beispiel #16
0
class TestJobScheduler(TestCase):
    @setup
    def setup_job(self):
        self.scheduler = scheduler.ConstantScheduler()
        mock_graph = mock.Mock(autospec=True)
        mock_graph.get_action_map.return_value = {}
        mock_graph.action_map = {}
        self.job = mock.Mock(autospec=True)
        self.job.allow_overlap = False
        self.job.max_runtime = datetime.timedelta(days=1)
        self.job_scheduler = JobScheduler(job=self.job)

    def test_restore_state_sets_job_runs(self):
        self.job.enabled = False
        mock_runs = [mock.Mock(), mock.Mock()]
        mock_action_runner = mock.Mock()
        job_state_data = {'runs': mock_runs, 'enabled': True}

        self.job_scheduler._set_callback = lambda x: x

        self.job.runs.runs = collections.deque()
        self.job.runs.get_scheduled.return_value = [mock.Mock()]
        self.job.get_job_runs_from_state.return_value = mock_runs

        with mock.patch(
            'tron.core.job_scheduler.recovery.launch_recovery_actionruns_for_job_runs',
            autospec=True,
        ) as mock_launch_recovery:
            mock_launch_recovery.return_value = mock.Mock(autospec=True)
            self.job_scheduler.restore_state(
                job_state_data, mock_action_runner
            )
            assert self.job.runs.runs == collections.deque(mock_runs)
            mock_launch_recovery.assert_called_once_with(
                job_runs=mock_runs, master_action_runner=mock_action_runner
            )
            calls = [mock.call(mock_runs[i]) for i in range(0, len(mock_runs))]
            self.job.watch.assert_has_calls(calls)

    def test_disable(self):
        self.job_scheduler.disable()
        assert self.job_scheduler.job.enabled is False
        self.job_scheduler.job.runs.cancel_pending.assert_called_once()

    def test_schedule_reconfigured(self):
        self.job_scheduler.schedule_reconfigured()
        self.job.runs.remove_pending.assert_called_once()

    def test_run_job(self):
        self.job_scheduler.schedule = mock.Mock(autospec=True)
        self.scheduler.schedule_on_complete = False
        self.job.runs.get_active = lambda n: []
        job_run = mock.Mock(autospec=True)
        job_run.is_cancelled = False
        self.job_scheduler.run_job(job_run)
        assert job_run.start.called_once()
        assert self.job_scheduler.schedule.called_once()

    def test_run_job_job_disabled(self):
        self.job_scheduler.schedule = MagicMock()
        job_run = MagicMock()
        self.job.enabled = False
        self.job_scheduler.run_job(job_run)
        assert_length(self.job_scheduler.schedule.mock_calls, 0)
        assert_length(job_run.start.mock_calls, 0)
        assert_length(job_run.cancel.mock_calls, 1)

    def test_run_job_cancelled(self):
        self.job_scheduler.schedule = MagicMock()
        job_run = MagicMock(is_scheduled=False)
        self.job_scheduler.run_job(job_run)
        assert_length(job_run.start.mock_calls, 0)
        assert_length(self.job_scheduler.schedule.mock_calls, 1)

    def test_run_job_already_running_queuing(self):
        self.job_scheduler.schedule = mock.Mock(autospec=True)
        self.job.runs.get_active = lambda s: [mock.Mock(autospec=True)]
        job_run = mock.Mock(autospec=True)
        job_run.is_cancelled = False
        self.job_scheduler.run_job(job_run)
        assert not job_run.start.called
        job_run.queue.assert_called_once()
        assert not self.job_scheduler.schedule.called

    def test_run_job_already_running_cancel(self):
        self.job_scheduler.schedule = mock.Mock(autospec=True)
        self.job.runs.get_active = lambda s: [mock.Mock(autospec=True)]
        self.job.queueing = False
        job_run = mock.Mock(autospec=True)
        job_run.is_cancelled = False
        self.job_scheduler.run_job(job_run)
        assert not job_run.start.called
        job_run.cancel.assert_called_once()
        self.job_scheduler.schedule.assert_called_once()

    def test_run_job_already_running_allow_overlap(self):
        self.job_scheduler.schedule = mock.Mock()
        self.job.runs.get_active = lambda s: [mock.Mock()]
        self.job.allow_overlap = True
        job_run = MagicMock(is_cancelled=False)
        self.job_scheduler.run_job(job_run)
        job_run.start.assert_called_with()

    def test_run_job_has_starting_queueing(self):
        self.job_scheduler.schedule = mock.Mock(autospec=True)
        self.job.runs.get_active = lambda s: [mock.Mock(autospec=True)]
        job_run = mock.Mock(autospec=True)
        job_run.is_cancelled = False
        self.job_scheduler.run_job(job_run)
        assert not job_run.start.called
        job_run.queue.assert_called_once()
        assert not self.job_scheduler.schedule.called

    def test_run_job_schedule_on_complete(self):
        self.job_scheduler.schedule = MagicMock()
        self.scheduler.schedule_on_complete = True
        self.job.runs.get_active = lambda s: []
        job_run = MagicMock(is_cancelled=False)
        self.job_scheduler.run_job(job_run)
        assert_length(job_run.start.mock_calls, 1)
        assert_length(self.job_scheduler.schedule.mock_calls, 0)
Beispiel #17
0
class TestJobSchedulerSchedule(TestCase):
    @setup
    def setup_job(self):
        self.scheduler = mock.Mock(autospec=True)
        self.scheduler.next_run_time.return_value = 0
        mock_run = mock.Mock()
        mock_run.seconds_until_run_time.return_value = 0
        run_collection = mock.Mock(
            has_pending=False,
            autospec=True,
            return_value=[mock_run],
        )
        mock_build_new_run = mock.Mock()
        run_collection.build_new_run.return_value = mock_build_new_run
        mock_build_new_run.seconds_until_run_time.return_value = 0
        node_pool = mock.Mock()
        self.job = job.Job(
            name="jobname",
            scheduler=self.scheduler,
            run_collection=run_collection,
            node_pool=node_pool,
        )
        self.job_scheduler = JobScheduler(self.job)
        self.original_build_new_runs = self.job.build_new_runs
        self.job.build_new_runs = mock.Mock(return_value=[mock_run])

    @mock.patch('tron.core.job_scheduler.reactor', autospec=True)
    def test_enable(self, reactor):
        self.job.enabled = False
        self.job_scheduler.enable()
        assert self.job.enabled
        assert_length(reactor.callLater.mock_calls, 1)

    @mock.patch('tron.core.job_scheduler.reactor', autospec=True)
    def test_enable_noop(self, reactor):
        self.job.enabled = True
        self.job_scheduler.enable()
        assert self.job.enabled
        assert_length(reactor.callLater.mock_calls, 0)

    @mock.patch('tron.core.job_scheduler.reactor', autospec=True)
    def test_schedule(self, reactor):
        self.job.build_new_runs = self.original_build_new_runs
        self.job_scheduler.schedule()
        assert reactor.callLater.call_count == 1

        # Args passed to callLater
        call_args = reactor.callLater.mock_calls[0][1]
        assert_equal(call_args[1], self.job_scheduler.run_job)
        secs = call_args[0]
        run = call_args[2]

        run.seconds_until_run_time.assert_called_with()
        # Assert that we use the seconds we get from the run to schedule
        assert_equal(run.seconds_until_run_time.return_value, secs)

    @mock.patch('tron.core.job_scheduler.reactor', autospec=True)
    def test_schedule_disabled_job(self, reactor):
        self.job.enabled = False
        self.job_scheduler.schedule()
        assert reactor.callLater.call_count == 0

    @mock.patch('tron.core.job_scheduler.reactor', autospec=True)
    def test_handle_job_events_no_schedule_on_complete(self, reactor):
        self.job_scheduler.run_job = mock.Mock()
        self.job.scheduler.schedule_on_complete = False
        queued_job_run = mock.Mock()
        self.job.runs.get_first_queued = lambda: queued_job_run
        self.job_scheduler.handle_job_events(self.job, job.Job.NOTIFY_RUN_DONE)
        reactor.callLater.assert_any_call(
            0,
            self.job_scheduler.run_job,
            queued_job_run,
            run_queued=True,
        )

    def test_handle_job_events_schedule_on_complete(self):
        self.job_scheduler.schedule = mock.Mock()
        self.job.scheduler.schedule_on_complete = True
        self.job_scheduler.handle_job_events(self.job, job.Job.NOTIFY_RUN_DONE)
        self.job_scheduler.schedule.assert_called_with()

    def test_handler_unknown_event(self):
        self.job.runs.get_runs_by_state = mock.Mock()
        self.job_scheduler.handler(self.job, 'some_other_event')
        self.job.runs.get_runs_by_state.assert_not_called()

    def test_handler_no_queued(self):
        self.job_scheduler.run_job = mock.Mock()

        def get_queued(state):
            if state == ActionRun.QUEUED:
                return []

        self.job.runs.get_runs_by_state = get_queued
        self.job_scheduler.handler(self.job, job.Job.NOTIFY_RUN_DONE)
        self.job_scheduler.run_job.assert_not_called()

    @mock.patch('tron.core.job_scheduler.reactor', autospec=True)
    def test_run_queue_schedule(self, reactor):
        with mock.patch.object(
            self.job_scheduler,
            'schedule',
        ) as mock_schedule:
            self.job_scheduler.run_job = mock.Mock()
            self.job.scheduler.schedule_on_complete = False
            queued_job_run = mock.Mock()
            self.job.runs.get_first_queued = lambda: queued_job_run
            self.job_scheduler.run_queue_schedule()
            reactor.callLater.assert_called_once_with(
                0,
                self.job_scheduler.run_job,
                queued_job_run,
                run_queued=True,
            )
            mock_schedule.assert_called_once_with()
Beispiel #18
0
class TestJobSchedulerSchedule(TestCase):
    @setup
    def setup_job(self):
        self.scheduler = mock.Mock(autospec=True)
        self.scheduler.next_run_time.return_value = 0
        mock_run = mock.Mock()
        mock_run.seconds_until_run_time.return_value = 0
        run_collection = mock.Mock(
            has_pending=False,
            autospec=True,
            return_value=[mock_run],
        )
        mock_build_new_run = mock.Mock()
        run_collection.build_new_run.return_value = mock_build_new_run
        mock_build_new_run.seconds_until_run_time.return_value = 0
        node_pool = mock.Mock()
        self.job = job.Job(
            name="jobname",
            scheduler=self.scheduler,
            run_collection=run_collection,
            node_pool=node_pool,
        )
        self.job_scheduler = JobScheduler(self.job)
        self.original_build_new_runs = self.job.build_new_runs
        self.job.build_new_runs = mock.Mock(return_value=[mock_run])

    @mock.patch('tron.core.job_scheduler.reactor', autospec=True)
    def test_enable(self, reactor):
        self.job.enabled = False
        self.job_scheduler.enable()
        assert self.job.enabled
        assert_length(reactor.callLater.mock_calls, 1)

    @mock.patch('tron.core.job_scheduler.reactor', autospec=True)
    def test_enable_noop(self, reactor):
        self.job.enabled = True
        self.job_scheduler.enable()
        assert self.job.enabled
        assert_length(reactor.callLater.mock_calls, 0)

    @mock.patch('tron.core.job_scheduler.reactor', autospec=True)
    def test_schedule(self, reactor):
        self.job.build_new_runs = self.original_build_new_runs
        self.job_scheduler.schedule()
        assert reactor.callLater.call_count == 1

        # Args passed to callLater
        call_args = reactor.callLater.mock_calls[0][1]
        assert_equal(call_args[1], self.job_scheduler.run_job)
        secs = call_args[0]
        run = call_args[2]

        run.seconds_until_run_time.assert_called_with()
        # Assert that we use the seconds we get from the run to schedule
        assert_equal(run.seconds_until_run_time.return_value, secs)

    @mock.patch('tron.core.job_scheduler.reactor', autospec=True)
    def test_schedule_disabled_job(self, reactor):
        self.job.enabled = False
        self.job_scheduler.schedule()
        assert reactor.callLater.call_count == 0

    @mock.patch('tron.core.job_scheduler.reactor', autospec=True)
    def test_handle_job_events_no_schedule_on_complete(self, reactor):
        self.job_scheduler.run_job = mock.Mock()
        self.job.scheduler.schedule_on_complete = False
        queued_job_run = mock.Mock()
        self.job.runs.get_first_queued = lambda: queued_job_run
        self.job_scheduler.handle_job_events(self.job, job.Job.NOTIFY_RUN_DONE)
        reactor.callLater.assert_any_call(
            0,
            self.job_scheduler.run_job,
            queued_job_run,
            run_queued=True,
        )

    def test_handle_job_events_schedule_on_complete(self):
        self.job_scheduler.schedule = mock.Mock()
        self.job.scheduler.schedule_on_complete = True
        self.job_scheduler.handle_job_events(self.job, job.Job.NOTIFY_RUN_DONE)
        self.job_scheduler.schedule.assert_called_with()

    def test_handler_unknown_event(self):
        self.job.runs.get_runs_by_state = mock.Mock()
        self.job_scheduler.handler(self.job, 'some_other_event')
        self.job.runs.get_runs_by_state.assert_not_called()

    def test_handler_no_queued(self):
        self.job_scheduler.run_job = mock.Mock()

        def get_queued(state):
            if state == ActionRun.QUEUED:
                return []

        self.job.runs.get_runs_by_state = get_queued
        self.job_scheduler.handler(self.job, job.Job.NOTIFY_RUN_DONE)
        self.job_scheduler.run_job.assert_not_called()

    @mock.patch('tron.core.job_scheduler.reactor', autospec=True)
    def test_run_queue_schedule(self, reactor):
        with mock.patch.object(
            self.job_scheduler,
            'schedule',
        ) as mock_schedule:
            self.job_scheduler.run_job = mock.Mock()
            self.job.scheduler.schedule_on_complete = False
            queued_job_run = mock.Mock()
            self.job.runs.get_first_queued = lambda: queued_job_run
            self.job_scheduler.run_queue_schedule()
            reactor.callLater.assert_called_once_with(
                0,
                self.job_scheduler.run_job,
                queued_job_run,
                run_queued=True,
            )
            mock_schedule.assert_called_once_with()