Example #1
0
    def test_with_scheduled_call_none(self, mock_increment_failure,
                                      mock_request):
        exc = Exception()
        task_id = str(uuid.uuid4())
        args = [1, 'b', 'iii']
        kwargs = {
            '1': 'for the money',
            'tags': ['test_tags'],
            'scheduled_call_id': None
        }

        class EInfo(object):
            """
            on_failure handler expects an instance of celery's ExceptionInfo class
            as one of the attributes. It stores string representation of traceback
            in it's traceback instance variable. This is a stub to imitate that behavior.
            """
            def __init__(self):
                self.traceback = "string_repr_of_traceback"

        einfo = EInfo()
        mock_request.called_directly = False
        TaskStatus(task_id).save()
        task = tasks.Task()
        task.on_failure(exc, task_id, args, kwargs, einfo)
        self.assertFalse(mock_increment_failure.called)
Example #2
0
    def test_async_result(self, mock_request):
        retval = AsyncResult('foo-id')

        task_id = str(uuid.uuid4())
        args = [1, 'b', 'iii']
        kwargs = {
            '1': 'for the money',
            'tags': ['test_tags'],
            'routing_key': WORKER_2
        }
        mock_request.called_directly = False

        task_status = TaskStatus(task_id).save()
        self.assertEqual(task_status['state'], 'waiting')
        self.assertEqual(task_status['finish_time'], None)

        task = tasks.Task()
        task.on_success(retval, task_id, args, kwargs)

        new_task_status = TaskStatus.objects(task_id=task_id).first()
        self.assertEqual(new_task_status['state'], 'finished')
        self.assertEqual(new_task_status['result'], None)
        self.assertFalse(new_task_status['finish_time'] is None)
        # Make sure that parse_iso8601_datetime is able to parse the finish_time without errors
        dateutils.parse_iso8601_datetime(new_task_status['finish_time'])
        self.assertEqual(new_task_status['spawned_tasks'], ['foo-id'])
Example #3
0
    def test_updates_task_status_correctly(self, mock_request):
        exc = Exception()
        task_id = str(uuid.uuid4())
        args = [1, 'b', 'iii']
        kwargs = {'1': 'for the money', 'tags': ['test_tags']}

        class EInfo(object):
            """
            on_failure handler expects an instance of celery's ExceptionInfo class
            as one of the attributes. It stores string representation of traceback
            in it's traceback instance variable. This is a stub to imitate that behavior.
            """
            def __init__(self):
                self.traceback = "string_repr_of_traceback"

        einfo = EInfo()
        mock_request.called_directly = False

        task_status = TaskStatus(task_id).save()
        self.assertEqual(task_status['state'], 'waiting')
        self.assertEqual(task_status['finish_time'], None)
        self.assertEqual(task_status['traceback'], None)

        task = tasks.Task()
        task.on_failure(exc, task_id, args, kwargs, einfo)

        new_task_status = TaskStatus.objects(task_id=task_id).first()
        self.assertEqual(new_task_status['state'], 'error')
        self.assertFalse(new_task_status['finish_time'] is None)
        # Make sure that parse_iso8601_datetime is able to parse the finish_time without errors
        dateutils.parse_iso8601_datetime(new_task_status['finish_time'])
        self.assertEqual(new_task_status['traceback'], einfo.traceback)
