Skip to content

Commit

Permalink
Merge pull request #78 from MachineLearningLifeScience/feature-better…
Browse files Browse the repository at this point in the history
…-testing

Test using `docker` & add `RaSP` to testing
  • Loading branch information
miguelgondu authored Nov 1, 2023
2 parents 3273c8f + f785116 commit 7074477
Show file tree
Hide file tree
Showing 25 changed files with 493 additions and 408 deletions.
38 changes: 38 additions & 0 deletions .github/workflows/python-tox-testing-including-conda-on-master.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Test (master, conda, python 3.9)

on:
pull_request:
branches:
- master

jobs:
build-linux:
runs-on: ubuntu-latest
strategy:
max-parallel: 5

steps:
- uses: actions/checkout@v3
- name: Set up Python 3.9
uses: actions/setup-python@v3
with:
python-version: '3.9'
- name: Add conda to system path
run: |
# $CONDA is an environment variable pointing to the root of the miniconda directory
echo $CONDA/bin >> $GITHUB_PATH
- name: Install dependencies
run: |
python -m pip install tox
- name: Test linting with tox
run: |
tox -c tox.master.ini -e lint
- name: Test poli-base with tox
run: |
tox -c tox.master.ini -e poli-base-py39
- name: Test poli-chem with tox
run: |
tox -c tox.master.ini -e poli-chem-py39
- name: Test poli-protein with tox
run: |
tox -c tox.master.ini -e poli-protein-py39
14 changes: 4 additions & 10 deletions .github/workflows/python-tox-testing-including-conda.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Test (conda, python 3.9)
name: Test (dev, conda, python 3.9)

on: [push]

Expand All @@ -23,13 +23,7 @@ jobs:
python -m pip install tox
- name: Test linting with tox
run: |
tox -e lint
- name: Test poli-base with tox
tox -c tox.dev.ini -e lint
- name: Test poli-base with tox (ignoring RaSP)
run: |
tox -e poli-base-py39
- name: Test poli-chem with tox
run: |
tox -e poli-chem-py39
- name: Test poli-protein with tox
run: |
tox -e poli-protein-py39
tox -c tox.dev.ini -e poli-base-py39 -- --ignore=src/poli/tests/registry/proteins/test_rasp.py
17 changes: 15 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,28 @@ pip install black
black ./path/to/files
```

## Testing your changes
## Testing your changes for `dev``

Since we are testing multiple conda environments, we settled for using a combination of `tox` and `pytest`.

```bash
pip install tox
tox # from root of project

# To test linting (from the root of the project)
tox -c tox.dev.ini -e lint

# To test in the base environment for poli
tox -c tox.dev.ini -e poli-base-py39
```

If you want to run tests in all environments, remove `-e poli-base-py39` and just run `tox`.

## More thorough testing

In many cases, testing with the instructions above should be enough. However, since we are dealing with creating conda environments, the definite test comes by building the Docker image specified in `Dockerfile.test`, and running it.

When contributing to the `@master` branch (i.e. to release), we will run these tests.

## Create a pull request to dev

Once all tests pass and you are ready to share your changes, create a pull request to the `dev` branch.
34 changes: 34 additions & 0 deletions Dockerfile.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# This dockerfile allows us to run the tests in a container
FROM --platform=linux/amd64 continuumio/anaconda3:latest

# Set working directory
WORKDIR /app

# Copying the files from the host to the container
COPY ./src /app/src
COPY ./pyproject.toml /app/
COPY ./setup.cfg /app/
COPY ./requirements.txt /app/
COPY ./requirements-dev.txt /app/
COPY ./tox.ini /app/

# Installing distutils
RUN apt-get update && \
apt-get install build-essential -y && \
apt-get install -y python3.9-distutils

# Installing python dependencies
RUN conda --version
RUN pip install -r requirements.txt
RUN pip install -r requirements-dev.txt

# Creating the relevant conda environments
# For chem
RUN conda env create --file src/poli/objective_repository/rdkit_qed/environment.yml

# For proteins
RUN conda env create --file src/poli/objective_repository/foldx_stability/environment.yml
RUN conda env create --file src/poli/objective_repository/rasp/environment.yml

# Running the tests
CMD ["tox"]
1 change: 1 addition & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
black
tox
setuptools
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
python
numpy
4 changes: 4 additions & 0 deletions src/poli/core/util/proteins/rasp/rasp_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import os, stat
import subprocess
import logging
import traceback

