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

Distribute tests #669

Merged
merged 10 commits into from
Oct 24, 2016
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ include requirements.txt
include setup.cfg
include setup.py
include test_requirements.txt
recursive-include odl/test test*.py *test.py
2 changes: 1 addition & 1 deletion conda/meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package:

source:
git_url: https://github.com/odlgroup/odl
git_rev: master # for testing, put any branch here
git_rev: distribute_tests # for testing, put any branch here
# git_rev: v0.5.0 # release

build:
Expand Down
6 changes: 3 additions & 3 deletions doc/source/getting_started/installing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ After that, follow the `build instructions there <https://github.com/odlgroup/od

ASTRA for X-ray tomography
==========================
To calculate fast forward and backward projections for image reconstruction in X-ray tomography, install the `ASTRA tomography toolbox`_.
To calculate fast forward and backward projections for image reconstruction in X-ray tomography, install the `ASTRA tomography toolbox <https://github.com/astra-toolbox/astra-toolbox>`_.
ASTRA projectors are fully supported in ODL.

You can try using the conda package, but we can give no guarantee that it works out of the box:
Expand All @@ -417,7 +417,7 @@ You can try using the conda package, but we can give no guarantee that it works

$ conda install -c astra-toolbox astra-toolbox

For further instructions, check `the ASTRA GitHub page <ASTRA tomography toolbox>`_.
For further instructions, check `the ASTRA GitHub page <https://github.com/astra-toolbox/astra-toolbox>`_.


STIR for emission tomography
Expand Down Expand Up @@ -467,5 +467,5 @@ If that does not help, `make an issue on GitHub <https://github.com/odlgroup/odl
.. _CVXPY: http://www.cvxpy.org/en/latest/
.. _odlcuda: https://github.com/odlgroup/odlcuda
.. _CUDA toolkit: https://developer.nvidia.com/cuda-toolkit
.. _ASTRA tomography toolbox: https://github.com/astra-toolbox/astra-toolbox
.. _ASTRA: https://github.com/astra-toolbox/astra-toolbox
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This link has to be wrong now?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the other one is inline now, I don't see a point in 3 different targets linking to the same page.

.. _STIR: https://github.com/UCL/STIR
7 changes: 7 additions & 0 deletions odl/test/test_doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@
from doctest import IGNORE_EXCEPTION_DETAIL, ELLIPSIS, NORMALIZE_WHITESPACE
import os
import pytest
try:
import matplotlib
matplotlib.use('Agg') # To avoid the backend freezing
import matplotlib.pyplot as plt
except ImportError:
pass

# Modules to be added to testing globals
import numpy
Expand Down Expand Up @@ -75,6 +81,7 @@ def test_file(doc_src_file):
doctest.testfile(doc_src_file, module_relative=False, report=True,
extraglobs=doctest_extraglobs, verbose=True,
optionflags=doctest_optionflags)
plt.close('all')


if __name__ == '__main__':
Expand Down
2 changes: 1 addition & 1 deletion odl/test/test_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def example(request):
reason='Need --examples option to run')
def test_example(example):
imp.load_source('tmp', example)
plt.close("all")
plt.close('all')


if __name__ == '__main__':
Expand Down
3 changes: 3 additions & 0 deletions odl/util/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,7 @@
from .numerics import *
__all__ += numerics.__all__

from .vectorization import *
__all__ += vectorization.__all__

from . import ufuncs
31 changes: 18 additions & 13 deletions conftest.py → odl/util/pytest_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,25 @@

import numpy as np
import operator
import pytest

import odl
from odl.trafos.backends import PYFFTW_AVAILABLE, PYWT_AVAILABLE
from odl.util import dtype_repr
from odl.util import dtype_repr, OptionalArgDecorator

try:
from pytest import fixture
except ImportError:
# Make trivial decorator
class fixture(OptionalArgDecorator):
@staticmethod
def _wrapper(f, *a, **kw):
return f


# --- Add numpy and ODL to all doctests ---


@pytest.fixture(autouse=True)
@fixture(autouse=True)
def add_doctest_np_odl(doctest_namespace):
doctest_namespace['np'] = np
doctest_namespace['odl'] = odl
Expand Down Expand Up @@ -71,7 +79,7 @@ def pytest_addoption(parser):
fn_impl_ids = [" impl='{}' ".format(p) for p in fn_impl_params]


@pytest.fixture(scope="module", ids=fn_impl_ids, params=fn_impl_params)
@fixture(scope="module", ids=fn_impl_ids, params=fn_impl_params)
def fn_impl(request):
"""String with an available `FnBase` implementation name."""
return request.param
Expand All @@ -80,8 +88,7 @@ def fn_impl(request):
ntuples_impl_ids = [" impl='{}' ".format(p) for p in ntuples_impl_params]


@pytest.fixture(scope="module", ids=ntuples_impl_ids,
params=ntuples_impl_params)
@fixture(scope="module", ids=ntuples_impl_ids, params=ntuples_impl_params)
def ntuples_impl(request):
"""String with an available `NtuplesBase` implementation name."""
return request.param
Expand All @@ -92,8 +99,7 @@ def ntuples_impl(request):
for dt in floating_dtype_params]


@pytest.fixture(scope="module", ids=floating_dtype_ids,
params=floating_dtype_params)
@fixture(scope="module", ids=floating_dtype_ids, params=floating_dtype_params)
def floating_dtype(request):
"""Floating point (real or complex) dtype."""
return request.param
Expand All @@ -106,8 +112,7 @@ def floating_dtype(request):
for dt in scalar_dtype_params]


@pytest.fixture(scope="module", ids=scalar_dtype_ids,
params=scalar_dtype_params)
@fixture(scope="module", ids=scalar_dtype_ids, params=scalar_dtype_params)
def scalar_dtype(request):
"""Scalar (integers or real or complex) dtype."""
return request.param
Expand All @@ -117,7 +122,7 @@ def scalar_dtype(request):
ufunc_ids = [' ufunc={} '.format(p[0]) for p in ufunc_params]


@pytest.fixture(scope="module", ids=ufunc_ids, params=ufunc_params)
@fixture(scope="module", ids=ufunc_ids, params=ufunc_params)
def ufunc(request):
"""Tuple with information on a ufunc.

Expand All @@ -139,7 +144,7 @@ def ufunc(request):
reduction_ids = [' reduction={} '.format(p[0]) for p in reduction_params]


@pytest.fixture(scope="module", ids=reduction_ids, params=reduction_params)
@fixture(scope="module", ids=reduction_ids, params=reduction_params)
def reduction(request):
"""Tuple with information on a reduction.

Expand All @@ -164,7 +169,7 @@ def reduction(request):
' += ', ' /= ', ' *= ', ' -= ']


@pytest.fixture(ids=arithmetic_op_ids, params=arithmetic_op_par)
@fixture(ids=arithmetic_op_ids, params=arithmetic_op_par)
def arithmetic_op(request):
"""An arithmetic operator, e.g. +, -, // etc."""
return request.param
3 changes: 2 additions & 1 deletion odl/util/vectorization.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@


__all__ = ('is_valid_input_array', 'is_valid_input_meshgrid',
'out_shape_from_meshgrid', 'out_shape_from_array', 'vectorize')
'out_shape_from_meshgrid', 'out_shape_from_array',
'OptionalArgDecorator', 'vectorize')


def is_valid_input_array(x, ndim=None):
Expand Down
39 changes: 27 additions & 12 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,12 @@
import sys


if os.environ.get('READTHEDOCS', None) == 'True':
# Mock requires in conf.py
requires = ''
test_requires = []
else:
requires = open(
os.path.join(os.path.dirname(__file__),
'requirements.txt')).readlines()
test_requires = open(
os.path.join(os.path.dirname(__file__),
'test_requirements.txt')).readlines()
root_path = os.path.dirname(__file__)


requires = open(os.path.join(root_path, 'requirements.txt')).readlines()
test_requires = open(
os.path.join(root_path, 'test_requirements.txt')).readlines()


class PyTest(TestCommand):
Expand All @@ -61,6 +56,23 @@ def run_tests(self):
errno = pytest.main(self.pytest_args)
sys.exit(errno)


test_path = os.path.join(root_path, 'odl/test')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

os.path.join(root_path, 'odl', test')

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, of course.



def find_tests():
tests = []
for path, _, filenames in os.walk(os.path.join(root_path, test_path)):
for filename in filenames:
basename, suffix = os.path.splitext(filename)
if (suffix == '.py' and
(basename.startswith('test') or
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is actually supposed to be _test and test_

See:

http://doc.pytest.org/en/latest/goodpractices.html

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I had that first, it was correct. Dunno why I changed it.

basename.endswith('test'))):
tests.append(os.path.join(path, filename))

return tests


long_description = """
Operator Discretization Library (ODL) is a Python library for fast prototyping focusing on (but not restricted to) inverse problems. ODL is being developed at `KTH Royal Institute of Technology <https://www.kth.se/en/sci/institutioner/math>`_.

