2018-03-27 14:30:46 -04:00
""" Utility functions to create MongoDB processes.
2015-05-08 14:20:43 -04:00
Handles all the nitty - gritty parameter conversion .
"""
import json
import os
import os . path
import stat
2020-06-17 17:41:54 +03:00
from buildscripts . resmokelib import config
from buildscripts . resmokelib import utils
from buildscripts . resmokelib . core import jasper_process
from buildscripts . resmokelib . core import process
2020-11-20 15:41:26 -05:00
from buildscripts . resmokelib . logging import loggers
2020-07-14 20:50:12 +00:00
from buildscripts . resmokelib . multiversionconstants import LAST_LTS_MONGOD_BINARY
from buildscripts . resmokelib . multiversionconstants import LAST_LTS_MONGOS_BINARY
2015-05-08 14:20:43 -04:00
2018-07-09 19:32:06 -04:00
# The below parameters define the default 'logComponentVerbosity' object passed to mongod processes
# started either directly via resmoke or those that will get started by the mongo shell. We allow
# this default to be different for tests run locally and tests run in Evergreen. This allows us, for
# example, to keep log verbosity high in Evergreen test runs without polluting the logs for
# developers running local tests.
# The default verbosity setting for any tests that are not started with an Evergreen task id. This
# will apply to any tests run locally.
2020-02-28 15:53:26 -05:00
DEFAULT_MONGOD_LOG_COMPONENT_VERBOSITY = {
2020-08-26 16:11:16 +00:00
" replication " : { " rollback " : 2 } , " sharding " : { " migration " : 2 } , " transaction " : 4 ,
" tenantMigration " : 4
2020-02-28 15:53:26 -05:00
}
2018-07-09 19:32:06 -04:00
2020-07-14 20:50:12 +00:00
DEFAULT_LAST_LTS_MONGOD_LOG_COMPONENT_VERBOSITY = { " replication " : { " rollback " : 2 } , " transaction " : 4 }
2020-03-02 17:56:18 -05:00
2020-08-26 16:11:16 +00:00
# The default verbosity setting for any mongod processes running in Evergreen i.e. started with an
# Evergreen task id.
2018-07-25 16:59:49 -04:00
DEFAULT_EVERGREEN_MONGOD_LOG_COMPONENT_VERBOSITY = {
2018-10-03 16:04:05 -04:00
" replication " : { " election " : 4 , " heartbeats " : 2 , " initialSync " : 2 , " rollback " : 2 } ,
2020-08-26 16:11:16 +00:00
" sharding " : { " migration " : 2 } , " storage " : { " recovery " : 2 } , " transaction " : 4 , " tenantMigration " : 4
2018-07-25 16:59:49 -04:00
}
2018-07-09 19:32:06 -04:00
2020-07-14 20:50:12 +00:00
# The default verbosity setting for any last-lts mongod processes running in Evergreen i.e. started
2020-03-02 17:56:18 -05:00
# with an Evergreen task id.
2020-07-14 20:50:12 +00:00
DEFAULT_EVERGREEN_LAST_LTS_MONGOD_LOG_COMPONENT_VERBOSITY = {
2020-03-02 17:56:18 -05:00
" replication " : { " election " : 4 , " heartbeats " : 2 , " initialSync " : 2 , " rollback " : 2 } ,
" storage " : { " recovery " : 2 } , " transaction " : 4
}
2019-03-22 11:36:22 -04:00
# The default verbosity setting for any tests that are not started with an Evergreen task id. This
# will apply to any tests run locally.
DEFAULT_MONGOS_LOG_COMPONENT_VERBOSITY = { " transaction " : 3 }
# The default verbosity setting for any tests running in Evergreen i.e. started with an Evergreen
# task id.
DEFAULT_EVERGREEN_MONGOS_LOG_COMPONENT_VERBOSITY = { " transaction " : 3 }
2018-07-09 19:32:06 -04:00
2018-11-01 11:53:08 -04:00
def make_process ( * args , * * kwargs ) :
""" Choose whether to use python built in process or jasper. """
process_cls = process . Process
if config . SPAWN_USING == " jasper " :
process_cls = jasper_process . Process
2020-10-21 11:44:22 -04:00
else :
# remove jasper process specific args
kwargs . pop ( " job_num " , None )
kwargs . pop ( " test_id " , None )
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 ( )
2019-12-17 14:40:28 -05:00
path = [
os . getcwd ( ) ,
config . DEFAULT_MULTIVERSION_DIR ,
]
# If installDir is provided, add it early to the path
if config . INSTALL_DIR is not None :
path . append ( config . INSTALL_DIR )
2020-04-15 10:52:25 -04:00
env_vars [ " INSTALL_DIR " ] = config . INSTALL_DIR
2019-12-17 14:40:28 -05:00
path . append ( env_vars . get ( " PATH " , os . environ . get ( " PATH " , " " ) ) )
2019-08-15 13:59:28 +00:00
env_vars [ " PATH " ] = os . pathsep . join ( path )
kwargs [ " env_vars " ] = env_vars
2018-11-01 11:53:08 -04:00
return process_cls ( * args , * * kwargs )
2018-07-09 19:32:06 -04:00
def default_mongod_log_component_verbosity ( ) :
""" Return the default ' logComponentVerbosity ' value to use for mongod processes. """
if config . EVERGREEN_TASK_ID :
return DEFAULT_EVERGREEN_MONGOD_LOG_COMPONENT_VERBOSITY
return DEFAULT_MONGOD_LOG_COMPONENT_VERBOSITY
2018-07-06 14:54:38 -04:00
2015-05-08 14:20:43 -04:00
2020-07-14 20:50:12 +00:00
def default_last_lts_mongod_log_component_verbosity ( ) :
""" Return the default ' logComponentVerbosity ' value to use for last-lts mongod processes. """
2020-03-02 17:56:18 -05:00
if config . EVERGREEN_TASK_ID :
2020-07-14 20:50:12 +00:00
return DEFAULT_EVERGREEN_LAST_LTS_MONGOD_LOG_COMPONENT_VERBOSITY
return DEFAULT_LAST_LTS_MONGOD_LOG_COMPONENT_VERBOSITY
2020-03-02 17:56:18 -05:00
2019-03-22 11:36:22 -04:00
def default_mongos_log_component_verbosity ( ) :
""" Return the default ' logComponentVerbosity ' value to use for mongos processes. """
if config . EVERGREEN_TASK_ID :
return DEFAULT_EVERGREEN_MONGOS_LOG_COMPONENT_VERBOSITY
return DEFAULT_MONGOS_LOG_COMPONENT_VERBOSITY
2020-03-02 17:56:18 -05:00
def get_default_log_component_verbosity_for_mongod ( executable ) :
""" Return the correct default ' logComponentVerbosity ' value for the executable version. """
2020-07-14 20:50:12 +00:00
if executable == LAST_LTS_MONGOD_BINARY :
return default_last_lts_mongod_log_component_verbosity ( )
2020-03-02 17:56:18 -05:00
return default_mongod_log_component_verbosity ( )
2020-06-05 17:45:38 +00:00
def _add_testing_set_parameters ( suite_set_parameters ) :
# Certain behaviors should only be enabled for resmoke usage. These are traditionally new
# commands, insecure access, and increased diagnostics.
suite_set_parameters . setdefault ( " testingDiagnosticsEnabled " , True )
suite_set_parameters . setdefault ( " enableTestCommands " , True )
2020-04-12 14:27:18 -04:00
def mongod_program ( # pylint: disable=too-many-branches,too-many-statements
2020-11-20 15:41:26 -05:00
logger , job_num , executable = None , process_kwargs = None , * * kwargs ) :
2018-03-27 14:30:46 -04:00
""" Return a Process instance that starts mongod arguments constructed from ' kwargs ' . """
2015-05-08 14:20:43 -04:00
executable = utils . default_if_none ( executable , config . DEFAULT_MONGOD_EXECUTABLE )
args = [ executable ]
2015-07-15 15:38:13 -04:00
# Apply the --setParameter command line argument. Command line options to resmoke.py override
# the YAML configuration.
suite_set_parameters = kwargs . pop ( " set_parameters " , { } )
if config . MONGOD_SET_PARAMETERS is not None :
suite_set_parameters . update ( utils . load_yaml ( config . MONGOD_SET_PARAMETERS ) )
2018-07-06 14:54:38 -04:00
# Set default log verbosity levels if none were specified.
if " logComponentVerbosity " not in suite_set_parameters :
2020-03-02 17:56:18 -05:00
suite_set_parameters [
" logComponentVerbosity " ] = get_default_log_component_verbosity_for_mongod ( executable )
2017-02-22 16:44:16 -05:00
2020-04-12 14:27:18 -04:00
# minNumChunksForSessionsCollection controls the minimum number of chunks the balancer will
# enforce for the sessions collection. If the actual number of chunks is less, the balancer will
# issue split commands to create more chunks. As a result, the balancer will also end up moving
# chunks for the sessions collection to balance the chunks across shards. Unless the suite is
# explicitly prepared to handle these background migrations, set the parameter to 1.
if " configsvr " in kwargs and " minNumChunksForSessionsCollection " not in suite_set_parameters :
suite_set_parameters [ " minNumChunksForSessionsCollection " ] = 1
2017-06-19 17:27:37 -04:00
# orphanCleanupDelaySecs controls an artificial delay before cleaning up an orphaned chunk
# that has migrated off of a shard, meant to allow most dependent queries on secondaries to
# complete first. It defaults to 900, or 15 minutes, which is prohibitively long for tests.
# Setting it in the .yml file overrides this.
if " shardsvr " in kwargs and " orphanCleanupDelaySecs " not in suite_set_parameters :
2018-04-11 11:05:13 -04:00
suite_set_parameters [ " orphanCleanupDelaySecs " ] = 1
2017-06-19 17:27:37 -04:00
2017-09-07 14:20:32 -04:00
# The LogicalSessionCache does automatic background refreshes in the server. This is
# race-y for tests, since tests trigger their own immediate refreshes instead. Turn off
# background refreshing for tests. Set in the .yml file to override this.
if " disableLogicalSessionCacheRefresh " not in suite_set_parameters :
suite_set_parameters [ " disableLogicalSessionCacheRefresh " ] = True
2020-04-24 14:01:56 -04:00
# Set coordinateCommitReturnImmediatelyAfterPersistingDecision to false so that tests do
2020-10-09 13:46:04 +01:00
# not need to rely on causal consistency or explicitly wait for the transaction to finish
# committing. If we are running LAST_LTS mongoD and the test suite has explicitly set the
# coordinateCommitReturnImmediatelyAfterPersistingDecision parameter, we remove it from
# the setParameter list, since coordinateCommitReturnImmediatelyAfterPersistingDecision
# does not exist prior to 4.7.
# TODO(SERVER-51682): remove the 'elif' clause on master when 5.0 becomes LAST_LTS.
2020-07-14 20:50:12 +00:00
if executable != LAST_LTS_MONGOD_BINARY and \
2020-04-24 14:01:56 -04:00
" coordinateCommitReturnImmediatelyAfterPersistingDecision " not in suite_set_parameters :
suite_set_parameters [ " coordinateCommitReturnImmediatelyAfterPersistingDecision " ] = False
2020-10-09 13:46:04 +01:00
elif executable == LAST_LTS_MONGOD_BINARY and \
" coordinateCommitReturnImmediatelyAfterPersistingDecision " in suite_set_parameters :
del suite_set_parameters [ " coordinateCommitReturnImmediatelyAfterPersistingDecision " ]
2020-04-24 14:01:56 -04:00
2021-02-08 22:01:56 +00:00
# TODO SERVER-54593 to remove the special-case handling when 5.0 becomes LAST_LTS.
if " reshardingMinimumOperationDurationMillis " in suite_set_parameters :
if executable == LAST_LTS_MONGOD_BINARY :
del suite_set_parameters [ " reshardingMinimumOperationDurationMillis " ]
elif executable != LAST_LTS_MONGOD_BINARY :
suite_set_parameters [ " reshardingMinimumOperationDurationMillis " ] = 5000
2018-03-26 17:26:50 -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-03-26 17:26:50 -04:00
if " transactionLifetimeLimitSeconds " not in suite_set_parameters :
2019-03-20 08:50:30 -04:00
suite_set_parameters [ " transactionLifetimeLimitSeconds " ] = 24 * 60 * 60
2018-03-26 17:26:50 -04:00
2019-05-02 09:48:17 -04:00
# Hybrid index builds drain writes received during the build process in batches of 1000 writes
# by default. Not all tests perform enough writes to exercise the code path where multiple
# batches are applied, which means certain bugs are harder to encounter. Set this level lower
# so there are more opportunities to drain writes in multiple batches.
if " maxIndexBuildDrainBatchSize " not in suite_set_parameters :
suite_set_parameters [ " maxIndexBuildDrainBatchSize " ] = 10
2017-11-02 16:27:43 -04:00
# The periodic no-op writer writes an oplog entry of type='n' once every 10 seconds. This has
# the potential to mask issues such as SERVER-31609 because it allows the operationTime of
# cluster to advance even if the client is blocked for other reasons. We should disable the
# periodic no-op writer. Set in the .yml file to override this.
if " replSet " in kwargs and " writePeriodicNoops " not in suite_set_parameters :
suite_set_parameters [ " writePeriodicNoops " ] = False
2020-04-27 09:17:25 -04:00
# The default time for stepdown and quiesce mode in response to SIGTERM is 15 seconds. Reduce
# this to 100ms for faster shutdown. On branches 4.4 and earlier, there is no quiesce mode, but
# the default time for stepdown is 10 seconds.
# TODO(SERVER-47797): Remove reference to waitForStepDownOnNonCommandShutdown.
if ( " replSet " in kwargs and " waitForStepDownOnNonCommandShutdown " not in suite_set_parameters
and " shutdownTimeoutMillisForSignaledShutdown " not in suite_set_parameters ) :
2020-07-14 20:50:12 +00:00
if executable == LAST_LTS_MONGOD_BINARY :
2020-04-27 09:17:25 -04:00
suite_set_parameters [ " waitForStepDownOnNonCommandShutdown " ] = False
else :
suite_set_parameters [ " shutdownTimeoutMillisForSignaledShutdown " ] = 100
2019-04-09 13:50:45 -04:00
2019-05-29 14:14:26 -04:00
if " enableFlowControl " not in suite_set_parameters and config . FLOW_CONTROL is not None :
suite_set_parameters [ " enableFlowControl " ] = ( config . FLOW_CONTROL == " on " )
2019-05-02 15:15:17 -04:00
2019-05-23 14:28:28 -04:00
if ( " failpoint.flowControlTicketOverride " not in suite_set_parameters
and config . FLOW_CONTROL_TICKETS is not None ) :
suite_set_parameters [ " failpoint.flowControlTicketOverride " ] = {
" mode " : " alwaysOn " , " data " : { " numTickets " : config . FLOW_CONTROL_TICKETS }
}
2020-08-18 22:35:17 +00:00
_add_testing_set_parameters ( suite_set_parameters )
2020-06-05 17:45:38 +00:00
2015-07-15 15:38:13 -04:00
_apply_set_parameters ( args , suite_set_parameters )
2015-05-08 14:20:43 -04:00
shortcut_opts = {
2018-09-26 11:26:36 -04:00
" enableMajorityReadConcern " : config . MAJORITY_READ_CONCERN ,
2015-05-08 14:20:43 -04:00
" nojournal " : config . NO_JOURNAL ,
" storageEngine " : config . STORAGE_ENGINE ,
2017-09-15 10:10:56 -04:00
" transportLayer " : config . TRANSPORT_LAYER ,
2015-05-08 14:20:43 -04:00
" wiredTigerCollectionConfigString " : config . WT_COLL_CONFIG ,
" wiredTigerEngineConfigString " : config . WT_ENGINE_CONFIG ,
" wiredTigerIndexConfigString " : config . WT_INDEX_CONFIG ,
}
2019-01-16 22:08:41 -05:00
if config . STORAGE_ENGINE == " inMemory " :
shortcut_opts [ " inMemorySizeGB " ] = config . STORAGE_ENGINE_CACHE_SIZE
elif config . STORAGE_ENGINE == " rocksdb " :
2016-06-14 12:44:00 -04:00
shortcut_opts [ " rocksdbCacheSizeGB " ] = config . STORAGE_ENGINE_CACHE_SIZE
elif config . STORAGE_ENGINE == " wiredTiger " or config . STORAGE_ENGINE is None :
shortcut_opts [ " wiredTigerCacheSizeGB " ] = config . STORAGE_ENGINE_CACHE_SIZE
2015-05-08 14:20:43 -04:00
# These options are just flags, so they should not take a value.
2020-01-22 14:25:03 -05:00
opts_without_vals = ( " nojournal " , " logappend " )
2015-05-08 14:20:43 -04:00
# Have the --nojournal command line argument to resmoke.py unset the journal option.
2015-09-21 09:06:22 -04:00
if shortcut_opts [ " nojournal " ] and " journal " in kwargs :
2015-05-08 14:20:43 -04:00
del kwargs [ " journal " ]
2015-10-08 16:31:31 -04:00
# Ensure that config servers run with journaling enabled.
if " configsvr " in kwargs :
shortcut_opts [ " nojournal " ] = False
kwargs [ " journal " ] = " "
2015-09-21 09:06:22 -04:00
# Command line options override the YAML configuration.
2015-05-08 14:20:43 -04:00
for opt_name in shortcut_opts :
2015-09-21 09:06:22 -04:00
opt_value = shortcut_opts [ opt_name ]
if opt_name in opts_without_vals :
# Options that are specified as --flag on the command line are represented by a boolean
# value where True indicates that the flag should be included in 'kwargs'.
if opt_value :
2015-05-08 14:20:43 -04:00
kwargs [ opt_name ] = " "
2015-09-21 09:06:22 -04:00
else :
# Options that are specified as --key=value on the command line are represented by a
# value where None indicates that the key-value pair shouldn't be included in 'kwargs'.
if opt_value is not None :
kwargs [ opt_name ] = opt_value
2015-05-08 14:20:43 -04:00
2015-07-29 17:24:35 -04:00
# Override the storage engine specified on the command line with "wiredTiger" if running a
# config server replica set.
if " replSet " in kwargs and " configsvr " in kwargs :
kwargs [ " storageEngine " ] = " wiredTiger "
2015-05-08 14:20:43 -04:00
# Apply the rest of the command line arguments.
_apply_kwargs ( args , kwargs )
2015-07-13 11:00:02 -04:00
_set_keyfile_permissions ( kwargs )
2015-05-08 14:20:43 -04:00
process_kwargs = utils . default_if_none ( process_kwargs , { } )
2020-11-20 15:41:26 -05:00
process_kwargs [ " job_num " ] = job_num
2018-11-01 11:53:08 -04:00
return make_process ( logger , args , * * process_kwargs )
2015-05-08 14:20:43 -04:00
2020-11-20 15:41:26 -05:00
def mongos_program ( logger , job_num , test_id = None , executable = None , process_kwargs = None , * * kwargs ) :
2018-03-27 14:30:46 -04:00
""" Return a Process instance that starts a mongos with arguments constructed from ' kwargs ' . """
2015-05-08 14:20:43 -04:00
executable = utils . default_if_none ( executable , config . DEFAULT_MONGOS_EXECUTABLE )
args = [ executable ]
2015-07-15 15:38:13 -04:00
# Apply the --setParameter command line argument. Command line options to resmoke.py override
# the YAML configuration.
suite_set_parameters = kwargs . pop ( " set_parameters " , { } )
if config . MONGOS_SET_PARAMETERS is not None :
suite_set_parameters . update ( utils . load_yaml ( config . MONGOS_SET_PARAMETERS ) )
2019-03-22 11:36:22 -04:00
# Set default log verbosity levels if none were specified.
if " logComponentVerbosity " not in suite_set_parameters :
suite_set_parameters [ " logComponentVerbosity " ] = default_mongos_log_component_verbosity ( )
2020-08-18 22:35:17 +00:00
_add_testing_set_parameters ( suite_set_parameters )
2020-06-05 17:45:38 +00:00
2015-07-15 15:38:13 -04:00
_apply_set_parameters ( args , suite_set_parameters )
2015-05-08 14:20:43 -04:00
# Apply the rest of the command line arguments.
_apply_kwargs ( args , kwargs )
2015-07-13 11:00:02 -04:00
_set_keyfile_permissions ( kwargs )
2015-05-08 14:20:43 -04:00
process_kwargs = utils . default_if_none ( process_kwargs , { } )
2020-11-20 15:41:26 -05:00
process_kwargs [ " job_num " ] = job_num
process_kwargs [ " test_id " ] = test_id
2018-11-01 11:53:08 -04:00
return make_process ( logger , args , * * process_kwargs )
2015-05-08 14:20:43 -04:00
2020-10-21 11:44:22 -04:00
def mongo_shell_program ( # pylint: disable=too-many-arguments,too-many-branches,too-many-locals,too-many-statements
2020-11-20 15:41:26 -05:00
logger , job_num , test_id = None , executable = None , connection_string = None , filename = None ,
2020-10-21 11:44:22 -04:00
process_kwargs = None , * * kwargs ) :
2018-03-27 14:30:46 -04:00
""" Return a Process instance that starts a mongo shell.
The shell is started with the given connection string and arguments constructed from ' kwargs ' .
2015-05-08 14:20:43 -04:00
"""
2018-10-08 17:32:36 -04:00
executable = utils . default_if_none (
utils . default_if_none ( executable , config . MONGO_EXECUTABLE ) , config . DEFAULT_MONGO_EXECUTABLE )
2015-05-08 14:20:43 -04:00
args = [ 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
2018-10-08 17:32:36 -04:00
if filename is not None :
test_name = os . path . splitext ( os . path . basename ( filename ) ) [ 0 ]
else :
test_name = None
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 ) ,
2018-09-26 11:26:36 -04:00
" enableMajorityReadConcern " : ( config . MAJORITY_READ_CONCERN , True ) ,
2019-09-09 14:09:29 +00:00
" mixedBinVersions " : ( config . MIXED_BIN_VERSIONS , " " ) ,
2015-05-08 14:20:43 -04:00
" noJournal " : ( config . NO_JOURNAL , False ) ,
" storageEngine " : ( config . STORAGE_ENGINE , " " ) ,
2016-06-10 17:21:19 -04:00
" storageEngineCacheSizeGB " : ( config . STORAGE_ENGINE_CACHE_SIZE , " " ) ,
2018-10-08 17:32:36 -04:00
" testName " : ( test_name , " " ) ,
2017-09-15 10:10:56 -04:00
" transportLayer " : ( config . TRANSPORT_LAYER , " " ) ,
2015-05-08 14:20:43 -04:00
" wiredTigerCollectionConfigString " : ( config . WT_COLL_CONFIG , " " ) ,
" wiredTigerEngineConfigString " : ( config . WT_ENGINE_CONFIG , " " ) ,
" wiredTigerIndexConfigString " : ( config . WT_INDEX_CONFIG , " " ) ,
}
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
2015-05-08 14:20:43 -04:00
global_vars [ " TestData " ] = test_data
2020-02-13 11:18:03 +03:00
if config . EVERGREEN_TASK_ID is not None :
test_data [ " inEvergreen " ] = True
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 ( )
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 ) )
# 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 ) )
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 ) )
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.
mongod_set_parameters . setdefault ( " logComponentVerbosity " ,
2018-07-09 19:32:06 -04:00
default_mongod_log_component_verbosity ( ) )
2018-07-06 14:54:38 -04:00
2019-05-02 15:15:17 -04:00
# If the 'enableFlowControl' setParameter for mongod was not already specified, we set its value
# to a default.
2019-05-29 14:14:26 -04:00
if config . FLOW_CONTROL is not None :
mongod_set_parameters . setdefault ( " enableFlowControl " , config . FLOW_CONTROL == " on " )
2019-05-02 15:15:17 -04:00
2021-02-08 22:01:56 +00:00
# Set the default value for minimum resharding operation duration to 5 seconds.
mongod_set_parameters . setdefault ( " reshardingMinimumOperationDurationMillis " , 5000 )
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.
mongos_set_parameters . setdefault ( " logComponentVerbosity " ,
default_mongos_log_component_verbosity ( ) )
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
2015-07-30 15:48:52 -04:00
2020-05-28 10:19:18 -04:00
test_data [ " undoRecorderPath " ] = config . UNDO_RECORDER_PATH
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 " ) ) )
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
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
2017-05-18 11:22:09 -04:00
# Load this file to allow a callback to validate collections before shutting down mongod.
2017-09-01 17:40:29 -04:00
eval_sb . append ( " load( ' 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 (
" load( ' jstests/libs/override_methods/check_uuids_consistent_across_cluster.js ' ); " )
2019-12-20 03:06:46 +00:00
# Load a callback to check index consistency before shutting down a ShardingTest.
eval_sb . append (
" load( ' jstests/libs/override_methods/check_indexes_consistent_across_cluster.js ' ); " )
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 ( " load( ' jstests/libs/override_methods/check_orphans_are_deleted.js ' ); " )
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 (
" load( ' jstests/libs/override_methods/implicitly_retry_on_background_op_in_progress.js ' ); " )
2020-08-04 21:15:08 -04:00
eval_sb . append (
" (function() { Timestamp.prototype.toString = function() { throw new Error( \" Cannot toString timestamps. Consider using timestampCmp() for comparison or tojson(<variable>) for output. \" ); } })(); "
)
2015-05-08 14:20:43 -04:00
eval_str = " ; " . join ( eval_sb )
args . append ( " --eval " )
args . append ( eval_str )
2015-07-28 16:54:58 -04:00
if config . SHELL_READ_MODE is not None :
kwargs [ " readMode " ] = config . SHELL_READ_MODE
2015-05-08 14:20:43 -04:00
if config . SHELL_WRITE_MODE is not None :
kwargs [ " writeMode " ] = config . SHELL_WRITE_MODE
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 " )
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.
if filename is not None :
args . append ( filename )
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 , { } )
2020-10-21 11:44:22 -04:00
process_kwargs [ " job_num " ] = job_num
process_kwargs [ " test_id " ] = test_id
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 ) :
return lst [ 0 ] + ' ' . join ( f ' [ " { i } " ] ' for i in lst [ 1 : ] )
2015-05-08 14:20:43 -04:00
# Only need to do special handling for JSON objects.
if not isinstance ( value , dict ) :
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
2020-11-20 15:41:26 -05:00
def dbtest_program ( logger , job_num , test_id = None , executable = None , suites = None , process_kwargs = None ,
* * kwargs ) : # pylint: disable=too-many-arguments
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 )
2018-09-26 11:26:36 -04:00
kwargs [ " enableMajorityReadConcern " ] = config . MAJORITY_READ_CONCERN
2015-05-08 14:20:43 -04:00
if config . STORAGE_ENGINE is not None :
kwargs [ " storageEngine " ] = config . STORAGE_ENGINE
2019-05-29 14:14:26 -04:00
if config . FLOW_CONTROL is not None :
kwargs [ " flowControl " ] = ( config . FLOW_CONTROL == " on " )
2019-05-02 15:15:17 -04:00
2020-11-20 15:41:26 -05:00
return generic_program ( logger , args , job_num , test_id = test_id , process_kwargs = process_kwargs ,
* * kwargs )
2015-08-04 11:33:33 -04:00
2017-07-21 10:21:09 -04:00
2020-11-20 15:41:26 -05:00
def genny_program ( logger , job_num , test_id = None , executable = None , process_kwargs = None , * * kwargs ) :
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 ]
2020-11-20 15:41:26 -05:00
return generic_program ( logger , args , job_num , test_id = test_id , process_kwargs = process_kwargs ,
* * kwargs )
2018-10-22 14:11:51 -04:00
2020-11-20 15:41:26 -05:00
def generic_program ( logger , args , job_num , test_id = None , process_kwargs = None , * * kwargs ) :
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 , { } )
2020-11-20 15:41:26 -05:00
process_kwargs [ " job_num " ] = job_num
process_kwargs [ " test_id " ] = test_id
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
"""
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 )