summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXuerui Fa <xuerui.fa@mongodb.com>2024-04-03 19:46:32 -0400
committerMongoDB Bot <mongo-bot@mongodb.com>2024-04-03 23:54:34 +0000
commitfb78dc746d92d85b1ad752eb9236a058912f2452 (patch)
tree88543ddb3b9e4c8b31e7ff3717b58f929302dfef
parent3a678285957b4a1695aa7d3ba65e90ceadf8db27 (diff)
SERVER-87898: Prepare server for FCV 8.1 upgrade (#20740)r8.1.0-alpha
GitOrigin-RevId: 0a8d8383477d3c96c5443e33242da2d74620ca21
-rw-r--r--buildscripts/resmokeconfig/matrix_suites/generated_suites/multiversion_auth_future_git_tag.yml1
-rw-r--r--buildscripts/resmokeconfig/matrix_suites/overrides/multiversion.yml1
-rw-r--r--buildscripts/resmokeconfig/suites/fcv_upgrade_downgrade_replica_sets_jscore_passthrough.yml1
-rw-r--r--buildscripts/resmokeconfig/suites/fcv_upgrade_downgrade_sharded_collections_jscore_passthrough.yml1
-rw-r--r--buildscripts/resmokeconfig/suites/fcv_upgrade_downgrade_sharding_jscore_passthrough.yml1
-rw-r--r--buildscripts/resmokeconfig/suites/multiversion_auth.yml1
-rw-r--r--evergreen/multiversion_setup.sh2
-rw-r--r--jstests/multiVersion/downgrade_fcv_only_if_internal_transaction_is_not_prepared.js119
-rw-r--r--jstests/multiVersion/genericBinVersion/timeseries_collection_mixed_type.js1
-rw-r--r--jstests/multiVersion/genericBinVersion/truncate_retryable_write_sessions_on_downgrade.js2
-rw-r--r--jstests/multiVersion/genericSetFCVUsage/major_version_upgrade.js1
-rw-r--r--jstests/multiVersion/libs/dbcheck_old_format_keys_test.js3
-rw-r--r--jstests/multiVersion/targetedTestsLastLtsFeatures/bindata_convert_view_upgrade_downgrade.js136
-rw-r--r--jstests/multiVersion/targetedTestsLastLtsFeatures/change_stream_pre_image_truncate_with_mixed_version_replicaset.js169
-rw-r--r--jstests/multiVersion/targetedTestsLastLtsFeatures/change_stream_v1_v2_within_txn.js62
-rw-r--r--jstests/multiVersion/targetedTestsLastLtsFeatures/change_streams_split_event_v1_v2_tokens.js222
-rw-r--r--jstests/multiVersion/targetedTestsLastLtsFeatures/dbcheck_invocation_mixed_versions.js33
-rw-r--r--jstests/multiVersion/targetedTestsLastLtsFeatures/downgrade_from_autobootstrapped_cluster.js349
-rw-r--r--jstests/multiVersion/targetedTestsLastLtsFeatures/fle2_range_preview_rename.js183
-rw-r--r--jstests/multiVersion/targetedTestsLastLtsFeatures/multi_update_coordinator_downgrade.js82
-rw-r--r--jstests/multiVersion/targetedTestsLastLtsFeatures/oidc_multipurpose_idp.js163
-rw-r--r--jstests/multiVersion/targetedTestsLastLtsFeatures/query_stats_upgrade_downgrade.js268
-rw-r--r--jstests/multiVersion/targetedTestsLastLtsFeatures/timeseries_fixed_bucket_match_rewrite.js153
-rw-r--r--jstests/multiVersion/targetedTestsLastLtsFeatures/timeseries_fixed_param_flag.js105
-rw-r--r--jstests/noPassthrough/index_build_aborted_on_fcv_downgrade.js195
-rw-r--r--jstests/noPassthrough/queryStats/query_stats_disable_after_initial_request.js26
-rw-r--r--jstests/noPassthrough/queryStats/query_stats_upgrade.js41
-rw-r--r--jstests/serverless/shard_merge_enabled.js124
-rw-r--r--src/mongo/util/version/releases.yml2
29 files changed, 21 insertions, 2426 deletions
diff --git a/buildscripts/resmokeconfig/matrix_suites/generated_suites/multiversion_auth_future_git_tag.yml b/buildscripts/resmokeconfig/matrix_suites/generated_suites/multiversion_auth_future_git_tag.yml
index 82bf30d5418..d48d7f0cfa1 100644
--- a/buildscripts/resmokeconfig/matrix_suites/generated_suites/multiversion_auth_future_git_tag.yml
+++ b/buildscripts/resmokeconfig/matrix_suites/generated_suites/multiversion_auth_future_git_tag.yml
@@ -32,7 +32,6 @@ selector:
- jstests/multiVersion/genericBinVersion/minor_version_tags_new_old_new.js
- jstests/multiVersion/genericSetFCVUsage/crash_mongos_against_upgraded_cluster.js
- jstests/multiVersion/genericBinVersion/load_keys_on_upgrade.js
- - jstests/multiVersion/targetedTestsLastLtsFeatures/oidc_multipurpose_idp.js
exclude_with_any_tags:
- DISABLED_TEMPORARILY_DUE_TO_FCV_UPGRADE
roots:
diff --git a/buildscripts/resmokeconfig/matrix_suites/overrides/multiversion.yml b/buildscripts/resmokeconfig/matrix_suites/overrides/multiversion.yml
index e168edc0bda..ce8555f9a21 100644
--- a/buildscripts/resmokeconfig/matrix_suites/overrides/multiversion.yml
+++ b/buildscripts/resmokeconfig/matrix_suites/overrides/multiversion.yml
@@ -149,7 +149,6 @@
# Skip any tests that run with auth explicitly.
- jstests/multiVersion/genericBinVersion/load_keys_on_upgrade.js
- - jstests/multiVersion/targetedTestsLastLtsFeatures/oidc_multipurpose_idp.js
exclude_with_any_tags:
- DISABLED_TEMPORARILY_DUE_TO_FCV_UPGRADE
executor:
diff --git a/buildscripts/resmokeconfig/suites/fcv_upgrade_downgrade_replica_sets_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/fcv_upgrade_downgrade_replica_sets_jscore_passthrough.yml
index be13188c6e8..b6ef585ed7e 100644
--- a/buildscripts/resmokeconfig/suites/fcv_upgrade_downgrade_replica_sets_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/fcv_upgrade_downgrade_replica_sets_jscore_passthrough.yml
@@ -28,6 +28,7 @@ selector:
- requires_fcv_72
- requires_fcv_73
- requires_fcv_80
+ - requires_fcv_81
# Exclude tests that are not compatible with upgrade/downgrade.
- cannot_run_during_upgrade_downgrade
diff --git a/buildscripts/resmokeconfig/suites/fcv_upgrade_downgrade_sharded_collections_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/fcv_upgrade_downgrade_sharded_collections_jscore_passthrough.yml
index 79c99084b3c..a1296cfb261 100644
--- a/buildscripts/resmokeconfig/suites/fcv_upgrade_downgrade_sharded_collections_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/fcv_upgrade_downgrade_sharded_collections_jscore_passthrough.yml
@@ -197,6 +197,7 @@ selector:
- requires_fcv_72
- requires_fcv_73
- requires_fcv_80
+ - requires_fcv_81
# Exclude tests that are not compatible with upgrade/downgrade.
- cannot_run_during_upgrade_downgrade
diff --git a/buildscripts/resmokeconfig/suites/fcv_upgrade_downgrade_sharding_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/fcv_upgrade_downgrade_sharding_jscore_passthrough.yml
index ed645ac1c80..908e723d9c5 100644
--- a/buildscripts/resmokeconfig/suites/fcv_upgrade_downgrade_sharding_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/fcv_upgrade_downgrade_sharding_jscore_passthrough.yml
@@ -150,6 +150,7 @@ selector:
- requires_fcv_72
- requires_fcv_73
- requires_fcv_80
+ - requires_fcv_81
# Exclude tests that are not compatible with upgrade/downgrade.
- cannot_run_during_upgrade_downgrade
diff --git a/buildscripts/resmokeconfig/suites/multiversion_auth.yml b/buildscripts/resmokeconfig/suites/multiversion_auth.yml
index 367f699ae84..af4df130c99 100644
--- a/buildscripts/resmokeconfig/suites/multiversion_auth.yml
+++ b/buildscripts/resmokeconfig/suites/multiversion_auth.yml
@@ -21,7 +21,6 @@ selector:
# Skip any tests that run with auth explicitly.
- jstests/multiVersion/genericBinVersion/load_keys_on_upgrade.js
- - jstests/multiVersion/targetedTestsLastLtsFeatures/oidc_multipurpose_idp.js
exclude_with_any_tags:
- featureFlagToaster
diff --git a/evergreen/multiversion_setup.sh b/evergreen/multiversion_setup.sh
index c1cbc3ebae6..7a6e5f782b7 100644
--- a/evergreen/multiversion_setup.sh
+++ b/evergreen/multiversion_setup.sh
@@ -41,7 +41,7 @@ local_args="--edition $edition \
--resmokeCmd \"python buildscripts/resmoke.py\" \
--debug \
${last_lts_arg} \
- ${last_continuous_arg} 4.2 4.4 5.0 6.0"
+ ${last_continuous_arg} 4.2 4.4 5.0 6.0 7.0"
remote_invocation="${base_command} ${evergreen_args} ${local_args}"
eval "${remote_invocation}"
diff --git a/jstests/multiVersion/downgrade_fcv_only_if_internal_transaction_is_not_prepared.js b/jstests/multiVersion/downgrade_fcv_only_if_internal_transaction_is_not_prepared.js
deleted file mode 100644
index 6648b16afba..00000000000
--- a/jstests/multiVersion/downgrade_fcv_only_if_internal_transaction_is_not_prepared.js
+++ /dev/null
@@ -1,119 +0,0 @@
-/**
- * Verify that during FCV downgrade we abort unprepared internal
- * transactions and wait for prepared internal transactions to
- * commit or abort.
- *
- * This test verifies this behavior with internal transactions in sessions with
- * retryableWrite: {false, true}, distinguished through the specification of txnNumber in their
- * lsids. Variables named with 0 correlates to the former and 1 with the latter.
- * @tags: [requires_fcv_60]
- */
-import {configureFailPoint} from "jstests/libs/fail_point_util.js";
-import {
- makeAbortTransactionCmdObj,
- makePrepareTransactionCmdObj
-} from "jstests/sharding/libs/sharded_transactions_helpers.js";
-
-const kDbName = "testDb";
-const kCollName = "testColl";
-let stmtId = 0;
-
-function makeInsertCmdObj(childLsid, txnNumber, startTransaction) {
- const cmdObj = {
- insert: kCollName,
- documents: [{x: 0}],
- lsid: childLsid,
- txnNumber: txnNumber,
- stmtId: NumberInt(stmtId++),
- autocommit: false,
- };
- if (startTransaction) {
- cmdObj.startTransaction = true;
- }
-
- return cmdObj;
-}
-
-(() => {
- jsTest.log(
- "Verify internal transactions in an in-progress, unprepared state are aborted when FCV is downgraded.");
-
- const st = new ShardingTest({shards: {rs0: {nodes: 2}}});
- const shard0Rst = st.rs0;
- const shard0Primary = shard0Rst.getPrimary();
-
- const testDB = shard0Primary.getDB(kDbName);
-
- const sessionUUID = UUID();
- const childLsid0 = {id: sessionUUID, txnUUID: UUID()};
- const childLsid1 = {id: sessionUUID, txnNumber: NumberLong(5), txnUUID: UUID()};
-
- // Start internal transactions inside sessions with retryableWrite: {false, true}.
- assert.commandWorked(testDB.runCommand(makeInsertCmdObj(childLsid0, NumberLong(0), true)));
- assert.commandWorked(testDB.runCommand(makeInsertCmdObj(childLsid1, NumberLong(0), true)));
-
- // By being unable to insert documents, verify that both transactions are aborted when FCV is
- // downgraded.
- assert.commandWorked(
- shard0Primary.adminCommand({setFeatureCompatibilityVersion: lastLTSFCV, confirm: true}));
-
- assert.commandFailedWithCode(testDB.runCommand(makeInsertCmdObj(childLsid0, NumberLong(0))),
- ErrorCodes.NoSuchTransaction);
- assert.commandFailedWithCode(testDB.runCommand(makeInsertCmdObj(childLsid1, NumberLong(0))),
- ErrorCodes.NoSuchTransaction);
-
- st.stop();
-})();
-
-(() => {
- jsTest.log(
- "Verify FCV cannot be downgraded when a session has a prepared internal transaction until the transaction is out of the prepared state (either aborted or committed).");
-
- const st = new ShardingTest({shards: 1});
- const shard0Rst = st.rs0;
- const shard0Primary = shard0Rst.getPrimary();
-
- const testDB = shard0Primary.getDB(kDbName);
- const adminDB = shard0Primary.getDB("admin");
-
- const sessionUUID = UUID();
- const childLsid0 = {id: sessionUUID, txnUUID: UUID()};
- const childLsid1 = {id: sessionUUID, txnNumber: NumberLong(5), txnUUID: UUID()};
-
- assert.commandWorked(testDB.createCollection(kCollName));
-
- // Start internal transactions for writes executed in sessions with retryableWrite: {false,
- // true} and bring to prepared state.
- assert.commandWorked(testDB.runCommand(makeInsertCmdObj(childLsid0, NumberLong(0), true)));
- assert.commandWorked(testDB.runCommand(makeInsertCmdObj(childLsid1, NumberLong(0), true)));
-
- assert.commandWorked(
- shard0Primary.adminCommand(makePrepareTransactionCmdObj(childLsid0, NumberLong(0))));
- assert.commandWorked(
- shard0Primary.adminCommand(makePrepareTransactionCmdObj(childLsid1, NumberLong(0))));
-
- // The setFCV command will need to acquire a global S lock to complete. The global
- // lock is currently held by prepare, so that will block. We use a failpoint to make that
- // command fails when it tries to get the lock.
- let fp = configureFailPoint(shard0Primary, "failNonIntentLocksIfWaitNeeded");
- assert.commandFailedWithCode(
- testDB.adminCommand({setFeatureCompatibilityVersion: lastLTSFCV, confirm: true}),
- ErrorCodes.LockTimeout);
- fp.wait();
- fp.off();
-
- assert.commandWorked(adminDB.runCommand(makeAbortTransactionCmdObj(childLsid0, NumberLong(0))));
- fp = configureFailPoint(shard0Primary, "failNonIntentLocksIfWaitNeeded");
- assert.commandFailedWithCode(
- testDB.adminCommand({setFeatureCompatibilityVersion: lastLTSFCV, confirm: true}),
- ErrorCodes.LockTimeout);
- fp.wait();
- fp.off();
- assert.commandWorked(adminDB.runCommand(makeAbortTransactionCmdObj(childLsid1, NumberLong(0))));
-
- // We are able to downgrade FCV only when both transactions are no longer in the prepared state.
- assert.commandWorked(
- shard0Primary.adminCommand({setFeatureCompatibilityVersion: lastLTSFCV, confirm: true}));
-
- st.stop();
-})(); \ No newline at end of file
diff --git a/jstests/multiVersion/genericBinVersion/timeseries_collection_mixed_type.js b/jstests/multiVersion/genericBinVersion/timeseries_collection_mixed_type.js
index 2fff9a58098..1a1ab164cd6 100644
--- a/jstests/multiVersion/genericBinVersion/timeseries_collection_mixed_type.js
+++ b/jstests/multiVersion/genericBinVersion/timeseries_collection_mixed_type.js
@@ -13,6 +13,7 @@ const timeFieldName = "time";
// Note that this list will need to be kept up to date as versions are added/dropped.
const upgradeVersions = [
{binVersion: "6.0", fcv: "6.0"},
+ {binVersion: "7.0", fcv: "7.0"},
{binVersion: "last-lts", fcv: lastLTSFCV},
{binVersion: "latest"}
];
diff --git a/jstests/multiVersion/genericBinVersion/truncate_retryable_write_sessions_on_downgrade.js b/jstests/multiVersion/genericBinVersion/truncate_retryable_write_sessions_on_downgrade.js
index 6710db83c4d..41eceadbeaa 100644
--- a/jstests/multiVersion/genericBinVersion/truncate_retryable_write_sessions_on_downgrade.js
+++ b/jstests/multiVersion/genericBinVersion/truncate_retryable_write_sessions_on_downgrade.js
@@ -5,6 +5,8 @@
*
* TODO(SERVER-84271): Remove this test when featureFlagReplicateVectoredInsertsTransactionally is
* removed.
+ *
+ * @tags: [DISABLED_TEMPORARILY_DUE_TO_FCV_UPGRADE]
*/
import "jstests/multiVersion/libs/multi_rs.js";
diff --git a/jstests/multiVersion/genericSetFCVUsage/major_version_upgrade.js b/jstests/multiVersion/genericSetFCVUsage/major_version_upgrade.js
index e1fcbe18b4d..b81962b9311 100644
--- a/jstests/multiVersion/genericSetFCVUsage/major_version_upgrade.js
+++ b/jstests/multiVersion/genericSetFCVUsage/major_version_upgrade.js
@@ -33,6 +33,7 @@ const versions = [
{binVersion: '4.4', featureCompatibilityVersion: '4.4', testCollection: 'four_four'},
{binVersion: '5.0', featureCompatibilityVersion: '5.0', testCollection: 'five_zero'},
{binVersion: '6.0', featureCompatibilityVersion: '6.0', testCollection: 'six_zero'},
+ {binVersion: '7.0', featureCompatibilityVersion: '7.0', testCollection: 'seven_zero'},
{binVersion: 'last-lts', featureCompatibilityVersion: lastLTSFCV, testCollection: 'last_lts'},
{
binVersion: 'last-continuous',
diff --git a/jstests/multiVersion/libs/dbcheck_old_format_keys_test.js b/jstests/multiVersion/libs/dbcheck_old_format_keys_test.js
index b903299cf31..8879e7995f0 100644
--- a/jstests/multiVersion/libs/dbcheck_old_format_keys_test.js
+++ b/jstests/multiVersion/libs/dbcheck_old_format_keys_test.js
@@ -26,7 +26,8 @@ const upgradeVersions = {
"4.4": {"fcv": "5.0", "nextVersion": "5.0"},
"5.0": {"fcv": "6.0", "nextVersion": "6.0"},
"6.0": {"fcv": "7.0", "nextVersion": "7.0"},
- "7.0": {"fcv": "8.0", "nextVersion": "latest"},
+ "7.0": {"fcv": "8.0", "nextVersion": "8.0"},
+ "8.0": {"fcv": "8.1", "nextVersion": "latest"},
// TODO (SERVER-66611): Automate modifying this list.
"latest": {}
}
diff --git a/jstests/multiVersion/targetedTestsLastLtsFeatures/bindata_convert_view_upgrade_downgrade.js b/jstests/multiVersion/targetedTestsLastLtsFeatures/bindata_convert_view_upgrade_downgrade.js
deleted file mode 100644
index 4de12016fa4..00000000000
--- a/jstests/multiVersion/targetedTestsLastLtsFeatures/bindata_convert_view_upgrade_downgrade.js
+++ /dev/null
@@ -1,136 +0,0 @@
-/**
- * Verifies that BinData $convert behaves correctly in FCV upgrade/downgrade scenarios.
- */
-
-import "jstests/multiVersion/libs/multi_rs.js";
-import {assertDropAndRecreateCollection} from "jstests/libs/collection_drop_recreate.js";
-
-const lastLTSVersion = {
- binVersion: "last-lts"
-};
-const latestVersion = {
- binVersion: "latest"
-};
-
-const collectionName = "coll";
-
-const rst = new ReplSetTest({
- name: jsTestName(),
- nodes: [
- {...lastLTSVersion},
- {...lastLTSVersion},
- ],
-});
-rst.startSet();
-rst.initiate();
-
-const getAdminDB = () => rst.getPrimary().getDB("admin");
-const getDB = () => rst.getPrimary().getDB(jsTestName());
-
-const coll = assertDropAndRecreateCollection(getDB(), collectionName);
-assert.commandWorked(coll.insertMany([
- {
- _id: 0,
- asUuid: UUID("867dee52-c331-484e-92d1-c56479b8e67e"),
- asString: "867dee52-c331-484e-92d1-c56479b8e67e",
- },
- {
- _id: 1,
- asUuid: UUID("b6684187-f74d-4872-818f-7a6e97fd5c04"),
- asString: "b6684187-f74d-4872-818f-7a6e97fd5c04",
- },
-]));
-
-const toUUIDViewName = "toUUIDView";
-const toUUIDPipeline = [{$project: {uuidFromString: {$toUUID: "$asString"}}}];
-
-const toStringViewName = "toStringView";
-const toStringPipeline = [{$project: {stringFromUuid: {$toString: "$asUuid"}}}];
-
-{
- const db = getDB();
-
- // View creation fails due to unknown $toUUID syntax.
- db[toUUIDViewName].drop();
- assert.commandFailedWithCode(db.createView(toUUIDViewName, collectionName, toUUIDPipeline),
- 31325);
-
- // View creation succeeds, but queries on the view fail due to unsupported bindata-to-string
- // conversion.
- db[toStringViewName].drop();
- assert.commandWorked(db.createView(toStringViewName, collectionName, toStringPipeline));
- assert.commandFailedWithCode(db.runCommand({find: toStringViewName, filter: {}}),
- ErrorCodes.ConversionFailure);
-}
-
-// Upgrade the binaries and the FCV.
-rst.upgradeSet({...latestVersion});
-assert.commandWorked(
- getAdminDB().runCommand({setFeatureCompatibilityVersion: latestFCV, confirm: true}));
-
-{
- // View creation and usage both succeed after upgrade.
- const db = getDB();
-
- db[toUUIDViewName].drop();
- assert.commandWorked(db.createView(toUUIDViewName, collectionName, toUUIDPipeline));
- assert.commandWorked(db.runCommand({find: toUUIDViewName, filter: {}}));
-
- db[toStringViewName].drop();
- assert.commandWorked(db.createView(toStringViewName, collectionName, toStringPipeline));
- assert.commandWorked(db.runCommand({find: toStringViewName, filter: {}}));
-}
-
-// Downgrade FCV without restarting.
-assert.commandWorked(
- getAdminDB().runCommand({setFeatureCompatibilityVersion: lastLTSFCV, confirm: true}));
-
-{
- const db = getDB();
-
- // Queries on views using BinData $convert should fail after downgrading the FCV.
- assert.commandFailedWithCode(db.runCommand({find: toUUIDViewName, filter: {}}),
- ErrorCodes.QueryFeatureNotAllowed);
- assert.commandFailedWithCode(db.runCommand({find: toStringViewName, filter: {}}),
- ErrorCodes.ConversionFailure);
-
- // BinData to string conversion still succeeds with onError value.
- assert.commandWorked(db.runCommand({
- aggregate: collectionName,
- cursor: {},
- pipeline: [{
- $project: {
- stringFromUuid: {
- $convert: {
- input: "$asUuid",
- to: "string",
- onError: "NULL",
- }
- }
- }
- }]
- }));
-
- // However, it should not succeed with a 'format' argument.
- assert.commandFailedWithCode(
- db.runCommand({
- aggregate: collectionName,
- cursor: {},
- pipeline: [{
- $project: {
- stringFromUuid: {
- $convert: {
- input: "$asUuid",
- to: "string",
- format: "uuid",
- onError: "NULL",
- }
- }
- }
- }]
- }),
- ErrorCodes.FailedToParse,
- );
-}
-
-rst.stopSet();
diff --git a/jstests/multiVersion/targetedTestsLastLtsFeatures/change_stream_pre_image_truncate_with_mixed_version_replicaset.js b/jstests/multiVersion/targetedTestsLastLtsFeatures/change_stream_pre_image_truncate_with_mixed_version_replicaset.js
deleted file mode 100644
index 4da21202e9e..00000000000
--- a/jstests/multiVersion/targetedTestsLastLtsFeatures/change_stream_pre_image_truncate_with_mixed_version_replicaset.js
+++ /dev/null
@@ -1,169 +0,0 @@
-// Tests behaviour of the preimage remover where initially the primary and secondary are on
-// different binary versions, and the behaviour after upgrading to latest.
-//
-// @tags: [
-// requires_fcv_72,
-// requires_replication,
-// ]
-import "jstests/multiVersion/libs/multi_rs.js";
-import {getPreImagesCollection} from "jstests/libs/change_stream_util.js";
-import {configureFailPoint} from "jstests/libs/fail_point_util.js";
-import {
- setupTimeBasedPreImageRetentionPolicyTest,
- verifyPreImages
-} from "jstests/noPassthrough/libs/change_stream_pre_image_time_based_expiration_utils.js";
-
-function serverParametersForVersionString(version) {
- let options = {
- binVersion: version,
- };
- // Reduce period of removal job to speed up test.
- let serverParams = {expiredChangeStreamPreImageRemovalJobSleepSecs: 1};
- if (version == "latest") {
- serverParams["preImagesCollectionTruncateMarkersMinBytes"] = 1;
- }
- options["setParameter"] = serverParams;
- return options;
-}
-
-function setupMixedVersionReplicaSetTest(binVersionList) {
- const nodeOptions = binVersionList.map(serverParametersForVersionString);
-
- const rst = new ReplSetTest({nodes: nodeOptions});
- rst.startSet();
- // Allow test cases to have complete control over which node is primary.
- rst.initiateWithHighElectionTimeout();
-
- return rst;
-}
-
-function setChangeStreamPreImageRemoverCurrentTimeAndWaitForAllNodes(
- rst, currentTimeForTimeBasedExpiration) {
- rst.nodes.forEach(node => {
- const currentTimeFailPoint = configureFailPoint(
- node,
- "changeStreamPreImageRemoverCurrentTime",
- {currentTimeForTimeBasedExpiration: currentTimeForTimeBasedExpiration});
-
- // Wait until at least 1 complete cycle of pre-image removal job is completed.
- currentTimeFailPoint.wait({timesEntered: 2});
- });
-}
-
-function verifyPreImagesForAllNodes(rst, expectedPreImagesForNodes, collectionsInfo) {
- // Verify that at some point in time, all expired pre-images will be deleted.
- rst.nodes.forEach((node, idx) => {
- const preImageColl = getPreImagesCollection(node);
- assert.soon(
- () => {
- return preImageColl.find().toArray().length ==
- expectedPreImagesForNodes[idx].length;
- },
- () => {
- const preImages = preImageColl.find().toArray();
- return `Host (${node.host}): expected ${
- tojson(expectedPreImagesForNodes[idx])} for collectionsInfo ${
- tojson(collectionsInfo)} but found ${tojson(preImages)}`;
- });
- verifyPreImages(preImageColl, expectedPreImagesForNodes[idx], collectionsInfo);
-
- if (node.host === rst.getPrimary().host) {
- // Await for primary to replicate deletes, in case it does not use unreplicated
- // truncates.
- rst.awaitReplication();
- }
- });
-}
-
-function setExpireAfterSeconds(rst, expireAfterSeconds) {
- // Enable time-based pre-image expiration and configure the 'expireAfterSeconds'.
- assert.commandWorked(rst.getPrimary().getDB("admin").runCommand({
- setClusterParameter:
- {changeStreamOptions: {preAndPostImages: {expireAfterSeconds: expireAfterSeconds}}}
- }));
-}
-
-// Test case: primary using truncate deletes, secondary with replicated deletes.
-// The secondary is expected to not delete anything because the primary is not replicating deletes.
-// The situation should be resolved on upgrading the node.
-function testPrimaryLatestSecondariesLastLts(shouldTruncateAllAfterUpgrade) {
- jsTestLog("Running testPrimaryLatestSecondariesLastLts. shouldTruncateAllAfterUpgrade: " +
- shouldTruncateAllAfterUpgrade);
-
- const rst = setupMixedVersionReplicaSetTest(["latest", "last-lts"]);
- const primary = rst.getPrimary();
- const expireAfterSeconds = shouldTruncateAllAfterUpgrade ? 1 : 3600;
- const {currentTimeForTimeBasedExpiration, _unused, shouldRetainDocs, allDocs, collectionsInfo} =
- setupTimeBasedPreImageRetentionPolicyTest(primary, primary, expireAfterSeconds);
-
- // Fix wall time used by pre image remover.
- setChangeStreamPreImageRemoverCurrentTimeAndWaitForAllNodes(rst,
- currentTimeForTimeBasedExpiration);
-
- // Verify that when time-based pre-image expiration disabled, no pre-images are not deleted.
- verifyPreImagesForAllNodes(rst, [allDocs, allDocs], collectionsInfo);
-
- // Enable time based expiration.
- setExpireAfterSeconds(rst, expireAfterSeconds);
-
- // The secondary is expected to not have removed any documents.
- verifyPreImagesForAllNodes(rst, [shouldRetainDocs, allDocs], collectionsInfo);
-
- // After upgrading the secondary to a version with truncate deletes, the preImages should be
- // deleted.
- rst.upgradeSecondaries(serverParametersForVersionString("latest"));
-
- // With shouldTruncateAllAfterUpgrade there's no need to simulate the current time given
- // the low value for expireAfterSeconds (and that we want all documents to be truncated).
- if (!shouldTruncateAllAfterUpgrade) {
- // On the other hand, if we expect some documents to survive, we need to re-enable the
- // failpoint to simulate the time to force expiration.
- setChangeStreamPreImageRemoverCurrentTimeAndWaitForAllNodes(
- rst, currentTimeForTimeBasedExpiration);
- }
- const upgradedNodeExpectedDocs = shouldTruncateAllAfterUpgrade ? [] : shouldRetainDocs;
- verifyPreImagesForAllNodes(rst, [shouldRetainDocs, upgradedNodeExpectedDocs], collectionsInfo);
-
- rst.stopSet();
-}
-
-// Test case: primary using replicated deletes, secondary using truncate deletes.
-// The secondary might try to delete the same document both with truncate and by applying the
-// replicated delete. This should be fine.
-function testPrimaryLastLtsSecondariesLatest(shouldTruncateAllAfterUpgrade) {
- jsTestLog("Running testPrimaryLastLtsSecondariesLatest. shouldTruncateAllAfterUpgrade: " +
- shouldTruncateAllAfterUpgrade);
- const rst = setupMixedVersionReplicaSetTest(["last-lts", "latest"]);
- const primary = rst.getPrimary();
- const expireAfterSeconds = shouldTruncateAllAfterUpgrade ? 1 : 3600;
- const {currentTimeForTimeBasedExpiration, _unused, shouldRetainDocs, allDocs, collectionsInfo} =
- setupTimeBasedPreImageRetentionPolicyTest(primary, primary, expireAfterSeconds);
-
- // Fix wall time used by pre image remover.
- setChangeStreamPreImageRemoverCurrentTimeAndWaitForAllNodes(rst,
- currentTimeForTimeBasedExpiration);
-
- // Verify that when time-based pre-image expiration disabled, no pre-images are not deleted.
- verifyPreImagesForAllNodes(rst, [allDocs, allDocs], collectionsInfo);
-
- // Enable time based expiration.
- setExpireAfterSeconds(rst, expireAfterSeconds);
-
- // Both primary and secondary should remove expired documents.
- verifyPreImagesForAllNodes(rst, [shouldRetainDocs, shouldRetainDocs], collectionsInfo);
-
- // After upgrading the secondary to a version with truncate deletes, the preImages should be
- // deleted.
- rst.upgradePrimary(rst.getPrimary(), serverParametersForVersionString("latest"));
-
- const upgradedNodeExpectedDocs = shouldTruncateAllAfterUpgrade ? [] : shouldRetainDocs;
- verifyPreImagesForAllNodes(rst, [upgradedNodeExpectedDocs, shouldRetainDocs], collectionsInfo);
-
- rst.stopSet();
-}
-
-testPrimaryLatestSecondariesLastLts(/*shouldTruncateAllAfterUpgrade=*/ true);
-testPrimaryLatestSecondariesLastLts(/*shouldTruncateAllAfterUpgrade=*/ false);
-
-testPrimaryLastLtsSecondariesLatest(/*shouldTruncateAllAfterUpgrade=*/ true);
-testPrimaryLastLtsSecondariesLatest(/*shouldTruncateAllAfterUpgrade=*/ false);
diff --git a/jstests/multiVersion/targetedTestsLastLtsFeatures/change_stream_v1_v2_within_txn.js b/jstests/multiVersion/targetedTestsLastLtsFeatures/change_stream_v1_v2_within_txn.js
deleted file mode 100644
index 4d35ae75da5..00000000000
--- a/jstests/multiVersion/targetedTestsLastLtsFeatures/change_stream_v1_v2_within_txn.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * Confirms that if a v1 token is used to resume a change stream from a point in the middle of a
- * transaction, then a >16MB event later in that transaction will be successfully split if the
- * '$changeStreamSplitLargeEvent' stage is present.
- * @tags: [
- * uses_change_streams,
- * uses_transactions,
- * ]
- */
-import "jstests/multiVersion/libs/multi_rs.js";
-import {assertDropAndRecreateCollection} from "jstests/libs/collection_drop_recreate.js";
-
-// Create a new replica set with 2 nodes (otherwise 'rst.upgradeSet()' does not work).
-const rst = new ReplSetTest({nodes: 2, nodeOptions: {binVersion: "last-lts"}});
-rst.startSet();
-rst.initiate();
-
-// Set up DBs and collections used in this test.
-let testDB = rst.getPrimary().getDB(jsTestName());
-let testColl = assertDropAndRecreateCollection(
- testDB, "test_coll", {changeStreamPreAndPostImages: {enabled: true}});
-
-// Open a change stream with batch size 1 and force it to create v1 tokens.
-const csCursor = testColl.watch(
- [{$changeStreamSplitLargeEvent: {}}],
- {fullDocumentBeforeChange: "whenAvailable", batchSize: 1, $_generateV2ResumeTokens: false});
-
-// Start a new transaction.
-const session = testDB.getMongo().startSession();
-const sessionDB = session.getDatabase(testDB.getName());
-const sessionColl = sessionDB[testColl.getName()];
-session.startTransaction();
-
-// Within the txn, insert a large document and then update it, then commit the transaction.
-assert.commandWorked(sessionColl.insert({_id: 1, largeString: "x".repeat(15 * 1024 * 1024)}));
-assert.commandWorked(
- sessionColl.update({_id: 1}, {$set: {largeString: "y".repeat(15 * 1024 * 1024)}}));
-session.commitTransaction();
-
-// Assert that we see the first event (the insert) in the v1 stream.
-assert.soon(() => csCursor.hasNext());
-const v1InsertEvent = csCursor.next();
-assert.eq(v1InsertEvent.operationType, "insert");
-// TODO SERVER-82330: Validate that the 'v1InsertEvent' has a v1 resume token.
-
-rst.upgradeSet({binVersion: "latest"});
-
-testDB = rst.getPrimary().getDB(jsTestName());
-testColl = testDB[testColl.getName()];
-
-// Now open a $changeStreamSplitLargeEvent pipeline and try to resume from the v1 token.
-const csSplitCursor = testColl.watch(
- [{$changeStreamSplitLargeEvent: {}}],
- {resumeAfter: v1InsertEvent._id, fullDocumentBeforeChange: "whenAvailable", batchSize: 0});
-
-// Confirm that the update within the same transaction is correctly split in the resumed stream.
-assert.soon(() => csSplitCursor.hasNext());
-const postResumeEvent = csSplitCursor.next();
-assert.eq(postResumeEvent.operationType, "update");
-assert.eq(postResumeEvent.splitEvent.fragment, 1);
-
-rst.stopSet();
diff --git a/jstests/multiVersion/targetedTestsLastLtsFeatures/change_streams_split_event_v1_v2_tokens.js b/jstests/multiVersion/targetedTestsLastLtsFeatures/change_streams_split_event_v1_v2_tokens.js
deleted file mode 100644
index 7dbf1d81cc5..00000000000
--- a/jstests/multiVersion/targetedTestsLastLtsFeatures/change_streams_split_event_v1_v2_tokens.js
+++ /dev/null
@@ -1,222 +0,0 @@
-/**
- * Tests the compatibility of v1 and v2 resume tokens across server version upgrade / downgrade.
- * @tags: [uses_change_streams]
- */
-
-import "jstests/multiVersion/libs/multi_cluster.js";
-import {
- assertCreateCollection,
- assertDropCollection
-} from "jstests/libs/collection_drop_recreate.js";
-
-const kLargeStringSize = 15 * 1024 * 1024;
-
-const st = new ShardingTest({
- shards: 2,
- config: 1,
- other: {
- mongosOptions: {binVersion: "last-lts"},
- configOptions: {
- binVersion: "last-lts",
- },
- rsOptions: {
- binVersion: "last-lts",
- },
- rs: {nodes: 2},
- }
-});
-
-let testDB = st.s.getDB(jsTestName());
-let testColl = testDB["test"];
-
-// Helper function to retrieve high-watermark change stream tokens.
-function getHighWaterMarkToken(collection, pipeline = [], options = {}) {
- const csCursor = collection.watch(pipeline, {batchSize: 0, ...options});
- const result = csCursor.getResumeToken();
- csCursor.close();
- return result;
-}
-
-// Record a high-watermark resume token marking the start point of the test.
-const testStartV1HWMToken = getHighWaterMarkToken(testColl, [], {$_generateV2ResumeTokens: false});
-
-// An array which will list the expected sequence of change events generated by the test.
-const expectedEvents = [];
-
-//
-// Below, we generate one of each type of change event so that we can later test resuming from a v1
-// token representing each such event.
-//
-testColl = assertCreateCollection(testDB, testColl.getName());
-expectedEvents.push({operationType: "create"});
-
-assert.commandWorked(testColl.createIndexes([{shard: 1}, {shard: 1, _id: 1}, {largeField: 1}]));
-expectedEvents.push({operationType: "createIndexes"},
- {operationType: "createIndexes"},
- {operationType: "createIndexes"});
-
-// The 'modify' event has to come before sharding the collection, otherwise we get different number
-// of events on 'last-lts' and on 'latest'.
-assert.commandWorked(testDB.runCommand(
- {collMod: testColl.getName(), changeStreamPreAndPostImages: {enabled: true}}));
-expectedEvents.push({operationType: "modify"});
-
-// Shard the test collection and split it into two chunks: one that contains all {shard: 1}
-// documents and one that contains all {shard: 2} documents.
-st.shardColl(testColl, {shard: 1} /* shard key */, {shard: 2} /* split at */);
-expectedEvents.push({operationType: "shardCollection"});
-
-assert.commandWorked(testColl.insertMany([
- {_id: "a", shard: 1, largeField: ""},
- {_id: "b", shard: 2, largeField: ""},
- {_id: "c", shard: 2, largeField: ""}
-]));
-expectedEvents.push({operationType: "insert", documentKey: {shard: 1, _id: "a"}},
- {operationType: "insert", documentKey: {shard: 2, _id: "b"}},
- {operationType: "insert", documentKey: {shard: 2, _id: "c"}});
-
-// This high watermark token will be at the same clusterTime as the subsequent update event that
-// needs to be split.
-const v1HwmTokenBeforeUpdateWithSplit = getHighWaterMarkToken(
- testColl, [{$changeStreamSplitLargeEvent: {}}], {$_generateV2ResumeTokens: false});
-
-assert.commandWorked(
- testColl.update({_id: "a", shard: 1}, {$set: {largeField: "x".repeat(kLargeStringSize)}}));
-expectedEvents.push({operationType: "update", documentKey: {_id: "a", shard: 1}});
-
-assert.commandWorked(
- testColl.update({_id: "b", shard: 2}, {$set: {largeField: "x".repeat(kLargeStringSize)}}));
-expectedEvents.push({operationType: "update", documentKey: {_id: "b", shard: 2}});
-
-assert.commandWorked(testColl.replaceOne(
- {_id: "a", shard: 1}, {_id: "a", shard: 1, largeField: "y".repeat(kLargeStringSize)}));
-expectedEvents.push({operationType: "replace", documentKey: {_id: "a", shard: 1}});
-
-assert.commandWorked(testColl.replaceOne(
- {_id: "b", shard: 2}, {_id: "b", shard: 2, largeField: "y".repeat(kLargeStringSize)}));
-expectedEvents.push({operationType: "replace", documentKey: {_id: "b", shard: 2}});
-
-assert.commandWorked(testColl.remove({_id: "a"}));
-expectedEvents.push({operationType: "delete", documentKey: {_id: "a", shard: 1}});
-
-assert.commandWorked(testColl.remove({_id: "b"}));
-expectedEvents.push({operationType: "delete", documentKey: {_id: "b", shard: 2}});
-
-assert.commandWorked(
- st.s.adminCommand({refineCollectionShardKey: testColl.getFullName(), key: {shard: 1, _id: 1}}));
-expectedEvents.push({operationType: "refineCollectionShardKey"});
-
-assert.commandWorked(st.s.adminCommand({reshardCollection: testColl.getFullName(), key: {_id: 1}}));
-expectedEvents.push({operationType: "reshardCollection"});
-
-assert.commandWorked(testColl.dropIndex({largeField: 1}));
-expectedEvents.push({operationType: "dropIndexes"});
-
-const newTestCollectionName = "test_";
-assert.commandWorked(testColl.renameCollection(newTestCollectionName));
-expectedEvents.push({operationType: "rename"});
-
-assertDropCollection(testDB, newTestCollectionName);
-expectedEvents.push({operationType: "drop"});
-
-assert.commandWorked(testDB.dropDatabase());
-// A whole-DB stream will be invalidated by the dropDatabase event. We include a second dropDatabase
-// event because one such event is generated on each shard, and will be reported if we resume after
-// the invalidate. This second dropDatabase acts as a sentinel here, signifying that we have reached
-// the end of the test stream.
-expectedEvents.push({operationType: "dropDatabase"},
- {operationType: "invalidate"},
- {operationType: "dropDatabase"});
-
-// Helper function to assert on the given event fields.
-function assertEventMatches(event, expectedEvent, errorMsg) {
- for (const k in expectedEvent) {
- assert.docEq(expectedEvent[k], event[k], errorMsg + `: value mismatch for field '${k}'`)
- }
-}
-
-// Asserts the next change event with the given pipeline and options matches the expected event.
-// Returns the resume token of the matched event on success.
-function assertNextChangeEvent(expectedEvent, pipeline, options) {
- const csCursor = testDB.watch([...pipeline], {showExpandedEvents: true, ...options});
- const errorMsg = "could not retrieve the expected event matching " + tojson(expectedEvent);
- let event;
- do {
- assert.doesNotThrow(() => assert.soon(() => csCursor.hasNext()), [], errorMsg);
- event = csCursor.next();
- // When using '$_generateV2ResumeTokens: false', the change stream will additionally
- // emit non-public 'kNewShardDetected' event. Unfortunately, it cannot be filtered out
- // by adding a '$match' stage, so we fast-forward all these events.
- } while (event.operationType === "kNewShardDetected");
- assertEventMatches(event, expectedEvent, errorMsg);
- csCursor.close();
- return event._id;
-}
-
-// Helper function to retrieve change event tokens for all events referred by 'expectedEvents'.
-function getTokensForExpectedEvents(expectedEvents, startToken, pipeline = [], options = {}) {
- return expectedEvents
- .reduce(
- (result, expectedEvent) => {
- const lastToken = result[result.length - 1];
- result.push(assertNextChangeEvent(
- expectedEvent, pipeline, {startAfter: lastToken, ...options}));
- return result;
- },
- [startToken])
- .slice(1);
-}
-
-// Generate v1 resume tokens for all expected events on 'last-lts'.
-const resumeTokensLastLTS = getTokensForExpectedEvents(
- expectedEvents, testStartV1HWMToken, [], {$_generateV2ResumeTokens: false});
-// TODO SERVER-82330: Validate that these tokens are indeed all v1 tokens.
-
-// Upgrade the cluster to 'latest' to allow testing v1 - v2 resume behaviour.
-st.upgradeCluster("latest", true);
-assert.commandWorked(st.s.adminCommand({setFeatureCompatibilityVersion: latestFCV, confirm: true}));
-
-testDB = st.s.getDB(jsTestName());
-
-// Verify that we can resume from each of the v1 tokens on the new binary version and with the
-// $changeStreamSplitLargeEvent stage in the pipeline. When resuming from (i-1)-th event's token we
-// expect to get the i-th event. We do not need to test the last token, because it is simply a
-// sentinel value that signifies the end of the test.
-for (let i = 1; i < expectedEvents.length; ++i) {
- assertNextChangeEvent(expectedEvents[i],
- [{$changeStreamSplitLargeEvent: {}}],
- {startAfter: resumeTokensLastLTS[i - 1]});
-}
-
-// Test that we can split the update events after 'v1HwmTokenBeforeUpdateWithSplit'.
-const expectedSplitEvents = [
- {operationType: "update", splitEvent: {fragment: 1, of: 2}},
- {splitEvent: {fragment: 2, of: 2}},
- {operationType: "update", splitEvent: {fragment: 1, of: 2}},
- {splitEvent: {fragment: 2, of: 2}},
- {operationType: "replace"}
-];
-// Generate a set of v2 resume tokens for each of the entries in 'expectedSplitEvents'.
-const resumeTokensWithSplitLatest = getTokensForExpectedEvents(expectedSplitEvents,
- v1HwmTokenBeforeUpdateWithSplit,
- [{$changeStreamSplitLargeEvent: {}}],
- {fullDocument: "required"});
-
-// Downgrade back to the original version.
-assert.commandWorked(
- st.s.adminCommand({setFeatureCompatibilityVersion: lastLTSFCV, confirm: true}));
-st.downgradeCluster("latest", "last-lts", true);
-
-testDB = st.s.getDB(jsTestName());
-
-// Test the v2 split 'update' event tokens on the downgraded binary version. When resuming from
-// (i-1)-th event token we expect to get the i-th event. This means, after the last 'update' event
-// we expect the first 'replace' event.
-for (let i = 1; i < expectedSplitEvents.length; ++i) {
- assertNextChangeEvent(
- expectedSplitEvents[i],
- [{$changeStreamSplitLargeEvent: {}}],
- {resumeAfter: resumeTokensWithSplitLatest[i - 1], fullDocument: "required"});
-}
-
-st.stop();
diff --git a/jstests/multiVersion/targetedTestsLastLtsFeatures/dbcheck_invocation_mixed_versions.js b/jstests/multiVersion/targetedTestsLastLtsFeatures/dbcheck_invocation_mixed_versions.js
index eee04b5c589..d13a44d25d1 100644
--- a/jstests/multiVersion/targetedTestsLastLtsFeatures/dbcheck_invocation_mixed_versions.js
+++ b/jstests/multiVersion/targetedTestsLastLtsFeatures/dbcheck_invocation_mixed_versions.js
@@ -29,31 +29,16 @@ function testDbCheckInvocationParameters(replSet) {
function checkEntryBounds(start, end) {
forEachNonArbiterNode(replSet, function(node) {
const healthlog = node.getDB("local").system.healthlog;
- let keyBoundsResult;
- const nodeBinVersion = node.getDB("admin").serverStatus()["version"];
- if (nodeBinVersion == MongoRunner.getBinVersionFor("latest")) {
- keyBoundsResult = healthlog.aggregate([
- {$match: {operation: "dbCheckBatch"}},
- {
- $group: {
- _id: null,
- batchStart: {$min: "$data.batchStart._id"},
- batchEnd: {$max: "$data.batchEnd._id"}
- }
+ const keyBoundsResult = healthlog.aggregate([
+ {$match: {operation: "dbCheckBatch"}},
+ {
+ $group: {
+ _id: null,
+ batchStart: {$min: "$data.batchStart._id"},
+ batchEnd: {$max: "$data.batchEnd._id"}
}
- ]);
- } else {
- keyBoundsResult = healthlog.aggregate([
- {$match: {operation: "dbCheckBatch"}},
- {
- $group: {
- _id: null,
- batchStart: {$min: "$data.minKey"},
- batchEnd: {$max: "$data.maxKey"}
- }
- }
- ]);
- }
+ }
+ ]);
assert(keyBoundsResult.hasNext(), "dbCheck put no batches in health log");
diff --git a/jstests/multiVersion/targetedTestsLastLtsFeatures/downgrade_from_autobootstrapped_cluster.js b/jstests/multiVersion/targetedTestsLastLtsFeatures/downgrade_from_autobootstrapped_cluster.js
deleted file mode 100644
index 59449ef92be..00000000000
--- a/jstests/multiVersion/targetedTestsLastLtsFeatures/downgrade_from_autobootstrapped_cluster.js
+++ /dev/null
@@ -1,349 +0,0 @@
-// Must keep this test until v8.0 becomes last lts.
-
-import "jstests/multiVersion/libs/multi_rs.js";
-
-const kDocId = 1;
-
-let makeNewCluster = function() {
- let st = new ShardingTest({
- shards: {rs0: {nodes: 1, setParameter: {featureFlagAllMongodsAreSharded: true}}},
- other: {useAutoBootstrapProcedure: true}
- });
-
- assert.commandWorked(st.s.adminCommand({enableSharding: 'test'}));
- assert.commandWorked(st.s.adminCommand({shardCollection: 'test.user', key: {_id: 1}}));
- assert.commandWorked(st.s.getDB('test').user.insert({_id: kDocId, z: 1}));
-
- assert.commandWorked(
- st.s.adminCommand({setFeatureCompatibilityVersion: lastLTSFCV, confirm: true}));
-
- return st;
-};
-
-let makeUpgradedClusterFromOldReplSet = function() {
- let nodeOption = {binVersion: 'last-lts'};
- // Need at least 2 nodes because upgradeSet method needs to be able call step down
- // with another primariy eligible node available.
- let replSet = new ReplSetTest({nodes: [nodeOption, nodeOption]});
- replSet.startSet();
- replSet.initiate();
-
- replSet.upgradeSet({
- binVersion: 'latest',
- setParameter:
- {featureFlagAllMongodsAreSharded: true, featureFlagTransitionToCatalogShard: true}
- });
-
- let primary = replSet.getPrimary();
- assert.commandWorked(
- primary.adminCommand({transitionToShardedCluster: 1, writeConcern: {w: 'majority'}}));
-
- return replSet;
-};
-
-let testCRUD = function(conn) {
- let coll = conn.getDB('test').user;
-
- let doc = coll.findOne({_id: kDocId});
- assert.neq(null, doc);
-
- let res = coll.update({_id: kDocId}, {$inc: {x: 1}});
- assert.eq(1, res.nMatched, tojson(res));
-};
-
-let removeShardingMetadata = function(conn) {
- let config = conn.getDB('config');
-
- config.actionlog.drop();
- config.databases.drop();
- config.cache.collections.drop();
- config.cache.databases.drop();
- config.migrationCoordinators.drop();
- config.migrationRecipients.drop();
- config.shardMergeRecipients.drop();
- config.shardSplitDonors.drop();
- config.rangeDeletions.drop();
- config.rangeDeletionsForRename.drop();
- config.reshardingOperations.drop();
- config.localReshardingOperations.donor.drop();
- config.localReshardingOperations.recipient.drop();
- config.localRenameParticipants.drop();
- config.settings.drop();
- config.localReshardingOperations.recipient.progress_applier.drop();
- config.localReshardingOperations.recipient.progress_txn_cloner.drop();
- config.collection_critical_sections.drop();
- config.sharding_configsvr_coordinators.drop();
- config.shards.drop();
- config.collections.drop();
- config.csrs.indexes.drop();
- config.shard.indexes.drop();
- config.shard.collections.drop();
- config.placementHistory.drop();
- config.lockpings.drop();
- config.locks.drop();
- config.analyzeShardKeySplitPoints.drop();
- config.changelog.drop();
- config.chunks.drop();
- config.tags.drop();
- config.getCollection('version').drop();
- config.mongos.drop();
-
- let cachedChunkColls = conn.getDB('config').runCommand(
- {listCollections: 1, filter: {name: /cache.chunks*/}, nameOnly: true});
-
- assert.eq(0, cachedChunkColls.cursor.id); // Should fit on first response
- cachedChunkColls.cursor.firstBatch.forEach((coll) => {
- conn.getDB('config').getCollection(coll.name).drop();
- });
-};
-
-let verifyConfigColl = function(conn) {
- let expectedCollections = [
- 'system.sessions',
- 'system.indexBuilds',
- // system.* cannot be dropped
- 'system.sharding_ddl_coordinators',
- 'sampledQueries',
- 'tenantMigrationDonors',
- 'sampledQueriesDiff',
- 'image_collection',
- 'external_validation_keys',
- 'tenantMigrationRecipients',
- 'transactions',
- 'system.preimages',
- 'vectorClock',
- ];
-
- let configColls = conn.getDB('config').runCommand({listCollections: 1, nameOnly: true});
-
- assert.eq(0, configColls.cursor.id); // Should fit on first response
-
- let unexpectedColls = [];
- configColls.cursor.firstBatch.forEach((coll) => {
- if (!expectedCollections.includes(coll.name)) {
- unexpectedColls.push(coll.name);
- }
- });
-
- assert.eq([], unexpectedColls);
-};
-
-(function() {
-jsTest.log('Testing downgrade to sharded cluster from a fresh new cluster');
-
-let st = makeNewCluster();
-
-// Add a shard in order to be able to transition to dedicated config
-const additionalShard = new ReplSetTest({name: "shard0", nodes: 1, nodeOptions: {shardsvr: ""}});
-additionalShard.startSet();
-additionalShard.initiate();
-
-assert.commandWorked(st.s.adminCommand({addShard: additionalShard.getURL(), name: 'shard0'}));
-assert.commandWorked(st.s.adminCommand(
- {moveChunk: 'test.user', find: {_id: MinKey}, to: 'shard0', _waitForDelete: true}));
-assert.commandWorked(st.s.adminCommand({movePrimary: 'test', to: 'shard0'}));
-assert.commandWorked(st.s.adminCommand(
- {moveChunk: "config.system.sessions", find: {_id: 0}, to: 'shard0', _waitForDelete: true}));
-
-let res = st.s.adminCommand({transitionToDedicatedConfigServer: 1});
-assert.eq("started", res.state);
-
-res = st.s.adminCommand({transitionToDedicatedConfigServer: 1});
-assert.eq("completed", res.state);
-
-st.stop({noCleanData: true}); // keep data files
-additionalShard.stopSet(null /* signal */, true /* forRestart */, {noCleanData: true});
-
-const oldConfig = st.rs0.nodes[0];
-let configConn = MongoRunner.runMongod({
- binVersion: 'last-lts',
- noCleanData: true,
- configsvr: '',
- replSet: st.rs0.name,
- dbpath: oldConfig.dbpath,
- port: oldConfig.port
-});
-
-const oldShard = additionalShard.nodes[0];
-let shardConn = MongoRunner.runMongod({
- binVersion: 'last-lts',
- noCleanData: true,
- shardsvr: '',
- replSet: additionalShard.name,
- dbpath: oldShard.dbpath,
- port: oldShard.port
-});
-
-const oldMongos = st.s;
-const newOpt = Object.merge({binVersion: 'last-lts'}, oldMongos.fullOptions);
-let mongosConn = MongoRunner.runMongos(newOpt);
-
-testCRUD(mongosConn);
-
-MongoRunner.stopMongos(mongosConn);
-MongoRunner.stopMongod(shardConn);
-MongoRunner.stopMongod(configConn);
-})();
-
-(function() {
-jsTest.log('Testing downgrade to replica set from a fresh new cluster');
-
-let st = makeNewCluster();
-
-st.stop({noCleanData: true}); // keep data files
-
-const oldConfig = st.rs0.nodes[0];
-let configConn = MongoRunner.runMongod(
- {binVersion: 'last-lts', noCleanData: true, dbpath: oldConfig.dbpath, port: oldConfig.port});
-
-assert.commandWorked(configConn.getDB('local').system.replset.update({}, {$unset: {configsvr: 1}}));
-
-MongoRunner.stopMongod(configConn);
-
-configConn = MongoRunner.runMongod({
- binVersion: 'last-lts',
- replSet: st.rs0.name,
- noCleanData: true,
- dbpath: oldConfig.dbpath,
- port: oldConfig.port
-});
-
-assert.soon(() => {
- let hello = configConn.getDB('admin')._helloOrLegacyHello();
- return hello.isWritablePrimary || hello.ismaster;
-});
-
-removeShardingMetadata(configConn);
-verifyConfigColl(configConn);
-
-testCRUD(configConn);
-
-MongoRunner.stopMongod(configConn);
-})();
-
-(function() {
-jsTest.log('Testing downgrade to standalone from a fresh new cluster');
-
-let st = makeNewCluster();
-
-st.stop({noCleanData: true}); // keep data files
-
-const oldConfig = st.rs0.nodes[0];
-let configConn = MongoRunner.runMongod(
- {binVersion: 'last-lts', noCleanData: true, dbpath: oldConfig.dbpath, port: oldConfig.port});
-
-assert.commandWorked(configConn.getDB('local').system.replset.update({}, {$unset: {configsvr: 1}}));
-
-MongoRunner.stopMongod(configConn);
-
-configConn = MongoRunner.runMongod(
- {binVersion: 'last-lts', noCleanData: true, dbpath: oldConfig.dbpath, port: oldConfig.port});
-
-let localDB = configConn.getDB("local");
-localDB.system.replset.remove({}, false /* justOne */);
-
-removeShardingMetadata(configConn);
-
-verifyConfigColl(configConn);
-testCRUD(configConn);
-
-MongoRunner.stopMongod(configConn);
-
-// Can still convert to replSet after repl doc was deleted.
-
-configConn = MongoRunner.runMongod({
- binVersion: 'last-lts',
- replSet: st.rs0.name,
- noCleanData: true,
- dbpath: oldConfig.dbpath,
- port: oldConfig.port
-});
-
-assert.commandWorked(configConn.getDB('admin').runCommand({replSetInitiate: 1}));
-
-configConn.setSecondaryOk();
-assert.soon(() => {
- let hello = configConn.getDB('admin')._helloOrLegacyHello();
- return hello.me && hello.me == hello.primary && (hello.isWritablePrimary || hello.ismaster);
-});
-
-testCRUD(configConn);
-MongoRunner.stopMongod(configConn);
-})();
-
-(function() {
-jsTest.log('Testing downgrade to sharded cluster from a cluster upgraded from replSet');
-
-let replTest = makeUpgradedClusterFromOldReplSet();
-
-const mongos = MongoRunner.runMongos(
- {configdb: replTest.getURL(), setParameter: "featureFlagTransitionToCatalogShard=true"});
-assert(mongos);
-assert.commandWorked(mongos.adminCommand({enableSharding: 'test'}));
-assert.commandWorked(mongos.adminCommand({shardCollection: 'test.user', key: {_id: 1}}));
-assert.commandWorked(mongos.getDB('test').user.insert({_id: kDocId, z: 1}));
-
-// Add a shard in order to be able to transition to dedicated config
-const additionalShard = new ReplSetTest({name: "shard0", nodes: 2, nodeOptions: {shardsvr: ""}});
-additionalShard.startSet();
-additionalShard.initiate();
-
-assert.commandWorked(mongos.adminCommand({addShard: additionalShard.getURL(), name: 'shard0'}));
-assert.commandWorked(mongos.adminCommand(
- {moveChunk: 'test.user', find: {_id: MinKey}, to: 'shard0', _waitForDelete: true}));
-assert.commandWorked(mongos.adminCommand({movePrimary: 'test', to: 'shard0'}));
-
-let res = mongos.adminCommand({transitionToDedicatedConfigServer: 1});
-assert.eq("started", res.state);
-
-assert.soon(() => {
- return mongos.adminCommand({transitionToDedicatedConfigServer: 1}).state == 'completed';
-});
-
-let replConfig = replTest.getReplSetConfigFromNode();
-replConfig.version += 1;
-replConfig.configsvr = true;
-
-assert.commandWorked(replTest.getPrimary().adminCommand({replSetReconfig: replConfig}));
-
-MongoRunner.stopMongos(mongos);
-
-delete replTest.nodeOptions['n0'].setParameter.featureFlagAllMongodsAreSharded;
-delete replTest.nodeOptions['n1'].setParameter.featureFlagAllMongodsAreSharded;
-replTest.upgradeSet({binVersion: 'last-lts', configsvr: ''});
-additionalShard.upgradeSet({binVersion: 'last-lts'});
-
-const newOpt = Object.merge({binVersion: 'last-lts'}, mongos.fullOptions);
-let mongosConn = MongoRunner.runMongos(newOpt);
-
-testCRUD(mongosConn);
-
-MongoRunner.stopMongos(mongosConn);
-replTest.stopSet();
-additionalShard.stopSet();
-})();
-
-(function() {
-jsTest.log('Testing downgrade to replica set from a cluster upgraded from replSet');
-
-let replTest = makeUpgradedClusterFromOldReplSet();
-
-var mongos = MongoRunner.runMongos({configdb: replTest.getURL()});
-assert(mongos);
-assert.commandWorked(mongos.adminCommand({enableSharding: 'test'}));
-assert.commandWorked(mongos.adminCommand({shardCollection: 'test.user', key: {_id: 1}}));
-assert.commandWorked(mongos.getDB('test').user.insert({_id: kDocId, z: 1}));
-MongoRunner.stopMongos(mongos);
-
-delete replTest.nodeOptions['n0'].setParameter.featureFlagAllMongodsAreSharded;
-delete replTest.nodeOptions['n1'].setParameter.featureFlagAllMongodsAreSharded;
-replTest.upgradeSet({binVersion: 'last-lts'});
-
-let configConn = replTest.getPrimary();
-removeShardingMetadata(configConn);
-verifyConfigColl(configConn);
-
-testCRUD(configConn);
-
-replTest.stopSet();
-})();
diff --git a/jstests/multiVersion/targetedTestsLastLtsFeatures/fle2_range_preview_rename.js b/jstests/multiVersion/targetedTestsLastLtsFeatures/fle2_range_preview_rename.js
deleted file mode 100644
index da8a700b448..00000000000
--- a/jstests/multiVersion/targetedTestsLastLtsFeatures/fle2_range_preview_rename.js
+++ /dev/null
@@ -1,183 +0,0 @@
-/**
- * Test edge cases for the rangePreview -> range rename.
- */
-import "jstests/multiVersion/libs/multi_rs.js";
-
-import {EncryptedClient} from "jstests/fle2/libs/encrypted_client_util.js";
-
-const CRUDOnDeprecatedCollectionCode = 8575606;
-const CreateDeprecatedCollectionCode = 8575605;
-function testBinaryUpgradeWithRangePreviewCollection(upgradeConfig, fcvUpgradeShouldSucceed) {
- const rst = new ReplSetTest({nodes: 2, nodeOptions: {binVersion: 'last-lts'}});
- rst.startSet();
- rst.initiate();
- let client = new EncryptedClient(rst.getPrimary(), "dbTest");
- // Old version; creating a new "rangePreview" collection succeeds.
- assert.commandWorked(client.createEncryptionCollection("coll1", {
- encryptedFields: {
- "fields": [{
- path: "field1",
- bsonType: "int",
- queries: [{
- queryType: "rangePreview",
- min: NumberInt(0),
- max: NumberInt(8),
- contention: NumberInt(0),
- sparsity: 1
- }]
- }]
- }
- }));
- assert.commandWorked(client.createEncryptionCollection("coll2", {
- encryptedFields: {
- "fields": [{
- path: "field1",
- bsonType: "int",
- queries: [{
- queryType: "rangePreview",
- min: NumberInt(0),
- max: NumberInt(8),
- contention: NumberInt(0),
- sparsity: 1
- }]
- }]
- }
- }));
-
- assert.commandWorked(
- client.getDB().runCommand({insert: "coll1", documents: [{_id: 0, field1: NumberInt(1)}]}));
- // The upgradeSet should always succeed and we should be able to start up with the rangePreview
- // collection.
- rst.upgradeSet(upgradeConfig);
- client = new EncryptedClient(rst.getPrimary(), "dbTest");
-
- // After upgrading, we can't do any CRUD ops on the collection
- assert.commandFailedWithCode(
- client.getDB().runCommand({insert: "coll1", documents: [{_id: 1, field1: NumberInt(2)}]}),
- CRUDOnDeprecatedCollectionCode);
- assert.commandFailedWithCode(client.getDB().runCommand({find: "coll1", filter: {}}),
- CRUDOnDeprecatedCollectionCode);
-
- // We should be able to drop the collection
- client.getDB().coll1.drop();
-
- const res =
- rst.getPrimary().adminCommand({setFeatureCompatibilityVersion: latestFCV, confirm: true});
- if (fcvUpgradeShouldSucceed) {
- assert.commandWorked(res);
- } else {
- assert.commandFailedWithCode(res, ErrorCodes.CannotUpgrade);
- client.getDB().coll2.drop();
- // After dropping both rangePreview collections, we should be able to upgrade (once drops
- // clear).
- assert.soon(() => {
- assert.commandWorked(rst.getPrimary().adminCommand(
- {setFeatureCompatibilityVersion: latestFCV, confirm: true}));
- return true;
- });
- }
- rst.stopSet();
-}
-
-// When we set feature flag off, upgrading FCV will succeed because rangePreview is allowed when
-// Range V2 is disabled
-testBinaryUpgradeWithRangePreviewCollection(
- {binVersion: 'latest', setParameter: {featureFlagQERangeV2: false}}, true);
-// When we set it on, upgrading will fail
-testBinaryUpgradeWithRangePreviewCollection(
- {binVersion: 'latest', setParameter: {featureFlagQERangeV2: true}}, false);
-
-function testDowngradeWithRangeCollection(config) {
- const rst = new ReplSetTest({nodes: 2, nodeOptions: config});
- rst.startSet();
- rst.initiate();
- let client = new EncryptedClient(rst.getPrimary(), "dbTest");
- // Old version; creating a new "rangePreview" collection succeeds.
- assert.commandWorked(client.createEncryptionCollection("coll", {
- encryptedFields: {
- "fields": [{
- path: "field1",
- bsonType: "int",
- queries: [{
- queryType: "range",
- min: NumberInt(0),
- max: NumberInt(8),
- contention: NumberInt(0),
- sparsity: 1
- }]
- }]
- }
- }));
-
- // Can't downgrade FCV to lastLTS with range collection, no matter if the feature flag is
- // enabled.
- assert.commandFailedWithCode(
- rst.getPrimary().adminCommand({setFeatureCompatibilityVersion: lastLTSFCV, confirm: true}),
- ErrorCodes.CannotDowngrade);
-
- client.getDB().coll.drop();
- // After dropping the collection, we should eventually be able to downgrade
- assert.soon(() => {
- assert.commandWorked(rst.getPrimary().adminCommand(
- {setFeatureCompatibilityVersion: lastLTSFCV, confirm: true}));
- return true;
- });
-
- rst.stopSet();
-}
-
-testDowngradeWithRangeCollection(
- {binVersion: 'latest', setParameter: {featureFlagQERangeV2: false}});
-testDowngradeWithRangeCollection(
- {binVersion: 'latest', setParameter: {featureFlagQERangeV2: true}});
-
-function testCreateCollection(config) {
- const rst = new ReplSetTest({nodes: 2, nodeConfig: config});
- rst.startSet();
- rst.initiate();
- const client = new EncryptedClient(rst.getPrimary(), "dbTest");
- // Creating a new rangePreview collection should fail.
- assert.throwsWithCode(() => client.createEncryptionCollection("coll", {
- encryptedFields: {
- "fields": [{
- path: "field1",
- bsonType: "int",
- queries: [{
- queryType: "rangePreview",
- min: NumberInt(0),
- max: NumberInt(8),
- contention: NumberInt(0),
- sparsity: 1
- }]
- }]
- }
- }),
- CreateDeprecatedCollectionCode);
- // Creating a new range collection should succeed.
- assert.commandWorked(client.createEncryptionCollection("coll", {
- encryptedFields: {
- "fields": [{
- path: "field1",
- bsonType: "int",
- queries: [{
- queryType: "range",
- min: NumberInt(0),
- max: NumberInt(8),
- contention: NumberInt(0),
- sparsity: 1
- }]
- }]
- }
- }));
-
- // CRUD operations should work fine on the range collection.
- assert.commandWorked(client.getDB().runCommand(
- {insert: "coll", documents: [{_id: 0, field1: NumberInt(1), field2: NumberInt(2)}]}));
- assert.eq(client.getDB().coll.find({}, {__safeContent__: 0}).toArray(),
- [{_id: 0, field1: NumberInt(1), field2: NumberInt(2)}]);
-
- rst.stopSet();
-}
-
-testCreateCollection({setParameter: {featureFlagQERangeV2: false}});
-testCreateCollection({setParameter: {featureFlagQERangeV2: true}})
diff --git a/jstests/multiVersion/targetedTestsLastLtsFeatures/multi_update_coordinator_downgrade.js b/jstests/multiVersion/targetedTestsLastLtsFeatures/multi_update_coordinator_downgrade.js
deleted file mode 100644
index 8f5f5a6bd89..00000000000
--- a/jstests/multiVersion/targetedTestsLastLtsFeatures/multi_update_coordinator_downgrade.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * Tests that any running MultiUpdateCoordinators are aborted and properly
- * cleaned up before downgrading to 7.0.
- *
- * @tags: [
- * requires_fcv_80
- * ]
- */
-
-import {migrationsAreAllowed} from "jstests/libs/chunk_manipulation_util.js";
-import {configureFailPoint} from "jstests/libs/fail_point_util.js";
-import {funWithArgs} from "jstests/libs/parallel_shell_helpers.js";
-import {CreateShardedCollectionUtil} from "jstests/sharding/libs/create_sharded_collection_util.js";
-
-const dbName = "test";
-const collName = "coll";
-const namespace = `${dbName}.${collName}`;
-
-function runDowngradeTest(phase) {
- jsTestLog(`Running MultiUpdateCoordinator downgrade test from phase ${phase}`);
- const st = new ShardingTest();
- const mongos = st.s0;
-
- const sourceCollection = mongos.getCollection(namespace);
- CreateShardedCollectionUtil.shardCollectionWithChunks(sourceCollection, {key: 1}, [
- {min: {key: MinKey}, max: {key: MaxKey}, shard: st.shard0.shardName},
- ]);
- sourceCollection.insertMany([{key: 1, counter: 0}, {key: 2, counter: 0}]);
- const dbPrimaryRsPrimary = st.getPrimaryShard(dbName).rs.getPrimary();
-
- function downgradeFcvFromParallelShell() {
- return startParallelShell(
- () => {assert.commandWorked(
- db.adminCommand({setFeatureCompatibilityVersion: lastLTSFCV, confirm: true}))},
- st.s.port);
- }
-
- function coordinateMultiUpdateFromParallelShell() {
- return startParallelShell(
- funWithArgs((nss, collName) => {
- db.adminCommand({
- _shardsvrCoordinateMultiUpdate: nss,
- uuid: UUID(),
- command: {
- update: collName,
- updates: [{q: {counter: 0}, u: {$set: {counter: 1}}, multi: true}]
- }
- });
- }, namespace, collName), dbPrimaryRsPrimary.port);
- }
-
- function assertNoDocumentsIn(dbName, collName) {
- const docs = dbPrimaryRsPrimary.getDB(dbName).getCollection(collName).find({}).toArray();
- assert.eq(docs, []);
- }
-
- const phaseFp = configureFailPoint(dbPrimaryRsPrimary,
- "pauseDuringMultiUpdateCoordinatorPhaseTransition",
- {progress: "after", phase});
- const abortFp =
- configureFailPoint(dbPrimaryRsPrimary, "hangAfterAbortingMultiUpdateCoordinators");
-
- const joinUpdate = coordinateMultiUpdateFromParallelShell();
- phaseFp.wait();
- const joinDowngrade = downgradeFcvFromParallelShell();
- abortFp.wait();
- abortFp.off();
- phaseFp.off();
- joinDowngrade();
-
- assertNoDocumentsIn("config", "system.sharding_ddl_coordinators");
- assertNoDocumentsIn("config", "localMigrationBlockingOperations.multiUpdateCoordinators");
- assert(migrationsAreAllowed(st.s.getDB(dbName), collName));
-
- joinUpdate();
- st.stop();
-}
-
-const phases = ["acquireSession", "blockMigrations", "performUpdate", "success", "done"];
-for (const phase of phases) {
- runDowngradeTest(phase);
-}
diff --git a/jstests/multiVersion/targetedTestsLastLtsFeatures/oidc_multipurpose_idp.js b/jstests/multiVersion/targetedTestsLastLtsFeatures/oidc_multipurpose_idp.js
deleted file mode 100644
index 1268857e56d..00000000000
--- a/jstests/multiVersion/targetedTestsLastLtsFeatures/oidc_multipurpose_idp.js
+++ /dev/null
@@ -1,163 +0,0 @@
-/**
- * Test downgrade/upgrade of server with respect to OIDC multipurpose IDP support
- */
-import "jstests/multiVersion/libs/multi_rs.js";
-
-import {determineSSLProvider} from "jstests/ssl/libs/ssl_helpers.js";
-import {
- OIDCKeyServer,
- tryTokenAuth
-} from "src/mongo/db/modules/enterprise/jstests/external_auth/lib/oidc_utils.js";
-import {OIDCVars} from "src/mongo/db/modules/enterprise/jstests/external_auth/lib/oidc_vars.js";
-
-if (determineSSLProvider() !== 'openssl') {
- print('Skipping test, OIDC is only available with OpenSSL');
- quit();
-}
-
-const keyMap = {
- issuer1: 'src/mongo/db/modules/enterprise/jstests/external_auth/lib/custom-key-1.json',
- issuer2: 'src/mongo/db/modules/enterprise/jstests/external_auth/lib/custom-key-1.json'
-};
-const KeyServer = new OIDCKeyServer(JSON.stringify(keyMap));
-const issuer1 = KeyServer.getURL() + '/issuer1';
-const issuer2 = KeyServer.getURL() + '/issuer2';
-const kOIDCConfig = [
- {
- issuer: issuer1,
- audience: 'jwt@kernel.mongodb.com',
- authNamePrefix: 'issuer1',
- matchPattern: '@mongodb.com$',
- clientId: 'deadbeefcafe',
- requestScopes: ['email'],
- principalName: 'sub',
- authorizationClaim: 'mongodb-roles',
- logClaims: ['sub', 'aud', 'mongodb-roles', 'does-not-exist'],
- JWKSPollSecs: 15,
- },
- {
- issuer: issuer2,
- audience: 'jwt@kernel.mongodb.com',
- authNamePrefix: 'issuer2',
- matchPattern: '@10gen.com$',
- clientId: 'deadbeefcafe',
- authorizationClaim: 'mongodb-roles',
- JWKSPollSecs: 15,
- }
-];
-
-const startupOptions = {
- authenticationMechanisms: 'SCRAM-SHA-256,MONGODB-OIDC',
- oidcIdentityProviders: tojson(kOIDCConfig),
-};
-
-const startupOptionsNotDowngradable = {
- authenticationMechanisms: 'SCRAM-SHA-256,MONGODB-OIDC',
- oidcIdentityProviders: tojson(kOIDCConfig.concat({
- issuer: issuer1,
- audience: 'jwt@kernel.10gen.com',
- authNamePrefix: 'issuer1-alt',
- authorizationClaim: 'mongodb-roles',
- supportsHumanFlows: false,
- JWKSPollSecs: 15,
- })),
-};
-
-const {
- 'Token_OIDCAuth_user1': issuerOneToken,
- 'Token_OIDCAuth_user1@10gen': issuerTwoToken,
- 'Token_OIDCAuth_user1_alt_audience': issuerOneAltAudienceToken,
-} = OIDCVars(KeyServer.getURL()).kOIDCTokens;
-
-function setup(conn) {
- const adminDB = conn.getDB('admin');
- assert.commandWorked(conn.adminCommand({createUser: 'admin', 'pwd': 'foo', roles: ['root']}));
-
- // Create the roles corresponding to user1@mongodb.com and user1@10gen.com's groups.
- assert.commandWorked(conn.adminCommand(
- {createRole: 'issuer1/myReadRole', roles: ['readAnyDatabase'], privileges: []}));
- assert.commandWorked(
- conn.adminCommand({createRole: 'issuer2/myReadRole', roles: ['read'], privileges: []}));
- assert.commandWorked(
- conn.adminCommand({createRole: 'issuer1-alt/myreadRole', roles: ['read'], privileges: []}));
- // Increase logging verbosity.
- assert.commandWorked(adminDB.setLogLevel(3));
-}
-
-function runAuthTest(hostname, altCanAuth) {
- let conn = new Mongo(hostname);
- assert(tryTokenAuth(conn, issuerOneToken));
- assert.commandWorked(conn.adminCommand({listDatabases: 1}));
- conn.close();
-
- conn = new Mongo(hostname);
- assert(tryTokenAuth(conn, issuerTwoToken));
- assert.commandWorked(conn.adminCommand({listDatabases: 1}));
- conn.close();
-
- conn = new Mongo(hostname);
- assert(tryTokenAuth(conn, issuerOneAltAudienceToken) == altCanAuth);
- if (altCanAuth) {
- assert.commandWorked(conn.adminCommand({listDatabases: 1}));
- }
- conn.close();
-}
-
-function testBinaryUpgrade(initConfig, altCanAuthBefore, newConfig, altCanAuthAfter) {
- jsTestLog("Testing upgrade from last-lts to latest");
- const rst = new ReplSetTest(
- {nodes: 2, nodeOptions: {binVersion: 'last-lts', setParameter: initConfig}});
- rst.startSet();
- rst.initiate();
-
- let conn = rst.getPrimary();
- setup(conn);
- runAuthTest(conn.host, altCanAuthBefore);
-
- jsTestLog("Starting binary upgrade to latest");
- rst.upgradeSet({binVersion: 'latest', setParameter: newConfig});
- jsTestLog("Finished binary upgrade to latest");
-
- conn = rst.getPrimary();
- runAuthTest(conn.host, altCanAuthAfter);
-
- rst.stopSet();
-}
-
-function testBinaryDowngrade(initConfig, altCanAuthBefore, newConfig, altCanAuthAfter) {
- jsTestLog("Testing downgrade from latest to last-lts");
- const rst = new ReplSetTest({nodes: 2, nodeOptions: {setParameter: initConfig}});
- rst.startSet();
- rst.initiate();
-
- let conn = rst.getPrimary();
- setup(conn);
- runAuthTest(conn.host, altCanAuthBefore);
-
- {
- const adminDB = conn.getDB('admin');
- assert.commandWorked(adminDB.runCommand(
- {setFeatureCompatibilityVersion: lastLTSFCV, confirm: true, writeConcern: {w: 1}}));
- checkFCV(adminDB, lastLTSFCV);
- adminDB.logout();
- }
-
- jsTestLog("Starting binary downgrade to last LTS");
- rst.upgradeSet({binVersion: 'last-lts', setParameter: newConfig});
- jsTestLog("Finished binary downgrade to last LTS");
-
- conn = rst.getPrimary();
- runAuthTest(conn.host, altCanAuthAfter);
-
- rst.stopSet();
-}
-
-KeyServer.start();
-
-testBinaryUpgrade(startupOptions, false, startupOptions, false);
-testBinaryUpgrade(startupOptions, false, startupOptionsNotDowngradable, true);
-
-testBinaryDowngrade(startupOptionsNotDowngradable, true, startupOptions, false);
-testBinaryDowngrade(startupOptions, false, startupOptions, false);
-
-KeyServer.stop();
diff --git a/jstests/multiVersion/targetedTestsLastLtsFeatures/query_stats_upgrade_downgrade.js b/jstests/multiVersion/targetedTestsLastLtsFeatures/query_stats_upgrade_downgrade.js
deleted file mode 100644
index fe8a90aed8f..00000000000
--- a/jstests/multiVersion/targetedTestsLastLtsFeatures/query_stats_upgrade_downgrade.js
+++ /dev/null
@@ -1,268 +0,0 @@
-/**
- * Verifies that $queryStats operates correctly when upgrading and downgrading.
- */
-
-import "jstests/multiVersion/libs/multi_rs.js";
-import "jstests/multiVersion/libs/multi_cluster.js";
-import {assertDropAndRecreateCollection} from "jstests/libs/collection_drop_recreate.js";
-import {getQueryStats, verifyMetrics} from "jstests/libs/query_stats_utils.js";
-(function() {
-"use strict";
-
-const lastLTSVersion = "last-lts";
-
-class UpgradeDowngradeTestFixture {
- constructor() {
- this.collectionName = "coll";
- }
-
- getTestDB() {
- return this.rst.getPrimary().getDB(jsTestName());
- }
-
- createAndPopulateTestCollection() {
- let testDB = this.getTestDB();
- let coll = assertDropAndRecreateCollection(testDB, "coll");
- assert.commandWorked(coll.insertMany([{x: 0}, {x: 1}, {x: 2}]));
- }
-
- setup() {
- jsTestLog("Starting ReplicaSet Upgrade/Downgrade Test!");
-
- this.rst = new ReplSetTest({
- name: jsTestName(),
- nodes: [{binVersion: lastLTSVersion}, {binVersion: lastLTSVersion}]
- });
- this.rst.startSet();
- this.rst.initiate();
- this.createAndPopulateTestCollection();
- }
-
- teardown() {
- jsTestLog("Teardown ReplicaSet Upgrade/Downgrade Test!");
-
- this.rst.stopSet();
- }
-
- getTestCollection() {
- return this.getTestDB().getCollection(this.collectionName);
- }
-
- adminCommand(command) {
- return this.rst.getPrimary().getDB("admin").runCommand(command);
- }
-
- upgradeBinaries() {
- this.rst.upgradeSet({binVersion: "latest"});
- }
-
- upgradeFCV() {
- assert.commandWorked(
- this.adminCommand({setFeatureCompatibilityVersion: latestFCV, confirm: true}));
- }
-
- downgradeFCV() {
- // Downgrade FCV (without restarting) and check that $queryStats returns an error.
- assert.commandWorked(
- this.adminCommand({setFeatureCompatibilityVersion: lastLTSFCV, confirm: true}));
- }
-
- testQueryStatsParam(expectedResult) {
- if (expectedResult === true) {
- assert.commandWorked(
- this.adminCommand({setParameter: 1, internalQueryStatsRateLimit: -1}));
- } else {
- // Check that $queryStats related parameter does not work.
- assert.commandFailedWithCode(
- this.adminCommand({setParameter: 1, internalQueryStatsRateLimit: -1}), 7373500);
- }
- }
-
- testQueryStatsCommandFailure(expectedErrorCode) {
- assert.commandFailedWithCode(
- this.adminCommand({aggregate: 1, pipeline: [{$queryStats: {}}], cursor: {}}),
- expectedErrorCode);
- }
-
- isShardedCluster() {
- return false;
- }
-
- verifyQueryStatsOutput({expectedNShapes}) {
- const queryStats = getQueryStats(this);
- assert.eq(expectedNShapes, queryStats.length, queryStats);
- verifyMetrics(queryStats);
- }
-}
-
-class ShardedClusterUpgradeDowngradeTestFixture extends UpgradeDowngradeTestFixture {
- setup() {
- jsTestLog("Starting Sharded Upgrade/Downgrade Test!");
- this.shardedTest = new ShardingTest({
- name: jsTestName(),
- shards: 1,
- mongos: 1,
- config: 1,
- rs: {nodes: [{binVersion: lastLTSVersion}, {binVersion: lastLTSVersion}]},
- mongosOptions: {binVersion: lastLTSVersion},
- });
- this.createAndPopulateTestCollection();
- }
-
- isShardedCluster() {
- return true;
- }
-
- adminCommand(command) {
- return this.shardedTest.s.adminCommand(command);
- }
-
- getTestDB() {
- return this.shardedTest.s.getDB(jsTestName());
- }
-
- upgradeBinaries() {
- this.shardedTest.upgradeCluster('latest');
- }
-
- teardown() {
- jsTestLog("Teardown ReplicaSet Upgrade/Downgrade Test!");
- this.shardedTest.stop();
- }
-}
-
-function runTest(fixture) {
- // 0. Initialize the fixture, we begin with a binary version that doesn't support queryStats.
- fixture.setup();
-
- // 1. Test that queryStats related features don't work in the base binary.
- // 1.a. Verify queryStats is disabled by checking that setting queryStats related parameters and
- // running the $queryStats stage both fail.
- fixture.testQueryStatsParam(false);
- fixture.testQueryStatsCommandFailure(ErrorCodes.QueryFeatureNotAllowed);
-
- // 1.b. Run some queries while running base binary. We don't expect these queries to be
- // collected by queryStats.
- {
- let coll = fixture.getTestCollection();
- let res = coll.aggregate([{$match: {x: 2}}]).toArray();
- assert.eq(1, res.length, res);
-
- res = coll.find({x: 2}).toArray();
- assert.eq(1, res.length, res);
- }
-
- // 2. Upgrade both the binaries and FCV. After the upgrade we expect query stats features
- // to work. Further, we verify that the previously executed queries were not collected by
- // checking the results from the $queryStats stage.
- fixture.upgradeBinaries();
- fixture.upgradeFCV();
-
- // 2.a. Verify that queryStats parameters can be set after the upgrade, and that previously
- // executed queries were not collected.
- fixture.testQueryStatsParam(true);
- fixture.verifyQueryStatsOutput({expectedNShapes: 0});
-
- // 2.b. Execute two new queries (i.e new query shapes) and check that they are collected.
- {
- let coll = fixture.getTestCollection();
- let res = coll.aggregate([{$match: {x: 2}}, {$sort: {x: -1}}]).toArray();
- assert.eq(1, res.length, res);
-
- res = coll.find({x: 2}, {noCursorTimeout: true}).toArray();
- assert.eq(1, res.length, res);
-
- fixture.verifyQueryStatsOutput({
- expectedNShapes: 3 /* 1 each for the above, plus $queryStats itself */
- });
- }
-
- // 3. Downgrade FCV (without restarting). Without restarting the server, we expect the
- // queryStatsStore to keep existing entries, but to not collect any more statistics while an FCV
- // that doesn't support queryStats is in place.
- fixture.downgradeFCV();
-
- // 3.a. Run additional queries (new query shapes) after the downgrade.
- {
- let coll = fixture.getTestCollection();
- let res = coll.aggregate([{$match: {x: 2}}]).toArray();
- assert.eq(1, res.length, res);
-
- res = coll.find({x: 2}).toArray();
- assert.eq(1, res.length, res);
- }
-
- // 3.b. If we are testing a sharded cluster, we don't expect queryStats to be disabled after the
- // FCV downgrade. This is because in a sharded cluster, query stats resides on mongos, and
- // mongos doesn't have a concept of its own in memory FCV settings. When a sharded cluster has
- // its FCV downgraded, it forwards the downgrade request to the shards and the config
- // servers. However, the router itself bases its FCV on its binaries. In our case, once we
- // upgrade the binary on the mongos, we can no longer downgrade the FCV to "disable" queryStats.
- // As a result, in the sharded scenario we expect the two queries run after the downgrade to
- // have been collected by query stats.
- if (fixture.isShardedCluster()) {
- fixture.verifyQueryStatsOutput({
- expectedNShapes: 5 /* 3 from the previous queries + the two additional ones captured
- after the downgrade. */
- });
- fixture.teardown();
- return;
- }
-
- // 3.c. After the FCV downgrade (i.e FCV v7.2), running $queryStats should return an error.
- fixture.testQueryStatsCommandFailure(ErrorCodes.QueryFeatureNotAllowed);
-
- // 3.d. Upgrade the FCV without restart. QueryStatsStore should not have been cleared. Previous
- // stats collected should be returned. The queries made during the downgrade should not
- // have been collected. Note that getQueryStats() uses the same query to collect the statistics,
- // so running $queryStats doesn't result in additional entries.
- fixture.upgradeFCV();
- fixture.verifyQueryStatsOutput({expectedNShapes: 3});
-
- // 4. Test query stats during a failed FCV downgrade. During the failed FCV downgrade, the FCV
- // reverts back to the lastLTSFCV which doesn't support queryStats.
- jsTestLog("Turning the failpoint on.");
- assert.commandWorked(
- fixture.adminCommand({configureFailPoint: 'failDowngrading', mode: "alwaysOn"}));
-
- assert.commandFailedWithCode(
- fixture.adminCommand({setFeatureCompatibilityVersion: lastLTSFCV, confirm: true}), 549181);
-
- // 4.a. Current FCV is lower than the FCV necessary (7.2) for queryStats to run. These queries
- // should not be collected.
- {
- let coll = fixture.getTestCollection();
- let res = coll.aggregate([{$match: {x: 2}}]).toArray();
- assert.eq(1, res.length, res);
-
- res = coll.find({x: 2}).toArray();
- assert.eq(1, res.length, res);
- }
- // 4.b. Running $queryStats should return an error.
- fixture.testQueryStatsCommandFailure(ErrorCodes.QueryFeatureNotAllowed);
-
- // 4.c. Successfully upgrade FCV. Check that the queries run during the failed downgrade were
- // not collected.
- fixture.upgradeFCV();
- fixture.verifyQueryStatsOutput({expectedNShapes: 3});
-
- // 4.d. Execute two new queries (new query shapes), these should result in new entries.
- {
- let coll = fixture.getTestCollection();
- let res = coll.aggregate([{$match: {x: 2}}], {allowDiskUse: false}).toArray();
- assert.eq(1, res.length, res);
-
- res = coll.find({x: 2}, {allowPartialResults: true}).toArray();
- assert.eq(1, res.length, res);
-
- fixture.verifyQueryStatsOutput({expectedNShapes: 5});
- }
-
- fixture.teardown();
-}
-
-// Perform Upgrade/Downgrade test on replica set.
-runTest(new UpgradeDowngradeTestFixture());
-// Perform Upgrade/Downgrade test on sharded cluster.
-runTest(new ShardedClusterUpgradeDowngradeTestFixture());
-})();
diff --git a/jstests/multiVersion/targetedTestsLastLtsFeatures/timeseries_fixed_bucket_match_rewrite.js b/jstests/multiVersion/targetedTestsLastLtsFeatures/timeseries_fixed_bucket_match_rewrite.js
deleted file mode 100644
index 360e42d70c6..00000000000
--- a/jstests/multiVersion/targetedTestsLastLtsFeatures/timeseries_fixed_bucket_match_rewrite.js
+++ /dev/null
@@ -1,153 +0,0 @@
-/**
- * Tests that the query rewrites for fixed bucketing can successfully be handled by a mixed cluster.
- * The primary shard rewrites the query and sends it to the secondary shard that can handle running
- * the rewritten query, even though the secondary shard's FCV is downgraded to 7.0.
- */
-import "jstests/multiVersion/libs/multi_cluster.js";
-
-import {getAggPlanStages} from "jstests/libs/analyze_plan.js";
-import {awaitRSClientHosts} from "jstests/replsets/rslib.js";
-
-(function() {
-"use strict";
-
-const st = new ShardingTest({
- shards: 2,
- rs: {nodes: 2},
- mongos: 1,
- other: {
- mongosOptions: {binVersion: "latest"},
- configOptions: {binVersion: "latest"},
- shardOptions: {binVersion: "latest"},
- rsOptions: {binVersion: "latest"}
- }
-});
-st.configRS.awaitReplication();
-
-// Create a sharded time-series collection that has fixed buckets.
-const dbName = "test";
-let testDB = st.s.getDB(dbName);
-assert.commandWorked(st.s.adminCommand({enableSharding: dbName, primaryShard: st.shard0.name}));
-
-let coll = testDB["timeseries"];
-const timeField = "t";
-coll.drop();
-const shardKey = {
- [timeField]: 1
-};
-
-function runPipeline(predValue) {
- // Run the query and confirm the correct results were returned.
- let predicate = ISODate("2022-11-12");
- if (predValue) {
- predicate = predValue;
- }
- const pipeline = [{$match: {[timeField]: {$lt: predicate}}}];
- const results = coll.aggregate(pipeline).toArray();
- assert.sameMembers(results, [docs[0], docs[1], docs[2]]);
-
- const explain = coll.explain().aggregate(pipeline);
- const unpackStage = getAggPlanStages(explain, "$_internalUnpackBucket");
- // If data is on both of the shards, we will see 2 "$_internalUnpackBucket" stages in the
- // explain plan.
- assert.gte(unpackStage.length, 1, `Expected $_internalUnpackBucket in ${tojson(explain)}`);
- return unpackStage[0]["$_internalUnpackBucket"];
-}
-
-assert.commandWorked(testDB.adminCommand({
- shardCollection: `${dbName}.${coll.getName()}`,
- key: shardKey,
- timeseries: {timeField, bucketRoundingSeconds: 3600, bucketMaxSpanSeconds: 3600}
-}));
-
-// Set up the shards such that the primary shard has [MinKey, 2022-09-30), and the other shard has
-// [2022-09-30, MaxKey].
-let splitPoint = {[`control.min.${timeField}`]: ISODate(`2022-09-30`)};
-assert.commandWorked(
- testDB.adminCommand({split: `${dbName}.system.buckets.${coll.getName()}`, middle: splitPoint}));
-
-// Move one of the chunks into the second shard.
-const primaryShard = st.getPrimaryShard(dbName);
-const otherShard = st.getOther(primaryShard);
-assert.commandWorked(testDB.adminCommand({
- movechunk: `${dbName}.system.buckets.${coll.getName()}`,
- find: splitPoint,
- to: otherShard.name,
- _waitForDelete: true
-}));
-
-// Insert 4 documents and expect 2 documents on each shard.
-const docs = [
- {_id: 0, [timeField]: ISODate("2017-10-12")},
- {_id: 1, [timeField]: ISODate("2018-10-12")},
- {_id: 2, [timeField]: ISODate("2022-10-12")},
- {_id: 3, [timeField]: ISODate("2023-11-12")},
-];
-coll.insertMany(docs);
-
-// Run the pipeline, and expect no eventFilter, since the rewrite should occur.
-let unpackStage = runPipeline();
-assert(!unpackStage["eventFilter"], "Expected no eventFilter, but got: " + tojson(unpackStage));
-
-// Run a different pipeline, and expect an eventFilter. The rewrite does not apply because the
-// predicate passed in does not align with the bucket boundaries.
-unpackStage = runPipeline(ISODate("2022-11-12T07:30:10.957Z") /* predValue */);
-assert(unpackStage["eventFilter"], "Expected an eventFilter, but got: " + tojson(unpackStage));
-
-// Downgrade the FCV version.
-jsTestLog('downgrading the FCV version.');
-assert.commandWorked(testDB.adminCommand({setFeatureCompatibilityVersion: '7.0', confirm: true}));
-
-// Run the pipeline, and expect an eventFilter, since the FCV version is downgraded.
-unpackStage = runPipeline();
-assert(unpackStage["eventFilter"], "Expected an eventFilter, but got: " + tojson(unpackStage));
-
-// Downgrade the mongos binary.
-jsTestLog('downgrading mongos.');
-st.restartBinariesWithDowngradeBackCompat('latest');
-st.downgradeBinariesWithoutDowngradeBackCompat('last-lts',
- {downgradeShards: false, downgradeConfigs: false});
-let mongosConn = st.s;
-testDB = mongosConn.getDB(dbName);
-coll = testDB[coll.getName()];
-
-// Downgrade the other shard's binary. We now have a mixed cluster.
-jsTestLog('downgrading other shard.');
-st.downgradeBinariesWithoutDowngradeBackCompat('last-lts', {
- downgradeShards: false,
- downgradeOneShard: st.rs1,
- downgradeMongos: false,
- downgradeConfigs: false
-});
-awaitRSClientHosts(st.s, st.rs0.getPrimary(), {ok: true, ismaster: true});
-awaitRSClientHosts(st.s, st.rs1.getPrimary(), {ok: true, ismaster: true});
-
-// Before running the query, restart the profiler.
-const primaryDB = st.shard0.getDB(dbName);
-const otherDB = st.shard1.getDB(dbName);
-for (let shardDB of [primaryDB, otherDB]) {
- shardDB.setProfilingLevel(0);
- shardDB.system.profile.drop();
- shardDB.setProfilingLevel(2);
-}
-// Run the pipeline, and expect an eventFilter, since the FCV version is still downgraded.
-unpackStage = runPipeline();
-assert(unpackStage["eventFilter"], "Expected an eventFilter, but got: " + tojson(unpackStage));
-
-// Confirm the other shard ran the query.
-let filter = {"command.aggregate": `system.buckets.${coll.getName()}`};
-const otherShardEntries = otherDB.system.profile.find(filter).toArray();
-assert.eq(otherShardEntries.length, 1, otherShardEntries);
-
-// Downgrade the rest of the shards and the config server.
-jsTestLog('downgrading the rest of the shards and the config server.');
-st.downgradeBinariesWithoutDowngradeBackCompat('last-lts', {downgradeMongos: false});
-awaitRSClientHosts(st.s, st.rs0.getPrimary(), {ok: true, ismaster: true});
-awaitRSClientHosts(st.s, st.rs1.getPrimary(), {ok: true, ismaster: true});
-
-// Run the pipeline, and expect an eventFilter, since the FCV version is still downgraded.
-unpackStage = runPipeline();
-assert(unpackStage["eventFilter"], "Expected an eventFilter, but got: " + tojson(unpackStage));
-
-st.stop();
-}());
diff --git a/jstests/multiVersion/targetedTestsLastLtsFeatures/timeseries_fixed_param_flag.js b/jstests/multiVersion/targetedTestsLastLtsFeatures/timeseries_fixed_param_flag.js
deleted file mode 100644
index 36eca2bb822..00000000000
--- a/jstests/multiVersion/targetedTestsLastLtsFeatures/timeseries_fixed_param_flag.js
+++ /dev/null
@@ -1,105 +0,0 @@
-/**
- * Verifies that the internal collection catalog parameter is correctly cleanup after downgrade.
- */
-
-import "jstests/multiVersion/libs/multi_rs.js";
-
-(function() {
-"use strict";
-
-const latestVersion = "latest";
-const rst = new ReplSetTest(
- {name: jsTestName(), nodes: [{binVersion: latestVersion}, {binVersion: latestVersion}]});
-rst.startSet();
-rst.initiate();
-const testDB = rst.getPrimary().getDB("test");
-
-const collectionName = "coll";
-assert.commandWorked(testDB.createCollection(collectionName, {timeseries: {timeField: 't'}}));
-let output = assert.commandWorked(
- testDB.runCommand({timeseriesCatalogBucketParamsChanged: 'system.buckets.coll'}));
-assert.eq(output.changed, false);
-
-// Ensure that running empty collMod does not affect the flag while on latest FCV.
-assert.commandWorked(testDB.runCommand({collMod: collectionName}));
-output = assert.commandWorked(
- testDB.runCommand({timeseriesCatalogBucketParamsChanged: 'system.buckets.coll'}));
-assert.eq(output.changed, false);
-
-// Running a setFCV downgrade command should remove the catalog flag.
-assert.commandWorked(rst.getPrimary().getDB("admin").runCommand(
- {setFeatureCompatibilityVersion: lastLTSFCV, confirm: true}));
-output = assert.commandWorked(
- testDB.runCommand({timeseriesCatalogBucketParamsChanged: 'system.buckets.coll'}));
-assert.eq(output.changed, undefined);
-
-// While FCV is in downgrading/downgraded state, collMod command should not effect the bucketing
-// parameters flag.
-assert.commandWorked(
- testDB.runCommand({collMod: collectionName, timeseries: {granularity: "minutes"}}));
-output = assert.commandWorked(
- testDB.runCommand({timeseriesCatalogBucketParamsChanged: 'system.buckets.coll'}));
-assert.eq(output.changed, undefined);
-
-assert.commandWorked(rst.getPrimary().getDB("admin").runCommand(
- {setFeatureCompatibilityVersion: latestFCV, confirm: true}));
-
-// After the FCV is set to latest, the value of the flag of the collection should be undefined.
-output = assert.commandWorked(
- testDB.runCommand({timeseriesCatalogBucketParamsChanged: 'system.buckets.coll'}));
-assert.eq(output.changed, undefined);
-
-// After FCV is set to latest, collMod command should explicity set the bucketing parameters flag
-// to true.
-assert.commandWorked(testDB.runCommand({
- collMod: collectionName,
- timeseries: {bucketRoundingSeconds: 100000, bucketMaxSpanSeconds: 100000}
-}));
-output = assert.commandWorked(
- testDB.runCommand({timeseriesCatalogBucketParamsChanged: 'system.buckets.coll'}));
-assert.eq(output.changed, true);
-
-// Now that the feature is turned on, new time-series collections by default will have the flag set
-// to 'false'.
-const otherCollName = "other_coll";
-const otherCollBucketsName = "system.buckets.other_coll";
-assert.commandWorked(testDB.createCollection(
- otherCollName,
- {timeseries: {timeField: 't', bucketRoundingSeconds: 3600, bucketMaxSpanSeconds: 3600}}));
-output = assert.commandWorked(
- testDB.runCommand({timeseriesCatalogBucketParamsChanged: otherCollBucketsName}));
-assert.eq(output.changed, false);
-
-// We will now test the flag is set correctly if the FCV downgrade fails after only reaching the
-// `downgrading` FCV state, and then is fully upgraded again.
-jsTestLog("Turning the failpoint on.");
-assert.commandWorked(
- rst.getPrimary().adminCommand({configureFailPoint: 'failDowngrading', mode: "alwaysOn"}));
-assert.commandFailedWithCode(
- testDB.adminCommand({setFeatureCompatibilityVersion: lastLTSFCV, confirm: true}), 549181);
-
-// Confirm feature is still enabled since the FCV downgrade failed.
-output = assert.commandWorked(
- testDB.runCommand({timeseriesCatalogBucketParamsChanged: otherCollBucketsName}));
-assert.eq(output.changed, false);
-
-assert.commandWorked(rst.getPrimary().getDB("admin").runCommand(
- {setFeatureCompatibilityVersion: latestFCV, confirm: true}));
-
-// Confirm the feature remains enabled when the FCV is upgraded. Since the FCV is already at '7.1'
-// the value of the flag should not change.
-output = assert.commandWorked(
- testDB.runCommand({timeseriesCatalogBucketParamsChanged: otherCollBucketsName}));
-assert.eq(output.changed, false);
-
-// The flag should be set to true after a collMod command.
-assert.commandWorked(testDB.runCommand({
- collMod: otherCollName,
- timeseries: {bucketRoundingSeconds: 100000, bucketMaxSpanSeconds: 100000}
-}));
-output = assert.commandWorked(
- testDB.runCommand({timeseriesCatalogBucketParamsChanged: otherCollBucketsName}));
-assert.eq(output.changed, true);
-
-rst.stopSet();
-})();
diff --git a/jstests/noPassthrough/index_build_aborted_on_fcv_downgrade.js b/jstests/noPassthrough/index_build_aborted_on_fcv_downgrade.js
deleted file mode 100644
index 9dd44910ddb..00000000000
--- a/jstests/noPassthrough/index_build_aborted_on_fcv_downgrade.js
+++ /dev/null
@@ -1,195 +0,0 @@
-/**
- * Ensures that index builds are aborted when setFCV causes an FCV downgrade, and that during that
- * period new index builds are blocked.
- *
- * TODO (SERVER-68290): remove test when removing index build abort on FCV downgrade and reintroduce
- * "jstests/noPassthrough/index_downgrade_fcv.js".
- *
- * @tags: [
- * requires_fcv_71,
- * requires_replication,
- * ]
- */
-import {configureFailPoint} from "jstests/libs/fail_point_util.js";
-import {funWithArgs} from "jstests/libs/parallel_shell_helpers.js";
-import {extractUUIDFromObject} from "jstests/libs/uuid_util.js";
-import {IndexBuildTest} from "jstests/noPassthrough/libs/index_build.js";
-
-function startParallelSetFcv(primary, expectedError) {
- return startParallelShell(
- funWithArgs(function(expectedError) {
- // Should fail due to failAfterReachingTransitioningState.
- assert.commandFailedWithCode(
- db.adminCommand({setFeatureCompatibilityVersion: lastLTSFCV, confirm: true}),
- expectedError);
- }, expectedError), primary.port);
-}
-
-function testIndexBuildsBlockedAndAbortedOnFcvDowngrade() {
- const rst = new ReplSetTest({
- nodes: [
- {},
- {
- // Disallow elections on secondary.
- rsConfig: {
- priority: 0,
- },
- },
- ]
- });
- rst.startSet();
- rst.initiate();
-
- const dbName = 'test';
- const collName = 'coll';
- const primary = rst.getPrimary();
- const primaryDB = primary.getDB(dbName);
- const primaryColl = primaryDB.getCollection(collName);
-
- assert.commandWorked(primaryColl.insert({a: 1}));
-
- rst.awaitReplication();
-
- // Clear log to ensure checkLog does not see unrelated log entries.
- assert.commandWorked(primaryDB.adminCommand({clearLog: 'global'}));
-
- // Hang an index build in the commit phase, to later check that FCV downgrade waits on a
- // commiting index build.
- const hangIndexBuildBeforeCommit = configureFailPoint(primary, "hangIndexBuildBeforeCommit");
- const createIdxCommit = IndexBuildTest.startIndexBuild(
- primary, primaryColl.getFullName(), {c: 1}, null, [ErrorCodes.IndexBuildAborted]);
- const commitBuildUUID =
- IndexBuildTest
- .assertIndexesSoon(primaryColl, 2, ['_id_'], ['c_1'], {includeBuildUUIDs: true})['c_1']
- .buildUUID;
- hangIndexBuildBeforeCommit.wait();
-
- // Setup index build to be aborted by the FCV downgrade.
- const hangAfterInitializingIndexBuild =
- configureFailPoint(primary, "hangAfterInitializingIndexBuild");
- const createIdxAborted = IndexBuildTest.startIndexBuild(
- primary, primaryColl.getFullName(), {a: 1}, null, [ErrorCodes.IndexBuildAborted]);
-
- const abortedBuildUUID =
- IndexBuildTest
- .assertIndexesSoon(
- primaryColl, 3, ['_id_'], ['a_1', 'c_1'], {includeBuildUUIDs: true})['a_1']
- .buildUUID;
-
- hangAfterInitializingIndexBuild.wait();
-
- const hangAfterBlockingIndexBuildsForFcvDowngrade =
- configureFailPoint(primary, "hangAfterBlockingIndexBuildsForFcvDowngrade");
-
- // Ensure index build block and abort happens during the FCV transitioning state.
- configureFailPoint(primary, "failAfterReachingTransitioningState");
-
- const awaitSetFcv = startParallelSetFcv(primary, 7555200);
-
- hangAfterBlockingIndexBuildsForFcvDowngrade.wait();
-
- // Start an index build while the block is active.
- const createIdxBlocked =
- IndexBuildTest.startIndexBuild(primary, primaryColl.getFullName(), {b: 1});
- // "Index build: new index builds are blocked, waiting".
- checkLog.containsJson(primary, 7738700);
-
- hangAfterBlockingIndexBuildsForFcvDowngrade.off();
-
- // "About to abort all index builders running".
- assert.soon(() => checkLog.checkContainsWithCountJson(primary,
- 7738702,
- {
- reason: function(reason) {
- return reason.startsWith(
- "FCV downgrade in progress");
- }
- },
- /*count=*/ 1));
-
- // "Index build: joined after abort".
- checkLog.containsJson(primary, 20655, {
- buildUUID: function(uuid) {
- return uuid && uuid["uuid"]["$uuid"] === extractUUIDFromObject(abortedBuildUUID);
- }
- });
-
- checkLog.containsJson(primary, 4725201, {
- indexBuilds: function(uuidArray) {
- return uuidArray && uuidArray.length == 1 &&
- uuidArray[0]["uuid"]["$uuid"] === extractUUIDFromObject(commitBuildUUID);
- }
- });
- hangIndexBuildBeforeCommit.off();
- hangAfterInitializingIndexBuild.off();
-
- jsTestLog("Waiting for threads to join");
- createIdxAborted();
- createIdxCommit();
- awaitSetFcv();
- createIdxBlocked();
-
- // The index build started before the FCV downgrade should have been aborted, while the build
- // started while the index build block was in place should have succeeded. The index build which
- // was already in the commit phase when the FCV downgrade took place should also have completed.
- IndexBuildTest.assertIndexesSoon(primaryColl, 3, ['_id_', 'b_1', 'c_1']);
-
- rst.stopSet();
-}
-
-function testIndexBuildsUnblockedOnSetFcvCommandInterrupt() {
- const rst = new ReplSetTest({
- nodes: [
- {},
- {
- // Disallow elections on secondary.
- rsConfig: {
- priority: 0,
- },
- },
- ]
- });
- rst.startSet();
- rst.initiate();
-
- const dbName = 'test';
- const collName = 'coll';
- const primary = rst.getPrimary();
- const primaryDB = primary.getDB(dbName);
- const primaryColl = primaryDB.getCollection(collName);
-
- assert.commandWorked(primaryColl.insert({a: 1}));
-
- rst.awaitReplication();
-
- // Clear log to ensure checkLog does not see unrelated log entries.
- assert.commandWorked(primaryDB.adminCommand({clearLog: 'global'}));
-
- const hangAfterBlockingIndexBuildsForFcvDowngrade =
- configureFailPoint(primary, "hangAfterBlockingIndexBuildsForFcvDowngrade");
-
- // Verify the index builds are unblocked in case the setFCV command is interrupted.
- const awaitKilledSetFcv = startParallelSetFcv(primary, ErrorCodes.Interrupted);
- hangAfterBlockingIndexBuildsForFcvDowngrade.wait();
-
- const pipeline = [
- {$currentOp: {allUsers: true, idleConnections: true}},
- {$match: {"command.setFeatureCompatibilityVersion": {$exists: true}}}
- ];
- const curOpResult =
- primary.getDB("admin").aggregate(pipeline, {readConcern: {level: "local"}}).toArray();
- assert.eq(curOpResult.length, 1);
- assert.commandWorked(primary.adminCommand({killOp: 1, op: curOpResult[0].opid}));
-
- awaitKilledSetFcv();
-
- const createIdxBlocked =
- IndexBuildTest.startIndexBuild(primary, primaryColl.getFullName(), {b: 1});
- createIdxBlocked();
- IndexBuildTest.assertIndexesSoon(primaryColl, 2, ['_id_', 'b_1']);
-
- rst.stopSet();
-}
-
-testIndexBuildsBlockedAndAbortedOnFcvDowngrade();
-testIndexBuildsUnblockedOnSetFcvCommandInterrupt();
diff --git a/jstests/noPassthrough/queryStats/query_stats_disable_after_initial_request.js b/jstests/noPassthrough/queryStats/query_stats_disable_after_initial_request.js
index f485f61e894..4ef1ae814f8 100644
--- a/jstests/noPassthrough/queryStats/query_stats_disable_after_initial_request.js
+++ b/jstests/noPassthrough/queryStats/query_stats_disable_after_initial_request.js
@@ -48,11 +48,6 @@ function setQueryStatsCacheSize(size) {
assert.commandWorked(testDB.adminCommand({setParameter: 1, internalQueryStatsCacheSize: size}));
}
-function setFCV(newFCV) {
- assert.commandWorked(
- testDB.adminCommand({setFeatureCompatibilityVersion: newFCV, confirm: true}));
-}
-
// Tests the scenario of disabling query stats by setting internalQueryStatsCacheSize to 0 and
// ending the command by running it to completion.
testStatsAreNotCollectedWhenDisabledBeforeCommandCompletion({
@@ -74,25 +69,4 @@ testStatsAreNotCollectedWhenDisabledBeforeCommandCompletion({
enableQueryStatsFn: () => setQueryStatsCacheSize("10MB")
});
-// Tests the scenario of disabling query stats by downgrading the FCV and ending the command by
-// running it to completion.
-testStatsAreNotCollectedWhenDisabledBeforeCommandCompletion({
- conn: testDB,
- coll,
- disableQueryStatsFn: () => setFCV(lastLTSFCV),
- endCommandFn: (cursor) => cursor.itcount(),
- enableQueryStatsFn: () => setFCV(binVersionToFCV("latest"))
-});
-
-// Tests the scenario of disabling query stats by downgrading the FCV and ending the command by
-// killing the cursor.
-testStatsAreNotCollectedWhenDisabledBeforeCommandCompletion({
- conn: testDB,
- coll,
- disableQueryStatsFn: () => setFCV(lastLTSFCV),
- endCommandFn: (cursor) => assert.commandWorked(
- testDB.runCommand({killCursors: coll.getName(), cursors: [cursor.getId()]})),
- enableQueryStatsFn: () => setFCV(binVersionToFCV("latest"))
-});
-
MongoRunner.stopMongod(conn);
diff --git a/jstests/noPassthrough/queryStats/query_stats_upgrade.js b/jstests/noPassthrough/queryStats/query_stats_upgrade.js
deleted file mode 100644
index 64b07068c9d..00000000000
--- a/jstests/noPassthrough/queryStats/query_stats_upgrade.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * Test that query stats doesn't work on a lower FCV version but works after an FCV upgrade.
- * @tags: [
- * # Query Stats is new in 7.1.
- * requires_fcv_71,
- * # Re-uses FCV state in the dbpath.
- * requires_persistence
- * ]
- */
-
-const dbpath = MongoRunner.dataPath + jsTestName();
-let conn = MongoRunner.runMongod({dbpath: dbpath});
-let testDB = conn.getDB(jsTestName());
-
-function testLower(restart = false) {
- let adminDB = conn.getDB("admin");
- assert.commandWorked(adminDB.runCommand(
- {setFeatureCompatibilityVersion: binVersionToFCV("last-lts"), confirm: true}));
- if (restart) {
- MongoRunner.stopMongod(conn);
- conn = MongoRunner.runMongod({dbpath: dbpath, noCleanData: true});
- testDB = conn.getDB(jsTestName());
- adminDB = conn.getDB("admin");
- }
-
- assert.commandFailedWithCode(
- testDB.adminCommand({aggregate: 1, pipeline: [{$queryStats: {}}], cursor: {}}),
- [6579000, ErrorCodes.QueryFeatureNotAllowed]);
-
- // Upgrade FCV.
- assert.commandWorked(adminDB.runCommand(
- {setFeatureCompatibilityVersion: binVersionToFCV("latest"), confirm: true}));
-
- // We should be able to run a query stats pipeline now that the FCV is correct.
- assert.commandWorked(
- testDB.adminCommand({aggregate: 1, pipeline: [{$queryStats: {}}], cursor: {}}),
- );
-}
-testLower(true);
-testLower(false);
-MongoRunner.stopMongod(conn);
diff --git a/jstests/serverless/shard_merge_enabled.js b/jstests/serverless/shard_merge_enabled.js
deleted file mode 100644
index ef7a4179914..00000000000
--- a/jstests/serverless/shard_merge_enabled.js
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- * Tests that the "shard merge" protocol is enabled only in the proper FCV.
- *
- * @tags: [
- * requires_shard_merge,
- * serverless,
- * requires_fcv_71,
- * ]
- */
-
-import {configureFailPoint} from "jstests/libs/fail_point_util.js";
-
-function runTest(downgradeFCV) {
- const rst = new ReplSetTest({nodes: 1, serverless: true});
- rst.startSet();
- rst.initiate();
-
- const primary = rst.getPrimary();
-
- const adminDB = primary.getDB("admin");
- const kDummyConnStr = "mongodb://localhost/?replicaSet=foo";
- const readPreference = {mode: 'primary'};
-
- // A function, not a constant, to ensure unique UUIDs.
- function donorStartMigrationCmd() {
- return {
- donorStartMigration: 1,
- protocol: "shard merge",
- migrationId: UUID(),
- recipientConnectionString: kDummyConnStr,
- readPreference: readPreference,
- tenantIds: [ObjectId()]
- };
- }
-
- function recipientSyncDataCmd() {
- return {
- recipientSyncData: 1,
- protocol: "shard merge",
- migrationId: UUID(),
- tenantIds: [ObjectId()],
- donorConnectionString: kDummyConnStr,
- readPreference: readPreference,
- startMigrationDonorTimestamp: Timestamp(1, 1),
- };
- }
-
- function recipientForgetMigrationCmd() {
- return {
- recipientForgetMigration: 1,
- protocol: "shard merge",
- migrationId: UUID(),
- tenantIds: [ObjectId()],
- donorConnectionString: kDummyConnStr,
- readPreference: readPreference,
- decision: "committed"
- };
- }
-
- function func(cmd) {
- return eval(cmd + "Cmd()");
- }
-
- function testCommandWithShardMerge(cmd) {
- let msg = cmd + " shouldn't reject 'shard merge' protocol when it's enabled";
- assert.commandWorked(adminDB.runCommand(func(cmd)), msg);
- }
-
- function testCommandFailsWithShardMerge(cmd, reason, expectedErrorMsg, expectedErrorCode) {
- let msg = `${cmd} ${reason}`;
- let response =
- assert.commandFailedWithCode(adminDB.runCommand(func(cmd)), expectedErrorCode, msg);
- assert.neq(-1,
- response.errmsg.indexOf(expectedErrorMsg),
- "Error message did not contain '" + expectedErrorMsg + "', found:\n" +
- tojson(response));
- }
-
- function testCommandFailsShardMergeNotSupported(cmd) {
- testCommandFailsWithShardMerge(cmd,
- "should reject 'shard merge' protocol when it's disabled",
- "protocol 'shard merge' not supported",
- ErrorCodes.IllegalOperation);
- }
-
- function testCommandFailsProtocolFieldNotSupported(cmd) {
- testCommandFailsWithShardMerge(cmd,
- "should reject 'protocol' field when it's disabled",
- "'protocol' field is not supported for FCV below 5.2'",
- ErrorCodes.InvalidOptions);
- }
-
- // Enable below fail points to prevent starting the donor/recipient POS instance.
- configureFailPoint(primary, "returnResponseCommittedForDonorStartMigrationCmd");
- configureFailPoint(primary, "returnResponseOkForRecipientSyncDataCmd");
- configureFailPoint(primary, "returnResponseOkForRecipientForgetMigrationCmd");
-
- // Preconditions: the shard merge feature is enabled and our fresh RS is on the latest FCV.
- assert.eq(getFCVConstants().latest,
- adminDB.system.version.findOne({_id: 'featureCompatibilityVersion'}).version);
-
- // Shard merge is enabled, so this call should work.
- let cmds = ["donorStartMigration", "recipientSyncData", "recipientForgetMigration"];
- cmds.forEach((cmd) => {
- testCommandWithShardMerge(cmd);
- });
-
- assert.commandWorked(
- adminDB.adminCommand({setFeatureCompatibilityVersion: downgradeFCV, confirm: true}));
- // Now that FCV is downgraded, shard merge is automatically disabled.
- cmds.forEach((cmd) => {
- if (MongoRunner.compareBinVersions(downgradeFCV, "5.2") >= 0) {
- // The "protocol" field is ok, but it can't be "shard merge".
- testCommandFailsShardMergeNotSupported(cmd);
- } else {
- // The "protocol" field is not supported.
- testCommandFailsProtocolFieldNotSupported(cmd);
- }
- });
-
- rst.stopSet();
-}
-
-runFeatureFlagMultiversionTest('featureFlagShardMerge', runTest);
diff --git a/src/mongo/util/version/releases.yml b/src/mongo/util/version/releases.yml
index e31f246c601..8d92bd371ca 100644
--- a/src/mongo/util/version/releases.yml
+++ b/src/mongo/util/version/releases.yml
@@ -24,6 +24,7 @@ featureCompatibilityVersions:
- "7.2"
- "7.3"
- "8.0"
+ - "8.1"
- "100.0" # This version is not an actual version and used for testing only
# All LTS releases starting with 4.0.
longTermSupportReleases:
@@ -33,6 +34,7 @@ longTermSupportReleases:
- "5.0"
- "6.0"
- "7.0"
+ - "8.0"
# List of stable MongoDB versions since 2.0 that have been EOL'd.
# Entries to this section will also stop them from running as "old" versions in