2021-03-03 14:10:37 -05:00
""" Utility functions for creating MongoDB processes.
2015-05-08 14:20:43 -04:00
Handles all the nitty - gritty parameter conversion .
"""
import json
import os
import os . path
2023-04-06 14:41:32 +00:00
import re
2015-05-08 14:20:43 -04:00
import stat
2024-10-10 10:59:18 -07:00
from typing import Any , Optional , Tuple
2025-10-23 12:19:39 -04:00
from opentelemetry import trace
from opentelemetry . trace . propagation . tracecontext import TraceContextTextMapPropagator
2024-10-10 10:59:18 -07:00
from packaging import version
2015-05-08 14:20:43 -04:00
2024-05-14 11:07:04 -07:00
from buildscripts . resmokelib import config , logging , utils
2024-10-10 10:59:18 -07:00
from buildscripts . resmokelib . core import network , process
from buildscripts . resmokelib . testing . fixtures import shardedcluster , standalone
2021-03-26 14:12:05 -04:00
from buildscripts . resmokelib . testing . fixtures . fixturelib import FixtureLib
2024-10-10 10:59:18 -07:00
from buildscripts . resmokelib . utils . history import HistoryDict , make_historic
2019-03-22 11:36:22 -04:00
2018-07-09 19:32:06 -04:00
2024-05-13 09:26:21 -07:00
def make_process ( * args , * * kwargs ) - > process . Process :
2022-04-24 01:18:07 +00:00
""" Set up the environment for subprocesses. """
2018-11-01 11:53:08 -04:00
process_cls = process . Process
2019-12-17 14:40:28 -05:00
2019-08-15 13:59:28 +00:00
# Add the current working directory and /data/multiversion to the PATH.
2019-11-05 16:31:58 +00:00
env_vars = kwargs . get ( " env_vars " , { } ) . copy ( )
2021-07-29 12:53:14 -04:00
path = get_path_env_var ( env_vars )
if config . INSTALL_DIR is not None :
env_vars [ " INSTALL_DIR " ] = config . INSTALL_DIR
env_vars [ " PATH " ] = os . pathsep . join ( path )
kwargs [ " env_vars " ] = env_vars
return process_cls ( * args , * * kwargs )
def get_path_env_var ( env_vars ) :
""" Return the path base on provided environment variable. """
2025-05-06 17:11:09 -04:00
path = [ os . getcwd ( ) ] + config . MULTIVERSION_DIRS
2019-12-17 14:40:28 -05:00
# If installDir is provided, add it early to the path
if config . INSTALL_DIR is not None :
path . append ( config . INSTALL_DIR )
path . append ( env_vars . get ( " PATH " , os . environ . get ( " PATH " , " " ) ) )
2021-07-29 12:53:14 -04:00
return path
2018-11-01 11:53:08 -04:00
2023-04-06 14:41:32 +00:00
def get_binary_version ( executable ) :
""" Return the string for the binary version of the given executable. """
from buildscripts . resmokelib . multiversionconstants import LATEST_FCV
2024-08-08 11:18:36 -04:00
split_executable = os . path . basename ( executable ) . split ( " - " )
2023-04-06 14:41:32 +00:00
version_regex = re . compile ( version . VERSION_PATTERN , re . VERBOSE | re . IGNORECASE )
if len ( split_executable ) > 1 and version_regex . match ( split_executable [ - 1 ] ) :
return split_executable [ - 1 ]
return LATEST_FCV
2024-05-16 18:00:17 -04:00
def remove_set_parameter_if_before_version (
set_parameters , parameter_name , bin_version , required_bin_version
) :
2023-04-06 14:41:32 +00:00
"""
Used for removing a server parameter that does not exist prior to a specified version .
Remove ' parameter_name ' from the ' set_parameters ' dictionary if ' bin_version ' is older than
' required_bin_version ' .
"""
if version . parse ( bin_version ) < version . parse ( required_bin_version ) :
set_parameters . pop ( parameter_name , None )
2025-10-30 13:57:08 -04:00
def _should_enable_otel ( test_data , bin_version ) :
""" Check whether OpenTelemetry is supported on the current platform. """
2025-10-31 14:46:59 -04:00
return test_data . get ( " enableOTELTracing " , True ) and version . parse ( bin_version ) > = version . parse (
" 8.3.0 "
2025-10-30 13:57:08 -04:00
)
2024-05-16 18:00:17 -04:00
def mongod_program (
logger : logging . Logger ,
job_num : int ,
executable : str ,
process_kwargs : dict ,
mongod_options : HistoryDict ,
) - > tuple [ process . Process , HistoryDict ] :
2021-03-01 22:58:17 -05:00
"""
Return a Process instance that starts mongod arguments constructed from ' mongod_options ' .
@param logger - The logger to pass into the process .
2022-04-24 01:18:07 +00:00
@param job_num - The Resmoke job number running this process .
2021-03-01 22:58:17 -05:00
@param executable - The mongod executable to run .
@param process_kwargs - A dict of key - value pairs to pass to the process .
@param mongod_options - A HistoryDict describing the various options to pass to the mongod .
"""
2015-05-08 14:20:43 -04:00
2023-04-06 14:41:32 +00:00
bin_version = get_binary_version ( executable )
2015-05-08 14:20:43 -04:00
args = [ executable ]
2021-03-26 14:12:05 -04:00
mongod_options = mongod_options . copy ( )
2015-05-08 14:20:43 -04:00
2023-09-19 16:43:05 +00:00
if config . NOOP_MONGO_D_S_PROCESSES :
2023-09-06 03:01:32 +00:00
args [ 0 ] = os . path . basename ( args [ 0 ] )
mongod_options [ " set_parameters " ] [ " fassertOnLockTimeoutForStepUpDown " ] = 0
mongod_options [ " set_parameters " ] . pop ( " backtraceLogFile " , None )
2024-05-16 18:00:17 -04:00
mongod_options . update (
{
" logpath " : " /var/log/mongodb/mongodb.log " ,
" dbpath " : " /data/db " ,
" bind_ip " : " 0.0.0.0 " ,
" oplogSize " : " 256 " ,
" wiredTigerCacheSizeGB " : " 1 " ,
}
)
2023-09-06 03:01:32 +00:00
2024-01-11 20:49:28 +00:00
if config . TLS_MODE :
mongod_options [ " tlsMode " ] = config . TLS_MODE
if config . TLS_MODE != " disabled " :
# Note: "tlsAllowInvalidCertificates" is enabled to avoid
# hostname conflicts with our testing certificates.
# The ssl and ssl_special suites handle hostname validation testing.
mongod_options [ " tlsAllowInvalidHostnames " ] = " "
if config . MONGOD_TLS_CERTIFICATE_KEY_FILE :
mongod_options [ " tlsCertificateKeyFile " ] = config . MONGOD_TLS_CERTIFICATE_KEY_FILE
if config . TLS_CA_FILE :
mongod_options [ " tlsCAFile " ] = config . TLS_CA_FILE
2021-03-26 14:12:05 -04:00
if " port " not in mongod_options :
mongod_options [ " port " ] = network . PortAllocator . next_fixture_port ( job_num )
2023-04-06 14:41:32 +00:00
2021-05-12 09:59:33 -04:00
suite_set_parameters = mongod_options . get ( " set_parameters " , { } )
2025-10-30 13:57:08 -04:00
if config . OTEL_COLLECTOR_DIR and _should_enable_otel ( mongod_options , bin_version ) :
suite_set_parameters [ " opentelemetryTraceDirectory " ] = config . OTEL_COLLECTOR_DIR
2023-04-06 14:41:32 +00:00
remove_set_parameter_if_before_version (
2024-05-16 18:00:17 -04:00
suite_set_parameters , " queryAnalysisSamplerConfigurationRefreshSecs " , bin_version , " 7.0.0 "
)
remove_set_parameter_if_before_version (
suite_set_parameters , " queryAnalysisWriterIntervalSecs " , bin_version , " 7.0.0 "
)
remove_set_parameter_if_before_version (
suite_set_parameters , " defaultConfigCommandTimeoutMS " , bin_version , " 7.3.0 "
)
2024-01-18 13:38:02 -05:00
2024-01-03 14:18:51 -06:00
remove_set_parameter_if_before_version (
2024-05-16 18:00:17 -04:00
suite_set_parameters , " internalQueryStatsRateLimit " , bin_version , " 7.3.0 "
)
remove_set_parameter_if_before_version (
suite_set_parameters , " internalQueryStatsErrorsAreCommandFatal " , bin_version , " 7.3.0 "
)
remove_set_parameter_if_before_version (
suite_set_parameters , " enableAutoCompaction " , bin_version , " 7.3.0 "
)
2025-09-10 11:07:12 +01:00
remove_set_parameter_if_before_version (
2025-09-12 16:44:21 +01:00
suite_set_parameters , " findShardsOnConfigTimeoutMS " , bin_version , " 8.3.0 "
2025-09-10 11:07:12 +01:00
)
2024-01-11 20:49:28 +00:00
if " grpcPort " not in mongod_options and suite_set_parameters . get ( " featureFlagGRPC " ) :
mongod_options [ " grpcPort " ] = network . PortAllocator . next_fixture_port ( job_num )
2015-07-15 15:38:13 -04:00
_apply_set_parameters ( args , suite_set_parameters )
2023-07-28 13:45:04 +00:00
final_mongod_options = mongod_options . copy ( )
2021-03-01 22:58:17 -05:00
mongod_options . pop ( " set_parameters " )
2015-07-29 17:24:35 -04:00
2015-05-08 14:20:43 -04:00
# Apply the rest of the command line arguments.
2021-03-01 22:58:17 -05:00
_apply_kwargs ( args , mongod_options )
2015-05-08 14:20:43 -04:00
2021-03-01 22:58:17 -05:00
_set_keyfile_permissions ( mongod_options )
2015-05-08 14:20:43 -04:00
2021-03-01 22:58:17 -05:00
process_kwargs = make_historic ( utils . default_if_none ( process_kwargs , { } ) )
if config . EXPORT_MONGOD_CONFIG == " regular " :
mongod_options . dump_history ( f " { logger . name } _config.yml " )
elif config . EXPORT_MONGOD_CONFIG == " detailed " :
mongod_options . dump_history ( f " { logger . name } _config.yml " , include_location = True )
2023-07-28 13:45:04 +00:00
return make_process ( logger , args , * * process_kwargs ) , final_mongod_options
2015-05-08 14:20:43 -04:00
2025-03-08 16:03:58 -05:00
def mongos_program (
logger : logging . Logger ,
job_num : int ,
executable : Optional [ str ] = None ,
process_kwargs : Optional [ dict ] = None ,
mongos_options : dict = None ,
) - > Tuple [ process . Process , dict ] :
2018-03-27 14:30:46 -04:00
""" Return a Process instance that starts a mongos with arguments constructed from ' kwargs ' . """
2023-04-06 14:41:32 +00:00
bin_version = get_binary_version ( executable )
2015-05-08 14:20:43 -04:00
args = [ executable ]
2021-03-26 14:12:05 -04:00
mongos_options = mongos_options . copy ( )
2025-03-08 16:03:58 -05:00
mongos_options . setdefault ( " set_parameters " , { } )
2021-03-26 14:12:05 -04:00
2023-09-19 16:43:05 +00:00
if config . NOOP_MONGO_D_S_PROCESSES :
2023-09-06 03:01:32 +00:00
args [ 0 ] = os . path . basename ( args [ 0 ] )
mongos_options [ " set_parameters " ] [ " fassertOnLockTimeoutForStepUpDown " ] = 0
mongos_options . update ( { " logpath " : " /var/log/mongodb/mongodb.log " , " bind_ip " : " 0.0.0.0 " } )
2024-01-11 20:49:28 +00:00
if config . TLS_MODE :
mongos_options [ " tlsMode " ] = config . TLS_MODE
if config . TLS_MODE != " disabled " :
mongos_options [ " tlsAllowInvalidHostnames " ] = " "
if config . MONGOS_TLS_CERTIFICATE_KEY_FILE :
mongos_options [ " tlsCertificateKeyFile " ] = config . MONGOS_TLS_CERTIFICATE_KEY_FILE
if config . TLS_CA_FILE :
mongos_options [ " tlsCAFile " ] = config . TLS_CA_FILE
2021-03-26 14:12:05 -04:00
if " port " not in mongos_options :
mongos_options [ " port " ] = network . PortAllocator . next_fixture_port ( job_num )
2023-04-06 14:41:32 +00:00
2021-03-26 14:12:05 -04:00
suite_set_parameters = mongos_options . get ( " set_parameters " , { } )
2025-10-30 13:57:08 -04:00
if config . OTEL_COLLECTOR_DIR and _should_enable_otel ( mongos_options , bin_version ) :
suite_set_parameters [ " opentelemetryTraceDirectory " ] = config . OTEL_COLLECTOR_DIR
2023-04-06 14:41:32 +00:00
remove_set_parameter_if_before_version (
2024-05-16 18:00:17 -04:00
suite_set_parameters , " queryAnalysisSamplerConfigurationRefreshSecs " , bin_version , " 7.0.0 "
)
remove_set_parameter_if_before_version (
suite_set_parameters , " defaultConfigCommandTimeoutMS " , bin_version , " 7.3.0 "
)
2024-01-18 13:38:02 -05:00
2024-01-03 14:18:51 -06:00
remove_set_parameter_if_before_version (
2024-05-16 18:00:17 -04:00
suite_set_parameters , " internalQueryStatsRateLimit " , bin_version , " 7.3.0 "
)
remove_set_parameter_if_before_version (
suite_set_parameters , " internalQueryStatsErrorsAreCommandFatal " , bin_version , " 7.3.0 "
)
2025-09-10 11:07:12 +01:00
remove_set_parameter_if_before_version (
2025-09-12 16:44:21 +01:00
suite_set_parameters , " findShardsOnConfigTimeoutMS " , bin_version , " 8.3.0 "
2025-09-10 11:07:12 +01:00
)
2025-09-09 19:20:08 +02:00
remove_set_parameter_if_before_version (
suite_set_parameters , " maxRoundsWithoutProgressParameter " , bin_version , " 8.2.0 "
)
2024-01-11 20:49:28 +00:00
if " grpcPort " not in mongos_options and suite_set_parameters . get ( " featureFlagGRPC " ) :
mongos_options [ " grpcPort " ] = network . PortAllocator . next_fixture_port ( job_num )
2015-07-15 15:38:13 -04:00
_apply_set_parameters ( args , suite_set_parameters )
2023-07-28 13:45:04 +00:00
final_mongos_options = mongos_options . copy ( )
2021-03-26 14:12:05 -04:00
mongos_options . pop ( " set_parameters " )
2015-05-08 14:20:43 -04:00
# Apply the rest of the command line arguments.
2021-03-26 14:12:05 -04:00
_apply_kwargs ( args , mongos_options )
2015-05-08 14:20:43 -04:00
2021-03-26 14:12:05 -04:00
_set_keyfile_permissions ( mongos_options )
2015-05-08 14:20:43 -04:00
2021-03-01 22:58:17 -05:00
process_kwargs = make_historic ( utils . default_if_none ( process_kwargs , { } ) )
2023-07-28 13:45:04 +00:00
return make_process ( logger , args , * * process_kwargs ) , final_mongos_options
2015-05-08 14:20:43 -04:00
2024-05-16 18:00:17 -04:00
def mongot_program (
logger , job_num , executable = None , process_kwargs = None , mongot_options = None
) - > Tuple [ process . Process , Any ] :
2024-02-23 16:34:11 +00:00
""" Return a Process instance that starts a mongot. """
args = [ executable ]
mongot_options = mongot_options . copy ( )
final_mongot_options = mongot_options . copy ( )
# Apply the rest of the command line arguments.
_apply_kwargs ( args , mongot_options )
process_kwargs = make_historic ( utils . default_if_none ( process_kwargs , { } ) )
return make_process ( logger , args , * * process_kwargs ) , final_mongot_options
2024-05-16 18:00:17 -04:00
def mongo_shell_program (
logger : logging . Logger ,
test_name : str ,
executable : Optional [ str ] = None ,
connection_string : Optional [ str ] = None ,
filenames : Optional [ list [ str ] ] = None ,
process_kwargs : Optional [ dict ] = None ,
* * kwargs ,
) - > process . Process :
2018-03-27 14:30:46 -04:00
""" Return a Process instance that starts a mongo shell.
2024-05-14 11:07:04 -07:00
Args :
logger ( logging . Logger ) : logger
test_name ( str ) : Name of the test . Passed into the test as ' testName ' .
executable ( Optional [ str ] , optional ) : Path to the mongo shell binary . Defaults to None . If not given will be inferred .
connection_string ( Optional [ str ] , optional ) : Connection string to mongodb . Defaults to None . If not given will be inferred .
filenames ( Optional [ list [ str ] ] , optional ) : The files to run by the mongo shell in a single invocation . Defaults to None .
process_kwargs ( Optional [ dict ] , optional ) : Extra args to pass into make_process . Defaults to None .
2021-05-20 12:07:51 -04:00
2024-05-14 11:07:04 -07:00
Returns
process . Process : The mongo shell invocation .
2015-05-08 14:20:43 -04:00
"""
2018-10-08 17:32:36 -04:00
executable = utils . default_if_none (
2024-05-16 18:00:17 -04:00
utils . default_if_none ( executable , config . MONGO_EXECUTABLE ) , config . DEFAULT_MONGO_EXECUTABLE
)
2015-05-08 14:20:43 -04:00
args = [ executable ]
2025-10-30 13:57:08 -04:00
bin_version = get_binary_version ( executable )
2015-05-11 10:12:09 -04:00
eval_sb = [ ] # String builder.
2015-07-30 15:48:52 -04:00
global_vars = kwargs . pop ( " global_vars " , { } ) . copy ( )
2015-05-08 14:20:43 -04:00
2021-11-02 23:39:47 -04:00
# the Shell fixtures uses hyphen-delimited versions (e.g. last-lts) while resmoke.py
# uses underscore (e.g. last_lts). resmoke's version is needed as it's part of the task name.
shell_mixed_version = ( config . MULTIVERSION_BIN_VERSION or " " ) . replace ( " _ " , " - " )
2015-05-08 14:20:43 -04:00
shortcut_opts = {
2020-06-16 13:47:22 -04:00
" backupOnRestartDir " : ( config . BACKUP_ON_RESTART_DIR , None ) ,
2019-09-09 14:09:29 +00:00
" mixedBinVersions " : ( config . MIXED_BIN_VERSIONS , " " ) ,
2021-11-02 23:39:47 -04:00
" multiversionBinVersion " : ( shell_mixed_version , " " ) ,
2015-05-08 14:20:43 -04:00
" storageEngine " : ( config . STORAGE_ENGINE , " " ) ,
2016-06-10 17:21:19 -04:00
" storageEngineCacheSizeGB " : ( config . STORAGE_ENGINE_CACHE_SIZE , " " ) ,
2025-06-12 15:32:49 +10:00
" storageEngineCacheSizePct " : ( config . STORAGE_ENGINE_CACHE_SIZE_PCT , " " ) ,
2018-10-08 17:32:36 -04:00
" testName " : ( test_name , " " ) ,
2015-05-08 14:20:43 -04:00
" wiredTigerCollectionConfigString " : ( config . WT_COLL_CONFIG , " " ) ,
" wiredTigerEngineConfigString " : ( config . WT_ENGINE_CONFIG , " " ) ,
" wiredTigerIndexConfigString " : ( config . WT_INDEX_CONFIG , " " ) ,
2025-06-24 21:02:28 +03:00
" pauseAfterPopulate " : ( config . PAUSE_AFTER_POPULATE , None ) ,
2015-05-08 14:20:43 -04:00
}
test_data = global_vars . get ( " TestData " , { } ) . copy ( )
for opt_name in shortcut_opts :
( opt_value , opt_default ) = shortcut_opts [ opt_name ]
if opt_value is not None :
test_data [ opt_name ] = opt_value
elif opt_name not in test_data :
# Only use 'opt_default' if the property wasn't set in the YAML configuration.
test_data [ opt_name ] = opt_default
2016-06-08 17:07:59 -04:00
2024-08-13 15:41:18 -05:00
if config . CONFIG_FUZZER_ENCRYPTION_OPTS :
for opt_name in config . CONFIG_FUZZER_ENCRYPTION_OPTS :
if opt_name in test_data :
continue
test_data [ opt_name ] = config . CONFIG_FUZZER_ENCRYPTION_OPTS [ opt_name ]
2025-01-30 13:12:34 +01:00
if config . LOG_FORMAT :
test_data [ " logFormat " ] = config . LOG_FORMAT
2025-02-04 15:08:28 +00:00
level_names_to_numbers = { " ERROR " : 1 , " WARNING " : 2 , " INFO " : 3 , " DEBUG " : 4 }
# Convert Log Level from string to numbered values. Defaults to using "INFO".
test_data [ " logLevel " ] = level_names_to_numbers . get ( config . LOG_LEVEL , 3 )
2024-01-11 20:49:28 +00:00
if config . SHELL_TLS_ENABLED :
test_data [ " shellTlsEnabled " ] = True
if config . SHELL_TLS_CERTIFICATE_KEY_FILE :
test_data [ " shellTlsCertificateKeyFile " ] = config . SHELL_TLS_CERTIFICATE_KEY_FILE
2024-01-18 13:38:02 -05:00
if config . SHELL_GRPC :
test_data [ " shellGRPC " ] = True
2024-01-11 20:49:28 +00:00
if config . TLS_CA_FILE :
test_data [ " tlsCAFile " ] = config . TLS_CA_FILE
if config . TLS_MODE :
test_data [ " tlsMode " ] = config . TLS_MODE
if config . MONGOD_TLS_CERTIFICATE_KEY_FILE :
test_data [ " mongodTlsCertificateKeyFile " ] = config . MONGOD_TLS_CERTIFICATE_KEY_FILE
if config . MONGOS_TLS_CERTIFICATE_KEY_FILE :
test_data [ " mongosTlsCertificateKeyFile " ] = config . MONGOS_TLS_CERTIFICATE_KEY_FILE
2025-10-30 13:57:08 -04:00
if config . OTEL_COLLECTOR_DIR and _should_enable_otel ( test_data , bin_version ) :
test_data [ " otelTraceDirectory " ] = config . OTEL_COLLECTOR_DIR
2015-05-08 14:20:43 -04:00
global_vars [ " TestData " ] = test_data
2025-10-23 12:19:39 -04:00
if test_data . get ( " enableOTELTracing " , True ) and " traceCtx " not in test_data :
current_span = trace . get_current_span ( )
if current_span :
otelCtx = { }
TraceContextTextMapPropagator ( ) . inject ( otelCtx )
test_data [ " traceCtx " ] = otelCtx
logger . debug ( " Mongo Shell: Using trace context %s " , otelCtx . get ( " traceparent " ) )
2020-02-13 11:18:03 +03:00
if config . EVERGREEN_TASK_ID is not None :
test_data [ " inEvergreen " ] = True
2021-08-05 02:05:50 +00:00
test_data [ " evergreenTaskId " ] = config . EVERGREEN_TASK_ID
2024-09-12 16:25:11 -04:00
test_data [ " evergreenVariantName " ] = config . EVERGREEN_VARIANT_NAME
2020-02-13 11:18:03 +03:00
2023-04-10 21:09:20 +00:00
if config . SHELL_SEED is not None :
test_data [ " seed " ] = int ( config . SHELL_SEED )
2018-07-06 14:54:38 -04:00
# Initialize setParameters for mongod and mongos, to be passed to the shell via TestData. Since
# they are dictionaries, they will be converted to JavaScript objects when passed to the shell
# by the _format_shell_vars() function.
2019-03-28 12:53:13 -04:00
mongod_set_parameters = test_data . get ( " setParameters " , { } ) . copy ( )
mongos_set_parameters = test_data . get ( " setParametersMongos " , { } ) . copy ( )
2020-12-09 20:18:45 +00:00
mongocryptd_set_parameters = test_data . get ( " setParametersMongocryptd " , { } ) . copy ( )
2025-04-15 12:30:26 -04:00
mongo_set_parameters = test_data . get ( " setParametersMongo " , { } ) . copy ( )
2019-03-28 12:53:13 -04:00
2021-11-02 23:39:47 -04:00
feature_flag_dict = { }
if config . ENABLED_FEATURE_FLAGS is not None :
feature_flag_dict = { ff : " true " for ff in config . ENABLED_FEATURE_FLAGS }
2025-05-29 16:12:10 -04:00
if config . DISABLED_FEATURE_FLAGS is not None :
feature_flag_dict | = { ff : " false " for ff in config . DISABLED_FEATURE_FLAGS }
2019-03-28 12:53:13 -04:00
# Propagate additional setParameters to mongod processes spawned by the mongo shell. Command
# line options to resmoke.py override the YAML configuration.
2015-07-30 15:48:52 -04:00
if config . MONGOD_SET_PARAMETERS is not None :
2019-03-28 12:53:13 -04:00
mongod_set_parameters . update ( utils . load_yaml ( config . MONGOD_SET_PARAMETERS ) )
2021-11-02 23:39:47 -04:00
mongod_set_parameters . update ( feature_flag_dict )
2019-03-28 12:53:13 -04:00
# Propagate additional setParameters to mongos processes spawned by the mongo shell. Command
# line options to resmoke.py override the YAML configuration.
if config . MONGOS_SET_PARAMETERS is not None :
mongos_set_parameters . update ( utils . load_yaml ( config . MONGOS_SET_PARAMETERS ) )
2021-11-02 23:39:47 -04:00
mongos_set_parameters . update ( feature_flag_dict )
2018-07-06 14:54:38 -04:00
2020-12-09 20:18:45 +00:00
# Propagate additional setParameters to mongocryptd processes spawned by the mongo shell.
# Command line options to resmoke.py override the YAML configuration.
if config . MONGOCRYPTD_SET_PARAMETERS is not None :
mongocryptd_set_parameters . update ( utils . load_yaml ( config . MONGOCRYPTD_SET_PARAMETERS ) )
2022-03-02 20:54:50 +00:00
mongocryptd_set_parameters . update ( feature_flag_dict )
2020-12-09 20:18:45 +00:00
2025-04-15 12:30:26 -04:00
if config . MONGO_SET_PARAMETERS is not None :
mongo_set_parameters . update ( utils . load_yaml ( config . MONGO_SET_PARAMETERS ) )
2021-03-26 14:12:05 -04:00
fixturelib = FixtureLib ( )
mongod_launcher = standalone . MongodLauncher ( fixturelib )
2018-07-06 14:54:38 -04:00
# If the 'logComponentVerbosity' setParameter for mongod was not already specified, we set its
# value to a default.
2021-07-22 07:35:13 -04:00
mongod_set_parameters . setdefault (
2024-05-16 18:00:17 -04:00
" logComponentVerbosity " , mongod_launcher . get_default_log_component_verbosity_for_mongod ( )
)
2018-07-06 14:54:38 -04:00
2021-03-26 14:12:05 -04:00
mongos_launcher = shardedcluster . MongosLauncher ( fixturelib )
2019-03-22 11:36:22 -04:00
# If the 'logComponentVerbosity' setParameter for mongos was not already specified, we set its
# value to a default.
2024-05-16 18:00:17 -04:00
mongos_set_parameters . setdefault (
" logComponentVerbosity " , mongos_launcher . default_mongos_log_component_verbosity ( )
)
2019-03-22 11:36:22 -04:00
2018-07-06 14:54:38 -04:00
test_data [ " setParameters " ] = mongod_set_parameters
2019-03-28 12:53:13 -04:00
test_data [ " setParametersMongos " ] = mongos_set_parameters
2020-12-09 20:18:45 +00:00
test_data [ " setParametersMongocryptd " ] = mongocryptd_set_parameters
2025-04-15 12:30:26 -04:00
test_data [ " setShellParameters " ] = mongo_set_parameters
2015-07-30 15:48:52 -04:00
2023-04-17 22:11:41 +00:00
if " configShard " not in test_data and config . CONFIG_SHARD is not None :
test_data [ " configShard " ] = True
2023-01-05 20:59:59 +00:00
2018-05-25 11:37:57 -04:00
# There's a periodic background thread that checks for and aborts expired transactions.
# "transactionLifetimeLimitSeconds" specifies for how long a transaction can run before expiring
# and being aborted by the background thread. It defaults to 60 seconds, which is too short to
2019-03-20 08:50:30 -04:00
# be reliable for our tests. Setting it to 24 hours, so that it is longer than the Evergreen
# execution timeout.
2018-05-25 11:37:57 -04:00
if " transactionLifetimeLimitSeconds " not in test_data :
2019-03-20 08:50:30 -04:00
test_data [ " transactionLifetimeLimitSeconds " ] = 24 * 60 * 60
2018-05-25 11:37:57 -04:00
2017-03-27 01:23:31 -04:00
if " eval_prepend " in kwargs :
eval_sb . append ( str ( kwargs . pop ( " eval_prepend " ) ) )
2024-09-27 16:11:10 -04:00
if config . SHELL_GRPC :
eval_sb . append ( ' await import( " jstests/libs/override_methods/enable_grpc_on_connect.js " ) ' )
2017-12-07 10:24:06 -05:00
# If nodb is specified, pass the connection string through TestData so it can be used inside the
# test, then delete it so it isn't given as an argument to the mongo shell.
if " nodb " in kwargs and connection_string is not None :
test_data [ " connectionString " ] = connection_string
connection_string = None
2024-06-28 10:29:33 -04:00
if config . FUZZ_MONGOD_CONFIGS is not None and config . FUZZ_MONGOD_CONFIGS is not False :
test_data [ " fuzzMongodConfigs " ] = True
2025-10-22 18:54:50 +02:00
if config . FUZZ_RUNTIME_PARAMS is not None and config . FUZZ_RUNTIME_PARAMS is not False :
test_data [ " fuzzRuntimeParams " ] = True
eval_sb . append (
' await import( " jstests/libs/override_methods/implicitly_retry_on_conflicting_operation_during_fuzztest.js " ) '
)
2015-05-08 14:20:43 -04:00
for var_name in global_vars :
2019-11-08 17:24:46 +00:00
_format_shell_vars ( eval_sb , [ var_name ] , global_vars [ var_name ] )
2015-05-08 14:20:43 -04:00
if " eval " in kwargs :
2015-09-22 16:40:06 -04:00
eval_sb . append ( str ( kwargs . pop ( " eval " ) ) )
2015-05-08 14:20:43 -04:00
2023-03-30 21:48:12 +00:00
# Load a callback to check that the cluster-wide metadata is consistent.
2023-08-02 13:01:31 +00:00
eval_sb . append ( ' await import( " jstests/libs/override_methods/check_metadata_consistency.js " ) ' )
2023-03-30 21:48:12 +00:00
2017-05-18 11:22:09 -04:00
# Load this file to allow a callback to validate collections before shutting down mongod.
2023-08-02 13:01:31 +00:00
eval_sb . append (
2024-05-16 18:00:17 -04:00
' await import( " jstests/libs/override_methods/validate_collections_on_shutdown.js " ) '
)
2017-05-18 11:22:09 -04:00
2017-08-22 18:06:47 -04:00
# Load a callback to check UUID consistency before shutting down a ShardingTest.
eval_sb . append (
2024-05-16 18:00:17 -04:00
' await import( " jstests/libs/override_methods/check_uuids_consistent_across_cluster.js " ) '
)
2017-08-22 18:06:47 -04:00
2019-12-20 03:06:46 +00:00
# Load a callback to check index consistency before shutting down a ShardingTest.
eval_sb . append (
2024-05-16 18:00:17 -04:00
' await import( " jstests/libs/override_methods/check_indexes_consistent_across_cluster.js " ) '
)
2019-12-20 03:06:46 +00:00
2020-02-06 10:50:21 -05:00
# Load a callback to check that all orphans are deleted before shutting down a ShardingTest.
eval_sb . append ( ' await import( " jstests/libs/override_methods/check_orphans_are_deleted.js " ) ' )
2022-04-19 07:46:13 +00:00
# Load a callback to check that the info stored in config.collections and config.chunks is
# semantically correct before shutting down a ShardingTest.
eval_sb . append (
2024-05-16 18:00:17 -04:00
' await import( " jstests/libs/override_methods/check_routing_table_consistency.js " ) '
)
2022-04-19 07:46:13 +00:00
2023-01-18 10:49:06 +00:00
# Load a callback to check that all shards have correct filtering information before shutting
# down a ShardingTest.
eval_sb . append (
2024-05-16 18:00:17 -04:00
' await import( " jstests/libs/override_methods/check_shard_filtering_metadata.js " ) '
)
2023-01-18 10:49:06 +00:00
2022-09-28 12:55:00 +00:00
if config . FUZZ_MONGOD_CONFIGS is not None and config . FUZZ_MONGOD_CONFIGS is not False :
# Prevent commands from running with the config fuzzer.
eval_sb . append (
2024-05-16 18:00:17 -04:00
' await import( " jstests/libs/override_methods/config_fuzzer_incompatible_commands.js " ) '
)
2022-09-28 12:55:00 +00:00
2019-02-21 20:49:48 -05:00
# Load this file to retry operations that fail due to in-progress background operations.
eval_sb . append (
2025-04-02 19:16:44 -04:00
' await import( " jstests/libs/override_methods/index_builds/implicitly_retry_on_background_op_in_progress.js " ) '
2019-02-21 20:49:48 -05:00
)
2020-08-04 21:15:08 -04:00
eval_sb . append (
2024-05-16 18:00:17 -04:00
' (function() { Timestamp.prototype.toString = function() { throw new Error( " Cannot toString timestamps. Consider using timestampCmp() for comparison or tojson(<variable>) for output. " ); } })() '
2020-08-04 21:15:08 -04:00
)
2025-07-10 16:13:11 -04:00
mocha_grep = json . dumps ( config . MOCHA_GREP )
eval_sb . append ( f " globalThis._mocha_grep = { mocha_grep } ; " )
2015-05-08 14:20:43 -04:00
eval_str = " ; " . join ( eval_sb )
args . append ( " --eval " )
args . append ( eval_str )
2024-01-11 20:49:28 +00:00
if config . SHELL_TLS_ENABLED :
args . extend ( [ " --tls " , " --tlsAllowInvalidHostnames " ] )
if config . TLS_CA_FILE :
kwargs [ " tlsCAFile " ] = config . TLS_CA_FILE
if config . SHELL_TLS_CERTIFICATE_KEY_FILE :
kwargs [ " tlsCertificateKeyFile " ] = config . SHELL_TLS_CERTIFICATE_KEY_FILE
2025-01-31 14:06:27 -08:00
# mongotmock testing with gRPC requires that the shell establish a connection with mongotmock
# over gRPC.
if config . SHELL_GRPC or mongod_set_parameters . get ( " useGrpcForSearch " ) :
2024-01-18 13:38:02 -05:00
args . append ( " --gRPC " )
2026-02-13 18:23:06 -05:00
if config . SHELL_JSDEBUGMODE :
# relay to the shell flags
kwargs [ " jsDebugMode " ] = " "
2017-09-01 17:40:29 -04:00
if connection_string is not None :
2017-07-21 10:21:09 -04:00
# The --host and --port options are ignored by the mongo shell when an explicit connection
# string is specified. We remove these options to avoid any ambiguity with what server the
# logged mongo shell invocation will connect to.
if " port " in kwargs :
kwargs . pop ( " port " )
if " host " in kwargs :
kwargs . pop ( " host " )
2025-04-15 12:30:26 -04:00
for key in mongo_set_parameters :
val = str ( mongo_set_parameters [ key ] )
args . append ( f " --setShellParameter= { key } = { val } " )
2015-05-08 14:20:43 -04:00
# Apply the rest of the command line arguments.
_apply_kwargs ( args , kwargs )
2017-09-01 17:40:29 -04:00
if connection_string is not None :
args . append ( connection_string )
2017-07-21 10:21:09 -04:00
2018-10-08 17:32:36 -04:00
# Have the mongo shell run the specified file.
2024-05-14 11:07:04 -07:00
if filenames :
args . extend ( filenames )
2015-05-08 14:20:43 -04:00
2015-07-30 15:48:52 -04:00
_set_keyfile_permissions ( test_data )
2015-05-08 14:20:43 -04:00
process_kwargs = utils . default_if_none ( process_kwargs , { } )
2018-11-01 11:53:08 -04:00
return make_process ( logger , args , * * process_kwargs )
2015-05-08 14:20:43 -04:00
2019-11-08 17:24:46 +00:00
def _format_shell_vars ( sb , paths , value ) :
"""
Format ' value ' in a way that can be passed to - - eval .
2015-05-08 14:20:43 -04:00
2019-11-08 17:24:46 +00:00
: param sb : string builder array for the output string .
: param paths : path of keys represented as a list .
: param value : value in the object corresponding to the keys in ` paths `
: return : Nothing .
2015-05-08 14:20:43 -04:00
"""
2019-11-08 17:24:46 +00:00
# Convert the list ["a", "b", "c"] into the string 'a["b"]["c"]'
def bracketize ( lst ) :
2024-05-16 18:00:17 -04:00
return lst [ 0 ] + " " . join ( f ' [ " { i } " ] ' for i in lst [ 1 : ] )
2019-11-08 17:24:46 +00:00
2015-05-08 14:20:43 -04:00
# Only need to do special handling for JSON objects.
2021-03-01 22:58:17 -05:00
if not isinstance ( value , ( dict , HistoryDict ) ) :
2019-11-08 17:24:46 +00:00
sb . append ( " %s = %s " % ( bracketize ( paths ) , json . dumps ( value ) ) )
2015-05-08 14:20:43 -04:00
return
# Avoid including curly braces and colons in output so that the command invocation can be
# copied and run through bash.
2019-11-08 17:24:46 +00:00
sb . append ( " %s = new Object() " % bracketize ( paths ) )
2015-05-08 14:20:43 -04:00
for subkey in value :
2019-11-08 17:24:46 +00:00
_format_shell_vars ( sb , paths + [ subkey ] , value [ subkey ] )
2015-05-08 14:20:43 -04:00
2024-05-16 18:00:17 -04:00
def dbtest_program (
logger , executable = None , suites = None , process_kwargs = None , * * kwargs
) - > process . Process :
2018-03-27 14:30:46 -04:00
""" Return a Process instance that starts a dbtest with arguments constructed from ' kwargs ' . """
2015-05-08 14:20:43 -04:00
executable = utils . default_if_none ( executable , config . DEFAULT_DBTEST_EXECUTABLE )
args = [ executable ]
if suites is not None :
args . extend ( suites )
if config . STORAGE_ENGINE is not None :
kwargs [ " storageEngine " ] = config . STORAGE_ENGINE
2022-04-24 01:18:07 +00:00
return generic_program ( logger , args , process_kwargs = process_kwargs , * * kwargs )
2015-08-04 11:33:33 -04:00
2017-07-21 10:21:09 -04:00
2024-05-13 09:26:21 -07:00
def genny_program ( logger , executable = None , process_kwargs = None , * * kwargs ) - > process . Process :
2018-10-22 14:11:51 -04:00
""" Return a Process instance that starts a genny executable with arguments constructed from ' kwargs ' . """
2018-10-29 13:39:11 -04:00
executable = utils . default_if_none ( executable , config . DEFAULT_GENNY_EXECUTABLE )
2018-10-22 14:11:51 -04:00
args = [ executable ]
2022-04-24 01:18:07 +00:00
return generic_program ( logger , args , process_kwargs = process_kwargs , * * kwargs )
2018-10-22 14:11:51 -04:00
2024-05-13 09:26:21 -07:00
def generic_program ( logger , args , process_kwargs = None , * * kwargs ) - > process . Process :
2018-03-27 14:30:46 -04:00
""" Return a Process instance that starts an arbitrary executable.
The executable arguments are constructed from ' kwargs ' .
The args parameter is an array of strings containing the command to execute .
2015-08-04 11:33:33 -04:00
"""
if not utils . is_string_list ( args ) :
raise ValueError ( " The args parameter must be a list of command arguments " )
_apply_kwargs ( args , kwargs )
2015-05-08 14:20:43 -04:00
process_kwargs = utils . default_if_none ( process_kwargs , { } )
2018-11-01 11:53:08 -04:00
return make_process ( logger , args , * * process_kwargs )
2015-05-08 14:20:43 -04:00
def _apply_set_parameters ( args , set_parameter ) :
2018-03-27 14:30:46 -04:00
""" Convert key-value pairs from ' kwargs ' into --setParameter key=value arguments.
This result is appended to ' args ' .
2015-05-08 14:20:43 -04:00
"""
for param_name in set_parameter :
param_value = set_parameter [ param_name ]
# --setParameter takes boolean values as lowercase strings.
if isinstance ( param_value , bool ) :
param_value = " true " if param_value else " false "
args . append ( " --setParameter " )
args . append ( " %s = %s " % ( param_name , param_value ) )
def _apply_kwargs ( args , kwargs ) :
2018-03-27 14:30:46 -04:00
""" Convert key-value pairs from ' kwargs ' into --key value arguments.
2015-05-08 14:20:43 -04:00
2018-03-27 14:30:46 -04:00
This result is appended to ' args ' .
2015-05-08 14:20:43 -04:00
A - - flag without a value is represented with the empty string .
"""
for arg_name in kwargs :
arg_value = str ( kwargs [ arg_name ] )
if arg_value :
2018-02-14 17:15:03 -05:00
args . append ( " -- %s = %s " % ( arg_name , arg_value ) )
else :
args . append ( " -- %s " % ( arg_name ) )
2015-05-08 14:20:43 -04:00
2015-07-13 11:00:02 -04:00
def _set_keyfile_permissions ( opts ) :
2018-03-27 14:30:46 -04:00
""" Change the permissions of keyfiles in ' opts ' to 600, (only user can read and write the file).
2015-05-08 14:20:43 -04:00
This necessary to avoid having the mongod / mongos fail to start up
2015-07-13 11:00:02 -04:00
because " permissions on the keyfiles are too open " .
We can ' t permanently set the keyfile permissions because git is not
aware of them .
2015-05-08 14:20:43 -04:00
"""
2023-06-22 22:08:32 +00:00
for keysuffix in [ " 1 " , " 2 " , " ForRollover " ] :
keyfile = " jstests/libs/key %s " % keysuffix
if os . path . exists ( keyfile ) :
os . chmod ( keyfile , stat . S_IRUSR | stat . S_IWUSR )
2015-07-13 11:00:02 -04:00
if " keyFile " in opts :
os . chmod ( opts [ " keyFile " ] , stat . S_IRUSR | stat . S_IWUSR )
if " encryptionKeyFile " in opts :
os . chmod ( opts [ " encryptionKeyFile " ] , stat . S_IRUSR | stat . S_IWUSR )