userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
testpoint.py
1
import
collections.abc
2
import
typing
3
4
import
pytest
5
6
from
testsuite
import
types
7
from
testsuite.mockserver
import
server
8
from
testsuite.utils
import
callinfo, http
9
10
TestpointHandler = typing.Callable[
11
[types.JsonAnyOptional],
12
types.MaybeAsyncResult[types.JsonAnyOptional],
13
]
14
TestpointDecorator = typing.Callable[
15
[TestpointHandler],
16
callinfo.AsyncCallQueue,
17
]
18
19
20
class
TestpointFixture
(collections.abc.MutableMapping):
21
"""Testpoint control object."""
22
23
def
__init__(self, *, checker_factory) -> None:
24
self.
_handlers
: dict[str,
callinfo.AsyncCallQueue
] = {}
25
self.
_checker_factory
= checker_factory
26
27
def
__getitem__(self, name: str) ->
callinfo.AsyncCallQueue
:
28
return
self.
_handlers
[name]
29
30
def
__setitem__(self, key: str, value:
callinfo.AsyncCallQueue
):
31
self.
_handlers
[key] = value
32
33
def
__delitem__(self, key):
34
if
isinstance(key,
callinfo.AsyncCallQueue
):
35
names = [
36
name
for
name, value
in
self.
_handlers
.items()
if
value == key
37
]
38
if
not
names:
39
raise
KeyError(f
'{key!r}'
)
40
for
name
in
names:
41
del self.
_handlers
[name]
42
else
:
43
del self.
_handlers
[key]
44
45
def
__len__(self):
46
return
len(self.
_handlers
)
47
48
def
__iter__(self):
49
return
iter(self.
_handlers
)
50
51
def
__call__
(self, name: str) -> TestpointDecorator:
52
"""Returns decorator for registering testpoint called ``name``.
53
54
After decoration function is wrapped with `AsyncCallQueue`_.
55
"""
56
57
checker = self.
_checker_factory
(name)
58
59
def
decorator(func) -> callinfo.AsyncCallQueue:
60
wrapped = callinfo.acallqueue(func, checker=checker)
61
self[name] = wrapped
62
return
wrapped
63
64
return
decorator
65
66
67
@pytest.fixture(scope='session')
68
def
testpoint_checker_factory
():
69
"""Testpoint checker factory fixture.
70
71
Can be used to control whether or not testpoint is valid.
72
Feel free to override, e.g.:
73
74
@code
75
@pytest.fixture
76
def testpoint_checker_factory(testpoint_enabled)
77
def create_checker(name):
78
def checker(opname):
79
if testpoint_enabled(name):
80
return
81
pytest.fail(
82
f'{opname}() called on disabled testpoint {name}'
83
)
84
return create_checker
85
@endcode
86
87
@ingroup userver_testsuite_fixtures
88
Part of the [yandex-taxi-testsuite](https://github.com/yandex/yandex-taxi-testsuite/blob/develop/testsuite/plugins/testpoint.py#L68)
89
"""
90
91
def
create_checker(name):
92
return
None
93
94
return
create_checker
95
96
97
@pytest.fixture
98
async def
testpoint
(
99
mockserver: server.MockserverFixture,
100
testpoint_checker_factory,
101
) -> TestpointFixture:
102
"""Testpoint fixture returns testpoint session instance that works
103
as decorator that registers testpoint handler. Original function is
104
wrapped with @ref AsyncCallQueue
105
106
@param name testpoint name
107
@returns decorator
108
109
@code
110
def test_foo(testpoint):
111
@testpoint('foo'):
112
def testpoint_handler(data):
113
pass
114
115
...
116
# testpoint_handler is AsyncCallQueue instance, e.g.:
117
assert testpoint_handler.has_calls
118
assert testpoint_handler.next_call == {...}
119
aseert testpoint_handler.wait_call() == {...}
120
@endcode
121
122
@ingroup userver_testsuite_fixtures
123
Part of the [yandex-taxi-testsuite](https://github.com/yandex/yandex-taxi-testsuite/blob/develop/testsuite/plugins/testpoint.py#L95)
124
"""
125
126
session =
TestpointFixture
(checker_factory=testpoint_checker_factory)
127
128
@mockserver.json_handler('/testpoint')
129
async def
_handler(request: http.Request):
130
body = request.json
131
handler = session.get(body[
'name'
])
132
if
handler
is
None
:
133
return
{
'data'
:
None
,
'handled'
:
False
}
134
data = await handler(body[
'data'
])
135
return
{
'data'
: data,
'handled'
:
True
}
136
137
return
session
en
testsuite
plugins
testpoint.py
Generated on
for userver by
Doxygen
1.17.0