Ticket #12542: t12542-r12278.1.2.diff

File t12542-r12278.1.2.diff, 7.3 KB (added by russellm, 6 years ago)

RC1 of a patch allowing for test mirrors for testing master/slave setups

  • django/db/utils.py

    diff -r d205a9ab4b3b django/db/utils.py
    a b  
    6565        conn.setdefault('TEST_CHARSET', None)
    6666        conn.setdefault('TEST_COLLATION', None)
    6767        conn.setdefault('TEST_NAME', None)
     68        conn.setdefault('TEST_MIRROR', None)
    6869        conn.setdefault('TIME_ZONE', settings.TIME_ZONE)
    6970        for setting in ('NAME', 'USER', 'PASSWORD', 'HOST', 'PORT'):
    7071            conn.setdefault(setting, '')
  • django/test/simple.py

    diff -r d205a9ab4b3b django/test/simple.py
    a b  
    231231    def setup_databases(self):
    232232        from django.db import connections
    233233        old_names = []
     234        mirrors = []
    234235        for alias in connections:
    235236            connection = connections[alias]
    236             old_names.append((connection, connection.settings_dict['NAME']))
    237             connection.creation.create_test_db(self.verbosity, autoclobber=not self.interactive)
    238         return old_names
     237            # If the database is a test mirror, redirect it's connection
     238            # instead of creating a test database.
     239            if connection.settings_dict['TEST_MIRROR']:
     240                mirrors.append((alias, connection))
     241                mirror_alias = connection.settings_dict['TEST_MIRROR']
     242                connections._connections[alias] = connections[mirror_alias]
     243            else:
     244                old_names.append((connection, connection.settings_dict['NAME']))
     245                connection.creation.create_test_db(self.verbosity, autoclobber=not self.interactive)
     246        return old_names, mirrors
    240248    def run_suite(self, suite):
    241249        return DjangoTestRunner(verbosity=self.verbosity, failfast=self.failfast).run(suite)
    243     def teardown_databases(self, old_names):
     251    def teardown_databases(self, old_config):
     252        from django.db import connections
     253        old_names, mirrors = old_config
     254        # Point all the mirrors back to the originals
     255        for alias, connection in mirrors:
     256            connections._connections[alias] = connection
     257        # Destroy all the non-mirror databases
    244258        for connection, old_name in old_names:
    245259            connection.creation.destroy_test_db(old_name, self.verbosity)
    274288        suite = self.build_suite(test_labels, extra_tests)
    276         old_names = self.setup_databases()
     290        old_config = self.setup_databases()
    278292        result = self.run_suite(suite)
    280         self.teardown_databases(old_names)
     294        self.teardown_databases(old_config)
    282296        self.teardown_test_environment()
  • docs/ref/settings.txt

    diff -r d205a9ab4b3b docs/ref/settings.txt
    a b  
    360360.. setting:: TEST_NAME
     365Default: ``None``
     367The alias of the database that this database should mirror during
     370This setting exists to allow for testing of master/slave
     371configurations of multiple databases. See the documentation on
     372:ref:`testing master/slave configurations
     373<topics-testing-masterslave>`. for details
  • docs/topics/testing.txt

    diff -r d205a9ab4b3b docs/topics/testing.txt
    a b  
    301301when all the tests have been executed.
    303303By default the test databases get their names by prepending ``test_``
    304 to the value of the :setting:`NAME`` settings for the databased
     304to the value of the :setting:`NAME` settings for the databases
    305305defined in :setting:`DATABASES`. When using the SQLite database engine
    306306the tests will by default use an in-memory database (i.e., the
    307307database will be created in memory, bypassing the filesystem
    308308entirely!). If you want to use a different database name, specify
    309 ``TEST_NAME`` in the dictionary for any given database in
     309:setting:`TEST_NAME` in the dictionary for any given database in
    312312Aside from using a separate database, the test runner will otherwise
    325325:ref:`settings documentation <ref-settings>` for details of these
    326326advanced settings.
     328.. _topics-testing-masterslave:
     330Testing master/slave configurations
     333.. versionadded:: 1.2
     335If you're testing a multiple database configuration with master/slave
     336replication, this strategy of creating test databases poses a problem.
     337When the test databases are created, there won't be any replication,
     338and as a result, data created on the master won't be seen on the
     341To compensate for this, Django allows you to define that a database is
     342a *test mirror*. Consider the following (simplified) example database
     345    DATABASES = {
     346        'default': {
     347            'ENGINE': 'django.db.backends.mysql',
     348            'NAME': 'myproject',
     349            'HOST': 'dbmaster',
     350             # ... plus some other settings
     351        },
     352        'slave': {
     353            'ENGINE': 'django.db.backends.mysql',
     354            'NAME': 'myproject',
     355            'HOST': 'dbslave',
     356            'TEST_MIRROR': 'default'
     357            # ... plus some other settings
     358        }
     359    }
     361In this setup, we have two database servers: ``dbmaster``, described
     362by the database alias ``default``, and ``dbslave`` described by the
     363alias ``slave``. As you might expect, ``dbslave`` has been configured
     364by the database administrator as a read slave of ``dbmaster``, so in
     365normal activity, any write to ``default`` will appear on ``slave``.
     367If Django created two independent test databases, this would break any
     368tests that expected replication to occur. However, the ``slave``
     369database has been configured as a test mirror (using the
     370:setting:`TEST_MIRROR` setting), indicating that under testing,
     371``slave`` should be treated as a mirror of ``default``.
     373When the test environment is configured, a test version of ``slave``
     374will *not* be created. Instead the connection to ``slave``
     375will be redirected to point at ``default``. As a result, writes to
     376``default`` will appear on ``slave`` -- but because they are actually
     377the same database, not because there is data replication between the
     378two databases.
    328380Other test conditions
    13501402    Creates the test databases.
    1352     Returns the list of old database names that will need to be restored
     1404    Returns a data structure that provides enough detail to undo the changes
     1405    that have been made. This data will be provided to the ``teardown_databases()``
     1406    function at the conclusion of testing.
    13541408.. method:: DjangoTestSuiteRunner.run_suite(suite)
    13581412    Returns the result produced by the running the test suite.
    1360 .. method:: DjangoTestSuiteRunner.teardown_databases(old_names)
     1414.. method:: DjangoTestSuiteRunner.teardown_databases(old_config)
    1362     Destroys the test databases, restoring the old names.
     1416    Destroys the test databases, restoring pre-test conditions.
     1418    ``old_config`` is a data structure defining the changes in the
     1419    database configuration that need to be reversed. It is the return
     1420    value of the ``setup_databases()`` method.
    13641422.. method:: DjangoTestSuiteRunner.teardown_test_environment()
Back to Top