From 4c7c608a1deee37055d4a2b8a71e34def04a2a1f Mon Sep 17 00:00:00 2001
From: Tim Graham <timograham@gmail.com>
Date: Wed, 5 Dec 2018 15:21:09 -0500
Subject: [PATCH] Reverted "Fixed #25251 -- Made data migrations available in
 TransactionTestCase when using --keepdb."

This reverts commits b3b1d3d45fc066367f4fcacf0b06f72fcd00a9c6 and
9fa0d3786febf36c87ef059a39115aa1ce3326e8 due to reverse build failures
for which a solution isn't forthcoming.
---
 django/test/runner.py                         | 27 +------
 django/test/testcases.py                      | 28 +++-----
 docs/ref/settings.txt                         |  5 --
 tests/test_discovery_sample3/__init__.py      |  0
 .../tests_transaction_test_case_mixed.py      | 50 -------------
 .../tests_transaction_test_case_ordering.py   | 28 --------
 tests/test_runner/test_discover_runner.py     | 29 --------
 tests/test_utils/test_transactiontestcase.py  | 72 +------------------
 8 files changed, 14 insertions(+), 225 deletions(-)
 delete mode 100644 tests/test_discovery_sample3/__init__.py
 delete mode 100644 tests/test_discovery_sample3/tests_transaction_test_case_mixed.py
 delete mode 100644 tests/test_discovery_sample3/tests_transaction_test_case_ordering.py

diff --git a/django/test/runner.py b/django/test/runner.py
index 7dc28587af..ed969cc42f 100644
--- a/django/test/runner.py
+++ b/django/test/runner.py
@@ -11,7 +11,7 @@ from io import StringIO
 
 from django.core.management import call_command
 from django.db import connections
