karec/cookiecutter-flask-restful

Celery test failed

Xiderowg opened this issue · 4 comments

I am running python 3.7.4 on windows 10 with celery 4.4.7, and I am using rabbitmq 3.8.5 for broker and result backend.
I deploy example project by cookiecutter and install all requirements and cli, but when I tried to use tox to do unittest, all tests except celery's one passed. So am I doing wrong here? any help will be appreciated.

E:\Project\testrestful\restful_api>tox
GLOB sdist-make: E:\Project\testrestful\restful_api\setup.py
py38 create: E:\Project\testrestful\restful_api\.tox\py38
ERROR: InterpreterNotFound: python3.8
py37 inst-nodeps: E:\Project\testrestful\restful_api\.tox\.tmp\package\3\myapi-0.1.zip
py37 installed: alembic==1.4.2,amqp==2.6.1,aniso8601==8.0.0,apispec==3.3.1,apispec-webframeworks==0.5.2,appdirs==1.4.4,atomicwrites==1.4.0,attrs==19.3.0,billiard==3.6.3.0,black==19.10b0,celery==4.4.7,click==7.1.2,colorama==0.4.3,distlib==0.3.1,factory-boy==2.12.0,Faker==4.1.1,filelock==3.0.12,flake8==3.8.3,Flask==1.1.2,Flask-JWT-Extended==3.24.1,flask-marshmallow==0.13.0,Flask-Migrate==2.5.3,Flask-RESTful==0.3.8,Flask-SQLAlchemy==2.4.4,gunicorn==20.0.4,importlib-metadata==1.7.0,inflection==0.5.0,iniconfig==1.0.1,itsdangerous==1.1.0,Jinja2==2.11.2,kombu==4.6.11,Mako==1.1.3,MarkupSafe==1.1.1,marshmallow==3.7.1,marshmallow-sqlalchemy==0.23.1,mccabe==0.6.1,more-itertools==8.4.0,myapi @ file:///E:/Project/testrestful/restful_api/.tox/.tmp/package/3/myapi-0.1.zip,packaging==20.4,passlib==1.7.2,pathspec==0.8.0,pluggy==0.13.1,py==1.9.0,pycodestyle==2.6.0,pyflakes==2.2.0,PyJWT==1.7.1,pyparsing==2.4.7,pytest==6.0.1,pytest-factoryboy==2.0.3,pytest-flask==1.0.0,pytest-runner==5.2,python-dateutil==2.8.1,python-dotenv==0.14.0,python-editor==1.0.4,pytz==2020.1,PyYAML==5.3.1,redis==3.5.3,regex==2020.7.14,six==1.15.0,SQLAlchemy==1.3.18,text-unidecode==1.3,toml==0.10.1,tox==3.18.1,typed-ast==1.4.1,vine==1.3.0,virtualenv==20.0.30,Werkzeug==1.0.1,zipp==3.1.0
py37 run-test-pre: PYTHONHASHSEED='862'
py37 run-test: commands[0] | flake8 myapi
py37 run-test: commands[1] | black myapi --check
All done! ✨ 🍰 ✨
24 files would be left unchanged.
py37 run-test: commands[2] | pytest tests
================================================= test session starts =================================================
platform win32 -- Python 3.7.4, pytest-6.0.1, py-1.9.0, pluggy-0.13.1
cachedir: .tox\py37\.pytest_cache
rootdir: E:\Project\testrestful\restful_api
plugins: celery-4.4.7, Faker-4.1.1, factoryboy-2.0.3, flask-1.0.0
collected 8 items

