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)
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)
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
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() == []
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
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
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
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}
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
def setup(func): w = WorkerFactory() w.startup() q.enqueue_call(func) task = q.dequeue(w) return task, w