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
525e0475
Commit
525e0475
authored
Jun 24, 2016
by
Nimisha Asthagiri
Committed by
GitHub
Jun 24, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #12857 from edx/tnl/grading-query-fixup
Grading followup
parents
10214839
a7a6fa77
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
52 additions
and
62 deletions
+52
-62
lms/djangoapps/ccx/tests/test_field_override_performance.py
+42
-55
openedx/core/lib/block_structure/block_structure.py
+10
-7
No files found.
lms/djangoapps/ccx/tests/test_field_override_performance.py
View file @
525e0475
...
...
@@ -16,6 +16,7 @@ from django.core.cache import caches
from
django.test.client
import
RequestFactory
from
django.test.utils
import
override_settings
from
nose.plugins.attrib
import
attr
from
opaque_keys.edx.keys
import
CourseKey
from
pytz
import
UTC
from
request_cache.middleware
import
RequestCache
from
student.models
import
CourseEnrollment
...
...
@@ -23,7 +24,7 @@ from student.tests.factories import UserFactory
from
xblock.core
import
XBlock
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
,
\
TEST_DATA_SPLIT_MODULESTORE
,
TEST_DATA_MONGO_MODULESTORE
from
xmodule.modulestore.tests.factories
import
check_mongo_calls
_range
,
CourseFactory
,
check_sum_of_calls
from
xmodule.modulestore.tests.factories
import
check_mongo_calls
,
CourseFactory
,
check_sum_of_calls
from
xmodule.modulestore.tests.utils
import
ProceduralCourseTestMixin
from
ccx_keys.locator
import
CCXLocator
from
lms.djangoapps.ccx.tests.factories
import
CcxFactory
...
...
@@ -125,15 +126,12 @@ class FieldOverridePerformanceTestCase(FieldOverrideTestMixin, ProceduralCourseT
self
.
student
,
course_key
)
return
CourseKey
.
from_string
(
unicode
(
course_key
))
def
grade_course
(
self
,
course
,
view_as_ccx
):
def
grade_course
(
self
,
course
_key
):
"""
Renders the progress page for the given course.
"""
course_key
=
course
.
id
if
view_as_ccx
:
course_key
=
CCXLocator
.
from_course_locator
(
course_key
,
self
.
ccx
.
id
)
return
progress
(
self
.
request
,
course_id
=
unicode
(
course_key
),
...
...
@@ -145,7 +143,7 @@ class FieldOverridePerformanceTestCase(FieldOverrideTestMixin, ProceduralCourseT
Assert that mongodb is queried ``calls`` times in the surrounded
context.
"""
return
check_mongo_calls
_range
(
max_finds
=
calls
)
return
check_mongo_calls
(
calls
)
def
assertXBlockInstantiations
(
self
,
instantiations
):
"""
...
...
@@ -156,12 +154,12 @@ class FieldOverridePerformanceTestCase(FieldOverrideTestMixin, ProceduralCourseT
def
instrument_course_progress_render
(
self
,
course_width
,
enable_ccx
,
view_as_ccx
,
default_queries
,
history_queries
,
reads
,
xblocks
sql_queries
,
mongo_reads
,
):
"""
Renders the progress page, instrumenting Mongo reads and SQL queries.
"""
self
.
setup_course
(
course_width
,
enable_ccx
,
view_as_ccx
)
course_key
=
self
.
setup_course
(
course_width
,
enable_ccx
,
view_as_ccx
)
# Switch to published-only mode to simulate the LMS
with
self
.
settings
(
MODULESTORE_BRANCH
=
'published-only'
):
...
...
@@ -170,7 +168,7 @@ class FieldOverridePerformanceTestCase(FieldOverrideTestMixin, ProceduralCourseT
caches
[
cache
]
.
clear
()
# Refill the metadata inheritance cache
get_course_in_cache
(
self
.
course
.
id
)
get_course_in_cache
(
course_key
)
# We clear the request cache to simulate a new request in the LMS.
RequestCache
.
clear_request_cache
()
...
...
@@ -179,11 +177,11 @@ class FieldOverridePerformanceTestCase(FieldOverrideTestMixin, ProceduralCourseT
# can actually take affect.
OverrideFieldData
.
provider_classes
=
None
with
self
.
assertNumQueries
(
default
_queries
,
using
=
'default'
):
with
self
.
assertNumQueries
(
history_queries
,
using
=
'student_module_history'
):
with
self
.
assertMongoCallCount
(
reads
):
with
self
.
assertXBlockInstantiations
(
xblocks
):
self
.
grade_course
(
self
.
course
,
view_as_ccx
)
with
self
.
assertNumQueries
(
sql
_queries
,
using
=
'default'
):
with
self
.
assertNumQueries
(
0
,
using
=
'student_module_history'
):
with
self
.
assertMongoCallCount
(
mongo_
reads
):
with
self
.
assertXBlockInstantiations
(
1
):
self
.
grade_course
(
course_key
)
@ddt.data
(
*
itertools
.
product
((
'no_overrides'
,
'ccx'
),
range
(
1
,
4
),
(
True
,
False
),
(
True
,
False
)))
@ddt.unpack
...
...
@@ -212,11 +210,11 @@ class FieldOverridePerformanceTestCase(FieldOverrideTestMixin, ProceduralCourseT
XBLOCK_FIELD_DATA_WRAPPERS
=
[
'lms.djangoapps.courseware.field_overrides:OverrideModulestoreFieldData.wrap'
],
MODULESTORE_FIELD_OVERRIDE_PROVIDERS
=
providers
[
overrides
],
):
default_queries
,
history_queries
,
reads
,
xblock
s
=
self
.
TEST_DATA
[
sql_queries
,
mongo_read
s
=
self
.
TEST_DATA
[
(
overrides
,
course_width
,
enable_ccx
,
view_as_ccx
)
]
self
.
instrument_course_progress_render
(
course_width
,
enable_ccx
,
view_as_ccx
,
default_queries
,
history_queries
,
reads
,
xblocks
course_width
,
enable_ccx
,
view_as_ccx
,
sql_queries
,
mongo_reads
,
)
...
...
@@ -230,28 +228,20 @@ class TestFieldOverrideMongoPerformance(FieldOverridePerformanceTestCase):
TEST_DATA
=
{
# (providers, course_width, enable_ccx, view_as_ccx): (
# # of sql queries to default,
# # sql queries to student_module_history,
# # of mongo queries,
# # of xblocks
# )
(
'no_overrides'
,
1
,
True
,
False
):
(
34
,
0
,
6
,
1
),
(
'no_overrides'
,
2
,
True
,
False
):
(
40
,
0
,
6
,
1
),
(
'no_overrides'
,
3
,
True
,
False
):
(
50
,
0
,
6
,
1
),
(
'ccx'
,
1
,
True
,
False
):
(
34
,
0
,
6
,
1
),
(
'ccx'
,
2
,
True
,
False
):
(
40
,
0
,
6
,
1
),
(
'ccx'
,
3
,
True
,
False
):
(
50
,
0
,
6
,
1
),
(
'ccx'
,
1
,
True
,
True
):
(
47
,
0
,
6
,
1
),
(
'ccx'
,
2
,
True
,
True
):
(
40
,
0
,
6
,
1
),
(
'ccx'
,
3
,
True
,
True
):
(
50
,
0
,
6
,
1
),
(
'no_overrides'
,
1
,
False
,
False
):
(
34
,
0
,
6
,
1
),
(
'no_overrides'
,
2
,
False
,
False
):
(
40
,
0
,
6
,
1
),
(
'no_overrides'
,
3
,
False
,
False
):
(
50
,
0
,
6
,
1
),
(
'ccx'
,
1
,
False
,
False
):
(
34
,
0
,
6
,
1
),
(
'ccx'
,
2
,
False
,
False
):
(
40
,
0
,
6
,
1
),
(
'ccx'
,
3
,
False
,
False
):
(
50
,
0
,
6
,
1
),
(
'ccx'
,
1
,
False
,
True
):
(
47
,
0
,
6
,
1
),
(
'ccx'
,
2
,
False
,
True
):
(
40
,
0
,
6
,
1
),
(
'ccx'
,
3
,
False
,
True
):
(
50
,
0
,
6
,
1
),
(
'no_overrides'
,
1
,
True
,
False
):
(
34
,
6
),
(
'no_overrides'
,
2
,
True
,
False
):
(
40
,
6
),
(
'no_overrides'
,
3
,
True
,
False
):
(
50
,
6
),
(
'ccx'
,
1
,
True
,
False
):
(
34
,
6
),
(
'ccx'
,
2
,
True
,
False
):
(
40
,
6
),
(
'ccx'
,
3
,
True
,
False
):
(
50
,
6
),
(
'no_overrides'
,
1
,
False
,
False
):
(
34
,
6
),
(
'no_overrides'
,
2
,
False
,
False
):
(
40
,
6
),
(
'no_overrides'
,
3
,
False
,
False
):
(
50
,
6
),
(
'ccx'
,
1
,
False
,
False
):
(
34
,
6
),
(
'ccx'
,
2
,
False
,
False
):
(
40
,
6
),
(
'ccx'
,
3
,
False
,
False
):
(
50
,
6
),
}
...
...
@@ -263,22 +253,19 @@ class TestFieldOverrideSplitPerformance(FieldOverridePerformanceTestCase):
__test__
=
True
TEST_DATA
=
{
(
'no_overrides'
,
1
,
True
,
False
):
(
34
,
0
,
4
,
1
),
(
'no_overrides'
,
2
,
True
,
False
):
(
40
,
0
,
19
,
1
),
(
'no_overrides'
,
3
,
True
,
False
):
(
50
,
0
,
84
,
1
),
(
'ccx'
,
1
,
True
,
False
):
(
34
,
0
,
4
,
1
),
(
'ccx'
,
2
,
True
,
False
):
(
40
,
0
,
19
,
1
),
(
'ccx'
,
3
,
True
,
False
):
(
50
,
0
,
84
,
1
),
(
'ccx'
,
1
,
True
,
True
):
(
35
,
0
,
5
,
6
),
(
'ccx'
,
2
,
True
,
True
):
(
41
,
0
,
20
,
47
),
(
'ccx'
,
3
,
True
,
True
):
(
51
,
0
,
85
,
202
),
(
'no_overrides'
,
1
,
False
,
False
):
(
34
,
0
,
4
,
1
),
(
'no_overrides'
,
2
,
False
,
False
):
(
40
,
0
,
19
,
1
),
(
'no_overrides'
,
3
,
False
,
False
):
(
50
,
0
,
84
,
1
),
(
'ccx'
,
1
,
False
,
False
):
(
34
,
0
,
4
,
1
),
(
'ccx'
,
2
,
False
,
False
):
(
40
,
0
,
19
,
1
),
(
'ccx'
,
3
,
False
,
False
):
(
50
,
0
,
84
,
1
),
(
'ccx'
,
1
,
False
,
True
):
(
46
,
0
,
4
,
1
),
(
'ccx'
,
2
,
False
,
True
):
(
118
,
0
,
19
,
1
),
(
'ccx'
,
3
,
False
,
True
):
(
398
,
0
,
84
,
1
),
(
'no_overrides'
,
1
,
True
,
False
):
(
34
,
3
),
(
'no_overrides'
,
2
,
True
,
False
):
(
40
,
3
),
(
'no_overrides'
,
3
,
True
,
False
):
(
50
,
3
),
(
'ccx'
,
1
,
True
,
False
):
(
34
,
3
),
(
'ccx'
,
2
,
True
,
False
):
(
40
,
3
),
(
'ccx'
,
3
,
True
,
False
):
(
50
,
3
),
(
'ccx'
,
1
,
True
,
True
):
(
35
,
3
),
(
'ccx'
,
2
,
True
,
True
):
(
41
,
3
),
(
'ccx'
,
3
,
True
,
True
):
(
51
,
3
),
(
'no_overrides'
,
1
,
False
,
False
):
(
34
,
3
),
(
'no_overrides'
,
2
,
False
,
False
):
(
40
,
3
),
(
'no_overrides'
,
3
,
False
,
False
):
(
50
,
3
),
(
'ccx'
,
1
,
False
,
False
):
(
34
,
3
),
(
'ccx'
,
2
,
False
,
False
):
(
40
,
3
),
(
'ccx'
,
3
,
False
,
False
):
(
50
,
3
),
}
openedx/core/lib/block_structure/block_structure.py
View file @
525e0475
...
...
@@ -8,7 +8,6 @@ The following internal data structures are implemented:
_BlockRelations - Data structure for a single block's relations.
_BlockData - Data structure for a single block's data.
"""
from
collections
import
defaultdict
from
logging
import
getLogger
from
openedx.core.lib.graph_traversals
import
traverse_topologically
,
traverse_post_order
...
...
@@ -58,8 +57,8 @@ class BlockStructure(object):
# Map of a block's usage key to its block relations. The
# existence of a block in the structure is determined by its
# presence in this map.
# d
efaultd
ict {UsageKey: _BlockRelations}
self
.
_block_relations
=
defaultdict
(
_BlockRelations
)
# dict {UsageKey: _BlockRelations}
self
.
_block_relations
=
{}
# Add the root block.
self
.
_add_block
(
self
.
_block_relations
,
root_block_usage_key
)
...
...
@@ -207,7 +206,7 @@ class BlockStructure(object):
# Create a new block relations map to store only those blocks
# that are still linked
pruned_block_relations
=
defaultdict
(
_BlockRelations
)
pruned_block_relations
=
{}
old_block_relations
=
self
.
_block_relations
# Build the structure from the leaves up by doing a post-order
...
...
@@ -245,7 +244,7 @@ class BlockStructure(object):
relations map.
Arguments:
block_relations (d
efaultd
ict({UsageKey: _BlockRelations})) -
block_relations (dict({UsageKey: _BlockRelations})) -
Internal map of a block's usage key to its
parents/children relations.
...
...
@@ -253,6 +252,9 @@ class BlockStructure(object):
child_key (UsageKey) - Usage key of the child block.
"""
BlockStructure
.
_add_block
(
block_relations
,
parent_key
)
BlockStructure
.
_add_block
(
block_relations
,
child_key
)
block_relations
[
child_key
]
.
parents
.
append
(
parent_key
)
block_relations
[
parent_key
]
.
children
.
append
(
child_key
)
...
...
@@ -262,14 +264,15 @@ class BlockStructure(object):
Adds the given usage_key to the given block_relations map.
Arguments:
block_relations (d
efaultd
ict({UsageKey: _BlockRelations})) -
block_relations (dict({UsageKey: _BlockRelations})) -
Internal map of a block's usage key to its
parents/children relations.
usage_key (UsageKey) - Usage key of the block that is to
be added to the given block_relations.
"""
block_relations
[
usage_key
]
=
_BlockRelations
()
if
usage_key
not
in
block_relations
:
block_relations
[
usage_key
]
=
_BlockRelations
()
class
FieldData
(
object
):
...
...
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