Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django testing mirror database not receiving data

I am trying to set up some testing on my Django application. I use a database mirror for some reads done throughout my application. When I try and test these parts, by creating mock data in the database and then attempting to read it, it appears as though the data is not in the mirror database, despite being configured as a TEST_MIRROR.

The database config for testing looks like this:

DATABASES = {
  'default': {
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'NAME': 'maindb',
    'HOST': 'localhost'
  },
  'mirror1': {
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'NAME': 'maindb',
    'HOST': 'localhost',
    'TEST_MIRROR': 'default'
  }
}

And then in my test I do something like this (Foo is a model)

Foo.objects.create(name='bar')
self.assertTrue(Foo.objects.filter(name='bar').exists()) # passes
self.assertTrue(Foo.objects.using('mirror1').filter(name='bar').exists()) # fails

This is confusing to me, as I thought the point of the TEST_MIRROR was to make calls to the mirror pass straight through to the default?

like image 410
Greg Hinch Avatar asked Sep 20 '13 13:09

Greg Hinch


2 Answers

If your setup contains multiple databases, and you have a test that requires every database, you can use the multi_db attribute on the test suite to request a full flush.

For example:

class TestMyViews(TestCase):
    multi_db = True        # for Django < 3.1 (deprecated since 2.2)
    databases = '__all__'  # for Django >= 2.2
    # databases = {'default', 'other'}  # or explicit databases


    def testIndexPageView(self):
        call_some_test_code()

That documentation (multi-database support testing) is not exact, because the condition multi_db (indirectly in _databases_names) is not used only for flush (tearDown) in Django source, but also for '_fixture_setup'. (Django-1.5.1/django/test/testcases.py:834) Therefore it seems to be a basic condition independent on master/slave settings.

like image 69
hynekcer Avatar answered Nov 03 '22 04:11

hynekcer


I think the answer might lie here:

When the test environment is configured, a test version of slave will not be created. Instead the connection to slave will be redirected to point at default

Since the slave doesn't really exist in the testing, it kinda makes sense that trying to call it directly fails

like image 29
yuvi Avatar answered Nov 03 '22 04:11

yuvi