pytest-services icon indicating copy to clipboard operation
pytest-services copied to clipboard

services_log throws Bad file descriptor in docker container

Open grote opened this issue 5 years ago • 1 comments

When running my pytests using pytest-services inside a Gitlab docker container, I get the stacktrace below and the tests fail.

The problem seems to be that the log handler using /dev/log is not available inside the container.

This workaround makes things work again:

logger = logging.getLogger('[{worker_id}] {name}'.format(name="pytest_services.log", worker_id=worker_id))
logger.handlers.clear()

Here's the huge stracktrace:

Traceback (most recent call last):
  File "/usr/lib/python3.8/logging/handlers.py", line 934, in emit
    self.socket.send(msg)
OSError: [Errno 9] Bad file descriptor
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/usr/lib/python3.8/logging/handlers.py", line 937, in emit
    self._connect_unixsocket(self.address)
  File "/usr/lib/python3.8/logging/handlers.py", line 855, in _connect_unixsocket
    self.socket.connect(address)
FileNotFoundError: [Errno 2] No such file or directory
Call stack:
  File "/usr/local/bin/pytest", line 8, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.8/dist-packages/_pytest/config/__init__.py", line 124, in main
    ret = config.hook.pytest_cmdline_main(
  File "/usr/local/lib/python3.8/dist-packages/pluggy/hooks.py", line 286, in __call__
    return self._hookexec(self, self.get_hookimpls(), kwargs)
  File "/usr/local/lib/python3.8/dist-packages/pluggy/manager.py", line 93, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "/usr/local/lib/python3.8/dist-packages/pluggy/manager.py", line 84, in <lambda>
    self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
  File "/usr/local/lib/python3.8/dist-packages/pluggy/callers.py", line 187, in _multicall
    res = hook_impl.function(*args)
  File "/usr/local/lib/python3.8/dist-packages/_pytest/main.py", line 240, in pytest_cmdline_main
    return wrap_session(config, _main)
  File "/usr/local/lib/python3.8/dist-packages/_pytest/main.py", line 191, in wrap_session
    session.exitstatus = doit(config, session) or 0
  File "/usr/local/lib/python3.8/dist-packages/_pytest/main.py", line 247, in _main
    config.hook.pytest_runtestloop(session=session)
  File "/usr/local/lib/python3.8/dist-packages/pluggy/hooks.py", line 286, in __call__
    return self._hookexec(self, self.get_hookimpls(), kwargs)
  File "/usr/local/lib/python3.8/dist-packages/pluggy/manager.py", line 93, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "/usr/local/lib/python3.8/dist-packages/pluggy/manager.py", line 84, in <lambda>
    self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
  File "/usr/local/lib/python3.8/dist-packages/pluggy/callers.py", line 187, in _multicall
    res = hook_impl.function(*args)
  File "/usr/local/lib/python3.8/dist-packages/_pytest/main.py", line 272, in pytest_runtestloop
    item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem)
  File "/usr/local/lib/python3.8/dist-packages/pluggy/hooks.py", line 286, in __call__
    return self._hookexec(self, self.get_hookimpls(), kwargs)
  File "/usr/local/lib/python3.8/dist-packages/pluggy/manager.py", line 93, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "/usr/local/lib/python3.8/dist-packages/pluggy/manager.py", line 84, in <lambda>
    self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
  File "/usr/local/lib/python3.8/dist-packages/pluggy/callers.py", line 187, in _multicall
    res = hook_impl.function(*args)
  File "/usr/local/lib/python3.8/dist-packages/_pytest/runner.py", line 85, in pytest_runtest_protocol
    runtestprotocol(item, nextitem=nextitem)
  File "/usr/local/lib/python3.8/dist-packages/_pytest/runner.py", line 94, in runtestprotocol
    rep = call_and_report(item, "setup", log)
  File "/usr/local/lib/python3.8/dist-packages/_pytest/runner.py", line 186, in call_and_report
    call = call_runtest_hook(item, when, **kwds)
  File "/usr/local/lib/python3.8/dist-packages/_pytest/runner.py", line 216, in call_runtest_hook
    return CallInfo.from_call(
  File "/usr/local/lib/python3.8/dist-packages/_pytest/runner.py", line 244, in from_call
    result = func()
  File "/usr/local/lib/python3.8/dist-packages/_pytest/runner.py", line 217, in <lambda>
    lambda: ihook(item=item, **kwds), when=when, reraise=reraise
  File "/usr/local/lib/python3.8/dist-packages/pluggy/hooks.py", line 286, in __call__
    return self._hookexec(self, self.get_hookimpls(), kwargs)
  File "/usr/local/lib/python3.8/dist-packages/pluggy/manager.py", line 93, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "/usr/local/lib/python3.8/dist-packages/pluggy/manager.py", line 84, in <lambda>
    self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
  File "/usr/local/lib/python3.8/dist-packages/pluggy/callers.py", line 187, in _multicall
    res = hook_impl.function(*args)
  File "/usr/local/lib/python3.8/dist-packages/_pytest/runner.py", line 123, in pytest_runtest_setup
    item.session._setupstate.prepare(item)
  File "/usr/local/lib/python3.8/dist-packages/_pytest/runner.py", line 373, in prepare
    col.setup()
  File "/usr/local/lib/python3.8/dist-packages/_pytest/python.py", line 1483, in setup
    fixtures.fillfixtures(self)
  File "/usr/local/lib/python3.8/dist-packages/_pytest/fixtures.py", line 297, in fillfixtures
    request._fillfixtures()
  File "/usr/local/lib/python3.8/dist-packages/_pytest/fixtures.py", line 477, in _fillfixtures
    item.funcargs[argname] = self.getfixturevalue(argname)
  File "/usr/local/lib/python3.8/dist-packages/_pytest/fixtures.py", line 487, in getfixturevalue
    return self._get_active_fixturedef(argname).cached_result[0]
File "/usr/local/lib/python3.8/dist-packages/_pytest/fixtures.py", line 503, in _get_active_fixturedef
    self._compute_fixture_value(fixturedef)
  File "/usr/local/lib/python3.8/dist-packages/_pytest/fixtures.py", line 584, in _compute_fixture_value
    fixturedef.execute(request=subrequest)
  File "/usr/local/lib/python3.8/dist-packages/_pytest/fixtures.py", line 914, in execute
    return hook.pytest_fixture_setup(fixturedef=self, request=request)
  File "/usr/local/lib/python3.8/dist-packages/pluggy/hooks.py", line 286, in __call__
    return self._hookexec(self, self.get_hookimpls(), kwargs)
  File "/usr/local/lib/python3.8/dist-packages/pluggy/manager.py", line 93, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "/usr/local/lib/python3.8/dist-packages/pluggy/manager.py", line 84, in <lambda>
    self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
  File "/usr/local/lib/python3.8/dist-packages/pluggy/callers.py", line 187, in _multicall
    res = hook_impl.function(*args)
  File "/usr/local/lib/python3.8/dist-packages/_pytest/fixtures.py", line 964, in pytest_fixture_setup
    result = call_fixture_func(fixturefunc, request, kwargs)
  File "/usr/local/lib/python3.8/dist-packages/_pytest/fixtures.py", line 792, in call_fixture_func
    res = fixturefunc(**kwargs)
  File "/builds/gnu-taler/wallet-core/tests/conftest.py", line 8, in coordinator
    return Coordinator(watcher_getter, request, tmpdir)
  File "/builds/gnu-taler/wallet-core/tests/components/coordinator.py", line 19, in __init__
    self.bank.start()
  File "/builds/gnu-taler/wallet-core/tests/components/bank.py", line 24, in start
    self.watcher_getter(
  File "/usr/local/lib/python3.8/dist-packages/pytest_services/service.py", line 78, in watcher_getter_function
    services_log.debug('Starting {0}: {1}'.format(name, arguments))

grote avatar Jul 28 '20 13:07 grote

looks like we should check for existence of /dev/log then, in this fixture:

@pytest.fixture(scope='session')
def services_log(slave_id):
    """A services_logger with the slave id."""
    handler = None
    for kwargs in (dict(socktype=socket.SOCK_RAW), dict(socktype=socket.SOCK_STREAM), dict()):
        try:
            handler = logging.handlers.SysLogHandler(
                facility=logging.handlers.SysLogHandler.LOG_LOCAL7, address='/dev/log', **kwargs)
            break
        except (IOError, TypeError):
            pass
    logger = logging.getLogger('[{slave_id}] {name}'.format(name=__name__, slave_id=slave_id))
    logger.setLevel(logging.DEBUG)
    if handler:
        logger.propagate = 0
        logger.addHandler(handler)
    return logger

would you like to submit the PR?

bubenkoff avatar Jul 30 '20 18:07 bubenkoff