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,
321 Depend on this fixture directly or transitively to make your fixture a per-daemon fixture.
326 @pytest.fixture(scope='session')
327 def users_cache_state(daemon_scoped_mark, ...):
328 return UsersCacheState(users_list=[])
331 For tests marked with `@pytest.mark.uservice_oneshot(...)`, the service will be restarted,
332 and all the per-daemon fixtures will be recreated.
334 This fixture returns kwargs passed to the `uservice_oneshot` mark (which may be an empty dict).
335 For normal tests, this fixture returns `None`.
337 @ingroup userver_testsuite_fixtures
345 return getattr(request,
'param',
None)
351def pytest_configure(config):
352 config.addinivalue_line(
354 'uservice_oneshot: use a per-test service daemon instance',
358def _contains_oneshot_marker(parametrize: Iterable[pytest.Mark]) -> bool:
360 Check if at least one of 'parametrize' marks is of the form:
362 @pytest.mark.parametrize(
366 pytest.param("b", 20, marks=pytest.mark.uservice_oneshot), # <====
372 for parametrize_mark
in parametrize
373 if len(parametrize_mark.args) >= 2
374 for parameter_set
in parametrize_mark.args[1]
375 if hasattr(parameter_set,
'marks')
376 for mark
in parameter_set.marks
377 if mark.name ==
'uservice_oneshot'
381def pytest_generate_tests(metafunc: pytest.Metafunc) ->
None:
382 oneshot_marker = metafunc.definition.get_closest_marker(
'uservice_oneshot')
383 parametrize_markers = metafunc.definition.iter_markers(
'parametrize')
384 if oneshot_marker
is not None or _contains_oneshot_marker(parametrize_markers):
386 metafunc.parametrize(
387 (daemon_scoped_mark.__name__,),
392 ids=[
'uservice_oneshot'],
399def pytest_collection_modifyitems(items: list[pytest.Item]):
401 oneshot_marker = item.get_closest_marker(
'uservice_oneshot')
402 if oneshot_marker
and isinstance(item, pytest.Function):
403 func_item = typing.cast(pytest.Function, item)
404 func_item.callspec.params[daemon_scoped_mark.__name__] = dict(oneshot_marker.kwargs, function=func_item)