Commit 3b9d22e4 by Victor Shnayder

Add import-export round-trip check.

* add fix for the file export code--remove tag tail and text,
  not just the children.
parent dff77d22
...@@ -257,6 +257,11 @@ class XmlDescriptor(XModuleDescriptor): ...@@ -257,6 +257,11 @@ class XmlDescriptor(XModuleDescriptor):
# ...and remove all of its children here # ...and remove all of its children here
for child in xml_object: for child in xml_object:
xml_object.remove(child) xml_object.remove(child)
# also need to remove the text of this object.
xml_object.text = ''
# and the tail for good measure...
xml_object.tail = ''
xml_object.set('filename', self.name) xml_object.set('filename', self.name)
......
import os
import sys import sys
import traceback import traceback
from filecmp import dircmp
from fs.osfs import OSFS from fs.osfs import OSFS
from path import path from path import path
from lxml import etree from lxml import etree
...@@ -10,28 +12,6 @@ from django.core.management.base import BaseCommand ...@@ -10,28 +12,6 @@ from django.core.management.base import BaseCommand
from xmodule.modulestore.xml import XMLModuleStore from xmodule.modulestore.xml import XMLModuleStore
def export(course, export_dir):
"""Export the specified course to course_dir. Creates dir if it doesn't exist.
Overwrites files, does not clean out dir beforehand.
"""
fs = OSFS(export_dir, create=True)
if not fs.isdirempty('.'):
print ('WARNING: Directory {dir} not-empty.'
' May clobber/confuse things'.format(dir=export_dir))
try:
xml = course.export_to_xml(fs)
with fs.open('course.xml', mode='w') as f:
f.write(xml)
return True
except:
print 'Export failed!'
traceback.print_exc()
return False
def traverse_tree(course): def traverse_tree(course):
'''Load every descriptor in course. Return bool success value.''' '''Load every descriptor in course. Return bool success value.'''
queue = [course] queue = [course]
...@@ -61,7 +41,30 @@ def make_logging_error_handler(): ...@@ -61,7 +41,30 @@ def make_logging_error_handler():
return (error_handler, errors) return (error_handler, errors)
def clean_xml(course_dir, export_dir, verbose=True):
def export(course, export_dir):
"""Export the specified course to course_dir. Creates dir if it doesn't exist.
Overwrites files, does not clean out dir beforehand.
"""
fs = OSFS(export_dir, create=True)
if not fs.isdirempty('.'):
print ('WARNING: Directory {dir} not-empty.'
' May clobber/confuse things'.format(dir=export_dir))
try:
xml = course.export_to_xml(fs)
with fs.open('course.xml', mode='w') as f:
f.write(xml)
return True
except:
print 'Export failed!'
traceback.print_exc()
return False
def import_with_checks(course_dir, verbose=True):
all_ok = True all_ok = True
print "Attempting to load '{0}'".format(course_dir) print "Attempting to load '{0}'".format(course_dir)
...@@ -105,7 +108,7 @@ def clean_xml(course_dir, export_dir, verbose=True): ...@@ -105,7 +108,7 @@ def clean_xml(course_dir, export_dir, verbose=True):
course = courses[0] course = courses[0]
print course #print course
validators = ( validators = (
traverse_tree, traverse_tree,
) )
...@@ -120,10 +123,36 @@ def clean_xml(course_dir, export_dir, verbose=True): ...@@ -120,10 +123,36 @@ def clean_xml(course_dir, export_dir, verbose=True):
if all_ok: if all_ok:
print 'Course passes all checks!' print 'Course passes all checks!'
export(course, export_dir)
else: else:
print "Course fails some checks. See above for errors." print "Course fails some checks. See above for errors."
return all_ok, course
def check_roundtrip(course_dir):
'''Check that import->export leaves the course the same'''
print "====== Roundtrip import ======="
(ok, course) = import_with_checks(course_dir)
if not ok:
raise Exception("Roundtrip import failed!")
print "====== Roundtrip export ======="
export_dir = course_dir + ".rt"
export(course, export_dir)
# dircmp doesn't do recursive diffs.
# diff = dircmp(course_dir, export_dir, ignore=[], hide=[])
print "======== Roundtrip diff: ========="
os.system("diff -r {0} {1}".format(course_dir, export_dir))
print "======== ideally there is no diff above this ======="
def clean_xml(course_dir, export_dir):
(ok, course) = import_with_checks(course_dir)
if ok:
export(course, export_dir)
check_roundtrip(export_dir)
else:
print "Did NOT export" print "Did NOT export"
...@@ -134,7 +163,6 @@ class Command(BaseCommand): ...@@ -134,7 +163,6 @@ class Command(BaseCommand):
Usage: clean_xml PATH-TO-COURSE-DIR PATH-TO-OUTPUT-DIR Usage: clean_xml PATH-TO-COURSE-DIR PATH-TO-OUTPUT-DIR
""" """
def handle(self, *args, **options): def handle(self, *args, **options):
if len(args) != 2: if len(args) != 2:
print Command.help print Command.help
......
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