11import asyncio
2+ import copy
23import pathlib
34import shutil
45import tempfile
@@ -214,7 +215,7 @@ def userver_pg_config(pgsql_local, pg_gate):
214215 db_uri = {name : conn .get_uri () for name , conn in pgsql_local .items ()}
215216 gate_host , gate_port = pg_gate .get_sockname_for_clients ()
216217
217- def _patch (config_yaml , _config_vars ):
218+ def _patch (config_yaml , config_vars ):
218219 components = config_yaml ["components_manager" ]["components" ]
219220 for component_name in ("capture_meta_db" , "shared_state_db" ):
220221 conninfo = db_uri [component_name ]
@@ -226,6 +227,9 @@ def _patch(config_yaml, _config_vars):
226227 else :
227228 netloc = f"{ gate_host } :{ gate_port } "
228229 updated = parsed ._replace (netloc = netloc )
230+ # Prefer config-vars for templated fields, but also patch the resolved YAML so
231+ # the hook remains effective even if config-vars resolution happens earlier.
232+ config_vars [f"pg_{ component_name } _dsn" ] = urlunparse (updated )
229233 component = components [component_name ]
230234 component ["dbconnection" ] = urlunparse (updated )
231235 component .pop ("dbalias" , None )
@@ -261,7 +265,8 @@ def allowed_url_prefixes_extra(s3_gate_port):
261265def patch_s3_config (s3_gate_port ):
262266 del s3_gate_port
263267
264- def _patch (config_yaml , _config_vars ):
268+ def _patch (config_yaml , config_vars ):
269+ del config_vars
265270 components = config_yaml ["components_manager" ]["components" ]
266271 cfg = components ["config" ]
267272 cfg ["s3_timeout_ms" ] = _TESTSUITE_S3_TIMEOUT_MS
@@ -275,16 +280,22 @@ def _patch(config_yaml, _config_vars):
275280
276281@pytest .fixture (scope = "session" )
277282def service_config_path_temp (
283+ daemon_scoped_mark ,
278284 service_tmpdir ,
279- _service_config_hooked ,
285+ service_config_yaml ,
286+ service_config_vars ,
280287 service_binary : pathlib .Path ,
281288 service_source_dir : pathlib .Path ,
282289 testsuite_webshotd_state_dir : pathlib .Path ,
283290 s3_bucket_name : str ,
284291) -> pathlib .Path :
292+ # Mark this fixture as per-daemon. For oneshot tests, daemon_scoped_mark changes
293+ # and pytest tears down/recreates the whole dependency tree.
294+ del daemon_scoped_mark
295+
285296 dst_path = service_tmpdir / "config.yaml"
286- config_yaml = dict ( _service_config_hooked . config_yaml )
287- config_vars = dict ( _service_config_hooked . config_vars )
297+ config_yaml = copy . deepcopy ( service_config_yaml )
298+ config_vars = copy . deepcopy ( service_config_vars )
288299 runtime_layout = runtime_layout_from_binary (service_binary )
289300 config_vars ["rapidoc_assets_dir" ] = str (runtime_layout .rapidoc_assets_dir )
290301 config_vars ["openapi_public_dir" ] = str (service_source_dir .parent / "schema" / "public" )
@@ -295,6 +306,9 @@ def service_config_path_temp(
295306 config_vars ["state_dir" ] = str (testsuite_webshotd_state_dir )
296307 config_vars ["s3_bucket" ] = s3_bucket_name
297308 config_vars ["public_base_url" ] = f"http://127.0.0.1:8333/{ s3_bucket_name } "
309+ # Ensure url_bytes_max always exists in config_vars so oneshot config hooks may override it.
310+ # static_config.yaml uses $url_bytes_max with a fallback; config vars must be concrete.
311+ config_vars .setdefault ("url_bytes_max" , 32768 )
298312 config_vars .update (task_processor_config_vars (config_yaml ))
299313
300314 components = config_yaml ["components_manager" ]["components" ]
0 commit comments