summaryrefslogtreecommitdiff
path: root/buildscripts/evergreen_task_timeout.py
diff options
context:
space:
mode:
authorLucas de Castro Borges <lucas@gnuabordo.com.br>2025-02-11 15:07:35 -0300
committerLucas de Castro Borges <lucas@gnuabordo.com.br>2025-02-11 15:07:35 -0300
commit4cb8841196d0625dfa3825aa326f071cd27c7b8b (patch)
tree1682a647d4463397c119183369ae6f750d5fdcff /buildscripts/evergreen_task_timeout.py
parentaa03c6362cbaa767638e6eed9b031d86dd2643d1 (diff)
parent8f0827553e09872941945a093b647a4211a9db7f (diff)
Update upstream source from tag 'upstream/6.0.0'master
Update to upstream version '6.0.0' with Debian dir 5604a80ec1c96ca76f25f40d78e6ef855abec322
Diffstat (limited to 'buildscripts/evergreen_task_timeout.py')
-rwxr-xr-xbuildscripts/evergreen_task_timeout.py73
1 files changed, 37 insertions, 36 deletions
diff --git a/buildscripts/evergreen_task_timeout.py b/buildscripts/evergreen_task_timeout.py
index 7bee3a8e57b..5c0eabf7aef 100755
--- a/buildscripts/evergreen_task_timeout.py
+++ b/buildscripts/evergreen_task_timeout.py
@@ -7,7 +7,7 @@ import math
import os
import shlex
import sys
-from datetime import timedelta
+from datetime import datetime, timedelta
from pathlib import Path
from typing import Dict, List, Optional
@@ -19,7 +19,7 @@ from evergreen import EvergreenApi, RetryingEvergreenApi
from buildscripts.ciconfig.evergreen import (EvergreenProjectConfig, parse_evergreen_file)
from buildscripts.task_generation.resmoke_proxy import ResmokeProxyService
-from buildscripts.timeouts.timeout_service import (TimeoutParams, TimeoutService)
+from buildscripts.timeouts.timeout_service import (TimeoutParams, TimeoutService, TimeoutSettings)
from buildscripts.util.cmdutils import enable_logging
from buildscripts.util.taskname import determine_task_base_name
@@ -28,21 +28,20 @@ DEFAULT_TIMEOUT_OVERRIDES = "etc/evergreen_timeouts.yml"
DEFAULT_EVERGREEN_CONFIG = "etc/evergreen.yml"
DEFAULT_EVERGREEN_AUTH_CONFIG = "~/.evergreen.yml"
COMMIT_QUEUE_ALIAS = "__commit_queue"
+UNITTEST_TASK = "run_unittests"
IGNORED_SUITES = {
- "integration_tests_replset",
- "integration_tests_replset_ssl_auth",
- "integration_tests_sharded",
- "integration_tests_standalone",
- "integration_tests_standalone_audit",
- "mongos_test",
- "server_selection_json_test",
- "sdam_json_test",
+ "integration_tests_replset", "integration_tests_replset_ssl_auth", "integration_tests_sharded",
+ "integration_tests_standalone", "integration_tests_standalone_audit", "mongos_test",
+ "server_selection_json_test"
}
HISTORY_LOOKBACK = timedelta(weeks=2)
-COMMIT_QUEUE_TIMEOUT = timedelta(minutes=20)
+COMMIT_QUEUE_TIMEOUT = timedelta(minutes=40)
DEFAULT_REQUIRED_BUILD_TIMEOUT = timedelta(hours=1, minutes=20)
DEFAULT_NON_REQUIRED_BUILD_TIMEOUT = timedelta(hours=2)
+# 2x the longest "run tests" phase for unittests as of c9bf1dbc9cc46e497b2f12b2d6685ef7348b0726,
+# which is 5 mins 47 secs, excluding outliers below
+UNITTESTS_TIMEOUT = timedelta(minutes=12)
class TimeoutOverride(BaseModel):
@@ -144,6 +143,16 @@ class TimeoutOverrides(BaseModel):
return None
+def _is_required_build_variant(build_variant: str) -> bool:
+ """
+ Determine if the given build variants is a required build variant.
+
+ :param build_variant: Name of build variant to check.
+ :return: True if the given build variant is required.
+ """
+ return build_variant.endswith("-required")
+
+
def output_timeout(exec_timeout: timedelta, idle_timeout: Optional[timedelta],
output_file: Optional[str]) -> None:
"""
@@ -213,7 +222,12 @@ class TaskTimeoutOrchestrator:
LOGGER.info("Overriding configured timeout", exec_timeout_secs=override.total_seconds())
determined_timeout = override
- elif self._is_required_build_variant(
+ elif task_name == UNITTEST_TASK and override is None:
+ LOGGER.info("Overriding unittest timeout",
+ exec_timeout_secs=UNITTESTS_TIMEOUT.total_seconds())
+ determined_timeout = UNITTESTS_TIMEOUT
+
+ elif _is_required_build_variant(
variant) and determined_timeout > DEFAULT_REQUIRED_BUILD_TIMEOUT:
LOGGER.info("Overriding required-builder timeout",
exec_timeout_secs=DEFAULT_REQUIRED_BUILD_TIMEOUT.total_seconds())
@@ -259,12 +273,11 @@ class TaskTimeoutOrchestrator:
return determined_timeout
- def determine_historic_timeout(self, project: str, task: str, variant: str, suite_name: str,
+ def determine_historic_timeout(self, task: str, variant: str, suite_name: str,
exec_timeout_factor: Optional[float]) -> TimeoutOverride:
"""
Calculate the timeout based on historic test results.
- :param project: Name of project to query.
:param task: Name of task to query.
:param variant: Name of build variant to query.
:param suite_name: Name of test suite being run.
@@ -274,7 +287,7 @@ class TaskTimeoutOrchestrator:
return TimeoutOverride(task=task, exec_timeout=None, idle_timeout=None)
timeout_params = TimeoutParams(
- evg_project=project,
+ evg_project="mongodb-mongo-master",
build_variant=variant,
task_name=task,
suite_name=suite_name,
@@ -301,20 +314,9 @@ class TaskTimeoutOrchestrator:
bv = self.evg_project_config.get_variant(build_variant)
return bv.is_asan_build()
- def _is_required_build_variant(self, build_variant: str) -> bool:
- """
- Determine if the given build variants is a required build variant.
-
- :param build_variant: Name of build variant to check.
- :param evergreen_project_config: Evergreen config to query the variant name.
- :return: True if the given build variant is required.
- """
- bv = self.evg_project_config.get_variant(build_variant)
- return "!" in bv.display_name
-
def determine_timeouts(self, cli_idle_timeout: Optional[timedelta],
- cli_exec_timeout: Optional[timedelta], outfile: Optional[str],
- project: str, task: str, variant: str, evg_alias: str, suite_name: str,
+ cli_exec_timeout: Optional[timedelta], outfile: Optional[str], task: str,
+ variant: str, evg_alias: str, suite_name: str,
exec_timeout_factor: Optional[float]) -> None:
"""
Determine the timeouts to use for the given task and write timeouts to expansion file.
@@ -322,14 +324,12 @@ class TaskTimeoutOrchestrator:
:param cli_idle_timeout: Idle timeout specified by the CLI.
:param cli_exec_timeout: Exec timeout specified by the CLI.
:param outfile: File to write timeout expansions to.
- :param project: Evergreen project task is being run on.
- :param task: Name of task.
:param variant: Build variant task is being run on.
:param evg_alias: Evergreen alias that triggered task.
:param suite_name: Name of evergreen suite being run.
:param exec_timeout_factor: Scaling factor to use when determining timeout.
"""
- historic_timeout = self.determine_historic_timeout(project, task, variant, suite_name,
+ historic_timeout = self.determine_historic_timeout(task, variant, suite_name,
exec_timeout_factor)
idle_timeout = self.determine_idle_timeout(task, variant, cli_idle_timeout,
@@ -351,8 +351,6 @@ def main():
help="Resmoke suite being run against.")
parser.add_argument("--build-variant", dest="variant", required=True,
help="Build variant task is being executed on.")
- parser.add_argument("--project", dest="project", required=True,
- help="Evergreen project task is being executed on.")
parser.add_argument("--evg-alias", dest="evg_alias", required=True,
help="Evergreen alias used to trigger build.")
parser.add_argument("--timeout", dest="timeout", type=int, help="Timeout to use (in sec).")
@@ -371,6 +369,9 @@ def main():
options = parser.parse_args()
+ end_date = datetime.now()
+ start_date = end_date - HISTORY_LOOKBACK
+
timeout_override = timedelta(seconds=options.timeout) if options.timeout else None
exec_timeout_override = timedelta(
seconds=options.exec_timeout) if options.exec_timeout else None
@@ -380,12 +381,12 @@ def main():
os.path.expanduser(options.timeout_overrides_file))
enable_logging(verbose=False)
- LOGGER.info("Determining timeouts", cli_args=options)
def dependencies(binder: inject.Binder) -> None:
binder.bind(
EvergreenApi,
RetryingEvergreenApi.get_api(config_file=os.path.expanduser(options.evg_api_config)))
+ binder.bind(TimeoutSettings, TimeoutSettings(start_date=start_date, end_date=end_date))
binder.bind(TimeoutOverrides, timeout_overrides)
binder.bind(EvergreenProjectConfig,
parse_evergreen_file(os.path.expanduser(options.evg_project_config)))
@@ -397,8 +398,8 @@ def main():
task_timeout_orchestrator = inject.instance(TaskTimeoutOrchestrator)
task_timeout_orchestrator.determine_timeouts(
- timeout_override, exec_timeout_override, options.outfile, options.project, task_name,
- options.variant, options.evg_alias, options.suite_name, options.exec_timeout_factor)
+ timeout_override, exec_timeout_override, options.outfile, task_name, options.variant,
+ options.evg_alias, options.suite_name, options.exec_timeout_factor)
if __name__ == "__main__":