From 36ceb478b1a88fdb00eae9eca036716a7bb057f5 Mon Sep 17 00:00:00 2001 From: Benjamin Greiner Date: Sun, 24 May 2020 18:28:33 +0200 Subject: [PATCH 1/3] make test_example more verbose on failures --- slycot/CMakeLists.txt | 5 +++-- slycot/tests/test_examples.py | 21 ++++++++++++++++++--- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/slycot/CMakeLists.txt b/slycot/CMakeLists.txt index 928c4737..c8c564a1 100644 --- a/slycot/CMakeLists.txt +++ b/slycot/CMakeLists.txt @@ -117,8 +117,9 @@ configure_file(version.py.in version.py @ONLY) set(PYSOURCE - __init__.py analysis.py examples.py math.py synthesis.py - transform.py ${CMAKE_CURRENT_BINARY_DIR}/version.py) + __init__.py examples.py exceptions.py + analysis.py math.py synthesis.py transform.py + ${CMAKE_CURRENT_BINARY_DIR}/version.py) set(SLYCOT_MODULE "_wrapper") find_package(PythonExtensions REQUIRED) diff --git a/slycot/tests/test_examples.py b/slycot/tests/test_examples.py index b926e2ea..bf43200d 100644 --- a/slycot/tests/test_examples.py +++ b/slycot/tests/test_examples.py @@ -14,7 +14,10 @@ if isfunction(fun) and "_example" in fname] +#ignore numpy ABI changes https://github.com/numpy/numpy/pull/432 @pytest.mark.parametrize('examplefun', examplefunctions) +@pytest.mark.filterwarnings("ignore:numpy.dtype size changed") +@pytest.mark.filterwarnings("ignore:numpy.ufunc size changed") def test_example(examplefun, capsys, recwarn): """ Test the examples. @@ -24,6 +27,18 @@ def test_example(examplefun, capsys, recwarn): """ examplefun() captured = capsys.readouterr() - assert len(captured.out) > 0 - assert not captured.err - assert not recwarn + + # fail for first in order + failconditions = [ + ((not len(captured.out) > 0), "Example {} did not print any results\n"), + (captured.err, "Example {} wrote to stderr\n"), + (recwarn, "Example {} produced a warning.\n")] + for failed, msgfmt in failconditions: + if failed: + pytest.fail(msgfmt.format(examplefun.__name__) + + "Captured output:\n{}\n" + "Captured stderr:\n{}\n" + "Captured warnings:\n{}\n" + "".format(captured.out, + captured.err, + [w.message for w in recwarn])) From 443577d595a79d09cfae5be08ee84e1a23b90380 Mon Sep 17 00:00:00 2001 From: Benjamin Greiner Date: Sun, 24 May 2020 18:48:38 +0200 Subject: [PATCH 2/3] move test_mc to pytest This fixes a failure with -Werror not taking into account that the warning is expected --- slycot/tests/test_mc.py | 87 ++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 48 deletions(-) diff --git a/slycot/tests/test_mc.py b/slycot/tests/test_mc.py index 5c3012d5..b27c0481 100644 --- a/slycot/tests/test_mc.py +++ b/slycot/tests/test_mc.py @@ -2,53 +2,44 @@ # test_mc.py - test suite for polynomial and rational function manipulation # bnavigator , Aug 2019 -import unittest -import warnings +import pytest +import re from slycot import mc01td - - -class test_mc(unittest.TestCase): - - def test_mc01td(self): - """ test_mc01td: doc example - data from http://slicot.org/objects/software/shared/doc/MC01TD.html - """ - (dp, stable, nz) = mc01td('C', 4, [2, 0, 1, -1, 1]) - self.assertEqual(dp, 4) - self.assertEqual(stable, 0) - self.assertEqual(nz, 2) - - def test_mc01td_D(self): - """ test_mc01td_D: test discrete option """ - (dp, stable, nz) = mc01td('D', 3, [1, 2, 3, 4]) - self.assertEqual(dp, 3) - self.assertEqual(stable, 1) - self.assertEqual(nz, 0) - (dp, stable, nz) = mc01td('D', 3, [4, 3, 2, 1]) - self.assertEqual(dp, 3) - self.assertEqual(stable, 0) - self.assertEqual(nz, 3) - - def test_mc01td_warnings(self): - """ test_mc01td_warnings: Test warnings """ - T = [([0, 0], "\n" - "Entry ``P(x)`` is the zero polynomial."), - ([0, 1], "\n" - "The polynomial ``P(x)`` is most probably unstable,\n" - "although it may be stable with one or more zeros\n" - "very close to the imaginary axis.\n" - "The number of unstable zeros (NZ) is not determined."), - ([1, 0], "\n" - "The degree of the polynomial ``P(x)`` has been\n" - "reduced to ``(DB - 1)`` because\n" - "``P(DB+1-j) = 0.0`` on entry\n" - "for ``j = 0, 1,..., k-1`` and ``P(DB+1-k) <> 0.0``.")] - for P, m in T: - with warnings.catch_warnings(record=True) as w: - (dp, stable, nz) = mc01td('C', len(P)-1, P) - self.assertEqual(str(w[0].message), m) - - -if __name__ == "__main__": - unittest.main() +from slycot.exceptions import SlycotResultWarning + + +def test_mc01td(): + """ test_mc01td: doc example + data from http://slicot.org/objects/software/shared/doc/MC01TD.html + """ + (dp, stable, nz) = mc01td('C', 4, [2, 0, 1, -1, 1]) + assert dp == 4 + assert stable == 0 + assert nz == 2 + +def test_mc01td_D(): + """ test_mc01td_D: test discrete option """ + (dp, stable, nz) = mc01td('D', 3, [1, 2, 3, 4]) + assert dp == 3 + assert stable == 1 + assert nz == 0 + (dp, stable, nz) = mc01td('D', 3, [4, 3, 2, 1]) + assert dp == 3 + assert stable == 0 + assert nz == 3 + +def test_mc01td_warnings(): + """ test_mc01td_warnings: Test warnings """ + T = [([0, 0], "Entry ``P(x)`` is the zero polynomial."), + ([0, 1], "The polynomial ``P(x)`` is most probably unstable,\n" + "although it may be stable with one or more zeros\n" + "very close to the imaginary axis.\n" + "The number of unstable zeros (NZ) is not determined."), + ([1, 0], "The degree of the polynomial ``P(x)`` has been\n" + "reduced to ``(DB - 1)`` because\n" + "``P(DB+1-j) = 0.0`` on entry\n" + "for ``j = 0, 1,..., k-1`` and ``P(DB+1-k) <> 0.0``.")] + for P, m in T: + with pytest.warns(SlycotResultWarning, match=re.escape(m)): + (dp, stable, nz) = mc01td('C', len(P)-1, P) From af98e9fca2d94e2ade6518034eea3405ee2fa0bd Mon Sep 17 00:00:00 2001 From: Benjamin Greiner Date: Sun, 24 May 2020 20:23:08 +0200 Subject: [PATCH 3/3] allow ab13fd_example to warn about computation of beta(A) --- slycot/tests/test_examples.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/slycot/tests/test_examples.py b/slycot/tests/test_examples.py index bf43200d..1197e14a 100644 --- a/slycot/tests/test_examples.py +++ b/slycot/tests/test_examples.py @@ -13,9 +13,25 @@ examplefunctions = [fun for (fname, fun) in getmembers(examples) if isfunction(fun) and "_example" in fname] +# Exempt certain functions to produce warnings with attributes (iwarn, info) +# +# Failed to compute beta(A) within the specified tolerance +examples.ab13fd_example.allow_iwarninfo = [(None, 1)] + + +def check_warn(recwarn, examplefun): + """Returns True if a warning occurs that is not exempt""" + for w in recwarn: + try: + if (w.message.iwarn, w.message.info) in examplefun.allow_iwarninfo: + continue + except AttributeError: + pass + return True + -#ignore numpy ABI changes https://github.com/numpy/numpy/pull/432 @pytest.mark.parametrize('examplefun', examplefunctions) +#ignore numpy ABI change warnings https://github.com/numpy/numpy/pull/432 @pytest.mark.filterwarnings("ignore:numpy.dtype size changed") @pytest.mark.filterwarnings("ignore:numpy.ufunc size changed") def test_example(examplefun, capsys, recwarn): @@ -32,7 +48,7 @@ def test_example(examplefun, capsys, recwarn): failconditions = [ ((not len(captured.out) > 0), "Example {} did not print any results\n"), (captured.err, "Example {} wrote to stderr\n"), - (recwarn, "Example {} produced a warning.\n")] + (check_warn(recwarn, examplefun), "Example {} produced a warning.\n")] for failed, msgfmt in failconditions: if failed: pytest.fail(msgfmt.format(examplefun.__name__) +