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 all 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
12 changes: 9 additions & 3 deletions .pypirc
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
[distutils]
index-servers=pypi
index-servers=
pypi
pypitest

[pypi]
repository = https://pypi.python.org/pypi
username = kohr-h
repository = https://upload.pypi.org/legacy
username = odlgroup

[pypitest]
repository = https://test.pypi.org/legacy
username = kohr-h
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ before_script:

script:
# Run tests, including PEP8 check, and produce a coverage report
- py.test --doctest-modules --cov --cov-report term-missing --pep8
- py.test --doctest-modules --cov --cov-report term-missing --pep8 $TRAVIS_BUILD_DIR/odl
# Build the Sphinx doc (only for Python 3.5 and the master branch)
- if [[ "$TRAVIS_PYTHON_VERSION" == "3.5" && "$TRAVIS_BRANCH" == "master" ]]; then
cd $TRAVIS_BUILD_DIR/doc/source && python generate_doc.py && cd -;
Expand Down
3 changes: 3 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ include requirements.txt
include setup.cfg
include setup.py
include test_requirements.txt
include odl/pytest.ini
exclude pytest.ini
recursive-include odl/test test*.py *test.py
8 changes: 5 additions & 3 deletions conda/meta.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package:
name: odl
version: "0.5.0"
version: "0.5.1"

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

build:
noarch_python: True
Expand All @@ -30,6 +30,8 @@ requirements:
test:
imports:
- odl
commands:
- python -c "import odl; odl.test()"

about:
home: https://github.com/odlgroup/odl
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
6 changes: 6 additions & 0 deletions doc/source/release_notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ Release Notes
Next release
============

ODL 0.5.1 Release Notes (2016-10-22)
====================================

This is a maintenance release since the test suite was not bundled with PyPI and Conda packages as intended already in 0.5.0.
From this version on, users can run ``python -c "import odl; odl.test()"`` with all types of installations (from PyPI, Conda or from source).


ODL 0.5.0 Release Notes (2016-10-21)
====================================
Expand Down
2 changes: 1 addition & 1 deletion odl/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

from __future__ import absolute_import

__version__ = '0.5.0'
__version__ = '0.5.1'
__all__ = ('diagnostics', 'discr', 'operator', 'set', 'space', 'solvers',
'tomo', 'trafos', 'util', 'phantom', 'deform')

Expand Down
File renamed without changes.
13 changes: 10 additions & 3 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 @@ -69,13 +75,14 @@ def doc_src_file(request):
return request.param


@pytest.mark.skipif("not pytest.config.getoption('--documentation')",
reason='Need --documentation option to run')
@pytest.mark.skipif("not pytest.config.getoption('--doctest-doc')",
reason='Need --doctest-doc option to run')
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__':
pytest.main([str(__file__.replace('\\', '/')), '-v', '--documentation'])
pytest.main([str(__file__.replace('\\', '/')), '-v', '--doctest-doc'])
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
47 changes: 29 additions & 18 deletions conftest.py → odl/util/pytest_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,26 @@

import numpy as np
import operator
import pytest
import os

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 All @@ -42,14 +51,19 @@ def add_doctest_np_odl(doctest_namespace):
# --- Files to be ignored by the tests ---


collect_ignore = ['setup.py']
this_dir = os.path.dirname(__file__)
odl_root = os.path.abspath(os.path.join(this_dir, os.pardir, os.pardir))
collect_ignore = [os.path.join(odl_root, 'setup.py')]

if not PYFFTW_AVAILABLE:
collect_ignore.append('odl/trafos/backends/pyfftw_bindings.py')
collect_ignore.append(
os.path.join(odl_root, 'odl/trafos/backends/pyfftw_bindings.py'))
if not PYWT_AVAILABLE:
collect_ignore.append('odl/trafos/backends/pywt_bindings.py')
collect_ignore.append(
os.path.join(odl_root, 'odl/trafos/backends/pywt_bindings.py'))
# Currently `pywt` is the only implementation
collect_ignore.append('odl/trafos/wavelet.py')
collect_ignore.append(
os.path.join(odl_root, 'odl/trafos/wavelet.py'))


def pytest_addoption(parser):
Expand All @@ -62,7 +76,7 @@ def pytest_addoption(parser):
parser.addoption('--examples', action='store_true',
help='Run examples')

parser.addoption('--documentation', action='store_true',
parser.addoption('--doctest-doc', action='store_true',
help='Run doctests in the documentation')


Expand All @@ -71,7 +85,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 +94,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 +105,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 +118,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 +128,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 +150,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 +175,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
15 changes: 10 additions & 5 deletions odl/util/testutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -589,13 +589,18 @@ def test(arguments=None):
'\nRun `$ pip install [--user] odl[testing]` in '
'order to install `pytest`.')

from .pytest_plugins import collect_ignore

this_dir = os.path.dirname(__file__)
odl_root = os.path.abspath(os.path.join(this_dir, os.pardir, os.pardir))
base_args = ['-x', '{root}/odl'.format(root=odl_root)]
if arguments is None:
args = base_args
else:
args = base_args + list(arguments)

args = ['-x', '{root}/odl'.format(root=odl_root)]

ignores = ['--ignore={}'.format(file) for file in collect_ignore]
args.extend(ignores)

if arguments is not None:
args.extend(arguments)

pytest.main(args)

Expand Down
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
41 changes: 28 additions & 13 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')


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
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 @@ -89,7 +101,7 @@ def run_tests(self):
setup(
name='odl',

version='0.5.0',
version='0.5.1',

description='Operator Discretization Library',
long_description=long_description,
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() + ['odl/pytest.ini']},
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
Loading