diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e9d34fbe..5ba1bcc4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,7 +9,7 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: psf/black@stable release: name: release @@ -23,7 +23,7 @@ jobs: with: release-type: python package-name: kimmdy - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: tag stable versions if: ${{ steps.release.outputs.release_created }} run: | @@ -34,3 +34,35 @@ jobs: git push origin :stable || true git tag -a stable -m "Last Stable Release" git push origin stable + prlabel: + runs-on: ubuntu-latest + outputs: + status: ${{ steps.prcheck.conclusion }} + steps: + - name: Check pr lable + id: prcheck + uses: jesusvasquez333/verify-pr-label-action@v1.4.0 + with: + github-token: '${{ secrets.GITHUB_TOKEN }}' + valid-labels: 'CI:run_test' + invalid-labels: '' + disable-reviews: true + test: + runs-on: ubuntu-latest + container: riedmiki/gromacs-plumed-python:2021 + needs: prlabel + if: needs.prlabel.outputs.status == 'success' + steps: + - uses : actions/checkout@v3 + - name: run tox + run: tox + - name: zip coverage report + if: ${{ !cancelled() }} + run: zip -r htmlcov.zip htmlcov || true + - uses: actions/upload-artifact@v3 + if: ${{ !cancelled() }} + with: + name: coverage artifact + path: htmlcov.zip + + diff --git a/.gitignore b/.gitignore index 64bff237..a007f418 100644 --- a/.gitignore +++ b/.gitignore @@ -68,7 +68,9 @@ pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports +artifacts htmlcov/ +htmlcov* .tox/ .nox/ .coverage diff --git a/README.md b/README.md index 857d9863..f6c00e78 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # KIMMDY +[![CI](https://github.com/hits-mbm-dev/kimmdy/actions/workflows/ci.yml/badge.svg)](https://github.com/hits-mbm-dev/kimmdy/actions/workflows/ci.yml) + Reactive MD pipeline for GROMACS using Kinetic Monte Carlo / Molecular Dynamics (KIMMDY) ## Quick start @@ -8,8 +10,16 @@ Reactive MD pipeline for GROMACS using Kinetic Monte Carlo / Molecular Dynamics * `cd kimmdy` * `python -m venv .venv` * `source ./venv/bin/activate` +* `python -m pip install -e ./` +* Some rections need a GROMACS version patched with PLUMED, gromacs name should then contain `MODIFIED` or `plumed` + +## Development setup + * `python -m pip install -r requirments.txt` -* Some rections need a GROMACS version patched with PLUMED +* code style: black +* docstrings: numpy +* [Conventional commit](https://www.conventionalcommits.org/en/v1.0.0/) messages when possible for pretty release notes. + ## First simulation @@ -19,3 +29,14 @@ Reactive MD pipeline for GROMACS using Kinetic Monte Carlo / Molecular Dynamics * check output: `kimmdy.log`, `test_out_00X/` +## Local testing + +For developoment, we provide a docker image containing gromacs and multiple python versions to test against. +To run the test locally, you must: +- install docker +- install [act](https://github.com/nektos/act), easiest option is with github cli + - install github cli (`gh`) + - `gh extension install https://github.com/nektos/gh-act` +- run tests with `gh extension exec act -j test --artifact-server-path ./artifacts` + - customize which python versions to test in `tox.ini` + - html coverage report is exported into `artifacts` diff --git a/plugins/setup.cfg b/plugins/setup.cfg index 9c1b3589..cfb4dc74 100644 --- a/plugins/setup.cfg +++ b/plugins/setup.cfg @@ -17,7 +17,6 @@ package_dir = =src include_package_data = True install_requires = - kimmdy MDAnalysis python_requires = >= 3.9 diff --git a/requirements.txt b/requirements.txt index 9448e5a4..b6c8d2b4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ tox black hypothesis jupyter -git+https://github.com/machow/quartodoc.git +# git+https://github.com/machow/quartodoc.git pydantic<2 -e . -e ./plugins diff --git a/src/kimmdy/utils.py b/src/kimmdy/utils.py index 2a86867d..ca0e3069 100644 --- a/src/kimmdy/utils.py +++ b/src/kimmdy/utils.py @@ -169,7 +169,7 @@ def check_gmx_version(config): """Check for an existing gromacs installation. If PLUMED is meant to be used it additionally checks for the keyword - 'MODIFIED' in the version name. + 'MODIFIED' or 'plumed' in the version name. """ try: version = [ @@ -184,18 +184,13 @@ def check_gmx_version(config): logging.error(m) raise SystemError(m) - # this should probably be a TODO: then - # i hate this - if ( - any( - "plumed" in y - for y in [ - config.mds.attr(x).get_attributes() for x in config.mds.get_attributes() - ] - ) - and not "MODIFIED" in version - ): - m = "GROMACS version does not contain MODIFIED, aborting due to lack of PLUMED patch." + if any( + "plumed" in y + for y in [ + config.mds.attr(x).get_attributes() for x in config.mds.get_attributes() + ] + ) and (not ("MODIFIED" in version or "plumed" in version)): + m = "GROMACS version does not contain MODIFIED or plumed, aborting due to lack of PLUMED patch." logging.error(m) logging.error("Version was: " + version) if not config.dryrun: diff --git a/tests/test_integration.py b/tests/test_integration.py index 59f9016c..fb56bf28 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -78,6 +78,7 @@ def test_grompp_with_kimmdy_topology(tmp_path): ) +@pytest.mark.slow def test_integration_hat_reaction(tmp_path, caplog): testdir = setup_testdir(tmp_path, "hat_naive") caplog.set_level(logging.INFO) @@ -91,6 +92,7 @@ def test_integration_hat_reaction(tmp_path, caplog): ) +@pytest.mark.slow def test_integration_homolysis_reaction(tmp_path, caplog): testdir = setup_testdir(tmp_path, "homolysis") caplog.set_level(logging.INFO) @@ -105,6 +107,7 @@ def test_integration_homolysis_reaction(tmp_path, caplog): ) +@pytest.mark.slow def test_integration_whole_run(tmp_path, caplog): testdir = setup_testdir(tmp_path, "whole_run") caplog.set_level(logging.INFO) diff --git a/tests/test_topology.py b/tests/test_topology.py index 7794f27a..030c9247 100644 --- a/tests/test_topology.py +++ b/tests/test_topology.py @@ -244,7 +244,10 @@ def test_break_bind_bond_hexala(self, hexala_top_fix): assert top.improper_dihedrals == og_top.improper_dihedrals @given(bondindex=st.integers(min_value=0, max_value=70)) - @settings(suppress_health_check=[HealthCheck.function_scoped_fixture]) + @settings( + suppress_health_check=[HealthCheck.function_scoped_fixture], deadline=1000 + ) + @pytest.mark.slow def test_break_bind_random_bond_hexala(self, hexala_top_fix, bondindex): top = deepcopy(hexala_top_fix) og_top = deepcopy(top) diff --git a/tox.ini b/tox.ini index 5260e422..b8e1efbd 100644 --- a/tox.ini +++ b/tox.ini @@ -1,13 +1,50 @@ [tox] envlist = - py38 + clean + lint py39 py310 + py311 + report [testenv] +description = run tests +package_root = + ./ + plugins deps = pytest pytest-cov pytest-randomly + hypothesis + ; installes editable, packaged would be better: + -r requirements.txt + ; would work if extra would be public: + ; extras = plugins commands = - pytest --cov=kimmdy --randomly-seed=1 \ No newline at end of file + pytest -m "not slow" --durations=15 --cov=kimmdy --randomly-seed=1 + ; pytest --cov=kimmdy --randomly-seed=1 + ; pytest --cov=kimmdy --cov-append --randomly-seed=1 + ; only test discovery: + ; pytest --cov=kimmdy --randomly-seed=1 --co + +[testenv:lint] +description = run black +skip_install = true +deps = + black +commands = + black src tests + +[testenv:clean] +deps = coverage +skip_install = true +commands = coverage erase + +[testenv:report] +deps = coverage +skip_install = true +commands = + coverage report + coverage html +