Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regression, faking TEST_MIRROR yields unusable REUSE_DB in django-nose 1.4 #247

Open
wdoekes opened this issue Nov 30, 2015 · 0 comments
Open
Labels

Comments

@wdoekes
Copy link
Contributor

wdoekes commented Nov 30, 2015

TLDR: If you "fake" a TEST_MIRROR config, by pointing it to the same database as the original, REUSE_DB is broken since django-nose 1.4.

See this settings.py:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'nosetest',
        'HOST': 'localhost',
        'USER': 'walter',
        'PASSWORD': os.environ.get('MYSQL_PASSWORD'),
    },
}
if os.environ.get('ISSUE'):
    DATABASES['web_db'] = DATABASES['default'].copy()

In django-nose 1.3, the following works fine:

$ REUSE_DB=1 ./manage.py test ./nosetest/test.py
nosetests ./nosetest/test.py --verbosity=1
Creating test database for alias 'default'...
Ran 2 tests in 0.019s
$ echo 'drop database test_nosetest;' | ./manage.py dbshell
(dropping the db again so we can see the issue)

So, that works with a single DB. Now try again, with the 2nd DB:

$ ISSUE=1 REUSE_DB=1 ./manage.py test ./nosetest/test.py
nosetests ./nosetest/test.py --verbosity=1
Creating test database for alias 'default'...
Ran 3 tests in 0.252s
$ echo 'drop database test_nosetest;' | ./manage.py dbshell
(dropping the db again so we can see the issue)

Awesome. That also works.

Now we update to django-nose 1.4:

$ REUSE_DB=1 ./manage.py test ./nosetest/test.py
nosetests ./nosetest/test.py --verbosity=1
Creating test database for alias 'default'...
Ran 2 tests in 0.064s
$ echo 'drop database test_nosetest;' | ./manage.py dbshell
(dropping the db again so we can see the issue)

Yes, without the 2nd DB, it works.

But now we try with the 2nd DB, and we get this:

$ ISSUE=1 REUSE_DB=1 ./manage.py test ./nosetest/test.py
nosetests ./nosetest/test.py --verbosity=1
Traceback (most recent call last):
  File "./manage.py", line 10, in <module>
...
  File "/home/walter/.virtualenvs/nosetest/local/lib/python2.7/site-packages/MySQLdb/__init__.py", line 81, in Connect
    return Connection(*args, **kwargs)
  File "/home/walter/.virtualenvs/nosetest/local/lib/python2.7/site-packages/MySQLdb/connections.py", line 193, in __init__
    super(Connection, self).__init__(*args, **kwargs2)
_mysql_exceptions.OperationalError: (1049, "Unknown database 'test_nosetest'")

The cause is this change:

a893caf

If we remove those two lines, things start working again.

Now, you ask me: why do you point your TEST_MIRROR to the same DB? That's because we use a 2nd DB in production, but not on our dev machines.


Files used for this test:

==> req.txt <==
Django>=1.4,<1.5
django-nose==1.3
MySQL-python

==> nosetest/__init__.py <==

==> nosetest/models.py <==
from django.db import models

class MyModel(models.Model):
    value = models.IntegerField()

==> nosetest/settings.py <==
import os
INSTALLED_APPS = ['nosetest']
SECRET_KEY = 'A' * 50
TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'nosetest',
        'HOST': 'localhost',
        'USER': 'walter',
        'PASSWORD': os.environ.get('MYSQL_PASSWORD'),
    },
}
if os.environ.get('ISSUE'):
    DATABASES['web_db'] = DATABASES['default'].copy()

==> nosetest/test.py <==
import os
from django.db import connection
from django.test import TestCase
from .models import MyModel

class MyTestCase(TestCase):
    def setUp(self):
        MyModel.objects.create(value=42)

    def test_test(self):
        "Test model"
        self.assertEqual(MyModel.objects.all()[0].value, 42)

    if os.environ.get('ISSUE'):
        def test_2nd_db(self):
            "Test model on 2nd db"
            self.assertEqual(MyModel.objects.using('web_db')[0].value, 42)

    def test_transactions(self):
        "Has transaction/rollback support"
        self.assertTrue(connection.features.supports_transactions)

Note that if we point the 2nd DB to somewhere else, the REUSE_DB works. But then we run into the fact that TEST_MIRROR support is unavailable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants