summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Walls <jacobtylerwalls@gmail.com>2024-06-01 19:34:30 -0400
committerSarah Boyce <42296566+sarahboyce@users.noreply.github.com>2024-09-03 08:07:53 +0200
commit4082a8886e8d5f60ab705fcd0aac107778175721 (patch)
tree900f5e0b5ed46451fd34bef09367df58a52364e7
parentc6a4f853c7167c1001761dcff30d7a64690e8236 (diff)
Fixed #35724 -- Tested migration commands handling of distributed namespace packages.
Also increased coverage of module_loading.py.
-rw-r--r--tests/migrations/migrations_test_apps/distributed_app_location_1/namespace_app/migrations/.gitkeep (renamed from tests/migrations/migrations_test_apps/without_init_file/migrations/.keep)0
-rw-r--r--tests/migrations/migrations_test_apps/distributed_app_location_2/namespace_app/migrations/.gitkeep0
-rw-r--r--tests/migrations/migrations_test_apps/without_init_file/migrations/.gitkeep0
-rw-r--r--tests/migrations/test_commands.py22
-rw-r--r--tests/migrations/test_writer.py26
5 files changed, 46 insertions, 2 deletions
diff --git a/tests/migrations/migrations_test_apps/without_init_file/migrations/.keep b/tests/migrations/migrations_test_apps/distributed_app_location_1/namespace_app/migrations/.gitkeep
index e69de29bb2..e69de29bb2 100644
--- a/tests/migrations/migrations_test_apps/without_init_file/migrations/.keep
+++ b/tests/migrations/migrations_test_apps/distributed_app_location_1/namespace_app/migrations/.gitkeep
diff --git a/tests/migrations/migrations_test_apps/distributed_app_location_2/namespace_app/migrations/.gitkeep b/tests/migrations/migrations_test_apps/distributed_app_location_2/namespace_app/migrations/.gitkeep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/migrations/migrations_test_apps/distributed_app_location_2/namespace_app/migrations/.gitkeep
diff --git a/tests/migrations/migrations_test_apps/without_init_file/migrations/.gitkeep b/tests/migrations/migrations_test_apps/without_init_file/migrations/.gitkeep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/migrations/migrations_test_apps/without_init_file/migrations/.gitkeep
diff --git a/tests/migrations/test_commands.py b/tests/migrations/test_commands.py
index 6ef172ee6f..cab2906ed1 100644
--- a/tests/migrations/test_commands.py
+++ b/tests/migrations/test_commands.py
@@ -4,6 +4,7 @@ import io
import os
import shutil
import sys
+from pathlib import Path
from unittest import mock
from django.apps import apps
@@ -21,7 +22,7 @@ from django.db.backends.utils import truncate_name
from django.db.migrations.exceptions import InconsistentMigrationHistory
from django.db.migrations.recorder import MigrationRecorder
from django.test import TestCase, override_settings, skipUnlessDBFeature
-from django.test.utils import captured_stdout
+from django.test.utils import captured_stdout, extend_sys_path
from django.utils import timezone
from django.utils.version import get_docs_version
@@ -1729,6 +1730,25 @@ class MakeMigrationsTests(MigrationTestBase):
call_command("makemigrations", stdout=out)
self.assertIn("0001_initial.py", out.getvalue())
+ def test_makemigrations_no_init_ambiguous(self):
+ """
+ Migration directories without an __init__.py file are not allowed if
+ there are multiple namespace search paths that resolve to them.
+ """
+ out = io.StringIO()
+ with self.temporary_migration_module(
+ module="migrations.test_migrations_no_init"
+ ) as migration_dir:
+ # Copy the project directory into another place under sys.path.
+ app_dir = Path(migration_dir).parent
+ os.remove(app_dir / "__init__.py")
+ project_dir = app_dir.parent
+ dest = project_dir.parent / "other_dir_in_path"
+ shutil.copytree(project_dir, dest)
+ with extend_sys_path(str(dest)):
+ call_command("makemigrations", stdout=out)
+ self.assertEqual("No changes detected\n", out.getvalue())
+
def test_makemigrations_migrations_announce(self):
"""
makemigrations announces the migration at the default verbosity level.
diff --git a/tests/migrations/test_writer.py b/tests/migrations/test_writer.py
index 891efd8ac7..51783b7346 100644
--- a/tests/migrations/test_writer.py
+++ b/tests/migrations/test_writer.py
@@ -22,7 +22,8 @@ from django.core.validators import EmailValidator, RegexValidator
from django.db import migrations, models
from django.db.migrations.serializer import BaseSerializer
from django.db.migrations.writer import MigrationWriter, OperationWriter
-from django.test import SimpleTestCase
+from django.test import SimpleTestCase, override_settings
+from django.test.utils import extend_sys_path
from django.utils.deconstruct import deconstructible
from django.utils.functional import SimpleLazyObject
from django.utils.timezone import get_default_timezone, get_fixed_timezone
@@ -954,6 +955,29 @@ class WriterTests(SimpleTestCase):
writer = MigrationWriter(migration)
self.assertEqual(writer.path, expected_path)
+ @override_settings(
+ MIGRATION_MODULES={"namespace_app": "namespace_app.migrations"},
+ INSTALLED_APPS=[
+ "migrations.migrations_test_apps.distributed_app_location_2.namespace_app"
+ ],
+ )
+ def test_migration_path_distributed_namespace(self):
+ base_dir = os.path.dirname(os.path.dirname(__file__))
+ test_apps_dir = os.path.join(base_dir, "migrations", "migrations_test_apps")
+ expected_msg = (
+ "Could not locate an appropriate location to create "
+ "migrations package namespace_app.migrations. Make sure the toplevel "
+ "package exists and can be imported."
+ )
+ with extend_sys_path(
+ os.path.join(test_apps_dir, "distributed_app_location_1"),
+ os.path.join(test_apps_dir, "distributed_app_location_2"),
+ ):
+ migration = migrations.Migration("0001_initial", "namespace_app")
+ writer = MigrationWriter(migration)
+ with self.assertRaisesMessage(ValueError, expected_msg):
+ writer.path
+
def test_custom_operation(self):
migration = type(
"Migration",