Commit 90723d91 by Don Mitchell

Make unit tests work on older mongo versions

parent 01205cde
...@@ -14,7 +14,8 @@ from course_action_state.models import CourseRerunState ...@@ -14,7 +14,8 @@ from course_action_state.models import CourseRerunState
from util.date_utils import get_default_time_display from util.date_utils import get_default_time_display
from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, check_mongo_calls from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, check_mongo_calls, \
mongo_uses_error_check
from opaque_keys.edx.locator import CourseLocator from opaque_keys.edx.locator import CourseLocator
from student.tests.factories import UserFactory from student.tests.factories import UserFactory
from course_action_state.managers import CourseRerunUIStateManager from course_action_state.managers import CourseRerunUIStateManager
...@@ -330,7 +331,11 @@ class OutlinePerfTest(TestCourseOutline): ...@@ -330,7 +331,11 @@ class OutlinePerfTest(TestCourseOutline):
course = modulestore().get_course(self.course.id, depth=0) course = modulestore().get_course(self.course.id, depth=0)
return _course_outline_json(None, course) return _course_outline_json(None, course)
with check_mongo_calls(5 * num_threads, 0): if mongo_uses_error_check(modulestore()):
per_thread = 5
else:
per_thread = 4
with check_mongo_calls(per_thread * num_threads, 0):
outline_threads = [threading.Thread(target=test_client) for __ in range(num_threads)] outline_threads = [threading.Thread(target=test_client) for __ in range(num_threads)]
[thread.start() for thread in outline_threads] [thread.start() for thread in outline_threads]
# now wait until they all finish # now wait until they all finish
......
...@@ -488,6 +488,13 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase, Mongo ...@@ -488,6 +488,13 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase, Mongo
""" """
self.collection.database.connection.close() self.collection.database.connection.close()
def mongo_wire_version(self):
"""
Returns the wire version for mongo. Only used to unit tests which instrument the connection.
"""
self.database.connection._ensure_connected()
return self.database.connection.max_wire_version
def _drop_database(self): def _drop_database(self):
""" """
A destructive operation to drop the underlying database and close all connections. A destructive operation to drop the underlying database and close all connections.
...@@ -1280,7 +1287,6 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase, Mongo ...@@ -1280,7 +1287,6 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase, Mongo
{'$set': {'definition.children': []}}, {'$set': {'definition.children': []}},
multi=False, multi=False,
upsert=True, upsert=True,
safe=self.collection.safe
) )
elif ancestor_loc.category == 'course': elif ancestor_loc.category == 'course':
# once we reach the top location of the tree and if the location is not an orphan then the # once we reach the top location of the tree and if the location is not an orphan then the
......
...@@ -609,6 +609,12 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase): ...@@ -609,6 +609,12 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase):
""" """
self.db.connection.close() self.db.connection.close()
def mongo_wire_version(self):
"""
Returns the wire version for mongo. Only used to unit tests which instrument the connection.
"""
return self.db.connection.max_wire_version
def _drop_database(self): def _drop_database(self):
""" """
A destructive operation to drop the underlying database and close all connections. A destructive operation to drop the underlying database and close all connections.
......
...@@ -279,6 +279,17 @@ def check_sum_of_calls(object_, methods, maximum_calls, minimum_calls=1): ...@@ -279,6 +279,17 @@ def check_sum_of_calls(object_, methods, maximum_calls, minimum_calls=1):
assert_less_equal(call_count, maximum_calls) assert_less_equal(call_count, maximum_calls)
def mongo_uses_error_check(store):
"""
Does mongo use the error check as a separate message?
"""
if hasattr(store, 'mongo_wire_version'):
return store.mongo_wire_version() <= 1
if hasattr(store, 'modulestores'):
return any([mongo_uses_error_check(substore) for substore in store.modulestores])
return False
@contextmanager @contextmanager
def check_mongo_calls(num_finds=0, num_sends=None): def check_mongo_calls(num_finds=0, num_sends=None):
""" """
......
...@@ -31,7 +31,8 @@ from xmodule.modulestore.draft_and_published import UnsupportedRevisionError, Mo ...@@ -31,7 +31,8 @@ from xmodule.modulestore.draft_and_published import UnsupportedRevisionError, Mo
from xmodule.modulestore.exceptions import ItemNotFoundError, DuplicateCourseError, ReferentialIntegrityError, NoPathToItem from xmodule.modulestore.exceptions import ItemNotFoundError, DuplicateCourseError, ReferentialIntegrityError, NoPathToItem
from xmodule.modulestore.mixed import MixedModuleStore from xmodule.modulestore.mixed import MixedModuleStore
from xmodule.modulestore.search import path_to_location from xmodule.modulestore.search import path_to_location
from xmodule.modulestore.tests.factories import check_mongo_calls, check_exact_number_of_calls from xmodule.modulestore.tests.factories import check_mongo_calls, check_exact_number_of_calls, \
mongo_uses_error_check
from xmodule.modulestore.tests.mongo_connection import MONGO_PORT_NUM, MONGO_HOST from xmodule.modulestore.tests.mongo_connection import MONGO_PORT_NUM, MONGO_HOST
from xmodule.tests import DATA_DIR, CourseComparisonTest from xmodule.tests import DATA_DIR, CourseComparisonTest
...@@ -672,6 +673,8 @@ class TestMixedModuleStore(CourseComparisonTest): ...@@ -672,6 +673,8 @@ class TestMixedModuleStore(CourseComparisonTest):
Delete should reject on r/o db and work on r/w one Delete should reject on r/o db and work on r/w one
""" """
self.initdb(default_ms) self.initdb(default_ms)
if default_ms == 'draft' and mongo_uses_error_check(self.store):
max_find += 1
# r/o try deleting the chapter (is here to ensure it can't be deleted) # r/o try deleting the chapter (is here to ensure it can't be deleted)
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
...@@ -703,6 +706,8 @@ class TestMixedModuleStore(CourseComparisonTest): ...@@ -703,6 +706,8 @@ class TestMixedModuleStore(CourseComparisonTest):
behavioral properties which this deletion test gets at. behavioral properties which this deletion test gets at.
""" """
self.initdb(default_ms) self.initdb(default_ms)
if default_ms == 'draft' and mongo_uses_error_check(self.store):
max_find += 1
# create and delete a private vertical with private children # create and delete a private vertical with private children
private_vert = self.store.create_child( private_vert = self.store.create_child(
# don't use course_location as it may not be the repr # don't use course_location as it may not be the repr
...@@ -776,6 +781,8 @@ class TestMixedModuleStore(CourseComparisonTest): ...@@ -776,6 +781,8 @@ class TestMixedModuleStore(CourseComparisonTest):
private_leaf.display_name = 'change me' private_leaf.display_name = 'change me'
private_leaf = self.store.update_item(private_leaf, self.user_id) private_leaf = self.store.update_item(private_leaf, self.user_id)
# test succeeds if delete succeeds w/o error # test succeeds if delete succeeds w/o error
if default_ms == 'draft' and mongo_uses_error_check(self.store):
max_find += 1
with check_mongo_calls(max_find, max_send): with check_mongo_calls(max_find, max_send):
self.store.delete_item(private_leaf.location, self.user_id) self.store.delete_item(private_leaf.location, self.user_id)
...@@ -1310,6 +1317,8 @@ class TestMixedModuleStore(CourseComparisonTest): ...@@ -1310,6 +1317,8 @@ class TestMixedModuleStore(CourseComparisonTest):
Test calling unpublish Test calling unpublish
""" """
self.initdb(default_ms) self.initdb(default_ms)
if default_ms == 'draft' and mongo_uses_error_check(self.store):
max_find += 1
self._create_block_hierarchy() self._create_block_hierarchy()
# publish # publish
......
...@@ -3,7 +3,7 @@ Test the publish code (mostly testing that publishing doesn't result in orphans) ...@@ -3,7 +3,7 @@ Test the publish code (mostly testing that publishing doesn't result in orphans)
""" """
from xmodule.modulestore.exceptions import ItemNotFoundError from xmodule.modulestore.exceptions import ItemNotFoundError
from xmodule.modulestore.tests.test_split_w_old_mongo import SplitWMongoCourseBoostrapper from xmodule.modulestore.tests.test_split_w_old_mongo import SplitWMongoCourseBoostrapper
from xmodule.modulestore.tests.factories import check_mongo_calls from xmodule.modulestore.tests.factories import check_mongo_calls, mongo_uses_error_check
from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore import ModuleStoreEnum
...@@ -103,7 +103,11 @@ class TestPublish(SplitWMongoCourseBoostrapper): ...@@ -103,7 +103,11 @@ class TestPublish(SplitWMongoCourseBoostrapper):
# delete the subtree of drafts (1 call), # delete the subtree of drafts (1 call),
# update the published version of each node in subtree (4 calls), # update the published version of each node in subtree (4 calls),
# update the ancestors up to course (2 calls) # update the ancestors up to course (2 calls)
with check_mongo_calls(19, 7): if mongo_uses_error_check(self.draft_mongo):
max_find = 20
else:
max_find = 19
with check_mongo_calls(max_find, 7):
self.draft_mongo.publish(item.location, self.user_id) self.draft_mongo.publish(item.location, self.user_id)
# verify status # verify status
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment