Opened 5 years ago
Last modified 5 years ago
#31065 closed Bug
"django.db.utils.InterfaceError: connection already closed" in unittests — at Version 1
Reported by: | Harm Verhagen | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
I found a weird bug in Django that causes database errors when running unittesets, this happens when doing nothing special/funky (see small included testcase)
Steps to reproduce
- Start a new project
myproj
, with a new appfoo
- Edit
foo/tests.py
from django.test import TestCase from django.contrib.auth.models import User class A(TestCase): """ We have a tearDownClass() in this class without a matching setUpClass Removing the tearDownClass, or adding a setUpClass fixes/hides the problem """ @classmethod def tearDownClass(cls): pass def test_foo(self): pass class B(TestCase): def test_foo(self): pass class C(TestCase): def test_foo(self): pass def setUp(self): User.objects.create_user('user', 'myemail@test.com', "123")
- edit your
settings.py
to connect to a postgresql server (The problem does _not_ reproduce with the default sqlite config)
-
./manage.py test foo.tests.A foo.tests.B foo.tests.C
(NB the order in which the tests are executed is important, in another order the problem does not reproduce)
result
$ ./manage.py test foo.tests.A foo.tests.B foo.tests.C Creating test database for alias 'default'... System check identified no issues (0 silenced). ..E ====================================================================== ERROR: test_foo (foo.tests.C) ---------------------------------------------------------------------- Traceback (most recent call last): File "/venv/lib/python3.5/site-packages/django/db/backends/base/base.py", line 235, in _cursor return self._prepare_cursor(self.create_cursor(name)) File "/venv/lib/python3.5/site-packages/django/db/backends/postgresql/base.py", line 223, in create_cursor cursor = self.connection.cursor() psycopg2.InterfaceError: connection already closed The above exception was the direct cause of the following exception: Traceback (most recent call last): File "myproj/foo/tests.py", line 39, in setUp User.objects.create_user('user', 'myemail@test.com', "123") File "/env/lib/python3.5/site-packages/django/contrib/auth/models.py", line 151, in create_user return self._create_user(username, email, password, **extra_fields) File "/venv/lib/python3.5/site-packages/django/contrib/auth/models.py", line 145, in _create_user user.save(using=self._db) File "/venv/lib/python3.5/site-packages/django/contrib/auth/base_user.py", line 66, in save super().save(*args, **kwargs) File "/venv/lib/python3.5/site-packages/django/db/models/base.py", line 741, in save force_update=force_update, update_fields=update_fields) File "/venv/lib/python3.5/site-packages/django/db/models/base.py", line 779, in save_base force_update, using, update_fields, File "/venv/lib/python3.5/site-packages/django/db/models/base.py", line 870, in _save_table result = self._do_insert(cls._base_manager, using, fields, update_pk, raw) File "/venv/lib/python3.5/site-packages/django/db/models/base.py", line 908, in _do_insert using=using, raw=raw) File "/venv/lib/python3.5/site-packages/django/db/models/manager.py", line 82, in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) File "/venv/lib/python3.5/site-packages/django/db/models/query.py", line 1186, in _insert return query.get_compiler(using=using).execute_sql(return_id) File "/venv/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 1366, in execute_sql with self.connection.cursor() as cursor: File "/venv/lib/python3.5/site-packages/django/db/backends/base/base.py", line 256, in cursor return self._cursor() File "/venv/lib/python3.5/site-packages/django/db/backends/base/base.py", line 235, in _cursor return self._prepare_cursor(self.create_cursor(name)) File "/venv/lib/python3.5/site-packages/django/db/utils.py", line 89, in __exit__ raise dj_exc_value.with_traceback(traceback) from exc_value File "/venv/lib/python3.5/site-packages/django/db/backends/base/base.py", line 235, in _cursor return self._prepare_cursor(self.create_cursor(name)) File "/venv/lib/python3.5/site-packages/django/db/backends/postgresql/base.py", line 223, in create_cursor cursor = self.connection.cursor() django.db.utils.InterfaceError: connection already closed ----------------------------------------------------------------------
expected result
All tests pass
notes
- The problem does not reproduce with sqlite
- The problem goes away if you add a
@setUpClass
to classA
- The problem goes away if you remove the
@tearDownClass
of classA
- The problem goes away if you change the order in which you execute the testclasses
- The problem goes away if you don't create the
User
in classC
version info
Seen on Django 2.2.8 and 2.2.6
psycopg2==2.7.3.1
postgresql 10.10
Note:
See TracTickets
for help on using tickets.