def test_expired(): """Test timeout expired task instances.""" celery.conf.update({'CELERYD_TASK_TIME_LIMIT': 5}) manager_class = _select_manager(celery.backend.__class__.__name__) manager_instance = list() task = celery.tasks['tests.instances.add'] original_exit = manager_class.__exit__ def new_exit(self, *_): manager_instance.append(self) return None setattr(manager_class, '__exit__', new_exit) # Run the task and don't remove the lock after a successful run. assert 8 == task.apply_async(args=(4, 4)).get() setattr(manager_class, '__exit__', original_exit) # Run again, lock is still active so this should fail. with pytest.raises(OtherInstanceError): task.apply_async(args=(4, 4)).get() # Wait 5 seconds (per CELERYD_TASK_TIME_LIMIT), then re-run, should work. time.sleep(5) assert 8 == task.apply_async(args=(4, 4)).get() celery.conf.update({'CELERYD_TASK_TIME_LIMIT': None})
def test_collision(task_name, expected): """Test single-instance collision.""" manager_class = _select_manager(celery.backend.__class__.__name__) manager_instance = list() task = celery.tasks[task_name] # First run the task and prevent it from removing the lock. def new_exit(self, *_): manager_instance.append(self) return None original_exit = manager_class.__exit__ setattr(manager_class, '__exit__', new_exit) assert expected == task.apply_async(args=(4, 4)).get() setattr(manager_class, '__exit__', original_exit) assert manager_instance[0].is_already_running is True # Now run it again. with pytest.raises(OtherInstanceError) as e: task.apply_async(args=(4, 4)).get() if manager_instance[0].include_args: assert str(e.value).startswith('Failed to acquire lock, {0}.args.'.format(task_name)) else: assert 'Failed to acquire lock, {0} already running.'.format(task_name) == str(e.value) assert manager_instance[0].is_already_running is True # Clean up. manager_instance[0].reset_lock() assert manager_instance[0].is_already_running is False # Once more. assert expected == task.apply_async(args=(4, 4)).get()
def test_instances(task_name, timeout): """Test task instances.""" manager_class = _select_manager(celery.backend.__class__.__name__) manager_instance = list() task = celery.tasks[task_name] original_exit = manager_class.__exit__ def new_exit(self, *_): manager_instance.append(self) return original_exit(self, *_) setattr(manager_class, '__exit__', new_exit) task.apply_async(args=(4, 4)).get() setattr(manager_class, '__exit__', original_exit) assert timeout == manager_instance[0].timeout
def test_settings(key, value): """Test different Celery time limit settings.""" celery.conf.update({key: value}) manager_class = _select_manager(celery.backend.__class__.__name__) manager_instance = list() original_exit = manager_class.__exit__ def new_exit(self, *_): manager_instance.append(self) return original_exit(self, *_) setattr(manager_class, '__exit__', new_exit) tasks = [('tests.instances.mul', 20), ('tests.instances.add', value), ('tests.instances.add2', 70), ('tests.instances.add3', 80)] for task_name, timeout in tasks: task = celery.tasks[task_name] task.apply_async(args=(4, 4)).get() assert timeout == manager_instance.pop().timeout setattr(manager_class, '__exit__', original_exit) celery.conf.update({key: None})
def test_include_args(): """Test single-instance collision with task arguments taken into account.""" manager_class = _select_manager(celery.backend.__class__.__name__) manager_instance = list() task = celery.tasks['tests.instances.mul'] # First run the tasks and prevent them from removing the locks. def new_exit(self, *_): """Expected to be run twice.""" manager_instance.append(self) return None original_exit = manager_class.__exit__ setattr(manager_class, '__exit__', new_exit) assert 16 == task.apply_async(args=(4, 4)).get() assert 20 == task.apply_async(args=(5, 4)).get() setattr(manager_class, '__exit__', original_exit) assert manager_instance[0].is_already_running is True assert manager_instance[1].is_already_running is True # Now run them again. with pytest.raises(OtherInstanceError) as e: task.apply_async(args=(4, 4)).get() assert str(e.value).startswith('Failed to acquire lock, tests.instances.mul.args.') assert manager_instance[0].is_already_running is True with pytest.raises(OtherInstanceError) as e: task.apply_async(args=(5, 4)).get() assert str(e.value).startswith('Failed to acquire lock, tests.instances.mul.args.') assert manager_instance[1].is_already_running is True # Clean up. manager_instance[0].reset_lock() assert manager_instance[0].is_already_running is False manager_instance[1].reset_lock() assert manager_instance[1].is_already_running is False # Once more. assert 16 == task.apply_async(args=(4, 4)).get() assert 20 == task.apply_async(args=(5, 4)).get()
def test_settings(key, value): """Test different Celery time limit settings.""" celery.conf.update({key: value}) manager_class = _select_manager(celery.backend.__class__.__name__) manager_instance = list() original_exit = manager_class.__exit__ def new_exit(self, *_): manager_instance.append(self) return original_exit(self, *_) setattr(manager_class, '__exit__', new_exit) tasks = [ ('tests.instances.mul', 20), ('tests.instances.add', value), ('tests.instances.add2', 70), ('tests.instances.add3', 80) ] for task_name, timeout in tasks: task = celery.tasks[task_name] task.apply_async(args=(4, 4)).get() assert timeout == manager_instance.pop().timeout setattr(manager_class, '__exit__', original_exit) celery.conf.update({key: None})