import asyncio
import os
import subprocess
import sys
from typing import AsyncGenerator
import pytest
import pytest_asyncio
from cockpit._vendor.systemd_ctypes import EventLoopPolicy
collect_ignore: list[str] = []
if sys.version_info < (3, 12):
collect_ignore.append("ws")
def any_subprocesses() -> bool:
try:
os.waitid(os.P_ALL, -1, os.WEXITED | os.WNOHANG | os.WNOWAIT)
except ChildProcessError:
return False
else:
return True
if "NO_QUNIT" in os.environ:
collect_ignore.append("test_browser.py")
else:
pytest_plugins = "js_coverage"
@pytest.fixture
def event_loop_policy() -> asyncio.AbstractEventLoopPolicy:
return EventLoopPolicy()
@pytest_asyncio.fixture(autouse=True)
async def _check_settled() -> AsyncGenerator[None, None]:
yield
current_task = asyncio.current_task()
assert current_task is not None
event_loop = asyncio.get_running_loop()
for _ in range(200):
all_tasks = asyncio.all_tasks(loop=event_loop) - {current_task}
if not (all_tasks or any_subprocesses()):
break
await asyncio.sleep(0.005)
assert asyncio.all_tasks(loop=event_loop) == {current_task}
if any_subprocesses():
subprocess.run(['ps', 'f', f'--pid={os.getpid()}', f'--ppid={os.getpid()}'])
subprocess.run(['pkill', '-9', '-P', f'{os.getpid()}'])
try:
for _ in range(100):
os.wait()
except ChildProcessError:
pass
pytest.fail('Some subprocesses still running!')