summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2024-12-17 23:38:23 -0500
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2025-02-16 08:43:42 +0100
commit2d34ebe49a25d0974392583d5bbd954baf742a32 (patch)
tree2d1803e68dadb701615094010310081b6ea9fd23
parent99ac8e2589ea978c1c80ff66b4536814121f77dd (diff)
Refs #35967 -- Deprecated BaseDatabaseCreation.create_test_db(serialize).
Given there are no longer any internal usages of serialize=True and it poses a risk to non-test databases integrity it seems appropriate to deprecate it.
-rw-r--r--django/core/management/commands/testserver.py2
-rw-r--r--django/db/backends/base/creation.py20
-rw-r--r--django/test/utils.py1
-rw-r--r--docs/internals/deprecation.txt3
-rw-r--r--docs/releases/6.0.txt6
-rw-r--r--docs/topics/testing/advanced.txt15
-rw-r--r--tests/backends/base/test_creation.py48
-rw-r--r--tests/test_runner/tests.py2
8 files changed, 78 insertions, 19 deletions
diff --git a/django/core/management/commands/testserver.py b/django/core/management/commands/testserver.py
index a8a03764c9..ee472794f7 100644
--- a/django/core/management/commands/testserver.py
+++ b/django/core/management/commands/testserver.py
@@ -41,7 +41,7 @@ class Command(BaseCommand):
# Create a test database.
db_name = connection.creation.create_test_db(
- verbosity=verbosity, autoclobber=not interactive, serialize=False
+ verbosity=verbosity, autoclobber=not interactive
)
# Import the fixture data into the test database.
diff --git a/django/db/backends/base/creation.py b/django/db/backends/base/creation.py
index 6856fdb596..845235bc72 100644
--- a/django/db/backends/base/creation.py
+++ b/django/db/backends/base/creation.py
@@ -1,5 +1,6 @@
import os
import sys
+import warnings
from io import StringIO
from django.apps import apps
@@ -7,6 +8,7 @@ from django.conf import settings
from django.core import serializers
from django.db import router
from django.db.transaction import atomic
+from django.utils.deprecation import RemovedInDjango70Warning
from django.utils.module_loading import import_string
# The prefix to put on the default database name when creating
@@ -29,8 +31,10 @@ class BaseDatabaseCreation:
def log(self, msg):
sys.stderr.write(msg + os.linesep)
+ # RemovedInDjango70Warning: When the deprecation ends, replace with:
+ # def create_test_db(self, verbosity=1, autoclobber=False, keepdb=False):
def create_test_db(
- self, verbosity=1, autoclobber=False, serialize=True, keepdb=False
+ self, verbosity=1, autoclobber=False, serialize=None, keepdb=False
):
"""
Create a test database, prompting the user for confirmation if the
@@ -90,8 +94,18 @@ class BaseDatabaseCreation:
# and store it on the connection. This slightly horrific process is so people
# who are testing on databases without transactions or who are using
# a TransactionTestCase still get a clean database on every test run.
- if serialize:
- self.connection._test_serialized_contents = self.serialize_db_to_string()
+ if serialize is not None:
+ warnings.warn(
+ "DatabaseCreation.create_test_db(serialize) is deprecated. Call "
+ "DatabaseCreation.serialize_test_db() once all test databases are set "
+ "up instead if you need fixtures persistence between tests.",
+ stacklevel=2,
+ category=RemovedInDjango70Warning,
+ )
+ if serialize:
+ self.connection._test_serialized_contents = (
+ self.serialize_db_to_string()
+ )
call_command("createcachetable", database=self.connection.alias)
diff --git a/django/test/utils.py b/django/test/utils.py
index a4e80b0b53..78bbb0cf65 100644
--- a/django/test/utils.py
+++ b/django/test/utils.py
@@ -205,7 +205,6 @@ def setup_databases(
verbosity=verbosity,
autoclobber=not interactive,
keepdb=keepdb,
- serialize=False,
)
if serialized_aliases is None or alias in serialized_aliases:
serialize_connections.append(connection)
diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt
index e29c554f95..0a8ccaa20a 100644
--- a/docs/internals/deprecation.txt
+++ b/docs/internals/deprecation.txt
@@ -15,6 +15,9 @@ about each item can often be found in the release notes of two versions prior.
See the :ref:`Django 6.0 release notes <deprecated-features-6.0>` for more
details on these changes.
+* The ``serialize`` keyword argument of
+ ``BaseDatabaseCreation.create_test_db()`` will be removed.
+
.. _deprecation-removed-in-6.1:
6.1
diff --git a/docs/releases/6.0.txt b/docs/releases/6.0.txt
index 4e5f3c1f02..abc56e6886 100644
--- a/docs/releases/6.0.txt
+++ b/docs/releases/6.0.txt
@@ -235,7 +235,8 @@ Database backend API
This section describes changes that may be needed in third-party database
backends.
-* ...
+* ``BaseDatabaseCreation.create_test_db(serialize)`` is deprecated. Use
+ ``serialize_db_to_string()`` instead.
Dropped support for MariaDB 10.5
--------------------------------
@@ -278,7 +279,8 @@ Features deprecated in 6.0
Miscellaneous
-------------
-* ...
+* ``BaseDatabaseCreation.create_test_db(serialize)`` is deprecated. Use
+ ``serialize_db_to_string()`` instead.
Features removed in 6.0
=======================
diff --git a/docs/topics/testing/advanced.txt b/docs/topics/testing/advanced.txt
index c2d1fc6c6e..79d3f97f48 100644
--- a/docs/topics/testing/advanced.txt
+++ b/docs/topics/testing/advanced.txt
@@ -796,7 +796,7 @@ utility methods in the ``django.test.utils`` module.
The creation module of the database backend also provides some utilities that
can be useful during testing.
-.. function:: create_test_db(verbosity=1, autoclobber=False, serialize=True, keepdb=False)
+.. function:: create_test_db(verbosity=1, autoclobber=False, keepdb=False)
Creates a new test database and runs ``migrate`` against it.
@@ -812,12 +812,6 @@ can be useful during testing.
* If ``autoclobber`` is ``True``, the database will be destroyed
without consulting the user.
- ``serialize`` determines if Django serializes the database into an
- in-memory JSON string before running tests (used to restore the database
- state between tests if you don't have transactions). You can set this to
- ``False`` to speed up creation time if you don't have any test classes
- with :ref:`serialized_rollback=True <test-case-serialized-rollback>`.
-
``keepdb`` determines if the test run should use an existing
database, or create a new one. If ``True``, the existing
database will be used, or created if not present. If ``False``,
@@ -830,6 +824,13 @@ can be useful during testing.
:setting:`NAME` in :setting:`DATABASES` to match the name of the test
database.
+ .. deprecated:: 6.0
+
+ The ``serialize`` keyword argument is deprecated. Passing
+ ``serialize=True`` would automatically call
+ :func:`serialize_db_to_string` but it was deprecated as it could result
+ in queries against non-test databases during serialization.
+
.. function:: destroy_test_db(old_database_name, verbosity=1, keepdb=False)
Destroys the database whose name is the value of :setting:`NAME` in
diff --git a/tests/backends/base/test_creation.py b/tests/backends/base/test_creation.py
index 7e760e8884..202d8e1b40 100644
--- a/tests/backends/base/test_creation.py
+++ b/tests/backends/base/test_creation.py
@@ -7,6 +7,7 @@ from django.db import DEFAULT_DB_ALIAS, connection, connections
from django.db.backends.base.creation import TEST_DATABASE_PREFIX, BaseDatabaseCreation
from django.test import SimpleTestCase, TransactionTestCase
from django.test.utils import override_settings
+from django.utils.deprecation import RemovedInDjango70Warning
from ..models import (
CircularA,
@@ -79,7 +80,7 @@ class TestDbCreationTests(SimpleTestCase):
old_database_name = test_connection.settings_dict["NAME"]
try:
with mock.patch.object(creation, "_create_test_db"):
- creation.create_test_db(verbosity=0, autoclobber=True, serialize=False)
+ creation.create_test_db(verbosity=0, autoclobber=True)
# Migrations don't run.
mocked_migrate.assert_called()
args, kwargs = mocked_migrate.call_args
@@ -109,7 +110,7 @@ class TestDbCreationTests(SimpleTestCase):
old_database_name = test_connection.settings_dict["NAME"]
try:
with mock.patch.object(creation, "_create_test_db"):
- creation.create_test_db(verbosity=0, autoclobber=True, serialize=False)
+ creation.create_test_db(verbosity=0, autoclobber=True)
# The django_migrations table is not created.
mocked_ensure_schema.assert_not_called()
# App is synced.
@@ -133,7 +134,7 @@ class TestDbCreationTests(SimpleTestCase):
old_database_name = test_connection.settings_dict["NAME"]
try:
with mock.patch.object(creation, "_create_test_db"):
- creation.create_test_db(verbosity=0, autoclobber=True, serialize=False)
+ creation.create_test_db(verbosity=0, autoclobber=True)
# Migrations run.
mocked_migrate.assert_called()
args, kwargs = mocked_migrate.call_args
@@ -163,12 +164,51 @@ class TestDbCreationTests(SimpleTestCase):
old_database_name = test_connection.settings_dict["NAME"]
try:
with mock.patch.object(creation, "_create_test_db"):
- creation.create_test_db(verbosity=0, autoclobber=True, serialize=False)
+ creation.create_test_db(verbosity=0, autoclobber=True)
self.assertIs(mark_expected_failures_and_skips.called, False)
finally:
with mock.patch.object(creation, "_destroy_test_db"):
creation.destroy_test_db(old_database_name, verbosity=0)
+ @mock.patch("django.db.migrations.executor.MigrationExecutor.migrate")
+ @mock.patch.object(BaseDatabaseCreation, "serialize_db_to_string")
+ def test_serialize_deprecation(self, serialize_db_to_string, *mocked_objects):
+ test_connection = get_connection_copy()
+ creation = test_connection.creation_class(test_connection)
+ if connection.vendor == "oracle":
+ # Don't close connection on Oracle.
+ creation.connection.close = mock.Mock()
+ old_database_name = test_connection.settings_dict["NAME"]
+ msg = (
+ "DatabaseCreation.create_test_db(serialize) is deprecated. Call "
+ "DatabaseCreation.serialize_test_db() once all test databases are set up "
+ "instead if you need fixtures persistence between tests."
+ )
+ try:
+ with (
+ self.assertWarnsMessage(RemovedInDjango70Warning, msg) as ctx,
+ mock.patch.object(creation, "_create_test_db"),
+ ):
+ creation.create_test_db(verbosity=0, serialize=True)
+ self.assertEqual(ctx.filename, __file__)
+ serialize_db_to_string.assert_called_once_with()
+ finally:
+ with mock.patch.object(creation, "_destroy_test_db"):
+ creation.destroy_test_db(old_database_name, verbosity=0)
+ # Now with `serialize` False.
+ serialize_db_to_string.reset_mock()
+ try:
+ with (
+ self.assertWarnsMessage(RemovedInDjango70Warning, msg) as ctx,
+ mock.patch.object(creation, "_create_test_db"),
+ ):
+ creation.create_test_db(verbosity=0, serialize=False)
+ self.assertEqual(ctx.filename, __file__)
+ serialize_db_to_string.assert_not_called()
+ finally:
+ with mock.patch.object(creation, "_destroy_test_db"):
+ creation.destroy_test_db(old_database_name, verbosity=0)
+
class TestDeserializeDbFromString(TransactionTestCase):
available_apps = ["backends"]
diff --git a/tests/test_runner/tests.py b/tests/test_runner/tests.py
index 4209e47ebb..a9fadc872b 100644
--- a/tests/test_runner/tests.py
+++ b/tests/test_runner/tests.py
@@ -931,7 +931,7 @@ class SetupDatabasesTests(unittest.TestCase):
with mock.patch("django.test.utils.connections", new=tested_connections):
self.runner_instance.setup_databases()
mocked_db_creation.return_value.create_test_db.assert_called_once_with(
- verbosity=0, autoclobber=False, serialize=False, keepdb=False
+ verbosity=0, autoclobber=False, keepdb=False
)
mocked_db_creation.return_value.serialize_db_to_string.assert_called_once_with()