Files
airflow/scripts/tests/ci/testing/test_compute_remaining_test_timeout.py
T
Shahar Epstein dafc96e67c Apply ruff Python 3.11 fixes to dev tooling, scripts and test suites (#74156)
Output of ruff --fix with the py311 target for dev/, scripts/ and the
e2e, integration and kubernetes test suites, followed by ruff format
where the shorter names let calls fit on one line: timezone.utc becomes
datetime.UTC. No behaviour change.

Four modules are left out: dev/registry/extract_metadata.py,
dev/registry/extract_versions.py and the update_airflow_pyproject_toml
and upgrade_dependency_floors prek scripts still fall back to tomli on
Python 3.10, so their UTC fixes land together with the removal of that
fallback in the requires-python bump.
2026-10-06 23:20:49 +02:00

80 lines
2.7 KiB
Python

# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
from __future__ import annotations
import importlib.util
import sys
from datetime import UTC, datetime
from pathlib import Path
import pytest
import time_machine
MODULE_PATH = (
Path(__file__).resolve().parents[4] / "scripts" / "ci" / "testing" / "compute_remaining_test_timeout.py"
)
@pytest.fixture
def timeout_module():
module_name = "test_compute_remaining_test_timeout_module"
sys.modules.pop(module_name, None)
spec = importlib.util.spec_from_file_location(module_name, MODULE_PATH)
module = importlib.util.module_from_spec(spec)
assert spec.loader is not None
sys.modules[module_name] = module
spec.loader.exec_module(module)
return module
@pytest.mark.parametrize(
("job_timeout_seconds", "elapsed_seconds", "expected_seconds"),
[
pytest.param(65 * 60, 8 * 60, 3120, id="image-pull-only"),
pytest.param(65 * 60, 25 * 60, 2100, id="image-pull-and-slow-migration-tests"),
pytest.param(65 * 60, 55 * 60, 600, id="floor-applies-when-budget-nearly-gone"),
pytest.param(65 * 60, 70 * 60, 600, id="floor-applies-when-budget-overrun"),
],
)
def test_compute_remaining_test_timeout(
timeout_module, job_timeout_seconds, elapsed_seconds, expected_seconds
):
assert (
timeout_module.compute_remaining_test_timeout(job_timeout_seconds, elapsed_seconds)
== expected_seconds
)
@time_machine.travel("2026-08-29 12:10:00+00:00", tick=False)
def test_main_derives_the_budget_left_from_the_job_start_time(timeout_module, monkeypatch, capsys):
job_start_epoch = int(datetime(2026, 8, 29, 12, 0, tzinfo=UTC).timestamp())
monkeypatch.setattr(
sys,
"argv",
[
"compute_remaining_test_timeout.py",
"--job-timeout-minutes",
"65",
"--job-start-epoch",
str(job_start_epoch),
],
)
timeout_module.main()
assert int(capsys.readouterr().out) == (65 - 10 - 5) * 60