check for old mongo course
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -49,6 +49,7 @@ coverage.xml
|
||||
cover/
|
||||
cover_html/
|
||||
reports/
|
||||
jscover.log
|
||||
jscover.log.*
|
||||
|
||||
### Installation artifacts
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
"""
|
||||
Django management command to rollback a migration to split. The way to do this
|
||||
is to delete the course from the split mongo datastore.
|
||||
"""
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||
from xmodule.modulestore.locator import CourseLocator
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
"Delete a course from the split Mongo datastore"
|
||||
|
||||
help = "Delete a course from the split Mongo datastore"
|
||||
args = "locator"
|
||||
|
||||
def handle(self, *args, **options):
|
||||
if len(args) < 1:
|
||||
raise CommandError(
|
||||
"delete_split_course requires at least one argument (locator)"
|
||||
)
|
||||
|
||||
try:
|
||||
locator = CourseLocator(url=args[0])
|
||||
except ValueError:
|
||||
raise CommandError("Invalid locator string {}".format(args[0]))
|
||||
|
||||
try:
|
||||
modulestore('split').delete_course(locator.package_id)
|
||||
except ItemNotFoundError:
|
||||
raise CommandError("No course found with locator {}".format(locator))
|
||||
@@ -0,0 +1,51 @@
|
||||
"""
|
||||
Django management command to rollback a migration to split. The way to do this
|
||||
is to delete the course from the split mongo datastore.
|
||||
"""
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from xmodule.modulestore.django import modulestore, loc_mapper
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError, InsufficientSpecificationError
|
||||
from xmodule.modulestore.locator import CourseLocator
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
"Rollback a course that was migrated to the split Mongo datastore"
|
||||
|
||||
help = "Rollback a course that was migrated to the split Mongo datastore"
|
||||
args = "locator"
|
||||
|
||||
def handle(self, *args, **options):
|
||||
if len(args) < 1:
|
||||
raise CommandError(
|
||||
"rollback_split_course requires at least one argument (locator)"
|
||||
)
|
||||
|
||||
try:
|
||||
locator = CourseLocator(url=args[0])
|
||||
except ValueError:
|
||||
raise CommandError("Invalid locator string {}".format(args[0]))
|
||||
|
||||
location = loc_mapper().translate_locator_to_location(locator, get_course=True)
|
||||
if not location:
|
||||
raise CommandError(
|
||||
"This course does not exist in the old Mongo store. "
|
||||
"This command is designed to rollback a course, not delete "
|
||||
"it entirely."
|
||||
)
|
||||
old_mongo_course = modulestore('direct').get_item(location)
|
||||
if not old_mongo_course:
|
||||
raise CommandError(
|
||||
"This course does not exist in the old Mongo store. "
|
||||
"This command is designed to rollback a course, not delete "
|
||||
"it entirely."
|
||||
)
|
||||
|
||||
try:
|
||||
modulestore('split').delete_course(locator.package_id)
|
||||
except ItemNotFoundError:
|
||||
raise CommandError("No course found with locator {}".format(locator))
|
||||
|
||||
print(
|
||||
'Course rolled back successfully. To delete this course entirely, '
|
||||
'call the "delete_course" management command.'
|
||||
)
|
||||
@@ -1,57 +0,0 @@
|
||||
"""
|
||||
Unittests for deleting a split mongo course
|
||||
"""
|
||||
import unittest
|
||||
|
||||
from django.core.management import CommandError, call_command
|
||||
from django.test.utils import override_settings
|
||||
from contentstore.management.commands.delete_split_course import Command
|
||||
from contentstore.tests.modulestore_config import TEST_MODULESTORE
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from xmodule.modulestore.tests.persistent_factories import PersistentCourseFactory
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||
# pylint: disable=E1101
|
||||
|
||||
|
||||
class TestArgParsing(unittest.TestCase):
|
||||
"""
|
||||
Tests for parsing arguments for the `delete_split_course` management command
|
||||
"""
|
||||
def setUp(self):
|
||||
self.command = Command()
|
||||
|
||||
def test_no_args(self):
|
||||
errstring = "delete_split_course requires at least one argument"
|
||||
with self.assertRaisesRegexp(CommandError, errstring):
|
||||
self.command.handle()
|
||||
|
||||
def test_invalid_locator(self):
|
||||
errstring = "Invalid locator string !?!"
|
||||
with self.assertRaisesRegexp(CommandError, errstring):
|
||||
self.command.handle("!?!")
|
||||
|
||||
def test_nonexistant_locator(self):
|
||||
errstring = "No course found with locator course/branch/name"
|
||||
with self.assertRaisesRegexp(CommandError, errstring):
|
||||
self.command.handle("course/branch/name")
|
||||
|
||||
|
||||
@override_settings(MODULESTORE=TEST_MODULESTORE)
|
||||
class TestDeleteSplitCourse(ModuleStoreTestCase):
|
||||
"""
|
||||
Unit tests for deleting a split-mongo course from command line
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(TestDeleteSplitCourse, self).setUp()
|
||||
self.course = PersistentCourseFactory()
|
||||
|
||||
def test_happy_path(self):
|
||||
locator = self.course.location
|
||||
call_command(
|
||||
"delete_split_course",
|
||||
str(locator),
|
||||
)
|
||||
with self.assertRaises(ItemNotFoundError):
|
||||
modulestore('split').get_course(locator)
|
||||
@@ -0,0 +1,108 @@
|
||||
"""
|
||||
Unittests for deleting a split mongo course
|
||||
"""
|
||||
import unittest
|
||||
from StringIO import StringIO
|
||||
from mock import patch
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.management import CommandError, call_command
|
||||
from django.test.utils import override_settings
|
||||
from contentstore.management.commands.rollback_split_course import Command
|
||||
from contentstore.tests.modulestore_config import TEST_MODULESTORE
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from xmodule.modulestore.tests.persistent_factories import PersistentCourseFactory
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
from xmodule.modulestore.django import modulestore, loc_mapper
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||
from xmodule.modulestore.split_migrator import SplitMigrator
|
||||
# pylint: disable=E1101
|
||||
|
||||
|
||||
class TestArgParsing(unittest.TestCase):
|
||||
"""
|
||||
Tests for parsing arguments for the `rollback_split_course` management command
|
||||
"""
|
||||
def setUp(self):
|
||||
self.command = Command()
|
||||
|
||||
def test_no_args(self):
|
||||
errstring = "rollback_split_course requires at least one argument"
|
||||
with self.assertRaisesRegexp(CommandError, errstring):
|
||||
self.command.handle()
|
||||
|
||||
def test_invalid_locator(self):
|
||||
errstring = "Invalid locator string !?!"
|
||||
with self.assertRaisesRegexp(CommandError, errstring):
|
||||
self.command.handle("!?!")
|
||||
|
||||
|
||||
@override_settings(MODULESTORE=TEST_MODULESTORE)
|
||||
class TestRollbackSplitCourseNoOldMongo(ModuleStoreTestCase):
|
||||
"""
|
||||
Unit tests for rolling back a split-mongo course from command line
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(TestRollbackSplitCourseNoOldMongo, self).setUp()
|
||||
self.course = PersistentCourseFactory()
|
||||
|
||||
def test_no_old_course(self):
|
||||
locator = self.course.location
|
||||
errstring = "course does not exist in the old Mongo store"
|
||||
with self.assertRaisesRegexp(CommandError, errstring):
|
||||
Command().handle(str(locator))
|
||||
|
||||
@override_settings(MODULESTORE=TEST_MODULESTORE)
|
||||
class TestRollbackSplitCourseNoSplitMongo(ModuleStoreTestCase):
|
||||
"""
|
||||
Unit tests for rolling back a split-mongo course from command line
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(TestRollbackSplitCourseNoSplitMongo, self).setUp()
|
||||
self.old_course = CourseFactory()
|
||||
|
||||
def test_nonexistent_locator(self):
|
||||
locator = loc_mapper().translate_location(self.old_course.id, self.old_course.location)
|
||||
errstring = "No course found with locator"
|
||||
with self.assertRaisesRegexp(CommandError, errstring):
|
||||
Command().handle(str(locator))
|
||||
|
||||
|
||||
@override_settings(MODULESTORE=TEST_MODULESTORE)
|
||||
class TestRollbackSplitCourse(ModuleStoreTestCase):
|
||||
"""
|
||||
Unit tests for rolling back a split-mongo course from command line
|
||||
"""
|
||||
def setUp(self):
|
||||
super(TestRollbackSplitCourse, self).setUp()
|
||||
self.old_course = CourseFactory()
|
||||
uname = 'testuser'
|
||||
email = 'test+courses@edx.org'
|
||||
password = 'foo'
|
||||
self.user = User.objects.create_user(uname, email, password)
|
||||
|
||||
# migrate old course to split
|
||||
migrator = SplitMigrator(
|
||||
draft_modulestore=modulestore('default'),
|
||||
direct_modulestore=modulestore('direct'),
|
||||
split_modulestore=modulestore('split'),
|
||||
loc_mapper=loc_mapper(),
|
||||
)
|
||||
migrator.migrate_mongo_course(self.old_course.location, self.user)
|
||||
locator = loc_mapper().translate_location(self.old_course.id, self.old_course.location)
|
||||
self.course = modulestore('split').get_course(locator)
|
||||
|
||||
@patch("sys.stdout", new_callable=StringIO)
|
||||
def test_happy_path(self, mock_stdout):
|
||||
locator = self.course.location
|
||||
call_command(
|
||||
"rollback_split_course",
|
||||
str(locator),
|
||||
)
|
||||
with self.assertRaises(ItemNotFoundError):
|
||||
modulestore('split').get_course(locator)
|
||||
|
||||
self.assertIn("Course rolled back successfully", mock_stdout.getvalue())
|
||||
|
||||
Reference in New Issue
Block a user