userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
scylla.py
1
"""
2
Plugin that waits for a ScyllaDB cluster to become reachable and adjusts
3
the `scylla-*` components of the static config to point at it.
4
"""
5
6
# pylint: disable=redefined-outer-name
7
import
dataclasses
8
import
logging
9
10
import
pytest
11
12
from
testsuite.environment
import
utils
as
env_utils
13
14
pytest_plugins = [
'pytest_userver.plugins.core'
]
15
16
USERVER_CONFIG_HOOKS = [
'userver_config_scylla'
]
17
18
logger = logging.getLogger(__name__)
19
20
DEFAULT_HOST =
'localhost'
21
DEFAULT_CQL_PORT = 9042
22
DEFAULT_WAIT_TIMEOUT = 60.0
23
24
_SCYLLA_COMPONENT_PREFIX =
'scylla-'
25
26
27
def
pytest_addoption(parser) -> None:
28
group = parser.getgroup(
'scylla'
)
29
group.addoption(
30
'--scylla-host'
,
31
help=(
32
'Host of the ScyllaDB cluster used by functional tests. Defaults to $TESTSUITE_SCYLLA_HOST or "localhost".'
33
),
34
)
35
group.addoption(
36
'--scylla-port'
,
37
type=int,
38
help=(
'CQL native transport port. Defaults to $TESTSUITE_SCYLLA_PORT or 9042.'
),
39
)
40
group.addoption(
41
'--scylla-wait-timeout'
,
42
type=float,
43
help=(
44
'Seconds to wait for the CQL port to start accepting '
45
'connections before failing service start. '
46
'Defaults to $TESTSUITE_SCYLLA_WAIT_TIMEOUT or 60.'
47
),
48
)
49
50
51
@dataclasses.dataclass(frozen=True)
52
class
ConnectionInfo
:
53
host: str
54
port: int
55
56
def
contact_points(self) -> str:
57
if
self.
port
== DEFAULT_CQL_PORT:
58
return
self.host
59
return
f
'{self.host}:{self.port}'
60
61
62
@pytest.fixture(scope='session')
63
def
scylla_connection_info
(pytestconfig) -> ConnectionInfo:
64
"""
65
Where the ScyllaDB cluster is expected to be running.
66
67
@ingroup userver_testsuite_fixtures
68
"""
69
host = pytestconfig.option.scylla_host
or
env_utils.getenv_str(
70
'TESTSUITE_SCYLLA_HOST'
,
71
DEFAULT_HOST,
72
)
73
port = pytestconfig.option.scylla_port
or
env_utils.getenv_int(
74
'TESTSUITE_SCYLLA_PORT'
,
75
DEFAULT_CQL_PORT,
76
)
77
return
ConnectionInfo
(host=host, port=port)
78
79
80
@pytest.fixture(scope='session')
81
def
scylla_wait_timeout(pytestconfig) -> float:
82
"""@ingroup userver_testsuite_fixtures"""
83
return
pytestconfig.option.scylla_wait_timeout
or
env_utils.getenv_float(
84
'TESTSUITE_SCYLLA_WAIT_TIMEOUT'
,
85
DEFAULT_WAIT_TIMEOUT,
86
)
87
88
89
@pytest.fixture(scope='session')
90
def
_scylla_tcp_ready(scylla_connection_info, scylla_wait_timeout) -> None:
91
info = scylla_connection_info
92
logger.info(
93
'Waiting up to %.1fs for ScyllaDB CQL port at %s:%d'
,
94
scylla_wait_timeout,
95
info.host,
96
info.port,
97
)
98
if
not
env_utils.wait_tcp_connection(
99
host=info.host,
100
port=info.port,
101
timeout=scylla_wait_timeout,
102
):
103
raise
RuntimeError(
104
f
'ScyllaDB is not reachable at {info.host}:{info.port} after '
105
f
'{scylla_wait_timeout:.1f}s. Start the cluster or set '
106
'--scylla-host / TESTSUITE_SCYLLA_HOST to a reachable endpoint.'
,
107
)
108
109
110
@pytest.fixture
111
def
scylla(_scylla_tcp_ready, scylla_connection_info) -> ConnectionInfo:
112
"""@ingroup userver_testsuite_fixtures"""
113
return
scylla_connection_info
114
115
116
@pytest.fixture(scope='session')
117
def
userver_config_scylla(scylla_connection_info, _scylla_tcp_ready):
118
"""@ingroup userver_testsuite_fixtures"""
119
contact_points = scylla_connection_info.contact_points()
120
121
def
_patch(config_yaml, config_vars):
122
components = config_yaml[
'components_manager'
][
'components'
]
123
for
name, params
in
components.items():
124
if
not
isinstance(params, dict):
125
continue
126
if
not
name.startswith(_SCYLLA_COMPONENT_PREFIX):
127
continue
128
if
'dbalias'
in
params
and
params[
'dbalias'
]:
129
continue
130
if
'dbconnection'
not
in
params:
131
continue
132
params[
'dbconnection'
] = contact_points
133
134
return
_patch
testsuite
pytest_plugins
pytest_userver
plugins
scylla.py
Generated on
for userver by
Doxygen
1.17.0