Last active
December 19, 2016 09:28
-
-
Save Sovetnikov/04343fee7516a501d79b93250922b675 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import logging | |
import os | |
ABSOLUTE_PATH = lambda x: os.path.abspath(os.path.join(os.path.abspath(os.path.dirname(__file__)), x)) | |
# For Django 1.7.7 sqlite and spatialite | |
# Uses monkeypatch | |
# | |
# Runs tests as: | |
# 1. Create initial db and apply all migrations if it does not exists | |
# 2. Apply any unapplied migrations to initial db if it exists | |
# 3. Copy initial db file to a new one | |
# 4. Run tests with a new db created via copy | |
# Use init_fast_sqlite_test at end of settings.py as: | |
# if len(sys.argv) > 1 and sys.argv[1] == "test": | |
# init_fast_sqlite_test(sys.modules[__name__]) | |
def init_fast_sqlite_test(settings, spatialite=False): | |
if 'cachalot' in settings.INSTALLED_APPS: | |
settings.INSTALLED_APPS.remove('cachalot') | |
logging.disable(logging.CRITICAL) | |
settings.PASSWORD_HASHERS = ( | |
'django.contrib.auth.hashers.MD5PasswordHasher', | |
) | |
settings.DEBUG = False | |
settings.TEMPLATE_DEBUG = False | |
if spatialite: | |
settings.SPATIALITE_SQL = ABSOLUTE_PATH('init_spatialite-2.3.sql') | |
settings.SPATIALITE_LIBRARY_PATH = 'libspatialite-1' | |
settings.DATABASES['default'] = { | |
'ENGINE': 'django.contrib.gis.db.backends.spatialite' if spatialite else 'django.db.backends.sqlite3', | |
'NAME': ABSOLUTE_PATH('../test_db.sqlite'), | |
'TEST': {'NAME': ABSOLUTE_PATH('../test_db.sqlite')} | |
} | |
def _sqlite3_create_test_db(self, verbosity, autoclobber): | |
# Just not delete any db here | |
test_database_name = self._get_test_db_name() | |
return test_database_name | |
from django.db.backends.sqlite3.creation import DatabaseCreation | |
# Just to prevent database deletion | |
DatabaseCreation._create_test_db = _sqlite3_create_test_db | |
def _spatialite_create_test_db(self, verbosity=1, autoclobber=False, serialize=True): | |
""" | |
Creates a test database, prompting the user for confirmation if the | |
database already exists. Returns the name of the test database created. | |
This method is overloaded to load up the SpatiaLite initialization | |
SQL prior to calling the `migrate` command. | |
""" | |
# Don't import django.core.management if it isn't needed. | |
from django.core.management import call_command | |
test_database_name = self._get_test_db_name() | |
if verbosity >= 1: | |
test_db_repr = '' | |
if verbosity >= 2: | |
test_db_repr = " ('%s')" % test_database_name | |
print("Creating test database for alias '%s'%s..." % (self.connection.alias, test_db_repr)) | |
# Is file there? | |
db_exists = os.access(test_database_name, os.F_OK) | |
self._create_test_db(verbosity, autoclobber) | |
self.connection.close() | |
self.connection.settings_dict["NAME"] = test_database_name | |
# Need to load the SpatiaLite initialization SQL before running `migrate`. | |
if spatialite and not db_exists: | |
# Is file exists - no need to initialize spatialite again, or it will raise | |
self.load_spatialite_sql() | |
# Report migrate messages at one level lower than that requested. | |
# This ensures we don't get flooded with messages during testing | |
# (unless you really ask to be flooded) | |
# Migrating our initial db, to ensure db structure actual | |
# Changed test_flush to False, because we do not need to flush any, db is ready for us | |
call_command('migrate', | |
verbosity=max(verbosity - 1, 0), | |
interactive=False, | |
database=self.connection.alias, | |
load_initial_data=False, | |
test_flush=False) | |
# We then serialize the current state of the database into a string | |
# and store it on the connection. This slightly horrific process is so people | |
# who are testing on databases without transactions or who are using | |
# a TransactionTestCase still get a clean database on every test run. | |
if serialize: | |
self.connection._test_serialized_contents = self.serialize_db_to_string() | |
if not db_exists: | |
call_command('createcachetable', database=self.connection.alias) | |
# Ensure a connection for the side effect of initializing the test database. | |
self.connection.ensure_connection() | |
# Just copy sqlite db file to a new one and change connection to it! | |
# All done, new db file will be removed on tests run end ... | |
# Original db file will be in place | |
from shutil import copyfile | |
new_db_name = self.connection.settings_dict["NAME"] + '_test' | |
copyfile(self.connection.settings_dict["NAME"], new_db_name) | |
self.connection.close() | |
self.connection.settings_dict["NAME"] = new_db_name | |
return test_database_name | |
if spatialite: | |
from django.contrib.gis.db.backends.spatialite.creation import SpatiaLiteCreation as Creation | |
else: | |
from django.db.backends.creation import BaseDatabaseCreation as Creation | |
Creation.create_test_db = _spatialite_create_test_db |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment