def test_worker_sets_job_status(loop): """Ensure that worker correctly sets job status.""" q = Queue() w = Worker([q]) job = yield from q.enqueue(say_hello) assert (yield from job.get_status()) == JobStatus.QUEUED assert (yield from job.is_queued) assert not (yield from job.is_finished) assert not (yield from job.is_failed) yield from w.work(burst=True, loop=loop) job = yield from Job.fetch(job.id) assert (yield from job.get_status()) == JobStatus.FINISHED assert not (yield from job.is_queued) assert (yield from job.is_finished) assert not (yield from job.is_failed) # Failed jobs should set status to "failed" job = yield from q.enqueue(div_by_zero, args=(1,)) yield from w.work(burst=True, loop=loop) job = yield from Job.fetch(job.id) assert (yield from job.get_status()) == JobStatus.FAILED assert not (yield from job.is_queued) assert not (yield from job.is_finished) assert (yield from job.is_failed)
def test_result_ttl_is_persisted(redis): """Ensure that job's result_ttl is set properly""" job = Job.create(func=say_hello, args=('Lionel',), result_ttl=10) yield from job.save() yield from Job.fetch(job.id, connection=redis) assert job.result_ttl == 10 job = Job.create(func=say_hello, args=('Lionel',)) yield from job.save() yield from Job.fetch(job.id, connection=redis) assert not job.result_ttl
def test_description_is_persisted(redis): """Ensure that job's custom description is set properly.""" job = Job.create(func=say_hello, args=('Lionel',), description='Say hello!') yield from job.save() yield from Job.fetch(job.id, connection=redis) assert job.description == 'Say hello!' # Ensure job description is constructed from function call string job = Job.create(func=say_hello, args=('Lionel',)) yield from job.save() yield from Job.fetch(job.id, connection=redis) assert job.description == "fixtures.say_hello('Lionel')"
def test_job_dependency(loop): """Enqueue dependent jobs only if their parents don't fail.""" q = Queue() w = Worker([q]) parent_job = yield from q.enqueue(say_hello) job = yield from q.enqueue_call(say_hello, depends_on=parent_job) yield from w.work(burst=True, loop=loop) job = yield from Job.fetch(job.id) assert (yield from job.get_status()) == JobStatus.FINISHED parent_job = yield from q.enqueue(div_by_zero) job = yield from q.enqueue_call(say_hello, depends_on=parent_job) yield from w.work(burst=True, loop=loop) job = yield from Job.fetch(job.id) assert (yield from job.get_status()) != JobStatus.FINISHED
def test_custom_exc_handling(loop): """Custom exception handling.""" @asyncio.coroutine def black_hole(job, *exc_info): # Don't fall through to default behaviour (moving to failed # queue) return False q = Queue() failed_q = get_failed_queue() # Preconditions assert not (yield from failed_q.count) assert not (yield from q.count) # Action job = yield from q.enqueue(div_by_zero) assert (yield from q.count) == 1 w = Worker([q], exception_handlers=black_hole) yield from w.work(burst=True, loop=loop) # Should silently pass # Postconditions assert not (yield from q.count) assert not (yield from failed_q.count) # Check the job job = yield from Job.fetch(job.id) assert job.is_failed
def test_work_fails(loop): """Failing jobs are put on the failed queue.""" q = Queue() failed_q = get_failed_queue() # Preconditions assert not (yield from failed_q.count) assert not (yield from q.count) # Action job = yield from q.enqueue(div_by_zero) assert (yield from q.count) == 1 # keep for later enqueued_at_date = strip_microseconds(job.enqueued_at) w = Worker([q]) yield from w.work(burst=True, loop=loop) # Should silently pass # Postconditions assert not (yield from q.count) assert (yield from failed_q.count) == 1 assert not (yield from w.get_current_job_id()) # Check the job job = yield from Job.fetch(job.id) assert job.origin == q.name # Should be the original enqueued_at date, not the date of enqueueing # to the failed queue assert job.enqueued_at == enqueued_at_date assert job.exc_info # should contain exc_info
def test_persistence_of_parent_job(): """Storing jobs with parent job, either instance or key.""" parent_job = Job.create(func=some_calculation) yield from parent_job.save() job = Job.create(func=some_calculation, depends_on=parent_job) yield from job.save() stored_job = yield from Job.fetch(job.id) assert stored_job._dependency_id == parent_job.id assert (yield from stored_job.dependency) == parent_job job = Job.create(func=some_calculation, depends_on=parent_job.id) yield from job.save() stored_job = yield from Job.fetch(job.id) assert stored_job._dependency_id == parent_job.id assert (yield from stored_job.dependency) == parent_job
def test_custom_meta_is_persisted(redis): """Additional meta data on jobs are stored persisted correctly.""" job = Job.create(func=say_hello, args=('Lionel',)) job.meta['foo'] = 'bar' yield from job.save() raw_data = yield from redis.hget(job.key, 'meta') assert loads(raw_data)['foo'] == 'bar' job2 = yield from Job.fetch(job.id) assert job2.meta['foo'] == 'bar'
def test_store_then_fetch(): """Store, then fetch.""" job = Job.create(func=some_calculation, args=(3, 4), kwargs=dict(z=2)) yield from job.save() job2 = yield from Job.fetch(job.id) assert job.func == job2.func assert job.args == job2.args assert job.kwargs == job2.kwargs # Mathematical equation assert job == job2
def test_cleanup(redis): """Test that jobs and results are expired properly.""" job = Job.create(func=say_hello) yield from job.save() # Jobs with negative TTLs don't expire yield from job.cleanup(ttl=-1) assert (yield from redis.ttl(job.key)) == -1 # Jobs with positive TTLs are eventually deleted yield from job.cleanup(ttl=100) assert (yield from redis.ttl(job.key)) == 100 # Jobs with 0 TTL are immediately deleted yield from job.cleanup(ttl=0) with pytest.raises(NoSuchJobError): yield from Job.fetch(job.id, redis)
def test_fetch(redis): """Fetching jobs.""" yield from redis.hset('rq:job:some_id', 'data', "(S'fixtures.some_calculation'\n" "N(I3\nI4\nt(dp1\nS'z'\nI2\nstp2\n.") yield from redis.hset('rq:job:some_id', 'created_at', '2012-02-07T22:13:24Z') # Fetch returns a job job = yield from Job.fetch('some_id') assert job.id == 'some_id' assert job.func_name == 'fixtures.some_calculation' assert not job.instance assert job.args == (3, 4) assert job.kwargs == dict(z=2) assert job.created_at == datetime(2012, 2, 7, 22, 13, 24)
def test_fetching_can_fail(): """Fetching fails for non-existing jobs.""" with pytest.raises(NoSuchJobError): yield from Job.fetch('b4a44d44-da16-4620-90a6-798e8cd72ca0')