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
c930e17f
Commit
c930e17f
authored
Jul 25, 2014
by
Nimisha Asthagiri
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #4534 from edx/nimisha/import-perf-unit-test-STUD-1994
Unit test for import performance STUD-1994
parents
f6b278e7
cd33165a
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
76 additions
and
30 deletions
+76
-30
cms/djangoapps/contentstore/tests/test_course_listing.py
+2
-2
cms/djangoapps/contentstore/tests/test_import.py
+18
-0
common/lib/xmodule/xmodule/modulestore/tests/factories.py
+47
-20
common/lib/xmodule/xmodule/modulestore/tests/test_publish.py
+9
-8
No files found.
cms/djangoapps/contentstore/tests/test_course_listing.py
View file @
c930e17f
...
@@ -200,10 +200,10 @@ class TestCourseListing(ModuleStoreTestCase):
...
@@ -200,10 +200,10 @@ class TestCourseListing(ModuleStoreTestCase):
# Now count the db queries
# Now count the db queries
store
=
modulestore
()
.
_get_modulestore_by_type
(
ModuleStoreEnum
.
Type
.
mongo
)
store
=
modulestore
()
.
_get_modulestore_by_type
(
ModuleStoreEnum
.
Type
.
mongo
)
with
check_mongo_calls
(
store
.
collection
,
USER_COURSES_COUNT
):
with
check_mongo_calls
(
store
,
USER_COURSES_COUNT
):
courses_list
=
_accessible_courses_list_from_groups
(
self
.
request
)
courses_list
=
_accessible_courses_list_from_groups
(
self
.
request
)
with
check_mongo_calls
(
store
.
collection
,
1
):
with
check_mongo_calls
(
store
,
1
):
courses_list
=
_accessible_courses_list
(
self
.
request
)
courses_list
=
_accessible_courses_list
(
self
.
request
)
def
test_get_course_list_with_same_course_id
(
self
):
def
test_get_course_list_with_same_course_id
(
self
):
...
...
cms/djangoapps/contentstore/tests/test_import.py
View file @
c930e17f
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
# pylint: disable=E1101
# pylint: disable=E1101
# pylint: disable=protected-access
"""
"""
Tests for import_from_xml using the mongo modulestore.
Tests for import_from_xml using the mongo modulestore.
"""
"""
...
@@ -10,8 +11,10 @@ from django.conf import settings
...
@@ -10,8 +11,10 @@ from django.conf import settings
import
copy
import
copy
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.django
import
modulestore
from
xmodule.contentstore.django
import
contentstore
from
xmodule.contentstore.django
import
contentstore
from
xmodule.modulestore.tests.factories
import
check_exact_number_of_calls
,
check_number_of_calls
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
,
AssetLocation
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
,
AssetLocation
from
xmodule.modulestore.xml_importer
import
import_from_xml
from
xmodule.modulestore.xml_importer
import
import_from_xml
from
xmodule.exceptions
import
NotFoundError
from
xmodule.exceptions
import
NotFoundError
...
@@ -149,6 +152,21 @@ class ContentStoreImportTest(ModuleStoreTestCase):
...
@@ -149,6 +152,21 @@ class ContentStoreImportTest(ModuleStoreTestCase):
print
"course tabs = {0}"
.
format
(
course
.
tabs
)
print
"course tabs = {0}"
.
format
(
course
.
tabs
)
self
.
assertEqual
(
course
.
tabs
[
2
][
'name'
],
'Syllabus'
)
self
.
assertEqual
(
course
.
tabs
[
2
][
'name'
],
'Syllabus'
)
def
test_import_performance_mongo
(
self
):
store
=
modulestore
()
.
_get_modulestore_by_type
(
ModuleStoreEnum
.
Type
.
mongo
)
# we try to refresh the inheritance tree for each update_item in the import
with
check_exact_number_of_calls
(
store
,
store
.
refresh_cached_metadata_inheritance_tree
,
46
):
# the post-publish step loads each item in the subtree, which calls _get_cached_metadata_inheritance_tree
with
check_exact_number_of_calls
(
store
,
store
.
_get_cached_metadata_inheritance_tree
,
22
):
# with bulk-edit in progress, the inheritance tree should be recomputed only at the end of the import
# NOTE: On Jenkins, with memcache enabled, the number of calls here is only 1.
# Locally, without memcache, the number of calls is actually 2 (once more during the publish step)
with
check_number_of_calls
(
store
,
store
.
_compute_metadata_inheritance_tree
,
2
):
self
.
load_test_import_course
()
def
test_rewrite_reference_list
(
self
):
def
test_rewrite_reference_list
(
self
):
module_store
=
modulestore
()
module_store
=
modulestore
()
target_course_id
=
SlashSeparatedCourseKey
(
'testX'
,
'conditional_copy'
,
'copy_run'
)
target_course_id
=
SlashSeparatedCourseKey
(
'testX'
,
'conditional_copy'
,
'copy_run'
)
...
...
common/lib/xmodule/xmodule/modulestore/tests/factories.py
View file @
c930e17f
...
@@ -9,7 +9,7 @@ from xblock.core import XBlock
...
@@ -9,7 +9,7 @@ from xblock.core import XBlock
from
xmodule.tabs
import
StaticTab
from
xmodule.tabs
import
StaticTab
from
decorator
import
contextmanager
from
decorator
import
contextmanager
from
mock
import
Mock
,
patch
from
mock
import
Mock
,
patch
from
nose.tools
import
assert_less_equal
from
nose.tools
import
assert_less_equal
,
assert_greater_equal
class
Dummy
(
object
):
class
Dummy
(
object
):
...
@@ -220,30 +220,57 @@ class ItemFactory(XModuleFactory):
...
@@ -220,30 +220,57 @@ class ItemFactory(XModuleFactory):
@contextmanager
@contextmanager
def
check_
mongo_calls
(
mongo_store
,
max_finds
=
0
,
max_sends
=
None
):
def
check_
exact_number_of_calls
(
object_with_method
,
method
,
num_calls
,
method_name
=
None
):
"""
"""
Instruments the given store to count the number of calls to find (incl find_one) and the number
Instruments the given method on the given object to verify the number of calls to the
of calls to send_message which is for insert, update, and remove (if you provide max_sends). At the
method is exactly equal to 'num_calls'.
end of the with statement, it compares the counts to the max_finds and max_sends using a simple
"""
assertLessEqual.
with
check_number_of_calls
(
object_with_method
,
method
,
num_calls
,
num_calls
,
method_name
):
yield
:param mongo_store: the MongoModulestore or subclass to watch
:param max_finds: the maximum number of find calls to allow
@contextmanager
:param max_sends: If none, don't instrument the send calls. If non-none, count and compare to
def
check_number_of_calls
(
object_with_method
,
method
,
maximum_calls
,
minimum_calls
=
1
,
method_name
=
None
):
the given int value.
"""
Instruments the given method on the given object to verify the number of calls to the method is
less than or equal to the expected maximum_calls and greater than or equal to the expected minimum_calls.
"""
"""
method_wrap
=
Mock
(
wraps
=
method
)
wrap_patch
=
patch
.
object
(
object_with_method
,
method_name
or
method
.
__name__
,
method_wrap
)
try
:
try
:
find_wrap
=
Mock
(
wraps
=
mongo_store
.
collection
.
find
)
wrap_patch
=
patch
.
object
(
mongo_store
.
collection
,
'find'
,
find_wrap
)
wrap_patch
.
start
()
wrap_patch
.
start
()
if
max_sends
:
sends_wrap
=
Mock
(
wraps
=
mongo_store
.
database
.
connection
.
_send_message
)
sends_patch
=
patch
.
object
(
mongo_store
.
database
.
connection
,
'_send_message'
,
sends_wrap
)
sends_patch
.
start
()
yield
yield
finally
:
finally
:
wrap_patch
.
stop
()
wrap_patch
.
stop
()
if
max_sends
:
sends_patch
.
stop
()
# verify the counter actually worked by ensuring we have counted greater than (or equal to) the minimum calls
assert_less_equal
(
sends_wrap
.
call_count
,
max_sends
)
assert_greater_equal
(
method_wrap
.
call_count
,
minimum_calls
)
assert_less_equal
(
find_wrap
.
call_count
,
max_finds
)
# now verify the number of actual calls is less than (or equal to) the expected maximum
assert_less_equal
(
method_wrap
.
call_count
,
maximum_calls
)
@contextmanager
def
check_mongo_calls
(
mongo_store
,
num_finds
=
0
,
num_sends
=
None
):
"""
Instruments the given store to count the number of calls to find (incl find_one) and the number
of calls to send_message which is for insert, update, and remove (if you provide num_sends). At the
end of the with statement, it compares the counts to the num_finds and num_sends.
:param mongo_store: the MongoModulestore or subclass to watch
:param num_finds: the exact number of find calls expected
:param num_sends: If none, don't instrument the send calls. If non-none, count and compare to
the given int value.
"""
with
check_exact_number_of_calls
(
mongo_store
.
collection
,
mongo_store
.
collection
.
find
,
num_finds
):
if
num_sends
:
with
check_exact_number_of_calls
(
mongo_store
.
database
.
connection
,
mongo_store
.
database
.
connection
.
_send_message
,
# pylint: disable=protected-access
num_sends
,
):
yield
else
:
yield
common/lib/xmodule/xmodule/modulestore/tests/test_publish.py
View file @
c930e17f
...
@@ -19,23 +19,23 @@ class TestPublish(SplitWMongoCourseBoostrapper):
...
@@ -19,23 +19,23 @@ class TestPublish(SplitWMongoCourseBoostrapper):
# There are 12 created items and 7 parent updates
# There are 12 created items and 7 parent updates
# create course: finds: 1 to verify uniqueness, 1 to find parents
# create course: finds: 1 to verify uniqueness, 1 to find parents
# sends: 1 to create course, 1 to create overview
# sends: 1 to create course, 1 to create overview
with
check_mongo_calls
(
self
.
draft_mongo
,
6
,
2
):
with
check_mongo_calls
(
self
.
draft_mongo
,
5
,
2
):
super
(
TestPublish
,
self
)
.
_create_course
(
split
=
False
)
# 2 inserts (course and overview)
super
(
TestPublish
,
self
)
.
_create_course
(
split
=
False
)
# 2 inserts (course and overview)
# with bulk will delay all inheritance computations which won't be added into the mongo_calls
# with bulk will delay all inheritance computations which won't be added into the mongo_calls
with
self
.
draft_mongo
.
bulk_write_operations
(
self
.
old_course_key
):
with
self
.
draft_mongo
.
bulk_write_operations
(
self
.
old_course_key
):
# finds: 1 for parent to add child
, 1 for parent to update edit info
# finds: 1 for parent to add child
# sends: 1 for insert,
2 for parent (add child, change edit info
)
# sends: 1 for insert,
1 for parent (add child
)
with
check_mongo_calls
(
self
.
draft_mongo
,
5
,
3
):
with
check_mongo_calls
(
self
.
draft_mongo
,
1
,
2
):
self
.
_create_item
(
'chapter'
,
'Chapter1'
,
{},
{
'display_name'
:
'Chapter 1'
},
'course'
,
'runid'
,
split
=
False
)
self
.
_create_item
(
'chapter'
,
'Chapter1'
,
{},
{
'display_name'
:
'Chapter 1'
},
'course'
,
'runid'
,
split
=
False
)
with
check_mongo_calls
(
self
.
draft_mongo
,
5
,
3
):
with
check_mongo_calls
(
self
.
draft_mongo
,
2
,
2
):
self
.
_create_item
(
'chapter'
,
'Chapter2'
,
{},
{
'display_name'
:
'Chapter 2'
},
'course'
,
'runid'
,
split
=
False
)
self
.
_create_item
(
'chapter'
,
'Chapter2'
,
{},
{
'display_name'
:
'Chapter 2'
},
'course'
,
'runid'
,
split
=
False
)
# update info propagation is 2 levels. create looks for draft and then published and then creates
# update info propagation is 2 levels. create looks for draft and then published and then creates
with
check_mongo_calls
(
self
.
draft_mongo
,
16
,
8
):
with
check_mongo_calls
(
self
.
draft_mongo
,
8
,
6
):
self
.
_create_item
(
'vertical'
,
'Vert1'
,
{},
{
'display_name'
:
'Vertical 1'
},
'chapter'
,
'Chapter1'
,
split
=
False
)
self
.
_create_item
(
'vertical'
,
'Vert1'
,
{},
{
'display_name'
:
'Vertical 1'
},
'chapter'
,
'Chapter1'
,
split
=
False
)
self
.
_create_item
(
'vertical'
,
'Vert2'
,
{},
{
'display_name'
:
'Vertical 2'
},
'chapter'
,
'Chapter1'
,
split
=
False
)
self
.
_create_item
(
'vertical'
,
'Vert2'
,
{},
{
'display_name'
:
'Vertical 2'
},
'chapter'
,
'Chapter1'
,
split
=
False
)
with
check_mongo_calls
(
self
.
draft_mongo
,
36
,
36
):
with
check_mongo_calls
(
self
.
draft_mongo
,
20
,
12
):
self
.
_create_item
(
'html'
,
'Html1'
,
"<p>Goodbye</p>"
,
{
'display_name'
:
'Parented Html'
},
'vertical'
,
'Vert1'
,
split
=
False
)
self
.
_create_item
(
'html'
,
'Html1'
,
"<p>Goodbye</p>"
,
{
'display_name'
:
'Parented Html'
},
'vertical'
,
'Vert1'
,
split
=
False
)
self
.
_create_item
(
self
.
_create_item
(
'discussion'
,
'Discussion1'
,
'discussion'
,
'Discussion1'
,
...
@@ -62,7 +62,8 @@ class TestPublish(SplitWMongoCourseBoostrapper):
...
@@ -62,7 +62,8 @@ class TestPublish(SplitWMongoCourseBoostrapper):
'vertical'
,
'Vert2'
,
'vertical'
,
'Vert2'
,
split
=
False
split
=
False
)
)
with
check_mongo_calls
(
self
.
draft_mongo
,
2
,
2
):
with
check_mongo_calls
(
self
.
draft_mongo
,
0
,
2
):
# 2 finds b/c looking for non-existent parents
# 2 finds b/c looking for non-existent parents
self
.
_create_item
(
'static_tab'
,
'staticuno'
,
"<p>tab</p>"
,
{
'display_name'
:
'Tab uno'
},
None
,
None
,
split
=
False
)
self
.
_create_item
(
'static_tab'
,
'staticuno'
,
"<p>tab</p>"
,
{
'display_name'
:
'Tab uno'
},
None
,
None
,
split
=
False
)
self
.
_create_item
(
'course_info'
,
'updates'
,
"<ol><li><h2>Sep 22</h2><p>test</p></li></ol>"
,
{},
None
,
None
,
split
=
False
)
self
.
_create_item
(
'course_info'
,
'updates'
,
"<ol><li><h2>Sep 22</h2><p>test</p></li></ol>"
,
{},
None
,
None
,
split
=
False
)
...
...
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