Opened 6 years ago
Closed 6 years ago
#31065 closed Bug (invalid)
"django.db.utils.InterfaceError: connection already closed" in unittests
| 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.pyfrom 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.pyto 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
@setUpClassto classA - The problem goes away if you remove the
@tearDownClassof 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
Userin classC
version info
Seen on Django 2.2.8 and 2.2.6
psycopg2==2.7.3.1
postgresql 10.10
Change History (2)
comment:1 by , 6 years ago
| Description: | modified (diff) |
|---|
comment:2 by , 6 years ago
| Resolution: | → invalid |
|---|---|
| Status: | new → closed |
| Version: | 2.2 → master |
Note:
See TracTickets
for help on using tickets.
You shouldn't override
setUpClass()ortearDownClass()methods without callingsuper(), see a warning box.