How to Test MongoDB and MySQL Call Counts and XBlock Instantiation Counts
An important performance measurement for code is the number of MongoDB and/or MySQL calls the code makes. Each call is likely a network round-trip in the production environment, which is relatively costly. So the number of calls should generally be minimized and tests should be written that monitors the amount of expected MongoDB / MySQL calls.
MongoDB Call Counting
There's a few Python context managers used to count MongoDB calls:
- check_mongo_calls
- check_mongo_calls_range
The context managers are part of edx-platform here:
from xmodule.modulestore.tests.factories import check_mongo_calls
Here's some code snippets which uses the context managers:
with check_mongo_calls(reads): with check_sum_of_calls(XBlock, ['__init__'], xblocks, xblocks, include_arguments=False): self.grade_course(self.course)
with check_mongo_calls_range(max_finds=max_mongo_calls, min_finds=min_mongo_calls): _course_overview_1 = CourseOverview.get_from_id(course.id)
To guarantee that no MongoDB calls are made in a section of code, use this pattern:
with check_mongo_calls(0): _course_overview_2 = CourseOverview.get_from_id(course.id)
MySQL Call Counting
MySQL queries are counted with a context manager provided by the Django framework -Â django.test.TestCase.assertNumQueries.
with self.assertNumQueries(4): outcomes.store_outcome_parameters(params, self.user, self.consumer)
To guarantee that no MySQL calls are made in a section of code, use this pattern:
with self.assertNumQueries(0): outcomes.store_outcome_parameters(params, self.user, self.consumer)
XBlock Instantiation Counting
Instantiating XBlocks can be expensive, and large numbers of instantiations can be indicative of a bad query pattern.
with check_sum_of_calls(XBlock, ['__init__'], instantiations, instantiations, include_arguments=False): self.grade_course(self.course)