2Mocks for the gRPC servers. 
    4@sa @ref scripts/docs/en/userver/tutorial/grpc_service.md 
   16from testsuite.utils 
import callinfo
 
   22    def __init__(self, servicer, methods):
 
   27    def get(self, method, default):
 
   28        return self.
_methods.get(method, default)
 
   30    @contextlib.contextmanager 
   37    def install_handler(self, method: str):
 
   41                    f
'Trying to mock unknown grpc method {method}',
 
   44            wrapped = callinfo.acallqueue(func)
 
   51@pytest.fixture(scope='session') 
 
   52def _grpc_mockserver_endpoint(pytestconfig):
 
   53    port = pytestconfig.option.grpc_mockserver_port
 
   54    if pytestconfig.option.service_wait 
or pytestconfig.option.service_disable:
 
   55        port = port 
or DEFAULT_PORT
 
   57        port = _find_free_port()
 
   58    return f
'{pytestconfig.option.grpc_mockserver_host}:{port}' 
   61@pytest.fixture(scope='session') 
   64    Returns the gRPC endpoint to start the mocking server that is set by 
   65    command line `--grpc-mockserver-host` and `--grpc-mockserver-port` options. 
   67    Override this fixture to change the way the gRPC endpoint 
   68    is detected by the testsuite. 
   70    @snippet samples/grpc_service/tests/conftest.py  Prepare configs 
   71    @ingroup userver_testsuite_fixtures 
   73    return f
'{pytestconfig.option.grpc_mockserver_host}:{_grpc_port}' 
 
   76def _find_free_port() -> int:
 
   77    with contextlib.closing(
 
   78            socket.socket(socket.AF_INET6, socket.SOCK_STREAM),
 
   81        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 
   82        return s.getsockname()[1]
 
   85@pytest.fixture(scope='session') 
   86def _grpc_port(_grpc_mockserver_endpoint):
 
   87    _, port = _grpc_mockserver_endpoint.rsplit(
':', 1)
 
   91@pytest.fixture(scope='session') 
   94    Returns the gRPC mocking server. 
   96    Override this fixture to change the way the gRPC 
   97    mocking server is started by the testsuite. 
   99    @snippet samples/grpc_service/tests/conftest.py  Prepare server mock 
  100    @ingroup userver_testsuite_fixtures 
  102    server = grpc.aio.server()
 
  103    server.add_insecure_port(_grpc_mockserver_endpoint)
 
  104    server_task = asyncio.create_task(server.start())
 
  109        await server.stop(grace=
None)
 
  110        await server.wait_for_termination()
 
  114@pytest.fixture(scope='session') 
 
  117    Creates the gRPC mock server for the provided type. 
  119    @snippet samples/grpc_service/tests/conftest.py  Prepare server mock 
  120    @ingroup userver_testsuite_fixtures 
  122    return _create_servicer_mock
 
 
  125def pytest_addoption(parser):
 
  126    group = parser.getgroup(
'grpc-mockserver')
 
  128        '--grpc-mockserver-host',
 
  130        help=
'gRPC mockserver hostname, default is [::]',
 
  133        '--grpc-mockserver-port',
 
  136        help=
'gRPC mockserver port, by default random port is used',
 
  140def _create_servicer_mock(servicer_class):
 
  141    def wrap_grpc_method(name, default_method):
 
  142        @functools.wraps(default_method) 
  143        async def run_method(self, *args, **kwargs):
 
  144            method = mock.get(name, 
None)
 
  145            if method 
is not None:
 
  146                return await method(*args, **kwargs)
 
  148                return await default_method(self, *args, **kwargs)
 
  153    for attname, value 
in servicer_class.__dict__.items():
 
  155            methods[attname] = wrap_grpc_method(attname, value)
 
  157    mocked_servicer_class = type(
 
  158        f
'Mock{servicer_class.__name__}', (servicer_class,), methods,
 
  160    servicer = mocked_servicer_class()