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, ...@@ -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 in roughly chronological order, most recent first. Add your entries at or near
the top. Include a label indicating the component affected. 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: 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 Blades: Add an upload button for authors to provide students with an option to
......
...@@ -39,6 +39,7 @@ graded status as'status' ...@@ -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 # 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. # general css and layout strategy for capa, document it, then implement it.
import time
import json import json
import logging import logging
from lxml import etree from lxml import etree
...@@ -53,6 +54,7 @@ from .registry import TagRegistry ...@@ -53,6 +54,7 @@ from .registry import TagRegistry
from chem import chemcalc from chem import chemcalc
from calc.preview import latex_preview from calc.preview import latex_preview
import xqueue_interface import xqueue_interface
from xqueue_interface import XQUEUE_TIMEOUT
from datetime import datetime from datetime import datetime
from xmodule.stringify import stringify_children from xmodule.stringify import stringify_children
...@@ -821,6 +823,15 @@ class MatlabInput(CodeInput): ...@@ -821,6 +823,15 @@ class MatlabInput(CodeInput):
self.status = 'queued' self.status = 'queued'
self.queue_len = 1 self.queue_len = 1
self.msg = self.submitted_msg 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): def handle_ajax(self, dispatch, data):
""" """
...@@ -945,6 +956,7 @@ class MatlabInput(CodeInput): ...@@ -945,6 +956,7 @@ class MatlabInput(CodeInput):
if error == 0: if error == 0:
self.input_state['queuekey'] = queuekey self.input_state['queuekey'] = queuekey
self.input_state['queuestate'] = 'queued' self.input_state['queuestate'] = 'queued'
self.input_state['queuetime'] = time.time()
return {'success': error == 0, 'message': msg} return {'success': error == 0, 'message': msg}
......
...@@ -28,6 +28,8 @@ from capa import inputtypes ...@@ -28,6 +28,8 @@ from capa import inputtypes
from mock import ANY, patch from mock import ANY, patch
from pyparsing import ParseException from pyparsing import ParseException
from capa.xqueue_interface import XQUEUE_TIMEOUT
# just a handy shortcut # just a handy shortcut
lookup_tag = inputtypes.registry.get_class_for_tag lookup_tag = inputtypes.registry.get_class_for_tag
...@@ -524,10 +526,11 @@ class MatlabTest(unittest.TestCase): ...@@ -524,10 +526,11 @@ class MatlabTest(unittest.TestCase):
self.assertEqual(context, expected) 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"', state = {'value': 'print "good evening"',
'status': 'incomplete', 'status': 'incomplete',
'input_state': {'queuestate': 'queued'}, 'input_state': {'queuestate': 'queued', 'queuetime': 5},
} }
elt = etree.fromstring(self.xml) elt = etree.fromstring(self.xml)
...@@ -576,9 +579,10 @@ class MatlabTest(unittest.TestCase): ...@@ -576,9 +579,10 @@ class MatlabTest(unittest.TestCase):
self.assertTrue('queuekey' not in self.the_input.input_state) self.assertTrue('queuekey' not in self.the_input.input_state)
self.assertTrue('queuestate' 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' queuekey = 'abcd'
input_state = {'queuekey': queuekey, 'queuestate': 'queued'} input_state = {'queuekey': queuekey, 'queuestate': 'queued', 'queuetime': 5}
state = {'value': 'print "good evening"', state = {'value': 'print "good evening"',
'status': 'incomplete', 'status': 'incomplete',
'input_state': input_state, 'input_state': input_state,
...@@ -594,9 +598,10 @@ class MatlabTest(unittest.TestCase): ...@@ -594,9 +598,10 @@ class MatlabTest(unittest.TestCase):
self.assertTrue(input_state['queuestate'] is None) self.assertTrue(input_state['queuestate'] is None)
self.assertEqual(input_state['queue_msg'], inner_msg) 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' queuekey = 'abcd'
input_state = {'queuekey': queuekey, 'queuestate': 'queued'} input_state = {'queuekey': queuekey, 'queuestate': 'queued', 'queuetime': 5}
state = {'value': 'print "good evening"', state = {'value': 'print "good evening"',
'status': 'incomplete', 'status': 'incomplete',
'input_state': input_state, 'input_state': input_state,
...@@ -612,6 +617,41 @@ class MatlabTest(unittest.TestCase): ...@@ -612,6 +617,41 @@ class MatlabTest(unittest.TestCase):
self.assertEqual(input_state['queuestate'], 'queued') self.assertEqual(input_state['queuestate'], 'queued')
self.assertFalse('queue_msg' in input_state) 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): def test_get_html(self):
# usual output # usual output
output = self.the_input.get_html() output = self.the_input.get_html()
...@@ -651,7 +691,7 @@ class MatlabTest(unittest.TestCase): ...@@ -651,7 +691,7 @@ class MatlabTest(unittest.TestCase):
queue_msg = textwrap.dedent(""" queue_msg = textwrap.dedent("""
<div class='matlabResponse'><div style='white-space:pre' class='commandWindowOutput'> <strong>if</strong> Conditionally execute statements. <div class='matlabResponse'><div style='white-space:pre' class='commandWindowOutput'> <strong>if</strong> Conditionally execute statements.
The general form of the <strong>if</strong> statement is The general form of the <strong>if</strong> statement is
<strong>if</strong> expression <strong>if</strong> expression
statements statements
ELSEIF expression ELSEIF expression
...@@ -659,11 +699,11 @@ class MatlabTest(unittest.TestCase): ...@@ -659,11 +699,11 @@ class MatlabTest(unittest.TestCase):
ELSE ELSE
statements statements
END END
The statements are executed if the real part of the expression The statements are executed if the real part of the expression
has all non-zero elements. The ELSE and ELSEIF parts are optional. has all non-zero elements. The ELSE and ELSEIF parts are optional.
Zero or more ELSEIF parts can be used as well as nested <strong>if</strong>'s. Zero or more ELSEIF parts can be used as well as nested <strong>if</strong>'s.
The expression is usually of the form expr rop expr where The expression is usually of the form expr rop expr where
rop is ==, <, >, <=, >=, or ~=. rop is ==, <, >, <=, >=, or ~=.
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAjAAAAGkCAIAAACgj==" /> <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAjAAAAGkCAIAAACgj==" />
...@@ -675,7 +715,7 @@ class MatlabTest(unittest.TestCase): ...@@ -675,7 +715,7 @@ class MatlabTest(unittest.TestCase):
else else
A(I,J) = 0; A(I,J) = 0;
end end
See also <a href="matlab:help relop">relop</a>, <a href="matlab:help else">else</a>, <a href="matlab:help elseif">elseif</a>, <a href="matlab:help end">end</a>, <a href="matlab:help for">for</a>, <a href="matlab:help while">while</a>, <a href="matlab:help switch">switch</a>. See also <a href="matlab:help relop">relop</a>, <a href="matlab:help else">else</a>, <a href="matlab:help elseif">elseif</a>, <a href="matlab:help end">end</a>, <a href="matlab:help for">for</a>, <a href="matlab:help while">while</a>, <a href="matlab:help switch">switch</a>.
Reference page in Help browser Reference page in Help browser
...@@ -693,7 +733,7 @@ class MatlabTest(unittest.TestCase): ...@@ -693,7 +733,7 @@ class MatlabTest(unittest.TestCase):
the_input = self.input_class(test_capa_system(), elt, state) the_input = self.input_class(test_capa_system(), elt, state)
context = the_input._get_render_context() # pylint: disable=W0212 context = the_input._get_render_context() # pylint: disable=W0212
self.maxDiff = None 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) self.assertEqual(context['queue_msg'], expected)
......
...@@ -13,6 +13,9 @@ dateformat = '%Y%m%d%H%M%S' ...@@ -13,6 +13,9 @@ dateformat = '%Y%m%d%H%M%S'
XQUEUE_METRIC_NAME = 'edxapp.xqueue' XQUEUE_METRIC_NAME = 'edxapp.xqueue'
# Wait time for response from Xqueue.
XQUEUE_TIMEOUT = 35 # seconds
def make_hashkey(seed): 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