diff options
| author | Julien Phalip <jphalip@gmail.com> | 2011-12-16 13:40:19 +0000 |
|---|---|---|
| committer | Julien Phalip <jphalip@gmail.com> | 2011-12-16 13:40:19 +0000 |
| commit | 34e248efeca272a2c0f2b15a5347dd66fc0340c9 (patch) | |
| tree | fd073f3b8a6132b002375ff454665bba090458fd /tests | |
| parent | 5df31c0164e9477a3ebb6b1bbde8604e06fbefd4 (diff) | |
Fixed #17258 -- Moved `threading.local` from `DatabaseWrapper` to the `django.db.connections` dictionary. This allows connections to be explicitly shared between multiple threads and is particularly useful for enabling the sharing of in-memory SQLite connections. Many thanks to Anssi Kääriäinen for the excellent suggestions and feedback, and to Alex Gaynor for the reviews. Refs #2879.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@17205 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/regressiontests/backends/tests.py | 94 |
1 files changed, 93 insertions, 1 deletions
diff --git a/tests/regressiontests/backends/tests.py b/tests/regressiontests/backends/tests.py index 936f010186..82c21c8c7b 100644 --- a/tests/regressiontests/backends/tests.py +++ b/tests/regressiontests/backends/tests.py @@ -3,6 +3,7 @@ from __future__ import with_statement, absolute_import import datetime +import threading from django.conf import settings from django.core.management.color import no_style @@ -283,7 +284,7 @@ class ConnectionCreatedSignalTest(TestCase): connection_created.connect(receiver) connection.close() cursor = connection.cursor() - self.assertTrue(data["connection"] is connection) + self.assertTrue(data["connection"].connection is connection.connection) connection_created.disconnect(receiver) data.clear() @@ -446,3 +447,94 @@ class FkConstraintsTests(TransactionTestCase): connection.check_constraints() finally: transaction.rollback() + + +class ThreadTests(TestCase): + + def test_default_connection_thread_local(self): + """ + Ensure that the default connection (i.e. django.db.connection) is + different for each thread. + Refs #17258. + """ + connections_set = set() + connection.cursor() + connections_set.add(connection.connection) + def runner(): + from django.db import connection + connection.cursor() + connections_set.add(connection.connection) + for x in xrange(2): + t = threading.Thread(target=runner) + t.start() + t.join() + self.assertEquals(len(connections_set), 3) + # Finish by closing the connections opened by the other threads (the + # connection opened in the main thread will automatically be closed on + # teardown). + for conn in connections_set: + if conn != connection.connection: + conn.close() + + def test_connections_thread_local(self): + """ + Ensure that the connections are different for each thread. + Refs #17258. + """ + connections_set = set() + for conn in connections.all(): + connections_set.add(conn) + def runner(): + from django.db import connections + for conn in connections.all(): + connections_set.add(conn) + for x in xrange(2): + t = threading.Thread(target=runner) + t.start() + t.join() + self.assertEquals(len(connections_set), 6) + # Finish by closing the connections opened by the other threads (the + # connection opened in the main thread will automatically be closed on + # teardown). + for conn in connections_set: + if conn != connection: + conn.close() + + def test_pass_connection_between_threads(self): + """ + Ensure that a connection can be passed from one thread to the other. + Refs #17258. + """ + models.Person.objects.create(first_name="John", last_name="Doe") + + def do_thread(): + def runner(main_thread_connection): + from django.db import connections + connections['default'] = main_thread_connection + try: + models.Person.objects.get(first_name="John", last_name="Doe") + except DatabaseError, e: + exceptions.append(e) + t = threading.Thread(target=runner, args=[connections['default']]) + t.start() + t.join() + + # Without touching allow_thread_sharing, which should be False by default. + exceptions = [] + do_thread() + # Forbidden! + self.assertTrue(isinstance(exceptions[0], DatabaseError)) + + # If explicitly setting allow_thread_sharing to False + connections['default'].allow_thread_sharing = False + exceptions = [] + do_thread() + # Forbidden! + self.assertTrue(isinstance(exceptions[0], DatabaseError)) + + # If explicitly setting allow_thread_sharing to True + connections['default'].allow_thread_sharing = True + exceptions = [] + do_thread() + # All good + self.assertEqual(len(exceptions), 0)
\ No newline at end of file |
