Set up ajax to submit to XQueue. Add some unit tests to make sure
this is working properly
This commit is contained in:
@@ -48,6 +48,8 @@ import pyparsing
|
||||
|
||||
from .registry import TagRegistry
|
||||
from capa.chem import chemcalc
|
||||
import xqueue_interface
|
||||
from datetime import datetime
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -639,6 +641,7 @@ class MatlabInput(CodeInput):
|
||||
|
||||
# Check if problem has been queued
|
||||
self.queue_len = 0
|
||||
self.queuename = 'matlab'
|
||||
# Flag indicating that the problem has been queued, 'msg' is length of
|
||||
# queue
|
||||
if self.status == 'incomplete':
|
||||
@@ -650,20 +653,44 @@ class MatlabInput(CodeInput):
|
||||
|
||||
def handle_ajax(self, dispatch, get):
|
||||
if dispatch == 'plot':
|
||||
# put the data in the queue and ship it off
|
||||
pass
|
||||
elif dispatch == 'display':
|
||||
return self.plot_data(get)
|
||||
elif dispatch == 'xqueue_response':
|
||||
# render the response
|
||||
pass
|
||||
|
||||
def plot_data(self, get):
|
||||
''' send data via xqueue to the mathworks backend'''
|
||||
|
||||
# only send data if xqueue exists
|
||||
if self.system.xqueue is not None:
|
||||
pass
|
||||
# pull relevant info out of get
|
||||
response = get['submission']
|
||||
|
||||
# construct xqueue headers
|
||||
qinterface = self.system.xqueue['interface']
|
||||
qtime = datetime.strftime(datetime.now(), xqueue_interface.dateformat)
|
||||
callback_url = self.system.xqueue['construct_callback']('input_ajax')
|
||||
anonymous_student_id = self.system.anonymous_student_id
|
||||
queuekey = xqueue_interface.make_hashkey(str(self.system.seed) + qtime +
|
||||
anonymous_student_id +
|
||||
self.id)
|
||||
xheader = xqueue_interface.make_xheader(
|
||||
lms_callback_url = callback_url,
|
||||
lms_key = queuekey,
|
||||
queue_name = self.queuename)
|
||||
|
||||
|
||||
# construct xqueue body
|
||||
student_info = {'anonymous_student_id': anonymous_student_id,
|
||||
'submission_time': qtime}
|
||||
contents = {'grader_payload': self.plot_payload,
|
||||
'student_info': json.dumps(student_info),
|
||||
'student_response': response}
|
||||
|
||||
(error, msg) = qinterface.send_to_queue(header=xheader,
|
||||
body = json.dumps(contents))
|
||||
|
||||
return json.dumps({'success': error != 0, 'message': msg})
|
||||
return json.dumps({'success': False, 'message': 'Cannot connect to the queue'})
|
||||
|
||||
|
||||
registry.register(MatlabInput)
|
||||
|
||||
@@ -1271,8 +1271,9 @@ class CodeResponse(LoncapaResponse):
|
||||
|
||||
Expects 'xqueue' dict in ModuleSystem with the following keys that are needed by CodeResponse:
|
||||
system.xqueue = { 'interface': XqueueInterface object,
|
||||
'callback_url': Per-StudentModule callback URL
|
||||
where results are posted (string),
|
||||
'construct_callback': Per-StudentModule callback URL
|
||||
constructor, defaults to using 'score_update'
|
||||
as the correct dispatch (function),
|
||||
'default_queuename': Default queuename to submit request (string)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import fs
|
||||
import fs.osfs
|
||||
import os
|
||||
|
||||
from mock import Mock
|
||||
from mock import Mock, MagicMock
|
||||
|
||||
import xml.sax.saxutils as saxutils
|
||||
|
||||
@@ -16,6 +16,11 @@ def tst_render_template(template, context):
|
||||
"""
|
||||
return '<div>{0}</div>'.format(saxutils.escape(repr(context)))
|
||||
|
||||
def calledback_url(dispatch = 'score_update'):
|
||||
return dispatch
|
||||
|
||||
xqueue_interface = MagicMock()
|
||||
xqueue_interface.send_to_queue.return_value = (1, 'Success!')
|
||||
|
||||
test_system = Mock(
|
||||
ajax_url='courses/course_id/modx/a_location',
|
||||
@@ -26,7 +31,7 @@ test_system = Mock(
|
||||
user=Mock(),
|
||||
filestore=fs.osfs.OSFS(os.path.join(TEST_DIR, "test_files")),
|
||||
debug=True,
|
||||
xqueue={'interface': None, 'callback_url': '/', 'default_queuename': 'testqueue', 'waittime': 10},
|
||||
xqueue={'interface': xqueue_interface, 'construct_callback': calledback_url, 'default_queuename': 'testqueue', 'waittime': 10},
|
||||
node_path=os.environ.get("NODE_PATH", "/usr/local/lib/node_modules"),
|
||||
anonymous_student_id='student'
|
||||
)
|
||||
|
||||
@@ -23,6 +23,7 @@ import xml.sax.saxutils as saxutils
|
||||
|
||||
from . import test_system
|
||||
from capa import inputtypes
|
||||
from mock import ANY
|
||||
|
||||
# just a handy shortcut
|
||||
lookup_tag = inputtypes.registry.get_class_for_tag
|
||||
@@ -300,6 +301,68 @@ class CodeInputTest(unittest.TestCase):
|
||||
|
||||
self.assertEqual(context, expected)
|
||||
|
||||
class MatlabTest(unittest.TestCase):
|
||||
'''
|
||||
Test Matlab input types
|
||||
'''
|
||||
def setUp(self):
|
||||
self.rows = '10'
|
||||
self.cols = '80'
|
||||
self.tabsize = '4'
|
||||
self.mode = ""
|
||||
self.payload = "payload"
|
||||
self.linenumbers = 'true'
|
||||
self.xml = """<matlabinput id="prob_1_2"
|
||||
rows="{r}" cols="{c}"
|
||||
tabsize="{tabsize}" mode="{m}"
|
||||
linenumbers="{ln}">
|
||||
<plot_payload>
|
||||
{payload}
|
||||
</plot_payload>
|
||||
</matlabinput>""".format(r = self.rows,
|
||||
c = self.cols,
|
||||
tabsize = self.tabsize,
|
||||
m = self.mode,
|
||||
payload = self.payload,
|
||||
ln = self.linenumbers)
|
||||
elt = etree.fromstring(self.xml)
|
||||
state = {'value': 'print "good evening"',
|
||||
'status': 'incomplete',
|
||||
'feedback': {'message': '3'}, }
|
||||
|
||||
self.input_class = lookup_tag('matlabinput')
|
||||
self.the_input = self.input_class(test_system, elt, state)
|
||||
|
||||
|
||||
def test_rendering(self):
|
||||
context = self.the_input._get_render_context()
|
||||
|
||||
expected = {'id': 'prob_1_2',
|
||||
'value': 'print "good evening"',
|
||||
'status': 'queued',
|
||||
'msg': self.input_class.submitted_msg,
|
||||
'mode': self.mode,
|
||||
'rows': self.rows,
|
||||
'cols': self.cols,
|
||||
'linenumbers': 'true',
|
||||
'hidden': '',
|
||||
'tabsize': int(self.tabsize),
|
||||
'queue_len': '3',
|
||||
}
|
||||
|
||||
self.assertEqual(context, expected)
|
||||
|
||||
def test_plot_data(self):
|
||||
get = {'submission': 'x = 1234;'}
|
||||
response = json.loads(self.the_input.handle_ajax("plot", get))
|
||||
|
||||
test_system.xqueue['interface'].send_to_queue.assert_called_with(header=ANY, body=ANY)
|
||||
|
||||
|
||||
self.assertTrue(response['success'])
|
||||
|
||||
|
||||
|
||||
|
||||
class SchematicTest(unittest.TestCase):
|
||||
'''
|
||||
|
||||
Reference in New Issue
Block a user