Merge pull request #1240 from edx/dhm/config_separation
Segregate the mongo db config from the modulestore config
This commit is contained in:
@@ -29,7 +29,7 @@ class Command(BaseCommand):
|
||||
# use a user-specified database name, if present
|
||||
# this is useful for doing dumps from databases restored from prod backups
|
||||
if len(args) == 3:
|
||||
settings.MODULESTORE['direct']['OPTIONS']['db'] = args[2]
|
||||
settings.MODULESTORE['direct']['DOC_STORE_CONFIG']['db'] = args[2]
|
||||
|
||||
loc = CourseDescriptor.id_to_location(course_id)
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ from student.models import CourseEnrollment
|
||||
from contentstore.utils import delete_course_and_groups
|
||||
|
||||
TEST_DATA_CONTENTSTORE = copy.deepcopy(settings.CONTENTSTORE)
|
||||
TEST_DATA_CONTENTSTORE['OPTIONS']['db'] = 'test_xcontent_%s' % uuid4().hex
|
||||
TEST_DATA_CONTENTSTORE['DOC_STORE_CONFIG']['db'] = 'test_xcontent_%s' % uuid4().hex
|
||||
|
||||
|
||||
class MongoCollectionFindWrapper(object):
|
||||
@@ -101,7 +101,7 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase):
|
||||
self.client.login(username=uname, password=password)
|
||||
|
||||
def tearDown(self):
|
||||
MongoClient().drop_database(TEST_DATA_CONTENTSTORE['OPTIONS']['db'])
|
||||
MongoClient().drop_database(TEST_DATA_CONTENTSTORE['DOC_STORE_CONFIG']['db'])
|
||||
_CONTENTSTORE.clear()
|
||||
|
||||
def check_components_on_page(self, component_types, expected_types):
|
||||
@@ -1313,7 +1313,7 @@ class ContentStoreTest(ModuleStoreTestCase):
|
||||
|
||||
def tearDown(self):
|
||||
mongo = MongoClient()
|
||||
mongo.drop_database(TEST_DATA_CONTENTSTORE['OPTIONS']['db'])
|
||||
mongo.drop_database(TEST_DATA_CONTENTSTORE['DOC_STORE_CONFIG']['db'])
|
||||
_CONTENTSTORE.clear()
|
||||
|
||||
def test_create_course(self):
|
||||
|
||||
@@ -20,7 +20,7 @@ from django.conf import settings
|
||||
from xmodule.contentstore.django import _CONTENTSTORE
|
||||
|
||||
TEST_DATA_CONTENTSTORE = copy.deepcopy(settings.CONTENTSTORE)
|
||||
TEST_DATA_CONTENTSTORE['OPTIONS']['db'] = 'test_xcontent_%s' % uuid4().hex
|
||||
TEST_DATA_CONTENTSTORE['DOC_STORE_CONFIG']['db'] = 'test_xcontent_%s' % uuid4().hex
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -70,7 +70,7 @@ class ImportTestCase(CourseTestCase):
|
||||
|
||||
def tearDown(self):
|
||||
shutil.rmtree(self.content_dir)
|
||||
MongoClient().drop_database(TEST_DATA_CONTENTSTORE['OPTIONS']['db'])
|
||||
MongoClient().drop_database(TEST_DATA_CONTENTSTORE['DOC_STORE_CONFIG']['db'])
|
||||
_CONTENTSTORE.clear()
|
||||
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ from uuid import uuid4
|
||||
from pymongo import MongoClient
|
||||
|
||||
TEST_DATA_CONTENTSTORE = copy.deepcopy(settings.CONTENTSTORE)
|
||||
TEST_DATA_CONTENTSTORE['OPTIONS']['db'] = 'test_xcontent_%s' % uuid4().hex
|
||||
TEST_DATA_CONTENTSTORE['DOC_STORE_CONFIG']['db'] = 'test_xcontent_%s' % uuid4().hex
|
||||
|
||||
|
||||
@override_settings(CONTENTSTORE=TEST_DATA_CONTENTSTORE, MODULESTORE=TEST_MODULESTORE)
|
||||
@@ -61,7 +61,7 @@ class ContentStoreImportNoStaticTest(ModuleStoreTestCase):
|
||||
self.client.login(username=uname, password=password)
|
||||
|
||||
def tearDown(self):
|
||||
MongoClient().drop_database(TEST_DATA_CONTENTSTORE['OPTIONS']['db'])
|
||||
MongoClient().drop_database(TEST_DATA_CONTENTSTORE['DOC_STORE_CONFIG']['db'])
|
||||
_CONTENTSTORE.clear()
|
||||
|
||||
def load_test_import_course(self):
|
||||
|
||||
@@ -30,30 +30,33 @@ DOC_STORE_CONFIG = {
|
||||
'collection': 'acceptance_modulestore_%s' % seed(),
|
||||
}
|
||||
|
||||
MODULESTORE_OPTIONS = dict({
|
||||
MODULESTORE_OPTIONS = {
|
||||
'default_class': 'xmodule.raw_module.RawDescriptor',
|
||||
'fs_root': TEST_ROOT / "data",
|
||||
'render_template': 'mitxmako.shortcuts.render_to_string',
|
||||
}, **DOC_STORE_CONFIG)
|
||||
}
|
||||
|
||||
MODULESTORE = {
|
||||
'default': {
|
||||
'ENGINE': 'xmodule.modulestore.draft.DraftModuleStore',
|
||||
'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
|
||||
'OPTIONS': MODULESTORE_OPTIONS
|
||||
},
|
||||
'direct': {
|
||||
'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore',
|
||||
'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
|
||||
'OPTIONS': MODULESTORE_OPTIONS
|
||||
},
|
||||
'draft': {
|
||||
'ENGINE': 'xmodule.modulestore.draft.DraftModuleStore',
|
||||
'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
|
||||
'OPTIONS': MODULESTORE_OPTIONS
|
||||
}
|
||||
}
|
||||
|
||||
CONTENTSTORE = {
|
||||
'ENGINE': 'xmodule.contentstore.mongo.MongoContentStore',
|
||||
'OPTIONS': {
|
||||
'DOC_STORE_CONFIG': {
|
||||
'host': 'localhost',
|
||||
'db': 'acceptance_xcontent_%s' % seed(),
|
||||
},
|
||||
|
||||
@@ -22,23 +22,26 @@ DOC_STORE_CONFIG = {
|
||||
'collection': 'modulestore',
|
||||
}
|
||||
|
||||
modulestore_options = dict({
|
||||
modulestore_options = {
|
||||
'default_class': 'xmodule.raw_module.RawDescriptor',
|
||||
'fs_root': GITHUB_REPO_ROOT,
|
||||
'render_template': 'mitxmako.shortcuts.render_to_string',
|
||||
}, **DOC_STORE_CONFIG)
|
||||
}
|
||||
|
||||
MODULESTORE = {
|
||||
'default': {
|
||||
'ENGINE': 'xmodule.modulestore.draft.DraftModuleStore',
|
||||
'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
|
||||
'OPTIONS': modulestore_options
|
||||
},
|
||||
'direct': {
|
||||
'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore',
|
||||
'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
|
||||
'OPTIONS': modulestore_options
|
||||
},
|
||||
'split': {
|
||||
'ENGINE': 'xmodule.modulestore.split_mongo.SplitMongoModuleStore',
|
||||
'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
|
||||
'OPTIONS': modulestore_options
|
||||
}
|
||||
}
|
||||
@@ -48,7 +51,7 @@ MODULESTORE = {
|
||||
# This is for static content for courseware, not system static content (e.g. javascript, css, edX branding, etc)
|
||||
CONTENTSTORE = {
|
||||
'ENGINE': 'xmodule.contentstore.mongo.MongoContentStore',
|
||||
'OPTIONS': {
|
||||
'DOC_STORE_CONFIG': {
|
||||
'host': 'localhost',
|
||||
'db': 'xcontent',
|
||||
},
|
||||
|
||||
@@ -57,34 +57,38 @@ DOC_STORE_CONFIG = {
|
||||
'collection': 'test_modulestore',
|
||||
}
|
||||
|
||||
MODULESTORE_OPTIONS = dict({
|
||||
MODULESTORE_OPTIONS = {
|
||||
'default_class': 'xmodule.raw_module.RawDescriptor',
|
||||
'fs_root': TEST_ROOT / "data",
|
||||
'render_template': 'mitxmako.shortcuts.render_to_string',
|
||||
}, **DOC_STORE_CONFIG)
|
||||
}
|
||||
|
||||
MODULESTORE = {
|
||||
'default': {
|
||||
'ENGINE': 'xmodule.modulestore.draft.DraftModuleStore',
|
||||
'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
|
||||
'OPTIONS': MODULESTORE_OPTIONS
|
||||
},
|
||||
'direct': {
|
||||
'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore',
|
||||
'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
|
||||
'OPTIONS': MODULESTORE_OPTIONS
|
||||
},
|
||||
'draft': {
|
||||
'ENGINE': 'xmodule.modulestore.draft.DraftModuleStore',
|
||||
'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
|
||||
'OPTIONS': MODULESTORE_OPTIONS
|
||||
},
|
||||
'split': {
|
||||
'ENGINE': 'xmodule.modulestore.split_mongo.SplitMongoModuleStore',
|
||||
'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
|
||||
'OPTIONS': MODULESTORE_OPTIONS
|
||||
}
|
||||
}
|
||||
|
||||
CONTENTSTORE = {
|
||||
'ENGINE': 'xmodule.contentstore.mongo.MongoContentStore',
|
||||
'OPTIONS': {
|
||||
'DOC_STORE_CONFIG': {
|
||||
'host': 'localhost',
|
||||
'db': 'test_xcontent',
|
||||
},
|
||||
|
||||
@@ -25,7 +25,7 @@ from xmodule.modulestore.xml_importer import import_from_xml
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
TEST_DATA_CONTENTSTORE = copy.deepcopy(settings.CONTENTSTORE)
|
||||
TEST_DATA_CONTENTSTORE['OPTIONS']['db'] = 'test_xcontent_%s' % uuid4().hex
|
||||
TEST_DATA_CONTENTSTORE['DOC_STORE_CONFIG']['db'] = 'test_xcontent_%s' % uuid4().hex
|
||||
|
||||
TEST_MODULESTORE = studio_store_config(settings.TEST_ROOT / "data")
|
||||
|
||||
@@ -80,7 +80,7 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase):
|
||||
|
||||
def tearDown(self):
|
||||
|
||||
MongoClient().drop_database(TEST_DATA_CONTENTSTORE['OPTIONS']['db'])
|
||||
MongoClient().drop_database(TEST_DATA_CONTENTSTORE['DOC_STORE_CONFIG']['db'])
|
||||
_CONTENTSTORE.clear()
|
||||
|
||||
def test_unlocked_asset(self):
|
||||
|
||||
@@ -175,7 +175,7 @@ def reset_databases(scenario):
|
||||
If no data is created during the test, these lines equivilently do nothing.
|
||||
'''
|
||||
mongo = MongoClient()
|
||||
mongo.drop_database(settings.CONTENTSTORE['OPTIONS']['db'])
|
||||
mongo.drop_database(settings.CONTENTSTORE['DOC_STORE_CONFIG']['db'])
|
||||
_CONTENTSTORE.clear()
|
||||
|
||||
modulestore = xmodule.modulestore.django.editable_modulestore()
|
||||
|
||||
@@ -21,7 +21,7 @@ def contentstore(name='default'):
|
||||
if name not in _CONTENTSTORE:
|
||||
class_ = load_function(settings.CONTENTSTORE['ENGINE'])
|
||||
options = {}
|
||||
options.update(settings.CONTENTSTORE['OPTIONS'])
|
||||
options.update(settings.CONTENTSTORE['DOC_STORE_CONFIG'])
|
||||
if 'ADDITIONAL_OPTIONS' in settings.CONTENTSTORE:
|
||||
if name in settings.CONTENTSTORE['ADDITIONAL_OPTIONS']:
|
||||
options.update(settings.CONTENTSTORE['ADDITIONAL_OPTIONS'][name])
|
||||
|
||||
@@ -397,7 +397,12 @@ class ModuleStoreBase(ModuleStore):
|
||||
'''
|
||||
Implement interface functionality that can be shared.
|
||||
'''
|
||||
def __init__(self, metadata_inheritance_cache_subsystem=None, request_cache=None, modulestore_update_signal=None, xblock_mixins=()):
|
||||
def __init__(
|
||||
self,
|
||||
doc_store_config=None, # ignore if passed up
|
||||
metadata_inheritance_cache_subsystem=None, request_cache=None,
|
||||
modulestore_update_signal=None, xblock_mixins=()
|
||||
):
|
||||
'''
|
||||
Set up the error-tracking logic.
|
||||
'''
|
||||
|
||||
@@ -35,7 +35,7 @@ def load_function(path):
|
||||
return getattr(import_module(module_path), name)
|
||||
|
||||
|
||||
def create_modulestore_instance(engine, options):
|
||||
def create_modulestore_instance(engine, doc_store_config, options):
|
||||
"""
|
||||
This will return a new instance of a modulestore given an engine and options
|
||||
"""
|
||||
@@ -63,6 +63,7 @@ def create_modulestore_instance(engine, options):
|
||||
request_cache=request_cache,
|
||||
modulestore_update_signal=Signal(providing_args=['modulestore', 'course_id', 'location']),
|
||||
xblock_mixins=getattr(settings, 'XBLOCK_MIXINS', ()),
|
||||
doc_store_config=doc_store_config,
|
||||
**_options
|
||||
)
|
||||
|
||||
@@ -73,8 +74,11 @@ def modulestore(name='default'):
|
||||
modulestore or create a new one
|
||||
"""
|
||||
if name not in _MODULESTORES:
|
||||
_MODULESTORES[name] = create_modulestore_instance(settings.MODULESTORE[name]['ENGINE'],
|
||||
settings.MODULESTORE[name]['OPTIONS'])
|
||||
_MODULESTORES[name] = create_modulestore_instance(
|
||||
settings.MODULESTORE[name]['ENGINE'],
|
||||
settings.MODULESTORE[name].get('DOC_STORE_CONFIG', {}),
|
||||
settings.MODULESTORE[name].get('OPTIONS', {})
|
||||
)
|
||||
# inject loc_mapper into newly created modulestore if it needs it
|
||||
if name == 'split' and _loc_singleton is not None:
|
||||
_MODULESTORES['split'].loc_mapper = _loc_singleton
|
||||
|
||||
@@ -30,8 +30,12 @@ class MixedModuleStore(ModuleStoreBase):
|
||||
raise Exception('Missing a default modulestore in the MixedModuleStore __init__ method.')
|
||||
|
||||
for key, store in stores.items():
|
||||
self.modulestores[key] = create_modulestore_instance(store['ENGINE'],
|
||||
store['OPTIONS'])
|
||||
self.modulestores[key] = create_modulestore_instance(
|
||||
store['ENGINE'],
|
||||
# XMLModuleStore's don't have doc store configs
|
||||
store.get('DOC_STORE_CONFIG', {}),
|
||||
store['OPTIONS']
|
||||
)
|
||||
|
||||
def _get_modulestore_for_courseid(self, course_id):
|
||||
"""
|
||||
|
||||
@@ -257,25 +257,35 @@ class MongoModuleStore(ModuleStoreBase):
|
||||
"""
|
||||
|
||||
# TODO (cpennington): Enable non-filesystem filestores
|
||||
def __init__(self, host, db, collection, fs_root, render_template,
|
||||
port=27017, default_class=None,
|
||||
# pylint: disable=C0103
|
||||
# pylint: disable=W0201
|
||||
def __init__(self, doc_store_config, fs_root, render_template,
|
||||
default_class=None,
|
||||
error_tracker=null_error_tracker,
|
||||
user=None, password=None, mongo_options=None, **kwargs):
|
||||
**kwargs):
|
||||
"""
|
||||
:param doc_store_config: must have a host, db, and collection entries. Other common entries: port, tz_aware.
|
||||
"""
|
||||
|
||||
super(MongoModuleStore, self).__init__(**kwargs)
|
||||
|
||||
if mongo_options is None:
|
||||
mongo_options = {}
|
||||
def do_connection(
|
||||
db, collection, host, port=27017, tz_aware=True, user=None, password=None, **kwargs
|
||||
):
|
||||
"""
|
||||
Create & open the connection, authenticate, and provide pointers to the collection
|
||||
"""
|
||||
self.collection = pymongo.connection.Connection(
|
||||
host=host,
|
||||
port=port,
|
||||
tz_aware=tz_aware,
|
||||
**kwargs
|
||||
)[db][collection]
|
||||
|
||||
self.collection = pymongo.connection.Connection(
|
||||
host=host,
|
||||
port=port,
|
||||
tz_aware=True,
|
||||
**mongo_options
|
||||
)[db][collection]
|
||||
if user is not None and password is not None:
|
||||
self.collection.database.authenticate(user, password)
|
||||
|
||||
if user is not None and password is not None:
|
||||
self.collection.database.authenticate(user, password)
|
||||
do_connection(**doc_store_config)
|
||||
|
||||
# Force mongo to report errors, at the expense of performance
|
||||
self.collection.safe = True
|
||||
@@ -283,7 +293,8 @@ class MongoModuleStore(ModuleStoreBase):
|
||||
# Force mongo to maintain an index over _id.* that is in the same order
|
||||
# that is used when querying by a location
|
||||
self.collection.ensure_index(
|
||||
zip(('_id.' + field for field in Location._fields), repeat(1)))
|
||||
zip(('_id.' + field for field in Location._fields), repeat(1))
|
||||
)
|
||||
|
||||
if default_class is not None:
|
||||
module_path, _, class_name = default_class.rpartition('.')
|
||||
|
||||
@@ -48,37 +48,48 @@ class SplitMongoModuleStore(ModuleStoreBase):
|
||||
A Mongodb backed ModuleStore supporting versions, inheritance,
|
||||
and sharing.
|
||||
"""
|
||||
# pylint: disable=C0103
|
||||
def __init__(self, host, db, collection, fs_root, render_template,
|
||||
port=27017, default_class=None,
|
||||
# pylint: disable=W0201
|
||||
def __init__(self, doc_store_config, fs_root, render_template,
|
||||
default_class=None,
|
||||
error_tracker=null_error_tracker,
|
||||
user=None, password=None,
|
||||
mongo_options=None,
|
||||
loc_mapper=None,
|
||||
**kwargs):
|
||||
"""
|
||||
:param doc_store_config: must have a host, db, and collection entries. Other common entries: port, tz_aware.
|
||||
"""
|
||||
|
||||
super(SplitMongoModuleStore, self).__init__(**kwargs)
|
||||
self.loc_mapper = loc_mapper
|
||||
if mongo_options is None:
|
||||
mongo_options = {}
|
||||
|
||||
self.db = pymongo.database.Database(pymongo.MongoClient(
|
||||
host=host,
|
||||
port=port,
|
||||
tz_aware=True,
|
||||
**mongo_options
|
||||
), db)
|
||||
def do_connection(
|
||||
db, collection, host, port=27017, tz_aware=True, user=None, password=None, **kwargs
|
||||
):
|
||||
"""
|
||||
Create & open the connection, authenticate, and provide pointers to the collections
|
||||
"""
|
||||
self.db = pymongo.database.Database(
|
||||
pymongo.MongoClient(
|
||||
host=host,
|
||||
port=port,
|
||||
tz_aware=tz_aware,
|
||||
**kwargs
|
||||
),
|
||||
db
|
||||
)
|
||||
|
||||
self.course_index = self.db[collection + '.active_versions']
|
||||
self.structures = self.db[collection + '.structures']
|
||||
self.definitions = self.db[collection + '.definitions']
|
||||
if user is not None and password is not None:
|
||||
self.db.authenticate(user, password)
|
||||
|
||||
self.course_index = self.db[collection + '.active_versions']
|
||||
self.structures = self.db[collection + '.structures']
|
||||
self.definitions = self.db[collection + '.definitions']
|
||||
|
||||
do_connection(**doc_store_config)
|
||||
|
||||
# Code review question: How should I expire entries?
|
||||
# _add_cache could use a lru mechanism to control the cache size?
|
||||
self.thread_cache = threading.local()
|
||||
|
||||
if user is not None and password is not None:
|
||||
self.db.authenticate(user, password)
|
||||
|
||||
# every app has write access to the db (v having a flag to indicate r/o v write)
|
||||
# Force mongo to report errors, at the expense of performance
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import re
|
||||
from xmodule.contentstore.content import StaticContent
|
||||
from xmodule.modulestore import Location
|
||||
from xmodule.modulestore.mongo import MongoModuleStore
|
||||
from xmodule.modulestore.inheritance import own_metadata
|
||||
|
||||
import logging
|
||||
|
||||
@@ -52,11 +52,13 @@ def mongo_store_config(data_dir):
|
||||
store = {
|
||||
'default': {
|
||||
'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore',
|
||||
'OPTIONS': {
|
||||
'default_class': 'xmodule.raw_module.RawDescriptor',
|
||||
'DOC_STORE_CONFIG': {
|
||||
'host': 'localhost',
|
||||
'db': 'test_xmodule',
|
||||
'collection': 'modulestore_%s' % uuid4().hex,
|
||||
},
|
||||
'OPTIONS': {
|
||||
'default_class': 'xmodule.raw_module.RawDescriptor',
|
||||
'fs_root': data_dir,
|
||||
'render_template': 'mitxmako.shortcuts.render_to_string'
|
||||
}
|
||||
@@ -74,9 +76,6 @@ def draft_mongo_store_config(data_dir):
|
||||
|
||||
modulestore_options = {
|
||||
'default_class': 'xmodule.raw_module.RawDescriptor',
|
||||
'host': 'localhost',
|
||||
'db': 'test_xmodule',
|
||||
'collection': 'modulestore_%s' % uuid4().hex,
|
||||
'fs_root': data_dir,
|
||||
'render_template': 'mitxmako.shortcuts.render_to_string'
|
||||
}
|
||||
@@ -84,6 +83,11 @@ def draft_mongo_store_config(data_dir):
|
||||
store = {
|
||||
'default': {
|
||||
'ENGINE': 'xmodule.modulestore.mongo.draft.DraftModuleStore',
|
||||
'DOC_STORE_CONFIG': {
|
||||
'host': 'localhost',
|
||||
'db': 'test_xmodule',
|
||||
'collection': 'modulestore_%s' % uuid4().hex,
|
||||
},
|
||||
'OPTIONS': modulestore_options
|
||||
}
|
||||
}
|
||||
@@ -114,11 +118,13 @@ def studio_store_config(data_dir):
|
||||
"""
|
||||
Defines modulestore structure used by Studio tests.
|
||||
"""
|
||||
options = {
|
||||
'default_class': 'xmodule.raw_module.RawDescriptor',
|
||||
store_config = {
|
||||
'host': 'localhost',
|
||||
'db': 'test_xmodule',
|
||||
'collection': 'modulestore_%s' % uuid4().hex,
|
||||
}
|
||||
options = {
|
||||
'default_class': 'xmodule.raw_module.RawDescriptor',
|
||||
'fs_root': data_dir,
|
||||
'render_template': 'mitxmako.shortcuts.render_to_string',
|
||||
}
|
||||
@@ -126,18 +132,22 @@ def studio_store_config(data_dir):
|
||||
store = {
|
||||
'default': {
|
||||
'ENGINE': 'xmodule.modulestore.draft.DraftModuleStore',
|
||||
'DOC_STORE_CONFIG': store_config,
|
||||
'OPTIONS': options
|
||||
},
|
||||
'direct': {
|
||||
'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore',
|
||||
'DOC_STORE_CONFIG': store_config,
|
||||
'OPTIONS': options
|
||||
},
|
||||
'draft': {
|
||||
'ENGINE': 'xmodule.modulestore.draft.DraftModuleStore',
|
||||
'DOC_STORE_CONFIG': store_config,
|
||||
'OPTIONS': options
|
||||
},
|
||||
'split': {
|
||||
'ENGINE': 'xmodule.modulestore.split_mongo.SplitMongoModuleStore',
|
||||
'DOC_STORE_CONFIG': store_config,
|
||||
'OPTIONS': options
|
||||
}
|
||||
}
|
||||
@@ -206,7 +216,7 @@ class ModuleStoreTestCase(TestCase):
|
||||
If using a Mongo-backed modulestore, drop the collection.
|
||||
"""
|
||||
|
||||
# This will return the mongo-backed modulestore
|
||||
# This will return the mongo-backed modulestore
|
||||
# even if we're using a mixed modulestore
|
||||
store = editable_modulestore()
|
||||
|
||||
|
||||
@@ -47,11 +47,13 @@ OPTIONS = {
|
||||
},
|
||||
'default': {
|
||||
'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore',
|
||||
'OPTIONS': {
|
||||
'default_class': DEFAULT_CLASS,
|
||||
'DOC_STORE_CONFIG': {
|
||||
'host': HOST,
|
||||
'db': DB,
|
||||
'collection': COLLECTION,
|
||||
},
|
||||
'OPTIONS': {
|
||||
'default_class': DEFAULT_CLASS,
|
||||
'fs_root': DATA_DIR,
|
||||
'render_template': RENDER_TEMPLATE,
|
||||
}
|
||||
|
||||
@@ -56,14 +56,19 @@ class TestMongoModuleStore(object):
|
||||
@staticmethod
|
||||
def initdb():
|
||||
# connect to the db
|
||||
store = MongoModuleStore(HOST, DB, COLLECTION, FS_ROOT, RENDER_TEMPLATE, default_class=DEFAULT_CLASS)
|
||||
doc_store_config = {
|
||||
'host': HOST,
|
||||
'db': DB,
|
||||
'collection': COLLECTION,
|
||||
}
|
||||
store = MongoModuleStore(doc_store_config, FS_ROOT, RENDER_TEMPLATE, default_class=DEFAULT_CLASS)
|
||||
# since MongoModuleStore and MongoContentStore are basically assumed to be together, create this class
|
||||
# as well
|
||||
content_store = MongoContentStore(HOST, DB)
|
||||
#
|
||||
# Also test draft store imports
|
||||
#
|
||||
draft_store = DraftModuleStore(HOST, DB, COLLECTION, FS_ROOT, RENDER_TEMPLATE, default_class=DEFAULT_CLASS)
|
||||
draft_store = DraftModuleStore(doc_store_config, FS_ROOT, RENDER_TEMPLATE, default_class=DEFAULT_CLASS)
|
||||
# Explicitly list the courses to load (don't want the big one)
|
||||
courses = ['toy', 'simple', 'simple_with_draft', 'test_unicode']
|
||||
import_from_xml(store, DATA_DIR, courses, draft_store=draft_store, static_content_store=content_store)
|
||||
@@ -113,7 +118,10 @@ class TestMongoModuleStore(object):
|
||||
pprint([Location(i['_id']).url() for i in ids])
|
||||
|
||||
def test_mongo_modulestore_type(self):
|
||||
store = MongoModuleStore(HOST, DB, COLLECTION, FS_ROOT, RENDER_TEMPLATE, default_class=DEFAULT_CLASS)
|
||||
store = MongoModuleStore(
|
||||
{'host': HOST, 'db': DB, 'collection': COLLECTION},
|
||||
FS_ROOT, RENDER_TEMPLATE, default_class=DEFAULT_CLASS
|
||||
)
|
||||
assert_equals(store.get_modulestore_type('foo/bar/baz'), 'mongo')
|
||||
|
||||
def test_get_courses(self):
|
||||
|
||||
@@ -26,18 +26,18 @@ class TestPublish(unittest.TestCase):
|
||||
'db': 'test_xmodule',
|
||||
}
|
||||
|
||||
modulestore_options = dict({
|
||||
modulestore_options = {
|
||||
'default_class': 'xmodule.raw_module.RawDescriptor',
|
||||
'fs_root': '',
|
||||
'render_template': mock.Mock(return_value=""),
|
||||
'xblock_mixins': (InheritanceMixin,)
|
||||
}, **db_config)
|
||||
}
|
||||
|
||||
def setUp(self):
|
||||
self.modulestore_options['collection'] = 'modulestore{0}'.format(uuid.uuid4().hex)
|
||||
self.db_config['collection'] = 'modulestore{0}'.format(uuid.uuid4().hex)
|
||||
|
||||
self.old_mongo = MongoModuleStore(**self.modulestore_options)
|
||||
self.draft_mongo = DraftMongoModuleStore(**self.modulestore_options)
|
||||
self.old_mongo = MongoModuleStore(self.db_config, **self.modulestore_options)
|
||||
self.draft_mongo = DraftMongoModuleStore(self.db_config, **self.modulestore_options)
|
||||
self.addCleanup(self.tear_down_mongo)
|
||||
self.course_location = None
|
||||
|
||||
|
||||
@@ -34,20 +34,22 @@ class TestMigration(unittest.TestCase):
|
||||
'collection': 'modulestore{0}'.format(uuid.uuid4().hex),
|
||||
}
|
||||
|
||||
modulestore_options = dict({
|
||||
modulestore_options = {
|
||||
'default_class': 'xmodule.raw_module.RawDescriptor',
|
||||
'fs_root': '',
|
||||
'render_template': mock.Mock(return_value=""),
|
||||
'xblock_mixins': (InheritanceMixin,)
|
||||
}, **db_config)
|
||||
}
|
||||
|
||||
def setUp(self):
|
||||
super(TestMigration, self).setUp()
|
||||
self.loc_mapper = LocMapperStore(**self.db_config)
|
||||
self.old_mongo = MongoModuleStore(**self.modulestore_options)
|
||||
self.draft_mongo = DraftModuleStore(**self.modulestore_options)
|
||||
self.old_mongo = MongoModuleStore(self.db_config, **self.modulestore_options)
|
||||
self.draft_mongo = DraftModuleStore(self.db_config, **self.modulestore_options)
|
||||
self.split_mongo = SplitMongoModuleStore(
|
||||
loc_mapper=self.loc_mapper, **self.modulestore_options
|
||||
doc_store_config=self.db_config,
|
||||
loc_mapper=self.loc_mapper,
|
||||
**self.modulestore_options
|
||||
)
|
||||
self.migrator = SplitMigrator(self.split_mongo, self.old_mongo, self.draft_mongo, self.loc_mapper)
|
||||
self.course_location = None
|
||||
|
||||
@@ -28,18 +28,21 @@ class SplitModuleTest(unittest.TestCase):
|
||||
versions. It creates unique collection names and removes them after all
|
||||
tests finish.
|
||||
'''
|
||||
# Snippet of what would be in the django settings envs file
|
||||
modulestore_options = {
|
||||
'default_class': 'xmodule.raw_module.RawDescriptor',
|
||||
# Snippets of what would be in the django settings envs file
|
||||
DOC_STORE_CONFIG = {
|
||||
'host': 'localhost',
|
||||
'db': 'test_xmodule',
|
||||
'collection': 'modulestore{0}'.format(uuid.uuid4().hex),
|
||||
}
|
||||
modulestore_options = {
|
||||
'default_class': 'xmodule.raw_module.RawDescriptor',
|
||||
'fs_root': '',
|
||||
'xblock_mixins': (InheritanceMixin, XModuleMixin)
|
||||
}
|
||||
|
||||
MODULESTORE = {
|
||||
'ENGINE': 'xmodule.modulestore.split_mongo.SplitMongoModuleStore',
|
||||
'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
|
||||
'OPTIONS': modulestore_options
|
||||
}
|
||||
|
||||
@@ -66,8 +69,8 @@ class SplitModuleTest(unittest.TestCase):
|
||||
Loads the initial data into the db ensuring the collection name is
|
||||
unique.
|
||||
'''
|
||||
collection_prefix = SplitModuleTest.MODULESTORE['OPTIONS']['collection'] + '.'
|
||||
dbname = SplitModuleTest.MODULESTORE['OPTIONS']['db']
|
||||
collection_prefix = SplitModuleTest.MODULESTORE['DOC_STORE_CONFIG']['collection'] + '.'
|
||||
dbname = SplitModuleTest.MODULESTORE['DOC_STORE_CONFIG']['db']
|
||||
processes = [
|
||||
subprocess.Popen([
|
||||
'mongoimport', '-d', dbname, '-c',
|
||||
@@ -89,7 +92,7 @@ class SplitModuleTest(unittest.TestCase):
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
collection_prefix = SplitModuleTest.MODULESTORE['OPTIONS']['collection'] + '.'
|
||||
collection_prefix = SplitModuleTest.MODULESTORE['DOC_STORE_CONFIG']['collection'] + '.'
|
||||
if SplitModuleTest.modulestore:
|
||||
for collection in ('active_versions', 'structures', 'definitions'):
|
||||
modulestore().db.drop_collection(collection_prefix + collection)
|
||||
@@ -1115,7 +1118,10 @@ def modulestore():
|
||||
options['render_template'] = render_to_template_mock
|
||||
|
||||
# pylint: disable=W0142
|
||||
SplitModuleTest.modulestore = class_(**options)
|
||||
SplitModuleTest.modulestore = class_(
|
||||
SplitModuleTest.MODULESTORE['DOC_STORE_CONFIG'],
|
||||
**options
|
||||
)
|
||||
|
||||
return SplitModuleTest.modulestore
|
||||
|
||||
|
||||
@@ -32,11 +32,11 @@ DOC_STORE_CONFIG = {
|
||||
'collection': 'acceptance_modulestore_%s' % seed(),
|
||||
}
|
||||
|
||||
modulestore_options = dict({
|
||||
modulestore_options = {
|
||||
'default_class': 'xmodule.raw_module.RawDescriptor',
|
||||
'fs_root': TEST_ROOT / "data",
|
||||
'render_template': 'mitxmako.shortcuts.render_to_string',
|
||||
}, **DOC_STORE_CONFIG)
|
||||
}
|
||||
|
||||
MODULESTORE = {
|
||||
'default': {
|
||||
@@ -46,6 +46,7 @@ MODULESTORE = {
|
||||
'stores': {
|
||||
'default': {
|
||||
'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore',
|
||||
'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
|
||||
'OPTIONS': modulestore_options
|
||||
}
|
||||
}
|
||||
@@ -57,7 +58,7 @@ MODULESTORE['direct'] = MODULESTORE['default']
|
||||
|
||||
CONTENTSTORE = {
|
||||
'ENGINE': 'xmodule.contentstore.mongo.MongoContentStore',
|
||||
'OPTIONS': {
|
||||
'DOC_STORE_CONFIG': {
|
||||
'host': 'localhost',
|
||||
'db': 'acceptance_xcontent_%s' % seed(),
|
||||
}
|
||||
|
||||
@@ -28,22 +28,23 @@ DOC_STORE_CONFIG = {
|
||||
'collection': 'modulestore',
|
||||
}
|
||||
|
||||
modulestore_options = dict({
|
||||
modulestore_options = {
|
||||
'default_class': 'xmodule.raw_module.RawDescriptor',
|
||||
'fs_root': DATA_DIR,
|
||||
'render_template': 'mitxmako.shortcuts.render_to_string',
|
||||
}, **DOC_STORE_CONFIG)
|
||||
}
|
||||
|
||||
MODULESTORE = {
|
||||
'default': {
|
||||
'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore',
|
||||
'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
|
||||
'OPTIONS': modulestore_options
|
||||
},
|
||||
}
|
||||
|
||||
CONTENTSTORE = {
|
||||
'ENGINE': 'xmodule.contentstore.mongo.MongoContentStore',
|
||||
'OPTIONS': {
|
||||
'DOC_STORE_CONFIG': {
|
||||
'host': 'localhost',
|
||||
'db': 'xcontent',
|
||||
}
|
||||
|
||||
@@ -25,11 +25,13 @@ MODULESTORE = {
|
||||
},
|
||||
'default': {
|
||||
'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore',
|
||||
'OPTIONS': {
|
||||
'default_class': 'xmodule.raw_module.RawDescriptor',
|
||||
'DOC_STORE_CONFIG': {
|
||||
'host': 'localhost',
|
||||
'db': 'xmodule',
|
||||
'collection': 'modulestore',
|
||||
},
|
||||
'OPTIONS': {
|
||||
'default_class': 'xmodule.raw_module.RawDescriptor',
|
||||
'fs_root': DATA_DIR,
|
||||
'render_template': 'mitxmako.shortcuts.render_to_string',
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ from .dev import *
|
||||
MODULESTORE = {
|
||||
'default': {
|
||||
'ENGINE': 'xmodule.modulestore.draft.DraftModuleStore',
|
||||
'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
|
||||
'OPTIONS': modulestore_options
|
||||
},
|
||||
}
|
||||
|
||||
@@ -13,11 +13,13 @@ GITHUB_REPO_ROOT = ENV_ROOT / "data"
|
||||
MODULESTORE = {
|
||||
'default': {
|
||||
'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore',
|
||||
'OPTIONS': {
|
||||
'default_class': 'xmodule.raw_module.RawDescriptor',
|
||||
'DOC_STORE_CONFIG': {
|
||||
'host': 'localhost',
|
||||
'db': 'xmodule',
|
||||
'collection': 'modulestore',
|
||||
},
|
||||
'OPTIONS': {
|
||||
'default_class': 'xmodule.raw_module.RawDescriptor',
|
||||
'fs_root': GITHUB_REPO_ROOT,
|
||||
'render_template': 'mitxmako.shortcuts.render_to_string',
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ MITX_FEATURES['ENABLE_SHOPPING_CART'] = True
|
||||
WIKI_ENABLED = True
|
||||
|
||||
# Makes the tests run much faster...
|
||||
SOUTH_TESTS_MIGRATE = False # To disable migrations and use syncdb instead
|
||||
SOUTH_TESTS_MIGRATE = False # To disable migrations and use syncdb instead
|
||||
|
||||
# Nose Test Runner
|
||||
TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
|
||||
@@ -78,7 +78,7 @@ XQUEUE_INTERFACE = {
|
||||
},
|
||||
"basic_auth": ('anant', 'agarwal'),
|
||||
}
|
||||
XQUEUE_WAITTIME_BETWEEN_REQUESTS = 5 # seconds
|
||||
XQUEUE_WAITTIME_BETWEEN_REQUESTS = 5 # seconds
|
||||
|
||||
|
||||
# Don't rely on a real staff grading backend
|
||||
@@ -115,7 +115,7 @@ INIT_MODULESTORE_ON_STARTUP = False
|
||||
|
||||
CONTENTSTORE = {
|
||||
'ENGINE': 'xmodule.contentstore.mongo.MongoContentStore',
|
||||
'OPTIONS': {
|
||||
'DOC_STORE_CONFIG': {
|
||||
'host': 'localhost',
|
||||
'db': 'xcontent',
|
||||
}
|
||||
@@ -247,4 +247,4 @@ PASSWORD_HASHERS = (
|
||||
# Generated checkid_setup request to http://testserver/openid/provider/login/ with assocication {HMAC-SHA1}{51d49995}{s/kRmA==}
|
||||
|
||||
import openid.oidutil
|
||||
openid.oidutil.log = lambda message, level=0: None
|
||||
openid.oidutil.log = lambda message, level = 0: None
|
||||
|
||||
Reference in New Issue
Block a user