labgrid-project / labgrid-project/labgrid

Can't run simple pytest session in a thread while using labgrid

Open
#604 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

question
Dominant language
Python
Stars
528
Forks
278
Avg merge
2d 19h
Merged PRs (30d)
4

Description

Hi,
While trying to invoke pytest in a thread with labgrid plugin in use
RuntimeError is raised.
Maybe the exeption should be catched in the module?

Example code:

from threading import Thread
import pytest

def tt():
    pytest.main(['-s', f'--lg-env=../qemu.yaml'])

t = Thread(target=tt, args=())
t.start()
t.join()

Can be worked around by adding this to the thread target function:

loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)

The line at fault:
https://github.com/labgrid-project/labgrid/blob/d11a5ecc86decd74d3ff86b6fb8b730c9ea4a962/labgrid/remote/client.py#L30

The error log:

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python3.7/threading.py", line 926, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.7/threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "hm.py", line 5, in tt
    pytest.main(['-s', f'--lg-env=../qemu.yaml'])
  File "/home/marek/.local/lib/python3.7/site-packages/_pytest/config/__init__.py", line 105, in main
    config = _prepareconfig(args, plugins)
  File "/home/marek/.local/lib/python3.7/site-packages/_pytest/config/__init__.py", line 258, in _prepareconfig
    pluginmanager=pluginmanager, args=args
  File "/home/marek/.local/lib/python3.7/site-packages/pluggy/hooks.py", line 286, in __call__
    return self._hookexec(self, self.get_hookimpls(), kwargs)
  File "/home/marek/.local/lib/python3.7/site-packages/pluggy/manager.py", line 93, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "/home/marek/.local/lib/python3.7/site-packages/pluggy/manager.py", line 87, in <lambda>
    firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
  File "/home/marek/.local/lib/python3.7/site-packages/pluggy/callers.py", line 203, in _multicall
    gen.send(outcome)
  File "/home/marek/.local/lib/python3.7/site-packages/_pytest/helpconfig.py", line 90, in pytest_cmdline_parse
    config = outcome.get_result()
  File "/home/marek/.local/lib/python3.7/site-packages/pluggy/callers.py", line 80, in get_result
    raise ex[1].with_traceback(ex[2])
  File "/home/marek/.local/lib/python3.7/site-packages/pluggy/callers.py", line 187, in _multicall
    res = hook_impl.function(*args)
  File "/home/marek/.local/lib/python3.7/site-packages/_pytest/config/__init__.py", line 836, in pytest_cmdline_parse
    self.parse(args)
  File "/home/marek/.local/lib/python3.7/site-packages/_pytest/config/__init__.py", line 1044, in parse
    self._preparse(args, addopts=addopts)
  File "/home/marek/.local/lib/python3.7/site-packages/_pytest/config/__init__.py", line 992, in _preparse
    self.pluginmanager.load_setuptools_entrypoints("pytest11")
  File "/home/marek/.local/lib/python3.7/site-packages/pluggy/manager.py", line 299, in load_setuptools_entrypoints
    plugin = ep.load()
  File "/home/marek/.local/lib/python3.7/site-packages/importlib_metadata/__init__.py", line 95, in load
    module = import_module(match.group('module'))
  File "/usr/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "/home/marek/.local/lib/python3.7/site-packages/_pytest/assertion/rewrite.py", line 152, in exec_module
    exec(co, module.__dict__)
  File "/home/marek/.local/lib/python3.7/site-packages/labgrid/pytestplugin/__init__.py", line 1, in <module>
    from .fixtures import pytest_addoption, env, target
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "/home/marek/.local/lib/python3.7/site-packages/_pytest/assertion/rewrite.py", line 152, in exec_module
    exec(co, module.__dict__)
  File "/home/marek/.local/lib/python3.7/site-packages/labgrid/pytestplugin/fixtures.py", line 6, in <module>
    from ..remote.client import UserError
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "/home/marek/.local/lib/python3.7/site-packages/_pytest/assertion/rewrite.py", line 152, in exec_module
    exec(co, module.__dict__)
  File "/home/marek/.local/lib/python3.7/site-packages/labgrid/remote/client.py", line 30, in <module>
    txaio.config.loop = asyncio.get_event_loop()
  File "/usr/lib/python3.7/asyncio/events.py", line 644, in get_event_loop
    % threading.current_thread().name)
RuntimeError: There is no current event loop in thread 'Thread-1'.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the threaded pytest.main example, then inspect labgrid/remote/client.py at line 30 and the import path through labgrid/pytestplugin/fixtures.py. Verify the behavior with and without the explicitly created asyncio event loop; done means a pytest session started from a thread no longer raises the reported RuntimeError.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
testing
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.