Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error on teardown of test database in Django integration test #1106

Open
medihack opened this issue Jul 8, 2024 · 6 comments
Open

Error on teardown of test database in Django integration test #1106

medihack opened this issue Jul 8, 2024 · 6 comments

Comments

@medihack
Copy link
Member

medihack commented Jul 8, 2024

When running an integration (sync) test using Pytest in Django I end up with a warning that another session is using the database:

adit/core/tests/test_tasks.py::test_process_dicom_task_that_succeeds
  /app:0: PytestWarning: Error when trying to teardown test databases: OperationalError('database "test_postgres" is being accessed by other users\nDETAIL:  There is 1 other session using the database.')

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html

This happens as soon as I run the worker, as mentioned in the documentation:

my_app = app.with_connector(app.connector.get_worker_connector())  # type: ignore
my_app.run_worker(wait=False, install_signal_handlers=False, listen_notify=False)

It seems the worker leaves some connections open. I tried calling app.close() explicitly at the end of the test, but this also doesn't help.

@medihack
Copy link
Member Author

medihack commented Jul 8, 2024

It's more complicated than I thought. I also run some async stuff in my sync task, and this error doesn't seem to purely depend on Procrastinate. I will close this for now and investigate it further. Also, our mix of sync and async stuff really bites us quite often 🙄.

@medihack medihack closed this as completed Jul 8, 2024
@medihack
Copy link
Member Author

medihack commented Jul 8, 2024

I investigated this a bit further. The above error happens as soon as I do a database access in the task, e.g.:

@app.task
def example_task():
    job = ProcrastinateJob.objects.first()
    assert job is not None

Also when using async tasks, e.g.:

@app.task
async def example_task_async():
    job = await ProcrastinateJob.objects.afirst()
    assert job is not None

A simple workaround is to close the database connection at the end of a task manually by calling db.close_old_connections() resp. await database_sync_to_async(db.close_old_connections)().
It doesn't work to close the connections in the test itself; it must be in the task. And maybe there is also a nicer workaround (without changing the task's code).

Maybe we should add a hint about this to the documentation. That's why I reopen this issue.

@medihack medihack reopened this Jul 8, 2024
@ewjoachim
Copy link
Member

This looks like we might be able to make a reproducing test in procrastinate's own codebase ?

@medihack
Copy link
Member Author

medihack commented Jul 8, 2024

Sure, I can add an integration test. It won't fail; pytest just provides it as a warning, but it will be visible on the console.

@ewjoachim
Copy link
Member

You can turn that warning into an error with @pytest.mark.filterwarnings (you can use filterwarning for the whole testsuite but in this cas we probably want to do it only for the specific tests that handle this)

@medihack
Copy link
Member Author

Just to keep you informed, it is not reproducible in Procrastinate itself, but we use a slightly different setup (Django 5, Psycopg 3). I will set up a minimal Django 5 project with Procrastinate in the upcoming days and see if I can reproduce it there, but I have the feeling there's nothing Procrastinate can do about it. I will keep you updated, and eventually close the issue again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants