#27286: Tests fails when using multi-db and some DB is read-only
-----------------------------------+-------------------------------
     Reporter:  Jose M Herrero     |      Owner:  nobody
         Type:  Bug                |     Status:  new
    Component:  Testing framework  |    Version:  1.10
     Severity:  Normal             |   Keywords:  multi-db dbrouter
 Triage Stage:  Unreviewed         |  Has patch:  0
Easy pickings:  0                  |      UI/UX:  0
-----------------------------------+-------------------------------
 I'm triying to implement a multi-db platform with one master and some
 read-replicas, I wanted to reflect this structure also in tests. When I
 run tests they try to write to read only databases although router is
 configured to not allow it.
 To reproduce with nothing interfering I started a fresh project, these are
 the steps to reproduce:

 1. Start a new Django 1.10.1 project with `django-admin startproject
 mysite` and cd into it `cd mysite`
 2. Create a database router `mysite/dbrouter.py`
 {{{
 #!div style="font-size: 80%"
 Code highlighting:
   {{{#!python
 class DbRouter(object):
     def db_for_read(self, model, **hints):
         return 'read_replica'

     def db_for_write(self, model, **hints):
         return 'default'

     def allow_relation(self, obj1, obj2, **hints):
         return True

     def allow_migrate(self, db, app_label, model_name=None, **hints):
         if db == 'read_replica':
             return False
         return True
    }}}
 }}}

 3. Edit `mysite.settings.py` with master and read databases and set the
 database router

 {{{
 #!div style="font-size: 80%"
 Code highlighting:
   {{{#!python
 DATABASES = {
     'default': {
         'ENGINE': 'django.db.backends.mysql',
         'NAME': 'mysite',
         'USER': 'myuser',
         'PASSWORD': 'mypassword',
         'HOST': '127.0.0.1',
         'PORT': '',
     },
     'read_replica': {
         'ENGINE': 'django.db.backends.mysql',
         'NAME': 'mysite',
         'USER': 'myuser_read',
         'PASSWORD': 'myreadpassword',
         'HOST': '127.0.0.1',
         'PORT': '',
     },
 }
 DATABASE_ROUTERS = ['mysite.dbrouter.DbRouter']
 }}}
 }}}

 4. Create `mysite/tests.py`
 {{{
 #!div style="font-size: 80%"
 Code highlighting:
   {{{#!python
 from django.test import TestCase

 class SurveyFormTest(TestCase):
     def test_sample(self):
         print 'hello'
 }}}
 }}}
 5. Execute the tests and bang! `python manage.py test mysite`

 {{{
 Creating test database for alias 'default'...
 E
 ======================================================================
 ERROR: setUpClass (mysite.tests.SurveyFormTest)
 ----------------------------------------------------------------------
 Traceback (most recent call last):
   File "/home/chemary/workspace/myvirtualenv/local/lib/python2.7/site-
 packages/django/test/testcases.py", line 1009, in setUpClass
     if not connections_support_transactions():
   File "/home/chemary/workspace/myvirtualenv/local/lib/python2.7/site-
 packages/django/test/testcases.py", line 974, in
 connections_support_transactions
     for conn in connections.all())
   File "/home/chemary/workspace/myvirtualenv/local/lib/python2.7/site-
 packages/django/test/testcases.py", line 974, in <genexpr>
     for conn in connections.all())
   File "/home/chemary/workspace/myvirtualenv/local/lib/python2.7/site-
 packages/django/utils/functional.py", line 35, in __get__
     res = instance.__dict__[self.name] = self.func(instance)
   File "/home/chemary/workspace/myvirtualenv/local/lib/python2.7/site-
 packages/django/db/backends/base/features.py", line 235, in
 supports_transactions
     cursor.execute('CREATE TABLE ROLLBACK_TEST (X INT)')
   File "/home/chemary/workspace/myvirtualenv/local/lib/python2.7/site-
 packages/django/db/backends/utils.py", line 64, in execute
     return self.cursor.execute(sql, params)
   File "/home/chemary/workspace/myvirtualenv/local/lib/python2.7/site-
 packages/django/db/utils.py", line 94, in __exit__
     six.reraise(dj_exc_type, dj_exc_value, traceback)
   File "/home/chemary/workspace/myvirtualenv/local/lib/python2.7/site-
 packages/django/db/backends/utils.py", line 62, in execute
     return self.cursor.execute(sql)
   File "/home/chemary/workspace/myvirtualenv/local/lib/python2.7/site-
 packages/django/db/backends/mysql/base.py", line 112, in execute
     return self.cursor.execute(query, args)
   File "/home/chemary/workspace/myvirtualenv/local/lib/python2.7/site-
 packages/MySQLdb/cursors.py", line 205, in execute
     self.errorhandler(self, exc, value)
   File "/home/chemary/workspace/myvirtualenv/local/lib/python2.7/site-
 packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
     raise errorclass, errorvalue
 OperationalError: (1142, "CREATE command denied to user
 'myuser_read'@'localhost' for table 'ROLLBACK_TEST'")

 ----------------------------------------------------------------------
 Ran 0 tests in 0.026s

 FAILED (errors=1)
 Destroying test database for alias 'default'...
 }}}

--
Ticket URL: <https://code.djangoproject.com/ticket/27286>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/050.929949375ca159162b80454f99b34ff5%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to