35 Allows to install mocks that are kept active between tests, see
36 @ref pytest_userver.plugins.grpc.mockserver.grpc_mockserver_session "grpc_mockserver_session".
38 @warning This is a sharp knife, use with caution! For most use-cases, prefer
39 @ref pytest_userver.plugins.grpc.mockserver.grpc_mockserver "grpc_mockserver" instead.
42 def __init__(self, *, server: grpc.aio.Server, experimental: bool =
False) ->
None:
44 @warning This initializer is an **experimental API**, likely to break in the future. Consider using
45 @ref pytest_userver.plugins.grpc.mockserver.grpc_mockserver_session "grpc_mockserver_session" instead.
47 Initializes `MockserverSession`. Takes ownership of `server`.
48 To properly start and stop the server, use `MockserverSession` as an async contextmanager:
51 async with pytest_userver.grpc.mockserver.MockserverSession(server=server) as mockserver:
55 @note `MockserverSession` is usually obtained from
56 @ref pytest_userver.plugins.grpc.mockserver.grpc_mockserver_session "grpc_mockserver_session".
63 def _get_auto_service_mock(self, servicer_class: type, /) -> _ServiceMock:
67 new_mock = _create_servicer_mock(servicer_class)
70 new_mock.add_to_server(self.
_server)
73 def _set_asyncexc_append(self, asyncexc_append: AsyncExcAppend |
None, /) ->
None:
76 mock.set_asyncexc_append(asyncexc_append)
80 @brief Removes all mocks for this mockserver that have been installed using
81 `MockserverSession` or @ref pytest_userver.grpc.Mockserver "Mockserver" API.
82 @note Mocks installed manually using @ref MockserverSession.server will not be removed, though.
87 @contextlib.contextmanager
90 Sets testsuite's `asyncexc_append` for use in the returned scope.
101 The underlying [grpc.aio.Server](https://grpc.github.io/grpc/python/grpc_asyncio.html#grpc.aio.Server).
108 @note Prefer starting mockserver using the async contextmanager syntax if possible.
114 Stops the server properly. Prefer this method to stopping `server` manually.
116 await _stop_server(self.
_server)
118 async def __aenter__(self) -> MockserverSession:
122 async def __aexit__(self, exc_type, exc_val, exc_tb) -> None:
128 Allows to install mocks that are reset between tests, see
129 @ref pytest_userver.plugins.grpc.mockserver.grpc_mockserver "grpc_mockserver".
132 def __init__(self, *, mockserver_session: MockserverSession, experimental: bool =
False) ->
None:
134 @warning This initializer is an **experimental API**, likely to break in the future. Consider using
135 @ref pytest_userver.plugins.grpc.mockserver.grpc_mockserver "grpc_mockserver" instead.
137 Initializes Mockserver.
139 @note `Mockserver` is usually obtained from
140 @ref pytest_userver.plugins.grpc.mockserver.grpc_mockserver "grpc_mockserver".
145 def __call__(self, servicer_method, /) -> MockDecorator:
147 Returns a decorator to mock the specified gRPC service method implementation.
151 @snippet samples/grpc_service/testsuite/test_grpc.py Prepare modules
152 @snippet samples/grpc_service/testsuite/test_grpc.py grpc client test
154 servicer_class = _get_class_from_method(servicer_method)
156 return mock.install_handler(servicer_method.__name__)
158 def mock_factory(self, servicer_class, /) -> Callable[[str], MockDecorator]:
160 Allows to create a fixture as a shorthand for mocking methods of the specified gRPC service.
164 @snippet grpc/functional_tests/metrics/tests/conftest.py Prepare modules
165 @snippet grpc/functional_tests/metrics/tests/conftest.py Prepare server mock
166 @snippet grpc/functional_tests/metrics/tests/test_metrics.py grpc client test
169 def factory(method_name):
170 method = getattr(servicer_class, method_name,
None)
172 raise ValueError(f
'No method "{method_name}" in servicer class "{servicer_class.__name__}"')
175 _check_is_servicer_class(servicer_class)
178 def install_servicer(self, servicer: object, /) ->
None:
180 Installs as a mock `servicer`, the class of which should inherit from a generated `*Servicer` class.
182 For example, @ref grpc/functional_tests/basic_chaos/tests-grpcclient/service.py "this servicer class"
183 can be installed as follows:
185 @snippet grpc/functional_tests/basic_chaos/tests-grpcclient/conftest.py installing mockserver servicer
187 @note Inheritance from multiple `*Servicer` classes at once is allowed.
189 @example grpc/functional_tests/basic_chaos/tests-grpcclient/service.py
191 base_servicer_classes = [cls
for cls
in inspect.getmro(type(servicer))[1:]
if cls.__name__.endswith(
'Servicer')]
192 if not base_servicer_classes:
193 raise ValueError(f
"Given object's type ({type(servicer)}) is not inherited from any grpc *Servicer class")
194 for servicer_class
in base_servicer_classes:
197 for python_method_name
in mock.known_methods:
198 handler_func = getattr(servicer, python_method_name)
199 mock.install_handler(python_method_name)(handler_func)
205async def _stop_server(server: grpc.aio.Server, /) ->
None:
206 async def stop_server():
207 await server.stop(grace=
None)
208 await server.wait_for_termination()
210 stop_server_task = asyncio.shield(asyncio.create_task(stop_server()))
214 await stop_server_task
215 except asyncio.CancelledError:
216 await stop_server_task
221def _get_class_from_method(method) -> type:
223 assert inspect.isfunction(method), f
'Expected an unbound method: foo(ClassName.MethodName), got: {method}'
224 class_name = method.__qualname__.split(
'.<locals>', 1)[0].rsplit(
'.', 1)[0]
226 cls = getattr(inspect.getmodule(method), class_name)
227 except AttributeError:
228 cls = method.__globals__.get(class_name)
229 assert isinstance(cls, type)