Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
8267a762
Commit
8267a762
authored
Sep 24, 2015
by
Calen Pennington
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move *ModuleStoreBuilders into xmodule.modulestore.tests.utils
parent
972196fe
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
350 additions
and
322 deletions
+350
-322
cms/djangoapps/contentstore/tests/test_courseware_index.py
+4
-2
common/lib/xmodule/xmodule/modulestore/perf_tests/test_asset_import_export.py
+1
-1
common/lib/xmodule/xmodule/modulestore/tests/test_asides.py
+1
-1
common/lib/xmodule/xmodule/modulestore/tests/test_assetstore.py
+1
-1
common/lib/xmodule/xmodule/modulestore/tests/test_cross_modulestore_import_export.py
+3
-312
common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py
+1
-1
common/lib/xmodule/xmodule/modulestore/tests/test_mongo_call_count.py
+1
-1
common/lib/xmodule/xmodule/modulestore/tests/test_publish.py
+1
-1
common/lib/xmodule/xmodule/modulestore/tests/test_split_w_old_mongo.py
+1
-1
common/lib/xmodule/xmodule/modulestore/tests/utils.py
+335
-0
common/lib/xmodule/xmodule/tests/test_course_metadata_utils.py
+1
-1
No files found.
cms/djangoapps/contentstore/tests/test_courseware_index.py
View file @
8267a762
...
...
@@ -29,8 +29,10 @@ from xmodule.modulestore.tests.django_utils import (
)
from
xmodule.modulestore.tests.factories
import
CourseFactory
,
ItemFactory
,
LibraryFactory
from
xmodule.modulestore.tests.mongo_connection
import
MONGO_PORT_NUM
,
MONGO_HOST
from
xmodule.modulestore.tests.test_cross_modulestore_import_export
import
MongoContentstoreBuilder
from
xmodule.modulestore.tests.utils
import
create_modulestore_instance
,
LocationMixin
,
MixedSplitTestCase
from
xmodule.modulestore.tests.utils
import
(
create_modulestore_instance
,
LocationMixin
,
MixedSplitTestCase
,
MongoContentstoreBuilder
)
from
xmodule.tests
import
DATA_DIR
from
xmodule.x_module
import
XModuleMixin
from
xmodule.partitions.partitions
import
UserPartition
...
...
common/lib/xmodule/xmodule/modulestore/perf_tests/test_asset_import_export.py
View file @
8267a762
...
...
@@ -16,7 +16,7 @@ from xmodule.assetstore import AssetMetadata
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.xml_importer
import
import_course_from_xml
from
xmodule.modulestore.xml_exporter
import
export_course_to_xml
from
xmodule.modulestore.tests.
test_cross_modulestore_import_export
import
(
from
xmodule.modulestore.tests.
utils
import
(
MODULESTORE_SETUPS
,
SHORT_NAME_MAP
,
TEST_DATA_DIR
,
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_asides.py
View file @
8267a762
...
...
@@ -5,7 +5,7 @@ from xblock.core import XBlockAside
from
xblock.fields
import
Scope
,
String
from
xblock.fragment
import
Fragment
from
unittest
import
TestCase
from
xmodule.modulestore.tests.
test_cross_modulestore_import_export
import
XmlModulestoreBuilder
from
xmodule.modulestore.tests.
utils
import
XmlModulestoreBuilder
from
mock
import
patch
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_assetstore.py
View file @
8267a762
...
...
@@ -14,7 +14,7 @@ from xmodule.assetstore import AssetMetadata
from
xmodule.modulestore
import
ModuleStoreEnum
,
SortedAssetList
,
IncorrectlySortedList
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
from
xmodule.modulestore.tests.factories
import
CourseFactory
from
xmodule.modulestore.tests.
test_cross_modulestore_import_export
import
(
from
xmodule.modulestore.tests.
utils
import
(
MIXED_MODULESTORE_BOTH_SETUP
,
MODULESTORE_SETUPS
,
XmlModulestoreBuilder
,
MixedModulestoreBuilder
)
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_cross_modulestore_import_export.py
View file @
8267a762
...
...
@@ -15,7 +15,6 @@ from contextlib import contextmanager, nested
import
itertools
import
os
from
path
import
Path
as
path
import
random
from
shutil
import
rmtree
from
tempfile
import
mkdtemp
...
...
@@ -24,326 +23,18 @@ from nose.plugins.attrib import attr
from
mock
import
patch
from
xmodule.tests
import
CourseComparisonTest
from
xmodule.modulestore.mongo.base
import
ModuleStoreEnum
from
xmodule.modulestore.mongo.draft
import
DraftModuleStore
from
xmodule.modulestore.mixed
import
MixedModuleStore
from
xmodule.contentstore.mongo
import
MongoContentStore
from
xmodule.modulestore.xml_importer
import
import_course_from_xml
from
xmodule.modulestore.xml_exporter
import
export_course_to_xml
from
xmodule.modulestore.split_mongo.split_draft
import
DraftVersioningModuleStore
from
xmodule.modulestore.tests.mongo_connection
import
MONGO_PORT_NUM
,
MONGO_HOST
from
xmodule.modulestore.tests.utils
import
mock_tab_from_json
from
xmodule.modulestore.inheritance
import
InheritanceMixin
from
xmodule.partitions.tests.test_partitions
import
PartitionTestCase
from
xmodule.x_module
import
XModuleMixin
from
xmodule.modulestore.xml
import
XMLModuleStore
TEST_DATA_DIR
=
'common/test/data/'
COMMON_DOCSTORE_CONFIG
=
{
'host'
:
MONGO_HOST
,
'port'
:
MONGO_PORT_NUM
,
}
DATA_DIR
=
path
(
__file__
)
.
dirname
()
.
parent
.
parent
/
"tests"
/
"data"
/
"xml-course-root"
XBLOCK_MIXINS
=
(
InheritanceMixin
,
XModuleMixin
)
class
MemoryCache
(
object
):
"""
This fits the metadata_inheritance_cache_subsystem interface used by
the modulestore, and stores the data in a dictionary in memory.
"""
def
__init__
(
self
):
self
.
_data
=
{}
def
get
(
self
,
key
,
default
=
None
):
"""
Get a key from the cache.
Args:
key: The key to update.
default: The value to return if the key hasn't been set previously.
"""
return
self
.
_data
.
get
(
key
,
default
)
def
set
(
self
,
key
,
value
):
"""
Set a key in the cache.
Args:
key: The key to update.
value: The value change the key to.
"""
self
.
_data
[
key
]
=
value
class
MongoContentstoreBuilder
(
object
):
"""
A builder class for a MongoContentStore.
"""
@contextmanager
def
build
(
self
):
"""
A contextmanager that returns a MongoContentStore, and deletes its contents
when the context closes.
"""
contentstore
=
MongoContentStore
(
db
=
'contentstore{}'
.
format
(
random
.
randint
(
0
,
10000
)),
collection
=
'content'
,
**
COMMON_DOCSTORE_CONFIG
)
contentstore
.
ensure_indexes
()
try
:
yield
contentstore
finally
:
# Delete the created database
contentstore
.
_drop_database
()
# pylint: disable=protected-access
def
__repr__
(
self
):
return
'MongoContentstoreBuilder()'
class
StoreBuilderBase
(
object
):
"""
Base class for all modulestore builders.
"""
@contextmanager
def
build
(
self
,
**
kwargs
):
"""
Build the modulstore, optionally building the contentstore as well.
"""
contentstore
=
kwargs
.
pop
(
'contentstore'
,
None
)
if
not
contentstore
:
with
self
.
build_without_contentstore
()
as
(
contentstore
,
modulestore
):
yield
contentstore
,
modulestore
else
:
with
self
.
build_with_contentstore
(
contentstore
)
as
modulestore
:
yield
modulestore
@contextmanager
def
build_without_contentstore
(
self
):
"""
Build both the contentstore and the modulestore.
"""
with
MongoContentstoreBuilder
()
.
build
()
as
contentstore
:
with
self
.
build_with_contentstore
(
contentstore
)
as
modulestore
:
yield
contentstore
,
modulestore
class
MongoModulestoreBuilder
(
StoreBuilderBase
):
"""
A builder class for a DraftModuleStore.
"""
@contextmanager
def
build_with_contentstore
(
self
,
contentstore
):
"""
A contextmanager that returns an isolated mongo modulestore, and then deletes
all of its data at the end of the context.
Args:
contentstore: The contentstore that this modulestore should use to store
all of its assets.
"""
doc_store_config
=
dict
(
db
=
'modulestore{}'
.
format
(
random
.
randint
(
0
,
10000
)),
collection
=
'xmodule'
,
asset_collection
=
'asset_metadata'
,
**
COMMON_DOCSTORE_CONFIG
)
# Set up a temp directory for storing filesystem content created during import
fs_root
=
mkdtemp
()
# pylint: disable=attribute-defined-outside-init
modulestore
=
DraftModuleStore
(
contentstore
,
doc_store_config
,
fs_root
,
render_template
=
repr
,
branch_setting_func
=
lambda
:
ModuleStoreEnum
.
Branch
.
draft_preferred
,
metadata_inheritance_cache_subsystem
=
MemoryCache
(),
xblock_mixins
=
XBLOCK_MIXINS
,
)
modulestore
.
ensure_indexes
()
try
:
yield
modulestore
finally
:
# Delete the created database
modulestore
.
_drop_database
()
# pylint: disable=protected-access
# Delete the created directory on the filesystem
rmtree
(
fs_root
,
ignore_errors
=
True
)
def
__repr__
(
self
):
return
'MongoModulestoreBuilder()'
class
VersioningModulestoreBuilder
(
StoreBuilderBase
):
"""
A builder class for a VersioningModuleStore.
"""
@contextmanager
def
build_with_contentstore
(
self
,
contentstore
):
"""
A contextmanager that returns an isolated versioning modulestore, and then deletes
all of its data at the end of the context.
Args:
contentstore: The contentstore that this modulestore should use to store
all of its assets.
"""
# pylint: disable=unreachable
doc_store_config
=
dict
(
db
=
'modulestore{}'
.
format
(
random
.
randint
(
0
,
10000
)),
collection
=
'split_module'
,
**
COMMON_DOCSTORE_CONFIG
)
# Set up a temp directory for storing filesystem content created during import
fs_root
=
mkdtemp
()
modulestore
=
DraftVersioningModuleStore
(
contentstore
,
doc_store_config
,
fs_root
,
render_template
=
repr
,
xblock_mixins
=
XBLOCK_MIXINS
,
)
modulestore
.
ensure_indexes
()
try
:
yield
modulestore
finally
:
# Delete the created database
modulestore
.
_drop_database
()
# pylint: disable=protected-access
# Delete the created directory on the filesystem
rmtree
(
fs_root
,
ignore_errors
=
True
)
def
__repr__
(
self
):
return
'SplitModulestoreBuilder()'
class
XmlModulestoreBuilder
(
StoreBuilderBase
):
"""
A builder class for a XMLModuleStore.
"""
# pylint: disable=unused-argument
@contextmanager
def
build_with_contentstore
(
self
,
contentstore
=
None
,
course_ids
=
None
):
"""
A contextmanager that returns an isolated xml modulestore
Args:
contentstore: The contentstore that this modulestore should use to store
all of its assets.
"""
modulestore
=
XMLModuleStore
(
DATA_DIR
,
course_ids
=
course_ids
,
default_class
=
'xmodule.hidden_module.HiddenDescriptor'
,
xblock_mixins
=
XBLOCK_MIXINS
,
)
yield
modulestore
class
MixedModulestoreBuilder
(
StoreBuilderBase
):
"""
A builder class for a MixedModuleStore.
"""
def
__init__
(
self
,
store_builders
,
mappings
=
None
):
"""
Args:
store_builders: A list of modulestore builder objects. These will be instantiated, in order,
as the backing stores for the MixedModuleStore.
mappings: Any course mappings to pass to the MixedModuleStore on instantiation.
"""
self
.
store_builders
=
store_builders
self
.
mappings
=
mappings
or
{}
self
.
mixed_modulestore
=
None
@contextmanager
def
build_with_contentstore
(
self
,
contentstore
):
"""
A contextmanager that returns a mixed modulestore built on top of modulestores
generated by other builder classes.
Args:
contentstore: The contentstore that this modulestore should use to store
all of its assets.
"""
names
,
generators
=
zip
(
*
self
.
store_builders
)
with
nested
(
*
(
gen
.
build_with_contentstore
(
contentstore
)
for
gen
in
generators
))
as
modulestores
:
# Make the modulestore creation function just return the already-created modulestores
store_iterator
=
iter
(
modulestores
)
create_modulestore_instance
=
lambda
*
args
,
**
kwargs
:
store_iterator
.
next
()
# Generate a fake list of stores to give the already generated stores appropriate names
stores
=
[{
'NAME'
:
name
,
'ENGINE'
:
'This space deliberately left blank'
}
for
name
in
names
]
self
.
mixed_modulestore
=
MixedModuleStore
(
contentstore
,
self
.
mappings
,
stores
,
create_modulestore_instance
=
create_modulestore_instance
,
xblock_mixins
=
XBLOCK_MIXINS
,
)
yield
self
.
mixed_modulestore
def
__repr__
(
self
):
return
'MixedModulestoreBuilder({!r}, {!r})'
.
format
(
self
.
store_builders
,
self
.
mappings
)
def
asset_collection
(
self
):
"""
Returns the collection storing the asset metadata.
"""
all_stores
=
self
.
mixed_modulestore
.
modulestores
if
len
(
all_stores
)
>
1
:
return
None
store
=
all_stores
[
0
]
if
hasattr
(
store
,
'asset_collection'
):
# Mongo modulestore beneath mixed.
# Returns the entire collection with *all* courses' asset metadata.
return
store
.
asset_collection
else
:
# Split modulestore beneath mixed.
# Split stores all asset metadata in the structure collection.
return
store
.
db_connection
.
structures
MIXED_MODULESTORE_BOTH_SETUP
=
MixedModulestoreBuilder
([
(
'draft'
,
MongoModulestoreBuilder
()),
(
'split'
,
VersioningModulestoreBuilder
())
])
DRAFT_MODULESTORE_SETUP
=
MixedModulestoreBuilder
([(
'draft'
,
MongoModulestoreBuilder
())])
SPLIT_MODULESTORE_SETUP
=
MixedModulestoreBuilder
([(
'split'
,
VersioningModulestoreBuilder
())])
MIXED_MODULESTORE_SETUPS
=
(
DRAFT_MODULESTORE_SETUP
,
SPLIT_MODULESTORE_SETUP
,
)
MIXED_MS_SETUPS_SHORT
=
(
'mixed_mongo'
,
'mixed_split'
,
)
DIRECT_MODULESTORE_SETUPS
=
(
MongoModulestoreBuilder
(),
# VersioningModulestoreBuilder(), # FUTUREDO: LMS-11227
)
DIRECT_MS_SETUPS_SHORT
=
(
'mongo'
,
#'split',
from
xmodule.modulestore.tests.utils
import
(
MongoContentstoreBuilder
,
MODULESTORE_SETUPS
,
SPLIT_MODULESTORE_SETUP
,
CONTENTSTORE_SETUPS
,
TEST_DATA_DIR
)
MODULESTORE_SETUPS
=
DIRECT_MODULESTORE_SETUPS
+
MIXED_MODULESTORE_SETUPS
MODULESTORE_SHORTNAMES
=
DIRECT_MS_SETUPS_SHORT
+
MIXED_MS_SETUPS_SHORT
SHORT_NAME_MAP
=
dict
(
zip
(
MODULESTORE_SETUPS
,
MODULESTORE_SHORTNAMES
))
CONTENTSTORE_SETUPS
=
(
MongoContentstoreBuilder
(),)
COURSE_DATA_NAMES
=
(
'toy'
,
'manual-testing-complete'
,
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py
View file @
8267a762
...
...
@@ -26,7 +26,7 @@ from tempfile import mkdtemp
from
xmodule.x_module
import
XModuleMixin
from
xmodule.modulestore.edit_info
import
EditInfoMixin
from
xmodule.modulestore.inheritance
import
InheritanceMixin
from
xmodule.modulestore.tests.
test_cross_modulestore_import_export
import
MongoContentstoreBuilder
from
xmodule.modulestore.tests.
utils
import
MongoContentstoreBuilder
from
xmodule.contentstore.content
import
StaticContent
from
opaque_keys.edx.keys
import
CourseKey
from
xmodule.modulestore.xml_importer
import
import_course_from_xml
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_mongo_call_count.py
View file @
8267a762
...
...
@@ -11,7 +11,7 @@ import ddt
from
xmodule.modulestore.xml_importer
import
import_course_from_xml
from
xmodule.modulestore.xml_exporter
import
export_course_to_xml
from
xmodule.modulestore.tests.factories
import
check_mongo_calls
from
xmodule.modulestore.tests.
test_cross_modulestore_import_export
import
(
from
xmodule.modulestore.tests.
utils
import
(
MixedModulestoreBuilder
,
VersioningModulestoreBuilder
,
MongoModulestoreBuilder
,
TEST_DATA_DIR
)
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_publish.py
View file @
8267a762
...
...
@@ -19,7 +19,7 @@ from xmodule.modulestore.exceptions import ItemNotFoundError
from
xmodule.modulestore.xml_exporter
import
export_course_to_xml
from
xmodule.modulestore.tests.test_split_w_old_mongo
import
SplitWMongoCourseBootstrapper
from
xmodule.modulestore.tests.factories
import
check_mongo_calls
,
mongo_uses_error_check
,
CourseFactory
,
ItemFactory
from
xmodule.modulestore.tests.
test_cross_modulestore_import_export
import
(
from
xmodule.modulestore.tests.
utils
import
(
MongoContentstoreBuilder
,
MODULESTORE_SETUPS
,
DRAFT_MODULESTORE_SETUP
,
SPLIT_MODULESTORE_SETUP
,
MongoModulestoreBuilder
,
)
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_split_w_old_mongo.py
View file @
8267a762
...
...
@@ -13,7 +13,7 @@ from xmodule.modulestore.inheritance import InheritanceMixin
from
xmodule.modulestore.mongo
import
DraftMongoModuleStore
from
xmodule.modulestore.split_mongo.split
import
SplitMongoModuleStore
from
xmodule.modulestore.tests.mongo_connection
import
MONGO_PORT_NUM
,
MONGO_HOST
from
xmodule.modulestore.tests.
test_cross_modulestore_import_export
import
MemoryCache
from
xmodule.modulestore.tests.
utils
import
MemoryCache
@attr
(
'mongo'
)
...
...
common/lib/xmodule/xmodule/modulestore/tests/utils.py
View file @
8267a762
"""
Helper classes and methods for running modulestore tests without Django.
"""
import
random
from
contextlib
import
contextmanager
,
nested
from
importlib
import
import_module
from
opaque_keys.edx.keys
import
UsageKey
from
path
import
Path
as
path
from
shutil
import
rmtree
from
tempfile
import
mkdtemp
from
unittest
import
TestCase
from
xblock.fields
import
XBlockMixin
from
xmodule.x_module
import
XModuleMixin
from
xmodule.contentstore.mongo
import
MongoContentStore
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.draft_and_published
import
ModuleStoreDraftAndPublished
from
xmodule.modulestore.edit_info
import
EditInfoMixin
from
xmodule.modulestore.inheritance
import
InheritanceMixin
from
xmodule.modulestore.mixed
import
MixedModuleStore
from
xmodule.modulestore.mongo.base
import
ModuleStoreEnum
from
xmodule.modulestore.mongo.draft
import
DraftModuleStore
from
xmodule.modulestore.split_mongo.split_draft
import
DraftVersioningModuleStore
from
xmodule.modulestore.tests.factories
import
ItemFactory
from
xmodule.modulestore.tests.mongo_connection
import
MONGO_PORT_NUM
,
MONGO_HOST
from
xmodule.modulestore.xml
import
XMLModuleStore
from
xmodule.tests
import
DATA_DIR
...
...
@@ -174,3 +186,326 @@ class ProceduralCourseTestMixin(object):
with
self
.
store
.
bulk_operations
(
self
.
course
.
id
,
emit_signals
=
emit_signals
):
descend
(
self
.
course
,
[
'chapter'
,
'sequential'
,
'vertical'
,
'problem'
])
class
MemoryCache
(
object
):
"""
This fits the metadata_inheritance_cache_subsystem interface used by
the modulestore, and stores the data in a dictionary in memory.
"""
def
__init__
(
self
):
self
.
_data
=
{}
def
get
(
self
,
key
,
default
=
None
):
"""
Get a key from the cache.
Args:
key: The key to update.
default: The value to return if the key hasn't been set previously.
"""
return
self
.
_data
.
get
(
key
,
default
)
def
set
(
self
,
key
,
value
):
"""
Set a key in the cache.
Args:
key: The key to update.
value: The value change the key to.
"""
self
.
_data
[
key
]
=
value
class
MongoContentstoreBuilder
(
object
):
"""
A builder class for a MongoContentStore.
"""
@contextmanager
def
build
(
self
):
"""
A contextmanager that returns a MongoContentStore, and deletes its contents
when the context closes.
"""
contentstore
=
MongoContentStore
(
db
=
'contentstore{}'
.
format
(
random
.
randint
(
0
,
10000
)),
collection
=
'content'
,
**
COMMON_DOCSTORE_CONFIG
)
contentstore
.
ensure_indexes
()
try
:
yield
contentstore
finally
:
# Delete the created database
contentstore
.
_drop_database
()
# pylint: disable=protected-access
def
__repr__
(
self
):
return
'MongoContentstoreBuilder()'
class
StoreBuilderBase
(
object
):
"""
Base class for all modulestore builders.
"""
@contextmanager
def
build
(
self
,
**
kwargs
):
"""
Build the modulstore, optionally building the contentstore as well.
"""
contentstore
=
kwargs
.
pop
(
'contentstore'
,
None
)
if
not
contentstore
:
with
self
.
build_without_contentstore
()
as
(
contentstore
,
modulestore
):
yield
contentstore
,
modulestore
else
:
with
self
.
build_with_contentstore
(
contentstore
)
as
modulestore
:
yield
modulestore
@contextmanager
def
build_without_contentstore
(
self
):
"""
Build both the contentstore and the modulestore.
"""
with
MongoContentstoreBuilder
()
.
build
()
as
contentstore
:
with
self
.
build_with_contentstore
(
contentstore
)
as
modulestore
:
yield
contentstore
,
modulestore
class
MongoModulestoreBuilder
(
StoreBuilderBase
):
"""
A builder class for a DraftModuleStore.
"""
@contextmanager
def
build_with_contentstore
(
self
,
contentstore
):
"""
A contextmanager that returns an isolated mongo modulestore, and then deletes
all of its data at the end of the context.
Args:
contentstore: The contentstore that this modulestore should use to store
all of its assets.
"""
doc_store_config
=
dict
(
db
=
'modulestore{}'
.
format
(
random
.
randint
(
0
,
10000
)),
collection
=
'xmodule'
,
asset_collection
=
'asset_metadata'
,
**
COMMON_DOCSTORE_CONFIG
)
# Set up a temp directory for storing filesystem content created during import
fs_root
=
mkdtemp
()
# pylint: disable=attribute-defined-outside-init
modulestore
=
DraftModuleStore
(
contentstore
,
doc_store_config
,
fs_root
,
render_template
=
repr
,
branch_setting_func
=
lambda
:
ModuleStoreEnum
.
Branch
.
draft_preferred
,
metadata_inheritance_cache_subsystem
=
MemoryCache
(),
xblock_mixins
=
XBLOCK_MIXINS
,
)
modulestore
.
ensure_indexes
()
try
:
yield
modulestore
finally
:
# Delete the created database
modulestore
.
_drop_database
()
# pylint: disable=protected-access
# Delete the created directory on the filesystem
rmtree
(
fs_root
,
ignore_errors
=
True
)
def
__repr__
(
self
):
return
'MongoModulestoreBuilder()'
class
VersioningModulestoreBuilder
(
StoreBuilderBase
):
"""
A builder class for a VersioningModuleStore.
"""
@contextmanager
def
build_with_contentstore
(
self
,
contentstore
):
"""
A contextmanager that returns an isolated versioning modulestore, and then deletes
all of its data at the end of the context.
Args:
contentstore: The contentstore that this modulestore should use to store
all of its assets.
"""
# pylint: disable=unreachable
doc_store_config
=
dict
(
db
=
'modulestore{}'
.
format
(
random
.
randint
(
0
,
10000
)),
collection
=
'split_module'
,
**
COMMON_DOCSTORE_CONFIG
)
# Set up a temp directory for storing filesystem content created during import
fs_root
=
mkdtemp
()
modulestore
=
DraftVersioningModuleStore
(
contentstore
,
doc_store_config
,
fs_root
,
render_template
=
repr
,
xblock_mixins
=
XBLOCK_MIXINS
,
)
modulestore
.
ensure_indexes
()
try
:
yield
modulestore
finally
:
# Delete the created database
modulestore
.
_drop_database
()
# pylint: disable=protected-access
# Delete the created directory on the filesystem
rmtree
(
fs_root
,
ignore_errors
=
True
)
def
__repr__
(
self
):
return
'SplitModulestoreBuilder()'
class
XmlModulestoreBuilder
(
StoreBuilderBase
):
"""
A builder class for a XMLModuleStore.
"""
# pylint: disable=unused-argument
@contextmanager
def
build_with_contentstore
(
self
,
contentstore
=
None
,
course_ids
=
None
):
"""
A contextmanager that returns an isolated xml modulestore
Args:
contentstore: The contentstore that this modulestore should use to store
all of its assets.
"""
modulestore
=
XMLModuleStore
(
DATA_DIR
,
course_ids
=
course_ids
,
default_class
=
'xmodule.hidden_module.HiddenDescriptor'
,
xblock_mixins
=
XBLOCK_MIXINS
,
)
yield
modulestore
class
MixedModulestoreBuilder
(
StoreBuilderBase
):
"""
A builder class for a MixedModuleStore.
"""
def
__init__
(
self
,
store_builders
,
mappings
=
None
):
"""
Args:
store_builders: A list of modulestore builder objects. These will be instantiated, in order,
as the backing stores for the MixedModuleStore.
mappings: Any course mappings to pass to the MixedModuleStore on instantiation.
"""
self
.
store_builders
=
store_builders
self
.
mappings
=
mappings
or
{}
self
.
mixed_modulestore
=
None
@contextmanager
def
build_with_contentstore
(
self
,
contentstore
):
"""
A contextmanager that returns a mixed modulestore built on top of modulestores
generated by other builder classes.
Args:
contentstore: The contentstore that this modulestore should use to store
all of its assets.
"""
names
,
generators
=
zip
(
*
self
.
store_builders
)
with
nested
(
*
(
gen
.
build_with_contentstore
(
contentstore
)
for
gen
in
generators
))
as
modulestores
:
# Make the modulestore creation function just return the already-created modulestores
store_iterator
=
iter
(
modulestores
)
next_modulestore
=
lambda
*
args
,
**
kwargs
:
store_iterator
.
next
()
# Generate a fake list of stores to give the already generated stores appropriate names
stores
=
[{
'NAME'
:
name
,
'ENGINE'
:
'This space deliberately left blank'
}
for
name
in
names
]
self
.
mixed_modulestore
=
MixedModuleStore
(
contentstore
,
self
.
mappings
,
stores
,
create_modulestore_instance
=
next_modulestore
,
xblock_mixins
=
XBLOCK_MIXINS
,
)
yield
self
.
mixed_modulestore
def
__repr__
(
self
):
return
'MixedModulestoreBuilder({!r}, {!r})'
.
format
(
self
.
store_builders
,
self
.
mappings
)
def
asset_collection
(
self
):
"""
Returns the collection storing the asset metadata.
"""
all_stores
=
self
.
mixed_modulestore
.
modulestores
if
len
(
all_stores
)
>
1
:
return
None
store
=
all_stores
[
0
]
if
hasattr
(
store
,
'asset_collection'
):
# Mongo modulestore beneath mixed.
# Returns the entire collection with *all* courses' asset metadata.
return
store
.
asset_collection
else
:
# Split modulestore beneath mixed.
# Split stores all asset metadata in the structure collection.
return
store
.
db_connection
.
structures
COMMON_DOCSTORE_CONFIG
=
{
'host'
:
MONGO_HOST
,
'port'
:
MONGO_PORT_NUM
,
}
DATA_DIR
=
path
(
__file__
)
.
dirname
()
.
parent
.
parent
/
"tests"
/
"data"
/
"xml-course-root"
TEST_DATA_DIR
=
'common/test/data/'
XBLOCK_MIXINS
=
(
InheritanceMixin
,
XModuleMixin
)
MIXED_MODULESTORE_BOTH_SETUP
=
MixedModulestoreBuilder
([
(
'draft'
,
MongoModulestoreBuilder
()),
(
'split'
,
VersioningModulestoreBuilder
())
])
DRAFT_MODULESTORE_SETUP
=
MixedModulestoreBuilder
([(
'draft'
,
MongoModulestoreBuilder
())])
SPLIT_MODULESTORE_SETUP
=
MixedModulestoreBuilder
([(
'split'
,
VersioningModulestoreBuilder
())])
MIXED_MODULESTORE_SETUPS
=
(
DRAFT_MODULESTORE_SETUP
,
SPLIT_MODULESTORE_SETUP
,
)
MIXED_MS_SETUPS_SHORT
=
(
'mixed_mongo'
,
'mixed_split'
,
)
DIRECT_MODULESTORE_SETUPS
=
(
MongoModulestoreBuilder
(),
# VersioningModulestoreBuilder(), # FUTUREDO: LMS-11227
)
DIRECT_MS_SETUPS_SHORT
=
(
'mongo'
,
#'split',
)
MODULESTORE_SETUPS
=
DIRECT_MODULESTORE_SETUPS
+
MIXED_MODULESTORE_SETUPS
MODULESTORE_SHORTNAMES
=
DIRECT_MS_SETUPS_SHORT
+
MIXED_MS_SETUPS_SHORT
SHORT_NAME_MAP
=
dict
(
zip
(
MODULESTORE_SETUPS
,
MODULESTORE_SHORTNAMES
))
CONTENTSTORE_SETUPS
=
(
MongoContentstoreBuilder
(),)
class
PureModulestoreTestCase
(
TestCase
):
"""
A TestCase designed to make testing Modulestore implementations without using Django
easier.
"""
MODULESTORE
=
None
def
setUp
(
self
):
super
(
PureModulestoreTestCase
,
self
)
.
setUp
()
builder
=
self
.
MODULESTORE
.
build
()
self
.
assets
,
self
.
store
=
builder
.
__enter__
()
self
.
addCleanup
(
builder
.
__exit__
,
None
,
None
,
None
)
common/lib/xmodule/xmodule/tests/test_course_metadata_utils.py
View file @
8267a762
...
...
@@ -22,7 +22,7 @@ from xmodule.course_metadata_utils import (
may_certify_for_course
,
)
from
xmodule.fields
import
Date
from
xmodule.modulestore.tests.
test_cross_modulestore_import_export
import
(
from
xmodule.modulestore.tests.
utils
import
(
MongoModulestoreBuilder
,
VersioningModulestoreBuilder
,
MixedModulestoreBuilder
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment