Skip to content

Commit 9fa5d02

Browse files
authored
feat: add integration tests (#331)
* feat: add integration tests * fix: fix the repo url and branch * fix: improve docs and remove try except to allow the fail * docs: improve test * refactor: improve the code with feedback * fix: test without codejail * Revert "fix: test without codejail" This reverts commit c4d48da. * fix: test that we can use the graders * fix: add matrixgrader in the test * fix: run the action monthly
1 parent 61184d6 commit 9fa5d02

File tree

2 files changed

+164
-0
lines changed

2 files changed

+164
-0
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
name: Integration Test
2+
3+
on:
4+
schedule:
5+
# Montlhy at 00:00
6+
- cron: '0 0 1 * *'
7+
8+
jobs:
9+
edx-platform-integration-test:
10+
name: Integration with Tutor
11+
strategy:
12+
matrix:
13+
# Open edX Version: Sumac
14+
tutor_version: ["<20.0.0"]
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Checkout
18+
uses: actions/checkout@v4
19+
with:
20+
path: mitx-grading-library
21+
22+
- name: Adjust permissions to execute Tutor commands
23+
run: |
24+
chmod 777 . -R
25+
shell: bash
26+
27+
- name: Set Tutor environment variables
28+
run: |
29+
cat <<EOF >> "$GITHUB_ENV"
30+
LMS_HOST=local.edly.io
31+
CMS_HOST=studio.local.edly.io
32+
TUTOR_ROOT=$(pwd)
33+
COURSE_KEY=course-v1:MITx+grading-library+course
34+
EOF
35+
shell: bash
36+
37+
- name: Install Tutor
38+
run: pip install "tutor${{ matrix.tutor_version }}"
39+
shell: bash
40+
41+
- name: Install, enable and initialize Tutor Codejail Plugin
42+
run: |
43+
pip install git+https://github.com/edunext/tutor-contrib-codejail
44+
tutor plugins enable codejail
45+
tutor local do init --limit codejail
46+
shell: bash
47+
48+
- name: Mount Integration Test
49+
run: tutor mounts add cms:mitx-grading-library/integration_tests/integration_test.py:/openedx/edx-platform/integration_test.py
50+
shell: bash
51+
52+
- name: Launch Tutor
53+
run: tutor local launch -I
54+
shell: bash
55+
56+
- name: Import MITx Demo Course
57+
run: |
58+
tutor local do importdemocourse -r ${{ github.event.pull_request.head.repo.clone_url }} -d course -v ${{ github.event.pull_request.head.ref }}
59+
shell: bash
60+
61+
- name: Run integration tests
62+
run: |
63+
tutor local run cms python integration_test.py "$COURSE_KEY"
64+
shell: bash
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
"""
2+
This script is used to test the integration of the mitx-graders library with the Open edX platform.
3+
Running a code that uses the functions provided by the library using the safe_exec function, and in the MIT course context,
4+
to be able to use the python_lib.zip that contains the library.
5+
"""
6+
7+
import logging
8+
import os
9+
import sys
10+
11+
import django
12+
from opaque_keys.edx.keys import CourseKey
13+
from xmodule.capa.safe_exec import safe_exec
14+
from xmodule.contentstore.django import contentstore
15+
from xmodule.util.sandboxing import SandboxService
16+
17+
# Set up Django environment
18+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cms.envs.test")
19+
django.setup()
20+
21+
log = logging.getLogger(__name__)
22+
23+
# Define the code to be executed
24+
GRADING_CLASSES_CODE = """
25+
# To test, we can use the custom graders
26+
from mitxgraders import (
27+
StringGrader,
28+
FormulaGrader,
29+
NumericalGrader,
30+
MatrixGrader,
31+
SingleListGrader,
32+
ListGrader,
33+
IntegralGrader,
34+
IntervalGrader,
35+
SumGrader,
36+
RealMatrices,
37+
RealVectors,
38+
ComplexRectangle,
39+
)
40+
41+
# Test the MatrixGrader, the class that uses the most external dependencies
42+
MatrixGrader(
43+
answers='x*A*B*u + z*C^3*v/(u*C*v)',
44+
variables=['A', 'B', 'C', 'u', 'v', 'z', 'x'],
45+
sample_from={
46+
'A': RealMatrices(shape=[2, 3]),
47+
'B': RealMatrices(shape=[3, 2]),
48+
'C': RealMatrices(shape=[2, 2]),
49+
'u': RealVectors(shape=[2]),
50+
'v': RealVectors(shape=[2]),
51+
'z': ComplexRectangle()
52+
},
53+
identity_dim=2
54+
)
55+
56+
"""
57+
58+
59+
def execute_code(course_key_str):
60+
"""
61+
Executes the provided code in a sandboxed environment with the specified course context.
62+
63+
Args:
64+
course_key_str (str): The string representation of the course key.
65+
66+
Returns:
67+
None
68+
"""
69+
course_key = CourseKey.from_string(course_key_str)
70+
sandbox_service = SandboxService(
71+
course_id=course_key,
72+
contentstore=contentstore
73+
)
74+
zip_lib = sandbox_service.get_python_lib_zip()
75+
76+
extra_files = []
77+
python_path = []
78+
79+
if zip_lib is not None:
80+
extra_files.append(("python_lib.zip", zip_lib))
81+
python_path.append("python_lib.zip")
82+
83+
safe_exec(
84+
code=GRADING_CLASSES_CODE,
85+
globals_dict={},
86+
python_path=python_path,
87+
extra_files=extra_files,
88+
slug="integration-test",
89+
limit_overrides_context=course_key_str,
90+
unsafely=False,
91+
)
92+
93+
94+
if __name__ == "__main__":
95+
if len(sys.argv) != 2:
96+
print("Usage: python integration_test.py <course_key>")
97+
sys.exit(1)
98+
99+
course_key_str = sys.argv[1]
100+
execute_code(course_key_str)

0 commit comments

Comments
 (0)