Repository: dask/distributed

Issue:
Pytest 4 deprecation warning on pytest.config
When running pytest 4.4.1, it triggers several deprecation warnings from this line in the test suite:
```
  /builddir/build/BUILD/distributed-1.27.1/distributed/utils_test.py:786: PytestDeprecationWarning: the `pytest.config` global is deprecated.  Please use `request.config` or `pytest_configure` (if you're a pytest plugin) instead.
    if not pytest.config.getoption("--runslow"):
```


Discussion:
I've been seeing that as well.  I don't know immediately how to solve it.
If anyone has suggestions, they would be welcome.

On Tue, May 7, 2019 at 7:37 PM Elliott Sales de Andrade <
notifications@github.com> wrote:

> When running pytest 4.4.1, it triggers several deprecation warnings from
> this line in the test suite:
>
>   /builddir/build/BUILD/distributed-1.27.1/distributed/utils_test.py:786: PytestDeprecationWarning: the `pytest.config` global is deprecated.  Please use `request.config` or `pytest_configure` (if you're a pytest plugin) instead.
>     if not pytest.config.getoption("--runslow"):
>
> —
> You are receiving this because you are subscribed to this thread.
> Reply to this email directly, view it on GitHub
> <https://github.com/dask/distributed/issues/2669>, or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AACKZTFPZKQKLJMSYTGJO7LPUIOE7ANCNFSM4HLNOVGA>
> .
>

I guess something like [this pytest example](https://docs.pytest.org/en/latest/example/simple.html#control-skipping-of-tests-according-to-command-line-option).

Resolving patch:
diff --git a/conftest.py b/conftest.py
--- a/conftest.py
+++ b/conftest.py
@@ -1,12 +1,11 @@
 # https://pytest.org/latest/example/simple.html#control-skipping-of-tests-according-to-command-line-option
-import os
 import pytest
 
 
 # Uncomment to enable more logging and checks
 # (https://docs.python.org/3/library/asyncio-dev.html)
 # Note this makes things slower and might consume much memory.
-#os.environ["PYTHONASYNCIODEBUG"] = "1"
+# os.environ["PYTHONASYNCIODEBUG"] = "1"
 
 try:
     import faulthandler
@@ -19,4 +18,15 @@
 def pytest_addoption(parser):
     parser.addoption("--runslow", action="store_true", help="run slow tests")
 
-pytest_plugins = ['distributed.pytest_resourceleaks']
+
+def pytest_collection_modifyitems(config, items):
+    if config.getoption("--runslow"):
+        # --runslow given in cli: do not skip slow tests
+        return
+    skip_slow = pytest.mark.skip(reason="need --runslow option to run")
+    for item in items:
+        if "slow" in item.keywords:
+            item.add_marker(skip_slow)
+
+
+pytest_plugins = ["distributed.pytest_resourceleaks"]


Test patch:
diff --git a/distributed/cli/tests/test_dask_worker.py b/distributed/cli/tests/test_dask_worker.py
--- a/distributed/cli/tests/test_dask_worker.py
+++ b/distributed/cli/tests/test_dask_worker.py
@@ -12,7 +12,7 @@
 from distributed import Client
 from distributed.metrics import time
 from distributed.utils import sync, tmpfile
-from distributed.utils_test import popen, slow, terminate_process, wait_for_port
+from distributed.utils_test import popen, terminate_process, wait_for_port
 from distributed.utils_test import loop  # noqa: F401
 
 
@@ -65,7 +65,7 @@ def test_no_nanny(loop):
             assert any(b"Registered" in worker.stderr.readline() for i in range(15))
 
 
-@slow
+@pytest.mark.slow
 @pytest.mark.parametrize("nanny", ["--nanny", "--no-nanny"])
 def test_no_reconnect(nanny, loop):
     with popen(["dask-scheduler", "--no-bokeh"]) as sched:
diff --git a/distributed/protocol/tests/test_numpy.py b/distributed/protocol/tests/test_numpy.py
--- a/distributed/protocol/tests/test_numpy.py
+++ b/distributed/protocol/tests/test_numpy.py
@@ -18,7 +18,7 @@
 )
 from distributed.protocol.utils import BIG_BYTES_SHARD_SIZE
 from distributed.utils import tmpfile, nbytes
-from distributed.utils_test import slow, gen_cluster
+from distributed.utils_test import gen_cluster
 from distributed.protocol.numpy import itemsize
 from distributed.protocol.compression import maybe_compress
 
@@ -152,7 +152,7 @@ def test_memmap():
         np.testing.assert_equal(x, y)
 
 
-@slow
+@pytest.mark.slow
 def test_dumps_serialize_numpy_large():
     psutil = pytest.importorskip("psutil")
     if psutil.virtual_memory().total < 2e9:
diff --git a/distributed/protocol/tests/test_protocol.py b/distributed/protocol/tests/test_protocol.py
--- a/distributed/protocol/tests/test_protocol.py
+++ b/distributed/protocol/tests/test_protocol.py
@@ -9,7 +9,6 @@
 from distributed.protocol.compression import compressions
 from distributed.protocol.serialize import Serialize, Serialized, serialize, deserialize
 from distributed.utils import nbytes
-from distributed.utils_test import slow
 
 
 def test_protocol():
@@ -110,7 +109,7 @@ def test_large_bytes():
         assert loads(frames, deserialize=False) == msg
 
 
-@slow
+@pytest.mark.slow
 def test_large_messages():
     np = pytest.importorskip("numpy")
     psutil = pytest.importorskip("psutil")
diff --git a/distributed/tests/test_batched.py b/distributed/tests/test_batched.py
--- a/distributed/tests/test_batched.py
+++ b/distributed/tests/test_batched.py
@@ -10,7 +10,7 @@
 from distributed.core import listen, connect, CommClosedError
 from distributed.metrics import time
 from distributed.utils import All
-from distributed.utils_test import gen_test, slow, captured_logger
+from distributed.utils_test import gen_test, captured_logger
 from distributed.protocol import to_serialize
 
 
@@ -158,7 +158,7 @@ def test_close_twice():
         yield b.close()
 
 
-@slow
+@pytest.mark.slow
 @gen_test(timeout=50)
 def test_stress():
     with echo_server() as e:
@@ -231,7 +231,7 @@ def test_sending_traffic_jam():
     yield run_traffic_jam(50, 300000)
 
 
-@slow
+@pytest.mark.slow
 @gen_test()
 def test_large_traffic_jam():
     yield run_traffic_jam(500, 1500000)
diff --git a/distributed/tests/test_client.py b/distributed/tests/test_client.py
--- a/distributed/tests/test_client.py
+++ b/distributed/tests/test_client.py
@@ -60,7 +60,6 @@
 from distributed.utils import ignoring, mp_context, sync, tmp_text, tokey, tmpfile
 from distributed.utils_test import (
     cluster,
-    slow,
     slowinc,
     slowadd,
     slowdec,
@@ -771,7 +770,7 @@ def test_recompute_released_key(c, s, a, b):
     assert result1 == result2
 
 
-@slow
+@pytest.mark.slow
 @gen_cluster(client=True)
 def test_long_tasks_dont_trigger_timeout(c, s, a, b):
     from time import sleep
@@ -3473,7 +3472,7 @@ def test_get_foo_lost_keys(c, s, u, v, w):
     assert_dict_key_equal(d, {x.key: [], y.key: []})
 
 
-@slow
+@pytest.mark.slow
 @gen_cluster(client=True, Worker=Nanny, check_new_threads=False)
 def test_bad_tasks_fail(c, s, a, b):
     f = c.submit(sys.exit, 1)
@@ -3528,7 +3527,7 @@ def test_get_returns_early(c):
     assert x.key in c.futures
 
 
-@slow
+@pytest.mark.slow
 @gen_cluster(Worker=Nanny, client=True)
 def test_Client_clears_references_after_restart(c, s, a, b):
     x = c.submit(inc, 1)
@@ -3644,7 +3643,7 @@ def test_scatter_raises_if_no_workers(c, s):
         yield c.scatter(1, timeout=0.5)
 
 
-@slow
+@pytest.mark.slow
 def test_reconnect(loop):
     w = Worker("127.0.0.1", 9393, loop=loop)
     w.start()
@@ -3721,7 +3720,7 @@ def test_reconnect_timeout(c, s):
     assert "Failed to reconnect" in text
 
 
-@slow
+@pytest.mark.slow
 @pytest.mark.skipif(
     sys.platform.startswith("win"), reason="num_fds not supported on windows"
 )
@@ -4251,7 +4250,7 @@ def test_normalize_collection_dask_array(c, s, a, b):
     assert result1 == result2
 
 
-@slow
+@pytest.mark.slow
 def test_normalize_collection_with_released_futures(c):
     da = pytest.importorskip("dask.array")
 
@@ -4382,7 +4381,7 @@ def test_scatter_dict_workers(c, s, a, b):
     assert "a" in a.data or "a" in b.data
 
 
-@slow
+@pytest.mark.slow
 @gen_test()
 def test_client_timeout():
     loop = IOLoop.current()
@@ -4710,7 +4709,7 @@ def test_quiet_client_close(loop):
             ), line
 
 
-@slow
+@pytest.mark.slow
 def test_quiet_client_close_when_cluster_is_closed_before_client(loop):
     with captured_logger(logging.getLogger("tornado.application")) as logger:
         cluster = LocalCluster(loop=loop, n_workers=1)
@@ -4755,7 +4754,7 @@ def f(_):
         del results
 
 
-@slow
+@pytest.mark.slow
 def test_threadsafe_get(c):
     da = pytest.importorskip("dask.array")
     x = da.arange(100, chunks=(10,))
@@ -4774,7 +4773,7 @@ def f(_):
     assert results and all(results)
 
 
-@slow
+@pytest.mark.slow
 def test_threadsafe_compute(c):
     da = pytest.importorskip("dask.array")
     x = da.arange(100, chunks=(10,))
@@ -4864,7 +4863,7 @@ def f():
     assert result == 2
 
 
-@slow
+@pytest.mark.slow
 @gen_cluster(client=True, ncores=[("127.0.0.1", 1)] * 2, timeout=60)
 def test_secede_balances(c, s, a, b):
     count = threading.active_count()
@@ -4970,7 +4969,7 @@ def test_dynamic_workloads_sync(c):
     _test_dynamic_workloads_sync(c, delay=0.02)
 
 
-@slow
+@pytest.mark.slow
 def test_dynamic_workloads_sync_random(c):
     _test_dynamic_workloads_sync(c, delay="random")
 
@@ -5190,7 +5189,7 @@ def test_client_async_before_loop_starts():
         client.close()
 
 
-@slow
+@pytest.mark.slow
 @gen_cluster(
     client=True,
     Worker=Nanny if PY3 else Worker,
diff --git a/distributed/tests/test_core.py b/distributed/tests/test_core.py
--- a/distributed/tests/test_core.py
+++ b/distributed/tests/test_core.py
@@ -25,7 +25,6 @@
 from distributed.protocol import to_serialize
 from distributed.utils import get_ip, get_ipv6
 from distributed.utils_test import (
-    slow,
     gen_test,
     gen_cluster,
     has_ipv6,
@@ -409,7 +408,7 @@ def check_large_packets(listen_arg):
     server.stop()
 
 
-@slow
+@pytest.mark.slow
 @gen_test()
 def test_large_packets_tcp():
     yield check_large_packets("tcp://")
diff --git a/distributed/tests/test_diskutils.py b/distributed/tests/test_diskutils.py
--- a/distributed/tests/test_diskutils.py
+++ b/distributed/tests/test_diskutils.py
@@ -16,7 +16,7 @@
 from distributed.diskutils import WorkSpace
 from distributed.metrics import time
 from distributed.utils import mp_context
-from distributed.utils_test import captured_logger, slow
+from distributed.utils_test import captured_logger
 
 
 def assert_directory_contents(dir_path, expected, trials=2):
@@ -279,7 +279,7 @@ def test_workspace_concurrency(tmpdir):
     _test_workspace_concurrency(tmpdir, 2.0, 6)
 
 
-@slow
+@pytest.mark.slow
 def test_workspace_concurrency_intense(tmpdir):
     n_created, n_purged = _test_workspace_concurrency(tmpdir, 8.0, 16)
     assert n_created >= 100
diff --git a/distributed/tests/test_failed_workers.py b/distributed/tests/test_failed_workers.py
--- a/distributed/tests/test_failed_workers.py
+++ b/distributed/tests/test_failed_workers.py
@@ -19,7 +19,6 @@
     gen_cluster,
     cluster,
     inc,
-    slow,
     div,
     slowinc,
     slowadd,
@@ -406,7 +405,7 @@ def test_worker_who_has_clears_after_failed_connection(c, s, a, b):
     yield n.close()
 
 
-@slow
+@pytest.mark.slow
 @gen_cluster(client=True, timeout=60, Worker=Nanny, ncores=[("127.0.0.1", 1)])
 def test_restart_timeout_on_long_running_task(c, s, a):
     with captured_logger("distributed.scheduler") as sio:
diff --git a/distributed/tests/test_nanny.py b/distributed/tests/test_nanny.py
--- a/distributed/tests/test_nanny.py
+++ b/distributed/tests/test_nanny.py
@@ -18,7 +18,7 @@
 from distributed.metrics import time
 from distributed.protocol.pickle import dumps
 from distributed.utils import ignoring, tmpfile
-from distributed.utils_test import gen_cluster, gen_test, slow, inc, captured_logger
+from distributed.utils_test import gen_cluster, gen_test, inc, captured_logger
 
 
 @gen_cluster(ncores=[])
@@ -127,7 +127,7 @@ def test_run(s):
     yield n.close()
 
 
-@slow
+@pytest.mark.slow
 @gen_cluster(
     Worker=Nanny, ncores=[("127.0.0.1", 1)], worker_kwargs={"reconnect": False}
 )
@@ -159,7 +159,7 @@ def test_nanny_alt_worker_class(c, s, w1, w2):
     assert w1.Worker is Something
 
 
-@slow
+@pytest.mark.slow
 @gen_cluster(client=False, ncores=[])
 def test_nanny_death_timeout(s):
     yield s.close()
@@ -318,7 +318,7 @@ def test_scheduler_address_config(c, s):
     yield nanny.close()
 
 
-@slow
+@pytest.mark.slow
 @gen_test()
 def test_wait_for_scheduler():
     with captured_logger("distributed") as log:
diff --git a/distributed/tests/test_queues.py b/distributed/tests/test_queues.py
--- a/distributed/tests/test_queues.py
+++ b/distributed/tests/test_queues.py
@@ -9,7 +9,7 @@
 
 from distributed import Client, Queue, Nanny, worker_client, wait
 from distributed.metrics import time
-from distributed.utils_test import gen_cluster, inc, slow, div
+from distributed.utils_test import gen_cluster, inc, div
 from distributed.utils_test import client, cluster_fixture, loop  # noqa: F401
 
 
@@ -114,7 +114,7 @@ def f(x):
 
 
 @pytest.mark.skipif(sys.version_info[0] == 2, reason="Multi-client issues")
-@slow
+@pytest.mark.slow
 @gen_cluster(client=True, ncores=[("127.0.0.1", 2)] * 5, Worker=Nanny, timeout=None)
 def test_race(c, s, *workers):
     def f(i):
diff --git a/distributed/tests/test_scheduler.py b/distributed/tests/test_scheduler.py
--- a/distributed/tests/test_scheduler.py
+++ b/distributed/tests/test_scheduler.py
@@ -35,7 +35,6 @@
     cluster,
     div,
     varying,
-    slow,
 )
 from distributed.utils_test import loop, nodebug  # noqa: F401
 from dask.compatibility import apply
@@ -775,7 +774,7 @@ def test_retire_workers_no_suspicious_tasks(c, s, a, b):
     assert all(ts.suspicious == 0 for ts in s.tasks.values())
 
 
-@slow
+@pytest.mark.slow
 @pytest.mark.skipif(
     sys.platform.startswith("win"), reason="file descriptors not really a thing"
 )
@@ -831,7 +830,7 @@ def test_file_descriptors(c, s):
         assert time() < start + 3
 
 
-@slow
+@pytest.mark.slow
 @nodebug
 @gen_cluster(client=True)
 def test_learn_occupancy(c, s, a, b):
@@ -844,7 +843,7 @@ def test_learn_occupancy(c, s, a, b):
         assert 50 < s.workers[w.address].occupancy < 700
 
 
-@slow
+@pytest.mark.slow
 @nodebug
 @gen_cluster(client=True)
 def test_learn_occupancy_2(c, s, a, b):
@@ -1062,7 +1061,7 @@ def test_close_worker(c, s, a, b):
     assert len(s.workers) == 1
 
 
-@slow
+@pytest.mark.slow
 @gen_cluster(client=True, Worker=Nanny, timeout=20)
 def test_close_nanny(c, s, a, b):
     assert len(s.workers) == 2
diff --git a/distributed/tests/test_stress.py b/distributed/tests/test_stress.py
--- a/distributed/tests/test_stress.py
+++ b/distributed/tests/test_stress.py
@@ -21,7 +21,6 @@
     inc,
     slowinc,
     slowadd,
-    slow,
     slowsum,
     bump_rlimit,
 )
@@ -198,7 +197,7 @@ def vsum(*args):
 
 
 @pytest.mark.avoid_travis
-@slow
+@pytest.mark.slow
 @gen_cluster(client=True, ncores=[("127.0.0.1", 1)] * 80, timeout=1000)
 def test_stress_communication(c, s, *workers):
     s.validate = False  # very slow otherwise
@@ -244,7 +243,7 @@ def test_stress_steal(c, s, *workers):
             break
 
 
-@slow
+@pytest.mark.slow
 @gen_cluster(ncores=[("127.0.0.1", 1)] * 10, client=True, timeout=120)
 def test_close_connections(c, s, *workers):
     da = pytest.importorskip("dask.array")
diff --git a/distributed/tests/test_variable.py b/distributed/tests/test_variable.py
--- a/distributed/tests/test_variable.py
+++ b/distributed/tests/test_variable.py
@@ -9,7 +9,7 @@
 
 from distributed import Client, Variable, worker_client, Nanny, wait
 from distributed.metrics import time
-from distributed.utils_test import gen_cluster, inc, slow, div
+from distributed.utils_test import gen_cluster, inc, div
 from distributed.utils_test import client, cluster_fixture, loop  # noqa: F401
 
 
@@ -147,7 +147,7 @@ def test_timeout_get(c, s, a, b):
 
 
 @pytest.mark.skipif(sys.version_info[0] == 2, reason="Multi-client issues")
-@slow
+@pytest.mark.slow
 @gen_cluster(client=True, ncores=[("127.0.0.1", 2)] * 5, Worker=Nanny, timeout=None)
 def test_race(c, s, *workers):
     NITERS = 50
diff --git a/distributed/tests/test_worker.py b/distributed/tests/test_worker.py
--- a/distributed/tests/test_worker.py
+++ b/distributed/tests/test_worker.py
@@ -33,7 +33,6 @@
     gen_cluster,
     div,
     dec,
-    slow,
     slowinc,
     gen_test,
     captured_logger,
@@ -147,7 +146,7 @@ def reset(self):
     assert tuple(results) == (3, 7)
 
 
-@slow
+@pytest.mark.slow
 @gen_cluster()
 def dont_test_delete_data_with_missing_worker(c, a, b):
     bad = "127.0.0.1:9001"  # this worker doesn't exist
@@ -312,7 +311,7 @@ def test_worker_with_port_zero():
     yield w.close()
 
 
-@slow
+@pytest.mark.slow
 def test_worker_waits_for_center_to_come_up(loop):
     @gen.coroutine
     def f():
@@ -726,7 +725,7 @@ def test_hold_onto_dependents(c, s, a, b):
     assert x.key in b.data
 
 
-@slow
+@pytest.mark.slow
 @gen_cluster(client=False, ncores=[])
 def test_worker_death_timeout(s):
     with dask.config.set({"distributed.comm.timeouts.connect": "1s"}):
@@ -1235,7 +1234,7 @@ def test_scheduler_address_config(c, s):
     yield worker.close()
 
 
-@slow
+@pytest.mark.slow
 @gen_cluster(client=True)
 def test_wait_for_outgoing(c, s, a, b):
     np = pytest.importorskip("numpy")
diff --git a/distributed/utils_test.py b/distributed/utils_test.py
--- a/distributed/utils_test.py
+++ b/distributed/utils_test.py
@@ -804,17 +804,6 @@ def disconnect_all(addresses, timeout=3, rpc_kwargs=None):
     yield [disconnect(addr, timeout, rpc_kwargs) for addr in addresses]
 
 
-def slow(func):
-    try:
-        if not pytest.config.getoption("--runslow"):
-            func = pytest.mark.skip("need --runslow option to run")(func)
-    except AttributeError:
-        # AttributeError: module 'pytest' has no attribute 'config'
-        pass
-
-    return nodebug(func)
-
-
 def gen_test(timeout=10):
     """ Coroutine test