Skip to content

Commit

Permalink
gateway: Test concurrent rinfo for main_thread_only
Browse files Browse the repository at this point in the history
Add test coverage for a bug triggered by pytest-cov when it
tried to call _rinfo after the gateway was already busy with
a remote_exec call:

pytest-dev/pytest-xdist#1071
  • Loading branch information
zmedico committed Apr 27, 2024
1 parent 4999a10 commit af78844
Showing 1 changed file with 44 additions and 0 deletions.
44 changes: 44 additions & 0 deletions testing/test_gateway.py
Expand Up @@ -645,3 +645,47 @@ def test_main_thread_only_concurrent_remote_exec_deadlock(
ch.close()
gw.exit()
gw.join()


def test_concurrent_rinfo(execmodel: gateway_base.ExecModel) -> None:
# Use a temporary Group to force the desired execmodel, since
# groups used by fixtures tend to use the thread execmodel.
group = execnet.Group(execmodel=execmodel.backend)
gw = group.makegateway(f"execmodel={execmodel.backend}//popen")

# For main_thread_only _rinfo will deadlock unless the gateway
# has cached the result earlier, but only if sleep_time
# exceeds the 1 second grace period in the WorkerGateway
# _local_schedulexec method. For other execmodels, a shorter
# sleep_time is sufficient to test concurrent _rinfo.
sleep_time = 1.5 if execmodel.backend == "main_thread_only" else 0.5
try:
if execmodel.backend == "main_thread_only":
# Cache rinfo like pytest-dist does for backward compatibility,
# in order to prevent a deadlock error when pytest-cov requests
# rinfo while the main thread is busy with the pytest-xdist
# WorkerController's remote_exec call.
gw._rinfo()
assert hasattr(gw, "_cache_rinfo")

ch = gw.remote_exec(
"""
import os, time
time.sleep({sleep_time})
channel.send(os.getpid())
""".format(
sleep_time=sleep_time
)
)
rinfo = gw._rinfo()
try:
res = ch.receive()
finally:
ch.close()
ch.waitclose()

assert res == rinfo.pid
finally:
gw.exit()
gw.join()
group.terminate(0.5)

0 comments on commit af78844

Please sign in to comment.