''' Package logger namespace regression tests. ''' import logging from types import SimpleNamespace import pytest import trio from piker.log import ( get_console_log, get_logger, ) @pytest.mark.parametrize( 'factory', [ get_logger, get_console_log, ], ) @pytest.mark.parametrize( 'name', [ 'piker.service._daemon', 'piker.paper', ], ) def test_package_logger_name( factory, name: str, ): ''' `str.lstrip('piker.')` treated the package prefix as a set of removable characters. A submodule beginning with any of those characters, such as `piker.paper`, was silently renamed to `piker.aper`, while service code asserted a stale parent name. Exercise both logger factories with service and prefix-sensitive submodule names, proving they retain the exact requested package namespace. ''' log = factory(name=name) assert log.name == name def test_feed_startup_configures_transport_logger( monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture, ) -> None: ''' Daemon INFO did not enable websocket reconnection diagnostics. Feed startup configured piker.data.feed, but ._util.log and ._web_bs.log emit on piker.data. Errors fell back to bare stderr while connection-success INFO stayed hidden. Client verbosity must also not demote that shared actor-wide transport logger. Run production feed startup and logger configuration with an INFO actor and ERROR client. Stop at feed-bus lookup before touching any provider. Use real logging/console emission, not mocked logger methods, to prove INFO from the websocket emitter is visible. ''' from piker.data import feed, _web_bs saved = {} for name in ('piker.data', 'piker.data.feed', 'tractor'): logger = logging.getLogger(name) saved[logger] = (logger.level, list(logger.handlers)) boundary = RuntimeError('stop before provider lookup') def stop_at_bus(brokername: str): raise boundary monkeypatch.setattr( feed.tractor, 'current_actor', lambda **kwargs: SimpleNamespace( name='brokerd.binance', loglevel='info', ), ) monkeypatch.setattr(feed, 'get_feed_bus', stop_at_bus) async def main() -> None: with pytest.raises(RuntimeError) as caught: await feed.open_feed_bus( ctx=None, brokername='binance', symbols=[], loglevel='error', ) assert caught.value is boundary try: logging.getLogger('piker.data').setLevel(logging.WARNING) trio.run(main) assert _web_bs.log.isEnabledFor(logging.INFO) _web_bs.log.info('websocket INFO visibility probe') assert 'websocket INFO visibility probe' in ( capsys.readouterr().err ) finally: for logger, (level, handlers) in saved.items(): for handler in list(logger.handlers): if handler not in handlers: logger.removeHandler(handler) handler.close() logger.setLevel(level)