From 8a41cf72c58d33f56a3ef16ca1c70f05f85c0444 Mon Sep 17 00:00:00 2001 From: Matt Broadstone Date: Wed, 2 Aug 2023 13:01:31 +0000 Subject: [PATCH] SERVER-79606 Convert validate collections hook to module --- buildscripts/resmokelib/core/programs.py | 5 +- etc/evergreen_yml_components/definitions.yml | 6 +- jstests/change_streams/lookup_post_image.js | 8 +- .../change_streams/metadata_notifications.js | 7 +- .../whole_cluster_metadata_notifications.js | 10 +- .../whole_db_metadata_notifications.js | 10 +- jstests/concurrency/fsm_libs/cluster.js | 6 +- .../concurrency/fsm_libs/resmoke_runner.js | 8 +- jstests/concurrency/fsm_libs/runner.js | 14 +- jstests/concurrency/fsm_libs/thread_mgr.js | 22 +- jstests/concurrency/fsm_libs/worker_thread.js | 6 +- .../hooks/run_initial_sync_node_validation.js | 6 +- jstests/hooks/run_validate_collections.js | 7 +- jstests/hooks/validate_collections.js | 276 +++++------ jstests/libs/command_sequence_with_retries.js | 53 +- jstests/libs/fsm_serial_client.js | 4 +- .../validate_collections_on_shutdown.js | 26 +- jstests/libs/parallelTester_module.js | 465 ++++++++++++++++++ .../genericBinVersion/keystring_index.js | 5 +- .../rollback_capped_deletions.js | 7 +- .../rollback_downgraded_to_latest.js | 7 +- .../rollback_latest_to_downgraded.js | 7 +- .../rollback_with_node_in_downgrading.js | 10 +- .../libs/multiversion_rollback.js | 20 +- .../capped_deletes_within_rollback.js | 8 +- .../noPassthrough/data_consistency_checks.js | 52 +- jstests/noPassthrough/drop_create_rollback.js | 6 +- jstests/noPassthrough/rollback_wt_drop.js | 7 +- .../timeseries_extended_range_rollback.js | 8 +- .../timeseries_insert_rollback.js | 8 +- .../validate_hook_resume_fcv_upgrade.js | 84 ++-- .../replsets/drop_collections_two_phase.js | 10 +- ..._collections_two_phase_apply_ops_create.js | 10 +- ...op_collections_two_phase_apply_ops_drop.js | 10 +- ..._collections_two_phase_apply_ops_rename.js | 10 +- ...drop_collections_two_phase_create_index.js | 10 +- .../drop_collections_two_phase_dbhash.js | 10 +- .../drop_collections_two_phase_drop_index.js | 10 +- ...ollections_two_phase_rename_drop_target.js | 10 +- .../drop_collections_two_phase_step_down.js | 10 +- ...rop_collections_two_phase_write_concern.js | 10 +- jstests/replsets/drop_databases_two_phase.js | 6 +- jstests/replsets/global_index_rollback.js | 8 +- .../replsets/initial_sync_drop_collection.js | 8 +- .../initial_sync_fails_on_rollback.js | 8 +- .../initial_sync_rename_collection.js | 8 +- .../libs/rollback_index_builds_test.js | 6 +- .../libs/rollback_resumable_index_build.js | 1 - jstests/replsets/libs/rollback_test.js | 8 +- jstests/replsets/libs/rollback_test_deluxe.js | 8 +- jstests/replsets/libs/two_phase_drops.js | 3 +- ...ors_returned_during_rollback_if_helloOk.js | 6 +- .../prepare_failover_rollback_commit.js | 5 +- ...backs_before_index_build_received_votes.js | 7 +- .../read_operations_during_rollback.js | 6 +- .../reconfig_removes_node_in_rollback.js | 8 +- ...committed_aborted_prepared_transactions.js | 8 +- .../recover_prepared_transaction_state.js | 8 +- ...build_if_resume_interrupted_by_rollback.js | 5 +- .../rollback_aborted_prepared_transaction.js | 8 +- jstests/replsets/rollback_all_op_types.js | 8 +- jstests/replsets/rollback_capped_deletions.js | 8 +- .../replsets/rollback_clustered_indexes.js | 6 +- jstests/replsets/rollback_collmods.js | 8 +- .../replsets/rollback_crud_op_sequences.js | 6 +- jstests/replsets/rollback_drop_database.js | 7 +- .../rollback_drop_index_after_rename.js | 8 +- jstests/replsets/rollback_dup_ids.js | 8 +- ..._dup_ids_clean_shutdown_during_rollback.js | 8 +- .../rollback_files_no_prepare_conflict.js | 7 +- .../rollback_index_build_and_create.js | 7 +- .../replsets/rollback_index_build_start.js | 7 +- .../rollback_index_build_start_abort.js | 7 +- ...back_index_build_start_abort_not_create.js | 7 +- .../rollback_index_build_start_commit.js | 7 +- .../rollback_index_build_start_commit_drop.js | 7 +- .../rollback_index_build_start_not_create.js | 7 +- .../rollback_large_batched_multi_deletes.js | 2 +- .../replsets/rollback_prepare_transaction.js | 8 +- ...cts_transactions_prepared_before_stable.js | 7 +- ...mit_transaction_before_stable_timestamp.js | 8 +- .../replsets/rollback_remote_cursor_retry.js | 7 +- ...llback_rename_collection_on_sync_source.js | 8 +- jstests/replsets/rollback_rename_count.js | 8 +- ...k_resumable_index_build_bulk_load_phase.js | 5 +- ...mable_index_build_bulk_load_phase_large.js | 5 +- ...mable_index_build_collection_scan_phase.js | 5 +- ...index_build_collection_scan_phase_large.js | 5 +- ...esumable_index_build_drain_writes_phase.js | 5 +- ...back_resumable_index_build_mixed_phases.js | 5 +- jstests/replsets/rollback_set_fcv.js | 4 +- jstests/replsets/rollback_test_control.js | 6 +- .../replsets/rollback_transactions_count.js | 8 +- ...back_unclean_shutdowns_parameter_obeyed.js | 8 +- .../rollback_unprepared_transactions.js | 6 +- ...rollback_via_refetch_commit_transaction.js | 5 +- jstests/replsets/rollbacktest_unittest.js | 8 +- .../tenant_migration_drop_collection.js | 2 +- .../replsets/unpin_history_after_rollback.js | 8 +- .../validate_fails_during_rollback.js | 8 +- .../create_indexes_with_tenant_migration.js | 6 +- .../findAndModify_with_tenant_migration.js | 6 +- .../multitenancy_rollback_crud_op.js | 6 +- ...n_concurrent_bulk_writes_against_mongoq.js | 6 +- .../change_stream_metadata_notifications.js | 7 +- jstests/sharding/change_streams.js | 10 +- jstests/sharding/change_streams_whole_db.js | 7 +- src/mongo/shell/replsettest.js | 9 +- src/mongo/shell/servers.js | 2 +- 109 files changed, 914 insertions(+), 802 deletions(-) create mode 100644 jstests/libs/parallelTester_module.js diff --git a/buildscripts/resmokelib/core/programs.py b/buildscripts/resmokelib/core/programs.py index ac6d0106148..f1bf970c5d5 100644 --- a/buildscripts/resmokelib/core/programs.py +++ b/buildscripts/resmokelib/core/programs.py @@ -283,10 +283,11 @@ def mongo_shell_program(logger, executable=None, connection_string=None, filenam eval_sb.append(str(kwargs.pop("eval"))) # Load a callback to check that the cluster-wide metadata is consistent. - eval_sb.append("await import('jstests/libs/override_methods/check_metadata_consistency.js');") + eval_sb.append('await import("jstests/libs/override_methods/check_metadata_consistency.js")') # Load this file to allow a callback to validate collections before shutting down mongod. - eval_sb.append("load('jstests/libs/override_methods/validate_collections_on_shutdown.js');") + eval_sb.append( + 'await import("jstests/libs/override_methods/validate_collections_on_shutdown.js")') # Load a callback to check UUID consistency before shutting down a ShardingTest. eval_sb.append( diff --git a/etc/evergreen_yml_components/definitions.yml b/etc/evergreen_yml_components/definitions.yml index 2a922f5a94c..6795fa547ca 100644 --- a/etc/evergreen_yml_components/definitions.yml +++ b/etc/evergreen_yml_components/definitions.yml @@ -4289,6 +4289,7 @@ tasks: num_files: 3 num_tasks: 5 npm_command: rollback-fuzzer + jstestfuzz_vars: --useEsModules suite: rollback_fuzzer # Rollback suites create indexes with majority of nodes not available for replication. So, disabling # index build commit quorum. @@ -4306,6 +4307,7 @@ tasks: num_files: 3 num_tasks: 5 npm_command: rollback-fuzzer + jstestfuzz_vars: --useEsModules suite: rollback_fuzzer # Rollback suites create indexes with majority of nodes not available for replication. So, disabling # index build commit quorum. @@ -4321,7 +4323,7 @@ tasks: <<: *jstestfuzz_config_vars num_files: 1 num_tasks: 4 - jstestfuzz_vars: --numLinesPerFile 300 --maxLinesBetweenEvents 50 + jstestfuzz_vars: --numLinesPerFile 300 --maxLinesBetweenEvents 50 --useEsModules npm_command: rollback-fuzzer suite: rollback_fuzzer_clean_shutdowns # Rollback suites create indexes with majority of nodes not available for replication. So, disabling @@ -4338,7 +4340,7 @@ tasks: <<: *jstestfuzz_config_vars num_files: 1 num_tasks: 4 - jstestfuzz_vars: --numLinesPerFile 300 --maxLinesBetweenEvents 50 + jstestfuzz_vars: --numLinesPerFile 300 --maxLinesBetweenEvents 50 --useEsModules npm_command: rollback-fuzzer suite: rollback_fuzzer_unclean_shutdowns # Rollback suites create indexes with majority of nodes not available for replication. So, disabling diff --git a/jstests/change_streams/lookup_post_image.js b/jstests/change_streams/lookup_post_image.js index dc472b3272c..1ef9e75a4c9 100644 --- a/jstests/change_streams/lookup_post_image.js +++ b/jstests/change_streams/lookup_post_image.js @@ -5,13 +5,10 @@ // do_not_wrap_aggregations_in_facets, // uses_multiple_connections, // ] -(function() { -"use strict"; - load("jstests/libs/change_stream_util.js"); load("jstests/libs/collection_drop_recreate.js"); // For assert[Drop|Create]Collection. load("jstests/libs/fixture_helpers.js"); // For FixtureHelpers. -load("jstests/replsets/libs/two_phase_drops.js"); // For 'TwoPhaseDropCollectionTest'. +import {TwoPhaseDropCollectionTest} from "jstests/replsets/libs/two_phase_drops.js"; const coll = assertDropAndRecreateCollection(db, "change_post_image"); const cst = new ChangeStreamTest(db); @@ -246,5 +243,4 @@ assert.eq(latestChange.operationType, "drop"); if (!isChangeStreamPassthrough()) { latestChange = cst.getOneChange(cursor, true); assert.eq(latestChange.operationType, "invalidate"); -} -}()); +} \ No newline at end of file diff --git a/jstests/change_streams/metadata_notifications.js b/jstests/change_streams/metadata_notifications.js index d25f5bd3aee..bc5e8587e05 100644 --- a/jstests/change_streams/metadata_notifications.js +++ b/jstests/change_streams/metadata_notifications.js @@ -5,11 +5,7 @@ // do_not_run_in_whole_cluster_passthrough, // requires_fcv_63, // ] -(function() { -"use strict"; - load("jstests/libs/change_stream_util.js"); // For ChangeStreamTest. -load('jstests/replsets/libs/two_phase_drops.js'); // For 'TwoPhaseDropCollectionTest'. load("jstests/libs/collection_drop_recreate.js"); // For assert[Drop|Create]Collection. load("jstests/libs/fixture_helpers.js"); // For isSharded. @@ -279,5 +275,4 @@ expectedChanges = [ cst.assertNextChangesEqual( {cursor: cursor, expectedChanges: expectedChanges, expectInvalidate: true}); -cst.cleanUp(); -}()); +cst.cleanUp(); \ No newline at end of file diff --git a/jstests/change_streams/whole_cluster_metadata_notifications.js b/jstests/change_streams/whole_cluster_metadata_notifications.js index 02164b0b682..efe2457f2b3 100644 --- a/jstests/change_streams/whole_cluster_metadata_notifications.js +++ b/jstests/change_streams/whole_cluster_metadata_notifications.js @@ -3,11 +3,8 @@ // collections will live on different shards. Majority read concern cannot be off with multi-shard // transactions, which is why this test needs the tag below. // @tags: [requires_majority_read_concern] -(function() { -"use strict"; - -load("jstests/libs/change_stream_util.js"); // For ChangeStreamTest. -load('jstests/replsets/libs/two_phase_drops.js'); // For 'TwoPhaseDropCollectionTest'. +load("jstests/libs/change_stream_util.js"); // For ChangeStreamTest. +import {TwoPhaseDropCollectionTest} from "jstests/replsets/libs/two_phase_drops.js"; load("jstests/libs/collection_drop_recreate.js"); // For assert[Drop|Create]Collection. load("jstests/libs/fixture_helpers.js"); // For FixtureHelpers. @@ -242,5 +239,4 @@ for (let collToInvalidate of [db1Coll, db2Coll]) { assert.eq(change.ns, {db: testDB.getName(), coll: collToInvalidate.getName()}); } -cst.cleanUp(); -}()); +cst.cleanUp(); \ No newline at end of file diff --git a/jstests/change_streams/whole_db_metadata_notifications.js b/jstests/change_streams/whole_db_metadata_notifications.js index 29fe3507c7b..5fd8a5fe8f7 100644 --- a/jstests/change_streams/whole_db_metadata_notifications.js +++ b/jstests/change_streams/whole_db_metadata_notifications.js @@ -2,11 +2,8 @@ // Do not run in whole-cluster passthrough since this test assumes that the change stream will be // invalidated by a database drop. // @tags: [do_not_run_in_whole_cluster_passthrough] -(function() { -"use strict"; - -load("jstests/libs/change_stream_util.js"); // For ChangeStreamTest -load('jstests/replsets/libs/two_phase_drops.js'); // For 'TwoPhaseDropCollectionTest'. +load("jstests/libs/change_stream_util.js"); // For ChangeStreamTest +import {TwoPhaseDropCollectionTest} from "jstests/replsets/libs/two_phase_drops.js"; load("jstests/libs/collection_drop_recreate.js"); // For assert[Drop|Create]Collection. load("jstests/libs/fixture_helpers.js"); // For FixtureHelpers. @@ -212,5 +209,4 @@ assert.soon(() => { }); assert.eq(resumeStream.getResumeToken(), invalidateEvent[0]._id); -cst.cleanUp(); -}()); +cst.cleanUp(); \ No newline at end of file diff --git a/jstests/concurrency/fsm_libs/cluster.js b/jstests/concurrency/fsm_libs/cluster.js index e5884f59161..cc5851b9732 100644 --- a/jstests/concurrency/fsm_libs/cluster.js +++ b/jstests/concurrency/fsm_libs/cluster.js @@ -1,12 +1,10 @@ -'use strict'; - /** * Represents a MongoDB cluster. */ -load('jstests/hooks/validate_collections.js'); // For validateCollections. +import {validateCollections} from "jstests/hooks/validate_collections.js"; load('jstests/concurrency/fsm_libs/shard_fixture.js'); // For FSMShardingTest. -var Cluster = function(options) { +export const Cluster = function(options) { if (!(this instanceof Cluster)) { return new Cluster(options); } diff --git a/jstests/concurrency/fsm_libs/resmoke_runner.js b/jstests/concurrency/fsm_libs/resmoke_runner.js index bf3461cda63..d13be37db80 100644 --- a/jstests/concurrency/fsm_libs/resmoke_runner.js +++ b/jstests/concurrency/fsm_libs/resmoke_runner.js @@ -1,7 +1,7 @@ -'use strict'; - -load('jstests/concurrency/fsm_libs/runner.js'); // for runner.internals -load('jstests/libs/discover_topology.js'); // For Topology and DiscoverTopology. +import {Cluster} from "jstests/concurrency/fsm_libs/cluster.js"; +import {runner} from "jstests/concurrency/fsm_libs/runner.js"; +import {ThreadManager} from "jstests/concurrency/fsm_libs/thread_mgr.js"; +load('jstests/libs/discover_topology.js'); // For Topology and DiscoverTopology. const validateExecutionOptions = runner.internals.validateExecutionOptions; const prepareCollections = runner.internals.prepareCollections; diff --git a/jstests/concurrency/fsm_libs/runner.js b/jstests/concurrency/fsm_libs/runner.js index ec6e0e17491..577ab5783e0 100644 --- a/jstests/concurrency/fsm_libs/runner.js +++ b/jstests/concurrency/fsm_libs/runner.js @@ -1,12 +1,10 @@ -'use strict'; - load('jstests/concurrency/fsm_libs/assert.js'); -load('jstests/concurrency/fsm_libs/cluster.js'); +import {Cluster} from "jstests/concurrency/fsm_libs/cluster.js"; load('jstests/concurrency/fsm_libs/parse_config.js'); -load('jstests/concurrency/fsm_libs/thread_mgr.js'); +import {ThreadManager} from "jstests/concurrency/fsm_libs/thread_mgr.js"; load('jstests/concurrency/fsm_utils/name_utils.js'); // for uniqueCollName and uniqueDBName -var runner = (function() { +export const runner = (function() { function validateExecutionMode(mode) { var allowedKeys = ['composed', 'parallel', 'serial']; @@ -705,6 +703,6 @@ var runner = (function() { }; })(); -var runWorkloadsSerially = runner.serial; -var runWorkloadsInParallel = runner.parallel; -var runCompositionOfWorkloads = runner.composed; +export const runWorkloadsSerially = runner.serial; +export const runWorkloadsInParallel = runner.parallel; +export const runCompositionOfWorkloads = runner.composed; diff --git a/jstests/concurrency/fsm_libs/thread_mgr.js b/jstests/concurrency/fsm_libs/thread_mgr.js index 3456746d6b6..71b8834e591 100644 --- a/jstests/concurrency/fsm_libs/thread_mgr.js +++ b/jstests/concurrency/fsm_libs/thread_mgr.js @@ -1,13 +1,13 @@ -'use strict'; - -load('jstests/libs/parallelTester.js'); // for Thread and CountDownLatch -load('jstests/concurrency/fsm_libs/worker_thread.js'); // for workerThread +load('jstests/libs/parallelTester.js'); // for Thread and CountDownLatch +import {workerThread} from "jstests/concurrency/fsm_libs/worker_thread.js"; /** * Helper for spawning and joining worker threads. */ -var ThreadManager = function(clusterOptions, executionMode = {composed: false}) { +export const ThreadManager = function(clusterOptions, executionMode = { + composed: false +}) { if (!(this instanceof ThreadManager)) { return new ThreadManager(clusterOptions, executionMode); } @@ -196,9 +196,9 @@ var ThreadManager = function(clusterOptions, executionMode = {composed: false}) * workload and a composition of them, respectively. */ -workerThread.fsm = function(workloads, args, options) { - load('jstests/concurrency/fsm_libs/worker_thread.js'); // for workerThread.main - load('jstests/concurrency/fsm_libs/fsm.js'); // for fsm.run +workerThread.fsm = async function(workloads, args, options) { + const {workerThread} = await import("jstests/concurrency/fsm_libs/worker_thread.js"); + load('jstests/concurrency/fsm_libs/fsm.js'); // for fsm.run return workerThread.main(workloads, args, function(configs) { var workloads = Object.keys(configs); @@ -207,9 +207,9 @@ workerThread.fsm = function(workloads, args, options) { }); }; -workerThread.composed = function(workloads, args, options) { - load('jstests/concurrency/fsm_libs/worker_thread.js'); // for workerThread.main - load('jstests/concurrency/fsm_libs/composer.js'); // for composer.run +workerThread.composed = async function(workloads, args, options) { + const {workerThread} = await import("jstests/concurrency/fsm_libs/worker_thread.js"); + load('jstests/concurrency/fsm_libs/composer.js'); // for composer.run return workerThread.main(workloads, args, function(configs) { composer.run(workloads, configs, options); diff --git a/jstests/concurrency/fsm_libs/worker_thread.js b/jstests/concurrency/fsm_libs/worker_thread.js index deeeb83e141..cdc0a040ac3 100644 --- a/jstests/concurrency/fsm_libs/worker_thread.js +++ b/jstests/concurrency/fsm_libs/worker_thread.js @@ -1,11 +1,9 @@ -'use strict'; - load('jstests/concurrency/fsm_libs/assert.js'); -load('jstests/concurrency/fsm_libs/cluster.js'); // for Cluster.isStandalone +import {Cluster} from "jstests/concurrency/fsm_libs/cluster.js"; load('jstests/concurrency/fsm_libs/parse_config.js'); // for parseConfig load('jstests/libs/specific_secondary_reader_mongo.js'); -var workerThread = (function() { +export const workerThread = (function() { // workloads = list of workload filenames // args.tid = the thread identifier // args.data = map of workload -> 'this' parameter passed to the FSM state functions diff --git a/jstests/hooks/run_initial_sync_node_validation.js b/jstests/hooks/run_initial_sync_node_validation.js index 935e9d46bc5..e81b2a37d17 100644 --- a/jstests/hooks/run_initial_sync_node_validation.js +++ b/jstests/hooks/run_initial_sync_node_validation.js @@ -1,8 +1,5 @@ // Runner that runs full validation on all collections of the initial sync node and checks the // dbhashes of all of the nodes including the initial sync node. -'use strict'; - -(function() { var startTime = Date.now(); var primaryInfo = db.isMaster(); @@ -42,8 +39,7 @@ assert.eq(res.myState, ReplSetTest.State.SECONDARY, tojson(res)); const excludedDBs = jsTest.options().excludedDBsFromDBHash; rst.checkReplicatedDataHashes(undefined, excludedDBs); -load('jstests/hooks/run_validate_collections.js'); +await import("jstests/hooks/run_validate_collections.js"); var totalTime = Date.now() - startTime; print('Finished consistency checks of initial sync node in ' + totalTime + ' ms.'); -})(); diff --git a/jstests/hooks/run_validate_collections.js b/jstests/hooks/run_validate_collections.js index 3a4880b7192..7818f226cba 100644 --- a/jstests/hooks/run_validate_collections.js +++ b/jstests/hooks/run_validate_collections.js @@ -1,10 +1,8 @@ // Runner for validateCollections that runs full validation on all collections when loaded into // the mongo shell. -'use strict'; -(function() { -load('jstests/libs/discover_topology.js'); // For Topology and DiscoverTopology. -load('jstests/hooks/validate_collections.js'); // For CollectionValidator. +import {CollectionValidator} from "jstests/hooks/validate_collections.js"; +load('jstests/libs/discover_topology.js'); // For Topology and DiscoverTopology. assert.eq(typeof db, 'object', 'Invalid `db` object, is the shell connected to a mongod?'); const topology = DiscoverTopology.findConnectedNodes(db.getMongo()); @@ -93,4 +91,3 @@ if (originalTransactionLifetimeLimitSeconds) { conn.adminCommand({setParameter: 1, transactionLifetimeLimitSeconds: originalValue})); } } -})(); diff --git a/jstests/hooks/validate_collections.js b/jstests/hooks/validate_collections.js index 70459c59141..4ee214f50a2 100644 --- a/jstests/hooks/validate_collections.js +++ b/jstests/hooks/validate_collections.js @@ -1,151 +1,19 @@ // Wrapper around the validate command that can be used to validate index key counts. -'use strict'; +import {Thread} from "jstests/libs/parallelTester_module.js"; -function CollectionValidator() { - load('jstests/libs/parallelTester.js'); - - if (!(this instanceof CollectionValidator)) { - throw new Error('Please use "new CollectionValidator()"'); +export class CollectionValidator { + validateCollections(db, obj) { + return validateCollectionsImpl(db, obj); } - this.validateCollections = function(db, obj) { - function dumpCollection(coll, limit) { - print('Printing indexes in: ' + coll.getFullName()); - printjson(coll.getIndexes()); - - print('Printing the first ' + limit + ' documents in: ' + coll.getFullName()); - const res = coll.find().limit(limit); - while (res.hasNext()) { - printjson(res.next()); - } - } - - assert.eq(typeof db, 'object', 'Invalid `db` object, is the shell connected to a mongod?'); - assert.eq(typeof obj, 'object', 'The `obj` argument must be an object'); - assert(obj.hasOwnProperty('full'), 'Please specify whether to use full validation'); - - // Failed collection validation results are saved in failed_res. - let full_res = {ok: 1, failed_res: []}; - - // Don't run validate on view namespaces. - let filter = {type: 'collection'}; - if (jsTest.options().skipValidationOnInvalidViewDefinitions) { - // If skipValidationOnInvalidViewDefinitions=true, then we avoid resolving the view - // catalog on the admin database. - // - // TODO SERVER-25493: Remove the $exists clause once performing an initial sync from - // versions of MongoDB <= 3.2 is no longer supported. - filter = {$or: [filter, {type: {$exists: false}}]}; - } - - // Optionally skip collections. - if (Array.isArray(jsTest.options().skipValidationNamespaces) && - jsTest.options().skipValidationNamespaces.length > 0) { - let skippedCollections = []; - for (let ns of jsTest.options().skipValidationNamespaces) { - // Attempt to strip the name of the database we are about to validate off of the - // namespace we wish to skip. If the replace() function does find a match with the - // database, then we know that the collection we want to skip is in the database we - // are about to validate. We will then put it in the 'filter' for later use. - const collName = ns.replace(new RegExp('^' + db.getName() + '\.'), ''); - if (collName !== ns) { - skippedCollections.push({name: {$ne: collName}}); - } - } - filter = {$and: [filter, ...skippedCollections]}; - } - - let collInfo = db.getCollectionInfos(filter); - for (let collDocument of collInfo) { - const coll = db.getCollection(collDocument['name']); - const res = coll.validate(obj); - - if (!res.ok || !res.valid) { - if (jsTest.options().skipValidationOnNamespaceNotFound && - res.codeName === "NamespaceNotFound") { - // During a 'stopStart' backup/restore on the secondary node, the actual list of - // collections can be out of date if ops are still being applied from the oplog. - // In this case we skip the collection if the ns was not found at time of - // validation and continue to next. - print('Skipping collection validation for ' + coll.getFullName() + - ' since collection was not found'); - continue; - } else if (res.codeName === "CommandNotSupportedOnView") { - // Even though we pass a filter to getCollectionInfos() to only fetch - // collections, nothing is preventing the collection from being dropped and - // recreated as a view. - print('Skipping collection validation for ' + coll.getFullName() + - ' as it is a view'); - continue; - } - const host = db.getMongo().host; - print('Collection validation failed on host ' + host + - ' with response: ' + tojson(res)); - dumpCollection(coll, 100); - full_res.failed_res.push(res); - full_res.ok = 0; - } - } - - return full_res; - }; - - // Run a separate thread to validate collections on each server in parallel. - const validateCollectionsThread = function(validatorFunc, host) { - try { - print('Running validate() on ' + host); - const conn = new Mongo(host); - conn.setSecondaryOk(); - jsTest.authenticate(conn); - - // Skip validating collections for arbiters. - if (conn.getDB('admin').isMaster('admin').arbiterOnly === true) { - print('Skipping collection validation on arbiter ' + host); - return {ok: 1}; - } - - let requiredFCV = jsTest.options().forceValidationWithFeatureCompatibilityVersion; - if (requiredFCV) { - requiredFCV = new Function(`return typeof ${requiredFCV} === "string" ? ${ - requiredFCV} : "${requiredFCV}"`)(); - // Make sure this node has the desired FCV as it may take time for the updates to - // replicate to the nodes that weren't part of the w=majority. - assert.soonNoExcept(() => { - checkFCV(conn.getDB('admin'), requiredFCV); - return true; - }); - } - - const dbNames = conn.getDBNames(); - for (let dbName of dbNames) { - const validateRes = validatorFunc(conn.getDB(dbName), { - full: true, - // TODO (SERVER-24266): Always enforce fast counts, once they are always - // accurate. - enforceFastCount: - !TestData.skipEnforceFastCountOnValidate && !TestData.allowUncleanShutdowns, - }); - if (validateRes.ok !== 1) { - return {ok: 0, host: host, validateRes: validateRes}; - } - } - return {ok: 1}; - } catch (e) { - print('Exception caught in scoped thread running validationCollections on server: ' + - host); - return {ok: 0, error: e.toString(), stack: e.stack, host: host}; - } - }; - - this.validateNodes = function(hostList) { + validateNodes(hostList) { // We run the scoped threads in a try/finally block in case any thread throws an exception, // in which case we want to still join all the threads. let threads = []; try { hostList.forEach(host => { - const thread = - new Thread(validateCollectionsThread, this.validateCollections, host); + const thread = new Thread(validateCollectionsThread, validateCollectionsImpl, host); threads.push(thread); thread.start(); }); @@ -160,9 +28,137 @@ function CollectionValidator() { assert.commandWorked(res, 'Collection validation failed'); }); } - }; + } +} + +function validateCollectionsImpl(db, obj) { + function dumpCollection(coll, limit) { + print('Printing indexes in: ' + coll.getFullName()); + printjson(coll.getIndexes()); + + print('Printing the first ' + limit + ' documents in: ' + coll.getFullName()); + const res = coll.find().limit(limit); + while (res.hasNext()) { + printjson(res.next()); + } + } + + assert.eq(typeof db, 'object', 'Invalid `db` object, is the shell connected to a mongod?'); + assert.eq(typeof obj, 'object', 'The `obj` argument must be an object'); + assert(obj.hasOwnProperty('full'), 'Please specify whether to use full validation'); + + // Failed collection validation results are saved in failed_res. + let full_res = {ok: 1, failed_res: []}; + + // Don't run validate on view namespaces. + let filter = {type: 'collection'}; + if (jsTest.options().skipValidationOnInvalidViewDefinitions) { + // If skipValidationOnInvalidViewDefinitions=true, then we avoid resolving the view + // catalog on the admin database. + // + // TODO SERVER-25493: Remove the $exists clause once performing an initial sync from + // versions of MongoDB <= 3.2 is no longer supported. + filter = {$or: [filter, {type: {$exists: false}}]}; + } + + // Optionally skip collections. + if (Array.isArray(jsTest.options().skipValidationNamespaces) && + jsTest.options().skipValidationNamespaces.length > 0) { + let skippedCollections = []; + for (let ns of jsTest.options().skipValidationNamespaces) { + // Attempt to strip the name of the database we are about to validate off of the + // namespace we wish to skip. If the replace() function does find a match with the + // database, then we know that the collection we want to skip is in the database we + // are about to validate. We will then put it in the 'filter' for later use. + const collName = ns.replace(new RegExp('^' + db.getName() + '\.'), ''); + if (collName !== ns) { + skippedCollections.push({name: {$ne: collName}}); + } + } + filter = {$and: [filter, ...skippedCollections]}; + } + + let collInfo = db.getCollectionInfos(filter); + for (let collDocument of collInfo) { + const coll = db.getCollection(collDocument['name']); + const res = coll.validate(obj); + + if (!res.ok || !res.valid) { + if (jsTest.options().skipValidationOnNamespaceNotFound && + res.codeName === "NamespaceNotFound") { + // During a 'stopStart' backup/restore on the secondary node, the actual list of + // collections can be out of date if ops are still being applied from the oplog. + // In this case we skip the collection if the ns was not found at time of + // validation and continue to next. + print('Skipping collection validation for ' + coll.getFullName() + + ' since collection was not found'); + continue; + } else if (res.codeName === "CommandNotSupportedOnView") { + // Even though we pass a filter to getCollectionInfos() to only fetch + // collections, nothing is preventing the collection from being dropped and + // recreated as a view. + print('Skipping collection validation for ' + coll.getFullName() + + ' as it is a view'); + continue; + } + const host = db.getMongo().host; + print('Collection validation failed on host ' + host + + ' with response: ' + tojson(res)); + dumpCollection(coll, 100); + full_res.failed_res.push(res); + full_res.ok = 0; + } + } + + return full_res; +} + +// Run a separate thread to validate collections on each server in parallel. +function validateCollectionsThread(validatorFunc, host) { + try { + print('Running validate() on ' + host); + const conn = new Mongo(host); + conn.setSecondaryOk(); + jsTest.authenticate(conn); + + // Skip validating collections for arbiters. + if (conn.getDB('admin').isMaster('admin').arbiterOnly === true) { + print('Skipping collection validation on arbiter ' + host); + return {ok: 1}; + } + + let requiredFCV = jsTest.options().forceValidationWithFeatureCompatibilityVersion; + if (requiredFCV) { + requiredFCV = new Function( + `return typeof ${requiredFCV} === "string" ? ${requiredFCV} : "${requiredFCV}"`)(); + // Make sure this node has the desired FCV as it may take time for the updates to + // replicate to the nodes that weren't part of the w=majority. + assert.soonNoExcept(() => { + checkFCV(conn.getDB('admin'), requiredFCV); + return true; + }); + } + + const dbNames = conn.getDBNames(); + for (let dbName of dbNames) { + const validateRes = validatorFunc(conn.getDB(dbName), { + full: true, + // TODO (SERVER-24266): Always enforce fast counts, once they are always + // accurate. + enforceFastCount: + !TestData.skipEnforceFastCountOnValidate && !TestData.allowUncleanShutdowns, + }); + if (validateRes.ok !== 1) { + return {ok: 0, host: host, validateRes: validateRes}; + } + } + return {ok: 1}; + } catch (e) { + print('Exception caught in scoped thread running validationCollections on server: ' + host); + return {ok: 0, error: e.toString(), stack: e.stack, host: host}; + } } // Ensure compatibility with existing callers. Cannot use `const` or `let` here since this file may // be loaded more than once. -var validateCollections = new CollectionValidator().validateCollections; +export const validateCollections = new CollectionValidator().validateCollections; diff --git a/jstests/libs/command_sequence_with_retries.js b/jstests/libs/command_sequence_with_retries.js index 101f6136c09..cbda2e0f422 100644 --- a/jstests/libs/command_sequence_with_retries.js +++ b/jstests/libs/command_sequence_with_retries.js @@ -7,40 +7,41 @@ * * @param {Mongo} conn - a connection to the server */ -function CommandSequenceWithRetries(conn) { - "use strict"; - if (!(this instanceof CommandSequenceWithRetries)) { - return new CommandSequenceWithRetries(conn); +function attemptReconnect(conn) { + try { + conn.adminCommand({ping: 1}); + } catch (e) { + return false; + } + return true; +} + +export class CommandSequenceWithRetries { + constructor(conn) { + this.conn = conn; + this.steps = []; } - const steps = []; - - function attemptReconnect(conn) { - try { - conn.adminCommand({ping: 1}); - } catch (e) { - return false; - } - return true; - } - - this.then = function then(phase, action) { - steps.push({phase: phase, action: action}); + then(phase, action) { + this.steps.push({phase, action}); return this; - }; + } - this.execute = function execute() { + execute() { let i = 0; let stepHadNetworkErrorAlready = false; - while (i < steps.length) { + while (i < this.steps.length) { try { // Treat no explicit return statement inside the action function as returning // {shouldStop: false} for syntactic convenience. - const result = steps[i].action(conn); + const result = this.steps[i].action(this.conn); if (result !== undefined && result.shouldStop) { - return {ok: 0, msg: "giving up after " + steps[i].phase + ": " + result.reason}; + return { + ok: 0, + msg: "giving up after " + this.steps[i].phase + ": " + result.reason + }; } } catch (e) { if (!isNetworkError(e)) { @@ -54,15 +55,15 @@ function CommandSequenceWithRetries(conn) { if (stepHadNetworkErrorAlready) { return { ok: 0, - msg: "giving up after " + steps[i].phase + + msg: "giving up after " + this.steps[i].phase + " because we encountered multiple network errors" }; } - if (!attemptReconnect(conn)) { + if (!attemptReconnect(this.conn)) { return { ok: 0, - msg: "giving up after " + steps[i].phase + + msg: "giving up after " + this.steps[i].phase + " because attempting to reconnect failed" }; } @@ -76,5 +77,5 @@ function CommandSequenceWithRetries(conn) { } return {ok: 1}; - }; + } } diff --git a/jstests/libs/fsm_serial_client.js b/jstests/libs/fsm_serial_client.js index 97fc766b5fc..d4021a30d9e 100644 --- a/jstests/libs/fsm_serial_client.js +++ b/jstests/libs/fsm_serial_client.js @@ -1,7 +1,5 @@ // This is the template file used in Powercycle testing for launching FSM Serial clients. -'use strict'; - -load('jstests/concurrency/fsm_libs/runner.js'); +import {runWorkloadsSerially} from "jstests/concurrency/fsm_libs/runner.js"; var workloadDir = 'jstests/concurrency/fsm_workloads'; diff --git a/jstests/libs/override_methods/validate_collections_on_shutdown.js b/jstests/libs/override_methods/validate_collections_on_shutdown.js index a378d6e390a..497e8920ef4 100644 --- a/jstests/libs/override_methods/validate_collections_on_shutdown.js +++ b/jstests/libs/override_methods/validate_collections_on_shutdown.js @@ -3,17 +3,14 @@ * collections and indexes before shutting down a mongod while running JS tests. */ -(function() { -"use strict"; +import {validateCollections} from "jstests/hooks/validate_collections.js"; +import {CommandSequenceWithRetries} from "jstests/libs/command_sequence_with_retries.js"; -load("jstests/libs/command_sequence_with_retries.js"); // for CommandSequenceWithRetries - -MongoRunner.validateCollectionsCallback = function(port) { - // This function may be executed in a new Thread context, so ensure the proper definitions - // are loaded. - if (typeof CommandSequenceWithRetries === "undefined") { - load("jstests/libs/command_sequence_with_retries.js"); - } +MongoRunner.validateCollectionsCallback = function(port, options) { + options = options || {}; + const CommandSequenceWithRetriesImpl = + options.CommandSequenceWithRetries || CommandSequenceWithRetries; + const validateCollectionsImpl = options.validateCollections || validateCollections; if (jsTest.options().skipCollectionAndIndexValidation) { print("Skipping collection validation during mongod shutdown"); @@ -34,7 +31,7 @@ MongoRunner.validateCollectionsCallback = function(port) { let dbNames; let result = - new CommandSequenceWithRetries(conn) + new CommandSequenceWithRetriesImpl(conn) .then("running the isMaster command", function(conn) { const res = assert.commandWorked(conn.adminCommand({isMaster: 1})); @@ -119,9 +116,7 @@ MongoRunner.validateCollectionsCallback = function(port) { return; } - load('jstests/hooks/validate_collections.js'); // for validateCollections - - const cmds = new CommandSequenceWithRetries(conn); + const cmds = new CommandSequenceWithRetriesImpl(conn); for (let i = 0; i < dbNames.length; ++i) { const dbName = dbNames[i]; cmds.then("validating " + dbName, function(conn) { @@ -132,7 +127,7 @@ MongoRunner.validateCollectionsCallback = function(port) { validateOptions.enforceFastCount = false; } - const validate_res = validateCollections(conn.getDB(dbName), validateOptions); + const validate_res = validateCollectionsImpl(conn.getDB(dbName), validateOptions); if (!validate_res.ok) { return { shouldStop: true, @@ -144,4 +139,3 @@ MongoRunner.validateCollectionsCallback = function(port) { assert.commandWorked(cmds.execute()); }; -})(); diff --git a/jstests/libs/parallelTester_module.js b/jstests/libs/parallelTester_module.js new file mode 100644 index 00000000000..ff44fecf58f --- /dev/null +++ b/jstests/libs/parallelTester_module.js @@ -0,0 +1,465 @@ +/** + * The ParallelTester class is used to test more than one test concurrently + */ + +export var Thread, fork, EventGenerator, ParallelTester; + +if (typeof _threadInject != "undefined") { + // With --enableJavaScriptProtection functions are presented as Code objects. + // This function evals all the Code objects then calls the provided start function. + // arguments: [startFunction, startFunction args...] + function _threadStartWrapper(testData) { + // Recursively evals all the Code objects present in arguments + // NOTE: This is a naive implementation that cannot handle cyclic objects. + function evalCodeArgs(arg) { + if (arg instanceof Code) { + return eval("(" + arg.code + ")"); + } else if (arg !== null && isObject(arg)) { + var newArg = arg instanceof Array ? [] : {}; + for (var prop in arg) { + if (arg.hasOwnProperty(prop)) { + newArg[prop] = evalCodeArgs(arg[prop]); + } + } + return newArg; + } + return arg; + } + var realStartFn; + var newArgs = []; + // We skip the first argument, which is always TestData. + TestData = evalCodeArgs(testData); + for (var i = 1, l = arguments.length; i < l; i++) { + newArgs.push(evalCodeArgs(arguments[i])); + } + realStartFn = newArgs.shift(); + return realStartFn.apply(this, newArgs); + } + + Thread = function() { + var args = Array.prototype.slice.call(arguments); + // Always pass TestData as the first argument. + args.unshift(TestData); + args.unshift(_threadStartWrapper); + this.init.apply(this, args); + }; + _threadInject(Thread.prototype); + + fork = function() { + var t = new Thread(function() {}); + Thread.apply(t, arguments); + return t; + }; + + // Helper class to generate a list of events which may be executed by a ParallelTester + EventGenerator = function(me, collectionName, mean, host) { + this.mean = mean; + if (host == undefined) + host = db.getMongo().host; + this.events = new Array(me, collectionName, host); + }; + + EventGenerator.prototype._add = function(action) { + this.events.push([Random.genExp(this.mean), action]); + }; + + EventGenerator.prototype.addInsert = function(obj) { + this._add("t.insert( " + tojson(obj) + " )"); + }; + + EventGenerator.prototype.addRemove = function(obj) { + this._add("t.remove( " + tojson(obj) + " )"); + }; + + EventGenerator.prototype.addCurrentOp = function() { + this._add("db.currentOp()"); + }; + + EventGenerator.prototype.addUpdate = function(objOld, objNew) { + this._add("t.update( " + tojson(objOld) + ", " + tojson(objNew) + " )"); + }; + + EventGenerator.prototype.addCheckCount = function(count, query, shouldPrint, checkQuery) { + query = query || {}; + shouldPrint = shouldPrint || false; + checkQuery = checkQuery || false; + var action = "assert.eq( " + count + ", t.count( " + tojson(query) + " ) );"; + if (checkQuery) { + action += + " assert.eq( " + count + ", t.find( " + tojson(query) + " ).toArray().length );"; + } + if (shouldPrint) { + action += " print( me + ' ' + " + count + " );"; + } + this._add(action); + }; + + EventGenerator.prototype.getEvents = function() { + return this.events; + }; + + EventGenerator.dispatch = function() { + var args = Array.from(arguments); + var me = args.shift(); + var collectionName = args.shift(); + var host = args.shift(); + var m = new Mongo(host); + + // We define 'db' and 't' as local variables so that calling eval() on the stringified + // JavaScript expression 'args[i][1]' can take advantage of using them. + var db = m.getDB("test"); + var t = db[collectionName]; + for (var i in args) { + sleep(args[i][0]); + eval(args[i][1]); + } + }; + + // Helper class for running tests in parallel. It assembles a set of tests + // and then calls assert.parallelests to run them. + ParallelTester = function() { + this.params = new Array(); + }; + + ParallelTester.prototype.add = function(fun, args) { + args = args || []; + args.unshift(fun); + this.params.push(args); + }; + + ParallelTester.prototype.run = async function(msg) { + await assert.parallelTests(this.params, msg); + }; + + // creates lists of tests from jstests dir in a format suitable for use by + // ParallelTester.fileTester. The lists will be in random order. + // n: number of lists to split these tests into + ParallelTester.createJstestsLists = function(n) { + var params = new Array(); + for (var i = 0; i < n; ++i) { + params.push([]); + } + + var makeKeys = function(a) { + var ret = {}; + for (var i in a) { + ret[a[i]] = 1; + } + return ret; + }; + + // some tests can't run in parallel with most others + var skipTests = makeKeys([ + "index/indexb.js", + + // Tests that set a parameter that causes the server to ignore + // long index keys. + "index_bigkeys_nofail.js", + "index_bigkeys_validation.js", + + // Tests that set the notablescan parameter, which makes queries fail rather than use a + // non-indexed plan. + "notablescan.js", + "notablescan_capped.js", + + "query/mr/mr_fail_invalid_js.js", + "run_program1.js", + "bench_test1.js", + + // These tests use getLog to examine the logs. Tests which do so shouldn't be run in + // this suite because any test being run at the same time could conceivably spam the + // logs so much that the line they are looking for has been rotated off the server's + // in-memory buffer of log messages, which only stores the 1024 most recent operations. + "comment_field.js", + "administrative/getlog2.js", + "logprocessdetails.js", + "query/queryoptimizera.js", + "log_remote_op_wait.js", + + "connections_opened.js", // counts connections, globally + "opcounters_write_cmd.js", + "administrative/set_param1.js", // changes global state + "index/geo/geo_update_btree2.js", // SERVER-11132 test disables table scans + "write/update/update_setOnInsert.js", // SERVER-9982 + "max_time_ms.js", // Sensitive to query execution time, by design + "shell/autocomplete.js", // Likewise. + + // This overwrites MinKey/MaxKey's singleton which breaks + // any other test that uses MinKey/MaxKey + "query/type/type6.js", + + // Assumes that other tests are not creating cursors. + "kill_cursors.js", + + // Assumes that other tests are not starting operations. + "administrative/current_op/currentop_shell.js", + + // These tests check global command counters. + "write/find_and_modify/find_and_modify_metrics.js", + "write/update/update_metrics.js", + + // Views tests + "views/invalid_system_views.js", // Puts invalid view definitions in system.views. + "views/views_all_commands.js", // Drops test DB. + "views/view_with_invalid_dbname.js", // Puts invalid view definitions in system.views. + + // This test causes collMod commands to hang, which interferes with other tests running + // collMod. + "write/crud_ops_do_not_throw_locktimeout.js", + + // Can fail if isMaster takes too long on a loaded machine. + "dbadmin.js", + + // Other tests will fail while the requireApiVersion server parameter is set. + "require_api_version.js", + + // This sets the 'disablePipelineOptimization' failpoint, which causes other tests + // running in parallel to fail if they were expecting their pipelines to be optimized. + "type_bracket.js", + + // This test updates global memory usage counters in the bucket catalog in a way that + // may affect other time-series tests running concurrently. + "timeseries/timeseries_idle_buckets.js", + + // Assumes that other tests are not creating API version 1 incompatible data. + "administrative/validate_db_metadata_command.js", + + // The tests in 'bench_test*.js' files use 'benchRun()'. The main purpose of + // 'benchRun()' is for performance testing and the 'benchRun()' implementation itself + // launches multiple threads internally, it's not necessary to keep 'bench_test*.js' + // within the parallel test job. + "bench_test1.js", + "bench_test2.js", + + // These tests cause deletes and updates to hang, which may affect other tests running + // concurrently. + "timeseries/timeseries_delete_hint.js", + "timeseries/timeseries_update_hint.js", + "timeseries/timeseries_delete_concurrent.js", + "timeseries/timeseries_update_concurrent.js", + + // These tests rely on no writes happening that would force oplog truncation. + "write_change_stream_pit_preimage_in_transaction.js", + "write/write_change_stream_pit_preimage.js", + + // These tests convert a non-unique index to a unique one, which is not compatible + // when running against inMemory storage engine variants. Since this test only fails + // in the parallel tester, which does not respect test tags, we omit the tests + // instead of manually checking TestData values in the mongo shell for the Evergreen + // variant. + "ddl/collmod_convert_index_uniqueness.js", + "ddl/collmod_convert_to_unique_apply_ops.js", + "ddl/collmod_convert_to_unique_violations.js", + "ddl/collmod_convert_to_unique_violations_size_limit.js", + + // The parallel tester does not respect test tags, compact cannot run against the + // inMemory storage engine. + "timeseries/timeseries_compact.js", + + // These tests load 'sbe_assert_error_override.js' unconditionally, which causes + // failures in the parallel suite. + "computed_projections.js", + "query/project/projection_expr_mod.js", + ]); + + // Get files, including files in subdirectories. + var getFilesRecursive = function(dir) { + var files = listFiles(dir); + var fileList = []; + files.forEach(file => { + if (file.isDirectory) { + getFilesRecursive(file.name).forEach(subDirFile => fileList.push(subDirFile)); + } else { + fileList.push(file); + } + }); + return fileList; + }; + + // Transactions are not supported on standalone nodes so we do not run them here. + // NOTE: We need to take substring of the full test path to ensure that 'jstests/core/' is + // not included. + const txnsTestFiles = + getFilesRecursive("jstests/core/txns/") + .map(fullPathToTest => fullPathToTest.name.substring("jstests/core/".length)); + Object.assign(skipTests, makeKeys(txnsTestFiles)); + + var parallelFilesDir = "jstests/core"; + + // some tests can't be run in parallel with each other + var serialTestsArr = [ + // These tests use fsyncLock. + parallelFilesDir + "/fsync.js", + parallelFilesDir + "/administrative/current_op/currentop.js", + parallelFilesDir + "/ddl/killop_drop_collection.js", + + // These tests expect the profiler to be on or off at specific points. They should not + // be run in parallel with tests that perform fsyncLock. User operations skip writing to + // the system.profile collection while the server is fsyncLocked. + // + // Most profiler tests can be run in parallel with each other as they use test-specific + // databases, with the exception of tests which modify slowms or the profiler's sampling + // rate, since those affect profile settings globally. + parallelFilesDir + "/api/apitest_db_profile_level.js", + parallelFilesDir + "/index/geo/geo_s2cursorlimitskip.js", + parallelFilesDir + "/administrative/profile/profile1.js", + parallelFilesDir + "/administrative/profile/profile2.js", + parallelFilesDir + "/administrative/profile/profile3.js", + parallelFilesDir + "/administrative/profile/profile_agg.js", + parallelFilesDir + "/administrative/profile/profile_count.js", + parallelFilesDir + "/administrative/profile/profile_delete.js", + parallelFilesDir + "/administrative/profile/profile_distinct.js", + parallelFilesDir + "/administrative/profile/profile_find.js", + parallelFilesDir + "/administrative/profile/profile_findandmodify.js", + parallelFilesDir + "/administrative/profile/profile_getmore.js", + parallelFilesDir + "/administrative/profile/profile_hide_index.js", + parallelFilesDir + "/administrative/profile/profile_insert.js", + parallelFilesDir + "/administrative/profile/profile_list_collections.js", + parallelFilesDir + "/administrative/profile/profile_list_indexes.js", + parallelFilesDir + "/administrative/profile/profile_mapreduce.js", + parallelFilesDir + "/administrative/profile/profile_no_such_db.js", + parallelFilesDir + "/administrative/profile/profile_query_hash.js", + parallelFilesDir + "/administrative/profile/profile_sampling.js", + parallelFilesDir + "/administrative/profile/profile_update.js", + parallelFilesDir + "/query/plan_cache/cached_plan_trial_does_not_discard_work.js", + parallelFilesDir + "/sbe/from_plan_cache_flag.js", + parallelFilesDir + "/timeseries/bucket_unpacking_with_sort_plan_cache.js", + + // These tests rely on a deterministically refreshable logical session cache. If they + // run in parallel, they could interfere with the cache and cause failures. + parallelFilesDir + "/administrative/list_all_local_sessions.js", + parallelFilesDir + "/administrative/list_all_sessions.js", + parallelFilesDir + "/administrative/list_sessions.js", + ]; + var serialTests = makeKeys(serialTestsArr); + + // prefix the first thread with the serialTests + // (which we will exclude from the rest of the threads below) + params[0] = serialTestsArr; + var files = getFilesRecursive(parallelFilesDir); + files = Array.shuffle(files); + + var i = 0; + files.forEach(function(x) { + if ((/[\/\\]_/.test(x.name)) || (!/\.js$/.test(x.name)) || + (x.name.match(parallelFilesDir + "/(.*\.js)")[1] in skipTests) || // + (x.name in serialTests)) { + print(" >>>>>>>>>>>>>>> skipping " + x.name); + return; + } + // add the test to run in one of the threads. + params[i % n].push(x.name); + ++i; + }); + + // randomize ordering of the serialTests + params[0] = Array.shuffle(params[0]); + + for (var i in params) { + params[i].unshift(i); + } + + return params; + }; + + async function measureAsync(fn) { + const start = new Date(); + await fn.apply(null, Array.from(arguments).slice(2)); + return (new Date()).getTime() - start.getTime(); + } + + // runs a set of test files + // first argument is an identifier for this tester, remaining arguments are file names + ParallelTester.fileTester = async function() { + var args = Array.from(arguments); + var suite = args.shift(); + for (const x of args) { + print(" S" + suite + " Test : " + x + " ..."); + const time = await measureAsync(async function() { + // Create a new connection to the db for each file. If tests share the same + // connection it can create difficult to debug issues. + var db = new Mongo(db.getMongo().host).getDB(db.getName()); + gc(); + await import(x); + }); + print(" S" + suite + " Test : " + x + " " + time + "ms"); + } + }; + + // params: array of arrays, each element of which consists of a function followed + // by zero or more arguments to that function. Each function and its arguments will + // be called in a separate thread. + // msg: failure message + assert.parallelTests = function(params, msg) { + function wrapper(fun, argv, globals) { + if (globals.hasOwnProperty("TestData")) { + TestData = globals.TestData; + } + + try { + fun.apply(0, argv); + return {passed: true}; + } catch (e) { + print("\n********** Parallel Test FAILED: " + tojson(e) + "\n"); + return { + passed: false, + testName: tojson(e).match(/Error: error loading js file: (.*\.js)/)[1] + }; + } + } + + TestData.isParallelTest = true; + + var runners = new Array(); + for (var i in params) { + var param = params[i]; + var test = param.shift(); + + // Make a shallow copy of TestData so we can override the test name to + // prevent tests on different threads that to use jsTestName() as the + // collection name from colliding. + const clonedTestData = Object.assign({}, TestData); + clonedTestData.testName = `ParallelTesterThread${i}`; + var t = new Thread(wrapper, test, param, {TestData: clonedTestData}); + runners.push(t); + } + + runners.forEach(function(x) { + x.start(); + }); + var nFailed = 0; + var failedTests = []; + // SpiderMonkey doesn't like it if we exit before all threads are joined + // (see SERVER-19615 for a similar issue). + runners.forEach(function(x) { + if (!x.returnData().passed) { + ++nFailed; + failedTests.push(x.returnData().testName); + } + }); + msg += ": " + tojsononeline(failedTests); + assert.eq(0, nFailed, msg); + }; +} + +globalThis.CountDownLatch = Object.extend(function(count) { + if (!(this instanceof CountDownLatch)) { + return new CountDownLatch(count); + } + this._descriptor = CountDownLatch._new.apply(null, arguments); + + // NOTE: The following methods have to be defined on the instance itself, + // and not on its prototype. This is because properties on the + // prototype are lost during the serialization to BSON that occurs + // when passing data to a child thread. + + this.await = function() { + CountDownLatch._await(this._descriptor); + }; + this.countDown = function() { + CountDownLatch._countDown(this._descriptor); + }; + this.getCount = function() { + return CountDownLatch._getCount(this._descriptor); + }; +}, CountDownLatch); diff --git a/jstests/multiVersion/genericBinVersion/keystring_index.js b/jstests/multiVersion/genericBinVersion/keystring_index.js index 105e6937212..8c834b243be 100644 --- a/jstests/multiVersion/genericBinVersion/keystring_index.js +++ b/jstests/multiVersion/genericBinVersion/keystring_index.js @@ -22,9 +22,7 @@ * For each index type, a v1 unique, v2 unique, v1 non-unique and v2 non-unique index * is considered except for hashed and wildcard, which only consider the v2 non-unique case. */ -(function() { -'use strict'; -load('jstests/hooks/validate_collections.js'); +import {validateCollections} from "jstests/hooks/validate_collections.js"; const kNumDocs = 100; @@ -273,4 +271,3 @@ function insertDocumentsUnique(collection, numDocs, getDoc) { } assert.commandWorked(bulk.execute()); } -})(); diff --git a/jstests/multiVersion/genericBinVersion/rollback_capped_deletions.js b/jstests/multiVersion/genericBinVersion/rollback_capped_deletions.js index a477ba3fe1d..e0b413b4c2c 100644 --- a/jstests/multiVersion/genericBinVersion/rollback_capped_deletions.js +++ b/jstests/multiVersion/genericBinVersion/rollback_capped_deletions.js @@ -1,10 +1,8 @@ /** * Tests that capped collections get the correct fast counts after rollback in FCV 4.4. */ -(function() { -'use strict'; - -load("jstests/multiVersion/libs/multiversion_rollback.js"); +import {setupReplicaSet} from "jstests/multiVersion/libs/multiversion_rollback.js"; +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const testName = 'rollback_capped_deletions'; const dbName = testName; @@ -47,4 +45,3 @@ try { // The fast count checks occur when tearing down the fixture as part of the consistency checks. rollbackTest.stop(); -})(); diff --git a/jstests/multiVersion/genericSetFCVUsage/rollback_downgraded_to_latest.js b/jstests/multiVersion/genericSetFCVUsage/rollback_downgraded_to_latest.js index 3b18543ea7a..798919814f3 100644 --- a/jstests/multiVersion/genericSetFCVUsage/rollback_downgraded_to_latest.js +++ b/jstests/multiVersion/genericSetFCVUsage/rollback_downgraded_to_latest.js @@ -3,9 +3,7 @@ * downgraded version rollback node and a 'latest' version sync source. */ -(function() { -"use strict"; -load("jstests/multiVersion/libs/multiversion_rollback.js"); +import {testMultiversionRollback} from "jstests/multiVersion/libs/multiversion_rollback.js"; var testName = "multiversion_rollback_last_lts_to_latest"; jsTestLog("Testing multiversion rollback from last-lts to latest"); @@ -13,5 +11,4 @@ testMultiversionRollback(testName, "last-lts", "latest"); testName = "multiversion_rollback_last_continuous_to_latest"; jsTestLog("Testing multiversion rollback from last-continuous to latest"); -testMultiversionRollback(testName, "last-continuous", "latest"); -})(); +testMultiversionRollback(testName, "last-continuous", "latest"); \ No newline at end of file diff --git a/jstests/multiVersion/genericSetFCVUsage/rollback_latest_to_downgraded.js b/jstests/multiVersion/genericSetFCVUsage/rollback_latest_to_downgraded.js index 84b818421e3..1aaeebfe801 100644 --- a/jstests/multiVersion/genericSetFCVUsage/rollback_latest_to_downgraded.js +++ b/jstests/multiVersion/genericSetFCVUsage/rollback_latest_to_downgraded.js @@ -3,9 +3,7 @@ * 'latest' version rollback node and a downgraded version sync source. */ -(function() { -"use strict"; -load("jstests/multiVersion/libs/multiversion_rollback.js"); +import {testMultiversionRollback} from "jstests/multiVersion/libs/multiversion_rollback.js"; var testName = "multiversion_rollback_latest_to_last_lts"; jsTestLog("Testing multiversion rollback from latest to last-lts"); @@ -13,5 +11,4 @@ testMultiversionRollback(testName, "latest", "last-lts"); var testName = "multiversion_rollback_latest_to_last_continuous"; jsTestLog("Testing multiversion rollback from latest to last-continuous"); -testMultiversionRollback(testName, "latest", "last-continuous"); -})(); +testMultiversionRollback(testName, "latest", "last-continuous"); \ No newline at end of file diff --git a/jstests/multiVersion/genericSetFCVUsage/rollback_with_node_in_downgrading.js b/jstests/multiVersion/genericSetFCVUsage/rollback_with_node_in_downgrading.js index 87a4e1e2ae1..8e81fb07e86 100644 --- a/jstests/multiVersion/genericSetFCVUsage/rollback_with_node_in_downgrading.js +++ b/jstests/multiVersion/genericSetFCVUsage/rollback_with_node_in_downgrading.js @@ -4,9 +4,10 @@ * downgrading version rollback node and a lastLTS version sync source. */ -(function() { -"use strict"; -load("jstests/multiVersion/libs/multiversion_rollback.js"); +import { + testMultiversionRollbackDowngradingFromLastLTS, + testMultiversionRollbackLatestFromDowngrading, +} from "jstests/multiVersion/libs/multiversion_rollback.js"; let testName = "multiversion_rollback_latest_from_downgrading"; jsTestLog("Testing multiversion rollback with a node in latest syncing from a node in downgrading"); @@ -16,5 +17,4 @@ testMultiversionRollbackLatestFromDowngrading(testName, false /* upgradeImmediat testName = "multiversion_rollback_downgrading_from_last_lts"; jsTestLog( "Testing multiversion rollback with a node in downgrading syncing from a node in lastLTS"); -testMultiversionRollbackDowngradingFromLastLTS(testName); -})(); +testMultiversionRollbackDowngradingFromLastLTS(testName); \ No newline at end of file diff --git a/jstests/multiVersion/libs/multiversion_rollback.js b/jstests/multiVersion/libs/multiversion_rollback.js index 4507cc6abb9..0e53142ce6d 100644 --- a/jstests/multiVersion/libs/multiversion_rollback.js +++ b/jstests/multiVersion/libs/multiversion_rollback.js @@ -5,19 +5,17 @@ * exercise rollback via refetch in the case that refetch is necessary. */ -'use strict'; - -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; load("jstests/libs/collection_drop_recreate.js"); load('jstests/libs/parallel_shell_helpers.js'); load("jstests/libs/fail_point_util.js"); -function printFCVDoc(nodeAdminDB, logMessage) { +export function printFCVDoc(nodeAdminDB, logMessage) { const fcvDoc = nodeAdminDB.system.version.findOne({_id: 'featureCompatibilityVersion'}); jsTestLog(logMessage + ` ${tojson(fcvDoc)}`); } -function CommonOps(dbName, node) { +export function CommonOps(dbName, node) { // Insert four documents on both nodes. assert.commandWorked(node.getDB(dbName)["bothNodesKeep"].insert({a: 1})); assert.commandWorked(node.getDB(dbName)["rollbackNodeDeletes"].insert({b: 1})); @@ -25,7 +23,7 @@ function CommonOps(dbName, node) { assert.commandWorked(node.getDB(dbName)["bothNodesUpdate"].insert({d: 1})); } -function RollbackOps(dbName, node) { +export function RollbackOps(dbName, node) { // Perform operations only on the rollback node: // 1. Delete a document. // 2. Update a document only on this node. @@ -36,7 +34,7 @@ function RollbackOps(dbName, node) { assert.commandWorked(node.getDB(dbName)["bothNodesUpdate"].update({d: 1}, {d: 0})); } -function SyncSourceOps(dbName, node) { +export function SyncSourceOps(dbName, node) { // Perform operations only on the sync source: // 1. Make a conflicting write on one of the documents the rollback node updates. // 2. Insert a new document. @@ -52,7 +50,7 @@ function SyncSourceOps(dbName, node) { * @param {string} syncSourceVersion the desired version for the sync source * */ -function testMultiversionRollback(testName, rollbackNodeVersion, syncSourceVersion) { +export function testMultiversionRollback(testName, rollbackNodeVersion, syncSourceVersion) { jsTestLog("Started multiversion rollback test for versions: {rollbackNode: " + rollbackNodeVersion + ", syncSource: " + syncSourceVersion + "}."); @@ -82,7 +80,7 @@ function testMultiversionRollback(testName, rollbackNodeVersion, syncSourceVersi } // Test rollback between latest rollback node and downgrading sync node. -function testMultiversionRollbackLatestFromDowngrading(testName, upgradeImmediately) { +export function testMultiversionRollbackLatestFromDowngrading(testName, upgradeImmediately) { const dbName = testName; const replSet = new ReplSetTest( {name: testName, nodes: 3, useBridge: true, settings: {chainingAllowed: false}}); @@ -186,7 +184,7 @@ function testMultiversionRollbackLatestFromDowngrading(testName, upgradeImmediat } // Test rollback between downgrading rollback node and lastLTS sync node. -function testMultiversionRollbackDowngradingFromLastLTS(testName) { +export function testMultiversionRollbackDowngradingFromLastLTS(testName) { const dbName = testName; const replSet = new ReplSetTest( {name: testName, nodes: 3, useBridge: true, settings: {chainingAllowed: false}}); @@ -290,7 +288,7 @@ function testMultiversionRollbackDowngradingFromLastLTS(testName) { * @param {string} rollbackNodeVersion the desired version for the rollback node * @param {string} syncSourceVersion the desired version for the sync source */ -function setupReplicaSet(testName, rollbackNodeVersion, syncSourceVersion) { +export function setupReplicaSet(testName, rollbackNodeVersion, syncSourceVersion) { jsTestLog( `[${testName}] Beginning cluster setup with versions: {rollbackNode: ${rollbackNodeVersion}, syncSource: ${syncSourceVersion}}.`); diff --git a/jstests/noPassthrough/capped_deletes_within_rollback.js b/jstests/noPassthrough/capped_deletes_within_rollback.js index c373f32c7a9..6c415b7b985 100644 --- a/jstests/noPassthrough/capped_deletes_within_rollback.js +++ b/jstests/noPassthrough/capped_deletes_within_rollback.js @@ -5,10 +5,7 @@ * requires_replication, * ] */ -(function() { -'use strict'; - -load('jstests/replsets/libs/rollback_test.js'); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const rollbackTest = new RollbackTest(jsTestName()); @@ -35,5 +32,4 @@ rollbackTest.transitionToSteadyStateOperations(); // Stopping the test fixture runs validate with {enforceFastCount: true}. This will cause collection // validation to fail if rollback did not perform capped deletes on documents that were inserted // earlier in rollback. -rollbackTest.stop(); -})(); +rollbackTest.stop(); \ No newline at end of file diff --git a/jstests/noPassthrough/data_consistency_checks.js b/jstests/noPassthrough/data_consistency_checks.js index f49e64a1ed2..b45ea2537a2 100644 --- a/jstests/noPassthrough/data_consistency_checks.js +++ b/jstests/noPassthrough/data_consistency_checks.js @@ -8,12 +8,6 @@ * ] */ -// The global 'db' variable is used by the data consistency hooks. -var db; - -(function() { -"use strict"; - // We skip doing the data consistency checks while terminating the cluster because they conflict // with the counts of the number of times the "dbhash" and "validate" commands are run. TestData.skipCollectionAndIndexValidation = true; @@ -42,24 +36,27 @@ function countMatches(pattern, output) { return numMatches; } -function runDataConsistencyChecks(testCase) { - db = testCase.conn.getDB("test"); - try { - clearRawMongoProgramOutput(); +async function runDataConsistencyChecks(testCase) { + clearRawMongoProgramOutput(); + // NOTE: once modules are imported they are cached, so we need to run this in a parallel shell. + const awaitShell = startParallelShell(async function() { + globalThis.db = db.getSiblingDB("test"); load("jstests/hooks/run_check_repl_dbhash.js"); - load("jstests/hooks/run_validate_collections.js"); + await import("jstests/hooks/run_validate_collections.js"); + }, testCase.conn.port); - // We terminate the processes to ensure that the next call to rawMongoProgramOutput() - // will return all of their output. - testCase.teardown(); - return rawMongoProgramOutput(); - } finally { - db = undefined; - } + awaitShell(); + const output = rawMongoProgramOutput(); + + // We terminate the processes to ensure that the next call to rawMongoProgramOutput() + // will return all of their output. + testCase.teardown(); + + return output; } -(function testReplicaSetWithVotingSecondaries() { +await (async function testReplicaSetWithVotingSecondaries() { const numNodes = 2; const rst = new ReplSetTest({ nodes: numNodes, @@ -72,7 +69,8 @@ function runDataConsistencyChecks(testCase) { // Insert a document so the "dbhash" and "validate" commands have some actual work to do. assert.commandWorked(rst.nodes[0].getDB("test").mycoll.insert({})); - const output = runDataConsistencyChecks({conn: rst.nodes[0], teardown: () => rst.stopSet()}); + const output = + await runDataConsistencyChecks({conn: rst.nodes[0], teardown: () => rst.stopSet()}); let pattern = makePatternForDBHash("test"); assert.eq(numNodes, @@ -85,7 +83,7 @@ function runDataConsistencyChecks(testCase) { "expected to find " + tojson(pattern) + " from each node in the log output"); })(); -(function testReplicaSetWithNonVotingSecondaries() { +await (async function testReplicaSetWithNonVotingSecondaries() { const numNodes = 2; const rst = new ReplSetTest({ nodes: numNodes, @@ -104,7 +102,8 @@ function runDataConsistencyChecks(testCase) { // Insert a document so the "dbhash" and "validate" commands have some actual work to do. assert.commandWorked(rst.nodes[0].getDB("test").mycoll.insert({})); - const output = runDataConsistencyChecks({conn: rst.nodes[0], teardown: () => rst.stopSet()}); + const output = + await runDataConsistencyChecks({conn: rst.nodes[0], teardown: () => rst.stopSet()}); let pattern = makePatternForDBHash("test"); assert.eq(numNodes, @@ -117,7 +116,7 @@ function runDataConsistencyChecks(testCase) { "expected to find " + tojson(pattern) + " from each node in the log output"); })(); -(function testShardedClusterWithOneNodeCSRS() { +await (async function testShardedClusterWithOneNodeCSRS() { const st = new ShardingTest({ mongos: 1, config: 1, @@ -131,7 +130,7 @@ function runDataConsistencyChecks(testCase) { // database exists for when we go to run the data consistency checks against the CSRS. st.shardColl(st.s.getDB("test").mycoll, {_id: 1}, false); - const output = runDataConsistencyChecks({conn: st.s, teardown: () => st.stop()}); + const output = await runDataConsistencyChecks({conn: st.s, teardown: () => st.stop()}); let pattern = makePatternForDBHash("config"); assert.eq(0, @@ -147,7 +146,7 @@ function runDataConsistencyChecks(testCase) { "expected to find " + tojson(pattern) + " in the log output for 1-node CSRS"); })(); -(function testShardedCluster() { +await (async function testShardedCluster() { const st = new ShardingTest({ mongos: 1, config: 3, @@ -168,7 +167,7 @@ function runDataConsistencyChecks(testCase) { // Insert a document so the "dbhash" and "validate" commands have some actual work to do on // the replica set shard. assert.commandWorked(st.s.getDB("test").mycoll.insert({_id: 0})); - const output = runDataConsistencyChecks({conn: st.s, teardown: () => st.stop()}); + const output = await runDataConsistencyChecks({conn: st.s, teardown: () => st.stop()}); // The "config" database exists on both the CSRS and the replica set shards due to the // "config.transactions" collection. @@ -198,4 +197,3 @@ function runDataConsistencyChecks(testCase) { "expected to find " + tojson(pattern) + " from each replica set shard node in the log output"); })(); -})(); diff --git a/jstests/noPassthrough/drop_create_rollback.js b/jstests/noPassthrough/drop_create_rollback.js index f28d3d07ef9..f8865ffe1e9 100644 --- a/jstests/noPassthrough/drop_create_rollback.js +++ b/jstests/noPassthrough/drop_create_rollback.js @@ -5,14 +5,11 @@ * requires_replication, * ] */ -(function() { -'use strict'; - TestData.rollbackShutdowns = true; TestData.logComponentVerbosity = { storage: {recovery: 2} }; -load('jstests/replsets/libs/rollback_test.js'); +const {RollbackTest} = await import("jstests/replsets/libs/rollback_test.js"); const rollbackTest = new RollbackTest(); let primary = rollbackTest.getPrimary(); @@ -51,4 +48,3 @@ rollbackTest.transitionToSteadyStateOperations(); assert.contains("timestamped", rollbackNode.getDB("foo").getCollectionNames()); assert.contains("untimestamped", rollbackNode.getDB("local").getCollectionNames()); rollbackTest.stop(); -})(); diff --git a/jstests/noPassthrough/rollback_wt_drop.js b/jstests/noPassthrough/rollback_wt_drop.js index a87e54a1c09..188c4d145aa 100644 --- a/jstests/noPassthrough/rollback_wt_drop.js +++ b/jstests/noPassthrough/rollback_wt_drop.js @@ -5,10 +5,8 @@ * requires_wiredtiger, * ] */ -(function() { -'use strict'; - -load('jstests/replsets/libs/rollback_test.js'); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; +import {TwoPhaseDropCollectionTest} from "jstests/replsets/libs/two_phase_drops.js"; // Returns list of collections in database, including pending drops. // Assumes all collections fit in first batch of results. @@ -148,4 +146,3 @@ assert.eq(2, noOpsToRollbackColl.find().itcount()); assert.eq(2, noOpsToRollbackColl.count()); rollbackTest.stop(); -})(); diff --git a/jstests/noPassthrough/timeseries_extended_range_rollback.js b/jstests/noPassthrough/timeseries_extended_range_rollback.js index 4e36ec9eaf7..b318e7bf2c7 100644 --- a/jstests/noPassthrough/timeseries_extended_range_rollback.js +++ b/jstests/noPassthrough/timeseries_extended_range_rollback.js @@ -5,10 +5,7 @@ * requires_replication, * ] */ -(function() { -'use strict'; - -load('jstests/replsets/libs/rollback_test.js'); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const getExtendedRangeCount = (db) => { return assert.commandWorked(db.adminCommand({serverStatus: 1})) @@ -67,5 +64,4 @@ rollbackTest.transitionToSteadyStateOperations(); // Make sure the collections get flagged properly again during rollback. assert.eq(1, getExtendedRangeCount(rollbackNode)); -rollbackTest.stop(); -})(); +rollbackTest.stop(); \ No newline at end of file diff --git a/jstests/noPassthrough/timeseries_insert_rollback.js b/jstests/noPassthrough/timeseries_insert_rollback.js index 8b90c8ecdf1..06c521ce076 100644 --- a/jstests/noPassthrough/timeseries_insert_rollback.js +++ b/jstests/noPassthrough/timeseries_insert_rollback.js @@ -6,10 +6,7 @@ * requires_replication, * ] */ -(function() { -'use strict'; - -load('jstests/replsets/libs/rollback_test.js'); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const rollbackTest = new RollbackTest(jsTestName()); @@ -57,5 +54,4 @@ assert.sameMembers(docs.slice(2), coll.find().toArray()); const buckets = bucketsColl.find().toArray(); assert.eq(buckets.length, 2, 'Expected two bucket but found: ' + tojson(buckets)); -rollbackTest.stop(); -})(); +rollbackTest.stop(); \ No newline at end of file diff --git a/jstests/noPassthrough/validate_hook_resume_fcv_upgrade.js b/jstests/noPassthrough/validate_hook_resume_fcv_upgrade.js index 18d9510c240..f8c4339db16 100644 --- a/jstests/noPassthrough/validate_hook_resume_fcv_upgrade.js +++ b/jstests/noPassthrough/validate_hook_resume_fcv_upgrade.js @@ -4,12 +4,6 @@ * the isCleaningServerMetadata state, where we must complete the downgrade before upgrading). */ -// The global 'db' variable is used by the data consistency hooks. -var db; - -(function() { -"use strict"; - // We skip doing the data consistency checks while terminating the cluster because they conflict // with the counts of the number of times the "validate" command is run. TestData.skipCollectionAndIndexValidation = true; @@ -43,25 +37,27 @@ function countMatches(pattern, output) { return numMatches; } -function runValidateHook(testCase) { - db = testCase.conn.getDB("test"); - TestData.forceValidationWithFeatureCompatibilityVersion = latestFCV; - try { - clearRawMongoProgramOutput(); +async function runValidateHook(testCase) { + clearRawMongoProgramOutput(); - load("jstests/hooks/run_validate_collections.js"); + // NOTE: once modules are imported they are cached, so we need to run this in a parallel shell. + const awaitShell = startParallelShell(async function() { + globalThis.db = db.getSiblingDB("test"); + TestData.forceValidationWithFeatureCompatibilityVersion = latestFCV; + await import("jstests/hooks/run_validate_collections.js"); + }, testCase.conn.port); - // We terminate the processes to ensure that the next call to rawMongoProgramOutput() - // will return all of their output. - testCase.teardown(); - return rawMongoProgramOutput(); - } finally { - db = undefined; - TestData.forceValidationWithFeatureCompatibilityVersion = undefined; - } + awaitShell(); + const output = rawMongoProgramOutput(); + + // We terminate the processes to ensure that the next call to rawMongoProgramOutput() + // will return all of their output. + testCase.teardown(); + + return output; } -function testStandalone(additionalSetupFn, { +async function testStandalone(additionalSetupFn, { expectedAtTeardownFCV, expectedSetLastLTSFCV: expectedSetLastLTSFCV = 0, expectedSetLatestFCV: expectedSetLatestFCV = 0 @@ -76,7 +72,7 @@ function testStandalone(additionalSetupFn, { // Run the additional setup function to put the server into the desired state. additionalSetupFn(conn); - const output = runValidateHook({ + const output = await runValidateHook({ conn: conn, teardown: () => { // The validate hook should leave the server with a feature compatibility version of @@ -185,31 +181,25 @@ function forceInterruptedUpgradeOrDowngrade(conn, targetVersion) { })); } -(function testStandaloneInLatestFCV() { - testStandalone(conn => { - checkFCV(conn.getDB("admin"), latestFCV); - }, {expectedAtTeardownFCV: latestFCV}); -})(); +// testStandaloneInLatestFCV +await testStandalone(conn => checkFCV(conn.getDB("admin"), latestFCV), + {expectedAtTeardownFCV: latestFCV}); -(function testStandaloneInLastLTSFCV() { - testStandalone(conn => { - assert.commandWorked( - conn.adminCommand({setFeatureCompatibilityVersion: lastLTSFCV, confirm: true})); - checkFCV(conn.getDB("admin"), lastLTSFCV); - }, {expectedAtTeardownFCV: lastLTSFCV, expectedSetLastLTSFCV: 1, expectedSetLatestFCV: 1}); -})(); +// testStandaloneInLastLTSFCV +await testStandalone(conn => { + assert.commandWorked( + conn.adminCommand({setFeatureCompatibilityVersion: lastLTSFCV, confirm: true})); + checkFCV(conn.getDB("admin"), lastLTSFCV); +}, {expectedAtTeardownFCV: lastLTSFCV, expectedSetLastLTSFCV: 1, expectedSetLatestFCV: 1}); -(function testStandaloneWithInterruptedFCVDowngrade() { - testStandalone(conn => { - forceInterruptedUpgradeOrDowngrade(conn, lastLTSFCV); - }, {expectedAtTeardownFCV: lastLTSFCV, expectedSetLastLTSFCV: 2, expectedSetLatestFCV: 1}); -})(); +// testStandaloneWithInterruptedFCVDowngrade +await testStandalone(conn => { + forceInterruptedUpgradeOrDowngrade(conn, lastLTSFCV); +}, {expectedAtTeardownFCV: lastLTSFCV, expectedSetLastLTSFCV: 2, expectedSetLatestFCV: 1}); -(function testStandaloneWithInterruptedFCVUpgrade() { - testStandalone(conn => { - assert.commandWorked( - conn.adminCommand({setFeatureCompatibilityVersion: lastLTSFCV, confirm: true})); - forceInterruptedUpgradeOrDowngrade(conn, latestFCV); - }, {expectedAtTeardownFCV: lastLTSFCV, expectedSetLastLTSFCV: 1, expectedSetLatestFCV: 1}); -})(); -})(); +// testStandaloneWithInterruptedFCVUpgrade +await testStandalone(conn => { + assert.commandWorked( + conn.adminCommand({setFeatureCompatibilityVersion: lastLTSFCV, confirm: true})); + forceInterruptedUpgradeOrDowngrade(conn, latestFCV); +}, {expectedAtTeardownFCV: lastLTSFCV, expectedSetLastLTSFCV: 1, expectedSetLatestFCV: 1}); diff --git a/jstests/replsets/drop_collections_two_phase.js b/jstests/replsets/drop_collections_two_phase.js index ac8b727834a..58e192ff208 100644 --- a/jstests/replsets/drop_collections_two_phase.js +++ b/jstests/replsets/drop_collections_two_phase.js @@ -3,10 +3,7 @@ * properly. */ -(function() { -"use strict"; - -load("jstests/replsets/libs/two_phase_drops.js"); // For TwoPhaseDropCollectionTest. +import {TwoPhaseDropCollectionTest} from "jstests/replsets/libs/two_phase_drops.js"; // Set up a two phase drop test. let testName = "drop_collection_two_phase"; @@ -21,7 +18,7 @@ let replTest = twoPhaseDropTest.initReplSet(); if (!twoPhaseDropTest.supportsDropPendingNamespaces()) { jsTestLog('Drop pending namespaces not supported by storage engine. Skipping test.'); twoPhaseDropTest.stop(); - return; + quit(); } // Create the collection that will be dropped. @@ -33,5 +30,4 @@ twoPhaseDropTest.prepareDropCollection(collName); // COMMIT collection drop. twoPhaseDropTest.commitDropCollection(collName); -twoPhaseDropTest.stop(); -}()); +twoPhaseDropTest.stop(); \ No newline at end of file diff --git a/jstests/replsets/drop_collections_two_phase_apply_ops_create.js b/jstests/replsets/drop_collections_two_phase_apply_ops_create.js index 34998dce7ec..3dd7b0f6897 100644 --- a/jstests/replsets/drop_collections_two_phase_apply_ops_create.js +++ b/jstests/replsets/drop_collections_two_phase_apply_ops_create.js @@ -5,10 +5,7 @@ * collection. */ -(function() { -"use strict"; - -load("jstests/replsets/libs/two_phase_drops.js"); // For TwoPhaseDropCollectionTest. +import {TwoPhaseDropCollectionTest} from "jstests/replsets/libs/two_phase_drops.js"; // Set up a two phase drop test. let testName = "drop_collection_two_phase_apply_ops_create"; @@ -23,7 +20,7 @@ let replTest = twoPhaseDropTest.initReplSet(); if (!twoPhaseDropTest.supportsDropPendingNamespaces()) { jsTestLog('Drop pending namespaces not supported by storage engine. Skipping test.'); twoPhaseDropTest.stop(); - return; + quit(); } // Create the collection that will be dropped. @@ -59,5 +56,4 @@ try { twoPhaseDropTest.commitDropCollection(collName); } finally { twoPhaseDropTest.stop(); -} -}()); +} \ No newline at end of file diff --git a/jstests/replsets/drop_collections_two_phase_apply_ops_drop.js b/jstests/replsets/drop_collections_two_phase_apply_ops_drop.js index 0d83fc8602b..7235d580c9b 100644 --- a/jstests/replsets/drop_collections_two_phase_apply_ops_drop.js +++ b/jstests/replsets/drop_collections_two_phase_apply_ops_drop.js @@ -3,10 +3,7 @@ * By definition, a drop-pending collection will be removed by the server eventually. */ -(function() { -"use strict"; - -load("jstests/replsets/libs/two_phase_drops.js"); // For TwoPhaseDropCollectionTest. +import {TwoPhaseDropCollectionTest} from "jstests/replsets/libs/two_phase_drops.js"; // Set up a two phase drop test. let testName = "drop_collection_two_phase_apply_ops_noop"; @@ -21,7 +18,7 @@ let replTest = twoPhaseDropTest.initReplSet(); if (!twoPhaseDropTest.supportsDropPendingNamespaces()) { jsTestLog('Drop pending namespaces not supported by storage engine. Skipping test.'); twoPhaseDropTest.stop(); - return; + quit(); } // Create the collection that will be dropped. @@ -61,5 +58,4 @@ assert( // COMMIT collection drop. twoPhaseDropTest.commitDropCollection(collName); -twoPhaseDropTest.stop(); -}()); +twoPhaseDropTest.stop(); \ No newline at end of file diff --git a/jstests/replsets/drop_collections_two_phase_apply_ops_rename.js b/jstests/replsets/drop_collections_two_phase_apply_ops_rename.js index 7a957df0269..f3109290f77 100644 --- a/jstests/replsets/drop_collections_two_phase_apply_ops_rename.js +++ b/jstests/replsets/drop_collections_two_phase_apply_ops_rename.js @@ -3,10 +3,7 @@ * remains in a drop-pending state. This is the same behavior as renaming a non-existent collection. */ -(function() { -"use strict"; - -load("jstests/replsets/libs/two_phase_drops.js"); // For TwoPhaseDropCollectionTest. +import {TwoPhaseDropCollectionTest} from "jstests/replsets/libs/two_phase_drops.js"; // Set up a two phase drop test. let testName = "drop_collection_two_phase_apply_ops_rename"; @@ -21,7 +18,7 @@ let replTest = twoPhaseDropTest.initReplSet(); if (!twoPhaseDropTest.supportsDropPendingNamespaces()) { jsTestLog('Drop pending namespaces not supported by storage engine. Skipping test.'); twoPhaseDropTest.stop(); - return; + quit(); } // Create the collection that will be dropped. @@ -76,5 +73,4 @@ try { twoPhaseDropTest.commitDropCollection(collName); } finally { twoPhaseDropTest.stop(); -} -}()); +} \ No newline at end of file diff --git a/jstests/replsets/drop_collections_two_phase_create_index.js b/jstests/replsets/drop_collections_two_phase_create_index.js index 8dc47ead7b4..85b4c411084 100644 --- a/jstests/replsets/drop_collections_two_phase_create_index.js +++ b/jstests/replsets/drop_collections_two_phase_create_index.js @@ -2,12 +2,9 @@ * Test to ensure that index creation fails on a drop-pending collection. */ -(function() { -"use strict"; - load("jstests/libs/fail_point_util.js"); // For kDefaultWaitForFailPointTimeout. load("jstests/noPassthrough/libs/index_build.js"); // For IndexBuildTest. -load("jstests/replsets/libs/two_phase_drops.js"); // For TwoPhaseDropCollectionTest. +import {TwoPhaseDropCollectionTest} from "jstests/replsets/libs/two_phase_drops.js"; // Set up a two phase drop test. let testName = "drop_collection_two_phase"; @@ -22,7 +19,7 @@ let replTest = twoPhaseDropTest.initReplSet(); if (!twoPhaseDropTest.supportsDropPendingNamespaces()) { jsTestLog('Drop pending namespaces not supported by storage engine. Skipping test.'); twoPhaseDropTest.stop(); - return; + quit(); } const primary = replTest.getPrimary(); @@ -66,5 +63,4 @@ try { IndexBuildTest.resumeIndexBuilds(primary); } -twoPhaseDropTest.stop(); -}()); +twoPhaseDropTest.stop(); \ No newline at end of file diff --git a/jstests/replsets/drop_collections_two_phase_dbhash.js b/jstests/replsets/drop_collections_two_phase_dbhash.js index a2fa498c7c7..5da4b472a3f 100644 --- a/jstests/replsets/drop_collections_two_phase_dbhash.js +++ b/jstests/replsets/drop_collections_two_phase_dbhash.js @@ -3,10 +3,7 @@ * phase collection drop. */ -(function() { -'use strict'; - -load("jstests/replsets/libs/two_phase_drops.js"); // For TwoPhaseDropCollectionTest. +import {TwoPhaseDropCollectionTest} from "jstests/replsets/libs/two_phase_drops.js"; // Compute db hash for all collections on given database. function getDbHash(database) { @@ -27,7 +24,7 @@ let replTest = twoPhaseDropTest.initReplSet(); if (!twoPhaseDropTest.supportsDropPendingNamespaces()) { jsTestLog('Drop pending namespaces not supported by storage engine. Skipping test.'); twoPhaseDropTest.stop(); - return; + quit(); } let primaryDB = replTest.getPrimary().getDB(dbName); @@ -48,5 +45,4 @@ let dropCommittedDbHash = getDbHash(primaryDB); let failMsg = "dbHash during drop pending phase did not match dbHash after drop was committed."; assert.eq(dropPendingDbHash, dropCommittedDbHash, failMsg); -replTest.stopSet(); -})(); +replTest.stopSet(); \ No newline at end of file diff --git a/jstests/replsets/drop_collections_two_phase_drop_index.js b/jstests/replsets/drop_collections_two_phase_drop_index.js index f7360b52d0b..59976baa564 100644 --- a/jstests/replsets/drop_collections_two_phase_drop_index.js +++ b/jstests/replsets/drop_collections_two_phase_drop_index.js @@ -5,10 +5,7 @@ * ] */ -(function() { -"use strict"; - -load("jstests/replsets/libs/two_phase_drops.js"); // For TwoPhaseDropCollectionTest. +import {TwoPhaseDropCollectionTest} from "jstests/replsets/libs/two_phase_drops.js"; // Set up a two phase drop test. let testName = "drop_collection_two_phase"; @@ -23,7 +20,7 @@ let replTest = twoPhaseDropTest.initReplSet(); if (!twoPhaseDropTest.supportsDropPendingNamespaces()) { jsTestLog('Drop pending namespaces not supported by storage engine. Skipping test.'); twoPhaseDropTest.stop(); - return; + quit(); } const primary = replTest.getPrimary(); @@ -46,5 +43,4 @@ try { twoPhaseDropTest.commitDropCollection(collName); } -twoPhaseDropTest.stop(); -}()); +twoPhaseDropTest.stop(); \ No newline at end of file diff --git a/jstests/replsets/drop_collections_two_phase_rename_drop_target.js b/jstests/replsets/drop_collections_two_phase_rename_drop_target.js index ee8d25cd512..fab9bc14df3 100644 --- a/jstests/replsets/drop_collections_two_phase_rename_drop_target.js +++ b/jstests/replsets/drop_collections_two_phase_rename_drop_target.js @@ -3,10 +3,7 @@ * renameCollection command when dropTarget is set to true. */ -(function() { -'use strict'; - -load('jstests/replsets/libs/two_phase_drops.js'); // For TwoPhaseDropCollectionTest. +import {TwoPhaseDropCollectionTest} from "jstests/replsets/libs/two_phase_drops.js"; // Return a list of all indexes for a given collection. Use 'args' as the // 'listIndexes' command arguments. @@ -33,7 +30,7 @@ let replTest = twoPhaseDropTest.initReplSet(); if (!twoPhaseDropTest.supportsDropPendingNamespaces()) { jsTestLog('Drop pending namespaces not supported by storage engine. Skipping test.'); twoPhaseDropTest.stop(); - return; + quit(); } // Create the collections that will be renamed and dropped. @@ -113,5 +110,4 @@ try { primary.setLogLevel(previousLogLevel, 'storage'); twoPhaseDropTest.stop(); -} -}()); +} \ No newline at end of file diff --git a/jstests/replsets/drop_collections_two_phase_step_down.js b/jstests/replsets/drop_collections_two_phase_step_down.js index 849a1c82e29..8323a77f357 100644 --- a/jstests/replsets/drop_collections_two_phase_step_down.js +++ b/jstests/replsets/drop_collections_two_phase_step_down.js @@ -12,10 +12,7 @@ * 6. Resume oplog application on secondary and make sure collection drop is eventually committed. */ -(function() { -"use strict"; - -load("jstests/replsets/libs/two_phase_drops.js"); // For TwoPhaseDropCollectionTest. +import {TwoPhaseDropCollectionTest} from "jstests/replsets/libs/two_phase_drops.js"; // Set up a two phase drop test. let testName = "drop_collection_two_phase_step_down"; @@ -30,7 +27,7 @@ let replTest = twoPhaseDropTest.initReplSet(); if (!twoPhaseDropTest.supportsDropPendingNamespaces()) { jsTestLog('Drop pending namespaces not supported by storage engine. Skipping test.'); twoPhaseDropTest.stop(); - return; + quit(); } // Create the collection that will be dropped. @@ -66,5 +63,4 @@ try { twoPhaseDropTest.commitDropCollection(collName); } finally { twoPhaseDropTest.stop(); -} -}()); +} \ No newline at end of file diff --git a/jstests/replsets/drop_collections_two_phase_write_concern.js b/jstests/replsets/drop_collections_two_phase_write_concern.js index b0eda43d14c..15d03a2dafa 100644 --- a/jstests/replsets/drop_collections_two_phase_write_concern.js +++ b/jstests/replsets/drop_collections_two_phase_write_concern.js @@ -3,11 +3,8 @@ * collections, with optimes preceding or equal to the operation's optime, to be reaped. */ -(function() { -'use strict'; - load("jstests/libs/fail_point_util.js"); -load('jstests/replsets/libs/two_phase_drops.js'); // For TwoPhaseDropCollectionTest. +import {TwoPhaseDropCollectionTest} from "jstests/replsets/libs/two_phase_drops.js"; // Alias to logging function in two_phase_drops.js const testLog = TwoPhaseDropCollectionTest._testLog; @@ -34,7 +31,7 @@ let replTest = twoPhaseDropTest.initReplSet(); if (!twoPhaseDropTest.supportsDropPendingNamespaces()) { jsTestLog('Drop pending namespaces not supported by storage engine. Skipping test.'); twoPhaseDropTest.stop(); - return; + quit(); } // Create the collection that will be dropped. @@ -84,5 +81,4 @@ assert.eq(4, collForInserts.find().itcount()); // COMMIT collection drop. twoPhaseDropTest.commitDropCollection(collName); -twoPhaseDropTest.stop(); -}()); +twoPhaseDropTest.stop(); \ No newline at end of file diff --git a/jstests/replsets/drop_databases_two_phase.js b/jstests/replsets/drop_databases_two_phase.js index 3f8d27742ec..cddb61cc98b 100644 --- a/jstests/replsets/drop_databases_two_phase.js +++ b/jstests/replsets/drop_databases_two_phase.js @@ -14,10 +14,7 @@ * unless explicitly requested by the user with a write concern. */ -(function() { -"use strict"; - -load('jstests/replsets/libs/two_phase_drops.js'); // For TwoPhaseDropCollectionTest. +import {TwoPhaseDropCollectionTest} from "jstests/replsets/libs/two_phase_drops.js"; load("jstests/replsets/rslib.js"); load("jstests/libs/write_concern_util.js"); @@ -163,4 +160,3 @@ assert.eq(0, exitCode, 'dropDatabase command on ' + primary.host + ' failed.'); jsTestLog('Completed dropDatabase command on ' + primary.host); replTest.stopSet(); -}()); diff --git a/jstests/replsets/global_index_rollback.js b/jstests/replsets/global_index_rollback.js index 83951472fce..d38ec973ccd 100644 --- a/jstests/replsets/global_index_rollback.js +++ b/jstests/replsets/global_index_rollback.js @@ -9,11 +9,8 @@ * ] */ -(function() { -'use strict'; - load('jstests/replsets/libs/rollback_files.js'); -load('jstests/replsets/libs/rollback_test.js'); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; load('jstests/libs/uuid_util.js'); function uuidToCollName(uuid) { @@ -533,5 +530,4 @@ for (let bulk of [false, true]) { rollbackDropWithCrud(bulk); } -rollbackTest.stop(); -})(); +rollbackTest.stop(); \ No newline at end of file diff --git a/jstests/replsets/initial_sync_drop_collection.js b/jstests/replsets/initial_sync_drop_collection.js index 8bf244ce4e2..deba7037a0e 100644 --- a/jstests/replsets/initial_sync_drop_collection.js +++ b/jstests/replsets/initial_sync_drop_collection.js @@ -2,11 +2,8 @@ * Test that CollectionCloner completes without error when a collection is dropped during cloning. */ -(function() { -"use strict"; - load("jstests/libs/fail_point_util.js"); -load('jstests/replsets/libs/two_phase_drops.js'); +import {TwoPhaseDropCollectionTest} from "jstests/replsets/libs/two_phase_drops.js"; load("jstests/libs/uuid_util.js"); // Set up replica set. Disallow chaining so nodes always sync from primary. @@ -187,5 +184,4 @@ runDropTest({ createNew: true }); -replTest.stopSet(); -})(); +replTest.stopSet(); \ No newline at end of file diff --git a/jstests/replsets/initial_sync_fails_on_rollback.js b/jstests/replsets/initial_sync_fails_on_rollback.js index 4bd98e0f960..908fc35ba7a 100644 --- a/jstests/replsets/initial_sync_fails_on_rollback.js +++ b/jstests/replsets/initial_sync_fails_on_rollback.js @@ -5,10 +5,7 @@ * @tags: [multiversion_incompatible] */ -(function() { -"use strict"; - -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const testName = "initial_sync_fails_on_rollback"; const dbName = testName; @@ -98,5 +95,4 @@ assert.lte(res.initialSyncStatus.databases[dbName][dbName + ".test"].documentsCo rst.stop(initialSyncNode); rst.remove(initialSyncNode); -rollbackTest.stop(); -})(); +rollbackTest.stop(); \ No newline at end of file diff --git a/jstests/replsets/initial_sync_rename_collection.js b/jstests/replsets/initial_sync_rename_collection.js index a5d21e3e968..3b8818e5d83 100644 --- a/jstests/replsets/initial_sync_rename_collection.js +++ b/jstests/replsets/initial_sync_rename_collection.js @@ -2,12 +2,9 @@ * Test that CollectionCloner completes without error when a collection is renamed during cloning. */ -(function() { -"use strict"; - load("jstests/libs/fail_point_util.js"); load("jstests/libs/uuid_util.js"); -load('jstests/replsets/libs/two_phase_drops.js'); +import {TwoPhaseDropCollectionTest} from "jstests/replsets/libs/two_phase_drops.js"; // Set up replica set. Disallow chaining so nodes always sync from primary. const testName = "initial_sync_rename_collection"; @@ -210,5 +207,4 @@ runRenameTest({ expectedLog: expectedLogFor6and8 }); -replTest.stopSet(); -})(); +replTest.stopSet(); \ No newline at end of file diff --git a/jstests/replsets/libs/rollback_index_builds_test.js b/jstests/replsets/libs/rollback_index_builds_test.js index a05c039cad8..dee132e5c98 100644 --- a/jstests/replsets/libs/rollback_index_builds_test.js +++ b/jstests/replsets/libs/rollback_index_builds_test.js @@ -2,12 +2,10 @@ * Fixture to test rollback permutations with index builds. */ -"use strict"; - load("jstests/noPassthrough/libs/index_build.js"); // for IndexBuildTest -load('jstests/replsets/libs/rollback_test.js'); // for RollbackTest +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; -class RollbackIndexBuildsTest { +export class RollbackIndexBuildsTest { constructor(expectedErrors) { jsTestLog("Set up a Rollback Test."); const replTest = new ReplSetTest({ diff --git a/jstests/replsets/libs/rollback_resumable_index_build.js b/jstests/replsets/libs/rollback_resumable_index_build.js index 9925b0b6941..9d9a9ccacc1 100644 --- a/jstests/replsets/libs/rollback_resumable_index_build.js +++ b/jstests/replsets/libs/rollback_resumable_index_build.js @@ -1,5 +1,4 @@ load("jstests/noPassthrough/libs/index_build.js"); -load('jstests/replsets/libs/rollback_test.js'); const RollbackResumableIndexBuildTest = class { static checkCompletedAndDrop( diff --git a/jstests/replsets/libs/rollback_test.js b/jstests/replsets/libs/rollback_test.js index bd1621d5997..049f1df2e7a 100644 --- a/jstests/replsets/libs/rollback_test.js +++ b/jstests/replsets/libs/rollback_test.js @@ -38,11 +38,9 @@ * of each stage. */ -"use strict"; - +import {CollectionValidator} from "jstests/hooks/validate_collections.js"; load("jstests/replsets/rslib.js"); -load("jstests/replsets/libs/two_phase_drops.js"); -load("jstests/hooks/validate_collections.js"); +import {TwoPhaseDropCollectionTest} from "jstests/replsets/libs/two_phase_drops.js"; load('jstests/libs/fail_point_util.js'); /** @@ -70,7 +68,7 @@ load('jstests/libs/fail_point_util.js'); * @param {Object} [optional] nodeOptions command-line options to apply to all nodes in the replica * set. Ignored if 'replSet' is provided. */ -function RollbackTest(name = "RollbackTest", replSet, nodeOptions) { +export function RollbackTest(name = "RollbackTest", replSet, nodeOptions) { const State = { kStopped: "kStopped", kRollbackOps: "kRollbackOps", diff --git a/jstests/replsets/libs/rollback_test_deluxe.js b/jstests/replsets/libs/rollback_test_deluxe.js index 6283d2b8e28..03c55f3fe08 100644 --- a/jstests/replsets/libs/rollback_test_deluxe.js +++ b/jstests/replsets/libs/rollback_test_deluxe.js @@ -35,10 +35,8 @@ * of restarts. */ -"use strict"; - -load("jstests/hooks/validate_collections.js"); -load("jstests/replsets/libs/two_phase_drops.js"); +import {CollectionValidator} from "jstests/hooks/validate_collections.js"; +import {TwoPhaseDropCollectionTest} from "jstests/replsets/libs/two_phase_drops.js"; load("jstests/replsets/rslib.js"); Random.setRandomSeed(); @@ -58,7 +56,7 @@ Random.setRandomSeed(); * @param {Object} [optional] nodeOptions command-line options to apply to all nodes in the replica * set. Ignored if 'replSet' is provided. */ -function RollbackTestDeluxe(name = "FiveNodeDoubleRollbackTest", replSet, nodeOptions) { +export function RollbackTestDeluxe(name = "FiveNodeDoubleRollbackTest", replSet, nodeOptions) { const State = { kStopped: "kStopped", kRollbackOps: "kRollbackOps", diff --git a/jstests/replsets/libs/two_phase_drops.js b/jstests/replsets/libs/two_phase_drops.js index d81f0043322..cd4cc3d2f60 100644 --- a/jstests/replsets/libs/two_phase_drops.js +++ b/jstests/replsets/libs/two_phase_drops.js @@ -14,13 +14,12 @@ * of the replica set. * */ -"use strict"; load("jstests/libs/fail_point_util.js"); load("jstests/libs/fixture_helpers.js"); // For 'FixtureHelpers'. load("jstests/aggregation/extras/utils.js"); // For 'arrayEq'. -class TwoPhaseDropCollectionTest { +export class TwoPhaseDropCollectionTest { constructor(testName, dbName) { this.testName = testName; this.dbName = dbName; diff --git a/jstests/replsets/not_primary_errors_returned_during_rollback_if_helloOk.js b/jstests/replsets/not_primary_errors_returned_during_rollback_if_helloOk.js index 55a97e1d32f..bd7bf9e8c09 100644 --- a/jstests/replsets/not_primary_errors_returned_during_rollback_if_helloOk.js +++ b/jstests/replsets/not_primary_errors_returned_during_rollback_if_helloOk.js @@ -8,10 +8,7 @@ * @tags: [requires_majority_read_concern] */ -(function() { -"use strict"; - -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; load("jstests/replsets/rslib.js"); const dbName = "test"; @@ -82,4 +79,3 @@ failPointAfterTransition.off(); rollbackTest.transitionToSteadyStateOperations(); rollbackTest.stop(); -}()); diff --git a/jstests/replsets/prepare_failover_rollback_commit.js b/jstests/replsets/prepare_failover_rollback_commit.js index 673d658a775..66a2fdeedd2 100644 --- a/jstests/replsets/prepare_failover_rollback_commit.js +++ b/jstests/replsets/prepare_failover_rollback_commit.js @@ -11,9 +11,7 @@ * uses_transactions, * ] */ -(function() { -"use strict"; -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; load("jstests/core/txns/libs/prepare_helpers.js"); const dbName = "test"; @@ -67,4 +65,3 @@ const newSession2 = new _DelegatingDriverSession(primary, session); assert.commandWorked(PrepareHelpers.commitTransaction(newSession2, prepareTimestamp)); rollbackTest.stop(); -})(); diff --git a/jstests/replsets/primary_rollbacks_before_index_build_received_votes.js b/jstests/replsets/primary_rollbacks_before_index_build_received_votes.js index 0ddd9389000..83b87896491 100644 --- a/jstests/replsets/primary_rollbacks_before_index_build_received_votes.js +++ b/jstests/replsets/primary_rollbacks_before_index_build_received_votes.js @@ -2,11 +2,7 @@ * Test that primary rollbacks before receiving any votes from the replica set should not * make createIndexes command's commit quorum value to be lost. */ -(function() { - -"use strict"; - -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; load('jstests/noPassthrough/libs/index_build.js'); const dbName = jsTest.name(); @@ -60,4 +56,3 @@ awaitBuild(); IndexBuildTest.assertIndexes(newPrimaryDB[collName], 2, ['_id_', 'i_1']); rollbackTest.stop(); -})(); diff --git a/jstests/replsets/read_operations_during_rollback.js b/jstests/replsets/read_operations_during_rollback.js index ae77d7b2e21..6717bf7e67a 100644 --- a/jstests/replsets/read_operations_during_rollback.js +++ b/jstests/replsets/read_operations_during_rollback.js @@ -6,10 +6,7 @@ * ] */ -(function() { -"use strict"; - -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; load("jstests/replsets/rslib.js"); const dbName = "test"; @@ -124,4 +121,3 @@ assert.commandFailedWithCode( // Check the replica set. rollbackTest.stop(); -}()); diff --git a/jstests/replsets/reconfig_removes_node_in_rollback.js b/jstests/replsets/reconfig_removes_node_in_rollback.js index 6057c4a8099..b12967edc13 100644 --- a/jstests/replsets/reconfig_removes_node_in_rollback.js +++ b/jstests/replsets/reconfig_removes_node_in_rollback.js @@ -2,10 +2,7 @@ * Test that a node in rollback state can safely be removed from the replica set * config via reconfig. See SERVER-48179. */ -(function() { -"use strict"; - -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const dbName = "test"; const collName = "rollbackColl"; @@ -86,5 +83,4 @@ rollbackTest.getTestFixture().waitForState(rollbackNode, ReplSetTest.State.SECON // Transition back to steady state. rollbackTest.transitionToSteadyStateOperations(); -rollbackTest.stop(); -})(); +rollbackTest.stop(); \ No newline at end of file diff --git a/jstests/replsets/recover_committed_aborted_prepared_transactions.js b/jstests/replsets/recover_committed_aborted_prepared_transactions.js index c4499ce87b4..2a82656665f 100644 --- a/jstests/replsets/recover_committed_aborted_prepared_transactions.js +++ b/jstests/replsets/recover_committed_aborted_prepared_transactions.js @@ -9,11 +9,8 @@ * uses_transactions, * ] */ -(function() { -"use strict"; - load("jstests/core/txns/libs/prepare_helpers.js"); -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const dbName = "test"; const collName = "recover_committed_aborted_prepared_transactions"; @@ -133,5 +130,4 @@ assert.commandFailedWithCode(sessionDB1.adminCommand({ assert.sameMembers(testColl.find().toArray(), [{_id: 1}, {_id: 2}, {_id: 5}]); assert.eq(testColl.count(), 3); -rollbackTest.stop(); -}()); +rollbackTest.stop(); \ No newline at end of file diff --git a/jstests/replsets/recover_prepared_transaction_state.js b/jstests/replsets/recover_prepared_transaction_state.js index 7abb3ae6ed1..6c36212a38f 100644 --- a/jstests/replsets/recover_prepared_transaction_state.js +++ b/jstests/replsets/recover_prepared_transaction_state.js @@ -17,11 +17,8 @@ * uses_transactions, * ] */ -(function() { -"use strict"; - load("jstests/core/txns/libs/prepare_helpers.js"); -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const dbName = "test"; const collName = "recover_prepared_transaction_state_after_rollback"; @@ -194,5 +191,4 @@ rollbackTest.awaitReplication(); assert.sameMembers(testColl.find().toArray(), [{_id: 1, a: 1}, {_id: 2}, {_id: 3}]); assert.eq(testColl.count(), 3); -rollbackTest.stop(); -}()); +rollbackTest.stop(); \ No newline at end of file diff --git a/jstests/replsets/restart_index_build_if_resume_interrupted_by_rollback.js b/jstests/replsets/restart_index_build_if_resume_interrupted_by_rollback.js index 83fcd526413..74b08228fb6 100644 --- a/jstests/replsets/restart_index_build_if_resume_interrupted_by_rollback.js +++ b/jstests/replsets/restart_index_build_if_resume_interrupted_by_rollback.js @@ -7,10 +7,8 @@ * requires_persistence, * ] */ -(function() { -"use strict"; - load("jstests/replsets/libs/rollback_resumable_index_build.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const dbName = "test"; @@ -20,4 +18,3 @@ RollbackResumableIndexBuildTest.runResumeInterruptedByRollback( rollbackTest, dbName, [{a: 1}, {a: 2}], {a: 1}, [{a: 3}], [{a: 4}]); rollbackTest.stop(); -})(); diff --git a/jstests/replsets/rollback_aborted_prepared_transaction.js b/jstests/replsets/rollback_aborted_prepared_transaction.js index b8bdc857992..c5a38be8005 100644 --- a/jstests/replsets/rollback_aborted_prepared_transaction.js +++ b/jstests/replsets/rollback_aborted_prepared_transaction.js @@ -7,11 +7,8 @@ * * @tags: [uses_transactions, uses_prepare_transaction] */ -(function() { -"use strict"; - load("jstests/core/txns/libs/prepare_helpers.js"); -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const dbName = "test"; const collName = "rollback_aborted_prepared_transaction"; @@ -104,5 +101,4 @@ PrepareHelpers.commitTransaction(session, prepareTimestamp); assert.eq(testColl.find().itcount(), 2); assert.eq(testColl.count(), 2); -rollbackTest.stop(); -}()); +rollbackTest.stop(); \ No newline at end of file diff --git a/jstests/replsets/rollback_all_op_types.js b/jstests/replsets/rollback_all_op_types.js index a2ae13b7d9a..66a00886db3 100644 --- a/jstests/replsets/rollback_all_op_types.js +++ b/jstests/replsets/rollback_all_op_types.js @@ -11,10 +11,7 @@ * @tags: [requires_fcv_53] */ -(function() { -"use strict"; - -load("jstests/replsets/libs/rollback_test_deluxe.js"); +import {RollbackTestDeluxe} from "jstests/replsets/libs/rollback_test_deluxe.js"; let noOp = () => {}; @@ -379,5 +376,4 @@ rollbackTest.transitionToSyncSourceOperationsDuringRollback(); rollbackTest.transitionToSteadyStateOperations(); // Check the replica set. -rollbackTest.stop(); -})(); +rollbackTest.stop(); \ No newline at end of file diff --git a/jstests/replsets/rollback_capped_deletions.js b/jstests/replsets/rollback_capped_deletions.js index 233384ff8e5..056107bf4db 100644 --- a/jstests/replsets/rollback_capped_deletions.js +++ b/jstests/replsets/rollback_capped_deletions.js @@ -1,10 +1,7 @@ /** * Tests that capped collections get the correct fastcounts after rollback. */ -(function() { -'use strict'; - -load('jstests/replsets/libs/rollback_test.js'); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const testName = 'rollback_capped_deletions'; const dbName = testName; @@ -44,5 +41,4 @@ try { primary.adminCommand({configureFailPoint: 'disableSnapshotting', mode: 'off'})); } -rollbackTest.stop(); -})(); +rollbackTest.stop(); \ No newline at end of file diff --git a/jstests/replsets/rollback_clustered_indexes.js b/jstests/replsets/rollback_clustered_indexes.js index 8e4b3dbbc85..bde0fa44e1e 100644 --- a/jstests/replsets/rollback_clustered_indexes.js +++ b/jstests/replsets/rollback_clustered_indexes.js @@ -4,10 +4,7 @@ * requires_replication, * ] */ -(function() { -'use strict'; - -load('jstests/replsets/libs/rollback_test.js'); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; load('jstests/replsets/libs/rollback_files.js'); load("jstests/libs/uuid_util.js"); @@ -67,4 +64,3 @@ const uuid = getUUIDFromListCollections(rollbackTest.getPrimary().getDB(dbName), checkRollbackFiles(replTest.getDbPath(rollbackNode), collName, uuid, rollbackDocs); rollbackTest.stop(); -})(); diff --git a/jstests/replsets/rollback_collmods.js b/jstests/replsets/rollback_collmods.js index 75c9af51d96..23e8a53bf51 100644 --- a/jstests/replsets/rollback_collmods.js +++ b/jstests/replsets/rollback_collmods.js @@ -5,10 +5,7 @@ * @tags: [requires_fcv_53] */ -(function() { -"use strict"; - -load("jstests/replsets/libs/rollback_test_deluxe.js"); +import {RollbackTestDeluxe} from "jstests/replsets/libs/rollback_test_deluxe.js"; const testName = "rollback_collmods"; const dbName = testName; @@ -106,5 +103,4 @@ printCollectionOptions(rollbackTest, "after rollback"); SteadyStateOps(rollbackTest.getPrimary()); printCollectionOptions(rollbackTest, "at completion"); -rollbackTest.stop(); -})(); +rollbackTest.stop(); \ No newline at end of file diff --git a/jstests/replsets/rollback_crud_op_sequences.js b/jstests/replsets/rollback_crud_op_sequences.js index 54c580b6bd1..5481149f632 100644 --- a/jstests/replsets/rollback_crud_op_sequences.js +++ b/jstests/replsets/rollback_crud_op_sequences.js @@ -1,12 +1,9 @@ /* * Basic test of a succesful replica set rollback for CRUD operations. */ -load('jstests/replsets/libs/rollback_test.js'); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; load("jstests/replsets/rslib.js"); -(function() { -"use strict"; - // Helper function for verifying contents at the end of the test. const checkFinalResults = function(db) { assert.eq(0, db.bar.count({q: 70})); @@ -77,4 +74,3 @@ checkFinalResults(rollbackNodeDB); checkFinalResults(syncSourceDB); rollbackTest.stop(); -}()); diff --git a/jstests/replsets/rollback_drop_database.js b/jstests/replsets/rollback_drop_database.js index 40792d97125..147891eb83f 100644 --- a/jstests/replsets/rollback_drop_database.js +++ b/jstests/replsets/rollback_drop_database.js @@ -19,9 +19,7 @@ * ] */ -(function() { - -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const testName = "rollback_drop_database"; @@ -103,5 +101,4 @@ rollbackTest.stepUpNode(rollbackNode); assert.commandWorked(rollbackNode.getDB(conflictingDbName)["afterRollback"].insert( {"num": 2}, {writeConcern: {w: 2}})); -rollbackTest.stop(); -})(); +rollbackTest.stop(); \ No newline at end of file diff --git a/jstests/replsets/rollback_drop_index_after_rename.js b/jstests/replsets/rollback_drop_index_after_rename.js index 143701e8e95..9fdf6c22858 100644 --- a/jstests/replsets/rollback_drop_index_after_rename.js +++ b/jstests/replsets/rollback_drop_index_after_rename.js @@ -5,10 +5,7 @@ * then renaming that collection and rolling back a drop on that index. */ -(function() { -"use strict"; - -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const testName = "rollback_drop_index_after_rename"; const dbName = testName; @@ -54,5 +51,4 @@ rollbackTest.transitionToSyncSourceOperationsBeforeRollback(); rollbackTest.transitionToSyncSourceOperationsDuringRollback(); rollbackTest.transitionToSteadyStateOperations(); -rollbackTest.stop(); -})(); +rollbackTest.stop(); \ No newline at end of file diff --git a/jstests/replsets/rollback_dup_ids.js b/jstests/replsets/rollback_dup_ids.js index 75297118d80..a67440d511b 100644 --- a/jstests/replsets/rollback_dup_ids.js +++ b/jstests/replsets/rollback_dup_ids.js @@ -1,10 +1,7 @@ // When run with --majorityReadConcern=off, this test reproduces the bug described in SERVER-38925, // where rolling back a delete followed by a restart produces documents with duplicate _id. // @tags: [requires_persistence] -(function() { -"use strict"; - -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; TestData.rollbackShutdowns = true; TestData.allowUncleanShutdowns = true; @@ -39,5 +36,4 @@ rollbackTest.transitionToSteadyStateOperations(); rollbackTest.restartNode(0, 9); // Check the replica set. -rollbackTest.stop(); -}()); +rollbackTest.stop(); \ No newline at end of file diff --git a/jstests/replsets/rollback_dup_ids_clean_shutdown_during_rollback.js b/jstests/replsets/rollback_dup_ids_clean_shutdown_during_rollback.js index 361ff74cfa3..341da387f73 100644 --- a/jstests/replsets/rollback_dup_ids_clean_shutdown_during_rollback.js +++ b/jstests/replsets/rollback_dup_ids_clean_shutdown_during_rollback.js @@ -6,10 +6,7 @@ // // @tags: [requires_persistence] // -(function() { -"use strict"; - -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; TestData.rollbackShutdowns = true; let dbName = "test"; @@ -51,5 +48,4 @@ rollbackTest.restartNode(0, 15 /* SIGTERM */); rollbackTest.transitionToSteadyStateOperations(); // Check the replica set. -rollbackTest.stop(); -}()); +rollbackTest.stop(); \ No newline at end of file diff --git a/jstests/replsets/rollback_files_no_prepare_conflict.js b/jstests/replsets/rollback_files_no_prepare_conflict.js index 25d0aa3f8de..a1e8bc17104 100644 --- a/jstests/replsets/rollback_files_no_prepare_conflict.js +++ b/jstests/replsets/rollback_files_no_prepare_conflict.js @@ -7,10 +7,8 @@ * * @tags: [uses_transactions, uses_prepare_transaction] */ -(function() { -"use strict"; load("jstests/core/txns/libs/prepare_helpers.js"); -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const name = "rollback_files_no_prepare_conflicts"; const dbName = "test"; @@ -52,5 +50,4 @@ testDB = primary.getDB(dbName); testColl = testDB.getCollection(collName); assert.docEq({_id: 42, a: "one"}, testColl.findOne({_id: 42})); -rollbackTest.stop(); -})(); +rollbackTest.stop(); \ No newline at end of file diff --git a/jstests/replsets/rollback_index_build_and_create.js b/jstests/replsets/rollback_index_build_and_create.js index c23aabaa2a0..7ac63dce1d2 100644 --- a/jstests/replsets/rollback_index_build_and_create.js +++ b/jstests/replsets/rollback_index_build_and_create.js @@ -1,11 +1,7 @@ /** * Test that rolling back an index build and collection creation behaves correctly. */ -(function() { -"use strict"; - -// For RollbackIndexBuildsTest -load('jstests/replsets/libs/rollback_index_builds_test.js'); +import {RollbackIndexBuildsTest} from "jstests/replsets/libs/rollback_index_builds_test.js"; const rollbackIndexTest = new RollbackIndexBuildsTest([ErrorCodes.InterruptedDueToReplStateChange]); @@ -25,4 +21,3 @@ const schedule = [ rollbackIndexTest.runSchedules([schedule]); rollbackIndexTest.stop(); -})(); diff --git a/jstests/replsets/rollback_index_build_start.js b/jstests/replsets/rollback_index_build_start.js index b155febf423..e80cd721be1 100644 --- a/jstests/replsets/rollback_index_build_start.js +++ b/jstests/replsets/rollback_index_build_start.js @@ -2,11 +2,7 @@ * Test that an index build aborted due to rollback restarts correctly, even if the none of the * associated oplog entries are rolled-back. */ -(function() { -"use strict"; - -// For RollbackIndexBuildsTest -load('jstests/replsets/libs/rollback_index_builds_test.js'); +import {RollbackIndexBuildsTest} from "jstests/replsets/libs/rollback_index_builds_test.js"; const rollbackIndexTest = new RollbackIndexBuildsTest([ErrorCodes.InterruptedDueToReplStateChange]); @@ -27,4 +23,3 @@ const schedule = [ rollbackIndexTest.runSchedules([schedule]); rollbackIndexTest.stop(); -})(); diff --git a/jstests/replsets/rollback_index_build_start_abort.js b/jstests/replsets/rollback_index_build_start_abort.js index 1f2ad4f1937..15a780e7502 100644 --- a/jstests/replsets/rollback_index_build_start_abort.js +++ b/jstests/replsets/rollback_index_build_start_abort.js @@ -1,11 +1,7 @@ /** * Tests different permutations of rolling-back index build start and abort oplog entries. */ -(function() { -"use strict"; - -// for RollbackIndexBuildTest -load('jstests/replsets/libs/rollback_index_builds_test.js'); +import {RollbackIndexBuildsTest} from "jstests/replsets/libs/rollback_index_builds_test.js"; const rollbackIndexTest = new RollbackIndexBuildsTest([ErrorCodes.Interrupted]); @@ -17,4 +13,3 @@ const indexBuildOps = ["start", "abort"]; const schedules = RollbackIndexBuildsTest.makeSchedules(rollbackOps, indexBuildOps); rollbackIndexTest.runSchedules(schedules); rollbackIndexTest.stop(); -})(); diff --git a/jstests/replsets/rollback_index_build_start_abort_not_create.js b/jstests/replsets/rollback_index_build_start_abort_not_create.js index 96d294ed6c6..22e6cade219 100644 --- a/jstests/replsets/rollback_index_build_start_abort_not_create.js +++ b/jstests/replsets/rollback_index_build_start_abort_not_create.js @@ -2,11 +2,7 @@ * Test that rolling back an index build, but not collection creation, behaves correctly even when * the index build is aborted. */ -(function() { -"use strict"; - -// For RollbackIndexBuildsTest -load('jstests/replsets/libs/rollback_index_builds_test.js'); +import {RollbackIndexBuildsTest} from "jstests/replsets/libs/rollback_index_builds_test.js"; const rollbackIndexTest = new RollbackIndexBuildsTest( [ErrorCodes.InterruptedDueToReplStateChange, ErrorCodes.Interrupted]); @@ -26,4 +22,3 @@ const schedule = [ rollbackIndexTest.runSchedules([schedule]); rollbackIndexTest.stop(); -})(); diff --git a/jstests/replsets/rollback_index_build_start_commit.js b/jstests/replsets/rollback_index_build_start_commit.js index 61edf7488f7..19fe1695954 100644 --- a/jstests/replsets/rollback_index_build_start_commit.js +++ b/jstests/replsets/rollback_index_build_start_commit.js @@ -1,11 +1,7 @@ /** * Tests different permutations of rolling-back index build start and commit oplog entries. */ -(function() { -"use strict"; - -// for RollbackIndexBuildTest -load('jstests/replsets/libs/rollback_index_builds_test.js'); +import {RollbackIndexBuildsTest} from "jstests/replsets/libs/rollback_index_builds_test.js"; const rollbackIndexTest = new RollbackIndexBuildsTest(); @@ -17,4 +13,3 @@ const indexBuildOps = ["start", "commit"]; const schedules = RollbackIndexBuildsTest.makeSchedules(rollbackOps, indexBuildOps); rollbackIndexTest.runSchedules(schedules); rollbackIndexTest.stop(); -})(); diff --git a/jstests/replsets/rollback_index_build_start_commit_drop.js b/jstests/replsets/rollback_index_build_start_commit_drop.js index b6332b66457..b31a6a6ac39 100644 --- a/jstests/replsets/rollback_index_build_start_commit_drop.js +++ b/jstests/replsets/rollback_index_build_start_commit_drop.js @@ -1,11 +1,7 @@ /** * Tests different permutations of rolling-back index build start, commit, and drop oplog entries. */ -(function() { -"use strict"; - -// for RollbackIndexBuildTest -load('jstests/replsets/libs/rollback_index_builds_test.js'); +import {RollbackIndexBuildsTest} from "jstests/replsets/libs/rollback_index_builds_test.js"; const rollbackIndexTest = new RollbackIndexBuildsTest(); @@ -17,4 +13,3 @@ const indexBuildOps = ["start", "commit", "drop"]; const schedules = RollbackIndexBuildsTest.makeSchedules(rollbackOps, indexBuildOps); rollbackIndexTest.runSchedules(schedules); rollbackIndexTest.stop(); -})(); diff --git a/jstests/replsets/rollback_index_build_start_not_create.js b/jstests/replsets/rollback_index_build_start_not_create.js index e56990e08ad..db3ce751df8 100644 --- a/jstests/replsets/rollback_index_build_start_not_create.js +++ b/jstests/replsets/rollback_index_build_start_not_create.js @@ -1,11 +1,7 @@ /** * Test that rolling back an index build, but not collection creation, behaves correctly. */ -(function() { -"use strict"; - -// For RollbackIndexBuildsTest -load('jstests/replsets/libs/rollback_index_builds_test.js'); +import {RollbackIndexBuildsTest} from "jstests/replsets/libs/rollback_index_builds_test.js"; const rollbackIndexTest = new RollbackIndexBuildsTest(); @@ -24,4 +20,3 @@ const schedule = [ rollbackIndexTest.runSchedules([schedule]); rollbackIndexTest.stop(); -})(); diff --git a/jstests/replsets/rollback_large_batched_multi_deletes.js b/jstests/replsets/rollback_large_batched_multi_deletes.js index 36f5736773b..37d0df46197 100644 --- a/jstests/replsets/rollback_large_batched_multi_deletes.js +++ b/jstests/replsets/rollback_large_batched_multi_deletes.js @@ -5,8 +5,8 @@ * requires_replication, * ] */ -load('jstests/replsets/libs/rollback_test.js'); import {FeatureFlagUtil} from "jstests/libs/feature_flag_util.js"; +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; // Operations that will be present on both nodes, before the common point. const dbName = 'test'; diff --git a/jstests/replsets/rollback_prepare_transaction.js b/jstests/replsets/rollback_prepare_transaction.js index 4edaac269c0..33ff1e1815e 100644 --- a/jstests/replsets/rollback_prepare_transaction.js +++ b/jstests/replsets/rollback_prepare_transaction.js @@ -6,11 +6,8 @@ * uses_transactions, * ] */ -(function() { -"use strict"; - load("jstests/core/txns/libs/prepare_helpers.js"); -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; load("jstests/replsets/libs/rollback_files.js"); load("jstests/libs/uuid_util.js"); @@ -101,5 +98,4 @@ assert.commandWorked(adminDB.adminCommand({ autocommit: false })); -rollbackTest.stop(); -})(); +rollbackTest.stop(); \ No newline at end of file diff --git a/jstests/replsets/rollback_reconstructs_transactions_prepared_before_stable.js b/jstests/replsets/rollback_reconstructs_transactions_prepared_before_stable.js index 02bcc1840b1..2bb19b59850 100644 --- a/jstests/replsets/rollback_reconstructs_transactions_prepared_before_stable.js +++ b/jstests/replsets/rollback_reconstructs_transactions_prepared_before_stable.js @@ -8,10 +8,8 @@ * ] */ -(function() { -"use strict"; load("jstests/core/txns/libs/prepare_helpers.js"); -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const dbName = "test"; const collName = "rollback_reconstructs_transactions_prepared_before_stable"; @@ -133,5 +131,4 @@ assert.commandWorked(sessionDB.adminCommand({ assert.sameMembers(testColl.find().toArray(), [{_id: 0, a: 1}, {_id: 1}, {_id: 2}]); assert.eq(testColl.count(), 3); -rollbackTest.stop(); -}()); +rollbackTest.stop(); \ No newline at end of file diff --git a/jstests/replsets/rollback_recovery_commit_transaction_before_stable_timestamp.js b/jstests/replsets/rollback_recovery_commit_transaction_before_stable_timestamp.js index 4739b50a264..c609ec552af 100644 --- a/jstests/replsets/rollback_recovery_commit_transaction_before_stable_timestamp.js +++ b/jstests/replsets/rollback_recovery_commit_transaction_before_stable_timestamp.js @@ -12,11 +12,8 @@ * ] */ -(function() { -"use strict"; - load("jstests/core/txns/libs/prepare_helpers.js"); -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const dbName = "test"; const collName = "commit_transaction_rollback_recovery_data_already_applied"; @@ -101,5 +98,4 @@ assert.commandWorked(PrepareHelpers.commitTransaction(session, prepareTimestamp) assert.eq(testDB[collName].findOne({_id: 1}), {_id: 1, a: 1}); -rollbackTest.stop(); -}()); +rollbackTest.stop(); \ No newline at end of file diff --git a/jstests/replsets/rollback_remote_cursor_retry.js b/jstests/replsets/rollback_remote_cursor_retry.js index 7a44d00bf9e..ad426013b48 100644 --- a/jstests/replsets/rollback_remote_cursor_retry.js +++ b/jstests/replsets/rollback_remote_cursor_retry.js @@ -5,10 +5,8 @@ * third attempt. */ -(function() { -"use strict"; load("jstests/libs/fail_point_util.js"); -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const testName = "rollback_remote_cursor_retry"; const dbName = testName; @@ -44,5 +42,4 @@ configureFailPoint(syncSource, rollbackHangBeforeStartFailPoint.off(); rollbackTest.transitionToSteadyStateOperations(); -rollbackTest.stop(); -})(); +rollbackTest.stop(); \ No newline at end of file diff --git a/jstests/replsets/rollback_rename_collection_on_sync_source.js b/jstests/replsets/rollback_rename_collection_on_sync_source.js index 2084aecfd76..ec02d9b76b4 100644 --- a/jstests/replsets/rollback_rename_collection_on_sync_source.js +++ b/jstests/replsets/rollback_rename_collection_on_sync_source.js @@ -4,10 +4,7 @@ * corruption on the rollback node. */ -(function() { -'use strict'; - -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; let dbName = "rollback_rename_collection_on_sync_source"; let otherDbName = "rollback_rename_collection_on_sync_source_other"; @@ -73,5 +70,4 @@ rollbackTestAcrossDBs.transitionToSyncSourceOperationsDuringRollback(); rollbackTestAcrossDBs.transitionToSteadyStateOperations(); // Check the replica set. -rollbackTestAcrossDBs.stop(); -}()); +rollbackTestAcrossDBs.stop(); \ No newline at end of file diff --git a/jstests/replsets/rollback_rename_count.js b/jstests/replsets/rollback_rename_count.js index 51fa88f5324..ea64ca254be 100644 --- a/jstests/replsets/rollback_rename_count.js +++ b/jstests/replsets/rollback_rename_count.js @@ -1,10 +1,7 @@ /** * Tests that rollback corrects fastcounts even when collections are renamed. */ -(function() { -"use strict"; - -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const testName = "rollback_rename_count"; const dbName = testName; @@ -55,5 +52,4 @@ try { assert.eq(coll1.find().itcount(), 2); assert.eq(coll2.find().itcount(), 2); -rollbackTest.stop(); -})(); +rollbackTest.stop(); \ No newline at end of file diff --git a/jstests/replsets/rollback_resumable_index_build_bulk_load_phase.js b/jstests/replsets/rollback_resumable_index_build_bulk_load_phase.js index 64767da0d07..ef370b6ec46 100644 --- a/jstests/replsets/rollback_resumable_index_build_bulk_load_phase.js +++ b/jstests/replsets/rollback_resumable_index_build_bulk_load_phase.js @@ -10,10 +10,8 @@ * incompatible_with_gcov, * ] */ -(function() { -"use strict"; - load('jstests/replsets/libs/rollback_resumable_index_build.js'); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const dbName = "test"; @@ -66,4 +64,3 @@ runRollbackTo( runRollbackTo({name: "hangIndexBuildDuringBulkLoadPhaseSecond", logIdWithIndexName: 4924400}); rollbackTest.stop(); -})(); diff --git a/jstests/replsets/rollback_resumable_index_build_bulk_load_phase_large.js b/jstests/replsets/rollback_resumable_index_build_bulk_load_phase_large.js index 59e43221c5c..f97c6a3d1fe 100644 --- a/jstests/replsets/rollback_resumable_index_build_bulk_load_phase_large.js +++ b/jstests/replsets/rollback_resumable_index_build_bulk_load_phase_large.js @@ -10,10 +10,8 @@ * incompatible_with_gcov, * ] */ -(function() { -"use strict"; - load('jstests/replsets/libs/rollback_resumable_index_build.js'); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const dbName = "test"; @@ -63,4 +61,3 @@ runRollbackTo( runRollbackTo({name: "hangIndexBuildDuringBulkLoadPhaseSecond", logIdWithIndexName: 4924400}); rollbackTest.stop(); -})(); diff --git a/jstests/replsets/rollback_resumable_index_build_collection_scan_phase.js b/jstests/replsets/rollback_resumable_index_build_collection_scan_phase.js index 46d633acafb..aedd8c4c4d9 100644 --- a/jstests/replsets/rollback_resumable_index_build_collection_scan_phase.js +++ b/jstests/replsets/rollback_resumable_index_build_collection_scan_phase.js @@ -10,10 +10,8 @@ * incompatible_with_gcov, * ] */ -(function() { -"use strict"; - load('jstests/replsets/libs/rollback_resumable_index_build.js'); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const dbName = "test"; @@ -68,4 +66,3 @@ runRollbackTo("hangAfterSettingUpIndexBuild", 20387); runRollbackTo("hangIndexBuildDuringCollectionScanPhaseAfterInsertion", 20386); rollbackTest.stop(); -})(); diff --git a/jstests/replsets/rollback_resumable_index_build_collection_scan_phase_large.js b/jstests/replsets/rollback_resumable_index_build_collection_scan_phase_large.js index 75bb4e54285..5d5d98662d3 100644 --- a/jstests/replsets/rollback_resumable_index_build_collection_scan_phase_large.js +++ b/jstests/replsets/rollback_resumable_index_build_collection_scan_phase_large.js @@ -11,10 +11,8 @@ * requires_persistence, * ] */ -(function() { -"use strict"; - load('jstests/replsets/libs/rollback_resumable_index_build.js'); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const dbName = "test"; @@ -69,4 +67,3 @@ runRollbackTo("hangAfterSettingUpIndexBuild", 20387); runRollbackTo("hangIndexBuildDuringCollectionScanPhaseAfterInsertion", 20386); rollbackTest.stop(); -})(); diff --git a/jstests/replsets/rollback_resumable_index_build_drain_writes_phase.js b/jstests/replsets/rollback_resumable_index_build_drain_writes_phase.js index a1f9210613a..3a7e1de8d55 100644 --- a/jstests/replsets/rollback_resumable_index_build_drain_writes_phase.js +++ b/jstests/replsets/rollback_resumable_index_build_drain_writes_phase.js @@ -10,10 +10,8 @@ * incompatible_with_gcov, * ] */ -(function() { -"use strict"; - load('jstests/replsets/libs/rollback_resumable_index_build.js'); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const dbName = "test"; const rollbackTest = new RollbackTest(jsTestName()); @@ -81,4 +79,3 @@ runRollbackTo({name: "hangIndexBuildDuringBulkLoadPhase", logIdWithIndexName: 49 runRollbackTo({name: "hangIndexBuildDuringDrainWritesPhaseSecond", logIdWithIndexName: 4841800}); rollbackTest.stop(); -})(); diff --git a/jstests/replsets/rollback_resumable_index_build_mixed_phases.js b/jstests/replsets/rollback_resumable_index_build_mixed_phases.js index bfe18551cfe..6ce47148322 100644 --- a/jstests/replsets/rollback_resumable_index_build_mixed_phases.js +++ b/jstests/replsets/rollback_resumable_index_build_mixed_phases.js @@ -10,10 +10,8 @@ * incompatible_with_gcov, * ] */ -(function() { -"use strict"; - load('jstests/replsets/libs/rollback_resumable_index_build.js'); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const dbName = "test"; const rollbackTest = new RollbackTest(jsTestName()); @@ -137,4 +135,3 @@ runRollbackTo( [{skippedPhaseLogID: 20391}, {skippedPhaseLogID: 20392}]); rollbackTest.stop(); -})(); diff --git a/jstests/replsets/rollback_set_fcv.js b/jstests/replsets/rollback_set_fcv.js index 6bf27921f77..30371a7ca90 100644 --- a/jstests/replsets/rollback_set_fcv.js +++ b/jstests/replsets/rollback_set_fcv.js @@ -9,7 +9,7 @@ * @tags: [multiversion_incompatible] */ -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; load('jstests/libs/parallel_shell_helpers.js'); load("jstests/libs/fail_point_util.js"); load("jstests/replsets/rslib.js"); @@ -372,4 +372,4 @@ rollbackFCVFromUpgradingToDowngrading(); // Tests roll back from isCleaningServerMetadata to downgrading. rollbackFCVFromIsCleaningServerMetadataToDowngrading(); -rollbackTest.stop(); \ No newline at end of file +rollbackTest.stop(); diff --git a/jstests/replsets/rollback_test_control.js b/jstests/replsets/rollback_test_control.js index 082b05da528..627dfadf87f 100644 --- a/jstests/replsets/rollback_test_control.js +++ b/jstests/replsets/rollback_test_control.js @@ -2,10 +2,7 @@ * This test serves as a baseline for measuring the performance of the RollbackTest fixture. */ -(function() { -'use strict'; - -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; let rollbackTest = new RollbackTest(); rollbackTest.transitionToRollbackOperations(); @@ -13,4 +10,3 @@ rollbackTest.transitionToSyncSourceOperationsBeforeRollback(); rollbackTest.transitionToSyncSourceOperationsDuringRollback(); rollbackTest.transitionToSteadyStateOperations(); rollbackTest.stop(); -}()); diff --git a/jstests/replsets/rollback_transactions_count.js b/jstests/replsets/rollback_transactions_count.js index 1aa7ceeef1c..9d362f90910 100644 --- a/jstests/replsets/rollback_transactions_count.js +++ b/jstests/replsets/rollback_transactions_count.js @@ -4,10 +4,7 @@ * * @tags: [uses_transactions] */ -(function() { -"use strict"; - -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const testName = "rollback_transactions_count"; const dbName = testName; @@ -62,5 +59,4 @@ try { assert.eq(sessionColl1.find().itcount(), 3); assert.eq(primary.getDB('config')['transactions'].find().itcount(), 2); -rollbackTest.stop(); -})(); +rollbackTest.stop(); \ No newline at end of file diff --git a/jstests/replsets/rollback_unclean_shutdowns_parameter_obeyed.js b/jstests/replsets/rollback_unclean_shutdowns_parameter_obeyed.js index b60c6916131..cb2cb3ffc6b 100644 --- a/jstests/replsets/rollback_unclean_shutdowns_parameter_obeyed.js +++ b/jstests/replsets/rollback_unclean_shutdowns_parameter_obeyed.js @@ -5,10 +5,7 @@ * * @tags: [requires_persistence] */ -(function() { -"use strict"; - -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; TestData.rollbackShutdowns = true; // Only clean shutdowns should be allowed. @@ -35,5 +32,4 @@ rollbackTest.transitionToSteadyStateOperations(); // Make sure no unclean shutdowns occurred. assert.eq(rawMongoProgramOutput().search(/Detected unclean shutdown/), -1); -rollbackTest.stop(); -}()); +rollbackTest.stop(); \ No newline at end of file diff --git a/jstests/replsets/rollback_unprepared_transactions.js b/jstests/replsets/rollback_unprepared_transactions.js index b4c0bc5cb63..353ab4787c7 100644 --- a/jstests/replsets/rollback_unprepared_transactions.js +++ b/jstests/replsets/rollback_unprepared_transactions.js @@ -4,10 +4,7 @@ * requires_replication, * ] */ -(function() { -'use strict'; - -load('jstests/replsets/libs/rollback_test.js'); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; load('jstests/replsets/libs/rollback_files.js'); load("jstests/libs/uuid_util.js"); @@ -60,4 +57,3 @@ const uuid = getUUIDFromListCollections(rollbackTest.getPrimary().getDB(dbName), checkRollbackFiles(replTest.getDbPath(rollbackNode), collName, uuid, expectedDocs); rollbackTest.stop(); -})(); diff --git a/jstests/replsets/rollback_via_refetch_commit_transaction.js b/jstests/replsets/rollback_via_refetch_commit_transaction.js index 192edd5e32d..cc6c04bd9e0 100644 --- a/jstests/replsets/rollback_via_refetch_commit_transaction.js +++ b/jstests/replsets/rollback_via_refetch_commit_transaction.js @@ -12,10 +12,8 @@ TestData.skipCheckDBHashes = true; -(function() { -"use strict"; load("jstests/core/txns/libs/prepare_helpers.js"); -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const dbName = "test"; const collName = "rollback_via_refetch_commit_transaction"; @@ -82,4 +80,3 @@ assert.soon(function() { // Transaction is still in prepared state and validation will be blocked, so skip it. rst.stopSet(undefined, undefined, {skipValidation: true}); -}()); diff --git a/jstests/replsets/rollbacktest_unittest.js b/jstests/replsets/rollbacktest_unittest.js index 4cc2728b259..26c4de1fda0 100644 --- a/jstests/replsets/rollbacktest_unittest.js +++ b/jstests/replsets/rollbacktest_unittest.js @@ -1,11 +1,8 @@ /** * Test of the RollbackTest helper library. */ -(function() { -"use strict"; - load("jstests/replsets/rslib.js"); -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; let checkDataConsistencyCallCount = 0; let stopSetCallCount = 0; @@ -35,5 +32,4 @@ rollbackTest.transitionToSteadyStateOperations(); rollbackTest.stop(); assert.eq(checkDataConsistencyCallCount, 1); -assert.eq(stopSetCallCount, 1); -})(); +assert.eq(stopSetCallCount, 1); \ No newline at end of file diff --git a/jstests/replsets/tenant_migration_drop_collection.js b/jstests/replsets/tenant_migration_drop_collection.js index f856ae201df..295d921d008 100644 --- a/jstests/replsets/tenant_migration_drop_collection.js +++ b/jstests/replsets/tenant_migration_drop_collection.js @@ -27,7 +27,7 @@ import { load("jstests/libs/fail_point_util.js"); load("jstests/libs/parallelTester.js"); load("jstests/libs/uuid_util.js"); -load('jstests/replsets/libs/two_phase_drops.js'); +import {TwoPhaseDropCollectionTest} from "jstests/replsets/libs/two_phase_drops.js"; load("jstests/replsets/rslib.js"); // 'createRstArgs' function runDropTest({failPointName, failPointData, expectedLog, createNew}) { diff --git a/jstests/replsets/unpin_history_after_rollback.js b/jstests/replsets/unpin_history_after_rollback.js index 6b5f10c118b..f2241a995a9 100644 --- a/jstests/replsets/unpin_history_after_rollback.js +++ b/jstests/replsets/unpin_history_after_rollback.js @@ -14,10 +14,7 @@ * requires_persistence, * ] */ -(function() { -"use strict"; - -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; let rst = new ReplSetTest({ name: "history_rollback_test", @@ -60,5 +57,4 @@ serverStatus = rollbackNode.adminCommand("serverStatus"); pinnedTs = serverStatus["wiredTiger"]["snapshot-window-settings"]["min pinned timestamp"]; assert.eq(maxTimestampValue, pinnedTs); -rst.stopSet(); -})(); +rst.stopSet(); \ No newline at end of file diff --git a/jstests/replsets/validate_fails_during_rollback.js b/jstests/replsets/validate_fails_during_rollback.js index a448ea69178..955312b925e 100644 --- a/jstests/replsets/validate_fails_during_rollback.js +++ b/jstests/replsets/validate_fails_during_rollback.js @@ -1,10 +1,7 @@ /* * This test makes sure the 'validate' command fails correctly during rollback. */ -(function() { -"use strict"; - -load("jstests/replsets/libs/rollback_test.js"); +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const dbName = "test"; const collName = "coll"; @@ -37,5 +34,4 @@ assert.commandWorked(rollbackNode.adminCommand( rollbackTest.transitionToSteadyStateOperations(); // Check the replica set. -rollbackTest.stop(); -}()); +rollbackTest.stop(); \ No newline at end of file diff --git a/jstests/serverless/create_indexes_with_tenant_migration.js b/jstests/serverless/create_indexes_with_tenant_migration.js index 77871aa7fde..cc86befcc3e 100644 --- a/jstests/serverless/create_indexes_with_tenant_migration.js +++ b/jstests/serverless/create_indexes_with_tenant_migration.js @@ -5,13 +5,10 @@ * @tags: [requires_fcv_52, serverless] */ +import {Thread} from "jstests/libs/parallelTester_module.js"; import {ShardedServerlessTest} from "jstests/serverless/libs/sharded_serverless_test.js"; -(function() { -"use strict"; - load("jstests/libs/fail_point_util.js"); -load('jstests/concurrency/fsm_libs/worker_thread.js'); // A function, not a constant, to ensure unique UUIDs. function donorStartMigrationCmd(tenantID, realConnUrl) { @@ -129,4 +126,3 @@ let adminDB = donor.getPrimary().getDB('admin'); })(); st.stop(); -})(); diff --git a/jstests/serverless/findAndModify_with_tenant_migration.js b/jstests/serverless/findAndModify_with_tenant_migration.js index 89fda5624b5..f66069a9064 100644 --- a/jstests/serverless/findAndModify_with_tenant_migration.js +++ b/jstests/serverless/findAndModify_with_tenant_migration.js @@ -4,13 +4,10 @@ * @tags: [requires_fcv_52, serverless] */ +import {Thread} from "jstests/libs/parallelTester_module.js"; import {ShardedServerlessTest} from "jstests/serverless/libs/sharded_serverless_test.js"; -(function() { -"use strict"; - load("jstests/libs/fail_point_util.js"); -load('jstests/concurrency/fsm_libs/worker_thread.js'); function donorStartMigrationCmd(tenantID, realConnUrl) { return { @@ -176,4 +173,3 @@ let adminDB = st.rs0.getPrimary().getDB('admin'); })(); st.stop(); -})(); diff --git a/jstests/serverless/multitenancy_rollback_crud_op.js b/jstests/serverless/multitenancy_rollback_crud_op.js index b44f13e19c7..ba243b37d07 100644 --- a/jstests/serverless/multitenancy_rollback_crud_op.js +++ b/jstests/serverless/multitenancy_rollback_crud_op.js @@ -2,10 +2,7 @@ * Test of a successfull replica set rollback for basic CRUD operations in multitenancy environment * with featureFlagRequireTenantId. This test is modeled from rollback_crud_ops_sequence.js. */ -load('jstests/replsets/libs/rollback_test.js'); - -(function() { -"use strict"; +import {RollbackTest} from "jstests/replsets/libs/rollback_test.js"; const kColl = "bar"; const tenantA = ObjectId(); @@ -166,4 +163,3 @@ checkFinalResults(rollbackNodeDB); checkFinalResults(syncSourceDB); rollbackTest.stop(); -}()); diff --git a/jstests/serverless/tenant_migration_concurrent_bulk_writes_against_mongoq.js b/jstests/serverless/tenant_migration_concurrent_bulk_writes_against_mongoq.js index 2166714f732..012e61d3ecb 100644 --- a/jstests/serverless/tenant_migration_concurrent_bulk_writes_against_mongoq.js +++ b/jstests/serverless/tenant_migration_concurrent_bulk_writes_against_mongoq.js @@ -4,13 +4,10 @@ * @tags: [requires_fcv_52, serverless] */ +import {Thread} from "jstests/libs/parallelTester_module.js"; import {ShardedServerlessTest} from "jstests/serverless/libs/sharded_serverless_test.js"; -(function() { -"use strict"; - load("jstests/libs/fail_point_util.js"); -load('jstests/concurrency/fsm_libs/worker_thread.js'); function donorStartMigrationCmd(tenantID, realConnUrl) { return { @@ -143,4 +140,3 @@ orderedBulkInsertAfterTenantMigrationAborted(st, true); orderedBulkInsertAfterTenantMigrationAborted(st, false); st.stop(); -})(); diff --git a/jstests/sharding/change_stream_metadata_notifications.js b/jstests/sharding/change_stream_metadata_notifications.js index 3f66edafe9e..5b7c263aa50 100644 --- a/jstests/sharding/change_stream_metadata_notifications.js +++ b/jstests/sharding/change_stream_metadata_notifications.js @@ -2,11 +2,7 @@ // @tags: [ // requires_majority_read_concern, // ] -(function() { -"use strict"; - load("jstests/libs/collection_drop_recreate.js"); // For assertDropAndRecreateCollection. -load('jstests/replsets/libs/two_phase_drops.js'); // For TwoPhaseDropCollectionTest. const st = new ShardingTest({ shards: 2, @@ -179,5 +175,4 @@ assert.soon(() => { }); assert.eq(resumeStream1.getResumeToken(), dbDropInvalidateToken); -st.stop(); -})(); +st.stop(); \ No newline at end of file diff --git a/jstests/sharding/change_streams.js b/jstests/sharding/change_streams.js index ad99d6caf95..62091f72cf1 100644 --- a/jstests/sharding/change_streams.js +++ b/jstests/sharding/change_streams.js @@ -3,12 +3,9 @@ // requires_majority_read_concern, // uses_change_streams, // ] -(function() { -"use strict"; - -load('jstests/replsets/libs/two_phase_drops.js'); // For TwoPhaseDropCollectionTest. -load('jstests/aggregation/extras/utils.js'); // For assertErrorCode(). -load('jstests/libs/change_stream_util.js'); // For assertChangeStreamEventEq. +import {TwoPhaseDropCollectionTest} from "jstests/replsets/libs/two_phase_drops.js"; +load('jstests/aggregation/extras/utils.js'); // For assertErrorCode(). +load('jstests/libs/change_stream_util.js'); // For assertChangeStreamEventEq. function runTest(collName, shardKey) { const st = new ShardingTest({ @@ -265,4 +262,3 @@ function runTest(collName, shardKey) { runTest('with_id_shard_key', '_id'); runTest('with_non_id_shard_key', 'non_id'); -})(); diff --git a/jstests/sharding/change_streams_whole_db.js b/jstests/sharding/change_streams_whole_db.js index bd1bfe64f21..0dfad25bb09 100644 --- a/jstests/sharding/change_streams_whole_db.js +++ b/jstests/sharding/change_streams_whole_db.js @@ -3,10 +3,6 @@ // requires_majority_read_concern, // uses_change_streams, // ] -(function() { -"use strict"; - -load('jstests/replsets/libs/two_phase_drops.js'); // For TwoPhaseDropCollectionTest. load('jstests/aggregation/extras/utils.js'); // For assertErrorCode(). load('jstests/libs/change_stream_util.js'); // For ChangeStreamTest. load("jstests/libs/collection_drop_recreate.js"); // For assertDropCollection. @@ -183,5 +179,4 @@ cst.assertNextChangesEqual({ cst.cleanUp(); -st.stop(); -})(); +st.stop(); \ No newline at end of file diff --git a/src/mongo/shell/replsettest.js b/src/mongo/shell/replsettest.js index 545d7dd3cbb..b57c0207298 100644 --- a/src/mongo/shell/replsettest.js +++ b/src/mongo/shell/replsettest.js @@ -3320,7 +3320,14 @@ var ReplSetTest = function ReplSetTest(opts) { // Perform collection validation on each node in parallel. let validators = []; for (let i = 0; i < ports.length; i++) { - let validator = new Thread(MongoRunner.validateCollectionsCallback, this.ports[i]); + let validator = new Thread(async function(port) { + const {CommandSequenceWithRetries} = + await import("jstests/libs/command_sequence_with_retries.js"); + const {validateCollections} = await import("jstests/hooks/validate_collections.js"); + await import("jstests/libs/override_methods/validate_collections_on_shutdown.js"); + MongoRunner.validateCollectionsCallback( + port, {CommandSequenceWithRetries, validateCollections}); + }, ports[i]); validators.push(validator); validators[i].start(); } diff --git a/src/mongo/shell/servers.js b/src/mongo/shell/servers.js index c52cb86a7f1..cae8bfb0315 100644 --- a/src/mongo/shell/servers.js +++ b/src/mongo/shell/servers.js @@ -1151,7 +1151,7 @@ MongoRunner.EXIT_UNCAUGHT = 100; // top level exception that wasn't caught MongoRunner.EXIT_TEST = 101; MongoRunner.EXIT_AUDIT_ROTATE_ERROR = 102; -MongoRunner.validateCollectionsCallback = function(port) {}; +MongoRunner.validateCollectionsCallback = function(port, options) {}; /** * Kills a mongod process.