Commit 0f70a997 by Oleg Marshev

Add timestamp and wait for 35 sec.

parent dead7801
......@@ -5,6 +5,9 @@ These are notable changes in edx-platform. This is a rolling list of changes,
in roughly chronological order, most recent first. Add your entries at or near
the top. Include a label indicating the component affected.
Blades: Handle situation if no response were sent from XQueue to LMS in Matlab
problem after Run Code button press. BLD-994.
Blades: Set initial video quality to large instead of default to avoid automatic switch to HD when iframe resizes. BLD-981.
Blades: Add an upload button for authors to provide students with an option to
......
......@@ -39,6 +39,7 @@ graded status as'status'
# makes sense, but a bunch of problems have markup that assumes block. Bigger TODO: figure out a
# general css and layout strategy for capa, document it, then implement it.
import time
import json
import logging
from lxml import etree
......@@ -53,6 +54,7 @@ from .registry import TagRegistry
from chem import chemcalc
from calc.preview import latex_preview
import xqueue_interface
from xqueue_interface import XQUEUE_TIMEOUT
from datetime import datetime
from xmodule.stringify import stringify_children
......@@ -821,6 +823,15 @@ class MatlabInput(CodeInput):
self.status = 'queued'
self.queue_len = 1
self.msg = self.submitted_msg
# Handle situation if no response from xqueue arrived during specified time.
if ('queuetime' not in self.input_state or
time.time() - self.input_state['queuetime'] > XQUEUE_TIMEOUT):
self.queue_len = 0
self.status = 'unsubmitted'
self.msg = _(
'No response from Xqueue within {xqueue_timeout} seconds. Aborted.'
).format(xqueue_timeout=XQUEUE_TIMEOUT)
def handle_ajax(self, dispatch, data):
"""
......@@ -945,6 +956,7 @@ class MatlabInput(CodeInput):
if error == 0:
self.input_state['queuekey'] = queuekey
self.input_state['queuestate'] = 'queued'
self.input_state['queuetime'] = time.time()
return {'success': error == 0, 'message': msg}
......
......@@ -28,6 +28,8 @@ from capa import inputtypes
from mock import ANY, patch
from pyparsing import ParseException
from capa.xqueue_interface import XQUEUE_TIMEOUT
# just a handy shortcut
lookup_tag = inputtypes.registry.get_class_for_tag
......@@ -524,10 +526,11 @@ class MatlabTest(unittest.TestCase):
self.assertEqual(context, expected)
def test_rendering_while_queued(self):
@patch('capa.inputtypes.time.time', return_value=10)
def test_rendering_while_queued(self, time):
state = {'value': 'print "good evening"',
'status': 'incomplete',
'input_state': {'queuestate': 'queued'},
'input_state': {'queuestate': 'queued', 'queuetime': 5},
}
elt = etree.fromstring(self.xml)
......@@ -576,9 +579,10 @@ class MatlabTest(unittest.TestCase):
self.assertTrue('queuekey' not in self.the_input.input_state)
self.assertTrue('queuestate' not in self.the_input.input_state)
def test_ungraded_response_success(self):
@patch('capa.inputtypes.time.time', return_value=10)
def test_ungraded_response_success(self, time):
queuekey = 'abcd'
input_state = {'queuekey': queuekey, 'queuestate': 'queued'}
input_state = {'queuekey': queuekey, 'queuestate': 'queued', 'queuetime': 5}
state = {'value': 'print "good evening"',
'status': 'incomplete',
'input_state': input_state,
......@@ -594,9 +598,10 @@ class MatlabTest(unittest.TestCase):
self.assertTrue(input_state['queuestate'] is None)
self.assertEqual(input_state['queue_msg'], inner_msg)
def test_ungraded_response_key_mismatch(self):
@patch('capa.inputtypes.time.time', return_value=10)
def test_ungraded_response_key_mismatch(self, time):
queuekey = 'abcd'
input_state = {'queuekey': queuekey, 'queuestate': 'queued'}
input_state = {'queuekey': queuekey, 'queuestate': 'queued', 'queuetime': 5}
state = {'value': 'print "good evening"',
'status': 'incomplete',
'input_state': input_state,
......@@ -612,6 +617,41 @@ class MatlabTest(unittest.TestCase):
self.assertEqual(input_state['queuestate'], 'queued')
self.assertFalse('queue_msg' in input_state)
@patch('capa.inputtypes.time.time', return_value=20)
def test_matlab_response_timeout_not_exceeded(self, time):
state = {'input_state': {'queuestate': 'queued', 'queuetime': 5}}
elt = etree.fromstring(self.xml)
the_input = self.input_class(test_capa_system(), elt, state)
context = the_input._get_render_context()
self.assertEqual(the_input.status, 'queued')
@patch('capa.inputtypes.time.time', return_value=45)
def test_matlab_response_timeout_exceeded(self, time):
state = {'input_state': {'queuestate': 'queued', 'queuetime': 5}}
elt = etree.fromstring(self.xml)
the_input = self.input_class(test_capa_system(), elt, state)
context = the_input._get_render_context()
self.assertEqual(the_input.status, 'unsubmitted')
self.assertEqual(the_input.msg, 'No response from Xqueue within {} seconds. Aborted.'.format(XQUEUE_TIMEOUT))
@patch('capa.inputtypes.time.time', return_value=20)
def test_matlab_response_migration_of_queuetime(self, time):
"""
Test if problem was saved before queuetime was introduced.
"""
state = {'input_state': {'queuestate': 'queued'}}
elt = etree.fromstring(self.xml)
the_input = self.input_class(test_capa_system(), elt, state)
context = the_input._get_render_context()
self.assertEqual(the_input.status, 'unsubmitted')
def test_get_html(self):
# usual output
output = self.the_input.get_html()
......@@ -693,7 +733,7 @@ class MatlabTest(unittest.TestCase):
the_input = self.input_class(test_capa_system(), elt, state)
context = the_input._get_render_context() # pylint: disable=W0212
self.maxDiff = None
expected = u'\n<div class="matlabResponse"><div class="commandWindowOutput" style="white-space: pre;"> <strong>if</strong> Conditionally execute statements.\nThe general form of the <strong>if</strong> statement is\n\n <strong>if</strong> expression\n statements\n ELSEIF expression\n statements\n ELSE\n statements\n END\n\nThe statements are executed if the real part of the expression \nhas all non-zero elements. The ELSE and ELSEIF parts are optional.\nZero or more ELSEIF parts can be used as well as nested <strong>if</strong>\'s.\nThe expression is usually of the form expr rop expr where \nrop is ==, &lt;, &gt;, &lt;=, &gt;=, or ~=.\n<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAjAAAAGkCAIAAACgj==">\n\nExample\n if I == J\n A(I,J) = 2;\n elseif abs(I-J) == 1\n A(I,J) = -1;\n else\n A(I,J) = 0;\n end\n\nSee also <a>relop</a>, <a>else</a>, <a>elseif</a>, <a>end</a>, <a>for</a>, <a>while</a>, <a>switch</a>.\n\nReference page in Help browser\n <a>doc if</a>\n\n</div><ul></ul></div>\n'
expected = u'\n<div class="matlabResponse"><div class="commandWindowOutput" style="white-space: pre;"> <strong>if</strong> Conditionally execute statements.\nThe general form of the <strong>if</strong> statement is\n\n <strong>if</strong> expression\n statements\n ELSEIF expression\n statements\n ELSE\n statements\n END\n\nThe statements are executed if the real part of the expression\nhas all non-zero elements. The ELSE and ELSEIF parts are optional.\nZero or more ELSEIF parts can be used as well as nested <strong>if</strong>\'s.\nThe expression is usually of the form expr rop expr where\nrop is ==, &lt;, &gt;, &lt;=, &gt;=, or ~=.\n<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAjAAAAGkCAIAAACgj==">\n\nExample\n if I == J\n A(I,J) = 2;\n elseif abs(I-J) == 1\n A(I,J) = -1;\n else\n A(I,J) = 0;\n end\n\nSee also <a>relop</a>, <a>else</a>, <a>elseif</a>, <a>end</a>, <a>for</a>, <a>while</a>, <a>switch</a>.\n\nReference page in Help browser\n <a>doc if</a>\n\n</div><ul></ul></div>\n'
self.assertEqual(context['queue_msg'], expected)
......
......@@ -13,6 +13,9 @@ dateformat = '%Y%m%d%H%M%S'
XQUEUE_METRIC_NAME = 'edxapp.xqueue'
# Wait time for response from Xqueue.
XQUEUE_TIMEOUT = 35 # seconds
def make_hashkey(seed):
"""
......
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