This is an automated email from the ASF dual-hosted git repository.

potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new 50227092c79 Fix flaky test_trigger_logger_fd_closed_when_removed on 
slow runners (#68965)
50227092c79 is described below

commit 50227092c79dd6b45e2b34a2eeac337eedfb604a
Author: Jarek Potiuk <[email protected]>
AuthorDate: Thu Jun 25 04:21:00 2026 -0400

    Fix flaky test_trigger_logger_fd_closed_when_removed on slow runners 
(#68965)
    
    The test starts a real 0.5s TimeDeltaTrigger and asserted the log file
    descriptor was closed after a fixed 30 iterations of 
_service_subprocess(0.1).
    Those iterations return as soon as there is subprocess I/O rather than 
after a
    full 0.1s, so the fixed count is not a reliable amount of wall-clock time: 
on a
    slow or loaded runner (e.g. when the triggerer async thread is briefly 
blocked)
    the trigger has not fired and been cleaned up yet, the FD is not closed, 
and the
    assertion fails with "close called 0 times".
    
    Poll until the close happens (bounded) instead of relying on a fixed 
iteration
    count, so the test is deterministic regardless of runner speed.
---
 airflow-core/tests/unit/jobs/test_triggerer_job.py | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/airflow-core/tests/unit/jobs/test_triggerer_job.py 
b/airflow-core/tests/unit/jobs/test_triggerer_job.py
index 9ad31b4e5c2..9eced8f1f80 100644
--- a/airflow-core/tests/unit/jobs/test_triggerer_job.py
+++ b/airflow-core/tests/unit/jobs/test_triggerer_job.py
@@ -1051,8 +1051,15 @@ def test_trigger_logger_fd_closed_when_removed(session):
         trigger_runner_supervisor = 
TriggerRunnerSupervisor.start(job=Job(id=123456), capacity=10)
         trigger_runner_supervisor.load_triggers()
 
-        for _ in range(30):
+        # The 0.5s trigger must fire and its finished-trigger cleanup must run 
before the log FD is
+        # closed. How many service iterations that takes depends on real 
wall-clock timing and runner
+        # speed (_service_subprocess returns as soon as there is I/O, not 
after a full 0.1s), so poll
+        # until the close happens rather than relying on a fixed iteration 
count -- a fixed count is
+        # flaky on slow/loaded runners where the trigger has not fired yet 
within the window.
+        for _ in range(300):
             trigger_runner_supervisor._service_subprocess(0.1)
+            if mock_file.close.called:
+                break
 
     mock_file.close.assert_called_once()
 

Reply via email to