From f36d95f193f3414e13a86960bcb32320f63277e5 Mon Sep 17 00:00:00 2001 From: mcleanmds Date: Tue, 14 Jul 2020 15:20:49 +1000 Subject: [PATCH 1/2] add parallel testing example to README --- README.rst | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/README.rst b/README.rst index 0b5a2bf6..64b58712 100644 --- a/README.rst +++ b/README.rst @@ -149,6 +149,62 @@ following lines to your test class: def tearDown(self): get_redis_connection("default").flushall() +In case you want to run the django tests in parallel mode, setup a custom +TestRunner similar to the following: + +.. code-block:: python + + import copy + import django.core.cache + from django.conf import UserSettingsHolder, settings + from django.test.runner import _init_worker + from django.test.runner import DiscoverRunner + from django.test.runner import ParallelTestSuite + + def parallel_init_worker(counter): + """ + Switch redis database dedicated to this worker. + + This helper lives at module-level because of the multiprocessing module's + requirements. + """ + _init_worker(counter) # call django default parallel init first + + with counter.get_lock(): + redis_db = settings.CACHE_DB + counter.value + redis_location = "redis://127.0.0.1:6379/{}".format(redis_db) + + caches = copy.deepcopy(settings.CACHES) + caches["default"]["LOCATION"] = redis_location + + # override the settings for the worker to use + override = UserSettingsHolder(settings._wrapped) + setattr(override, "CACHES", caches) + settings._wrapped = override + + # re-initialise django cache to use new settings + django.core.cache.caches = django.core.cache.CacheHandler() + + + class CustomParallelTestSuite(ParallelTestSuite): + init_worker = parallel_init_worker + + + class CustomDiscoverRunner(DiscoverRunner): + parallel_test_suite = CustomParallelTestSuite + +When running django tests in parallel mode, flushing the data following a test +should be limited to the cache db used in that test process, by using +``flushdb()`` instead of ``flushall()`` in the test class tearDown: + +.. code-block:: python + + from django_redis import get_redis_connection + + def tearDown(self): + get_redis_connection("default").flushdb() + + Advanced usage -------------- From 33deab4b7efcac1b622e25a2d5c6fb6d31a3626a Mon Sep 17 00:00:00 2001 From: Michael McLean Date: Mon, 27 Nov 2023 14:02:41 +1100 Subject: [PATCH 2/2] Update README.rst update parallel test suite example config for Django 4.2 --- README.rst | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/README.rst b/README.rst index 64b58712..2e893afc 100644 --- a/README.rst +++ b/README.rst @@ -155,35 +155,44 @@ TestRunner similar to the following: .. code-block:: python import copy + import multiprocessing import django.core.cache from django.conf import UserSettingsHolder, settings from django.test.runner import _init_worker from django.test.runner import DiscoverRunner from django.test.runner import ParallelTestSuite - def parallel_init_worker(counter): + def parallel_init_worker( + counter: multiprocessing.Value, + *args, **kwargs, + ): """ Switch redis database dedicated to this worker. This helper lives at module-level because of the multiprocessing module's requirements. """ - _init_worker(counter) # call django default parallel init first + + _init_worker(counter, *args, **kwargs) # call django default to setup parallel db + from django.test.runner import _worker_id # import after _init_worker called - with counter.get_lock(): - redis_db = settings.CACHE_DB + counter.value - redis_location = "redis://127.0.0.1:6379/{}".format(redis_db) + redis_db = settings.CACHE_DB + _worker_id + redis_test_location = f'redis://127.0.0.1:6379/{redis_db}' caches = copy.deepcopy(settings.CACHES) caches["default"]["LOCATION"] = redis_location - # override the settings for the worker to use + # based of approach in django.tests.utils.override_settings override = UserSettingsHolder(settings._wrapped) - setattr(override, "CACHES", caches) + setattr(override, 'CACHE_DB', redis_db) + setattr(override, 'REDIS_SERVER_LOCATION', redis_test_location) + setattr(override, 'CACHES', caches) settings._wrapped = override - - # re-initialise django cache to use new settings - django.core.cache.caches = django.core.cache.CacheHandler() + + setting_changed.send( + sender=settings._wrapped.__class__, + setting='CACHES', value=caches, enter=True, + ) class CustomParallelTestSuite(ParallelTestSuite): @@ -193,6 +202,7 @@ TestRunner similar to the following: class CustomDiscoverRunner(DiscoverRunner): parallel_test_suite = CustomParallelTestSuite + When running django tests in parallel mode, flushing the data following a test should be limited to the cache db used in that test process, by using ``flushdb()`` instead of ``flushall()`` in the test class tearDown: