Ejemplo n.º 1
0
def test_cancel(assert_atomic, connection):
    q = QueueFactory()
    task = q.enqueue_call()
    with assert_atomic():
        task.cancel()
    assert q.get_task_ids() == []
    assert task.status == TaskStatus.CANCELED
    assert not connection.exists(task.key)

    w = WorkerFactory()
    w.startup()
    task = q.enqueue_call()
    q.dequeue(w)
    with pytest.raises(InvalidOperation):
        with assert_atomic():
            task.cancel()
    assert worker_registry.get_running_tasks() == {w.id: task.id}
    assert connection.exists(task.key)
Ejemplo n.º 2
0
def test_unblocking(connection):
    worker = WorkerFactory()
    q = Queue()
    q.enqueue_call()
    assert connection.llen(q.unblock_key)
    assert q.dequeue(worker) is not None
    assert connection.llen(q.unblock_key)
    assert q.dequeue(worker) is None
    assert not connection.llen(q.unblock_key)
Ejemplo n.º 3
0
def test_info(cli_run, stub):
    cli_run('info')

    for i in range(2):
        QueueFactory().enqueue_call(stub)

    for i in range(3):
        WorkerFactory().startup()

    result = cli_run('info')
    assert "2 queue(s), 2 task(s) total" in result.output
    assert "3 worker(s)" in result.output
Ejemplo n.º 4
0
def test_worker_registry(connection, settings, mocker, assert_atomic):
    registry = registries.worker_registry
    worker1 = WorkerFactory()
    worker2 = WorkerFactory()
    settings.WORKER_HEARTBEAT_TIMEOUT = 100

    timestamp = mocker.patch('redis_tasks.conf.RTRedis.time')
    timestamp.return_value = (1000, 0)
    with assert_atomic():
        registry.add(worker1)
    timestamp.return_value = (1050, 0)
    registry.add(worker2)
    assert registry.get_worker_ids() == [worker1.id, worker2.id]

    timestamp.return_value = (1120, 0)
    assert registry.get_dead_ids() == [worker1.id]

    registry.heartbeat(worker1)
    timestamp.return_value = (1140, 0)
    assert registry.get_dead_ids() == []

    timestamp.return_value = (1200, 0)
    assert registry.get_dead_ids() == [worker2.id]

    with assert_atomic():
        registry.remove(worker1)
    # worker is already dead
    with pytest.raises(WorkerDoesNotExist):
        registry.heartbeat(worker1)

    with assert_atomic():
        with connection.pipeline() as pipe:
            registry.remove(worker1, pipeline=pipe)
            registry.remove(worker2, pipeline=pipe)
            pipe.execute()
    assert registry.get_worker_ids() == []
    assert registry.get_dead_ids() == []
Ejemplo n.º 5
0
def test_queue_basics(assert_atomic):
    worker = WorkerFactory()
    q = Queue()
    assert q.name == 'default'
    assert str(q) == '<Queue default>'
    assert repr(q) == "Queue('default')"

    assert q.count() == 0
    with assert_atomic():
        task = q.enqueue_call()
    q.enqueue_call()
    assert q.count() == 2

    assert q.dequeue(worker).id == task.id
    assert q.count() == 1
Ejemplo n.º 6
0
def test_dequeue(connection):
    worker = WorkerFactory()
    q = Queue()
    assert q.dequeue(worker) is None

    task1 = q.enqueue_call()
    task2 = q.enqueue_call()
    assert connection.llen(q.unblock_key) == 2

    assert q.dequeue(worker).id == task1.id
    assert worker.current_task_id == task1.id
    assert connection.lrange(worker.task_key, 0, -1) == [task1.id.encode()]

    assert q.dequeue(worker).id == task2.id
    assert worker.current_task_id == task2.id
    assert connection.lrange(worker.task_key, 0, -1) == [task2.id.encode(), task1.id.encode()]
    assert connection.llen(q.unblock_key) == 2

    # Clear block_key when queue is empty
    assert q.dequeue(worker) is None
    assert connection.llen(q.unblock_key) == 0
