diff --git a/lms/djangoapps/grades/models.py b/lms/djangoapps/grades/models.py index 2a4b82ca3d..fcf8c6da23 100644 --- a/lms/djangoapps/grades/models.py +++ b/lms/djangoapps/grades/models.py @@ -20,6 +20,7 @@ from django.db import models from django.utils.timezone import now from eventtracking import tracker from model_utils.models import TimeStampedModel +from track import contexts from track.event_transaction_utils import get_event_transaction_id, get_event_transaction_type from coursewarehistoryextended.fields import UnsignedBigIntAutoField @@ -433,24 +434,28 @@ class PersistentSubsectionGrade(TimeStampedModel): Emits an edx.grades.subsection.grade_calculated event with data from the passed grade. """ - tracker.emit( - u'edx.grades.subsection.grade_calculated', - { - 'user_id': unicode(grade.user_id), - 'course_id': unicode(grade.course_id), - 'block_id': unicode(grade.usage_key), - 'course_version': unicode(grade.course_version), - 'weighted_total_earned': grade.earned_all, - 'weighted_total_possible': grade.possible_all, - 'weighted_graded_earned': grade.earned_graded, - 'weighted_graded_possible': grade.possible_graded, - 'first_attempted': unicode(grade.first_attempted), - 'subtree_edited_timestamp': unicode(grade.subtree_edited_timestamp), - 'event_transaction_id': unicode(get_event_transaction_id()), - 'event_transaction_type': unicode(get_event_transaction_type()), - 'visible_blocks_hash': unicode(grade.visible_blocks_id), - } - ) + # TODO: remove this context manager after completion of AN-6134 + event_name = u'edx.grades.subsection.grade_calculated' + context = contexts.course_context_from_course_id(grade.course_id) + with tracker.get_tracker().context(event_name, context): + tracker.emit( + event_name, + { + 'user_id': unicode(grade.user_id), + 'course_id': unicode(grade.course_id), + 'block_id': unicode(grade.usage_key), + 'course_version': unicode(grade.course_version), + 'weighted_total_earned': grade.earned_all, + 'weighted_total_possible': grade.possible_all, + 'weighted_graded_earned': grade.earned_graded, + 'weighted_graded_possible': grade.possible_graded, + 'first_attempted': unicode(grade.first_attempted), + 'subtree_edited_timestamp': unicode(grade.subtree_edited_timestamp), + 'event_transaction_id': unicode(get_event_transaction_id()), + 'event_transaction_type': unicode(get_event_transaction_type()), + 'visible_blocks_hash': unicode(grade.visible_blocks_id), + } + ) class PersistentCourseGrade(TimeStampedModel): @@ -543,17 +548,21 @@ class PersistentCourseGrade(TimeStampedModel): Emits an edx.grades.course.grade_calculated event with data from the passed grade. """ - tracker.emit( - u'edx.grades.course.grade_calculated', - { - 'user_id': unicode(grade.user_id), - 'course_id': unicode(grade.course_id), - 'course_version': unicode(grade.course_version), - 'percent_grade': grade.percent_grade, - 'letter_grade': unicode(grade.letter_grade), - 'course_edited_timestamp': unicode(grade.course_edited_timestamp), - 'event_transaction_id': unicode(get_event_transaction_id()), - 'event_transaction_type': unicode(get_event_transaction_type()), - 'grading_policy_hash': unicode(grade.grading_policy_hash), - } - ) + # TODO: remove this context manager after completion of AN-6134 + event_name = u'edx.grades.course.grade_calculated' + context = contexts.course_context_from_course_id(grade.course_id) + with tracker.get_tracker().context(event_name, context): + tracker.emit( + event_name, + { + 'user_id': unicode(grade.user_id), + 'course_id': unicode(grade.course_id), + 'course_version': unicode(grade.course_version), + 'percent_grade': grade.percent_grade, + 'letter_grade': unicode(grade.letter_grade), + 'course_edited_timestamp': unicode(grade.course_edited_timestamp), + 'event_transaction_id': unicode(get_event_transaction_id()), + 'event_transaction_type': unicode(get_event_transaction_type()), + 'grading_policy_hash': unicode(grade.grading_policy_hash), + } + ) diff --git a/lms/djangoapps/grades/tests/integration/test_events.py b/lms/djangoapps/grades/tests/integration/test_events.py index 3c579f3fb9..488bda27cb 100644 --- a/lms/djangoapps/grades/tests/integration/test_events.py +++ b/lms/djangoapps/grades/tests/integration/test_events.py @@ -80,8 +80,8 @@ class GradesEventIntegrationTest(ProblemSubmissionTestMixin, SharedModuleStoreTe self.submit_question_answer('p1', {'2_1': 'choice_choice_2'}) # check logging to make sure id's are tracked correctly across events - event_transaction_id = handlers_tracker.method_calls[0][1][1]['event_transaction_id'] - for call in models_tracker.method_calls: + event_transaction_id = handlers_tracker.emit.mock_calls[0][1][1]['event_transaction_id'] + for call in models_tracker.emit.mock_calls: self.assertEqual(event_transaction_id, call[1][1]['event_transaction_id']) self.assertEqual(unicode(SUBMITTED_TYPE), call[1][1]['event_transaction_type']) @@ -123,7 +123,7 @@ class GradesEventIntegrationTest(ProblemSubmissionTestMixin, SharedModuleStoreTe event_transaction_id = enrollment_tracker.method_calls[0][1][1]['event_transaction_id'] # make sure the id is propagated throughout the event flow - for call in models_tracker.method_calls: + for call in models_tracker.emit.mock_calls: self.assertEqual(event_transaction_id, call[1][1]['event_transaction_id']) self.assertEqual(unicode(STATE_DELETED_TYPE), call[1][1]['event_transaction_type']) @@ -188,13 +188,23 @@ class GradesEventIntegrationTest(ProblemSubmissionTestMixin, SharedModuleStoreTe ) # check logging to make sure id's are tracked correctly across # events - event_transaction_id = instructor_task_tracker.method_calls[0][1][1]['event_transaction_id'] - + event_transaction_id = instructor_task_tracker.emit.mock_calls[0][1][1]['event_transaction_id'] + self.assertEqual( + instructor_task_tracker.get_tracker().context.call_args[0], + ('edx.grades.problem.rescored', {'course_id': unicode(self.course.id), 'org_id': unicode(self.course.org)}) + ) # make sure the id is propagated throughout the event flow - for call in models_tracker.method_calls: + for call in models_tracker.emit.mock_calls: self.assertEqual(event_transaction_id, call[1][1]['event_transaction_id']) self.assertEqual(unicode(RESCORE_TYPE), call[1][1]['event_transaction_type']) + # make sure the models calls have re-added the course id to the context + for args in models_tracker.get_tracker().context.call_args_list: + self.assertEqual( + args[0][1], + {'course_id': unicode(self.course.id), 'org_id': unicode(self.course.org)} + ) + handlers_tracker.assert_not_called() instructor_task_tracker.emit.assert_called_with( diff --git a/lms/djangoapps/instructor_task/tasks_helper.py b/lms/djangoapps/instructor_task/tasks_helper.py index c29ce5f0fd..95c8b76d1f 100644 --- a/lms/djangoapps/instructor_task/tasks_helper.py +++ b/lms/djangoapps/instructor_task/tasks_helper.py @@ -28,6 +28,7 @@ from lms.djangoapps.instructor.paidcourse_enrollment_report import PaidCourseEnr from lms.djangoapps.teams.models import CourseTeamMembership from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification from pytz import UTC +from track import contexts from xmodule.modulestore.django import modulestore from xmodule.split_test_module import get_split_user_partitions @@ -573,20 +574,24 @@ def rescore_problem_module_state(xmodule_instance_args, module_descriptor, stude result['new_raw_possible'], module_descriptor.weight, ) - tracker.emit( - unicode(GRADES_RESCORE_EVENT_TYPE), - { - 'course_id': unicode(course_id), - 'user_id': unicode(student.id), - 'problem_id': unicode(usage_key), - 'new_weighted_earned': new_weighted_earned, - 'new_weighted_possible': new_weighted_possible, - 'only_if_higher': task_input['only_if_higher'], - 'instructor_id': unicode(xmodule_instance_args['request_info']['user_id']), - 'event_transaction_id': unicode(event_transaction_id), - 'event_transaction_type': unicode(GRADES_RESCORE_EVENT_TYPE), - } - ) + + # TODO: remove this context manager after completion of AN-6134 + context = contexts.course_context_from_course_id(course_id) + with tracker.get_tracker().context(GRADES_RESCORE_EVENT_TYPE, context): + tracker.emit( + unicode(GRADES_RESCORE_EVENT_TYPE), + { + 'course_id': unicode(course_id), + 'user_id': unicode(student.id), + 'problem_id': unicode(usage_key), + 'new_weighted_earned': new_weighted_earned, + 'new_weighted_possible': new_weighted_possible, + 'only_if_higher': task_input['only_if_higher'], + 'instructor_id': unicode(xmodule_instance_args['request_info']['user_id']), + 'event_transaction_id': unicode(event_transaction_id), + 'event_transaction_type': unicode(GRADES_RESCORE_EVENT_TYPE), + } + ) return UPDATE_STATUS_SUCCEEDED