Skip to content

Commit

Permalink
feat: add integration tests (#331)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
MaferMazu authored Jan 23, 2025
1 parent 61184d6 commit 9fa5d02
Show file tree
Hide file tree
Showing 2 changed files with 164 additions and 0 deletions.
64 changes: 64 additions & 0 deletions .github/workflows/integration-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Integration Test

on:
schedule:
# Montlhy at 00:00
- cron: '0 0 1 * *'

jobs:
edx-platform-integration-test:
name: Integration with Tutor
strategy:
matrix:
# Open edX Version: Sumac
tutor_version: ["<20.0.0"]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
path: mitx-grading-library

- name: Adjust permissions to execute Tutor commands
run: |
chmod 777 . -R
shell: bash

- name: Set Tutor environment variables
run: |
cat <<EOF >> "$GITHUB_ENV"
LMS_HOST=local.edly.io
CMS_HOST=studio.local.edly.io
TUTOR_ROOT=$(pwd)
COURSE_KEY=course-v1:MITx+grading-library+course
EOF
shell: bash

- name: Install Tutor
run: pip install "tutor${{ matrix.tutor_version }}"
shell: bash

- name: Install, enable and initialize Tutor Codejail Plugin
run: |
pip install git+https://github.com/edunext/tutor-contrib-codejail
tutor plugins enable codejail
tutor local do init --limit codejail
shell: bash

- name: Mount Integration Test
run: tutor mounts add cms:mitx-grading-library/integration_tests/integration_test.py:/openedx/edx-platform/integration_test.py
shell: bash

- name: Launch Tutor
run: tutor local launch -I
shell: bash

- name: Import MITx Demo Course
run: |
tutor local do importdemocourse -r ${{ github.event.pull_request.head.repo.clone_url }} -d course -v ${{ github.event.pull_request.head.ref }}
shell: bash

- name: Run integration tests
run: |
tutor local run cms python integration_test.py "$COURSE_KEY"
shell: bash
100 changes: 100 additions & 0 deletions integration_tests/integration_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
"""
This script is used to test the integration of the mitx-graders library with the Open edX platform.
Running a code that uses the functions provided by the library using the safe_exec function, and in the MIT course context,
to be able to use the python_lib.zip that contains the library.
"""

import logging
import os
import sys

import django
from opaque_keys.edx.keys import CourseKey
from xmodule.capa.safe_exec import safe_exec
from xmodule.contentstore.django import contentstore
from xmodule.util.sandboxing import SandboxService

# Set up Django environment
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cms.envs.test")
django.setup()

log = logging.getLogger(__name__)

# Define the code to be executed
GRADING_CLASSES_CODE = """
# To test, we can use the custom graders
from mitxgraders import (
StringGrader,
FormulaGrader,
NumericalGrader,
MatrixGrader,
SingleListGrader,
ListGrader,
IntegralGrader,
IntervalGrader,
SumGrader,
RealMatrices,
RealVectors,
ComplexRectangle,
)
# Test the MatrixGrader, the class that uses the most external dependencies
MatrixGrader(
answers='x*A*B*u + z*C^3*v/(u*C*v)',
variables=['A', 'B', 'C', 'u', 'v', 'z', 'x'],
sample_from={
'A': RealMatrices(shape=[2, 3]),
'B': RealMatrices(shape=[3, 2]),
'C': RealMatrices(shape=[2, 2]),
'u': RealVectors(shape=[2]),
'v': RealVectors(shape=[2]),
'z': ComplexRectangle()
},
identity_dim=2
)
"""


def execute_code(course_key_str):
"""
Executes the provided code in a sandboxed environment with the specified course context.
Args:
course_key_str (str): The string representation of the course key.
Returns:
None
"""
course_key = CourseKey.from_string(course_key_str)
sandbox_service = SandboxService(
course_id=course_key,
contentstore=contentstore
)
zip_lib = sandbox_service.get_python_lib_zip()

extra_files = []
python_path = []

if zip_lib is not None:
extra_files.append(("python_lib.zip", zip_lib))
python_path.append("python_lib.zip")

safe_exec(
code=GRADING_CLASSES_CODE,
globals_dict={},
python_path=python_path,
extra_files=extra_files,
slug="integration-test",
limit_overrides_context=course_key_str,
unsafely=False,
)


if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python integration_test.py <course_key>")
sys.exit(1)

course_key_str = sys.argv[1]
execute_code(course_key_str)

0 comments on commit 9fa5d02

Please sign in to comment.