diff --git a/django/test/testcases.py b/django/test/testcases.py
index b8d5737..6abbf3b 100644
a
|
b
|
class TransactionTestCase(SimpleTestCase):
|
794 | 794 | # are not available, we allow queries to be run. |
795 | 795 | allow_database_queries = True |
796 | 796 | |
| 797 | @classmethod |
| 798 | def setUpClass(cls): |
| 799 | super().setUpClass() |
| 800 | if not cls.multi_db: |
| 801 | for alias in connections: |
| 802 | if alias != DEFAULT_DB_ALIAS: |
| 803 | connection = connections[alias] |
| 804 | connection.cursor = _CursorFailure(cls.__name__, connection.cursor) |
| 805 | connection.chunked_cursor = _CursorFailure(cls.__name__, connection.chunked_cursor) |
| 806 | |
| 807 | @classmethod |
| 808 | def tearDownClass(cls): |
| 809 | super().tearDownClass() |
| 810 | if not cls.multi_db: |
| 811 | for alias in connections: |
| 812 | if alias != DEFAULT_DB_ALIAS: |
| 813 | connection = connections[alias] |
| 814 | connection.cursor = connection.cursor.wrapped |
| 815 | connection.chunked_cursor = connection.chunked_cursor.wrapped |
| 816 | |
797 | 817 | def _pre_setup(self): |
798 | 818 | """Performs any pre-test setup. This includes: |
799 | 819 | |
… |
… |
class TransactionTestCase(SimpleTestCase):
|
943 | 963 | func(*args, **kwargs) |
944 | 964 | |
945 | 965 | |
946 | | def connections_support_transactions(): |
947 | | """ |
948 | | Returns True if all connections support transactions. |
949 | | """ |
950 | | return all(conn.features.supports_transactions |
951 | | for conn in connections.all()) |
952 | | |
953 | | |
954 | 966 | class TestCase(TransactionTestCase): |
955 | 967 | """ |
956 | 968 | Similar to TransactionTestCase, but uses `transaction.atomic()` to achieve |
… |
… |
class TestCase(TransactionTestCase):
|
981 | 993 | atomics[db_name].__exit__(None, None, None) |
982 | 994 | |
983 | 995 | @classmethod |
| 996 | def connections_support_transactions(cls): |
| 997 | """Return True if all connections support transactions.""" |
| 998 | return all( |
| 999 | connections[db_name].features.supports_transactions |
| 1000 | for db_name in cls._databases_names() |
| 1001 | ) |
| 1002 | |
| 1003 | @classmethod |
984 | 1004 | def setUpClass(cls): |
985 | 1005 | super().setUpClass() |
986 | | if not connections_support_transactions(): |
| 1006 | if not cls.connections_support_transactions(): |
987 | 1007 | return |
988 | 1008 | cls.cls_atomics = cls._enter_atomics() |
989 | 1009 | |
… |
… |
class TestCase(TransactionTestCase):
|
1006 | 1026 | |
1007 | 1027 | @classmethod |
1008 | 1028 | def tearDownClass(cls): |
1009 | | if connections_support_transactions(): |
| 1029 | if cls.connections_support_transactions(): |
1010 | 1030 | cls._rollback_atomics(cls.cls_atomics) |
1011 | 1031 | for conn in connections.all(): |
1012 | 1032 | conn.close() |
… |
… |
class TestCase(TransactionTestCase):
|
1018 | 1038 | pass |
1019 | 1039 | |
1020 | 1040 | def _should_reload_connections(self): |
1021 | | if connections_support_transactions(): |
| 1041 | if self.connections_support_transactions(): |
1022 | 1042 | return False |
1023 | 1043 | return super()._should_reload_connections() |
1024 | 1044 | |
1025 | 1045 | def _fixture_setup(self): |
1026 | | if not connections_support_transactions(): |
| 1046 | if not self.connections_support_transactions(): |
1027 | 1047 | # If the backend does not support transactions, we should reload |
1028 | 1048 | # class data before each test |
1029 | 1049 | self.setUpTestData() |
… |
… |
class TestCase(TransactionTestCase):
|
1033 | 1053 | self.atomics = self._enter_atomics() |
1034 | 1054 | |
1035 | 1055 | def _fixture_teardown(self): |
1036 | | if not connections_support_transactions(): |
| 1056 | if not self.connections_support_transactions(): |
1037 | 1057 | return super()._fixture_teardown() |
1038 | 1058 | try: |
1039 | 1059 | for db_name in reversed(self._databases_names()): |
diff --git a/tests/servers/tests.py b/tests/servers/tests.py
index b114b96..4f4d3fb 100644
a
|
b
|
|
1 | 1 | """ |
2 | 2 | Tests for django.core.servers. |
3 | 3 | """ |
4 | | import errno |
5 | 4 | import os |
6 | | import socket |
7 | 5 | from urllib.error import HTTPError |
8 | 6 | from urllib.parse import urlencode |
9 | 7 | from urllib.request import urlopen |
… |
… |
class LiveServerDatabase(LiveServerBase):
|
103 | 101 | ) |
104 | 102 | |
105 | 103 | |
106 | | class LiveServerPort(LiveServerBase): |
107 | | |
108 | | def test_port_bind(self): |
109 | | """ |
110 | | Each LiveServerTestCase binds to a unique port or fails to start a |
111 | | server thread when run concurrently (#26011). |
112 | | """ |
113 | | TestCase = type("TestCase", (LiveServerBase,), {}) |
114 | | try: |
115 | | TestCase.setUpClass() |
116 | | except socket.error as e: |
117 | | if e.errno == errno.EADDRINUSE: |
118 | | # We're out of ports, LiveServerTestCase correctly fails with |
119 | | # a socket error. |
120 | | return |
121 | | # Unexpected error. |
122 | | raise |
123 | | try: |
124 | | # We've acquired a port, ensure our server threads acquired |
125 | | # different addresses. |
126 | | self.assertNotEqual( |
127 | | self.live_server_url, TestCase.live_server_url, |
128 | | "Acquired duplicate server addresses for server threads: %s" % self.live_server_url |
129 | | ) |
130 | | finally: |
131 | | if hasattr(TestCase, 'server_thread'): |
132 | | TestCase.server_thread.terminate() |
| 104 | # Remove for debugging purposes since this test isn't isolated |
133 | 105 | |
134 | 106 | |
135 | 107 | class LiverServerThreadedTests(LiveServerBase): |
diff --git a/tests/test_runner/tests.py b/tests/test_runner/tests.py
index 708a7c2..63194dc 100644
a
|
b
|
from django.test import (
|
14 | 14 | TestCase, TransactionTestCase, skipUnlessDBFeature, testcases, |
15 | 15 | ) |
16 | 16 | from django.test.runner import DiscoverRunner |
17 | | from django.test.testcases import connections_support_transactions |
18 | 17 | from django.test.utils import dependency_ordered |
19 | 18 | |
20 | 19 | from .models import Person |
… |
… |
class Sqlite3InMemoryTestDbs(TestCase):
|
229 | 228 | # Transaction support should be properly initialized for the 'other' DB |
230 | 229 | self.assertTrue(other.features.supports_transactions, msg) |
231 | 230 | # And all the DBs should report that they support transactions |
232 | | self.assertTrue(connections_support_transactions(), msg) |
233 | 231 | |
234 | 232 | |
235 | 233 | class DummyBackendTest(unittest.TestCase): |
… |
… |
class EmptyDefaultDatabaseTest(unittest.TestCase):
|
358 | 356 | testcases.connections = db.ConnectionHandler({'default': {}}) |
359 | 357 | connection = testcases.connections[db.utils.DEFAULT_DB_ALIAS] |
360 | 358 | self.assertEqual(connection.settings_dict['ENGINE'], 'django.db.backends.dummy') |
361 | | connections_support_transactions() |
diff --git a/tests/test_utils/tests.py b/tests/test_utils/tests.py
index 19ef405..242bea4 100644
a
|
b
|
class TestBadSetUpTestData(TestCase):
|
1022 | 1022 | cls._in_atomic_block = connection.in_atomic_block |
1023 | 1023 | |
1024 | 1024 | @classmethod |
1025 | | def tearDownClass(Cls): |
| 1025 | def tearDownClass(cls): |
1026 | 1026 | # override to avoid a second cls._rollback_atomics() which would fail. |
1027 | 1027 | # Normal setUpClass() methods won't have exception handling so this |
1028 | 1028 | # method wouldn't typically be run. |
1029 | | pass |
| 1029 | super(TestCase, cls).tearDownClass() |
1030 | 1030 | |
1031 | 1031 | @classmethod |
1032 | 1032 | def setUpTestData(cls): |