Expand Down Expand Up @@ -124,8 +136,11 @@ def run_tests(self):

keywords='research development mathematics prototyping imaging tomography',

packages=find_packages(exclude=['*test*']),
packages=find_packages(),
package_dir={'odl': 'odl'},
package_data={'odl': find_tests()},
include_package_data=True,
entry_points={'pytest11': ['odl_plugins = odl.util.pytest_plugins']},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this make pytest find it? What does 11 mean?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is one of the 4 or 5 ways to extend pytest by custom "plugins". The mechanism I used is described here. The name "pytest11" is fixed and magic :-)


install_requires=[requires],
tests_require=['pytest'],
Expand Down
30 changes: 19 additions & 11 deletions tools/release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ fi
### PyPI upload

PYPI_DIST_DIR=$(cd dist && echo "$PWD") # Absolute path
PYPI_DIST_FILES="$(ls -1ad $PYPI_DIST_DIR/* | grep ${PACKAGE_NAME}-${VERSION})"
PYPI_DIST_FILES="$(find $PYPI_DIST_DIR/ -name ${PACKAGE_NAME}-${VERSION}*)"

if [[ -z $PYPI_DIST_FILES ]]; then
echo 'No distribution files found in the `dist` directory.'
Expand All @@ -63,6 +63,7 @@ fi
if [ $DRY_RUN -eq 1 ]; then
echo ""
echo "The following files would be uploaded to PyPI:"
echo ""
echo -e "$PYPI_DIST_FILES"
else
PYPI_USER=odlgroup
Expand All @@ -74,34 +75,41 @@ else
$TWINE upload -u $PYPI_USER $PYPI_DIST_FILES || exit 1
fi
fi


### Conda upload
CONDA_USER="odlgroup"
ANACONDA=$(which anaconda)

# Find conda build directory
if [ -n $CONDA_ENV_PATH ]; then
CONDA_BUILD_DIR="$CONDA_ENV_PATH/../../conda-bld"
if [ -z $CONDA_PREFIX ]; then
# Not in a conda env
CONDA=$(which conda)
CONDA_DIR=$(dirname $CONDA)
CONDA_BUILD_DIR="$CONDA_DIR/../conda-bld"
else
CONDA_BUILD_DIR="$(which conda)/../../conda-bld"
CONDA_BUILD_DIR="$CONDA_PREFIX/../../conda-bld"
fi

# Prettify path
cd $CONDA_BUILD_DIR || exit 1
CONDA_BUILD_DIR=$(pwd)
cd --

# Compile all files in the build folders corresponding to package and version
CONDA_DIST_FILES=""
CONDA_DIST_DIRS="linux-32 linux-64 osx-64 win-32 win-64"
CONDA_DIST_DIRS="linux-32 linux-64 osx-64 win-32 win-64 noarch"
for DIR in $CONDA_DIST_DIRS; do
if [ -d $CONDA_BUILD_DIR/$DIR ]; then
if [ -z $CONDA_DIST_FILES ]; then
CONDA_DIST_FILES="$(ls -1 $CONDA_BUILD_DIR/$DIR/$PACKAGE_NAME-$VERSION*)\n"
else
CONDA_DIST_FILES="$CONDA_DIST_FILES$(ls -1 $CONDA_BUILD_DIR/$DIR/$PACKAGE_NAME-$VERSION*)\n"
FOUND_FILES="$(find $CONDA_BUILD_DIR/$DIR -name $PACKAGE_NAME-$VERSION*)"

if [[ $FOUND_FILES != "\n" ]]; then
CONDA_DIST_FILES+="$FOUND_FILES\n"
fi
fi
done

# Do the upload (or pretend to)
if [ $DRY_RUN -eq 1 ]; then
echo ""
echo ""
echo "The following files would be uploaded to Anaconda Cloud:"
echo -e $CONDA_DIST_FILES
Expand Down