Example #4
0
    def test_apply_async_task_status(self, apply_async):
        """
        Assert that apply_async() creates new task status.
        """
        args = [1, 'b', 'iii']
        kwargs = {
            '1': 'for the money',
            'tags': ['test_tags'],
            'queue': WORKER_1_QUEUE
        }
        apply_async.return_value = celery.result.AsyncResult('test_task_id')
        task = tasks.Task()

        task.apply_async(*args, **kwargs)

        task_statuses = list(TaskStatusManager.find_all())
        self.assertEqual(len(task_statuses), 1)
        new_task_status = task_statuses[0]
        self.assertEqual(new_task_status['task_id'], 'test_task_id')
        self.assertEqual(new_task_status['queue'], WORKER_1_QUEUE)
        self.assertEqual(new_task_status['tags'], kwargs['tags'])
        self.assertEqual(new_task_status['state'], 'waiting')
        self.assertEqual(new_task_status['error'], None)
        self.assertEqual(new_task_status['spawned_tasks'], [])
        self.assertEqual(new_task_status['progress_report'], {})
        self.assertEqual(new_task_status['task_type'],
                         'pulp.server.async.tasks.Task')
        self.assertEqual(new_task_status['start_time'], None)
        self.assertEqual(new_task_status['finish_time'], None)
        self.assertEqual(new_task_status['result'], None)
Example #5
0
    def test_creates_task_status_with_group_id(self, apply_async):
        args = [1, 'b', 'iii']
        group_id = uuid.uuid4()
        kwargs = {
            'a': 'for the money',
            'tags': ['test_tags'],
            'routing_key': WORKER_1,
            'group_id': group_id
        }
        apply_async.return_value = celery.result.AsyncResult('test_task_id')
        task = tasks.Task()

        task.apply_async(*args, **kwargs)

        task_statuses = TaskStatus.objects()
        self.assertEqual(task_statuses.count(), 1)
        new_task_status = task_statuses[0]
        self.assertEqual(new_task_status['task_id'], 'test_task_id')
        self.assertEqual(new_task_status['group_id'], group_id)
        self.assertEqual(new_task_status['worker_name'], WORKER_1)
        self.assertEqual(new_task_status['tags'], kwargs['tags'])
        self.assertEqual(new_task_status['state'], 'waiting')
        self.assertEqual(new_task_status['error'], None)
        self.assertEqual(new_task_status['spawned_tasks'], [])
        self.assertEqual(new_task_status['progress_report'], {})
        self.assertEqual(new_task_status['task_type'],
                         'pulp.server.async.tasks.Task')
        self.assertEqual(new_task_status['start_time'], None)
        self.assertEqual(new_task_status['finish_time'], None)
        self.assertEqual(new_task_status['result'], None)
Example #6
0
    def test_on_success_handler_async_result(self, mock_request):
        """
        Make sure that overridden on_success handler updates task status correctly
        """
        retval = AsyncResult('foo-id')

        task_id = str(uuid.uuid4())
        args = [1, 'b', 'iii']
        kwargs = {
            '1': 'for the money',
            'tags': ['test_tags'],
            'queue': WORKER_2_QUEUE
        }
        mock_request.called_directly = False

        task_status = TaskStatusManager.create_task_status(
            task_id, 'some_queue')
        self.assertEqual(task_status['state'], 'waiting')
        self.assertEqual(task_status['finish_time'], None)

        task = tasks.Task()
        task.on_success(retval, task_id, args, kwargs)

        new_task_status = TaskStatusManager.find_by_task_id(task_id)
        self.assertEqual(new_task_status['state'], 'finished')
        self.assertEqual(new_task_status['result'], None)
        self.assertFalse(new_task_status['finish_time'] is None)
        # Make sure that parse_iso8601_datetime is able to parse the finish_time without errors
        dateutils.parse_iso8601_datetime(new_task_status['finish_time'])
        self.assertEqual(new_task_status['spawned_tasks'], ['foo-id'])
