예제 #1
0
class CommandsTests(TestCase):
    """
    Tests that we can both run worker and clear jobs using custom commands.
    """
    def setUp(self):
        self.cq = CacheQ(name='CacheQTests')
    
    def test_run_worker(self):
        """
        Tests that we can run a worker. We will test only with burst mode option.
        """
        self.cq.enqueue(operator.add, 1,2)
        self.assertEqual(Job.objects.filter(status=Job.PENDING).count(), 1)
        call_command('cqworker', burst=True, queue_name='CacheQTests')
        self.assertEqual(Job.objects.filter(status=Job.DONE).count(), 1)
    
    def test_clear_jobs(self):
        """
        Tests that we can clear jobs depending on status.
        """
        for status in [Job.PENDING, Job.PENDING, Job.FAILED, Job.FAILED, Job.DONE, Job.DONE]:
            Job.objects.create(status=status)
        self.assertEqual(Job.objects.count(), 6)
        call_command('cqclear', 'failed')
        self.assertEqual(Job.objects.count(), 4)
        self.assertFalse(Job.objects.filter(status=Job.FAILED).exists())
        call_command('cqclear', 'all', no_input=True)
        self.assertEqual(Job.objects.count(), 0)
예제 #2
0
 def setUp(self):
     self.cq = CacheQ(name='CacheQTests')
예제 #3
0
 def setUp(self):
     self.cq = CacheQ(name='CacheQTests')
     self.worker = get_worker(queue_name='CacheQTests', worker_name='testworker')
     _, self.tempfname = tempfile.mkstemp()
예제 #4
0
class WorkerTests(TestCase):
    """
    Tests cacheq's worker. This worker will poll the message queue and run jobs accordingly, 
    also updating job status and results.
    """
    def setUp(self):
        self.cq = CacheQ(name='CacheQTests')
        self.worker = get_worker(queue_name='CacheQTests', worker_name='testworker')
        _, self.tempfname = tempfile.mkstemp()
    
    def test_single_task(self):
        """
        Tests we can process a single task in burst mode.
        """
        job = self.cq.enqueue(operator.add, 1,2)
        self.worker.run(burst=True)
        # check job status and result
        self.assertTrue(job.ready())
        self.assertEqual(job.status, Job.DONE)
        self.assertEqual(job.result, 3)
        self.assertEqual(type(job.execution_time), float)
        self.assertTrue(job.execution_time > 0)
    
    def test_multiple_tasks(self):
        """
        Tests we can process multiple tasks for a single job in burst mode.
        """
        job = self.cq.enqueue_many([
                (operator.add, (2,3), {}), (operator.div, (5,float(2)), {})])
        self.worker.run(burst=True)
        # check job status and results
        self.assertTrue(job.ready())
        self.assertEqual(job.status, Job.DONE)
        self.assertEqual(job.result, [5, 2.5])
    
    def test_complex_tasks(self):
        """
        Tests that we can add a series of tasks that depend on each other, which will be run 
        in order. Also, multiple jobs will be submitted.
        """
        job1 = self.cq.enqueue_many([
            (task1, (self.tempfname, 'Hello world!'), {}), 
            (task2, (self.tempfname, 'Hello world!'), {})])
        job2 = self.cq.enqueue(operator.add, 3,3)
        self.worker.run(burst=True)
        # check job status and response
        self.assertTrue(job1.ready())
        self.assertEqual(job1.status, Job.DONE)
        self.assertEqual(job1.result, [None, None])
        self.assertTrue(job2.ready())
        self.assertEqual(job2.status, Job.DONE)
        self.assertEqual(job2.result, 6)
    
    def test_exception(self):
        """
        Tests that jobs can handle exceptions properly.
        """
        job = failtask.delay()
        self.worker.run(burst=True)
        # let's check status and traceback
        self.assertTrue(job.ready())
        self.assertEqual(job.status, Job.FAILED)
        self.assertEqual(job.result, None)
        self.assertTrue('raise Exception("Custom exception")' in job.traceback)
        self.assertFalse(job.running)
    
    def tearDown(self):
        # remove tempfile
        os.remove(self.tempfname)
예제 #5
0
 def setUp(self):
     self.cq = CacheQ('CacheQTests')
예제 #6
0
class CacheQTests(TestCase):
    """
    Tests that we can create a CacheQ object that manages job placement.
    """
    def setUp(self):
        self.cq = CacheQ('CacheQTests')
    
    def test_enqueue(self):
        """
        Tests that we can enqueue jobs using CacheQ.enqueue.
        """
        self.cq.enqueue(operator.add, 1, 2)
        # check if a Job object was created
        self.assertEqual(Job.objects.count(), 1)
        job = Job.objects.all()[0]
        task = job.pop_task()
        self.assertEqual(operator.add, task[0])
        # JSON field won't store tuples, so we need 
        # to take that into account for args
        self.assertEqual([1, 2], task[1])
        self.assertEqual({}, task[2])
        self.assertEqual(job.status, Job.PENDING)
        self.assertEqual(job.running, False)
        # no more tasks in job
        self.assertEqual(job.pop_task(), None)
        # check if message queue was signaled
        self.assertEqual(self.cq.queue.pop_message(), job.uuid)
    
    def test_enqueue_many(self):
        """
        Tests that we can enqueu a list of tasks using the following syntax:
        
        sqobj.enqueue_many([(func1, args1, kwargs1), (func2, args2, kwargs2), ...])
        """
        # JSON field will not store tuples, only lists
        # so we need to take that into account for args
        tasks = [(operator.add, [1,2], {}), (operator.div, [], {'a': 2, 'b': 2})]
        self.cq.enqueue_many(tasks)
        # only one job was created
        self.assertEqual(Job.objects.count(), 1)
        job = Job.objects.all()[0]
        # test tasks are equal
        for task in tasks:
            test_iter = zip(task, job.pop_task())
            for item in test_iter:
                self.assertEqual(*item)
        # no more tasks are available
        self.assertEqual(job.pop_task(), None)
        # check if message queue was signaled
        self.assertEqual(self.cq.queue.pop_message(), job.uuid)
    
    def test_job_decorator(self):
        """
        Tests that we can enqueu a function by calling func.delay(*args, **kwargs), which 
        will create a Job with one task and return the job instance.
        """
        decorated = self.cq.job(operator.div)
        decorated.delay(1,b=2)
        # this should have created one job
        self.assertEqual(Job.objects.count(), 1)
        job = Job.objects.all()[0]
        task = job.pop_task()
        self.assertEqual(task[0], operator.div)
        self.assertEqual(task[1], [1])
        self.assertEqual(task[2], {'b': 2})
        # no more tasks
        self.assertEqual(job.pop_task(), None)
        # check if message queue was signaled
        self.assertEqual(self.cq.queue.pop_message(), job.uuid)
        # try with decorated myfunc
        myfunc.delay(2,3)
        self.assertEqual(Job.objects.count(), 2)
        job = Job.objects.all()[1]
        task = job.pop_task()
        self.assertEqual(task[0], myfunc)
        self.assertEqual(task[1], [2,3])
        self.assertEqual(task[2], {})
        self.assertEqual(job.pop_task(), None)
        # check if message queue was signaled
        self.assertEqual(self.cq.queue.pop_message(), job.uuid)