Merge pull request #18771 from edx/youngstrom/fix-xdist-test-errors
Fix commonlib-unit test collection errors in xdist
This commit is contained in:
@@ -93,6 +93,10 @@ class TestMongoAssetMetadataStorage(TestCase):
|
||||
Tests for storing/querying course asset metadata.
|
||||
"""
|
||||
shard = 1
|
||||
XML_MODULESTORE_MAP = {
|
||||
'XML_MODULESTORE_BUILDER': XmlModulestoreBuilder(),
|
||||
'MIXED_MODULESTORE_BUILDER': MixedModulestoreBuilder([('xml', XmlModulestoreBuilder())])
|
||||
}
|
||||
|
||||
def setUp(self):
|
||||
super(TestMongoAssetMetadataStorage, self).setUp()
|
||||
@@ -641,11 +645,12 @@ class TestMongoAssetMetadataStorage(TestCase):
|
||||
)
|
||||
self.assertEquals(len(asset_page), 2)
|
||||
|
||||
@ddt.data(XmlModulestoreBuilder(), MixedModulestoreBuilder([('xml', XmlModulestoreBuilder())]))
|
||||
def test_xml_not_yet_implemented(self, storebuilder):
|
||||
@ddt.data('XML_MODULESTORE_BUILDER', 'MIXED_MODULESTORE_BUILDER')
|
||||
def test_xml_not_yet_implemented(self, storebuilderName):
|
||||
"""
|
||||
Test coverage which shows that for now xml read operations are not implemented
|
||||
"""
|
||||
storebuilder = self.XML_MODULESTORE_MAP[storebuilderName]
|
||||
with storebuilder.build(contentstore=None) as (__, store):
|
||||
course_key = store.make_course_key("org", "course", "run")
|
||||
asset_key = course_key.make_asset_key('asset', 'foo.jpg')
|
||||
|
||||
@@ -13,6 +13,14 @@ from xmodule.modulestore.split_mongo.mongo_connection import MongoConnection
|
||||
from opaque_keys.edx.locator import CourseLocator
|
||||
|
||||
|
||||
VERSION_GUID_DICT = {
|
||||
'SAMPLE_VERSION_GUID': 'deadbeef1234' * 2,
|
||||
'SAMPLE_UNICODE_VERSION_GUID': u'deadbeef1234' * 2,
|
||||
'BSON_OBJECTID': ObjectId()
|
||||
}
|
||||
SAMPLE_GUIDS_LIST = ['SAMPLE_VERSION_GUID', 'SAMPLE_UNICODE_VERSION_GUID', 'BSON_OBJECTID']
|
||||
|
||||
|
||||
class TestBulkWriteMixin(unittest.TestCase):
|
||||
shard = 2
|
||||
|
||||
@@ -58,10 +66,11 @@ class TestBulkWriteMixinClosed(TestBulkWriteMixin):
|
||||
"""
|
||||
shard = 2
|
||||
|
||||
@ddt.data('deadbeef1234' * 2, u'deadbeef1234' * 2, ObjectId())
|
||||
def test_no_bulk_read_structure(self, version_guid):
|
||||
@ddt.data(*SAMPLE_GUIDS_LIST)
|
||||
def test_no_bulk_read_structure(self, version_guid_name):
|
||||
# Reading a structure when no bulk operation is active should just call
|
||||
# through to the db_connection
|
||||
version_guid = VERSION_GUID_DICT[version_guid_name]
|
||||
result = self.bulk.get_structure(self.course_key, version_guid)
|
||||
self.assertConnCalls(
|
||||
call.get_structure(self.course_key.as_object_id(version_guid), self.course_key)
|
||||
@@ -77,10 +86,11 @@ class TestBulkWriteMixinClosed(TestBulkWriteMixin):
|
||||
self.assertConnCalls(call.insert_structure(self.structure, self.course_key))
|
||||
self.clear_cache.assert_called_once_with(self.structure['_id'])
|
||||
|
||||
@ddt.data('deadbeef1234' * 2, u'deadbeef1234' * 2, ObjectId())
|
||||
def test_no_bulk_read_definition(self, version_guid):
|
||||
@ddt.data(*SAMPLE_GUIDS_LIST)
|
||||
def test_no_bulk_read_definition(self, version_guid_name):
|
||||
# Reading a definition when no bulk operation is active should just call
|
||||
# through to the db_connection
|
||||
version_guid = VERSION_GUID_DICT[version_guid_name]
|
||||
result = self.bulk.get_definition(self.course_key, version_guid)
|
||||
self.assertConnCalls(
|
||||
call.get_definition(
|
||||
@@ -584,38 +594,42 @@ class TestBulkWriteMixinOpen(TestBulkWriteMixin):
|
||||
super(TestBulkWriteMixinOpen, self).setUp()
|
||||
self.bulk._begin_bulk_operation(self.course_key)
|
||||
|
||||
@ddt.data('deadbeef1234' * 2, u'deadbeef1234' * 2, ObjectId())
|
||||
def test_read_structure_without_write_from_db(self, version_guid):
|
||||
@ddt.data(*SAMPLE_GUIDS_LIST)
|
||||
def test_read_structure_without_write_from_db(self, version_guid_name):
|
||||
# Reading a structure before it's been written (while in bulk operation mode)
|
||||
# returns the structure from the database
|
||||
version_guid = VERSION_GUID_DICT[version_guid_name]
|
||||
result = self.bulk.get_structure(self.course_key, version_guid)
|
||||
self.assertEquals(self.conn.get_structure.call_count, 1)
|
||||
self.assertEqual(result, self.conn.get_structure.return_value)
|
||||
self.assertCacheNotCleared()
|
||||
|
||||
@ddt.data('deadbeef1234' * 2, u'deadbeef1234' * 2, ObjectId())
|
||||
def test_read_structure_without_write_only_reads_once(self, version_guid):
|
||||
@ddt.data(*SAMPLE_GUIDS_LIST)
|
||||
def test_read_structure_without_write_only_reads_once(self, version_guid_name):
|
||||
# Reading the same structure multiple times shouldn't hit the database
|
||||
# more than once
|
||||
version_guid = VERSION_GUID_DICT[version_guid_name]
|
||||
for _ in xrange(2):
|
||||
result = self.bulk.get_structure(self.course_key, version_guid)
|
||||
self.assertEquals(self.conn.get_structure.call_count, 1)
|
||||
self.assertEqual(result, self.conn.get_structure.return_value)
|
||||
self.assertCacheNotCleared()
|
||||
|
||||
@ddt.data('deadbeef1234' * 2, u'deadbeef1234' * 2, ObjectId())
|
||||
def test_read_structure_after_write_no_db(self, version_guid):
|
||||
@ddt.data(*SAMPLE_GUIDS_LIST)
|
||||
def test_read_structure_after_write_no_db(self, version_guid_name):
|
||||
# Reading a structure that's already been written shouldn't hit the db at all
|
||||
version_guid = VERSION_GUID_DICT[version_guid_name]
|
||||
self.structure['_id'] = version_guid
|
||||
self.bulk.update_structure(self.course_key, self.structure)
|
||||
result = self.bulk.get_structure(self.course_key, version_guid)
|
||||
self.assertEquals(self.conn.get_structure.call_count, 0)
|
||||
self.assertEqual(result, self.structure)
|
||||
|
||||
@ddt.data('deadbeef1234' * 2, u'deadbeef1234' * 2, ObjectId())
|
||||
def test_read_structure_after_write_after_read(self, version_guid):
|
||||
@ddt.data(*SAMPLE_GUIDS_LIST)
|
||||
def test_read_structure_after_write_after_read(self, version_guid_name):
|
||||
# Reading a structure that's been updated after being pulled from the db should
|
||||
# still get the updated value
|
||||
version_guid = VERSION_GUID_DICT[version_guid_name]
|
||||
self.structure['_id'] = version_guid
|
||||
self.bulk.get_structure(self.course_key, version_guid)
|
||||
self.bulk.update_structure(self.course_key, self.structure)
|
||||
@@ -623,38 +637,42 @@ class TestBulkWriteMixinOpen(TestBulkWriteMixin):
|
||||
self.assertEquals(self.conn.get_structure.call_count, 1)
|
||||
self.assertEqual(result, self.structure)
|
||||
|
||||
@ddt.data('deadbeef1234' * 2, u'deadbeef1234' * 2, ObjectId())
|
||||
def test_read_definition_without_write_from_db(self, version_guid):
|
||||
@ddt.data(*SAMPLE_GUIDS_LIST)
|
||||
def test_read_definition_without_write_from_db(self, version_guid_name):
|
||||
# Reading a definition before it's been written (while in bulk operation mode)
|
||||
# returns the definition from the database
|
||||
version_guid = VERSION_GUID_DICT[version_guid_name]
|
||||
result = self.bulk.get_definition(self.course_key, version_guid)
|
||||
self.assertEquals(self.conn.get_definition.call_count, 1)
|
||||
self.assertEqual(result, self.conn.get_definition.return_value)
|
||||
self.assertCacheNotCleared()
|
||||
|
||||
@ddt.data('deadbeef1234' * 2, u'deadbeef1234' * 2, ObjectId())
|
||||
def test_read_definition_without_write_only_reads_once(self, version_guid):
|
||||
@ddt.data(*SAMPLE_GUIDS_LIST)
|
||||
def test_read_definition_without_write_only_reads_once(self, version_guid_name):
|
||||
# Reading the same definition multiple times shouldn't hit the database
|
||||
# more than once
|
||||
version_guid = VERSION_GUID_DICT[version_guid_name]
|
||||
for _ in xrange(2):
|
||||
result = self.bulk.get_definition(self.course_key, version_guid)
|
||||
self.assertEquals(self.conn.get_definition.call_count, 1)
|
||||
self.assertEqual(result, self.conn.get_definition.return_value)
|
||||
self.assertCacheNotCleared()
|
||||
|
||||
@ddt.data('deadbeef1234' * 2, u'deadbeef1234' * 2, ObjectId())
|
||||
def test_read_definition_after_write_no_db(self, version_guid):
|
||||
@ddt.data(*SAMPLE_GUIDS_LIST)
|
||||
def test_read_definition_after_write_no_db(self, version_guid_name):
|
||||
# Reading a definition that's already been written shouldn't hit the db at all
|
||||
version_guid = VERSION_GUID_DICT[version_guid_name]
|
||||
self.definition['_id'] = version_guid
|
||||
self.bulk.update_definition(self.course_key, self.definition)
|
||||
result = self.bulk.get_definition(self.course_key, version_guid)
|
||||
self.assertEquals(self.conn.get_definition.call_count, 0)
|
||||
self.assertEqual(result, self.definition)
|
||||
|
||||
@ddt.data('deadbeef1234' * 2, u'deadbeef1234' * 2, ObjectId())
|
||||
def test_read_definition_after_write_after_read(self, version_guid):
|
||||
@ddt.data(*SAMPLE_GUIDS_LIST)
|
||||
def test_read_definition_after_write_after_read(self, version_guid_name):
|
||||
# Reading a definition that's been updated after being pulled from the db should
|
||||
# still get the updated value
|
||||
version_guid = VERSION_GUID_DICT[version_guid_name]
|
||||
self.definition['_id'] = version_guid
|
||||
self.bulk.get_definition(self.course_key, version_guid)
|
||||
self.bulk.update_definition(self.course_key, self.definition)
|
||||
|
||||
@@ -52,22 +52,21 @@ class TestUtils(unittest.TestCase):
|
||||
shard = 2
|
||||
|
||||
ONLY_ROOTS = [
|
||||
draft_node_constructor(Mock(), 'url1', 'vertical'),
|
||||
draft_node_constructor(Mock(), 'url2', 'sequential'),
|
||||
('url1', 'vertical'),
|
||||
('url2', 'sequential'),
|
||||
]
|
||||
ONLY_ROOTS_URLS = ['url1', 'url2']
|
||||
|
||||
SOME_TREES = [
|
||||
draft_node_constructor(Mock(), 'child_1', 'vertical_1'),
|
||||
draft_node_constructor(Mock(), 'child_2', 'vertical_1'),
|
||||
draft_node_constructor(Mock(), 'vertical_1', 'sequential_1'),
|
||||
('child_1', 'vertical_1'),
|
||||
('child_2', 'vertical_1'),
|
||||
('vertical_1', 'sequential_1'),
|
||||
|
||||
draft_node_constructor(Mock(), 'child_3', 'vertical_2'),
|
||||
draft_node_constructor(Mock(), 'child_4', 'vertical_2'),
|
||||
draft_node_constructor(Mock(), 'vertical_2', 'grandparent_vertical'),
|
||||
draft_node_constructor(Mock(), 'grandparent_vertical', 'great_grandparent_vertical'),
|
||||
('child_3', 'vertical_2'),
|
||||
('child_4', 'vertical_2'),
|
||||
('vertical_2', 'grandparent_vertical'),
|
||||
('grandparent_vertical', 'great_grandparent_vertical'),
|
||||
]
|
||||
|
||||
SOME_TREES_ROOTS_URLS = ['vertical_1', 'grandparent_vertical']
|
||||
|
||||
@ddt.data(
|
||||
@@ -75,8 +74,11 @@ class TestUtils(unittest.TestCase):
|
||||
(SOME_TREES, SOME_TREES_ROOTS_URLS),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_get_draft_subtree_roots(self, module_nodes, expected_roots_urls):
|
||||
def test_get_draft_subtree_roots(self, node_arguments_list, expected_roots_urls):
|
||||
"""tests for get_draft_subtree_roots"""
|
||||
module_nodes = []
|
||||
for node_args in node_arguments_list:
|
||||
module_nodes.append(draft_node_constructor(Mock(), node_args[0], node_args[1]))
|
||||
subtree_roots_urls = [root.url for root in get_draft_subtree_roots(module_nodes)]
|
||||
# check that we return the expected urls
|
||||
self.assertEqual(set(subtree_roots_urls), set(expected_roots_urls))
|
||||
|
||||
@@ -2,6 +2,10 @@ import ddt
|
||||
import itertools
|
||||
from xmodule.tests import BulkAssertionTest, BulkAssertionError
|
||||
|
||||
ASSERTION_METHODS_DICT = {
|
||||
"GETITEM_SPECIAL_METHOD": {}.__getitem__,
|
||||
"LAMBDA": lambda: None
|
||||
}
|
||||
|
||||
STATIC_PASSING_ASSERTIONS = (
|
||||
('assertTrue', True),
|
||||
@@ -36,13 +40,13 @@ STATIC_FAILING_ASSERTIONS = (
|
||||
)
|
||||
|
||||
CONTEXT_PASSING_ASSERTIONS = (
|
||||
('assertRaises', KeyError, {}.__getitem__, '1'),
|
||||
('assertRaisesRegexp', KeyError, "1", {}.__getitem__, '1'),
|
||||
('assertRaises', KeyError, "GETITEM_SPECIAL_METHOD", '1'),
|
||||
('assertRaisesRegexp', KeyError, "1", "GETITEM_SPECIAL_METHOD", '1'),
|
||||
)
|
||||
|
||||
CONTEXT_FAILING_ASSERTIONS = (
|
||||
('assertRaises', ValueError, lambda: None),
|
||||
('assertRaisesRegexp', KeyError, "2", {}.__getitem__, '1'),
|
||||
('assertRaises', ValueError, "LAMBDA"),
|
||||
('assertRaisesRegexp', KeyError, "2", "GETITEM_SPECIAL_METHOD", '1'),
|
||||
)
|
||||
|
||||
|
||||
@@ -55,11 +59,22 @@ class TestBulkAssertionTestCase(BulkAssertionTest):
|
||||
|
||||
# pylint: disable=bad-super-call
|
||||
|
||||
def _is_arg_in_assertion_methods_dict(self, argument):
|
||||
"""
|
||||
Takes in an argument, and returns whether
|
||||
"""
|
||||
return type(argument) == str and argument in ASSERTION_METHODS_DICT
|
||||
|
||||
def _run_assertion(self, assertion_tuple):
|
||||
"""
|
||||
Run the supplied tuple of (assertion, *args) as a method on this class.
|
||||
"""
|
||||
assertion, args = assertion_tuple[0], assertion_tuple[1:]
|
||||
args_list = list(args)
|
||||
for index, argument in enumerate(args_list):
|
||||
if self._is_arg_in_assertion_methods_dict(argument):
|
||||
args_list[index] = ASSERTION_METHODS_DICT[argument]
|
||||
args = tuple(args_list)
|
||||
getattr(self, assertion)(*args)
|
||||
|
||||
def _raw_assert(self, assertion_name, *args, **kwargs):
|
||||
@@ -88,10 +103,10 @@ class TestBulkAssertionTestCase(BulkAssertionTest):
|
||||
|
||||
exception = args.pop(0)
|
||||
|
||||
while not callable(args[0]):
|
||||
while not self._is_arg_in_assertion_methods_dict(args[0]):
|
||||
assertion_args.append(args.pop(0))
|
||||
|
||||
function = args.pop(0)
|
||||
function = ASSERTION_METHODS_DICT[args.pop(0)]
|
||||
|
||||
with getattr(self, assertion)(exception, *assertion_args):
|
||||
function(*args)
|
||||
@@ -104,10 +119,10 @@ class TestBulkAssertionTestCase(BulkAssertionTest):
|
||||
|
||||
exception = args.pop(0)
|
||||
|
||||
while not callable(args[0]):
|
||||
while not self._is_arg_in_assertion_methods_dict(args[0]):
|
||||
assertion_args.append(args.pop(0))
|
||||
|
||||
function = args.pop(0)
|
||||
function = ASSERTION_METHODS_DICT[args.pop(0)]
|
||||
|
||||
with self._raw_assert('Raises', AssertionError) as context:
|
||||
with getattr(self, assertion)(exception, *assertion_args):
|
||||
|
||||
@@ -80,7 +80,8 @@ def flatten(class_dict):
|
||||
Flatten a dict from cls -> [fields, ...] and yields values of the form (cls, fields)
|
||||
for each entry in the dictionary value.
|
||||
"""
|
||||
for cls, fields_list in class_dict.items():
|
||||
for cls in sorted(class_dict, key=lambda err: err.__name__):
|
||||
fields_list = class_dict[cls]
|
||||
for fields in fields_list:
|
||||
yield (cls, fields)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user