tests\test_auth.py ..                                                                                            [ 25%]
tests\test_celery.py Message: 'Task handler raised error: %r'
Arguments: (Task of kind 'celery.ping' never registered, please make sure it's imported.,)
E                                                                                           [ 37%]
tests\test_user.py .....                                                                                         [100%]

======================================================= ERRORS ========================================================
___________________________________________ ERROR at setup of test_example ____________________________________________

request = <SubRequest 'celery_worker' for <Function test_example>>, celery_app = <Celery celery.tests at 0x1e4291ade08>
celery_includes = (), celery_worker_pool = 'prefork', celery_worker_parameters = {}

    @pytest.fixture()
    def celery_worker(request,
                      celery_app,
                      celery_includes,
                      celery_worker_pool,
                      celery_worker_parameters):
        # type: (Any, Celery, Sequence[str], str, Any) -> WorkController
        """Fixture: Start worker in a thread, stop it when the test returns."""
        if not NO_WORKER:
            for module in celery_includes:
                celery_app.loader.import_task_module(module)
            with worker.start_worker(celery_app,
                                     pool=celery_worker_pool,
>                                    **celery_worker_parameters) as w:

.tox\py37\lib\site-packages\celery\contrib\pytest.py:198:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
f:\anaconda\lib\contextlib.py:112: in __enter__
    return next(self.gen)
.tox\py37\lib\site-packages\celery\contrib\testing\worker.py:84: in start_worker
    assert ping.delay().get(timeout=ping_task_timeout) == 'pong'
.tox\py37\lib\site-packages\celery\result.py:237: in get
    on_message=on_message,
.tox\py37\lib\site-packages\celery\backends\base.py:668: in wait_for_pending
    return result.maybe_throw(propagate=propagate, callback=callback)
.tox\py37\lib\site-packages\celery\result.py:342: in maybe_throw
    self.throw(value, self._to_remote_traceback(tb))
.tox\py37\lib\site-packages\celery\result.py:335: in throw
    self.on_ready.throw(*args, **kwargs)
.tox\py37\lib\site-packages\vine\promises.py:244: in throw
    reraise(type(exc), exc, tb)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

tp = <class 'celery.exceptions.NotRegistered'>
value = Task of kind 'celery.ping' never registered, please make sure it's imported., tb = None

    def reraise(tp, value, tb=None):
        """Reraise exception."""
        if value.__traceback__ is not tb:
            raise value.with_traceback(tb)
>       raise value
E       celery.exceptions.NotRegistered: 'celery.ping'

.tox\py37\lib\site-packages\vine\five.py:195: NotRegistered
------------------------------------------------ Captured stderr setup ------------------------------------------------
--- Logging error ---
Traceback (most recent call last):
  File "f:\anaconda\lib\logging\__init__.py", line 1028, in emit
    stream.write(msg + self.terminator)
OSError: [WinError 6] 句柄无效。
Call stack:
================================================== warnings summary ===================================================
tests/test_celery.py::test_example
  e:\project\testrestful\restful_api\.tox\py37\lib\site-packages\celery\backends\amqp.py:67: CPendingDeprecationWarning:
      The AMQP result backend is scheduled for deprecation in     version 4.0 and removal in version v5.0.     Please use RPC backend or a persistent backend.

    alternative='Please use RPC backend or a persistent backend.')

-- Docs: https://docs.pytest.org/en/stable/warnings.html
=============================================== short test summary info ===============================================
ERROR tests/test_celery.py::test_example - celery.exceptions.NotRegistered: 'celery.ping'
======================================== 7 passed, 1 warning, 1 error in 1.98s ========================================

after disabling celery.ping by adding following code to ./test/test_celery.py

@pytest.fixture
def celery_worker_parameters():
    return {
        'perform_ping_check': False,
    }

error about celery.ping disappear, but it introduced a new error:

____________________________________________________ test_example _____________________________________________________

celery_app = <Celery celery.tests at 0x1aa60d7c688>, celery_worker = <Worker: gen4968@AlexLyn-PC (running)>

    def test_example(celery_app, celery_worker):
        """Simply test our dummy task using celery"""
        res = dummy_task.delay()
>       assert res.get() == "OK"

tests\test_celery.py:43:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.tox\tests\lib\site-packages\celery\result.py:237: in get
    on_message=on_message,
.tox\tests\lib\site-packages\celery\backends\base.py:668: in wait_for_pending
    return result.maybe_throw(propagate=propagate, callback=callback)
.tox\tests\lib\site-packages\celery\result.py:342: in maybe_throw
    self.throw(value, self._to_remote_traceback(tb))
.tox\tests\lib\site-packages\celery\result.py:335: in throw
    self.on_ready.throw(*args, **kwargs)
.tox\tests\lib\site-packages\vine\promises.py:244: in throw
    reraise(type(exc), exc, tb)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

tp = <class 'celery.exceptions.NotRegistered'>
value = Task of kind 'myapi.tasks.example.dummy_task' never registered, please make sure it's imported., tb = None

    def reraise(tp, value, tb=None):
        """Reraise exception."""
        if value.__traceback__ is not tb:
            raise value.with_traceback(tb)
>       raise value
E       celery.exceptions.NotRegistered: 'myapi.tasks.example.dummy_task'

.tox\tests\lib\site-packages\vine\five.py:195: NotRegistered

after changing

@pytest.fixture(scope="session")
def celery_worker_pool():
    return "prefork"

to

@pytest.fixture(scope="session")
def celery_worker_pool():
    return "solo"

the test finally passed, so I guess it is pool issue on windows to blame.
discussion on this issue: link
celery-4-windows also point out that not using the default prefork pool: link

karec commented

Hello @Xiderowg,

Thanks for this detailed investigation on that issue. Sadly I don't have a windows available to tests, but on linux using solo as worker pool doesn't have any impact on tests, so if that works for you I can update those tests and replace prefork with solo since it will have no impact on current test suit

thank you @karec , I will close this issue since it has been fixed.