diff --git a/.circleci/config.yml b/.circleci/config.yml index 77deed95..12b7d3d0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,18 +18,15 @@ jobs: name: pytest of BABS no_output_timeout: 1h command: | - docker build \ - -t pennlinc/slurm-docker-ci:unstable \ - -f Dockerfile_testing . - - # Make a directory that will hold the test artifacts mkdir -p ${HOME}/e2e-testing docker run -it \ - -v ${PWD}:/tests \ + -v ${PWD}:/babs \ -v ${HOME}/e2e-testing:/test-temp:rw \ + -w /babs \ -h slurmctl --cap-add sys_admin \ --privileged \ - pennlinc/slurm-docker-ci:unstable \ + pennlinc/slurm-docker-ci:0.14 \ + bash -c "pip install -e .[tests] && \ pytest -n 4 -sv \ --durations=0 \ --timeout=300 \ @@ -37,7 +34,7 @@ jobs: --cov-report term-missing \ --cov-report xml:/test-temp/coverage.xml \ --cov=babs \ - /babs + /babs/tests/" - store_test_results: path: /home/circleci/e2e-testing/junit.xml @@ -54,22 +51,10 @@ jobs: - checkout: path: /home/circleci/src/babs - run: - name: pytest of BABS + name: e2e SLURM tests no_output_timeout: 1h command: | - docker build \ - -t pennlinc/slurm-docker-ci:unstable \ - -f Dockerfile_testing . - - # Make a directory that will hold the test artifacts - mkdir -p ${HOME}/e2e-testing - docker run -it \ - -v ${PWD}:/tests \ - -v ${HOME}/e2e-testing:/test-temp:rw \ - -h slurmctl --cap-add sys_admin \ - --privileged \ - pennlinc/slurm-docker-ci:unstable \ - /tests/tests/e2e-slurm/container/walkthrough-tests.sh + E2E_DIR=${HOME}/e2e-testing bash tests/e2e_in_docker.sh - run: name: clean up test artifacts diff --git a/Dockerfile_testing b/Dockerfile_testing deleted file mode 100644 index 4b0cff97..00000000 --- a/Dockerfile_testing +++ /dev/null @@ -1,6 +0,0 @@ -FROM pennlinc/slurm-docker-ci:0.14 - -# install BABS in development mode for proper coverage tracking -COPY . /babs -WORKDIR /babs -RUN pip install -e .[tests] diff --git a/docs/developer_how_to_test.rst b/docs/developer_how_to_test.rst index a3292243..2cd0bf13 100644 --- a/docs/developer_how_to_test.rst +++ b/docs/developer_how_to_test.rst @@ -25,8 +25,25 @@ Manually run pytest The easiest way to run pytest is to run the ``tests/pytest_in_docker.sh`` script from the root directory of BABS. -This will build a docker container that has a running SLURM job scheduler system. -It will also install the local copy of BABS and run the pytests in the container. +This runs the tests inside a Docker container that has a running SLURM job scheduler system, +and installs the local copy of BABS at runtime via volume mount. + +.. code-block:: bash + + bash tests/pytest_in_docker.sh + +To run the end-to-end walkthrough tests (``babs init`` → ``submit`` → ``merge``): + +.. code-block:: bash + + bash tests/e2e_in_docker.sh + +By default, e2e test artifacts go to a temporary directory under ``/tmp``. +To specify a location (e.g., for inspection after the run): + +.. code-block:: bash + + E2E_DIR=/path/to/output bash tests/e2e_in_docker.sh ----------------------------- Automatic pytest via CircleCI diff --git a/tests/e2e_in_docker.sh b/tests/e2e_in_docker.sh index 9de3de14..a571a449 100755 --- a/tests/e2e_in_docker.sh +++ b/tests/e2e_in_docker.sh @@ -1,17 +1,12 @@ #!/bin/bash -mkdir -p "${HOME}"/projects/e2e-testing -docker build --platform linux/amd64 \ - -t pennlinc/slurm-docker-ci:unstable \ - -f Dockerfile_testing . +E2E_DIR="${E2E_DIR:-$(mktemp -d /tmp/babs-e2e-XXXXXX)}" +mkdir -p "${E2E_DIR}" +echo "E2E_DIR=${E2E_DIR}" docker run -it \ --platform linux/amd64 \ - -v "${HOME}"/projects/babs:/tests \ - -v "${HOME}"/projects/e2e-testing:/test-temp:rw \ + -v "$(pwd)":/tests \ + -v "${E2E_DIR}":/test-temp:rw \ -h slurmctl --cap-add sys_admin \ --privileged \ - pennlinc/slurm-docker-ci:unstable #\ - #/babs/tests/e2e-slurm/container/walkthrough-tests.sh - - - #pytest -svx --pdb \ - #/babs/tests \ No newline at end of file + pennlinc/slurm-docker-ci:0.14 \ + /tests/tests/e2e-slurm/container/walkthrough-tests.sh diff --git a/tests/pytest_in_docker.sh b/tests/pytest_in_docker.sh index c8646923..4251d601 100755 --- a/tests/pytest_in_docker.sh +++ b/tests/pytest_in_docker.sh @@ -1,15 +1,14 @@ #!/bin/bash -docker build --platform linux/amd64 -t pennlinc/slurm-docker-ci:unstable -f Dockerfile_testing . docker run -it \ --platform linux/amd64 \ -h slurmctl --cap-add sys_admin \ --privileged \ - -v "${HOME}"/projects/babs:/babs \ - pennlinc/slurm-docker-ci:unstable \ - pytest -svx \ + -v "$(pwd)":/babs \ + -w /babs \ + pennlinc/slurm-docker-ci:0.14 \ + bash -c "pip install -e .[tests] && pytest -svx \ --cov-report=term-missing \ - --cov-report=xml \ + --cov-report=xml:/tmp/coverage.xml \ --cov=babs \ --pdb \ - /babs/tests/ - \ No newline at end of file + /babs/tests/" diff --git a/tests/test_generate_bidsapp_runscript.py b/tests/test_generate_bidsapp_runscript.py index 9c454475..19a34402 100644 --- a/tests/test_generate_bidsapp_runscript.py +++ b/tests/test_generate_bidsapp_runscript.py @@ -112,7 +112,7 @@ def test_get_input_unipping_cmds(): @pytest.mark.parametrize(('input_datasets', 'config_file', 'processing_level'), testing_pairs) -def test_generate_bidsapp_runscript(input_datasets, config_file, processing_level): +def test_generate_bidsapp_runscript(input_datasets, config_file, processing_level, tmp_path): """Test that the bidsapp runscript is generated correctly.""" config_path = NOTEBOOKS_DIR / config_file container_name = config_file.split('_')[1] @@ -130,7 +130,7 @@ def test_generate_bidsapp_runscript(input_datasets, config_file, processing_leve templateflow_home='/path/to/templateflow_home', ) - out_fn = Path('.') / f'{config_path.name}_{processing_level}.sh' + out_fn = tmp_path / f'{config_path.name}_{processing_level}.sh' with open(out_fn, 'w') as f: f.write(script_content) passed, status = run_shellcheck(str(out_fn)) @@ -164,7 +164,7 @@ def run_shellcheck(script_path): return False, str(e) -def test_generate_pipeline_runscript(): +def test_generate_pipeline_runscript(tmp_path): """Test that the pipeline runscript is generated correctly.""" config_path = NOTEBOOKS_DIR / 'eg_nordic-fmriprep_pipeline.yaml' config = read_yaml(config_path) @@ -180,7 +180,7 @@ def test_generate_pipeline_runscript(): final_zip_foldernames=config.get('zip_foldernames', {}), ) - out_fn = Path('.') / f'{config_path.name}_pipeline.sh' + out_fn = tmp_path / f'{config_path.name}_pipeline.sh' with open(out_fn, 'w') as f: f.write(script_content) passed, status = run_shellcheck(str(out_fn)) diff --git a/tests/test_generate_submit_script.py b/tests/test_generate_submit_script.py index 6d0868a3..62184ef0 100644 --- a/tests/test_generate_submit_script.py +++ b/tests/test_generate_submit_script.py @@ -91,7 +91,7 @@ @pytest.mark.parametrize(('input_datasets', 'config_file', 'processing_level'), testing_pairs) -def test_generate_submit_script(input_datasets, config_file, processing_level): +def test_generate_submit_script(input_datasets, config_file, processing_level, tmp_path): """Test that the bidsapp runscript is generated correctly.""" config_path = NOTEBOOKS_DIR / config_file container_name = config_file.split('_')[1] @@ -107,7 +107,7 @@ def test_generate_submit_script(input_datasets, config_file, processing_level): zip_foldernames=config['zip_foldernames'], ) - out_fn = Path('.') / f'participant_job_{config_path.name}_{processing_level}.sh' + out_fn = tmp_path / f'participant_job_{config_path.name}_{processing_level}.sh' with open(out_fn, 'w') as f: f.write(script_content) passed, status = run_shellcheck(str(out_fn))