2Service main and monitor clients. 
   10from testsuite.daemons 
import service_client 
as base_service_client
 
   11from testsuite.utils 
import compat
 
   13from pytest_userver 
import client
 
   16logger = logging.getLogger(__name__)
 
   22    Service client dependencies hook. Feel free to override, e.g.: 
   26    def extra_client_deps(some_fixtures_to_wait_before_service_start): 
   29    @ingroup userver_testsuite_fixtures 
 
   36    Service client dependencies hook that knows about pgsql, mongodb, 
   37    clickhouse, rabbitmq, redis_store and mysql dependencies. 
   38    To add some other dependencies prefer overriding the 
   39    extra_client_deps() fixture. 
   41    @ingroup userver_testsuite_fixtures 
   48        'redis_cluster_store',
 
   54        FixtureLookupError = pytest.FixtureLookupError
 
   55    except AttributeError:
 
   57        import _pytest.fixtures
 
   58        FixtureLookupError = _pytest.fixtures.FixtureLookupError
 
   61    for dep 
in known_deps:
 
   63            request.getfixturevalue(dep)
 
   64            resolved_deps.append(dep)
 
   65        except FixtureLookupError:
 
   69        'userver fixture "auto_client_deps" resolved dependencies %s',
 
 
   75async def service_client(
 
   76        ensure_daemon_started,
 
   79        cleanup_userver_dumps,
 
   82        _testsuite_client_config: client.TestsuiteClientConfig,
 
   84        _service_client_testsuite,
 
   87    Main fixture that provides access to userver based service. 
   89    @snippet samples/testsuite-support/tests/test_ping.py service_client 
   90    @anchor service_client 
   91    @ingroup userver_testsuite_fixtures 
   95    await ensure_daemon_started(service_daemon)
 
   97    if _testsuite_client_config.testsuite_action_path:
 
   98        return _service_client_testsuite
 
   99    return _service_client_base
 
 
  105    Fixture that provides access to userver based websocket service. 
  107    @anchor websocket_client 
  108    @ingroup userver_testsuite_fixtures 
  112        @compat.asynccontextmanager 
  113        async def get(self, path):
 
  114            update_server_state = getattr(
 
  115                service_client, 
'update_server_state', 
None,
 
  117            if update_server_state:
 
  118                await update_server_state()
 
  119            ws_context = websockets.connect(
 
  120                f
'ws://localhost:{service_port}/{path}',
 
  122            async with ws_context 
as socket:
 
 
  131        service_client_options,
 
  133        monitor_baseurl: str,
 
  137    Main fixture that provides access to userver monitor listener. 
  139    @snippet samples/testsuite-support/tests/test_metrics.py metrics labels 
  140    @ingroup userver_testsuite_fixtures 
  142    aiohttp_client = client.AiohttpClientMonitor(
 
  144        config=_testsuite_client_config,
 
  145        headers={
'x-yatraceid': mockserver.trace_id},
 
  146        **service_client_options,
 
 
  152async def _service_client_base(service_baseurl, service_client_options):
 
  153    class _ClientDiagnose(base_service_client.Client):
 
  154        def __getattr__(self, name: str) -> 
None:
 
  155            raise AttributeError(
 
  156                f
'"Client" object has no attribute "{name}". ' 
  157                'Note that "service_client" fixture returned the basic ' 
  158                '"testsuite.daemons.service_client.Client" client rather than ' 
  159                'a "pytest_userver.client.Client" client with userver ' 
  160                'extensions. That happened because the service ' 
  161                'static configuration file contains no "tests-control" ' 
  162                'component with "action" field.',
 
  165    return _ClientDiagnose(service_baseurl, **service_client_options)
 
  169def _service_client_testsuite(
 
  171        service_client_options,
 
  176        cache_invalidation_state,
 
  177        _testsuite_client_config: client.TestsuiteClientConfig,
 
  179    aiohttp_client = client.AiohttpClient(
 
  181        config=_testsuite_client_config,
 
  183        testpoint_control=testpoint_control,
 
  184        log_capture_fixture=userver_log_capture,
 
  185        mocked_time=mocked_time,
 
  186        cache_invalidation_state=cache_invalidation_state,
 
  187        **service_client_options,
 
  192@pytest.fixture(scope='session') 
  195    Returns the main listener URL of the service. 
  197    Override this fixture to change the main listener URL that the testsuite 
  200    @ingroup userver_testsuite_fixtures 
  202    return f
'http://localhost:{service_port}/' 
  205@pytest.fixture(scope='session') 
 
  208    Returns the main monitor URL of the service. 
  210    Override this fixture to change the main monitor URL that the testsuite 
  213    @ingroup userver_testsuite_fixtures 
  215    return f
'http://localhost:{monitor_port}/' 
  218@pytest.fixture(scope='session') 
 
  219def _testsuite_client_config(
 
  220        pytestconfig, service_config_yaml,
 
  221) -> client.TestsuiteClientConfig:
 
  222    components = service_config_yaml[
'components_manager'][
'components']
 
  224    def get_component_path(name, argname=None):
 
  225        if name 
in components:
 
  226            path = components[name][
'path']
 
  227            path = path.rstrip(
'*')
 
  229            if argname 
and f
'{{{argname}}}' not in path:
 
  231                    f
'Component {name} must provide path argument {argname}',
 
  237        server_monitor_path=get_component_path(
'handler-server-monitor'),
 
  238        testsuite_action_path=get_component_path(
'tests-control', 
'action'),