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()