Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion launch/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
from pathlib import PurePath


def pytest_ignore_collect(path):
def pytest_ignore_collect(collection_path=None, path=None):
if collection_path is not None:
path = collection_path
# pytest doctest messes up when trying to import .launch.py packages, ignore them.
# It also messes up when trying to import launch.logging.handlers due to conflicts with
# logging.handlers, ignore that as well.
Expand Down
9 changes: 6 additions & 3 deletions launch_pytest/launch_pytest/fixture.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,16 @@ def scope_gt(scope1, scope2):
from _pytest.fixtures import scopemismatch as scope_gt


def finalize_launch_service(launch_service, eprefix='', auto_shutdown=True):
def finalize_launch_service(launch_service, eprefix='', auto_shutdown=True, task=None):
if auto_shutdown:
launch_service.shutdown(force_sync=True)
loop = launch_service.event_loop
if loop is not None and not loop.is_closed():
rc = loop.run_until_complete(launch_service.task)
assert rc == 0, f"{eprefix} launch service failed when finishing, return code '{rc}'"
if task is None:
task = launch_service.task
if task is not None:
rc = loop.run_until_complete(task)
assert rc == 0, f"{eprefix} launch service failed when finishing, return code '{rc}'"


def get_launch_service_fixture(*, scope='function', overridable=True):
Expand Down
15 changes: 10 additions & 5 deletions launch_pytest/launch_pytest/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,17 @@ def pytest_fixture_setup(fixturedef, request):
run_async_task = event_loop.create_task(ls.run_async(
shutdown_when_idle=options['shutdown_when_idle']
))
fixturedef.addfinalizer(functools.partial(
finalize_launch_service,
ls,
eprefix=eprefix,
auto_shutdown=options['auto_shutdown'],
task=run_async_task
))
ready = get_ready_to_test_action(ld)
asyncio.set_event_loop(event_loop)
event = asyncio.Event()
ready._add_callback(lambda: event.set())
fixturedef.addfinalizer(functools.partial(
finalize_launch_service, ls, eprefix=eprefix, auto_shutdown=options['auto_shutdown']))
run_until_complete(event_loop, event.wait())
# this is guaranteed by the current run_async() implementation, let's check it just in case
# it changes in the future
Expand Down Expand Up @@ -361,7 +366,7 @@ def pytest_pyfunc_call(pyfuncitem):
wrap_generator(func, event_loop, on_shutdown)
)
shutdown_item._fixtureinfo = shutdown_item.session._fixturemanager.getfixtureinfo(
shutdown_item, shutdown_item.obj, shutdown_item.cls, funcargs=True)
shutdown_item, shutdown_item.obj, shutdown_item.cls)
else:
pyfuncitem.obj = wrap_generator_fscope(func, event_loop, on_shutdown)
elif inspect.isasyncgenfunction(func):
Expand All @@ -371,7 +376,7 @@ def pytest_pyfunc_call(pyfuncitem):
wrap_asyncgen(func, event_loop, on_shutdown)
)
shutdown_item._fixtureinfo = shutdown_item.session._fixturemanager.getfixtureinfo(
shutdown_item, shutdown_item.obj, shutdown_item.cls, funcargs=True)
shutdown_item, shutdown_item.obj, shutdown_item.cls)
else:
pyfuncitem.obj = wrap_asyncgen_fscope(func, event_loop, on_shutdown)
elif not getattr(pyfuncitem.obj, '_launch_pytest_wrapped', False):
Expand Down Expand Up @@ -417,7 +422,7 @@ def wrap_generator(func, event_loop, on_shutdown):
"""Return wrappers for the normal test and the teardown test for a generator function."""
gen = None

def shutdown():
def shutdown(**kwargs):
if gen is None:
skip('shutdown test skipped because the test failed before')
on_shutdown()
Expand Down
18 changes: 13 additions & 5 deletions launch_testing/launch_testing/pytest/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,12 +189,20 @@ def find_launch_test_entrypoint(path):
return None


def pytest_pycollect_makemodule(path, parent):
if _pytest_version_ge(8):
def pytest_pycollect_makemodule(module_path, parent):
return _pytest_pycollect_makemodule(module_path, parent)
else:
def pytest_pycollect_makemodule(path, parent):
return _pytest_pycollect_makemodule(path, parent)


def _pytest_pycollect_makemodule(path, parent):
entrypoint = find_launch_test_entrypoint(path)
if entrypoint is not None:
ihook = parent.session.gethookproxy(path)
module = ihook.pytest_launch_collect_makemodule(
path=path, parent=parent, entrypoint=entrypoint
module_path=path, parent=parent, entrypoint=entrypoint
)
if module is not None:
return module
Expand All @@ -216,14 +224,14 @@ def pytest_pycollect_makemodule(path, parent):


@pytest.hookimpl(trylast=True)
def pytest_launch_collect_makemodule(path, parent, entrypoint):
def pytest_launch_collect_makemodule(module_path, parent, entrypoint):
marks = getattr(entrypoint, 'pytestmark', [])
if marks and any(m.name == 'launch_test' for m in marks):
if _pytest_version_ge(7):
path = pathlib.Path(path)
path = pathlib.Path(module_path)
module = LaunchTestModule.from_parent(parent=parent, path=path)
else:
module = LaunchTestModule.from_parent(parent=parent, fspath=path)
module = LaunchTestModule.from_parent(parent=parent, fspath=module_path)
for mark in marks:
decorator = getattr(pytest.mark, mark.name)
decorator = decorator.with_args(*mark.args, **mark.kwargs)
Expand Down
2 changes: 1 addition & 1 deletion launch_testing/launch_testing/pytest/hookspecs.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@


@pytest.hookspec(firstresult=True)
def pytest_launch_collect_makemodule(path, parent, entrypoint):
def pytest_launch_collect_makemodule(module_path, parent, entrypoint):
"""Make launch test module appropriate for the found test entrypoint."""
pass