Example #7
0
    def test_on_success_with_canceled_task(self, mock_request):
        """
        Make sure on_success() does not move a canceled Task to 'finished' state.
        """
        retval = 'random_return_value'
        task_id = str(uuid.uuid4())
        args = [1, 'b', 'iii']
        kwargs = {
            '1': 'for the money',
            'tags': ['test_tags'],
            'queue': WORKER_2_QUEUE
        }
        mock_request.called_directly = False
        task_status = TaskStatusManager.create_task_status(
            task_id, 'some_queue', state=CALL_CANCELED_STATE)
        task = tasks.Task()

        # This should not update the task status to finished, since this task was canceled.
        task.on_success(retval, task_id, args, kwargs)

        updated_task_status = TaskStatusManager.find_by_task_id(task_id)
        # Make sure the task is still canceled.
        self.assertEqual(updated_task_status['state'], CALL_CANCELED_STATE)
        self.assertEqual(updated_task_status['result'], retval)
        self.assertFalse(updated_task_status['finish_time'] is None)
        # Make sure that parse_iso8601_datetime is able to parse the finish_time without errors
        dateutils.parse_iso8601_datetime(updated_task_status['finish_time'])
Example #8
0
    def test_apply_async_with_reservation_calls_apply_async(
            self, apply_async, _reserve_resource, _queue_release_resource):
        """
        Assert that apply_async_with_reservation() calls Celery's apply_async.
        """
        class MockAsyncResult(object):
            def __init__(self):
                self.id = 'some_task_id'

        # Let's make up the return value from Celery
        mock_async_result = MockAsyncResult()
        apply_async.return_value = mock_async_result
        some_args = [1, 'b', 'iii']
        some_kwargs = {
            '1': 'for the money',
            '2': 'for the show',
            'queue': WORKER_1_QUEUE
        }
        resource_id = 'three_to_get_ready'
        resource_type = 'reserve_me'
        task = tasks.Task()

        async_result = task.apply_async_with_reservation(
            resource_type, resource_id, *some_args, **some_kwargs)

        self.assertEqual(async_result, mock_async_result)
        expected_resource_id = ":".join([resource_type, resource_id])
        _reserve_resource.assert_called_once_with(
            (expected_resource_id, ), queue=tasks.RESOURCE_MANAGER_QUEUE)
        apply_async.assert_called_once_with(task, *some_args, **some_kwargs)
        _queue_release_resource.apply_async.assert_called_once_with(
            (expected_resource_id, ), queue=WORKER_1_QUEUE)
Example #9
0
    def test_on_success_handler_spawned_task_dict(self, mock_request):
        """
        Make sure that overridden on_success handler updates task status correctly
        """
        retval = tasks.TaskResult(spawned_tasks=[{
            'task_id': 'foo-id'
        }],
                                  result='bar')

        task_id = str(uuid.uuid4())
        args = [1, 'b', 'iii']
        kwargs = {
            '1': 'for the money',
            'tags': ['test_tags'],
            'queue': WORKER_2_QUEUE
        }
        mock_request.called_directly = False

        task_status = TaskStatusManager.create_task_status(
            task_id, 'some_queue')
        self.assertEqual(task_status['state'], 'waiting')
        self.assertEqual(task_status['finish_time'], None)

        task = tasks.Task()
        task.on_success(retval, task_id, args, kwargs)

        new_task_status = TaskStatusManager.find_by_task_id(task_id)
        self.assertEqual(new_task_status['state'], 'finished')
        self.assertEqual(new_task_status['result'], 'bar')
        self.assertFalse(new_task_status['finish_time'] is None)
        self.assertEqual(new_task_status['spawned_tasks'], ['foo-id'])
Example #10
0
    def test_spawned_task_status(self, mock_request):
        async_result = AsyncResult('foo-id')

        retval = tasks.TaskResult(error=PulpException('error-foo'),
                                  result='bar')
        retval.spawned_tasks = [async_result]

        task_id = str(uuid.uuid4())
        args = [1, 'b', 'iii']
        kwargs = {
            '1': 'for the money',
            'tags': ['test_tags'],
            'routing_key': WORKER_2
        }
        mock_request.called_directly = False

        task_status = TaskStatusManager.create_task_status(task_id)
        self.assertEqual(task_status['state'], 'waiting')
        self.assertEqual(task_status['finish_time'], None)

        task = tasks.Task()
        task.on_success(retval, task_id, args, kwargs)

        new_task_status = TaskStatusManager.find_by_task_id(task_id)
        self.assertEqual(new_task_status['state'], 'finished')
        self.assertEqual(new_task_status['result'], 'bar')
        self.assertEqual(new_task_status['error']['description'], 'error-foo')
        self.assertFalse(new_task_status['finish_time'] is None)
        # Make sure that parse_iso8601_datetime is able to parse the finish_time without errors
        dateutils.parse_iso8601_datetime(new_task_status['finish_time'])
        self.assertEqual(new_task_status['spawned_tasks'], ['foo-id'])