-from django.test import SimpleTestCase, TestCase, TransactionTestCase
+from django.test import SimpleTestCase, TestCase
 from django.test.utils import (
     setup_databases as _setup_databases, setup_test_environment,
     teardown_databases as _teardown_databases, teardown_test_environment,
@@ -399,7 +399,7 @@ class DiscoverRunner:
     parallel_test_suite = ParallelTestSuite
     test_runner = unittest.TextTestRunner
     test_loader = unittest.defaultTestLoader
-    reorder_by = (TestCase, TransactionTestCase, SimpleTestCase)
+    reorder_by = (TestCase, SimpleTestCase)
 
     def __init__(self, pattern=None, top_level=None, verbosity=1,
                  interactive=True, failfast=False, keepdb=False,
@@ -637,27 +637,6 @@ def is_discoverable(label):
     return os.path.isdir(os.path.abspath(label))
 
 
-def reorder_postprocess(reordered_suite):
-    """
-    To make TransactionTestCases initialize their data properly, they must know
-    if the next TransactionTestCase needs initial data migrations serialized in
-    the connection. Initialize _next_serialized_rollback attribute depending on
-    the serialized_rollback option present in the next test class in the suite.
-    If the next test has no serialized_rollback attribute, it means there
-    aren't any more TransactionTestCases.
-    """
-    # Filter out skipped tests.
-    active_tests = [
-        test for test in reordered_suite._tests
-        if not getattr(test, '__unittest_skip__', False)
-    ]
-    for previous_test, next_test in zip(active_tests[:-1], active_tests[1:]):
-        next_serialized_rollback = getattr(next_test, 'serialized_rollback', None)
-        if next_serialized_rollback is not None:
-            previous_test._next_serialized_rollback = next_serialized_rollback
-    return reordered_suite
-
-
 def reorder_suite(suite, classes, reverse=False):
     """
     Reorder a test suite by test type.
@@ -677,7 +656,7 @@ def reorder_suite(suite, classes, reverse=False):
     reordered_suite = suite_class()
     for i in range(class_count + 1):
         reordered_suite.addTests(bins[i])
-    return reorder_postprocess(reordered_suite)
+    return reordered_suite
 
 
 def partition_suite_by_type(suite, classes, bins, reverse=False):
diff --git a/django/test/testcases.py b/django/test/testcases.py
index 9f549f626f..36986185ce 100644
--- a/django/test/testcases.py
+++ b/django/test/testcases.py
@@ -827,15 +827,6 @@ class TransactionTestCase(SimpleTestCase):
     # This can be slow; this flag allows enabling on a per-case basis.
     serialized_rollback = False
 
-    # This attribute is strongly linked to serialized_rollback parameter and
-    # allows the data restoration after the database flush, at the end of the
-    # test, if the next test needs the initial data. This attribute is updated
-    # by the test runner when the test suite is built. Being initialized to
-    # True is crucial: the last TransactionTestCase, which doesn't have any
-    # test classes with the serialized_rollback attribute, will always have
-    # this value set to True.
-    _next_serialized_rollback = True
-
     # Since tests will be wrapped in a transaction, or serialized if they
     # are not available, we allow queries to be run.
     allow_database_queries = True
@@ -906,6 +897,16 @@ class TransactionTestCase(SimpleTestCase):
             if self.reset_sequences:
                 self._reset_sequences(db_name)
 
+            # Provide replica initial data from migrated apps, if needed.
+            if self.serialized_rollback and hasattr(connections[db_name], "_test_serialized_contents"):
+                if self.available_apps is not None:
+                    apps.unset_available_apps()
+                connections[db_name].creation.deserialize_db_from_string(
+                    connections[db_name]._test_serialized_contents
+                )
+                if self.available_apps is not None:
+                    apps.set_available_apps(self.available_apps)
+
             if self.fixtures:
                 # We have to use this slightly awkward syntax due to the fact
                 # that we're using *args and **kwargs together.
@@ -959,15 +960,6 @@ class TransactionTestCase(SimpleTestCase):
                          database=db_name, reset_sequences=False,
                          allow_cascade=self.available_apps is not None,
                          inhibit_post_migrate=inhibit_post_migrate)
-            # Provide replica initial data from migrated apps, if needed.
-            if self._next_serialized_rollback and hasattr(connections[db_name], '_test_serialized_contents'):
-                if self.available_apps is not None:
-                    apps.unset_available_apps()
-                connections[db_name].creation.deserialize_db_from_string(
-                    connections[db_name]._test_serialized_contents
-                )
-                if self.available_apps is not None:
-                    apps.set_available_apps(self.available_apps)
 
     def assertQuerysetEqual(self, qs, values, transform=repr, ordered=True, msg=None):
         items = map(transform, qs)
diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt
index 40f8a5cf49..5ebc26d868 100644
--- a/docs/ref/settings.txt
+++ b/docs/ref/settings.txt
@@ -777,11 +777,6 @@ 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>`.
 
-Don't set this to ``False`` if you want to use :option:`test --keepdb`
-and your test suite contains :class:`~django.test.TransactionTestCase` or
-doesn't support transactions, as this in-memory JSON string is used to restore
-the initial data migrations in these situations.
-
 .. setting:: TEST_TEMPLATE
 
 ``TEMPLATE``
diff --git a/tests/test_discovery_sample3/__init__.py b/tests/test_discovery_sample3/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/tests/test_discovery_sample3/tests_transaction_test_case_mixed.py b/tests/test_discovery_sample3/tests_transaction_test_case_mixed.py
deleted file mode 100644
index 13059bbb87..0000000000
--- a/tests/test_discovery_sample3/tests_transaction_test_case_mixed.py
+++ /dev/null
@@ -1,50 +0,0 @@
-from unittest import TestCase
-
-from django.test import (
-    TestCase as DjangoTestCase, TransactionTestCase, skipUnlessDBFeature,
-)
-
-
-class TestVanillaUnittest(TestCase):
-    def test_sample(self):
-        self.assertEqual(1, 1)
-
-
-class TestDjangoTestCase(DjangoTestCase):
-    def test_sample(self):
-        self.assertEqual(1, 1)
-
-
-class TestTransactionTestCase1(TransactionTestCase):
-    available_apps = ['test_discovery_sample3']
-    serialized_rollback = False
-
-    def test_sample(self):
-        self.assertEqual(1, 1)
-
-
-class TestTransactionTestCase2(TransactionTestCase):
-    available_apps = ['test_discovery_sample3']
-    serialized_rollback = True
-
-    def test_sample(self):
-        self.assertEqual(1, 1)
-
-
-# django.test.runner.reorder_postprocess() ignores this skipped test when
-# assigning _next_serialized_rollback.
-@skipUnlessDBFeature('nonexistent')
-class TestTransactionTestCase3(TransactionTestCase):
-    available_apps = ['test_discovery_sample3']
-    serialized_rollback = True
-
-    def test_sample(self):
-        self.assertEqual(1, 1)
-
-
-class TestTransactionTestCase4(TransactionTestCase):
-    available_apps = ['test_discovery_sample3']
-    serialized_rollback = False
-
-    def test_sample(self):
-        self.assertEqual(1, 1)
diff --git a/tests/test_discovery_sample3/tests_transaction_test_case_ordering.py b/tests/test_discovery_sample3/tests_transaction_test_case_ordering.py
deleted file mode 100644
index 8d79bc08a6..0000000000
--- a/tests/test_discovery_sample3/tests_transaction_test_case_ordering.py
+++ /dev/null
@@ -1,28 +0,0 @@
-from unittest import TestCase
-
-from django.test import (
-    SimpleTestCase, TestCase as DjangoTestCase, TransactionTestCase,
-)
-
-
-class TestDjangoTestCase(DjangoTestCase):
-    def test_sample(self):
-        self.assertEqual(1, 1)
-
-
-class TestVanillaUnittest(TestCase):
-    def test_sample(self):
-        self.assertEqual(1, 1)
-
-
-class TestZimpleTestCase(SimpleTestCase):
-    # Z gets this test to appear after Vanilla in the default suite.
-    def test_sample(self):
-        self.assertEqual(1, 1)
-
-
-class TestTransactionTestCase(TransactionTestCase):
-    available_apps = ['test_discovery_sample3']
-
-    def test_sample(self):
-        self.assertEqual(1, 1)
diff --git a/tests/test_runner/test_discover_runner.py b/tests/test_runner/test_discover_runner.py
index efc055978d..d7569fc111 100644
--- a/tests/test_runner/test_discover_runner.py
+++ b/tests/test_runner/test_discover_runner.py
@@ -223,32 +223,3 @@ class DiscoverRunnerTests(SimpleTestCase):
         with captured_stdout() as stdout:
             runner.build_suite(['test_runner_apps.tagged.tests'])
             self.assertIn('Excluding test tag(s): bar, foo.\n', stdout.getvalue())
-
-    def test_transaction_test_case_before_simple_test_case(self):
-        runner = DiscoverRunner()
-        suite = runner.build_suite(['test_discovery_sample3.tests_transaction_test_case_ordering'])
-        suite = tuple(suite)
-        # TransactionTestCase is second after TestCase.
-        self.assertIn('TestTransactionTestCase', suite[1].id())
-
-    def test_transaction_test_case_next_serialized_rollback_option(self):
-        runner = DiscoverRunner()
-        suite = runner.build_suite(['test_discovery_sample3.tests_transaction_test_case_mixed'])
-        django_test_case, first_transaction_test_case, second_transaction_test_case, \
-            third_transaction_test_case, fourth_transaction_test_case, vanilla_test_case = suite
-        # TransactionTestCase1._next_serialized_rollback is
-        # TransactionTestCase2.serialize_rollback.
-        self.assertEqual(
-            first_transaction_test_case._next_serialized_rollback,
-            second_transaction_test_case.serialized_rollback
-        )
-        # TransactionTestCase2._next_serialized_rollback is
-        # TransactionTestCase4.serialize_rollback because TransactionTestCase3
-        # is skipped.
-        self.assertEqual(
-            second_transaction_test_case._next_serialized_rollback,
-            fourth_transaction_test_case.serialized_rollback
-        )
-        # The last TransactionTestCase of the suite has
-        # _next_serialized_rollback = True.
-        self.assertIs(fourth_transaction_test_case._next_serialized_rollback, True)
diff --git a/tests/test_utils/test_transactiontestcase.py b/tests/test_utils/test_transactiontestcase.py
index 193a4e299e..40c9b7576f 100644
--- a/tests/test_utils/test_transactiontestcase.py
+++ b/tests/test_utils/test_transactiontestcase.py
@@ -1,44 +1,10 @@
-import json
 from unittest import mock
 
-from django.apps import apps
 from django.db import connections
 from django.test import TestCase, TransactionTestCase, override_settings
 
-from .models import Car
 
-
-class TestSerializedContentMockMixin:
-    """
-    Use this mixin on each test involving TransactionTestCase and
-    serialized_rollback = True option to avoid test dependencies. It mocks what
-    would be serialized after initial data migrations and restores it at the
-    end of the test.
-    """
-    initial_data_migration = '[]'
-    _connections_test_serialized_content = {}
-
-    def _pre_setup(self):
-        for db_name in self._databases_names(include_mirrors=False):
-            self._connections_test_serialized_content[db_name] = connections[db_name]._test_serialized_contents
-            connections[db_name]._test_serialized_contents = self.initial_data_migration
-        super()._pre_setup()
-
-    def _post_teardown(self):
-        super()._post_teardown()
-        for db_name in self._databases_names(include_mirrors=False):
-            connections[db_name]._test_serialized_contents = self._connections_test_serialized_content[db_name]
-
-    @classmethod
-    def tearDownClass(cls):
-        super().tearDownClass()
-        # Clean up any data that has been created by the class.
-        for data in json.loads(cls.initial_data_migration):
-            model = apps.get_model(*data['model'].split('.'))
-            model.objects.filter(pk=data['pk']).delete()
-
-
-class TestSerializedRollbackInhibitsPostMigrate(TestSerializedContentMockMixin, TransactionTestCase):
+class TestSerializedRollbackInhibitsPostMigrate(TransactionTestCase):
     """
     TransactionTestCase._fixture_teardown() inhibits the post_migrate signal
     for test classes with serialized_rollback=True.
@@ -78,39 +44,3 @@ class TransactionTestCaseMultiDbTests(TestCase):
         """
         for alias in connections:
             self.assertEqual(len(connections[alias].queries_log), 0, 'Failed for alias %s' % alias)
-
-
-class TestDataRestoredOnTearDownIfSerializedRollback(TestSerializedContentMockMixin, TransactionTestCase):
-    """
-    Initial data is recreated in TransactionTestCase._fixture_teardown()
-    after the database is flushed so it's available in next test.
-    """
-    available_apps = ['test_utils']
-    _next_serialized_rollback = True
-    initial_data_migration = '[{"model": "test_utils.car", "pk": 666, "fields": {"name": "K 2000"}}]'
-
-    def _post_teardown(self):
-        super()._post_teardown()
-        # Won't be True if running the tests with --reverse.
-        if self._next_serialized_rollback:
-            self.assertTrue(Car.objects.exists())
-
-    def test(self):
-        pass  # Should be the only one in this class.
-
-
-class TestDataNotRestoredOnTearDownIfNotSerializedRollback(TestSerializedContentMockMixin, TransactionTestCase):
-    """
-    Initial data isn't recreated in TransactionTestCase._fixture_teardown()
-    if _next_serialized_rollback is False.
-    """
-    available_apps = ['test_utils']
-    _next_serialized_rollback = False
-    initial_data_migration = '[{"model": "test_utils.car", "pk": 666, "fields": {"name": "K 2000"}}]'
-
-    def _post_teardown(self):
-        super()._post_teardown()
-        self.assertFalse(Car.objects.exists())
-
-    def test(self):
-        pass  # Should be the only one in this class.