diff --git a/.travis.yml b/.travis.yml index 594565b46f0b..dca90b733a68 100644 --- a/.travis.yml +++ b/.travis.yml @@ -131,6 +131,7 @@ install: codecov \ coverage \ $CYCLER \ + $DATEUTIL \ $NOSE \ $NUMPY \ $PANDAS \ @@ -138,8 +139,8 @@ install: coverage \ pillow \ $PYPARSING \ - $DATEUTIL \ - $SPHINX + $SPHINX \ + tornado # GUI toolkits are pip-installable only for some versions of Python so # don't fail if we can't install them. Make it easier to check whether the # install was successful by trying to import the toolkit (sometimes, the diff --git a/lib/matplotlib/tests/test_backends_interactive.py b/lib/matplotlib/tests/test_backends_interactive.py index 1880a27af343..b66fe64e99b0 100644 --- a/lib/matplotlib/tests/test_backends_interactive.py +++ b/lib/matplotlib/tests/test_backends_interactive.py @@ -1,10 +1,15 @@ import importlib import os -from subprocess import Popen +import signal +import subprocess import sys +import time +import urllib.request import pytest +import matplotlib as mpl + # Minimal smoke-testing of the backends for which the dependencies are # PyPI-installable on Travis. They are not available for all tested Python @@ -17,6 +22,7 @@ def _get_testable_interactive_backends(): (["PyQt5"], "qt5agg"), (["cairocffi", "PyQt5"], "qt5cairo"), (["tkinter"], "tkagg"), + (["wx"], "wx"), (["wx"], "wxagg")]: reason = None if not os.environ.get("DISPLAY"): @@ -30,20 +36,47 @@ def _get_testable_interactive_backends(): _test_script = """\ import sys -from matplotlib import pyplot as plt +from matplotlib import pyplot as plt, rcParams +rcParams.update({ + "webagg.open_in_browser": False, + "webagg.port_retries": 1, +}) fig = plt.figure() ax = fig.add_subplot(111) -ax.plot([1,2,3], [1,3,1]) +ax.plot([1, 2], [2, 3]) fig.canvas.mpl_connect("draw_event", lambda event: sys.exit()) plt.show() """ +_test_timeout = 10 # Empirically, 1s is not enough on Travis. @pytest.mark.parametrize("backend", _get_testable_interactive_backends()) @pytest.mark.flaky(reruns=3) -def test_backend(backend): - proc = Popen([sys.executable, "-c", _test_script], - env={**os.environ, "MPLBACKEND": backend}) - # Empirically, 1s is not enough on Travis. - assert proc.wait(timeout=10) == 0 +def test_interactive_backend(backend): + subprocess.run([sys.executable, "-c", _test_script], + env={**os.environ, "MPLBACKEND": backend}, + check=True, # Throw on failure. + timeout=_test_timeout) + + +@pytest.mark.skipif(os.name == "nt", reason="Cannot send SIGINT on Windows.") +def test_webagg(): + pytest.importorskip("tornado") + proc = subprocess.Popen([sys.executable, "-c", _test_script], + env={**os.environ, "MPLBACKEND": "webagg"}) + url = "http://{}:{}".format( + mpl.rcParams["webagg.address"], mpl.rcParams["webagg.port"]) + timeout = time.perf_counter() + _test_timeout + while True: + try: + conn = urllib.request.urlopen(url) + break + except urllib.error.URLError: + if time.perf_counter() > timeout: + pytest.fail("Failed to connect to the webagg server.") + else: + continue + conn.close() + proc.send_signal(signal.SIGINT) + assert proc.wait(timeout=_test_timeout) == 0