Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add integration tests #331

Merged
merged 10 commits into from
Jan 23, 2025
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
MaferMazu marked this conversation as resolved.
Show resolved Hide resolved
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)
Loading