check for old mongo course

This commit is contained in:
David Baumgold
2014-01-29 10:20:03 -05:00
parent e18507f188
commit e0c1abc11f
5 changed files with 160 additions and 88 deletions

1
.gitignore vendored
View File

@@ -49,6 +49,7 @@ coverage.xml
cover/
cover_html/
reports/
jscover.log
jscover.log.*
### Installation artifacts

View File

@@ -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))

View File

@@ -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.'
)

View File

@@ -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)

View File

@@ -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())