mirror of
https://github.com/django/django.git
synced 2025-06-05 03:29:12 +00:00
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.
This commit is contained in:
parent
99ac8e2589
commit
2d34ebe49a
@ -41,7 +41,7 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
# Create a test database.
|
# Create a test database.
|
||||||
db_name = connection.creation.create_test_db(
|
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.
|
# Import the fixture data into the test database.
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import warnings
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
|
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
@ -7,6 +8,7 @@ from django.conf import settings
|
|||||||
from django.core import serializers
|
from django.core import serializers
|
||||||
from django.db import router
|
from django.db import router
|
||||||
from django.db.transaction import atomic
|
from django.db.transaction import atomic
|
||||||
|
from django.utils.deprecation import RemovedInDjango70Warning
|
||||||
from django.utils.module_loading import import_string
|
from django.utils.module_loading import import_string
|
||||||
|
|
||||||
# The prefix to put on the default database name when creating
|
# The prefix to put on the default database name when creating
|
||||||
@ -29,8 +31,10 @@ class BaseDatabaseCreation:
|
|||||||
def log(self, msg):
|
def log(self, msg):
|
||||||
sys.stderr.write(msg + os.linesep)
|
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(
|
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
|
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
|
# and store it on the connection. This slightly horrific process is so people
|
||||||
# who are testing on databases without transactions or who are using
|
# who are testing on databases without transactions or who are using
|
||||||
# a TransactionTestCase still get a clean database on every test run.
|
# a TransactionTestCase still get a clean database on every test run.
|
||||||
if serialize:
|
if serialize is not None:
|
||||||
self.connection._test_serialized_contents = self.serialize_db_to_string()
|
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)
|
call_command("createcachetable", database=self.connection.alias)
|
||||||
|
|
||||||
|
@ -205,7 +205,6 @@ def setup_databases(
|
|||||||
verbosity=verbosity,
|
verbosity=verbosity,
|
||||||
autoclobber=not interactive,
|
autoclobber=not interactive,
|
||||||
keepdb=keepdb,
|
keepdb=keepdb,
|
||||||
serialize=False,
|
|
||||||
)
|
)
|
||||||
if serialized_aliases is None or alias in serialized_aliases:
|
if serialized_aliases is None or alias in serialized_aliases:
|
||||||
serialize_connections.append(connection)
|
serialize_connections.append(connection)
|
||||||
|
@ -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
|
See the :ref:`Django 6.0 release notes <deprecated-features-6.0>` for more
|
||||||
details on these changes.
|
details on these changes.
|
||||||
|
|
||||||
|
* The ``serialize`` keyword argument of
|
||||||
|
``BaseDatabaseCreation.create_test_db()`` will be removed.
|
||||||
|
|
||||||
.. _deprecation-removed-in-6.1:
|
.. _deprecation-removed-in-6.1:
|
||||||
|
|
||||||
6.1
|
6.1
|
||||||
|
@ -235,7 +235,8 @@ Database backend API
|
|||||||
This section describes changes that may be needed in third-party database
|
This section describes changes that may be needed in third-party database
|
||||||
backends.
|
backends.
|
||||||
|
|
||||||
* ...
|
* ``BaseDatabaseCreation.create_test_db(serialize)`` is deprecated. Use
|
||||||
|
``serialize_db_to_string()`` instead.
|
||||||
|
|
||||||
Dropped support for MariaDB 10.5
|
Dropped support for MariaDB 10.5
|
||||||
--------------------------------
|
--------------------------------
|
||||||
@ -278,7 +279,8 @@ Features deprecated in 6.0
|
|||||||
Miscellaneous
|
Miscellaneous
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
* ...
|
* ``BaseDatabaseCreation.create_test_db(serialize)`` is deprecated. Use
|
||||||
|
``serialize_db_to_string()`` instead.
|
||||||
|
|
||||||
Features removed in 6.0
|
Features removed in 6.0
|
||||||
=======================
|
=======================
|
||||||
|
@ -796,7 +796,7 @@ utility methods in the ``django.test.utils`` module.
|
|||||||
The creation module of the database backend also provides some utilities that
|
The creation module of the database backend also provides some utilities that
|
||||||
can be useful during testing.
|
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.
|
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
|
* If ``autoclobber`` is ``True``, the database will be destroyed
|
||||||
without consulting the user.
|
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
|
``keepdb`` determines if the test run should use an existing
|
||||||
database, or create a new one. If ``True``, the existing
|
database, or create a new one. If ``True``, the existing
|
||||||
database will be used, or created if not present. If ``False``,
|
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
|
:setting:`NAME` in :setting:`DATABASES` to match the name of the test
|
||||||
database.
|
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)
|
.. function:: destroy_test_db(old_database_name, verbosity=1, keepdb=False)
|
||||||
|
|
||||||
Destroys the database whose name is the value of :setting:`NAME` in
|
Destroys the database whose name is the value of :setting:`NAME` in
|
||||||
|
@ -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.db.backends.base.creation import TEST_DATABASE_PREFIX, BaseDatabaseCreation
|
||||||
from django.test import SimpleTestCase, TransactionTestCase
|
from django.test import SimpleTestCase, TransactionTestCase
|
||||||
from django.test.utils import override_settings
|
from django.test.utils import override_settings
|
||||||
|
from django.utils.deprecation import RemovedInDjango70Warning
|
||||||
|
|
||||||
from ..models import (
|
from ..models import (
|
||||||
CircularA,
|
CircularA,
|
||||||
@ -79,7 +80,7 @@ class TestDbCreationTests(SimpleTestCase):
|
|||||||
old_database_name = test_connection.settings_dict["NAME"]
|
old_database_name = test_connection.settings_dict["NAME"]
|
||||||
try:
|
try:
|
||||||
with mock.patch.object(creation, "_create_test_db"):
|
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.
|
# Migrations don't run.
|
||||||
mocked_migrate.assert_called()
|
mocked_migrate.assert_called()
|
||||||
args, kwargs = mocked_migrate.call_args
|
args, kwargs = mocked_migrate.call_args
|
||||||
@ -109,7 +110,7 @@ class TestDbCreationTests(SimpleTestCase):
|
|||||||
old_database_name = test_connection.settings_dict["NAME"]
|
old_database_name = test_connection.settings_dict["NAME"]
|
||||||
try:
|
try:
|
||||||
with mock.patch.object(creation, "_create_test_db"):
|
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.
|
# The django_migrations table is not created.
|
||||||
mocked_ensure_schema.assert_not_called()
|
mocked_ensure_schema.assert_not_called()
|
||||||
# App is synced.
|
# App is synced.
|
||||||
@ -133,7 +134,7 @@ class TestDbCreationTests(SimpleTestCase):
|
|||||||
old_database_name = test_connection.settings_dict["NAME"]
|
old_database_name = test_connection.settings_dict["NAME"]
|
||||||
try:
|
try:
|
||||||
with mock.patch.object(creation, "_create_test_db"):
|
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.
|
# Migrations run.
|
||||||
mocked_migrate.assert_called()
|
mocked_migrate.assert_called()
|
||||||
args, kwargs = mocked_migrate.call_args
|
args, kwargs = mocked_migrate.call_args
|
||||||
@ -163,12 +164,51 @@ class TestDbCreationTests(SimpleTestCase):
|
|||||||
old_database_name = test_connection.settings_dict["NAME"]
|
old_database_name = test_connection.settings_dict["NAME"]
|
||||||
try:
|
try:
|
||||||
with mock.patch.object(creation, "_create_test_db"):
|
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)
|
self.assertIs(mark_expected_failures_and_skips.called, False)
|
||||||
finally:
|
finally:
|
||||||
with mock.patch.object(creation, "_destroy_test_db"):
|
with mock.patch.object(creation, "_destroy_test_db"):
|
||||||
creation.destroy_test_db(old_database_name, verbosity=0)
|
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):
|
class TestDeserializeDbFromString(TransactionTestCase):
|
||||||
available_apps = ["backends"]
|
available_apps = ["backends"]
|
||||||
|
@ -931,7 +931,7 @@ class SetupDatabasesTests(unittest.TestCase):
|
|||||||
with mock.patch("django.test.utils.connections", new=tested_connections):
|
with mock.patch("django.test.utils.connections", new=tested_connections):
|
||||||
self.runner_instance.setup_databases()
|
self.runner_instance.setup_databases()
|
||||||
mocked_db_creation.return_value.create_test_db.assert_called_once_with(
|
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()
|
mocked_db_creation.return_value.serialize_db_to_string.assert_called_once_with()
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user