Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,3 @@ prune */spec
prune xblocks_contrib/problem/capa/static/js/capa/spec
prune xblocks_contrib/problem/capa/static/js/capa/fixtures
prune xblocks_contrib/problem/capa/tests/test_files

# --- TEST UTILITY INCLUSIONS ---
# Re-include specific test files that are excluded above.
# We do this because openedx-platform imports these specific test helpers.
include xblocks_contrib/problem/capa/tests/test_util.py
include xblocks_contrib/problem/capa/tests/helpers.py
include xblocks_contrib/problem/capa/tests/response_xml_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
is_codejail_rest_service_enabled,
)
from xblocks_contrib.problem.capa.safe_exec.safe_exec import emsg_normalizers, normalize_error_message
from xblocks_contrib.problem.capa.tests.test_util import UseUnsafeCodejail
from xblocks_contrib.problem.capa.testing.codejail import UseUnsafeCodejail


@UseUnsafeCodejail()
Expand Down
7 changes: 7 additions & 0 deletions xblocks_contrib/problem/capa/testing/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"""
Reusable capa testing utilities.

Unlike ``xblocks_contrib.problem.capa.tests``, this package ships in the
published distribution: it holds the fixtures that downstream test suites --
notably openedx-platform's -- import. Keep actual tests out of it.
"""
31 changes: 31 additions & 0 deletions xblocks_contrib/problem/capa/testing/codejail.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""Codejail controls for tests that execute capa problem code."""

import codejail.safe_exec
from django.test.utils import TestContextDecorator


class UseUnsafeCodejail(TestContextDecorator):
"""
Tell codejail to run in unsafe mode for the scope of the decorator.
Use this as a decorator on Django TestCase classes or methods.

This is needed because codejail has significant OS-level setup requirements
which we don't even attempt to fulfill for unit testing purposes. Running
tests in unsafe mode (that is, running code executions in-process, with no
sandboxing) is only safe because we control the contents of the unit tests.
It's not a perfect replica of how safe mode operates but it's generally good
enough for testing the integration and overall behavior.
"""

def __init__(self):
self.old_be_unsafe = None
super().__init__()

def enable(self):
"""Enable unsafe mode for codejail within the test scope."""
self.old_be_unsafe = codejail.safe_exec.ALWAYS_BE_UNSAFE
codejail.safe_exec.ALWAYS_BE_UNSAFE = True

def disable(self):
"""Restore the previous codejail unsafe mode state."""
codejail.safe_exec.ALWAYS_BE_UNSAFE = self.old_be_unsafe
2 changes: 1 addition & 1 deletion xblocks_contrib/problem/capa/tests/test_capa_problem.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@

from xblocks_contrib.problem.capa.correctmap import CorrectMap
from xblocks_contrib.problem.capa.responsetypes import LoncapaProblemError
from xblocks_contrib.problem.capa.testing.codejail import UseUnsafeCodejail
from xblocks_contrib.problem.capa.tests.helpers import new_loncapa_problem
from xblocks_contrib.problem.capa.tests.test_util import UseUnsafeCodejail
from xblocks_contrib.problem.markup import HTML


Expand Down
4 changes: 2 additions & 2 deletions xblocks_contrib/problem/capa/tests/test_html_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
import ddt
from lxml import etree

from xblocks_contrib.problem.capa.testing.codejail import UseUnsafeCodejail
from xblocks_contrib.problem.capa.tests.helpers import mock_capa_system, new_loncapa_problem
from xblocks_contrib.problem.capa.tests.test_util import UseUnsafeCodejail
from xblocks_contrib.problem.markup import HTML

from .response_xml_factory import CustomResponseXMLFactory, StringResponseXMLFactory
from ..testing.response_xml_factory import CustomResponseXMLFactory, StringResponseXMLFactory


@ddt.ddt
Expand Down
6 changes: 3 additions & 3 deletions xblocks_contrib/problem/capa/tests/test_responsetypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@

from xblocks_contrib.problem.capa.correctmap import CorrectMap
from xblocks_contrib.problem.capa.responsetypes import LoncapaProblemError, ResponseError, StudentInputError
from xblocks_contrib.problem.capa.tests.helpers import load_fixture, mock_capa_system, new_loncapa_problem
from xblocks_contrib.problem.capa.tests.response_xml_factory import (
from xblocks_contrib.problem.capa.testing.codejail import UseUnsafeCodejail
from xblocks_contrib.problem.capa.testing.response_xml_factory import (
AnnotationResponseXMLFactory,
ChoiceResponseXMLFactory,
ChoiceTextResponseXMLFactory,
Expand All @@ -38,7 +38,7 @@
SymbolicResponseXMLFactory,
TrueFalseResponseXMLFactory,
)
from xblocks_contrib.problem.capa.tests.test_util import UseUnsafeCodejail
from xblocks_contrib.problem.capa.tests.helpers import load_fixture, mock_capa_system, new_loncapa_problem
from xblocks_contrib.problem.capa.util import convert_files_to_filenames
from xblocks_contrib.problem.capa.xqueue_interface import DATEFORMAT

Expand Down
29 changes: 0 additions & 29 deletions xblocks_contrib/problem/capa/tests/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@

import unittest

import codejail.safe_exec
import ddt
from django.test.utils import TestContextDecorator
from lxml import etree

from xblocks_contrib.problem.capa.tests.helpers import mock_capa_system
Expand Down Expand Up @@ -167,30 +165,3 @@ def test_contextualize_text_with_non_ascii_context(self):
expected_text = "$あなたあなたあなたあなた あなたhi"
contextual_text = contextualize_text(text, context)
assert expected_text == contextual_text


class UseUnsafeCodejail(TestContextDecorator):
"""
Tell codejail to run in unsafe mode for the scope of the decorator.
Use this as a decorator on Django TestCase classes or methods.

This is needed because codejail has significant OS-level setup requirements
which we don't even attempt to fulfill for unit testing purposes. Running
tests in unsafe mode (that is, running code executions in-process, with no
sandboxing) is only safe because we control the contents of the unit tests.
It's not a perfect replica of how safe mode operates but it's generally good
enough for testing the integration and overall behavior.
"""

def __init__(self):
self.old_be_unsafe = None
super().__init__()

def enable(self):
"""Enable unsafe mode for codejail within the test scope."""
self.old_be_unsafe = codejail.safe_exec.ALWAYS_BE_UNSAFE
codejail.safe_exec.ALWAYS_BE_UNSAFE = True

def disable(self):
"""Restore the previous codejail unsafe mode state."""
codejail.safe_exec.ALWAYS_BE_UNSAFE = self.old_be_unsafe
2 changes: 1 addition & 1 deletion xblocks_contrib/problem/tests/test_capa_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
from xblocks_contrib.problem.capa import responsetypes
from xblocks_contrib.problem.capa.correctmap import CorrectMap
from xblocks_contrib.problem.capa.responsetypes import LoncapaProblemError, ResponseError, StudentInputError
from xblocks_contrib.problem.capa.tests.test_util import UseUnsafeCodejail
from xblocks_contrib.problem.capa.testing.codejail import UseUnsafeCodejail
from xblocks_contrib.problem.capa.xqueue_interface import XQueueInterface
from xblocks_contrib.problem.capa_block import ComplexEncoder, ProblemBlock
from xblocks_contrib.problem.tests import DATA_DIR
Expand Down