forked from Deep-MI/FastSurfer
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request Deep-MI#549 from taha-abdullah/pytest
Migrating Quicktest to PyTest and adding dockerized self hosted runner
- Loading branch information
Showing
16 changed files
with
967 additions
and
217 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,90 +1,109 @@ | ||
name: FastSurfer Singularity | ||
name: quicktest | ||
|
||
# File: quicktest.yaml | ||
# Author: Taha Abdullah | ||
# Created on: 2023-03-04 | ||
# Functionality: This workflow runs some quick integration tests on FastSurfer commits. It checks out the new | ||
# FastSurfer repo, sets up Python, builds a Singularity image, runs FastSurfer on sample MRI data, and | ||
# runs pytest to check if the results are acceptable | ||
# Usage: This workflow is exclusively triggered manually with workflow-dispatch in DeepMI/FastSurfer. | ||
|
||
|
||
on: | ||
# pull_request: | ||
workflow_dispatch: | ||
|
||
jobs: | ||
# Checkout repo | ||
checkout: | ||
runs-on: ci-gpu | ||
runs-on: self-hosted | ||
steps: | ||
- uses: actions/checkout@v2 | ||
|
||
# Prepare job: Set up Python, Go, Singularity | ||
# Prepare job: Set up Python, Go, Apptainer | ||
prepare-job: | ||
runs-on: ci-gpu | ||
runs-on: self-hosted | ||
needs: checkout | ||
steps: | ||
- name: Set up Python 3.10 | ||
uses: actions/setup-python@v3 | ||
with: | ||
python-version: "3.10" | ||
- name: Set up Go | ||
uses: actions/setup-go@v5 | ||
with: | ||
go-version: '^1.13.1' # The Go version to download (if necessary) and use. | ||
- name: Install package | ||
run: | | ||
python -m pip install --progress-bar off --upgrade pip setuptools wheel | ||
python -m pip install --progress-bar off .[test] | ||
# - name: Set up Go | ||
# uses: actions/setup-go@v5 | ||
# with: | ||
# go-version: '^1.13.1' # The Go version to download (if necessary) and use. | ||
- name: Set up Singularity | ||
uses: eWaterCycle/setup-singularity@v7 | ||
with: | ||
singularity-version: 3.8.3 | ||
# Build Docker Image and convert it to Singularity | ||
build-singularity-image: | ||
runs-on: ci-gpu | ||
singularity-version: 3.8.7 | ||
|
||
# Build Docker Image and convert it to Apptainer | ||
build-apptainer-image: | ||
runs-on: self-hosted | ||
needs: prepare-job | ||
steps: | ||
- name: Build Docker Image and convert to Singularity | ||
- name: Build Docker Image and convert to Apptainer | ||
run: | | ||
cd $RUNNER_SINGULARITY_IMGS | ||
cd $RUNNER_FASTSURFER_IMGS | ||
FILE="fastsurfer-gpu.sif" | ||
if [ ! -f "$FILE" ]; then | ||
# If the file does not exist, build the file | ||
echo "SIF File does not exist. Building file." | ||
PYTHONPATH=$PYTHONPATH | ||
cd $PYTHONPATH | ||
cd $FASTSURFER_HOME | ||
python3 Docker/build.py --device cuda --tag fastsurfer_gpu:cuda | ||
cd $RUNNER_SINGULARITY_IMGS | ||
singularity build --force fastsurfer-gpu.sif docker-daemon://fastsurfer_gpu:cuda | ||
apptainer build --force fastsurfer-gpu.sif docker-daemon://fastsurfer_gpu:cuda | ||
else | ||
echo "File already exists" | ||
cd $PYTHONPATH | ||
cd $FASTSURFER_HOME | ||
fi | ||
# Run FastSurfer on MRI data | ||
run-fastsurfer: | ||
runs-on: ci-gpu | ||
needs: build-singularity-image | ||
runs-on: self-hosted | ||
needs: build-apptainer-image | ||
steps: | ||
- name: Run FastSurfer | ||
run: | | ||
singularity exec --nv \ | ||
cd $RUNNER_FS_OUTPUT | ||
# DIRECTORY="subjectX" | ||
echo "pwd: $(pwd)" | ||
# if [ -d "$DIRECTORY" ]; then | ||
# # if output already exists, delete it and run again | ||
# echo "Output already exists. Deleting output directory and running FastSurfer again." | ||
# rm -rf $DIRECTORY | ||
# fi | ||
apptainer exec --nv \ | ||
--no-home \ | ||
--bind $GITHUB_WORKSPACE:/fastsurfer-dev \ | ||
--env FASTSURFER_HOME=/fastsurfer-dev \ | ||
-B $RUNNER_FS_MRI_DATA:/data \ | ||
-B $RUNNER_FS_OUTPUT:/output \ | ||
-B $RUNNER_FS_LICENSE:/fs_license \ | ||
$RUNNER_SINGULARITY_IMGS/fastsurfer-gpu.sif \ | ||
/fastsurfer/run_fastsurfer.sh \ | ||
-B $RUNNER_FS_LICENSE:/fs_license/.license \ | ||
$RUNNER_FASTSURFER_IMGS/fastsurfer-gpu.sif \ | ||
/fastsurfer/brun_fastsurfer.sh \ | ||
--fs_license /fs_license/.license \ | ||
--t1 /data/subjectx/orig.mgz \ | ||
--sid subjectX --sd /output \ | ||
--parallel --3T | ||
--subject_list /data/subject_list.txt \ | ||
--sd /output \ | ||
--parallel --3T \ | ||
--parallel_subjects surf | ||
# Test file existence | ||
test-file-existence: | ||
runs-on: ci-gpu | ||
needs: run-fastsurfer | ||
steps: | ||
- name: Test File Existence | ||
run: | | ||
python3 test/quick_test/test_file_existence.py $RUNNER_FS_OUTPUT_FILES | ||
# Test for errors in log files | ||
test-error-messages: | ||
runs-on: ci-gpu | ||
needs: [run-fastsurfer, test-file-existence] | ||
steps: | ||
- name: Test Log Files For Error Messages | ||
run: | | ||
python3 test/quick_test/test_errors.py $RUNNER_FS_OUTPUT_LOGS | ||
# Run pytest | ||
run-pytest: | ||
runs-on: self-hosted | ||
needs: run-fastsurfer | ||
steps: | ||
- name: Set up Python 3.10 | ||
uses: actions/setup-python@v3 | ||
with: | ||
python-version: "3.10" | ||
- name: Install package | ||
run: | | ||
python -m pip install --progress-bar off --upgrade pip setuptools wheel | ||
python -m pip install --progress-bar off .[test] | ||
- name : Run pytest | ||
run: pytest test/quick_test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
name: quicktest-runner | ||
|
||
# File: quicktest_runner.yaml | ||
# Author: Taha Abdullah | ||
# Created on: 2023-07-10 | ||
# Functionality: This workflow runs FastSurfer on MRI data and runs pytest to check if the results are acceptable. It | ||
# also checks if the FastSurfer environment and output already exist, and if not, it creates them. | ||
# Usage: This workflow is triggered on a pull request to the dev and main branch. It can also be triggered manually | ||
# with workflow-dispatch. | ||
# Expected/Used Environment Variables: | ||
# - MAMBAPATH: Path to the micromamba binary. | ||
# - MAMBAROOT: Root path for micromamba. | ||
# - RUNNER_FS_OUTPUT: Path to the directory where FastSurfer output is stored. | ||
# - RUNNER_FS_MRI_DATA: Path to the directory where MRI data is stored. | ||
# - FREESURFER_HOME: Path to the freesurfer directory. | ||
# - FS_LICENSE: Path to the FreeSurfer license file. | ||
|
||
on: | ||
pull_request: | ||
branches: | ||
- dev | ||
- stable | ||
workflow_dispatch: | ||
|
||
jobs: | ||
# Checkout repo | ||
checkout: | ||
runs-on: self-hosted | ||
steps: | ||
- uses: actions/checkout@v2 | ||
|
||
# Create conda environment, install packages, and run Fastsurfer | ||
run-fastsurfer: | ||
runs-on: self-hosted | ||
needs: checkout | ||
steps: | ||
# Check if the Environment Variables used in further steps are present | ||
- name: Check Environment Variables | ||
run: | | ||
REQUIRED_ENV_VARS=( | ||
"MAMBAPATH" | ||
"MAMBAROOT" | ||
"RUNNER_FS_OUTPUT" | ||
"RUNNER_FS_MRI_DATA" | ||
"FREESURFER_HOME" | ||
"FS_LICENSE" | ||
) | ||
for VAR_NAME in "${REQUIRED_ENV_VARS[@]}"; do | ||
if [ -z "${!VAR_NAME}" ]; then | ||
echo "Error: Required environment variable $VAR_NAME is not set" | ||
exit 1 | ||
fi | ||
done | ||
if [ ! -f "$FS_LICENSE" ]; then | ||
echo "Error: FreeSurfer license file does not exist at $FS_LICENSE" | ||
exit 1 | ||
fi | ||
if [ ! -d "$FREESURFER_HOME" ]; then | ||
echo "Error: FreeSurfer installation directory does not exist at $FREESURFER_HOME" | ||
exit 1 | ||
fi | ||
# Run FastSurfer on test subjects | ||
- name: Run FastSurfer | ||
run: | | ||
echo "Running FastSurfer..." | ||
echo "Output will be saved in data/${GITHUB_SHA:0:7}" | ||
export FASTSURFER_HOME=$(pwd) | ||
export THIS_RUN_OUTDIR=${GITHUB_SHA:0:7} | ||
mkdir -p $SUBJECTS_DIR/$THIS_RUN_OUTDIR | ||
export TEST_DIR=$THIS_RUN_OUTDIR | ||
./brun_fastsurfer.sh --subject_list $RUNNER_FS_MRI_DATA/subjects_list.txt \ | ||
--sd $SUBJECTS_DIR/$THIS_RUN_OUTDIR \ | ||
--parallel --threads 4 --3T --parallel_subjects surf | ||
# Test fastsurfer output | ||
run-pytest: | ||
runs-on: self-hosted | ||
if: always() | ||
needs: run-fastsurfer | ||
steps: | ||
- name: Run pytest | ||
run: | | ||
source /venv-pytest/bin/activate | ||
python -m pytest test/quick_test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,5 @@ | ||
|
||
|
||
|
||
__all__ = [ # This is a list of modules that should be imported when using the import * syntax | ||
'test_file_existence', | ||
'test_error_messages', | ||
'test_errors' | ||
] | ||
__all__ = [ # This is a list of modules that should be imported when using the import * syntax | ||
"test_file_existence", | ||
"test_error_messages", | ||
"test_errors", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import os | ||
from logging import getLogger | ||
|
||
logger = getLogger(__name__) | ||
|
||
|
||
__all__ = ["load_test_subjects"] | ||
|
||
|
||
def load_test_subjects(): | ||
""" | ||
Load the test files from the given file path. | ||
Returns: | ||
test_subjects (list): List of subjects to test subjects. | ||
""" | ||
|
||
subjects_dir = os.environ["SUBJECTS_DIR"] | ||
subjects_list = os.environ["SUBJECTS_LIST"] | ||
|
||
test_subjects = [] | ||
|
||
# Load the reference and test files | ||
with open(os.path.join(subjects_dir, subjects_list)) as file: | ||
for line in file: | ||
filename = line.strip() | ||
logger.debug(filename) | ||
# test_file = os.path.join(subjects_dir, filename) | ||
test_subjects.append(filename) | ||
|
||
return test_subjects |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import os | ||
from pathlib import Path | ||
|
||
import pytest | ||
|
||
__all__ = ["subjects_dir", "test_dir", "reference_dir", "subjects_list"] | ||
|
||
|
||
@pytest.fixture | ||
def subjects_dir(): | ||
return Path(os.environ["SUBJECTS_DIR"]) | ||
|
||
|
||
@pytest.fixture | ||
def test_dir(): | ||
return Path(os.environ["TEST_DIR"]) | ||
|
||
|
||
@pytest.fixture | ||
def reference_dir(): | ||
return Path(os.environ["REFERENCE_DIR"]) | ||
|
||
|
||
@pytest.fixture | ||
def subjects_list(): | ||
return Path(os.environ["SUBJECTS_LIST"]) |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
errors: | ||
- "error" | ||
- "error:" | ||
- "exception" | ||
- "traceback" | ||
|
||
whitelist: | ||
- "without error" | ||
- "not included" | ||
- "distance" | ||
- "correcting" | ||
- "error=" | ||
- "rms error" | ||
- "mcsrch error" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
default_threshold: 0.01 | ||
|
||
thresholds: | ||
BrainSegVol: 0.1 | ||
BrainSegVolNotVent: 0.1 | ||
VentricleChoroidVol: 0.1 | ||
lhCortexVol: 0.1 | ||
rhCortexVol: 0.1 | ||
CortexVol: 0.1 | ||
lhCerebralWhiteMatterVol: 0.1 | ||
rhCerebralWhiteMatterVol: 0.1 | ||
CerebralWhiteMatterVol: 0.1 | ||
SubCortGrayVol: 0.1 | ||
TotalGrayVol: 0.1 | ||
SupraTentorialVol: 0.1 | ||
SupraTentorialVolNotVent: 0.1 | ||
MaskVol: 0.1 | ||
BrainSegVol-to-eTIV: 0.1 | ||
MaskVol-to-eTIV: 0.1 | ||
lhSurfaceHoles: 0.1 | ||
rhSurfaceHoles: 0.1 | ||
SurfaceHoles: 0.1 | ||
eTIV: 0.1 |
Oops, something went wrong.