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
3546c261
Commit
3546c261
authored
Jan 30, 2017
by
Eric Fischer
Committed by
GitHub
Jan 30, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #14410 from edx/efischer/tnl-6408
Allow null course_edited_timestamp
parents
f3085378
6f838319
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
47 additions
and
15 deletions
+47
-15
lms/djangoapps/grades/migrations/0011_null_edited_time.py
+29
-0
lms/djangoapps/grades/models.py
+3
-3
lms/djangoapps/grades/new/subsection_grade.py
+2
-2
lms/djangoapps/grades/signals/handlers.py
+3
-2
lms/djangoapps/grades/tasks.py
+1
-0
lms/djangoapps/grades/tests/test_models.py
+7
-6
lms/djangoapps/grades/tests/test_tasks.py
+2
-2
No files found.
lms/djangoapps/grades/migrations/0011_null_edited_time.py
0 → 100644
View file @
3546c261
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
migrations
,
models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'grades'
,
'0010_auto_20170112_1156'
),
]
operations
=
[
migrations
.
AlterField
(
model_name
=
'persistentcoursegrade'
,
name
=
'course_edited_timestamp'
,
field
=
models
.
DateTimeField
(
null
=
True
,
verbose_name
=
'Last content edit timestamp'
,
blank
=
True
),
),
migrations
.
AlterField
(
model_name
=
'persistentsubsectiongrade'
,
name
=
'course_version'
,
field
=
models
.
CharField
(
max_length
=
255
,
verbose_name
=
'Guid of latest course version'
,
blank
=
True
),
),
migrations
.
AlterField
(
model_name
=
'persistentsubsectiongrade'
,
name
=
'subtree_edited_timestamp'
,
field
=
models
.
DateTimeField
(
null
=
True
,
verbose_name
=
'Last content edit timestamp'
,
blank
=
True
),
),
]
lms/djangoapps/grades/models.py
View file @
3546c261
...
...
@@ -277,8 +277,8 @@ class PersistentSubsectionGrade(DeleteGradesMixin, TimeStampedModel):
usage_key
=
UsageKeyField
(
blank
=
False
,
max_length
=
255
)
# Information relating to the state of content when grade was calculated
subtree_edited_timestamp
=
models
.
DateTimeField
(
'last content edit timestamp'
,
blank
=
Fals
e
)
course_version
=
models
.
CharField
(
'g
uid of latest course version'
,
blank
=
True
,
max_length
=
255
)
subtree_edited_timestamp
=
models
.
DateTimeField
(
u'Last content edit timestamp'
,
blank
=
True
,
null
=
Tru
e
)
course_version
=
models
.
CharField
(
u'G
uid of latest course version'
,
blank
=
True
,
max_length
=
255
)
# earned/possible refers to the number of points achieved and available to achieve.
# graded refers to the subset of all problems that are marked as being graded.
...
...
@@ -529,7 +529,7 @@ class PersistentCourseGrade(DeleteGradesMixin, TimeStampedModel):
course_id
=
CourseKeyField
(
blank
=
False
,
max_length
=
255
)
# Information relating to the state of content when grade was calculated
course_edited_timestamp
=
models
.
DateTimeField
(
u'Last content edit timestamp'
,
blank
=
Fals
e
)
course_edited_timestamp
=
models
.
DateTimeField
(
u'Last content edit timestamp'
,
blank
=
True
,
null
=
Tru
e
)
course_version
=
models
.
CharField
(
u'Course content version identifier'
,
blank
=
True
,
max_length
=
255
)
grading_policy_hash
=
models
.
CharField
(
u'Hash of grading policy'
,
blank
=
False
,
max_length
=
255
)
...
...
lms/djangoapps/grades/new/subsection_grade.py
View file @
3546c261
...
...
@@ -32,7 +32,7 @@ class SubsectionGrade(object):
self
.
graded
=
getattr
(
subsection
,
'graded'
,
False
)
self
.
course_version
=
getattr
(
subsection
,
'course_version'
,
None
)
self
.
subtree_edited_timestamp
=
subsection
.
subtree_edited_on
self
.
subtree_edited_timestamp
=
getattr
(
subsection
,
'subtree_edited_on'
,
None
)
self
.
graded_total
=
None
# aggregated grade for all graded problems
self
.
all_total
=
None
# aggregated grade for all problems, regardless of whether they are graded
...
...
@@ -341,6 +341,6 @@ class SubsectionGradeFactory(object):
log_statement
,
self
.
course
.
id
,
getattr
(
subsection
,
'course_version'
,
None
),
subsection
.
subtree_edited_on
,
getattr
(
subsection
,
'subtree_edited_on'
,
None
)
,
self
.
student
.
id
,
))
lms/djangoapps/grades/signals/handlers.py
View file @
3546c261
...
...
@@ -27,7 +27,7 @@ from .signals import (
from
..constants
import
ScoreDatabaseTableEnum
from
..new.course_grade
import
CourseGradeFactory
from
..scores
import
weighted_score
from
..tasks
import
recalculate_subsection_grade_v3
from
..tasks
import
recalculate_subsection_grade_v3
,
RECALCULATE_GRADE_DELAY
log
=
getLogger
(
__name__
)
...
...
@@ -191,7 +191,8 @@ def enqueue_subsection_update(sender, **kwargs): # pylint: disable=unused-argum
event_transaction_id
=
unicode
(
get_event_transaction_id
()),
event_transaction_type
=
unicode
(
get_event_transaction_type
()),
score_db_table
=
kwargs
[
'score_db_table'
],
)
),
countdown
=
RECALCULATE_GRADE_DELAY
,
)
log
.
info
(
u'Grades: Request async calculation of subsection grades with args: {}. Task [{}]'
.
format
(
...
...
lms/djangoapps/grades/tasks.py
View file @
3546c261
...
...
@@ -33,6 +33,7 @@ from .transformer import GradesTransformer
log
=
getLogger
(
__name__
)
KNOWN_RETRY_ERRORS
=
(
DatabaseError
,
ValidationError
)
# Errors we expect occasionally, should be resolved on retry
RECALCULATE_GRADE_DELAY
=
2
# in seconds, to prevent excessive _has_db_updated failures. See TNL-6424.
@task
(
bind
=
True
,
base
=
PersistOnFailureTask
,
default_retry_delay
=
30
,
routing_key
=
settings
.
RECALCULATE_GRADES_ROUTING_KEY
)
...
...
lms/djangoapps/grades/tests/test_models.py
View file @
3546c261
...
...
@@ -231,14 +231,14 @@ class PersistentSubsectionGradeTest(GradesModelTestCase):
with
self
.
assertRaises
(
ValidationError
):
PersistentSubsectionGrade
.
create_grade
(
**
self
.
params
)
def
test_optional_fields
(
self
):
del
self
.
params
[
"course_version"
]
@ddt.data
(
'course_version'
,
'subtree_edited_timestamp'
)
def
test_optional_fields
(
self
,
field
):
del
self
.
params
[
field
]
PersistentSubsectionGrade
.
create_grade
(
**
self
.
params
)
@ddt.data
(
(
"user_id"
,
ValidationError
),
(
"usage_key"
,
KeyError
),
(
"subtree_edited_timestamp"
,
ValidationError
),
(
"earned_all"
,
ValidationError
),
(
"possible_all"
,
ValidationError
),
(
"earned_graded"
,
ValidationError
),
...
...
@@ -427,10 +427,11 @@ class PersistentCourseGradesTest(GradesModelTestCase):
self
.
assertIsInstance
(
created_grade
.
passed_timestamp
,
datetime
)
self
.
assertEqual
(
created_grade
,
read_grade
)
def
test_course_version_optional
(
self
):
del
self
.
params
[
"course_version"
]
@ddt.data
(
'course_version'
,
'course_edited_timestamp'
)
def
test_optional_fields
(
self
,
field
):
del
self
.
params
[
field
]
grade
=
PersistentCourseGrade
.
update_or_create_course_grade
(
**
self
.
params
)
self
.
assert
Equal
(
""
,
grade
.
course_version
)
self
.
assert
False
(
getattr
(
grade
,
field
)
)
@ddt.data
(
(
"percent_grade"
,
"Not a float at all"
,
ValueError
),
...
...
lms/djangoapps/grades/tests/test_tasks.py
View file @
3546c261
...
...
@@ -27,7 +27,7 @@ from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, chec
from
lms.djangoapps.grades.config.models
import
PersistentGradesEnabledFlag
from
lms.djangoapps.grades.constants
import
ScoreDatabaseTableEnum
from
lms.djangoapps.grades.signals.signals
import
PROBLEM_WEIGHTED_SCORE_CHANGED
from
lms.djangoapps.grades.tasks
import
recalculate_subsection_grade_v3
from
lms.djangoapps.grades.tasks
import
recalculate_subsection_grade_v3
,
RECALCULATE_GRADE_DELAY
@patch.dict
(
settings
.
FEATURES
,
{
'PERSISTENT_GRADES_ENABLED_FOR_ALL_TESTS'
:
False
})
...
...
@@ -114,7 +114,7 @@ class RecalculateSubsectionGradeTest(ModuleStoreTestCase):
return_value
=
None
)
as
mock_task_apply
:
PROBLEM_WEIGHTED_SCORE_CHANGED
.
send
(
sender
=
None
,
**
send_args
)
mock_task_apply
.
assert_called_once_with
(
kwargs
=
local_task_args
)
mock_task_apply
.
assert_called_once_with
(
countdown
=
RECALCULATE_GRADE_DELAY
,
kwargs
=
local_task_args
)
@patch
(
'lms.djangoapps.grades.signals.signals.SUBSECTION_SCORE_CHANGED.send'
)
def
test_triggers_subsection_score_signal
(
self
,
mock_subsection_signal
):
...
...
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