Ejemplo n.º 7
0
    def test_is_enqueued(self, stub):
        schedule = CrontabSchedule('* * * * *')
        queue = Queue()
        worker = WorkerFactory()
        worker.startup()
        se = SchedulerEntry("a", {"task": stub.path, "schedule": schedule})
        assert se.is_enqueued() is False

        task = se.enqueue()
        assert se.is_enqueued() is True
        task.cancel()
        assert se.is_enqueued() is False

        se.enqueue()
        assert se.is_enqueued() is True
        task = queue.dequeue(worker)
        assert se.is_enqueued() is True
        worker.start_task(task)
        assert se.is_enqueued() is True
        worker.end_task(task, TaskOutcome("success"))
        assert se.is_enqueued() is False

        se.enqueue()
        task = queue.dequeue(worker)
        worker.start_task(task)
        assert se.is_enqueued() is True
        worker.end_task(task, TaskOutcome("failure"))
        assert se.is_enqueued() is False
Ejemplo n.º 8
0
def test_worker_reg_running_tasks():
    registry = registries.worker_registry
    queue = QueueFactory()
    t1 = queue.enqueue_call()
    t2 = queue.enqueue_call()
    worker1 = WorkerFactory(queues=[queue])
    worker2 = WorkerFactory(queues=[queue])
    worker1.startup()
    worker2.startup()

    assert registry.get_running_tasks() == dict()
    queue.push(t1)
    queue.dequeue(worker1)
    assert registry.get_running_tasks() == {worker1.id: t1.id}
    worker1.start_task(t1)

    queue.push(t2)
    queue.dequeue(worker2)
    worker2.start_task(t2)
    assert registry.get_running_tasks() == {
        worker1.id: t1.id,
        worker2.id: t2.id
    }
    worker1.end_task(t1, TaskOutcome("success"))
    assert registry.get_running_tasks() == {worker2.id: t2.id}
Ejemplo n.º 9
0
def test_state_transistions(assert_atomic, connection, time_mocker, stub):
    time = time_mocker('redis_tasks.task.utcnow')
    task = Task(reentrant_stub)
    q = QueueFactory()
    w = WorkerFactory()
    w.startup()

    # enqueue
    time.step()
    assert not connection.exists(task.key)
    with assert_atomic():
        task.enqueue(q)
    assert q.get_task_ids() == [task.id]
    assert connection.exists(task.key)
    for t in [task, Task.fetch(task.id)]:
        assert t.enqueued_at == time.now
        assert t.status == TaskStatus.QUEUED
        assert t.origin == q.name

    # dequeue
    task = q.dequeue(w)
    assert q.get_task_ids() == []
    assert worker_registry.get_running_tasks() == {w.id: task.id}

    # set_running
    time.step()
    with assert_atomic():
        w.start_task(task)
    assert worker_registry.get_running_tasks() == {w.id: task.id}
    for t in [task, Task.fetch(task.id)]:
        assert t.status == TaskStatus.RUNNING
        assert t.started_at == time.now

    # requeue
    time.step()
    with assert_atomic():
        w.end_task(task, TaskOutcome("requeue"))
    assert worker_registry.get_running_tasks() == dict()
    assert q.get_task_ids() == [task.id]
    for t in [task, Task.fetch(task.id)]:
        assert t.status == TaskStatus.QUEUED
        assert t.started_at is None

    # set_finished
    task = q.dequeue(w)
    w.start_task(task)
    time.step()
    with assert_atomic():
        w.end_task(task, TaskOutcome("success"))
    assert q.get_task_ids() == []
    assert finished_task_registry.get_task_ids() == [task.id]
    for t in [task, Task.fetch(task.id)]:
        assert t.status == TaskStatus.FINISHED
        assert t.ended_at == time.now

    # set_failed
    task = q.enqueue_call(stub)
    task = q.dequeue(w)
    w.start_task(task)
    assert worker_registry.get_running_tasks() == {w.id: task.id}
    time.step()
    with assert_atomic():
        w.end_task(task, TaskOutcome("failure", message="my error"))
    assert worker_registry.get_running_tasks() == dict()
    assert failed_task_registry.get_task_ids() == [task.id]
    for t in [task, Task.fetch(task.id)]:
        assert t.status == TaskStatus.FAILED
        assert t.error_message == "my error"
        assert t.ended_at == time.now
Ejemplo n.º 10
0
 def setup(func):
     w = WorkerFactory()
     w.startup()
     q.enqueue_call(func)
     task = q.dequeue(w)
     return task, w