Example #11
0
    def test_task_status_not_modified_when_task_status_exists(
            self, apply_async):
        args = [1, 'b', 'iii']
        kwargs = {'a': 'for the money', 'tags': ['test_tags']}
        task_id = 'test_task_id'

        # This simulates the case where a task had already completed
        # prior to apply_sync attempting to create a TaskStatus.
        # https://pulp.plan.io/issues/2959
        TaskStatus(task_id,
                   'test-worker',
                   state=CALL_FINISHED_STATE,
                   result='any_result',
                   start_time='2017-09-20T10:00:00Z',
                   finish_time='2017-09-20T11:00:00Z').save()
        apply_async.return_value = celery.result.AsyncResult(task_id)

        task = tasks.Task()
        task.apply_async(*args, **kwargs)

        task_status = TaskStatus.objects(task_id=task_id).first()

        # Fields which were missing on the object have been added
        self.assertEqual(task_status['task_type'],
                         'pulp.server.async.tasks.Task')
        self.assertEqual(task_status['tags'], ['test_tags'])

        # Fields which already existed on the object are retained
        self.assertEqual(task_status['state'], 'finished')
        self.assertEqual(task_status['start_time'], '2017-09-20T10:00:00Z')
        self.assertEqual(task_status['finish_time'], '2017-09-20T11:00:00Z')
        self.assertEqual(task_status['result'], 'any_result')
Example #12
0
    def test_spawned_task_dict(self, mock_request):
        retval = tasks.TaskResult(spawned_tasks=[{
            'task_id': 'foo-id'
        }],
                                  result='bar')

        task_id = str(uuid.uuid4())
        args = [1, 'b', 'iii']
        kwargs = {
            '1': 'for the money',
            'tags': ['test_tags'],
            'routing_key': WORKER_2
        }
        mock_request.called_directly = False

        task_status = TaskStatus(task_id).save()
        self.assertEqual(task_status['state'], 'waiting')
        self.assertEqual(task_status['finish_time'], None)

        task = tasks.Task()
        task.on_success(retval, task_id, args, kwargs)

        new_task_status = TaskStatus.objects(task_id=task_id).first()
        self.assertEqual(new_task_status['state'], 'finished')
        self.assertEqual(new_task_status['result'], 'bar')
        self.assertFalse(new_task_status['finish_time'] is None)
        self.assertEqual(new_task_status['spawned_tasks'], ['foo-id'])
Example #13
0
    def test_exception_task_status_with_bad_group_id(self, apply_async):
        args = [1, 'b', 'iii']
        kwargs = {'a': 'for the money', 'tags': ['test_tags'], 'routing_key': WORKER_1,
                  'group_id': 'string-id'}
        apply_async.return_value = celery.result.AsyncResult('test_task_id')
        task = tasks.Task()

        self.assertRaises(ValidationError, task.apply_async, *args, **kwargs)
Example #14
0
    def test_calls_parent_apply_async(self, apply_async):
        args = [1, 'b', 'iii']
        kwargs = {'a': 'for the money', 'tags': ['test_tags'], 'routing_key': 'asdf'}
        apply_async.return_value = celery.result.AsyncResult('test_task_id')
        task = tasks.Task()

        task.apply_async(*args, **kwargs)

        apply_async.assert_called_once_with(1, 'b', 'iii', a='for the money', routing_key='asdf')
