def test_wait_for_job_should_respond_with_queue_and_job_when_a_queue_is_not_empty(self): queue = Queue.get_queue('test') worker = Worker('test') worker.test_content = None class Thread(threading.Thread): def run(self): worker.update_keys() queue, job = worker.wait_for_job() worker.test_content = queue, job # start listening thread = Thread() thread.start() time.sleep(0.1) # no job, nothing received self.assertIsNone(worker.test_content) # add a job job = Job.add_job(queue_name='test', identifier='job:1') time.sleep(0.1) # info should be received self.assertEqual(worker.test_content[0].get_pk(), queue.get_pk()) self.assertTrue(isinstance(worker.test_content[0], Queue)) self.assertEqual(worker.test_content[1].get_pk(), job.get_pk()) self.assertTrue(isinstance(worker.test_content[1], Job)) # job must no be in the queue anymore self.assertNotIn(job.get_pk(), queue.waiting.lmembers())
def test_a_worker_should_run_only_one_time(self): worker = Worker('test', max_loops=2) worker.run() with self.assertRaises(ImplementationError): worker.run()
def tests_worker_should_handle_many_queues(self): queue1 = Queue(name='test', priority=1) queue2 = Queue(name='test', priority=2) worker = Worker('test') worker.update_keys() self.assertEqual(worker.keys, [queue2.waiting.key, queue1.waiting.key])
def test_get_job_method_should_return_a_job_based_on_its_pk(self): worker = Worker('test') job = Job.add_job(queue_name='test', identifier='job:1') # a job... test_job = worker.get_job(job.get_pk()) self.assertTrue(isinstance(test_job, Job)) self.assertEqual(test_job.get_pk(), job.get_pk()) # not a job... with self.assertRaises(ValueError): worker.get_job('foo')
def test_callback_should_be_called(self): result = {} def callback(job, queue): result['job'] = job.get_pk() result['queue'] = queue.get_pk() job = Job.add_job(identifier='job:1', queue_name='test') queue = Queue.get_queue(name='test') worker = Worker(name='test', callback=callback, max_loops=1) worker.run() self.assertEqual(result, {'job': job.get_pk(), 'queue': queue.get_pk()})
def test_job_error_method_should_be_called(self): class ExceptionWithCode(Exception): def __init__(self, message, code): super(ExceptionWithCode, self).__init__(message) self.message = message self.code = code def callback(job, queue): raise ExceptionWithCode('foobar', 42) job1 = Job.add_job(identifier='job:1', queue_name='test') queue = Queue.get_queue(name='test') worker = Worker(name='test', max_loops=1) # no callback worker.run() self.assertEqual(job1.status.hget(), STATUSES.ERROR) self.assertIn(job1.get_pk(), queue.errors.lmembers()) self.assertEqual(len(Error.collection()), 1) error = Error.get(identifier='job:1') self.assertEqual(error.message.hget(), 'You must implement your own action') self.assertEqual(error.code.hget(), None) job2 = Job.add_job(identifier='job:2', queue_name='test') queue = Queue.get_queue(name='test') worker = Worker(name='test', max_loops=1, callback=callback) # callback with exception worker.run() self.assertEqual(job2.status.hget(), STATUSES.ERROR) self.assertIn(job2.get_pk(), queue.errors.lmembers()) self.assertEqual(len(Error.collection()), 2) error = Error.get(identifier='job:2') self.assertEqual(error.message.hget(), 'foobar') self.assertEqual(error.code.hget(), '42')
def test_get_queue_method_should_return_a_queue_based_on_its_waiting_field_key(self): worker = Worker('test') queue = Queue.get_queue('test') # a queue... test_queue = worker.get_queue(queue.waiting.key) self.assertTrue(isinstance(test_queue, Queue)) self.assertEqual(test_queue.get_pk(), queue.get_pk()) # a non_existing_queue fake_queue_key = test_queue.waiting.key.replace('1', '2') with self.assertRaises(ValueError): worker.get_queue(fake_queue_key) # not a queue... with self.assertRaises(DoesNotExist): worker.get_queue('foo')
def test_blpop_timeout(self): class TestWorker(Worker): def wait_for_job(self): result = super(TestWorker, self).wait_for_job() if result is None: # force end to quit quickly self.end_forced = True return result Queue.get_queue('test') # test specific methods worker = Worker(name='test', timeout=1) worker.update_keys() test_value = worker.wait_for_job() self.assertIsNone(test_value) # test whole run worker = TestWorker(name='test', timeout=1) worker.run() self.assertEqual(worker.num_loops, 0)
def test_worker_without_queues_should_stop(self): worker = Worker(name='test', max_loops=1) worker.run() self.assertEqual(worker.num_loops, 0)
def test_must_stop_method_should_work(self): worker = Worker('test') self.assertEqual(worker.must_stop(), False) worker.num_loops = worker.max_loops self.assertEqual(worker.must_stop(), True) worker.num_loops = 0 worker.end_forced = True self.assertEqual(worker.must_stop(), True) worker.end_forced = False worker.end_signal_caught = True self.assertEqual(worker.must_stop(), True) worker.terminate_gracefuly = False self.assertEqual(worker.must_stop(), False)
def test_worker_should_stop_after_max_loops(self): Job.add_job('job:1', 'test') worker = Worker('test', max_loops=1) # one loop to run only one job worker.run() self.assertEqual(worker.num_loops, 1) self.assertEqual(worker.status, 'terminated')