def test_serialize_after_finish(self):
        """
        Tests serializing a job's state to a RunningJob instance.
        """
        task_name = 'task-1'
        state = JobState(task_name)
        state.save_state()
        expected_events = [
            {
                'name': 'event-1',
                'arguments': ['a', 'b'],
            },
            {
                'name': 'event-2',
                'arguments': None,
            }
        ]
        mock_task = self.create_mock_task(task_name, expected_events)

        state.add_processed_task(mock_task)
        state.save_state()
        state.mark_as_complete()

        # Stil only one running job instance
        self.assertEqual(RunningJob.objects.count(), 1)
        job = RunningJob.objects.all()[0]
        self.assertSequenceEqual(job.state['events'], expected_events)
        self.assertSequenceEqual(job.state['processed_tasks'], [task_name])
        self.assertTrue(job.is_complete)
    def test_serialize_start(self):
        """
        Tests serializing a job's state to a RunningJob instance.
        """
        state = JobState('initial-task-name')
        state.save_state()

        # A running job was created.
        self.assertEqual(RunningJob.objects.count(), 1)
        job = RunningJob.objects.all()[0]
        self.assertEqual(job.initial_task_name, 'initial-task-name')
        self.assertIsNone(job.additional_parameters)
        self.assertFalse(job.is_complete)
    def test_continue_job_finished(self):
        """
        Tests continuing a job from a job state where the job was finished.
        """
        task1 = self.create_task_class(('a',), (), ('a',))
        job_state = JobState(task1.task_name())
        task1_instance = task1()
        task1_instance.execute()
        job_state.add_processed_task(task1_instance)
        job_state.save_state()

        self.clear_executed_tasks_list()
        continue_task_from_state(job_state)

        # No tasks were ran from the continue
        self.assertEqual(len(self.execution_list), 0)
    def test_continue_job_some_finished(self):
        """
        Tests continuing a job from a job state where a task has finished.
        """
        task1 = self.create_task_class(('a',), (), ('a',))
        task2 = self.create_task_class((), ('a',), ())
        job_state = JobState(task1.task_name())
        task1_instance = task1()
        task1_instance.execute()
        job_state.add_processed_task(task1_instance)
        job_state.save_state()

        self.clear_executed_tasks_list()
        continue_task_from_state(job_state)

        # Only one task ran
        self.assertEqual(len(self.execution_list), 1)
        # It was the one that was not completed before the continue
        self.assert_task_ran(task2)
    def test_deserialize(self):
        """
        Tests deserializing a RunningJob instance to a JobState.
        """
        initial_task_name = 'initial-task'
        additional_parameters = {
            'param1': 1
        }
        job = RunningJob.objects.create(
            initial_task_name=initial_task_name,
            additional_parameters=additional_parameters)
        processed_tasks = ['initial-task', 'task-1']
        job.state = {
            'events': [
                {
                    'name': 'event-1',
                },
                {
                    'name': 'event-2',
                    'arguments': {
                        'a': 1,
                        'b': '2'
                    }
                }
            ],
            'processed_tasks': processed_tasks
        }
        job.save()

        state = JobState.deserialize_running_job_state(job)

        self.assertEqual(state.initial_task_name, 'initial-task')
        self.assertEqual(state.additional_parameters, additional_parameters)
        self.assertEqual(state.processed_tasks, processed_tasks)

        self.assertEqual(len(state.events), 2)
        self.assertEqual(state.events[0].name, 'event-1')
        self.assertIsNone(state.events[0].arguments)
        self.assertEqual(state.events[1].arguments, {
            'a': 1,
            'b': '2'
        })
        self.assertEqual(state._running_job, job)
    def test_serialize_after_update(self):
        """
        Tests serializing a job's state after multiple tasks have finished.
        """
        task_names = ['task-1', 'task-2']
        state = JobState(task_names[0])
        state.save_state()
        expected_events = [
            {
                'name': 'event-1',
                'arguments': {
                    'a': 1,
                    'b': '2'
                },
            },
            {
                'name': 'event-2',
                'arguments': None,
            }
        ]
        mock_task_1 = self.create_mock_task(task_names[0], [expected_events[0]])
        state.add_processed_task(mock_task_1)
        state.save_state()

        mock_task_2 = self.create_mock_task(task_names[1], [expected_events[1]])
        state.add_processed_task(mock_task_2)
        state.save_state()

        # Stil only one running job instance
        self.assertEqual(RunningJob.objects.count(), 1)
        job = RunningJob.objects.all()[0]
        # All events found now
        self.assertSequenceEqual(job.state['events'], expected_events)
        # Both tasks processed
        self.assertSequenceEqual(job.state['processed_tasks'], task_names)
        self.assertFalse(job.is_complete)