Example #15
0
    def test_returns_apply_async_result_including_tags(self, apply_async):
        args = [1, 'b', 'iii']
        kwargs = {'a': 'for the money', 'tags': ['test_tags']}
        async_result = celery.result.AsyncResult('test_task_id')
        apply_async.return_value = async_result
        task = tasks.Task()

        result = task.apply_async(*args, **kwargs)

        self.assertEqual(result.tags, ['test_tags'])
Example #16
0
 def test_with_scheduled_call(self, mock_reset_failure, mock_request):
     retval = 'random_return_value'
     task_id = str(uuid.uuid4())
     args = [1, 'b', 'iii']
     kwargs = {'1': 'for the money', 'tags': ['test_tags'], 'routing_key': WORKER_2,
               'scheduled_call_id': '12345'}
     mock_request.called_directly = False
     TaskStatus(task_id).save()
     task = tasks.Task()
     task.on_success(retval, task_id, args, kwargs)
     mock_reset_failure.assert_called_once_with('12345')
Example #17
0
    def test_task_status_not_modified_when_task_status_exists(self, apply_async):
        args = [1, 'b', 'iii']
        kwargs = {'a': 'for the money', 'tags': ['test_tags']}
        task_id = 'test_task_id'
        TaskStatus(task_id, 'test-worker', state=CALL_CANCELED_STATE).save()
        apply_async.return_value = celery.result.AsyncResult(task_id)

        task = tasks.Task()
        task.apply_async(*args, **kwargs)

        task_status = TaskStatus.objects(task_id=task_id).first()
        self.assertEqual(task_status['state'], 'canceled')
        self.assertEqual(task_status['start_time'], None)
Example #18
0
 def test_with_scheduled_call_none(self, mock_reset_failure, mock_request):
     """
     Ensure that if scheduled_call_id  exists but is `None`, do not fail.
     """
     retval = 'random_return_value'
     task_id = str(uuid.uuid4())
     args = [1, 'b', 'iii']
     kwargs = {'1': 'for the money', 'tags': ['test_tags'], 'routing_key': WORKER_2,
               'scheduled_call_id': None}
     mock_request.called_directly = False
     TaskStatus(task_id).save()
     task = tasks.Task()
     task.on_success(retval, task_id, args, kwargs)
     self.assertFalse(mock_reset_failure.called)
Example #19
0
    def test_saves_passed_in_routing_key_as_worker_name(self, apply_async):
        args = [1, 'b', 'iii']
        kwargs = {'a': 'for the money', 'tags': ['test_tags'], 'routing_key': 'othername'}
        apply_async.return_value = celery.result.AsyncResult('test_task_id')
        task = tasks.Task()

        task.apply_async(*args, **kwargs)

        task_statuses = TaskStatus.objects()
        self.assertEqual(len(task_statuses), 1)
        new_task_status = task_statuses[0]
        self.assertEqual(new_task_status['task_id'], 'test_task_id')
        self.assertEqual(new_task_status['worker_name'], 'othername')
        self.assertEqual(new_task_status['tags'], kwargs['tags'])
        self.assertEqual(new_task_status['state'], 'waiting')
Example #20
0
    def test_saves_default_routing_key_as_worker_name(self, apply_async):
        args = [1, 'b', 'iii']
        kwargs = {'a': 'for the money', 'tags': ['test_tags']}
        apply_async.return_value = celery.result.AsyncResult('test_task_id')
        task = tasks.Task()

        task.apply_async(*args, **kwargs)

        task_statuses = TaskStatus.objects()
        self.assertEqual(len(task_statuses), 1)
        new_task_status = task_statuses[0]
        self.assertEqual(new_task_status['task_id'], 'test_task_id')
        self.assertEqual(new_task_status['worker_name'],
                         defaults.NAMESPACES['CELERY']['DEFAULT_ROUTING_KEY'].default)
        self.assertEqual(new_task_status['tags'], kwargs['tags'])
        self.assertEqual(new_task_status['state'], 'waiting')
