perf: avoid invoking codejail for problem response report
We don't need to execute instuctor code for the problem response report because we're grabbing existing student state and scores. Running codejail is expensive, slow, and risks report failures if there is CPU intensive instructor code that is run at times when the servers are already heavily loaded (and things start timing out). This came up in TNL-8183 (and many others).
This commit is contained in:
@@ -460,6 +460,11 @@ class ProblemBlock(
|
||||
'seed': user_state.state.get('seed'),
|
||||
},
|
||||
seed=user_state.state.get('seed'),
|
||||
# The main point of minimal_init=True here is to avoid invoking
|
||||
# codejail, which makes the reports take much longer to run,
|
||||
# and can also cause failures for CPU intensive instructor code
|
||||
# in problems.
|
||||
minimal_init=True,
|
||||
# extract_tree=False allows us to work without a fully initialized CapaModule
|
||||
# We'll still be able to find particular data in the XML when we need it
|
||||
extract_tree=False,
|
||||
|
||||
@@ -3179,7 +3179,14 @@ class ProblemBlockReportGenerationTest(unittest.TestCase):
|
||||
scope_ids = Mock(block_type='problem')
|
||||
descriptor = ProblemBlock(get_test_system(), scope_ids=scope_ids)
|
||||
descriptor.runtime = Mock()
|
||||
descriptor.data = '<problem/>'
|
||||
# Put a script tag so that codejail is normally invoked, to test that we
|
||||
# suppress that invocation when generating this report.
|
||||
descriptor.data = '''<problem>
|
||||
<script type="loncapa/python">
|
||||
x1 = random.randint(0, 100)
|
||||
</script>
|
||||
</problem>
|
||||
'''
|
||||
return descriptor
|
||||
|
||||
def test_generate_report_data_not_implemented(self):
|
||||
@@ -3210,3 +3217,17 @@ class ProblemBlockReportGenerationTest(unittest.TestCase):
|
||||
iterator = iter([self._user_state(suffix='_dynamath')])
|
||||
report_data = list(descriptor.generate_report_data(iterator))
|
||||
assert 0 == len(report_data)
|
||||
|
||||
def test_safe_exec_not_called(self):
|
||||
"""
|
||||
Make sure we're not calling instructor code when doing this report.
|
||||
|
||||
This relies on us passing minimal_init=True when making the
|
||||
LoncapaProblem. Without that, this whole suite will break because the
|
||||
data in the descriptor (self._get_descriptor()) will force capa to do
|
||||
initializations that are mocked out at the moment.
|
||||
"""
|
||||
with patch('capa.safe_exec.safe_exec') as mock_safe_exec:
|
||||
descriptor = self._get_descriptor()
|
||||
list(descriptor.generate_report_data(self._mock_user_state_generator(), 2))
|
||||
assert not mock_safe_exec.called
|
||||
|
||||
Reference in New Issue
Block a user