userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
mockserver.py
1
"""
2
Mocks for the gRPC servers.
3
4
@sa @ref scripts/docs/en/userver/tutorial/grpc_service.md
5
"""
6
7
from
collections.abc
import
AsyncIterator
8
from
collections.abc
import
Iterator
9
10
import
grpc
11
import
pytest
12
13
import
pytest_userver.grpc
14
15
# @cond
16
17
18
DEFAULT_PORT = 8091
19
20
USERVER_CONFIG_HOOKS = [
'userver_config_grpc_mockserver'
]
21
22
23
# @endcond
24
25
26
@pytest.fixture(scope='session')
27
def
grpc_mockserver_endpoint
(pytestconfig, get_free_port) -> str:
28
"""
29
Returns the gRPC endpoint to start the mocking server that is set by
30
command line `--grpc-mockserver-host` and `--grpc-mockserver-port` options.
31
32
For port 0, picks some free port.
33
34
Override this fixture to customize the endpoint used by gRPC mockserver.
35
36
@snippet grpc/functional_tests/basic_chaos/tests-grpcclient/conftest.py grpc_mockserver_endpoint example
37
@ingroup userver_testsuite_fixtures
38
"""
39
port = pytestconfig.option.grpc_mockserver_port
40
if
pytestconfig.option.service_wait
or
pytestconfig.option.service_disable:
41
port = port
or
DEFAULT_PORT
42
if
port == 0:
43
port = get_free_port()
44
return
f
'{pytestconfig.option.grpc_mockserver_host}:{port}'
45
46
47
@pytest.fixture(scope='session')
48
async def
grpc_mockserver_session
(grpc_mockserver_endpoint) -> AsyncIterator[pytest_userver.grpc.MockserverSession]:
49
"""
50
Returns the gRPC mocking server.
51
52
@warning This is a sharp knife, use with caution! For most use-cases, prefer
53
@ref pytest_userver.plugins.grpc.mockserver.grpc_mockserver "grpc_mockserver" instead.
54
55
@ingroup userver_testsuite_fixtures
56
"""
57
server = grpc.aio.server()
58
server.add_insecure_port(grpc_mockserver_endpoint)
59
60
async
with
pytest_userver.grpc.MockserverSession
(server=server, experimental=
True
)
as
mockserver:
61
yield
mockserver
62
63
64
@pytest.fixture
65
def
grpc_mockserver
(grpc_mockserver_session, asyncexc_append) -> Iterator[pytest_userver.grpc.Mockserver]:
66
"""
67
Returns the gRPC mocking server.
68
In order for gRPC clients in your service to work, mock handlers need to be installed for them using this fixture.
69
70
Example:
71
72
@snippet samples/grpc_service/testsuite/test_grpc.py Prepare modules
73
@snippet samples/grpc_service/testsuite/test_grpc.py grpc client test
74
75
Alternatively, you can create a shorthand for mocking frequently-used services:
76
77
@snippet grpc/functional_tests/metrics/tests/conftest.py Prepare modules
78
@snippet grpc/functional_tests/metrics/tests/conftest.py Prepare server mock
79
@snippet grpc/functional_tests/metrics/tests/test_metrics.py grpc client test
80
81
Mocks are only active within tests after their respective handler functions are created, not between tests.
82
If the service needs the mock during startup, add the fixture that defines your mock to
83
@ref pytest_userver.plugins.service.extra_client_deps "extra_client_deps".
84
85
To return an error status instead of response, use `context` (see
86
[ServicerContext](https://grpc.github.io/grpc/python/grpc_asyncio.html#grpc.aio.ServicerContext)
87
docs):
88
89
@snippet grpc/functional_tests/middleware_client/tests/test_error_status.py Mocked error status
90
91
To trigger special exceptions in the service's gRPC client, raise these mocked errors from the mock handler:
92
93
* @ref pytest_userver.grpc._mocked_errors.TimeoutError "pytest_userver.grpc.TimeoutError"
94
* @ref pytest_userver.grpc._mocked_errors.NetworkError "pytest_userver.grpc.NetworkError"
95
96
@ingroup userver_testsuite_fixtures
97
"""
98
with
grpc_mockserver_session.asyncexc_append_scope(asyncexc_append):
99
with
pytest_userver.grpc.Mockserver
(
100
mockserver_session=grpc_mockserver_session,
101
experimental=
True
,
102
)
as
mockserver:
103
yield
mockserver
104
105
106
@pytest.fixture(scope='session')
107
def
userver_config_grpc_mockserver
():
108
"""
109
Returns a function that adjusts the static config for testsuite.
110
Finds `grpc-client-middleware-pipeline` in config_yaml and
111
enables `grpc-client-middleware-testsuite`.
112
113
@ingroup userver_testsuite_fixtures
114
"""
115
116
def
get_dict_field(parent: dict, field_name: str) -> dict:
117
if
parent.setdefault(field_name, {})
is
None
:
118
parent[field_name] = {}
119
120
return
parent[field_name]
121
122
def
patch_config(config_yaml, _config_vars):
123
components = config_yaml[
'components_manager'
][
'components'
]
124
if
components.get(
'grpc-client-common'
,
None
)
is
not
None
:
125
client_middlewares_pipeline = get_dict_field(components,
'grpc-client-middlewares-pipeline'
)
126
middlewares = get_dict_field(client_middlewares_pipeline,
'middlewares'
)
127
testsuite_middleware = get_dict_field(middlewares,
'grpc-client-middleware-testsuite'
)
128
testsuite_middleware[
'enabled'
] =
True
129
130
return
patch_config
131
132
133
# @cond
134
135
136
def
pytest_addoption(parser):
137
group = parser.getgroup(
'grpc-mockserver'
)
138
group.addoption(
139
'--grpc-mockserver-host'
,
140
default=
'[::]'
,
141
help=
'gRPC mockserver hostname, default is [::]'
,
142
)
143
group.addoption(
144
'--grpc-mockserver-port'
,
145
type=int,
146
default=0,
147
help=
'gRPC mockserver port, by default random port is used'
,
148
)
149
150
151
# @endcond
testsuite
pytest_plugins
pytest_userver
plugins
grpc
mockserver.py
Generated on
for userver by
Doxygen
1.17.0