import pandas as pd
import numpy as np
Expand Down Expand Up @@ -138,6 +139,8 @@ def get_and_compile_reduce(self):
check=True,
)
except subprocess.CalledProcessError:
# Printing the traceback
traceback.print_exc()
raise RuntimeError(
"Could not clone the reduce repository. "
"Please check your internet connection."
Expand All @@ -153,6 +156,7 @@ def get_and_compile_reduce(self):
)
except subprocess.CalledProcessError:
# TODO: should we be purging it ourselves?
traceback.print_exc()
raise RuntimeError(
"Something went wrong while compiling reduce. "
"Purge the folder ~/.poli_objectives/rasp/reduce "
Expand Down
4 changes: 0 additions & 4 deletions src/poli/objective_repository/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@
from .white_noise.register import WhiteNoiseProblemFactory
from .aloha.register import AlohaProblemFactory

# These have more complex dependencies
# from .super_mario_bros.register import SuperMarioBrosBlackBox
# from .rdkit_qed.register import QEDBlackBox


THIS_DIR = Path(__file__).parent.resolve()

Expand Down
2 changes: 2 additions & 0 deletions src/poli/objective_repository/foldx_sasa/environment.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
name: poli__protein
channels:
- defaults
- conda-forge
dependencies:
- python=3.9
- gcc
- pip
- pip:
- biopython
Expand Down
2 changes: 2 additions & 0 deletions src/poli/objective_repository/foldx_stability/environment.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
name: poli__protein
channels:
- defaults
- conda-forge
dependencies:
- python=3.9
- gcc
- pip
- pip:
- biopython
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
name: poli__protein
channels:
- defaults
- conda-forge
dependencies:
- python=3.9
- gcc
- pip
- pip:
- biopython
Expand Down
2 changes: 2 additions & 0 deletions src/poli/objective_repository/rasp/environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ dependencies:
- mpl-scatter-density
- clang
- cmake
- make
- gcc
- pip
- pip:
- "git+https://github.com/MachineLearningLifeScience/poli.git@dev"
Expand Down
Empty file.
21 changes: 21 additions & 0 deletions src/poli/tests/registry/basic_objectives/test_basic_objectives.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from pathlib import Path

import numpy as np

from poli import objective_factory

THIS_DIR = Path(__file__).parent.resolve()


def test_registering_white_noise():
_, f, _, _, _ = objective_factory.create(name="white_noise")
x = np.array([["A", "B", "C", "D"]])
f(x)
f.terminate()


def test_registering_aloha():
_, f, _, y0, _ = objective_factory.create(name="aloha")
x = np.array([list("ALOOF")])
assert f(x) == 3
f.terminate()
Empty file.
File renamed without changes.
148 changes: 148 additions & 0 deletions src/poli/tests/registry/chemistry/test_chemistry_objectives.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import pytest
from pathlib import Path

import numpy as np

from poli import objective_factory

THIS_DIR = Path(__file__).parent.resolve()


def test_qed_is_available():
"""
We test whether the qed problem is available
when rdkit and selfies are installed.
"""
_ = pytest.importorskip("rdkit")
_ = pytest.importorskip("selfies")
from poli.objective_repository import AVAILABLE_PROBLEM_FACTORIES

assert "rdkit_qed" in AVAILABLE_PROBLEM_FACTORIES


def test_logp_is_available():
"""
We test whether the logp problem is available
when rdkit and selfies are installed.
"""
_ = pytest.importorskip("rdkit")
_ = pytest.importorskip("selfies")
from poli.objective_repository import AVAILABLE_PROBLEM_FACTORIES

assert "rdkit_logp" in AVAILABLE_PROBLEM_FACTORIES


def test_force_registering_qed():
"""
We test whether we can force-register the qed problem
if rdkit and selfies are not installed.
"""
alphabet = ["", "C", "..."]
_, f, _, y0, _ = objective_factory.create(
name="rdkit_qed",
alphabet=alphabet,
force_register=True,
)

# Asserting that the QED of a single carbon
# is close to 0.35978494 (according to RDKit).
assert np.isclose(y0, 0.35978494).all()
f.terminate()


def test_force_registering_qed_with_context_manager():
"""
Tests the objective_factory.start method on QED.
"""
with objective_factory.start(
name="rdkit_qed",
force_register=True,
force_isolation=True,
path_to_alphabet=THIS_DIR / "alphabet_qed.json",
) as f:
x = np.array([["C"]])
y = f(x)
assert np.isclose(y, 0.35978494).all()


def test_force_registering_logp():
"""
We test whether we can force-register the logp problem
if rdkit and selfies are not installed.
"""
alphabet = ["", "C", ""]
_, f, _, y0, _ = objective_factory.create(
name="rdkit_logp",
alphabet=alphabet,
# path_to_alphabet=THIS_DIR / "alphabet_qed.json",
force_register=True,
)

# Asserting that a single carbon atom has logp close
# to 0.6361. (according to RDKit)
assert np.isclose(y0, 0.6361).all()
f.terminate()


def test_registering_qed():
"""
Testing whether we can register the qed problem
if rdkit and selfies are installed.
"""
_ = pytest.importorskip("rdkit")
_ = pytest.importorskip("selfies")
np = pytest.importorskip("numpy")

_, f, _, y0, _ = objective_factory.create(
name="rdkit_qed",
path_to_alphabet=THIS_DIR / "alphabet_qed.json",
)
x = np.array([["C"]])
y = f(x)

# Asserting that the QED of a single carbon
# is close to 0.35978494 (according to RDKit).
assert np.isclose(y, 0.35978494).all()

f.terminate()


def test_registering_logp():
"""
Testing whether we can register the logp problem
if rdkit and selfies are installed.
"""
rdkit = pytest.importorskip("rdkit")
selfies = pytest.importorskip("selfies")
np = pytest.importorskip("numpy")

_, f, _, y0, _ = objective_factory.create(
name="rdkit_logp",
path_to_alphabet=THIS_DIR / "alphabet_qed.json",
)
x = np.array([[1]])
f(x)

# Asserting that a single carbon atom has logp close
# to 0.6361. (according to RDKit)
assert np.isclose(y0, 0.6361).all()

f.terminate()


def test_penalized_logp_lambo():
"""
Testing whether we can register the logp problem
from lambo.
"""
from poli import objective_factory

_ = pytest.importorskip("lambo")

# Using create
_, f, x0, y0, _ = objective_factory.create(
name="penalized_logp_lambo", force_register=True
)
print(x0)
print(y0)
f.terminate()
File renamed without changes.
File renamed without changes.
Empty file.
Loading

0 comments on commit 7074477

Please sign in to comment.