Example #21
0
    def test_with_canceled_task(self, mock_request):
        retval = 'random_return_value'
        task_id = str(uuid.uuid4())
        args = [1, 'b', 'iii']
        kwargs = {'1': 'for the money', 'tags': ['test_tags'], 'routing_key': WORKER_2}
        mock_request.called_directly = False
        TaskStatus(task_id, state=CALL_CANCELED_STATE).save()
        task = tasks.Task()

        # This should not update the task status to finished, since this task was canceled.
        task.on_success(retval, task_id, args, kwargs)

        updated_task_status = TaskStatus.objects(task_id=task_id).first()
        # Make sure the task is still canceled.
        self.assertEqual(updated_task_status['state'], CALL_CANCELED_STATE)
        self.assertEqual(updated_task_status['result'], retval)
        self.assertFalse(updated_task_status['finish_time'] is None)
        # Make sure that parse_iso8601_datetime is able to parse the finish_time without errors
        dateutils.parse_iso8601_datetime(updated_task_status['finish_time'])
Example #22
0
    def test_apply_async_task_canceled(self, apply_async):
        """
        Assert that apply_async() honors 'canceled' task status.
        """
        args = [1, 'b', 'iii']
        kwargs = {'1': 'for the money', 'tags': ['test_tags']}
        task_id = 'test_task_id'
        now = datetime.utcnow()
        TaskStatusManager.create_task_status(task_id,
                                             Worker('test-worker', now),
                                             state=CALL_CANCELED_STATE)
        apply_async.return_value = celery.result.AsyncResult(task_id)

        task = tasks.Task()
        task.apply_async(*args, **kwargs)

        task_status = TaskStatusManager.find_by_task_id(task_id)
        self.assertEqual(task_status['state'], 'canceled')
        self.assertEqual(task_status['start_time'], None)
Example #23
0
    def test_apply_async_task_status_default_queue(self, apply_async):
        """
        Assert that apply_async() creates new task status when we do not pass the queue kwarg. It
        default to the default Celery queue.
        """
        args = [1, 'b', 'iii']
        kwargs = {'1': 'for the money', 'tags': ['test_tags']}
        apply_async.return_value = celery.result.AsyncResult('test_task_id')
        task = tasks.Task()

        task.apply_async(*args, **kwargs)

        task_statuses = list(TaskStatusManager.find_all())
        self.assertEqual(len(task_statuses), 1)
        new_task_status = task_statuses[0]
        self.assertEqual(new_task_status['task_id'], 'test_task_id')
        self.assertEqual(
            new_task_status['queue'],
            defaults.NAMESPACES['CELERY']['DEFAULT_QUEUE'].default)
        self.assertEqual(new_task_status['tags'], kwargs['tags'])
        self.assertEqual(new_task_status['state'], 'waiting')
Example #24
0
    def test_updates_task_status_correctly(self, mock_request):
        retval = 'random_return_value'
        task_id = str(uuid.uuid4())
        args = [1, 'b', 'iii']
        kwargs = {
            '1': 'for the money',
            'tags': ['test_tags'],
            'routing_key': WORKER_2
        }
        mock_request.called_directly = False

        task_status = TaskStatusManager.create_task_status(task_id)
        self.assertEqual(task_status['state'], 'waiting')
        self.assertEqual(task_status['finish_time'], None)

        task = tasks.Task()
        task.on_success(retval, task_id, args, kwargs)

        new_task_status = TaskStatusManager.find_by_task_id(task_id)
        self.assertEqual(new_task_status['state'], 'finished')
        self.assertEqual(new_task_status['result'], retval)
        self.assertFalse(new_task_status['finish_time'] is None)
        # Make sure that parse_iso8601_datetime is able to parse the finish_time without errors
        dateutils.parse_iso8601_datetime(new_task_status['finish_time'])