151 lines
4.4 KiB
Python
151 lines
4.4 KiB
Python
import os
|
|
import glob
|
|
import json
|
|
from contextlib import closing, contextmanager
|
|
import subprocess
|
|
import tempfile
|
|
import shutil
|
|
|
|
import pytest
|
|
|
|
import django_webtest
|
|
|
|
import psycopg2
|
|
|
|
|
|
from django.db import transaction
|
|
from django.contrib.auth.models import User
|
|
from django.core.management import call_command
|
|
|
|
|
|
def pytest_addoption(parser):
|
|
parser.addoption(
|
|
'--bijoe-store-table', action='store_true', default=False, help='Store tables value in new_tables.json',
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def app(settings, request):
|
|
settings.TEMPLATE_DEBUG = True
|
|
settings.DEBUG = True
|
|
wtm = django_webtest.WebTestMixin()
|
|
wtm._patch_settings()
|
|
request.addfinalizer(wtm._unpatch_settings)
|
|
return django_webtest.DjangoTestApp()
|
|
|
|
|
|
@pytest.fixture
|
|
def john_doe(db):
|
|
u = User(username='john.doe', first_name='John', last_name='Doe', email='john.doe@example.net')
|
|
u.set_password('john.doe')
|
|
u.save()
|
|
return u
|
|
|
|
|
|
@pytest.fixture
|
|
def admin(db):
|
|
u = User(username='super.user', first_name='Super', last_name='User',
|
|
email='super.user@example.net')
|
|
u.set_password('super.user')
|
|
u.is_superuser = True
|
|
u.is_staff = True
|
|
u.save()
|
|
return u
|
|
|
|
SCHEMA_PATHS = os.path.join(os.path.dirname(__file__), 'fixtures/')
|
|
|
|
|
|
@contextmanager
|
|
def load_schema_db(schema):
|
|
import random
|
|
|
|
database_name = 'db%s' % random.getrandbits(20)
|
|
tmpdir = tempfile.mkdtemp()
|
|
bijoe_schema_dir = os.path.join(tmpdir, 'schemas')
|
|
os.makedirs(bijoe_schema_dir)
|
|
|
|
try:
|
|
with closing(psycopg2.connect('')) as conn:
|
|
conn.set_isolation_level(0)
|
|
with conn.cursor() as cursor:
|
|
cursor.execute('CREATE DATABASE %s' % database_name)
|
|
|
|
schema_dir = os.path.join(SCHEMA_PATHS, schema)
|
|
|
|
# copy schemas and set pg_dsn
|
|
for schema_path in glob.glob(os.path.join(schema_dir, '*_schema.json')):
|
|
with open(schema_path) as f:
|
|
schema = json.load(f)
|
|
schema['pg_dsn'] = 'dbname=%s' % database_name
|
|
new_schema_path = os.path.join(bijoe_schema_dir, os.path.basename(schema_path))
|
|
with open(new_schema_path, 'w') as fp:
|
|
json.dump(schema, fp)
|
|
|
|
# load data
|
|
for sql_path in sorted(glob.glob(os.path.join(schema_dir, '*.sql'))):
|
|
process = subprocess.Popen(['psql', '--single-transaction', database_name, '-f', sql_path],
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE)
|
|
stdout, stderr = process.communicate()
|
|
return_code = process.returncode
|
|
assert return_code == 0, [stdout, stderr]
|
|
|
|
# load fixtures
|
|
fixtures = sorted(glob.glob(os.path.join(schema_dir, '*_fixture.json')))
|
|
|
|
d = {
|
|
'schema_dir': schema_dir,
|
|
'database_name': database_name,
|
|
'bijoe_schemas': [os.path.join(bijoe_schema_dir, '*_schema.json')],
|
|
'fixtures': fixtures
|
|
}
|
|
tables_path = os.path.join(schema_dir, 'tables.json')
|
|
if os.path.exists(tables_path):
|
|
with open(tables_path) as f:
|
|
d['tables'] = json.load(f)
|
|
yield d
|
|
finally:
|
|
with closing(psycopg2.connect('')) as conn:
|
|
conn.set_isolation_level(0)
|
|
with conn.cursor() as cursor:
|
|
cursor.execute('DROP DATABASE IF EXISTS %s' % database_name)
|
|
shutil.rmtree(tmpdir)
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
def schema1_db():
|
|
with load_schema_db('schema1') as d:
|
|
yield d
|
|
|
|
|
|
@pytest.fixture
|
|
def schema1(db, schema1_db, settings):
|
|
settings.BIJOE_SCHEMAS = schema1_db['bijoe_schemas']
|
|
for json_fixture in schema1_db['fixtures']:
|
|
call_command('loaddata', json_fixture)
|
|
return schema1_db
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
def schema2_db():
|
|
with load_schema_db('schema2') as d:
|
|
yield d
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
def schema2_fixtures(schema2_db, django_db_setup, django_db_blocker):
|
|
with django_db_blocker.unblock():
|
|
with transaction.atomic():
|
|
try:
|
|
for json_fixture in schema2_db['fixtures']:
|
|
call_command('loaddata', json_fixture)
|
|
yield
|
|
finally:
|
|
transaction.set_rollback(True)
|
|
|
|
|
|
@pytest.fixture
|
|
def schema2(schema2_db, schema2_fixtures, settings, django_db_blocker):
|
|
settings.BIJOE_SCHEMAS = schema2_db['bijoe_schemas']
|
|
yield schema2_db
|