63 Returns the service HTTP ping URL that is used by the testsuite to detect
64 that the service is ready to work. Returns None if there's no such URL.
66 By default, attempts to find server::handlers::Ping component by
67 "handler-ping" name in static config. Override this fixture to change the
70 @ingroup userver_testsuite_fixtures
72 components = service_config[
'components_manager'][
'components']
73 ping_handler = components.get(
'handler-ping')
75 return url_util.join(service_baseurl, ping_handler[
'path'])
79@pytest.fixture(scope='session')
134 service_http_ping_url,
135 service_config_path_temp,
137 service_binary_launcher,
138 service_non_http_health_checks,
139 service_start_timeout,
142 Prepares the start of the service daemon.
143 Configures the health checking to use service_http_ping_url fixture value
144 if it is not None; otherwise uses the service_non_http_health_checks info.
146 @see @ref pytest_userver.plugins.service.service_daemon_instance "service_daemon_instance"
147 @ingroup userver_testsuite_fixtures
149 assert service_http_ping_url
or service_non_http_health_checks.tcp, (
150 '"service_http_ping_url" and "create_health_checker" fixtures '
151 'returned None. Testsuite is unable to detect if the service is ready '
152 'to accept requests.',
156 'userver fixture "service_daemon_scope" would check for "%s"',
157 service_non_http_health_checks,
164 async def _checker(*, session, process) -> bool:
165 LocalCounters.attempts += 1
166 new_log_time = time.monotonic()
167 if new_log_time - LocalCounters.last_log_time > 1.0:
168 LocalCounters.last_log_time = new_log_time
170 'userver fixture "service_daemon_scope" checking "%s", attempt %s',
171 service_non_http_health_checks,
172 LocalCounters.attempts,
175 return await net.check_availability(service_non_http_health_checks)
177 health_check = _checker
178 if service_http_ping_url:
182 poll_retries = int(service_start_timeout / 0.05)
184 async with create_daemon_scope(
185 args=service_binary_launcher + [str(service_binary),
'--config', str(service_config_path_temp)],
186 ping_url=service_http_ping_url,
187 health_check=health_check,
189 poll_retries=poll_retries,
319 Depend on this fixture directly or transitively to make your fixture a per-daemon fixture.
324 @pytest.fixture(scope='session')
325 def users_cache_state(daemon_scoped_mark, ...):
326 return UsersCacheState(users_list=[])
329 For tests marked with `@pytest.mark.uservice_oneshot(...)`, the service will be restarted,
330 and all the per-daemon fixtures will be recreated.
332 This fixture returns kwargs passed to the `uservice_oneshot` mark (which may be an empty dict).
333 For normal tests, this fixture returns `None`.
335 @ingroup userver_testsuite_fixtures
343 return getattr(request,
'param',
None)
349def pytest_configure(config):
350 config.addinivalue_line(
352 'uservice_oneshot: use a per-test service daemon instance',
356def _contains_oneshot_marker(parametrize: Iterable[pytest.Mark]) -> bool:
358 Check if at least one of 'parametrize' marks is of the form:
360 @pytest.mark.parametrize(
364 pytest.param("b", 20, marks=pytest.mark.uservice_oneshot), # <====
370 for parametrize_mark
in parametrize
371 if len(parametrize_mark.args) >= 2
372 for parameter_set
in parametrize_mark.args[1]
373 if hasattr(parameter_set,
'marks')
374 for mark
in parameter_set.marks
375 if mark.name ==
'uservice_oneshot'
379def pytest_generate_tests(metafunc: pytest.Metafunc) ->
None:
380 oneshot_marker = metafunc.definition.get_closest_marker(
'uservice_oneshot')
381 parametrize_markers = metafunc.definition.iter_markers(
'parametrize')
382 if oneshot_marker
is not None or _contains_oneshot_marker(parametrize_markers):
384 metafunc.parametrize(
385 (daemon_scoped_mark.__name__,),
390 ids=[
'uservice_oneshot'],
397def pytest_collection_modifyitems(items: list[pytest.Item]):
399 oneshot_marker = item.get_closest_marker(
'uservice_oneshot')
400 if oneshot_marker
and isinstance(item, pytest.Function):
401 func_item = typing.cast(pytest.Function, item)
402 func_item.callspec.params[daemon_scoped_mark.__name__] = dict(oneshot_marker.kwargs, function=func_item)