samedi 19 décembre 2020

Django TestCase: duplicate database on fixture loading

Context

I just arrived on someone's Django project and I encounter a behavior I never experienced before. It has been a one man project for a year and a half now and the app became both quite complexe; like, a lot of dependencies and custom modules

Usually, I create a FIXTURE_DIRS in settings.py and it allows me to simply load fixtures while I run my tests:

class OnboardedViewTest(TestCase):
    fixtures = ["users.yaml", "surveys.yaml", "users_survey.yaml"]
    cbv = OnboardedView()

    def test_non_onboarded_users_fail_test_func(self):
        some_testing

In the context of this application, it raises the following exception

AssertionError: Problem installing fixture '/app/tests/fixtures/users.yaml': Database queries to 'userdata' are not allowed in this test. Add 'userdata' to tests.test_some_app.OnboardedViewTest.databases to ensure proper test isolation and silence this failure.

Ok then, what if I explicitly add this userdata database (and the other named default) to this test class ?

class OnboardedViewTest(TestCase):
    fixtures = ["users.yaml", "surveys.yaml", "users_survey.yaml"]
    cbv = OnboardedView()
    databases = ["default", "userdata"]

    def test_non_onboarded_users_fail_test_func(self):
        some_testing

Error

I'm then getting a psycopg2.errors.DuplicateDatabase

Creating test database for alias 'userdata'...
Got an error creating the test database: database "test_some_app" already exists

Type 'yes' if you would like to try deleting the test database 'test_some_app', or 'no' to cancel: Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 82, in _execute
    return self.cursor.execute(sql)
  File "/usr/local/lib/python3.8/site-packages/django_prometheus/db/common.py", line 71, in execute
    return super().execute(*args, **kwargs)
psycopg2.errors.DuplicateDatabase: database "test_some_app" already exists


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/creation.py", line 188, in _create_test_db
    self._execute_create_test_db(cursor, test_db_params, keepdb)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/postgresql/creation.py", line 42, in _execute_create_test_db
    super()._execute_create_test_db(cursor, parameters, keepdb)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/creation.py", line 174, in _execute_create_test_db
    cursor.execute('CREATE DATABASE %(dbname)s %(suffix)s' % parameters)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 66, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 82, in _execute
    return self.cursor.execute(sql)
  File "/usr/local/lib/python3.8/site-packages/django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 82, in _execute
    return self.cursor.execute(sql)
  File "/usr/local/lib/python3.8/site-packages/django_prometheus/db/common.py", line 71, in execute
    return super().execute(*args, **kwargs)
django.db.utils.ProgrammingError: database "test_some_app" already exists

There a few details that triggers me:

  1. why is this testing db creation handled at one point by django_prometheus? Is my problem a side effect of some exotic tuning?
  2. As I understand it, in the context of django's TestCase, separate DB are created for every test class (which seems to be the case here). Is test_some_app really created twice? By what?
  3. a weird exception concerning IPython (not sure of its relevance in the project)
...
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/creation.py", line 55, in create_test_db
    self._create_test_db(verbosity, autoclobber, keepdb)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/creation.py", line 197, in _create_test_db
    confirm = input(
EOFError: EOF when reading a line

If you suspect this is an IPython 7.19.0 bug, please report it at:
    https://github.com/ipython/ipython/issues

Question

Why is this database created twice?

env:

  • django 3.1.2
  • django-prometheus 2.1.0

Aucun commentaire:

Enregistrer un commentaire