From 7e3e035146a481ccbc55c5f032d5d800c8cd841e Mon Sep 17 00:00:00 2001 From: Trevor Guidry Date: Tue, 20 Jan 2026 09:42:54 -0600 Subject: [PATCH] SERVER-117088 Increase pymongo timeouts on asan variants (#46306) GitOrigin-RevId: 3400fa6aead18edcdb42185ad2284af6ca0dc94e --- buildscripts/resmokelib/config.py | 5 +++- .../resmokelib/testing/fixtures/interface.py | 9 ++++--- .../testing/hooks/fuzz_runtime_parameters.py | 27 ++++++++++--------- .../resmokelib/testing/hooks/validate.py | 8 +++++- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/buildscripts/resmokelib/config.py b/buildscripts/resmokelib/config.py index ca3438cd68d..c223bf3cdfc 100644 --- a/buildscripts/resmokelib/config.py +++ b/buildscripts/resmokelib/config.py @@ -3,7 +3,7 @@ import collections import datetime import itertools -import os.path +import os import time import buildscripts.resmokelib.setup_multiversion.config as multiversion_config @@ -866,3 +866,6 @@ LOAD_ALL_EXTENSIONS = False # Avoids running hooks as part of the suite. NO_HOOKS = False + +# Whether ASAN (AddressSanitizer) is enabled, determined by the presence of ASAN_OPTIONS. +IS_ASAN = bool(os.environ.get("ASAN_OPTIONS")) diff --git a/buildscripts/resmokelib/testing/fixtures/interface.py b/buildscripts/resmokelib/testing/fixtures/interface.py index a3bc2f09c3b..7ea9d23b7d3 100644 --- a/buildscripts/resmokelib/testing/fixtures/interface.py +++ b/buildscripts/resmokelib/testing/fixtures/interface.py @@ -217,7 +217,7 @@ class Fixture(object, metaclass=registry.make_registry_metaclass(_FIXTURES)): def mongo_client( self, read_preference=pymongo.ReadPreference.PRIMARY, timeout_millis=30000, **kwargs - ): + ) -> pymongo.MongoClient: """Return a pymongo.MongoClient connecting to this fixture with specified 'read_preference'. The PyMongo driver will wait up to 'timeout_millis' milliseconds @@ -524,7 +524,9 @@ def create_fixture_table(fixture): return "Fixture status:\n" + table -def build_client(node, auth_options=None, read_preference=pymongo.ReadPreference.PRIMARY): +def build_client( + node, auth_options=None, read_preference=pymongo.ReadPreference.PRIMARY, **kwargs +) -> pymongo.MongoClient: """Authenticate client for the 'authenticationDatabase' and return the client.""" if auth_options is not None: return node.mongo_client( @@ -533,9 +535,10 @@ def build_client(node, auth_options=None, read_preference=pymongo.ReadPreference authSource=auth_options["authenticationDatabase"], authMechanism=auth_options["authenticationMechanism"], read_preference=read_preference, + **kwargs, ) else: - return node.mongo_client(read_preference=read_preference) + return node.mongo_client(read_preference=read_preference, **kwargs) # Represents a row in a node info table. diff --git a/buildscripts/resmokelib/testing/hooks/fuzz_runtime_parameters.py b/buildscripts/resmokelib/testing/hooks/fuzz_runtime_parameters.py index 8946a4c33da..8dc9c7ce750 100644 --- a/buildscripts/resmokelib/testing/hooks/fuzz_runtime_parameters.py +++ b/buildscripts/resmokelib/testing/hooks/fuzz_runtime_parameters.py @@ -9,7 +9,7 @@ import time from pymongo.errors import OperationFailure -from buildscripts.resmokelib import errors +from buildscripts.resmokelib import config, errors from buildscripts.resmokelib.generate_fuzz_config.mongo_fuzzer_configs import ( generate_normal_mongo_parameters, ) @@ -28,6 +28,13 @@ def validate_runtime_parameter_spec(spec): ) +def build_client(node, auth_options): + """Build a pymongo MongoClient for the given node with the given auth options.""" + if config.IS_ASAN: + return fixture_interface.build_client(node, auth_options, timeout_millis=120000) + return fixture_interface.build_client(node, auth_options) + + class RuntimeParametersState: """Encapsulates the runtime-state of a set of parameters we are fuzzing. Tracks the last time we set a parameter value and holds the logic for generating new values.""" @@ -226,7 +233,7 @@ class FuzzRuntimeParameters(interface.Hook): def _invoke_get_parameter_and_log(self, node): """Helper to print the current state of a node's runtime-fuzzable parameters. Only usable once before_suite has initialized the runtime state of the parameters.""" - client = fixture_interface.build_client(node, self._auth_options) + client = build_client(node, self._auth_options) params_to_get = ( self._mongos_param_state.get_spec() if client.is_mongos @@ -241,7 +248,7 @@ class FuzzRuntimeParameters(interface.Hook): def _invoke_get_cluster_parameter_and_log(self, node): """Helper to print the current state of a cluster's fuzzable cluster parameters. Only usable once before_suite has initialized the runtime state of the parameters.""" - client = fixture_interface.build_client(node, self._auth_options) + client = build_client(node, self._auth_options) params_to_get = self._cluster_param_state.get_keys() get_result = client.admin.command("getClusterParameter", params_to_get) self.logger.info( @@ -404,9 +411,7 @@ class _SetParameterThread(threading.Thread): mongod_params_to_set, ) for node in repl_set.nodes: - invoke_set_parameter( - fixture_interface.build_client(node, self._auth_options), mongod_params_to_set - ) + invoke_set_parameter(build_client(node, self._auth_options), mongod_params_to_set) for standalone in self._standalone_fixtures: self.logger.info( @@ -414,9 +419,7 @@ class _SetParameterThread(threading.Thread): standalone.port, mongod_params_to_set, ) - invoke_set_parameter( - fixture_interface.build_client(standalone, self._auth_options), mongod_params_to_set - ) + invoke_set_parameter(build_client(standalone, self._auth_options), mongod_params_to_set) for mongos in self._mongos_fixtures: self.logger.info( @@ -424,9 +427,7 @@ class _SetParameterThread(threading.Thread): mongos.port, mongos_params_to_set, ) - invoke_set_parameter( - fixture_interface.build_client(mongos, self._auth_options), mongos_params_to_set - ) + invoke_set_parameter(build_client(mongos, self._auth_options), mongos_params_to_set) if self._mongos_fixtures: self.logger.info( @@ -434,6 +435,6 @@ class _SetParameterThread(threading.Thread): cluster_params_to_set, ) invoke_set_cluster_parameter( - fixture_interface.build_client(self._mongos_fixtures[0], self._auth_options), + build_client(self._mongos_fixtures[0], self._auth_options), cluster_params_to_set, ) diff --git a/buildscripts/resmokelib/testing/hooks/validate.py b/buildscripts/resmokelib/testing/hooks/validate.py index 4d3b0d8f562..dcc0237cd52 100644 --- a/buildscripts/resmokelib/testing/hooks/validate.py +++ b/buildscripts/resmokelib/testing/hooks/validate.py @@ -11,6 +11,7 @@ import pymongo.mongo_client from pymongo.collection import Collection from pymongo.database import Database +from buildscripts.resmokelib import config from buildscripts.resmokelib.testing.fixtures.external import ExternalFixture from buildscripts.resmokelib.testing.fixtures.interface import build_client from buildscripts.resmokelib.testing.fixtures.standalone import MongoDFixture @@ -135,7 +136,12 @@ def validate_node( auth_options = None if shell_options and "authenticationMechanism" in shell_options: auth_options = shell_options - client = build_client(node, auth_options, pymongo.ReadPreference.PRIMARY_PREFERRED) + if config.IS_ASAN: + client = build_client( + node, auth_options, pymongo.ReadPreference.PRIMARY_PREFERRED, timeout_millis=120000 + ) + else: + client = build_client(node, auth_options, pymongo.ReadPreference.PRIMARY_PREFERRED) # Skip validating collections for arbiters. admin_db = client.get_database("admin")