@@ -132,7 +132,7 @@ async def test_background_status_returns_output(client, created_api_key, bg_flow
132132 assert body ["outputs" ], f"completed background status carried no outputs: { body } "
133133
134134
135- async def test_background_status_from_job_table_with_vertex_builds_off (client , created_api_key , bg_flow ):
135+ async def test_background_status_from_job_table_with_vertex_builds_off (client , created_api_key , bg_flow , monkeypatch ):
136136 """With vertex_build storage OFF, GET status must still carry the full output.
137137
138138 Proves the headless-executor path: disable ``vertex_builds_storage_enabled`` so
@@ -150,49 +150,45 @@ async def test_background_status_from_job_table_with_vertex_builds_off(client, c
150150 from lfx .services .deps import get_settings_service
151151
152152 settings = get_settings_service ().settings
153- original = settings .vertex_builds_storage_enabled
154- settings .vertex_builds_storage_enabled = False
155- try :
156- submit = await client .post ("api/v2/workflows" , json = _body (bg_flow ), headers = _headers (created_api_key ))
157- assert submit .status_code == 200 , submit .text
158- job_id = submit .json ()["job_id" ]
159-
160- row = None
161- for _ in range (200 ):
162- async with session_scope () as session :
163- row = await session .get (Job , UUID (job_id ))
164- if row is not None and row .status in (
165- JobStatus .COMPLETED ,
166- JobStatus .FAILED ,
167- JobStatus .TIMED_OUT ,
168- ):
169- break
170- await asyncio .sleep (0.1 )
171- assert row is not None , "job row was never created"
172- assert row .status == JobStatus .COMPLETED , f"job did not complete: { row .status } "
153+ monkeypatch .setattr (settings , "vertex_builds_storage_enabled" , False )
154+ submit = await client .post ("api/v2/workflows" , json = _body (bg_flow ), headers = _headers (created_api_key ))
155+ assert submit .status_code == 200 , submit .text
156+ job_id = submit .json ()["job_id" ]
173157
174- # Proof 1: storage OFF => no vertex_build rows persisted for this job_id.
158+ row = None
159+ for _ in range (200 ):
175160 async with session_scope () as session :
176- vbs = await get_vertex_builds_by_job_id (session , job_id )
177- assert not vbs , f"vertex_builds were written despite storage OFF: { len (vbs )} rows"
178-
179- # Proof 2: the durable Job.result blob carries the captured terminal outputs.
180- assert isinstance (row .result , dict ), f"Job.result is not a dict: { row .result !r} "
181- assert row .result .get ("outputs" ), f"Job.result carried no outputs: { row .result } "
182-
183- # Proof 3: GET status returns the full output, sourced from Job.result (reconstruct
184- # finds nothing with storage off, so the COMPLETED branch falls back to Job.result).
185- status = await client .get ("api/v2/workflows" , params = {"job_id" : job_id }, headers = _headers (created_api_key ))
186- assert status .status_code == 200 , status .text
187- body = status .json ()
188- assert body ["status" ] == "completed"
189- assert body ["outputs" ], f"GET status carried no outputs with vertex_builds OFF: { body } "
190- # Proof 4: the Job.result path recovers the session_id from the terminal
191- # events (parity with the vertex-build path), so a background GET can
192- # continue the same chat thread even with vertex-build storage off.
193- assert body .get ("session_id" ), f"GET status lost session_id with vertex_builds OFF: { body } "
194- finally :
195- settings .vertex_builds_storage_enabled = original
161+ row = await session .get (Job , UUID (job_id ))
162+ if row is not None and row .status in (
163+ JobStatus .COMPLETED ,
164+ JobStatus .FAILED ,
165+ JobStatus .TIMED_OUT ,
166+ ):
167+ break
168+ await asyncio .sleep (0.1 )
169+ assert row is not None , "job row was never created"
170+ assert row .status == JobStatus .COMPLETED , f"job did not complete: { row .status } "
171+
172+ # Proof 1: storage OFF => no vertex_build rows persisted for this job_id.
173+ async with session_scope () as session :
174+ vbs = await get_vertex_builds_by_job_id (session , job_id )
175+ assert not vbs , f"vertex_builds were written despite storage OFF: { len (vbs )} rows"
176+
177+ # Proof 2: the durable Job.result blob carries the captured terminal outputs.
178+ assert isinstance (row .result , dict ), f"Job.result is not a dict: { row .result !r} "
179+ assert row .result .get ("outputs" ), f"Job.result carried no outputs: { row .result } "
180+
181+ # Proof 3: GET status returns the full output, sourced from Job.result (reconstruct
182+ # finds nothing with storage off, so the COMPLETED branch falls back to Job.result).
183+ status = await client .get ("api/v2/workflows" , params = {"job_id" : job_id }, headers = _headers (created_api_key ))
184+ assert status .status_code == 200 , status .text
185+ body = status .json ()
186+ assert body ["status" ] == "completed"
187+ assert body ["outputs" ], f"GET status carried no outputs with vertex_builds OFF: { body } "
188+ # Proof 4: the Job.result path recovers session_id from the persisted submit
189+ # request in job.job_metadata["request"], so a background GET can continue
190+ # the same chat thread even with vertex-build storage off.
191+ assert body .get ("session_id" ), f"GET status lost session_id with vertex_builds OFF: { body } "
196192
197193
198194async def test_background_agui_populates_job_result_outputs (client , created_api_key , bg_flow ):
0 commit comments