Skip to content

Commit b415cef

Browse files
authored
Fixed #36946 -- Respected test database name when running tests in parallel on SQLite.
The "spawn" and "forkserver" multiprocessing modes were affected.
1 parent e4372f1 commit b415cef

2 files changed

Lines changed: 52 additions & 1 deletion

File tree

django/db/backends/sqlite3/creation.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,9 @@ def setup_worker_connection(self, _worker_id):
142142
connection_str = (
143143
f"file:memorydb_{alias}_{_worker_id}?mode=memory&cache=shared"
144144
)
145+
source_db_name = settings_dict["NAME"]
145146
source_db = self.connection.Database.connect(
146-
f"file:{alias}_{_worker_id}.sqlite3?mode=ro", uri=True
147+
f"file:{source_db_name}?mode=ro", uri=True
147148
)
148149
target_db = sqlite3.connect(connection_str, uri=True)
149150
source_db.backup(target_db)

tests/backends/sqlite/test_creation.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import copy
22
import multiprocessing
3+
import sqlite3
34
import unittest
45
from unittest import mock
56

@@ -41,3 +42,52 @@ def test_get_test_db_clone_settings_not_supported(self, *mocked_objects):
4142
msg = "Cloning with start method 'unsupported' is not supported."
4243
with self.assertRaisesMessage(NotSupportedError, msg):
4344
connection.creation.get_test_db_clone_settings(1)
45+
46+
@mock.patch.object(multiprocessing, "get_start_method", return_value="spawn")
47+
def test_setup_worker_connection_respects_test_database_name(self, *mocked_objects):
48+
test_connection = copy.copy(connections[DEFAULT_DB_ALIAS])
49+
test_connection.settings_dict = copy.deepcopy(
50+
connections[DEFAULT_DB_ALIAS].settings_dict
51+
)
52+
tests = [
53+
("mytest.db", "mytest_2.db"),
54+
("mytest", "mytest_2"),
55+
]
56+
for test_db_name, expected_source_db_name in tests:
57+
with self.subTest(test_db_name=test_db_name):
58+
# When calling setup_worker_connection(), the test db has been
59+
# created already and its name has been copied to
60+
# settings_dict["NAME"], so no need to set ["TEST"]["NAME"].
61+
test_connection.settings_dict["NAME"] = test_db_name
62+
creation_class = test_connection.creation_class(test_connection)
63+
worker_id = 2
64+
mock_source_db = mock.MagicMock()
65+
mock_target_db = mock.MagicMock()
66+
with (
67+
# Mock connection to source test database.
68+
mock.patch.object(
69+
test_connection.Database,
70+
"connect",
71+
return_value=mock_source_db,
72+
) as mock_source_connect,
73+
# Mock connection to target in-memory db for copying.
74+
mock.patch.object(
75+
sqlite3,
76+
"connect",
77+
return_value=mock_target_db,
78+
) as mock_target_connect,
79+
# Mock reconnection to target in-memory db after copying.
80+
mock.patch.object(test_connection, "connect"),
81+
):
82+
creation_class.setup_worker_connection(worker_id)
83+
mock_source_connect.assert_called_once_with(
84+
f"file:{expected_source_db_name}?mode=ro",
85+
uri=True,
86+
)
87+
mock_target_connect.assert_called_once_with(
88+
"file:memorydb_default_2?mode=memory&cache=shared",
89+
uri=True,
90+
)
91+
mock_source_db.backup.assert_called_once_with(mock_target_db)
92+
mock_source_db.close.assert_called_once()
93+
mock_target_db.close.assert_called_once()

0 commit comments

Comments
 (0)