@@ -229,62 +229,133 @@ def test_application_run_status_to_str_terminated() -> None:
229229# Tests for is_not_terminated_with_deadline_exceeded
230230
231231
232+ # --- Tests using scheduling response object (new primary path) ---
233+
234+
235+ @pytest .mark .unit
236+ def test_is_not_terminated_with_deadline_exceeded_scheduling_object_terminated_run () -> None :
237+ """Test that terminated runs always return None regardless of scheduling deadline."""
238+ past_deadline = datetime (2020 , 1 , 1 , 12 , 0 , 0 , tzinfo = UTC )
239+ scheduling = Mock (deadline = past_deadline )
240+ result = is_not_terminated_with_deadline_exceeded (RunState .TERMINATED , scheduling = scheduling )
241+ assert result is None
242+
243+
244+ @pytest .mark .unit
245+ def test_is_not_terminated_with_deadline_exceeded_scheduling_object_pending_future () -> None :
246+ """Test that a pending run with scheduling deadline in the future returns False."""
247+ from datetime import timedelta
248+
249+ future_deadline = datetime .now (tz = UTC ) + timedelta (hours = 1 )
250+ scheduling = Mock (deadline = future_deadline )
251+ result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , scheduling = scheduling )
252+ assert result is False
253+
254+
255+ @pytest .mark .unit
256+ def test_is_not_terminated_with_deadline_exceeded_scheduling_object_pending_past () -> None :
257+ """Test that a pending run with scheduling deadline in the past returns True."""
258+ past_deadline = datetime (2020 , 1 , 1 , 12 , 0 , 0 , tzinfo = UTC )
259+ scheduling = Mock (deadline = past_deadline )
260+ result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , scheduling = scheduling )
261+ assert result is True
262+
263+
264+ @pytest .mark .unit
265+ def test_is_not_terminated_with_deadline_exceeded_scheduling_object_processing_past () -> None :
266+ """Test that a processing run with scheduling deadline in the past returns True."""
267+ past_deadline = datetime (2020 , 1 , 1 , 12 , 0 , 0 , tzinfo = UTC )
268+ scheduling = Mock (deadline = past_deadline )
269+ result = is_not_terminated_with_deadline_exceeded (RunState .PROCESSING , scheduling = scheduling )
270+ assert result is True
271+
272+
273+ @pytest .mark .unit
274+ def test_is_not_terminated_with_deadline_exceeded_scheduling_object_none_deadline () -> None :
275+ """Test that scheduling object with None deadline returns None."""
276+ scheduling = Mock (deadline = None )
277+ result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , scheduling = scheduling )
278+ assert result is None
279+
280+
281+ @pytest .mark .unit
282+ def test_is_not_terminated_with_deadline_exceeded_scheduling_none () -> None :
283+ """Test that None scheduling and None metadata returns None."""
284+ result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , scheduling = None , custom_metadata = None )
285+ assert result is None
286+
287+
288+ @pytest .mark .unit
289+ def test_is_not_terminated_with_deadline_exceeded_scheduling_takes_precedence () -> None :
290+ """Test that scheduling object takes precedence over custom_metadata."""
291+ from datetime import timedelta
292+
293+ # scheduling says future (not exceeded), custom_metadata says past (exceeded)
294+ future_deadline = datetime .now (tz = UTC ) + timedelta (hours = 1 )
295+ scheduling = Mock (deadline = future_deadline )
296+ metadata = {"sdk" : {"scheduling" : {"deadline" : "2020-01-01T12:00:00Z" }}}
297+ result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , scheduling = scheduling , custom_metadata = metadata )
298+ assert result is False # scheduling wins
299+
300+
301+ # --- Tests using custom_metadata fallback (backward compatibility for older runs) ---
302+
303+
232304@pytest .mark .unit
233305def test_is_not_terminated_with_deadline_exceeded_terminated_run () -> None :
234306 """Test that terminated runs always return None regardless of deadline."""
235307 past_deadline = datetime (2020 , 1 , 1 , 12 , 0 , 0 , tzinfo = UTC )
236308 metadata = {"sdk" : {"scheduling" : {"deadline" : past_deadline .isoformat ()}}}
237- result = is_not_terminated_with_deadline_exceeded (RunState .TERMINATED , metadata )
309+ result = is_not_terminated_with_deadline_exceeded (RunState .TERMINATED , custom_metadata = metadata )
238310 assert result is None
239311
240312
241313@pytest .mark .unit
242314def test_is_not_terminated_with_deadline_exceeded_none_metadata () -> None :
243315 """Test that None metadata returns None."""
244- result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , None )
316+ result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , custom_metadata = None )
245317 assert result is None
246318
247319
248320@pytest .mark .unit
249321def test_is_not_terminated_with_deadline_exceeded_empty_metadata () -> None :
250322 """Test that empty metadata returns None."""
251- result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , {})
323+ result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , custom_metadata = {})
252324 assert result is None
253325
254326
255327@pytest .mark .unit
256328def test_is_not_terminated_with_deadline_exceeded_no_sdk_key () -> None :
257329 """Test that metadata without 'sdk' key returns None."""
258330 metadata = {"other_key" : "other_value" }
259- result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , metadata )
331+ result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , custom_metadata = metadata )
260332 assert result is None
261333
262334
263335@pytest .mark .unit
264336def test_is_not_terminated_with_deadline_exceeded_no_scheduling_key () -> None :
265337 """Test that metadata without 'scheduling' key returns None."""
266338 metadata = {"sdk" : {"other_key" : "other_value" }}
267- result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , metadata )
339+ result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , custom_metadata = metadata )
268340 assert result is None
269341
270342
271343@pytest .mark .unit
272344def test_is_not_terminated_with_deadline_exceeded_no_deadline_key () -> None :
273345 """Test that metadata without 'deadline' key returns None."""
274346 metadata = {"sdk" : {"scheduling" : {"other_key" : "other_value" }}}
275- result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , metadata )
347+ result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , custom_metadata = metadata )
276348 assert result is None
277349
278350
279351@pytest .mark .unit
280352def test_is_not_terminated_with_deadline_exceeded_pending_deadline_in_future () -> None :
281353 """Test that a pending run with deadline in the future returns False."""
282- # Create a deadline 1 hour in the future
283354 from datetime import timedelta
284355
285356 future_deadline = datetime .now (tz = UTC ) + timedelta (hours = 1 )
286357 metadata = {"sdk" : {"scheduling" : {"deadline" : future_deadline .isoformat ()}}}
287- result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , metadata )
358+ result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , custom_metadata = metadata )
288359 assert result is False
289360
290361
@@ -293,7 +364,7 @@ def test_is_not_terminated_with_deadline_exceeded_pending_deadline_in_past() ->
293364 """Test that a pending run with deadline in the past returns True."""
294365 past_deadline = datetime (2020 , 1 , 1 , 12 , 0 , 0 , tzinfo = UTC )
295366 metadata = {"sdk" : {"scheduling" : {"deadline" : past_deadline .isoformat ()}}}
296- result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , metadata )
367+ result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , custom_metadata = metadata )
297368 assert result is True
298369
299370
@@ -302,15 +373,15 @@ def test_is_not_terminated_with_deadline_exceeded_processing_deadline_in_past()
302373 """Test that a processing run with deadline in the past returns True."""
303374 past_deadline = datetime (2020 , 1 , 1 , 12 , 0 , 0 , tzinfo = UTC )
304375 metadata = {"sdk" : {"scheduling" : {"deadline" : past_deadline .isoformat ()}}}
305- result = is_not_terminated_with_deadline_exceeded (RunState .PROCESSING , metadata )
376+ result = is_not_terminated_with_deadline_exceeded (RunState .PROCESSING , custom_metadata = metadata )
306377 assert result is True
307378
308379
309380@pytest .mark .unit
310381def test_is_not_terminated_with_deadline_exceeded_invalid_datetime_format () -> None :
311382 """Test that invalid datetime format returns None."""
312383 metadata = {"sdk" : {"scheduling" : {"deadline" : "not-a-valid-datetime" }}}
313- result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , metadata )
384+ result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , custom_metadata = metadata )
314385 assert result is None
315386
316387
@@ -319,7 +390,7 @@ def test_is_not_terminated_with_deadline_exceeded_deadline_with_z_suffix() -> No
319390 """Test that deadline with Z suffix (UTC) is handled correctly for pending run."""
320391 past_deadline = "2020-01-01T12:00:00Z"
321392 metadata = {"sdk" : {"scheduling" : {"deadline" : past_deadline }}}
322- result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , metadata )
393+ result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , custom_metadata = metadata )
323394 assert result is True
324395
325396
@@ -328,31 +399,31 @@ def test_is_not_terminated_with_deadline_exceeded_deadline_with_timezone_offset(
328399 """Test that deadline with timezone offset is handled correctly for pending run."""
329400 past_deadline = "2020-01-01T12:00:00+00:00"
330401 metadata = {"sdk" : {"scheduling" : {"deadline" : past_deadline }}}
331- result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , metadata )
402+ result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , custom_metadata = metadata )
332403 assert result is True
333404
334405
335406@pytest .mark .unit
336407def test_is_not_terminated_with_deadline_exceeded_deadline_empty_string () -> None :
337408 """Test that empty string deadline returns None."""
338409 metadata = {"sdk" : {"scheduling" : {"deadline" : "" }}}
339- result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , metadata )
410+ result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , custom_metadata = metadata )
340411 assert result is None
341412
342413
343414@pytest .mark .unit
344415def test_is_not_terminated_with_deadline_exceeded_deadline_none_value () -> None :
345416 """Test that None deadline value returns None."""
346417 metadata = {"sdk" : {"scheduling" : {"deadline" : None }}}
347- result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , metadata )
418+ result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , custom_metadata = metadata )
348419 assert result is None
349420
350421
351422@pytest .mark .unit
352423def test_is_not_terminated_with_deadline_exceeded_deadline_numeric_value () -> None :
353424 """Test that numeric deadline value returns None."""
354425 metadata = {"sdk" : {"scheduling" : {"deadline" : 123456789 }}}
355- result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , metadata )
426+ result = is_not_terminated_with_deadline_exceeded (RunState .PENDING , custom_metadata = metadata )
356427 assert result is None
357428
358429
0 commit comments