summaryrefslogtreecommitdiff
path: root/jstests/multiVersion
diff options
context:
space:
mode:
authorRobert Guo <robert.guo@10gen.com>2018-05-22 13:04:28 -0400
committerRobert Guo <robert.guo@10gen.com>2018-05-22 15:15:53 -0400
commit27d3642878e8efd88334957b339708f96daa1dbd (patch)
tree3e90c42b467912de48d7f8bba07d705a746de78a /jstests/multiVersion
parent7d71638c84fe95e77e2bdd58cfe117b616aeb31a (diff)
downloadmongo-27d3642878e8efd88334957b339708f96daa1dbd.tar.gz
SERVER-35152 update tests for 4.0
Diffstat (limited to 'jstests/multiVersion')
-rw-r--r--jstests/multiVersion/cannot_create_system_dot_indexes.js69
-rw-r--r--jstests/multiVersion/change_streams_feature_compatibility_version.js234
-rw-r--r--jstests/multiVersion/collection_validator_feature_compatibility_version.js304
-rw-r--r--jstests/multiVersion/downgrade_to_36_only_with_recovered_data.js91
-rw-r--r--jstests/multiVersion/drop_mmap_system_collections_on_wt.js78
-rw-r--r--jstests/multiVersion/ensure_last_applied_on_upgrade_to_40.js85
-rw-r--r--jstests/multiVersion/fcv_chunk_history.js74
-rw-r--r--jstests/multiVersion/fcv_db_versioning.js65
-rw-r--r--jstests/multiVersion/global_snapshot_reads_downgrade_cluster.js91
-rw-r--r--jstests/multiVersion/global_snapshot_reads_upgrade_cluster.js89
-rw-r--r--jstests/multiVersion/startup_without_UUIDs_fails.js66
-rw-r--r--jstests/multiVersion/verify_versions_test.js5
-rw-r--r--jstests/multiVersion/view_definition_feature_compatibility_version.js257
13 files changed, 3 insertions, 1505 deletions
diff --git a/jstests/multiVersion/cannot_create_system_dot_indexes.js b/jstests/multiVersion/cannot_create_system_dot_indexes.js
deleted file mode 100644
index dcdacfcf04b..00000000000
--- a/jstests/multiVersion/cannot_create_system_dot_indexes.js
+++ /dev/null
@@ -1,69 +0,0 @@
-// Tests that the 'system.indexes' collection cannot be created via data transfer from a
-// lower-version node.
-(function() {
-
- // This test should not be run on mmapv1 because the 'system.indexes' collection exists on that
- // storage engine.
- const isMMAPv1 = jsTest.options().storageEngine === "mmapv1";
- if (isMMAPv1) {
- return;
- }
-
- const latest = "latest";
- const downgrade = "3.6";
- const downgradeFCV = "3.6";
-
- const dbName = "test";
- const collName = "coll";
-
- const upgradeConn = MongoRunner.runMongod({binVersion: latest});
- const upgradeDB = upgradeConn.getDB(dbName);
-
- // Set the featureCompatibilityVersion to the downgrade value to allow data transfer from a
- // lower-version node.
- assert.commandWorked(upgradeDB.adminCommand({setFeatureCompatibilityVersion: downgradeFCV}));
-
- const downgradeConn = MongoRunner.runMongod({binVersion: downgrade});
- const downgradeDB = downgradeConn.getDB(dbName);
-
- // The 'system.indexes' collection can be created on a lower-version node.
- assert.commandWorked(downgradeDB.coll.insert({}));
- assert.commandWorked(downgradeDB.createCollection("system.indexes"));
- assert.eq(1,
- downgradeDB.getCollectionInfos({name: "system.indexes"}).length,
- tojson(downgradeDB.getCollectionInfos()));
-
- // The 'system.indexes' collection cannot be created on the upgrade node using
- // 'cloneCollection'.
- assert.commandFailedWithCode(
- upgradeDB.cloneCollection(downgradeDB.getMongo().host, "system.indexes"),
- ErrorCodes.InvalidNamespace);
-
- // The 'clone' command does not copy the 'system.indexes' collection.
- assert.commandWorked(upgradeDB.cloneDatabase(downgradeDB.getMongo().host));
- assert.eq(0,
- upgradeDB.getCollectionInfos({name: "system.indexes"}).length,
- tojson(upgradeDB.getCollectionInfos()));
-
- // The 'copydb' command does not copy the 'system.indexes' collection.
- if (jsTest.options().auth) {
- downgradeDB.createUser({
- user: jsTest.options().authUser,
- pwd: jsTest.options().authPassword,
- roles: ["dbOwner"]
- });
- assert.commandWorked(upgradeDB.copyDatabase(dbName,
- "other",
- downgradeDB.getMongo().host,
- jsTest.options().authUser,
- jsTest.options().authPassword));
- } else {
- assert.commandWorked(upgradeDB.copyDatabase(dbName, "other", downgradeDB.getMongo().host));
- }
- assert.eq(0,
- upgradeConn.getDB("other").getCollectionInfos({name: "system.indexes"}).length,
- tojson(upgradeDB.getCollectionInfos()));
-
- MongoRunner.stopMongod(upgradeConn);
- MongoRunner.stopMongod(downgradeConn);
-}()); \ No newline at end of file
diff --git a/jstests/multiVersion/change_streams_feature_compatibility_version.js b/jstests/multiVersion/change_streams_feature_compatibility_version.js
deleted file mode 100644
index a4b77fb350b..00000000000
--- a/jstests/multiVersion/change_streams_feature_compatibility_version.js
+++ /dev/null
@@ -1,234 +0,0 @@
-// Test that change streams involving 4.0 features are not allowed to be opened when the FCV is
-// older than 4.0.
-(function() {
- "use strict";
-
- load("jstests/libs/change_stream_util.js"); // For ChangeStreamTest.
- load("jstests/multiVersion/libs/multi_rs.js"); // For upgradeSet.
- load("jstests/replsets/rslib.js"); // For startSetIfSupportsReadMajority.
-
- const rst = new ReplSetTest({
- nodes: 2,
- nodeOptions: {binVersion: "last-stable"},
- });
-
- if (!startSetIfSupportsReadMajority(rst)) {
- jsTestLog("Skipping test since storage engine doesn't support majority read concern.");
- rst.stopSet();
- return;
- }
-
- rst.initiate();
-
- function assertResumeTokenUsesStringFormat(resumeToken) {
- assert.neq(resumeToken._data, undefined);
- assert.eq(typeof resumeToken._data, "string", tojson(resumeToken));
- }
-
- function assertResumeTokenUsesBinDataFormat(resumeToken) {
- assert.neq(resumeToken._data, undefined);
- assert(resumeToken._data instanceof BinData, tojson(resumeToken));
- }
-
- let testDB = rst.getPrimary().getDB(jsTestName());
- let adminDB = rst.getPrimary().getDB("admin");
- let coll = testDB[jsTestName()];
-
- let cst = new ChangeStreamTest(testDB);
- let adminCST = new ChangeStreamTest(adminDB);
-
- // We can't open a change stream on a non-existent database on last-stable, so we insert a dummy
- // document to create the database.
- // TODO BACKPORT-34138 Remove this check once the change has been backported.
- assert.writeOK(testDB.dummy.insert({_id: "dummy"}));
-
- // Open a change stream against a 3.6 binary. We will use the resume token from this stream to
- // resume the stream once the set has been upgraded.
- let streamOnOldVersion =
- cst.startWatchingChanges({pipeline: [{$changeStream: {}}], collection: coll.getName()});
- assert.writeOK(coll.insert({_id: 0}));
-
- let change = cst.getOneChange(streamOnOldVersion);
- assert.eq(change.operationType, "insert", tojson(change));
- assert.eq(change.documentKey._id, 0);
-
- // Extract the resume token and test that it is using the old resume token format using
- // BinData.
- const resumeTokenFromLastStable = change._id;
- assertResumeTokenUsesBinDataFormat(resumeTokenFromLastStable);
-
- // Test that new query features are banned on 3.6.
- const failedResponse = assert.commandFailedWithCode(
- testDB.runCommand({aggregate: 1, pipeline: [{$changeStream: {}}], cursor: {}}),
- ErrorCodes.InvalidNamespace);
- assert.commandFailedWithCode(
- adminDB.runCommand(
- {aggregate: 1, pipeline: [{$changeStream: {allChangesForCluster: true}}], cursor: {}}),
- 40415);
-
- assert.commandFailedWithCode(testDB.runCommand({
- aggregate: coll.getName(),
- pipeline: [{$changeStream: {startAtOperationTime: failedResponse.operationTime}}],
- cursor: {}
- }),
- 40415);
-
- // Upgrade the set to the new binary version, but keep the feature compatibility version at
- // 3.6.
- rst.upgradeSet({binVersion: "latest"});
- testDB = rst.getPrimary().getDB(jsTestName());
- adminDB = rst.getPrimary().getDB("admin");
- coll = testDB[jsTestName()];
- cst = new ChangeStreamTest(testDB);
- adminCST = new ChangeStreamTest(adminDB);
-
- // Test that we can resume the stream on the new binaries.
- streamOnOldVersion = cst.startWatchingChanges({
- pipeline: [{$changeStream: {resumeAfter: resumeTokenFromLastStable}}],
- collection: coll.getName()
- });
-
- assert.writeOK(coll.insert({_id: 1}));
-
- change = cst.getOneChange(streamOnOldVersion);
- assert.eq(change.operationType, "insert", tojson(change));
- assert.eq(change.documentKey._id, 1);
-
- // Test that the stream is still using the old resume token format using BinData.
- assertResumeTokenUsesBinDataFormat(change._id);
-
- // Explicitly set feature compatibility version 4.0. Remember the cluster time from that
- // response to use later.
- const startTime =
- assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: "4.0"}))
- .operationTime;
-
- // Test that we can now use 4.0 features to open a stream.
- const wholeDbCursor =
- cst.startWatchingChanges({pipeline: [{$changeStream: {}}], collection: 1});
- const wholeClusterCursor = adminCST.startWatchingChanges(
- {pipeline: [{$changeStream: {allChangesForCluster: true}}], collection: 1});
- const cursorStartedWithTime = cst.startWatchingChanges({
- pipeline: [{$changeStream: {startAtOperationTime: startTime}}],
- collection: coll.getName()
- });
-
- assert.writeOK(coll.insert({_id: 2}));
-
- // Test that the stream opened in FCV 3.6 continues to work and still generates tokens in the
- // old format.
- change = cst.getOneChange(streamOnOldVersion);
- assert.eq(change.operationType, "insert", tojson(change));
- assert.eq(change.documentKey._id, 2);
- assertResumeTokenUsesBinDataFormat(change._id);
-
- // Test all the newly created streams can see an insert.
- change = cst.getOneChange(wholeDbCursor);
- assert.eq(change.operationType, "insert", tojson(change));
- assert.eq(change.documentKey._id, 2);
-
- change = adminCST.getOneChange(wholeClusterCursor);
- assert.eq(change.operationType, "insert", tojson(change));
- assert.eq(change.documentKey._id, 2);
-
- change = cst.getOneChange(cursorStartedWithTime);
- assert.eq(change.operationType, "insert", tojson(change));
- assert.eq(change.documentKey._id, 2);
-
- // Test that the resume token is using the new format and has type string while FCV is 4.0.
- const resumeToken = change._id;
- assertResumeTokenUsesStringFormat(resumeToken);
-
- // Test that we can resume with the resume token with either format, either against the entire
- // DB, the entire cluster, or against the single collection.
- assert.doesNotThrow(() => cst.startWatchingChanges({
- pipeline: [{$changeStream: {resumeAfter: resumeTokenFromLastStable}}],
- collection: 1
- }));
- assert.doesNotThrow(() => adminCST.startWatchingChanges({
- pipeline:
- [{$changeStream: {allChangesForCluster: true, resumeAfter: resumeTokenFromLastStable}}],
- collection: 1
- }));
- assert.doesNotThrow(() => cst.startWatchingChanges({
- pipeline: [{$changeStream: {resumeAfter: resumeTokenFromLastStable}}],
- collection: coll.getName()
- }));
- assert.doesNotThrow(
- () => cst.startWatchingChanges(
- {pipeline: [{$changeStream: {resumeAfter: resumeToken}}], collection: 1}));
- assert.doesNotThrow(() => adminCST.startWatchingChanges({
- pipeline: [{$changeStream: {allChangesForCluster: true, resumeAfter: resumeToken}}],
- collection: 1
- }));
- assert.doesNotThrow(
- () => cst.startWatchingChanges(
- {pipeline: [{$changeStream: {resumeAfter: resumeToken}}], collection: coll.getName()}));
-
- // Set the feature compatibility version to 3.6.
- assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: "3.6"}));
-
- // Test that existing streams continue, but still generate resume tokens in the new format.
- assert.writeOK(coll.insert({_id: 3}));
- change = cst.getOneChange(wholeDbCursor);
- assert.eq(change.operationType, "insert", tojson(change));
- assert.eq(change.documentKey._id, 3);
- assertResumeTokenUsesStringFormat(change._id);
-
- change = adminCST.getOneChange(wholeClusterCursor);
- assert.eq(change.operationType, "insert", tojson(change));
- assert.eq(change.documentKey._id, 3);
- assertResumeTokenUsesStringFormat(change._id);
-
- change = cst.getOneChange(cursorStartedWithTime);
- assert.eq(change.operationType, "insert", tojson(change));
- assert.eq(change.documentKey._id, 3);
- assertResumeTokenUsesStringFormat(change._id);
-
- // Creating a new change stream with a 4.0 feature should fail.
- assert.commandFailedWithCode(
- testDB.runCommand({aggregate: 1, pipeline: [{$changeStream: {}}], cursor: {}}),
- ErrorCodes.QueryFeatureNotAllowed);
- assert.commandFailedWithCode(
- adminDB.runCommand(
- {aggregate: 1, pipeline: [{$changeStream: {allChangesForCluster: true}}], cursor: {}}),
- ErrorCodes.QueryFeatureNotAllowed);
-
- assert.commandFailedWithCode(testDB.runCommand({
- aggregate: coll.getName(),
- pipeline: [{$changeStream: {startAtOperationTime: startTime}}],
- cursor: {}
- }),
- ErrorCodes.QueryFeatureNotAllowed);
-
- // Test that resuming a change stream opened on FCV 4.0 should continue to work, though a
- // whole-db or whole-cluster cursor cannot be resumed.
- assert.commandFailedWithCode(
- testDB.runCommand(
- {aggregate: 1, pipeline: [{$changeStream: {resumeAfter: resumeToken}}], cursor: {}}),
- ErrorCodes.QueryFeatureNotAllowed);
- assert.commandFailedWithCode(adminDB.runCommand({
- aggregate: 1,
- pipeline: [{$changeStream: {allChangesForCluster: true, resumeAfter: resumeToken}}],
- cursor: {}
- }),
- ErrorCodes.QueryFeatureNotAllowed);
- let resumedOnFCV36With40BinaryResumeToken;
- assert.doesNotThrow(() => {
- resumedOnFCV36With40BinaryResumeToken = coll.watch([], {resumeAfter: resumeToken});
- });
- assert.soon(() => resumedOnFCV36With40BinaryResumeToken.hasNext());
- change = resumedOnFCV36With40BinaryResumeToken.next();
- assertResumeTokenUsesBinDataFormat(change._id);
-
- // Test that resuming a change stream with the original resume token still works.
- let resumedWith36Token;
- assert.doesNotThrow(() => {
- resumedWith36Token = coll.watch([], {resumeAfter: resumeTokenFromLastStable});
- });
- assert.soon(() => resumedWith36Token.hasNext());
- change = resumedWith36Token.next();
- assertResumeTokenUsesBinDataFormat(change._id);
-
- rst.stopSet();
-}());
diff --git a/jstests/multiVersion/collection_validator_feature_compatibility_version.js b/jstests/multiVersion/collection_validator_feature_compatibility_version.js
deleted file mode 100644
index 5f652417ac8..00000000000
--- a/jstests/multiVersion/collection_validator_feature_compatibility_version.js
+++ /dev/null
@@ -1,304 +0,0 @@
-/**
- * Test that mongod will not allow creation of collection validators using 4.0 query features when
- * the feature compatibility version is older than 4.0.
- *
- * TODO SERVER-33321: Remove FCV 3.6 validation during the 4.1 development cycle.
- *
- * We restart mongod during the test and expect it to have the same data after restarting.
- * @tags: [requires_persistence]
- */
-
-(function() {
- "use strict";
-
- const testName = "collection_validator_feature_compatibility_version";
- const dbpath = MongoRunner.dataPath + testName;
-
- // In order to avoid restarting the server for each test case, we declare all the test cases up
- // front, and test them all at once.
- const testCases = [
- {
- validator: {$expr: {$eq: [{$trim: {input: "$a"}}, "good"]}},
- nonMatchingDocument: {a: "bad"}
- },
- {
- validator: {$expr: {$eq: [{$ltrim: {input: "$a"}}, "good"]}},
- nonMatchingDocument: {a: "bad"}
- },
- {
- validator: {$expr: {$eq: [{$rtrim: {input: "$a"}}, "good"]}},
- nonMatchingDocument: {a: "bad"}
- },
- {
- validator: {
- $expr: {
- $eq: [
- // The 'format' option was added in 4.0.
- {$dateFromString: {dateString: "2018-02-08", format: "$format"}},
- new Date("2018-02-08")
- ]
- }
- },
- // Swap the month and day so it doesn't match.
- nonMatchingDocument: {format: "%Y-%d-%m"}
- },
- {
- validator: {
- $expr: {
- $eq: [
- // The 'onNull' option was added in 4.0.
- {
- $dateFromString:
- {dateString: "$dateString", onNull: new Date("1970-01-01")}
- },
- new Date("2018-02-08")
- ]
- }
- },
- nonMatchingDocument: {dateString: null}
- },
- {
- validator: {
- $expr: {
- $eq: [
- // The 'onError' option was added in 4.0.
- {
- $dateFromString:
- {dateString: "$dateString", onError: new Date("1970-01-01")}
- },
- new Date("2018-02-08")
- ]
- }
- },
- nonMatchingDocument: {dateString: "Not a date"}
- },
- {
- validator: {
- $expr: {
- $eq: [
- // The 'onNull' option was added in 4.0.
- {$dateToString: {date: "$date", format: "%Y-%m-%d", onNull: "null input"}},
- "2018-02-08"
- ]
- }
- },
- nonMatchingDocument: {date: null}
- },
- {
- validator: {
- $expr: {
- $eq: [
- // The 'format' option was made optional in 4.0.
- {$dateToString: {date: "$date"}},
- "2018-02-08T00:00:00.000Z"
- ]
- }
- },
- nonMatchingDocument: {date: new Date("2018-02-07")}
- },
- {
- validator: {$expr: {$eq: [{$convert: {input: "$a", to: "int"}}, 2018]}},
- nonMatchingDocument: {a: "2017"}
- },
- {
- validator: {$expr: {$eq: [{$convert: {input: "$a", to: "int", onNull: 0}}, 2018]}},
- nonMatchingDocument: {a: null}
- },
- {
- validator: {$expr: {$eq: [{$convert: {input: "$a", to: "int", onError: 0}}, 2018]}},
- nonMatchingDocument: {a: "hello"}
- },
- {validator: {$expr: {$eq: [{$toInt: "$a"}, 2018]}}, nonMatchingDocument: {a: "0"}},
- {validator: {$expr: {$eq: [{$toLong: "$a"}, 2018]}}, nonMatchingDocument: {a: 0}},
- {validator: {$expr: {$eq: [{$toDouble: "$a"}, 2018]}}, nonMatchingDocument: {a: 0}},
- {validator: {$expr: {$eq: [{$toDecimal: "$a"}, 2018]}}, nonMatchingDocument: {a: 0}},
- {
- validator: {$expr: {$eq: [{$toDate: "$a"}, new ISODate("2018-02-27")]}},
- nonMatchingDocument: {a: 0}
- },
- {
- validator:
- {$expr: {$eq: [{$toObjectId: "$a"}, new ObjectId("aaaaaaaaaaaaaaaaaaaaaaaa")]}},
- nonMatchingDocument: {a: "bbbbbbbbbbbbbbbbbbbbbbbb"}
- },
- {validator: {$expr: {$eq: [{$toBool: "$a"}, false]}}, nonMatchingDocument: {a: 1}},
- {validator: {$expr: {$eq: [{$toString: "$a"}, "false"]}}, nonMatchingDocument: {a: 1}},
- ];
-
- let conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: "latest"});
- assert.neq(null, conn, "mongod was unable to start up");
-
- let testDB = conn.getDB(testName);
-
- let adminDB = conn.getDB("admin");
-
- // Explicitly set feature compatibility version 4.0.
- assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: "4.0"}));
-
- testCases.forEach(function(test, i) {
- // Create a collection with a validator using 4.0 query features.
- const coll = testDB["coll" + i];
- assert.commandWorked(
- testDB.createCollection(coll.getName(), {validator: test.validator}),
- `Expected to be able to create collection with validator ${tojson(test.validator)}`);
-
- // The validator should cause this insert to fail.
- assert.writeErrorWithCode(
- coll.insert(test.nonMatchingDocument),
- ErrorCodes.DocumentValidationFailure,
- `Expected document ${tojson(test.nonMatchingDocument)} to fail validation for ` +
- `collection with validator ${tojson(test.validator)}`);
-
- // Set a validator using 4.0 query features on an existing collection.
- coll.drop();
- assert.commandWorked(testDB.createCollection(coll.getName()));
- assert.commandWorked(
- testDB.runCommand({collMod: coll.getName(), validator: test.validator}),
- `Expected to be able to modify collection validator to be ${tojson(test.validator)}`);
-
- // Another failing update.
- assert.writeErrorWithCode(
- coll.insert(test.nonMatchingDocument),
- ErrorCodes.DocumentValidationFailure,
- `Expected document ${tojson(test.nonMatchingDocument)} to fail validation for ` +
- `collection with validator ${tojson(test.validator)}`);
- });
-
- // Set the feature compatibility version to 3.6.
- assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: "3.6"}));
-
- testCases.forEach(function(test, i) {
- // The validator is already in place, so it should still cause this insert to fail.
- const coll = testDB["coll" + i];
- assert.writeErrorWithCode(
- coll.insert(test.nonMatchingDocument),
- ErrorCodes.DocumentValidationFailure,
- `Expected document ${tojson(test.nonMatchingDocument)} to fail validation for ` +
- `collection with validator ${tojson(test.validator)}`);
-
- // Trying to create a new collection with a validator using 4.0 query features should fail
- // while feature compatibility version is 3.6.
- let res = testDB.createCollection("other", {validator: test.validator});
- assert.commandFailedWithCode(
- res,
- ErrorCodes.QueryFeatureNotAllowed,
- `Expected *not* to be able to create collection with validator ${tojson(test.validator)}`);
- assert(
- res.errmsg.match(/feature compatibility version/),
- `Expected error message from createCollection with validator ` +
- `${tojson(test.validator)} to reference 'feature compatibility version' but got: ` +
- res.errmsg);
-
- // Trying to update a collection with a validator using 4.0 query features should also fail.
- res = testDB.runCommand({collMod: coll.getName(), validator: test.validator});
- assert.commandFailedWithCode(
- res,
- ErrorCodes.QueryFeatureNotAllowed,
- `Expected to be able to create collection with validator ${tojson(test.validator)}`);
- assert(
- res.errmsg.match(/feature compatibility version/),
- `Expected error message from createCollection with validator ` +
- `${tojson(test.validator)} to reference 'feature compatibility version' but got: ` +
- res.errmsg);
- });
-
- MongoRunner.stopMongod(conn);
-
- // If we try to start up a 3.6 mongod, it will fail, because it will not be able to parse
- // the validator using 4.0 query features.
- conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: "3.6", noCleanData: true});
- assert.eq(
- null, conn, "mongod 3.6 started, even with a validator using 4.0 query features in place.");
-
- // Starting up a 4.0 mongod, however, should succeed, even though the feature compatibility
- // version is still set to 3.6.
- conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: "latest", noCleanData: true});
- assert.neq(null, conn, "mongod was unable to start up");
-
- adminDB = conn.getDB("admin");
- testDB = conn.getDB(testName);
-
- // And the validator should still work.
- testCases.forEach(function(test, i) {
- const coll = testDB["coll" + i];
- assert.writeErrorWithCode(
- coll.insert(test.nonMatchingDocument),
- ErrorCodes.DocumentValidationFailure,
- `Expected document ${tojson(test.nonMatchingDocument)} to fail validation for ` +
- `collection with validator ${tojson(test.validator)}`);
-
- // Remove the validator.
- assert.commandWorked(testDB.runCommand({collMod: coll.getName(), validator: {}}));
- });
-
- MongoRunner.stopMongod(conn);
-
- // Now, we should be able to start up a 3.6 mongod.
- conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: "3.6", noCleanData: true});
- assert.neq(
- null,
- conn,
- "mongod 3.6 failed to start, even after we removed the validator using 4.0 query features");
-
- MongoRunner.stopMongod(conn);
-
- // The rest of the test uses mongod 4.0.
- conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: "latest", noCleanData: true});
- assert.neq(null, conn, "mongod was unable to start up");
-
- adminDB = conn.getDB("admin");
- testDB = conn.getDB(testName);
-
- // Set the feature compatibility version back to 4.0.
- assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: "4.0"}));
-
- testCases.forEach(function(test, i) {
- const coll = testDB["coll2" + i];
-
- // Now we should be able to create a collection with a validator using 4.0 query features
- // again.
- assert.commandWorked(
- testDB.createCollection(coll.getName(), {validator: test.validator}),
- `Expected to be able to create collection with validator ${tojson(test.validator)}`);
-
- // And we should be able to modify a collection to have a validator using 4.0 query
- // features.
- assert.commandWorked(
- testDB.runCommand({collMod: coll.getName(), validator: test.validator}),
- `Expected to be able to modify collection validator to be ${tojson(test.validator)}`);
- });
-
- // Set the feature compatibility version to 3.6 and then restart with
- // internalValidateFeaturesAsMaster=false.
- assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: "3.6"}));
- MongoRunner.stopMongod(conn);
- conn = MongoRunner.runMongod({
- dbpath: dbpath,
- binVersion: "latest",
- noCleanData: true,
- setParameter: "internalValidateFeaturesAsMaster=false"
- });
- assert.neq(null, conn, "mongod was unable to start up");
-
- testDB = conn.getDB(testName);
-
- testCases.forEach(function(test, i) {
- const coll = testDB["coll3" + i];
- // Even though the feature compatibility version is 3.6, we should still be able to add a
- // validator using 4.0 query features, because internalValidateFeaturesAsMaster is false.
- assert.commandWorked(
- testDB.createCollection(coll.getName(), {validator: test.validator}),
- `Expected to be able to create collection with validator ${tojson(test.validator)}`);
-
- // We should also be able to modify a collection to have a validator using 4.0 query
- // features.
- coll.drop();
- assert.commandWorked(testDB.createCollection(coll.getName()));
- assert.commandWorked(
- testDB.runCommand({collMod: coll.getName(), validator: test.validator}),
- `Expected to be able to modify collection validator to be ${tojson(test.validator)}`);
- });
-
- MongoRunner.stopMongod(conn);
-
-}());
diff --git a/jstests/multiVersion/downgrade_to_36_only_with_recovered_data.js b/jstests/multiVersion/downgrade_to_36_only_with_recovered_data.js
deleted file mode 100644
index 2803273524e..00000000000
--- a/jstests/multiVersion/downgrade_to_36_only_with_recovered_data.js
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
- * Test that a node that is shutdown without running replication recovery does not downgrade to
- * 3.6 compatible data files, even when FCV is 3.6.
- *
- * @tags: [requires_wiredtiger, requires_persistence, requires_replication]
- */
-
-// Steps:
-// 1) Setup a one node replica set with `--shardsvr`. Shards are born in FCV 3.6
-// 2) Initiate the replica set.
-// 3) Wait for the first stable checkpoint.
-// 4) Set FCV to 4.0
-// 5) Insert a document.
-// 6) Hard crash the server. The checkpoint does not contain (4) nor (5), but
-// the oplog does.
-// 7) Start the node as a standalone. Confirm the write at (5) is missing.
-// 8) Shutdown the node. Run `--repair`. This will not play oplog recovery.
-// When this process shuts down, it must not downgrade the files.
-// 9) Restart the node as a replica set/shard. Assert oplog recovery went well
-// by observing the write at (5).
-(function() {
- "use strict";
-
- const name = "rs";
- let conn = MongoRunner.runMongod(
- {binVersion: "latest", shardsvr: "", replSet: name, syncdelay: "600"});
-
- assert.neq(conn, null, "mongod was unable to start up");
-
- let options = conn.fullOptions;
-
- assert.commandWorked(conn.adminCommand({replSetInitiate: 1}));
- assert.soon(function() {
- let status = assert.commandWorked(conn.adminCommand("replSetGetStatus"));
- return status["lastStableCheckpointTimestamp"].t > 0;
- });
-
- assert.commandWorked(conn.adminCommand({setFeatureCompatibilityVersion: "4.0"}));
- assert.commandWorked(
- conn.getDB("foo")["bar"].insert({_id: 0}, {writeConcern: {w: 1, j: true}}));
-
- jsTestLog("Oplog entries:");
- let cursor = conn.getDB("local").oplog.rs.find();
- while (cursor.hasNext()) {
- printjson(cursor.next());
- }
-
- MongoRunner.stopMongod(conn, 9, {allowedExitCode: MongoRunner.EXIT_SIGKILL});
-
- jsTestLog("Running as standalone.");
- options.shardsvr = undefined;
- options.replSet = undefined;
- options.restart = true;
- conn = MongoRunner.runMongod(options);
-
- assert.eq(0, conn.getDB("foo")["bar"].find({_id: 0}).itcount());
- MongoRunner.stopMongod(conn);
-
- jsTestLog("Restarting after standalone with replication.");
- options.shardsvr = "";
- options.replSet = name;
-
- conn = MongoRunner.runMongod(options);
- assert.neq(conn, null, "mongod was unable to start up");
-
- assert.soon(function() {
- return conn.adminCommand("ismaster")["ismaster"];
- });
- assert.eq(1, conn.getDB("foo")["bar"].find({_id: 0}).itcount());
- MongoRunner.stopMongod(conn);
-
- jsTestLog("Running repair. The process will automatically exit when complete.");
- options.shardsvr = undefined;
- options.replSet = undefined;
- options.repair = '';
- MongoRunner.runMongod(options);
-
- jsTestLog("Restarting after repair with replication.");
- options.shardsvr = '';
- options.replSet = name;
- options.repair = undefined;
-
- conn = MongoRunner.runMongod(options);
- assert.neq(conn, null, "mongod was unable to start up");
-
- assert.soon(function() {
- return conn.adminCommand("ismaster")["ismaster"];
- });
- assert.eq(1, conn.getDB("foo")["bar"].find({_id: 0}).itcount());
- MongoRunner.stopMongod(conn);
-})();
diff --git a/jstests/multiVersion/drop_mmap_system_collections_on_wt.js b/jstests/multiVersion/drop_mmap_system_collections_on_wt.js
deleted file mode 100644
index c59b7cdacd0..00000000000
--- a/jstests/multiVersion/drop_mmap_system_collections_on_wt.js
+++ /dev/null
@@ -1,78 +0,0 @@
-// Ensure system.indexes created on wiredTiger 3.4 does not cause mongodb 4.0 to fail to start up
-// (see SERVER-34482). This test is to be removed after mongodb 4.0.
-(function() {
- "use strict";
-
- load("jstests/libs/feature_compatibility_version.js");
- load("jstests/libs/check_uuids.js");
- load("jstests/multiVersion/libs/multi_rs.js");
-
- const UUIDCheckBinary = "latest";
- const UUIDBinary = "3.6";
- const noUUIDBinary = "3.4";
- const systemIndexesDB = "systemIndexesDB";
- const UUIDFCV = "3.6";
-
- // This test is irrelevant for MMAP.
- if (jsTest.options().storageEngine == "mmapv1") {
- return;
- }
-
- // Create system.indexes on wiredTiger, using a version of mongod that does not assign UUIDs.
- let rst = new ReplSetTest({
- nodes: 3,
- nodeOptions: {binVersion: noUUIDBinary},
- });
- rst.startSet();
- rst.initiate();
- let primaryTestDB = rst.getPrimary().getDB(systemIndexesDB);
- primaryTestDB.dropDatabase();
- const systemIndexesColl = "system.indexes";
- const createCmd = {create: systemIndexesColl, writeConcern: {w: "majority"}};
- assert.commandWorked(primaryTestDB.runCommand(createCmd),
- "expected " + tojson(createCmd) + " to succeed");
- rst.awaitReplication();
- assert(primaryTestDB.getCollectionInfos().length == 1);
- assert(primaryTestDB.getCollectionInfos()[0].name == systemIndexesColl);
- let secondaries = rst.getSecondaries();
- for (let j = 0; j < secondaries.length; j++) {
- let secondaryTestDB = secondaries[j].getDB(systemIndexesDB);
- assert(secondaryTestDB.getCollectionInfos().length == 1);
- assert(secondaryTestDB.getCollectionInfos()[0].name == systemIndexesColl);
- }
-
- // Restart with mongodb 3.6 and set the FCV to 3.6, which will assign UUIDs to all
- // collections except for system.indexes and system.namespaces.
- rst.upgradeSet({binVersion: UUIDBinary});
-
- let primaryAdminDB = rst.getPrimary().getDB("admin");
- assert.commandWorked(primaryAdminDB.runCommand({setFeatureCompatibilityVersion: UUIDFCV}));
- rst.awaitReplication();
- checkFCV(primaryAdminDB, UUIDFCV);
- secondaries = rst.getSecondaries();
- for (let j = 0; j < secondaries.length; j++) {
- let secondaryAdminDB = secondaries[j].getDB("admin");
- checkFCV(secondaryAdminDB, UUIDFCV);
- }
-
- primaryTestDB = rst.getPrimary().getDB(systemIndexesDB);
- assert(!primaryTestDB.getCollectionInfos()[0].info.uuid);
-
- // Restart with mongodb 4.0. This will drop system.indexes and system.namespaces if they
- // exist, allowing the UUID check on start up to pass.
- rst.upgradeSet({binVersion: UUIDCheckBinary});
-
- primaryTestDB = rst.getPrimary().getDB(systemIndexesDB);
- assert(primaryTestDB.getCollectionInfos().length == 0);
-
- primaryAdminDB = rst.getPrimary().getDB("admin");
- secondaries = rst.getSecondaries();
- checkCollectionUUIDs(primaryAdminDB);
- for (let j = 0; j < secondaries.length; j++) {
- let secondaryTestDB = secondaries[j].getDB(systemIndexesDB);
- assert(secondaryTestDB.getCollectionInfos().length == 0);
- let secondaryAdminDB = secondaries[j].getDB("admin");
- checkCollectionUUIDs(secondaryAdminDB);
- }
- rst.stopSet();
-})();
diff --git a/jstests/multiVersion/ensure_last_applied_on_upgrade_to_40.js b/jstests/multiVersion/ensure_last_applied_on_upgrade_to_40.js
deleted file mode 100644
index 29aca9695e8..00000000000
--- a/jstests/multiVersion/ensure_last_applied_on_upgrade_to_40.js
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- * This tests that nodes upgrading from 3.6 to 4.0 can recover without data loss if the 4.0 binary
- * crashes before taking a stable checkpoint.
- *
- * @tags: [requires_replication, requires_persistence]
- */
-(function() {
- "use strict";
-
- load('./jstests/multiVersion/libs/multi_rs.js');
-
- var oldVersion = "3.6";
- var nodes = {n0: {binVersion: oldVersion}, n1: {binVersion: oldVersion}};
- var rst = new ReplSetTest({nodes: nodes});
-
- rst.startSet();
- rst.initiate();
-
- if (!rst.getPrimary().adminCommand("serverStatus").storageEngine.supportsSnapshotReadConcern) {
- // Only snapshotting storage engines require correct timestamping of index builds.
- rst.stopSet();
- return;
- }
-
- function getColl(conn) {
- return conn.getDB("test").getCollection("foo");
- }
-
- // Insert 100 documents before the upgrade.
- let coll = getColl(rst.getPrimary());
- for (let docNum = 0; docNum < 100; ++docNum) {
- assert.commandWorked(coll.insert({x: docNum}, {writeConcern: {j: true}}));
- }
- rst.awaitReplication(undefined, ReplSetTest.OpTimeType.LAST_DURABLE);
-
- jsTest.log("Upgrading replica set...");
-
- rst.upgradeSet({
- binVersion: "latest", // Only relevant for 3.6 <-> 4.0, but 4.0 does not exist yet.
- setParameter: {logComponentVerbosity: tojsononeline({storage: {recovery: 2}})}
- });
-
- jsTest.log("Replica set upgraded.");
-
- // Turn off snapshotting to prevent a stable timestamp from being communicated. Thus
- // preventing any stable checkpoints.
- rst.nodes.forEach(node => assert.commandWorked(node.adminCommand(
- {configureFailPoint: "disableSnapshotting", mode: "alwaysOn"})));
-
- // Insert 100 more documents. These should be persisted only in the oplog and not as part of
- // the datafiles in the checkpoint.
- coll = getColl(rst.getPrimary());
- for (let docNum = 100; docNum < 200; ++docNum) {
- assert.commandWorked(coll.insert({x: docNum}, {writeConcern: {j: true}}));
- }
-
- // Crash the nodes and validate on restart that they both have 200 documents.
- rst.stopSet(9, true, {allowedExitCode: MongoRunner.EXIT_SIGKILL});
- rst.startSet(undefined, true);
- rst.awaitReplication();
- for (let node of rst.nodes) {
- node.setSlaveOk();
- coll = getColl(node);
- assert.eq(200, coll.find().itcount());
- }
-
- // Upgrade to FCV 4.0 so we persist stable timestamps across clean shutdown.
- assert.commandWorked(rst.getPrimary().adminCommand({setFeatureCompatibilityVersion: "4.0"}));
-
- // Restart the replica set to load off of a stable checkpoint.
- rst.stopSet(undefined, true);
- rst.startSet(undefined, true);
-
- // Assert all nodes report a `lastStableCheckpointTimestamp`.
- function getStableCheckpointTimestamp(node) {
- let res = assert.commandWorked(node.adminCommand("replSetGetStatus"));
- if (!res.hasOwnProperty("lastStableCheckpointTimestamp")) {
- return Timestamp(0, 0);
- }
-
- return res.lastStableCheckpointTimestamp;
- }
- rst.nodes.forEach(node => assert.gt(getStableCheckpointTimestamp(node), Timestamp(0, 0)));
- rst.stopSet();
-})();
diff --git a/jstests/multiVersion/fcv_chunk_history.js b/jstests/multiVersion/fcv_chunk_history.js
deleted file mode 100644
index 90beb36a2c4..00000000000
--- a/jstests/multiVersion/fcv_chunk_history.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * Tests that chunk histories are properly generated and stored when upgrading from FCV 3.6 to FCV
- * 4.0 in a sharded cluster.
- */
-
-(function() {
- "use strict";
-
- load("jstests/libs/feature_compatibility_version.js");
-
- var st = new ShardingTest({
- shards: 1,
- });
-
- let configPrimaryAdminDB = st.configRS.getPrimary().getDB("admin");
- let shardPrimaryAdminDB = st.rs0.getPrimary().getDB("admin");
-
- // Change FCV to last stable so chunks will not have histories.
- assert.commandWorked(st.s.adminCommand({setFeatureCompatibilityVersion: "3.6"}));
- checkFCV(configPrimaryAdminDB, "3.6");
- checkFCV(shardPrimaryAdminDB, "3.6");
-
- let testDB = st.s.getDB("test1");
-
- // Create a sharded collection with primary shard 0.
- assert.commandWorked(st.s.adminCommand({enableSharding: testDB.getName()}));
- st.ensurePrimaryShard(testDB.getName(), st.shard0.shardName);
- assert.commandWorked(
- st.s.adminCommand({shardCollection: testDB.foo.getFullName(), key: {a: 1}}));
- assert.commandWorked(st.s.adminCommand({split: testDB.foo.getFullName(), middle: {a: 0}}));
-
- assert.writeOK(st.s.getDB("test1").foo.insert({_id: "id1", a: 1}));
- assert.neq(null, st.s.getDB("test1").foo.findOne({_id: "id1", a: 1}));
-
- assert.writeOK(st.s.getDB("test1").foo.insert({_id: "id2", a: -1}));
- assert.neq(null, st.s.getDB("test1").foo.findOne({_id: "id2", a: -1}));
-
- // Make sure chunks do not have history when FCV <= 3.6.
- let chunks = st.s.getDB("config").getCollection("chunks").find({ns: "test1.foo"}).toArray();
- assert.eq(chunks.length, 2);
- chunks.forEach((chunk) => {
- assert.neq(null, chunk);
- assert(!chunk.hasOwnProperty("history"), "test1.foo has a history before upgrade");
- });
-
- // Set FCV to latest.
- assert.commandWorked(st.s.adminCommand({setFeatureCompatibilityVersion: "4.0"}));
- checkFCV(configPrimaryAdminDB, latestFCV);
- checkFCV(shardPrimaryAdminDB, latestFCV);
-
- // Make sure chunks for test1.foo were given history after upgrade.
- chunks = st.s.getDB("config").getCollection("chunks").find({ns: "test1.foo"}).toArray();
- assert.eq(chunks.length, 2);
- chunks.forEach((chunk) => {
- assert.neq(null, chunk);
- assert(chunk.hasOwnProperty("history"), "test1.foo does not have a history after upgrade");
- });
-
- // Set FCV to last-stable.
- assert.commandWorked(st.s.adminCommand({setFeatureCompatibilityVersion: "3.6"}));
- checkFCV(configPrimaryAdminDB, "3.6");
- checkFCV(shardPrimaryAdminDB, "3.6");
-
- // Make sure history was removed when FCV changed to <= 3.6.
- chunks = st.s.getDB("config").getCollection("chunks").find({ns: "test1.foo"}).toArray();
- assert.eq(chunks.length, 2);
- chunks.forEach((chunk) => {
- assert.neq(null, chunk);
- assert(!chunk.hasOwnProperty("history"), "test1.foo has a history after downgrade");
- });
-
- st.stop();
-
-})(); \ No newline at end of file
diff --git a/jstests/multiVersion/fcv_db_versioning.js b/jstests/multiVersion/fcv_db_versioning.js
deleted file mode 100644
index 778eac2a28d..00000000000
--- a/jstests/multiVersion/fcv_db_versioning.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * Tests that database versions are properly generated and stored when upgrading from FCV 3.6 to FCV
- * 4.0 in a sharded cluster.
- */
-
-(function() {
- "use strict";
-
- load("jstests/libs/feature_compatibility_version.js");
-
- var st = new ShardingTest({
- shards: 1,
- });
-
- let configPrimaryAdminDB = st.configRS.getPrimary().getDB("admin");
- let shardPrimaryAdminDB = st.rs0.getPrimary().getDB("admin");
-
- // Change FCV to last stable so databases will not have version
- assert.commandWorked(st.s.adminCommand({setFeatureCompatibilityVersion: lastStableFCV}));
- checkFCV(configPrimaryAdminDB, lastStableFCV);
- checkFCV(shardPrimaryAdminDB, lastStableFCV);
-
- assert.writeOK(st.s.getDB("test1").foo.insert({_id: "test1", x: 1}));
- assert.writeOK(st.s.getDB("test2").foo.insert({_id: "test2", x: 1}));
- assert.neq(null, st.s.getDB("test1").foo.findOne({_id: "test1", x: 1}));
- assert.neq(null, st.s.getDB("test2").foo.findOne({_id: "test2", x: 1}));
-
- // Make sure the databases don't have versions when FCV <= 3.6
- let test1 = st.s.getDB("config").getCollection("databases").findOne({_id: "test1"});
- assert.neq(null, test1);
- assert(!test1.hasOwnProperty("version"), "db test1 has db version before upgrade");
-
- let test2 = st.s.getDB("config").getCollection("databases").findOne({_id: "test2"});
- assert.neq(null, test2);
- assert(!test2.hasOwnProperty("version"), "db test2 has db version before upgrade");
-
- // Set FCV to latest
- assert.commandWorked(st.s.adminCommand({setFeatureCompatibilityVersion: latestFCV}));
- checkFCV(configPrimaryAdminDB, latestFCV);
- checkFCV(shardPrimaryAdminDB, latestFCV);
-
- // Make sure databases were given versions after upgrade
- test1 = st.s.getDB("config").getCollection("databases").findOne({_id: "test1"});
- assert(test1.hasOwnProperty("version"), "db test1 does not have db version after upgrade");
-
- test2 = st.s.getDB("config").getCollection("databases").findOne({_id: "test2"});
- assert(test2.hasOwnProperty("version"), "db test2 does not have db version after upgrade");
-
- // Set FCV to last-stable
- assert.commandWorked(st.s.adminCommand({setFeatureCompatibilityVersion: lastStableFCV}));
- checkFCV(configPrimaryAdminDB, lastStableFCV);
- checkFCV(shardPrimaryAdminDB, lastStableFCV);
-
- // Make sure versions were removed when FCV changed to <= 3.6
- test1 = st.s.getDB("config").getCollection("databases").findOne({_id: "test1"});
- assert.neq(null, test1);
- assert(!test1.hasOwnProperty("version"), "db test1 has db version before upgrade");
-
- test2 = st.s.getDB("config").getCollection("databases").findOne({_id: "test2"});
- assert.neq(null, test2);
- assert(!test2.hasOwnProperty("version"), "db test2 has db version before upgrade");
-
- st.stop();
-
-})(); \ No newline at end of file
diff --git a/jstests/multiVersion/global_snapshot_reads_downgrade_cluster.js b/jstests/multiVersion/global_snapshot_reads_downgrade_cluster.js
deleted file mode 100644
index 9dfdaa7c8a0..00000000000
--- a/jstests/multiVersion/global_snapshot_reads_downgrade_cluster.js
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
- * Test the downgrade of a sharded cluster from latest to last-stable version succeeds, verifying
- * the behavior of global snapshot reads throughout the process.
- */
-
-// Checking UUID consistency uses cached connections, which are not valid across restarts or
-// stepdowns.
-TestData.skipCheckingUUIDsConsistentAcrossCluster = true;
-
-(function() {
- "use strict";
-
- load("jstests/libs/feature_compatibility_version.js");
- load("jstests/multiVersion/libs/multi_rs.js");
- load("jstests/multiVersion/libs/multi_cluster.js");
- load("jstests/multiVersion/libs/global_snapshot_reads_helpers.js");
-
- if (!supportsSnapshotReadConcern()) {
- jsTestLog("Skipping test since storage engine doesn't support snapshot read concern.");
- return;
- }
-
- // Start a cluster with two shards and two mongos at the latest version.
- var st = new ShardingTest({
- shards: 2,
- mongos: 2,
- other: {
- mongosOptions: {binVersion: "latest"},
- configOptions: {binVersion: "latest"},
- rsOptions: {binVersion: "latest"},
- },
- rs: {nodes: 3} // Use 3 node replica sets to allow downgrades with no downtime.
- });
- checkFCV(st.configRS.getPrimary().getDB("admin"), latestFCV);
-
- // Setup a sharded collection with two chunks, one on each shard.
- assert.commandWorked(st.s.adminCommand({enableSharding: "shardedDb"}));
- st.ensurePrimaryShard("shardedDb", st.shard0.shardName);
- assert.commandWorked(st.s.adminCommand({shardCollection: "shardedDb.sharded", key: {x: 1}}));
- assert.commandWorked(st.s.adminCommand({split: "shardedDb.sharded", middle: {x: 0}}));
- assert.commandWorked(
- st.s.adminCommand({moveChunk: "shardedDb.sharded", find: {x: 1}, to: st.shard1.shardName}));
-
- // Insert some data for the reads to find.
- st.s.getDB("unshardedDb").unsharded.insert({x: 1});
- st.s.getDB("shardedDb").sharded.insert([{x: -1}, {x: 1}]);
-
- // Global snapshot reads are accepted.
- verifyGlobalSnapshotReads(st.s0, true);
- verifyGlobalSnapshotReads(st.s1, true);
-
- // Downgrade featureCompatibilityVersion to 3.6.
- assert.commandWorked(st.s.adminCommand({setFeatureCompatibilityVersion: lastStableFCV}));
- checkFCV(st.configRS.getPrimary().getDB("admin"), lastStableFCV);
-
- // Global snapshot reads are accepted.
- verifyGlobalSnapshotReads(st.s0, true);
- verifyGlobalSnapshotReads(st.s1, true);
-
- // Downgrade the mongos servers first.
- jsTest.log("Downgrading mongos servers.");
- st.upgradeCluster("last-stable",
- {upgradeConfigs: false, upgradeMongos: true, upgradeShards: false});
-
- // Global snapshot reads are rejected with InvalidOptions, because downgraded mongos will not
- // forward the txnNumber to the shards.
- verifyGlobalSnapshotReads(st.s0, false, ErrorCodes.InvalidOptions);
- verifyGlobalSnapshotReads(st.s1, false, ErrorCodes.InvalidOptions);
-
- // Then downgrade the shard servers.
- jsTest.log("Downgrading shard servers.");
- st.upgradeCluster("last-stable",
- {upgradeConfigs: false, upgradeMongos: false, upgradeShards: true});
-
- // Global snapshot reads are rejected with FailedToParse, because the shards will reject the
- // unknown readConcern field.
- verifyGlobalSnapshotReads(st.s0, false, ErrorCodes.FailedToParse);
- verifyGlobalSnapshotReads(st.s1, false, ErrorCodes.FailedToParse);
-
- // Finally, downgrade the config servers.
- jsTest.log("Downgrading config servers.");
- st.upgradeCluster("last-stable",
- {upgradeConfigs: true, upgradeMongos: false, upgradeShards: false});
-
- // Global snapshot reads are rejected with FailedToParse, because the shards will reject the
- // unknown readConcern field.
- verifyGlobalSnapshotReads(st.s0, false, ErrorCodes.FailedToParse);
- verifyGlobalSnapshotReads(st.s1, false, ErrorCodes.FailedToParse);
-
- st.stop();
-})();
diff --git a/jstests/multiVersion/global_snapshot_reads_upgrade_cluster.js b/jstests/multiVersion/global_snapshot_reads_upgrade_cluster.js
deleted file mode 100644
index 86113083fb0..00000000000
--- a/jstests/multiVersion/global_snapshot_reads_upgrade_cluster.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * Tests upgrading a cluster with two shards and two mongos servers from last stable to current
- * version, verifying the behavior of global snapshot reads throughout the process.
- */
-
-// Checking UUID consistency uses cached connections, which are not valid across restarts or
-// stepdowns.
-TestData.skipCheckingUUIDsConsistentAcrossCluster = true;
-
-(function() {
- "use strict";
-
- load("jstests/libs/feature_compatibility_version.js");
- load("jstests/multiVersion/libs/multi_rs.js");
- load("jstests/multiVersion/libs/multi_cluster.js");
- load("jstests/multiVersion/libs/global_snapshot_reads_helpers.js");
-
- if (!supportsSnapshotReadConcern()) {
- jsTestLog("Skipping test since storage engine doesn't support snapshot read concern.");
- return;
- }
-
- // Start a cluster with two shards and two mongos at the last stable version.
- var st = new ShardingTest({
- shards: 2,
- mongos: 2,
- other: {
- configOptions: {binVersion: "last-stable"},
- mongosOptions: {binVersion: "last-stable"},
- rsOptions: {binVersion: "last-stable"},
- },
- rs: {nodes: 3} // Use 3 node replica sets to allow upgrades with no downtime.
- });
-
- // Setup a sharded collection with two chunks, one on each shard.
- assert.commandWorked(st.s.adminCommand({enableSharding: "shardedDb"}));
- st.ensurePrimaryShard("shardedDb", st.shard0.shardName);
- assert.commandWorked(st.s.adminCommand({shardCollection: "shardedDb.sharded", key: {x: 1}}));
- assert.commandWorked(st.s.adminCommand({split: "shardedDb.sharded", middle: {x: 0}}));
- assert.commandWorked(
- st.s.adminCommand({moveChunk: "shardedDb.sharded", find: {x: 1}, to: st.shard1.shardName}));
-
- // Insert some data for the reads to find.
- st.s.getDB("unshardedDb").unsharded.insert({x: 1});
- st.s.getDB("shardedDb").sharded.insert([{x: -1}, {x: 1}]);
-
- // Global snapshot reads are rejected with FailedToParse, because the shards will reject the
- // unknown readConcern field.
- verifyGlobalSnapshotReads(st.s0, false, ErrorCodes.FailedToParse);
- verifyGlobalSnapshotReads(st.s1, false, ErrorCodes.FailedToParse);
-
- // Upgrade the config servers.
- jsTest.log("Upgrading config servers.");
- st.upgradeCluster("latest", {upgradeConfigs: true, upgradeMongos: false, upgradeShards: false});
-
- // Global snapshot reads are rejected with FailedToParse, because the shards will reject the
- // unknown readConcern field.
- verifyGlobalSnapshotReads(st.s0, false, ErrorCodes.FailedToParse);
- verifyGlobalSnapshotReads(st.s1, false, ErrorCodes.FailedToParse);
-
- // Then upgrade the shard servers.
- jsTest.log("Upgrading shard servers.");
- st.upgradeCluster("latest", {upgradeConfigs: false, upgradeMongos: false, upgradeShards: true});
-
- // Global snapshot reads are rejected with InvalidOptions, because mongos will not forward the
- // txnNumber to the upgraded shards.
- verifyGlobalSnapshotReads(st.s0, false, ErrorCodes.InvalidOptions);
- verifyGlobalSnapshotReads(st.s1, false, ErrorCodes.InvalidOptions);
-
- // Finally, upgrade mongos servers.
- jsTest.log("Upgrading mongos servers.");
- st.upgradeCluster("latest", {upgradeConfigs: false, upgradeMongos: true, upgradeShards: false});
- checkFCV(st.configRS.getPrimary().getDB("admin"), lastStableFCV);
-
- // Global snapshot reads are accepted.
- verifyGlobalSnapshotReads(st.s0, true);
- verifyGlobalSnapshotReads(st.s1, true);
-
- // Upgrade the cluster's feature compatibility version to the latest.
- assert.commandWorked(
- st.s.getDB("admin").runCommand({setFeatureCompatibilityVersion: latestFCV}));
- checkFCV(st.configRS.getPrimary().getDB("admin"), latestFCV);
-
- // Global snapshot reads are accepted.
- verifyGlobalSnapshotReads(st.s0, true);
- verifyGlobalSnapshotReads(st.s1, true);
-
- st.stop();
-})();
diff --git a/jstests/multiVersion/startup_without_UUIDs_fails.js b/jstests/multiVersion/startup_without_UUIDs_fails.js
deleted file mode 100644
index 1980fe8039b..00000000000
--- a/jstests/multiVersion/startup_without_UUIDs_fails.js
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * Tests that a v4.0 mongod cannot start up if any collection is missing a UUID.
- *
- * Utilizes a v3.6 binary and downgrade to FCV 3.4 to set up collections without UUIDs
- *
- * Also demonstrate a v4.0 mongod will shutdown to 3.4 compatible data files when started up on
- * 3.4 data files.
- */
-
-(function() {
- "use strict";
-
- let dbpath = MongoRunner.dataPath + "startup_without_UUIDs";
- resetDbpath(dbpath);
- let connection;
-
- connection = MongoRunner.runMongod({dbpath: dbpath, binVersion: "3.4"});
- assert.commandWorked(connection.adminCommand({setFeatureCompatibilityVersion: "3.4"}));
- MongoRunner.stopMongod(connection);
-
- jsTest.log("Asserting a v4.0 binary does not startup on 3.4 data files.");
-
- let returnCode = runMongoProgram("mongod", "--port", connection.port, "--dbpath", dbpath, "-v");
- const needsUpgradeCode = 62;
- assert.eq(returnCode, needsUpgradeCode);
-
- jsTest.log("Asserting v3.4 does start up after a v4.0 binary failed.");
-
- connection = MongoRunner.runMongod({dbpath: dbpath, binVersion: "3.4"});
- MongoRunner.stopMongod(connection);
-
- jsTest.log("Set up a v3.6 binary downgraded to FCV 3.4 without collection UUIDs.");
-
- connection = MongoRunner.runMongod({dbpath: dbpath, binVersion: "3.6"});
- assert.commandWorked(connection.adminCommand({setFeatureCompatibilityVersion: "3.4"}));
- MongoRunner.stopMongod(connection);
-
- jsTest.log("Attempting v4.0 --repair should fail because collections lack UUIDs.");
-
- returnCode =
- runMongoProgram("mongod", "--port", connection.port, "--repair", "--dbpath", dbpath);
- assert.neq(returnCode, 0);
-
- jsTest.log("Trying to start up a v4.0 binary on FCV 3.4 data files should fail because the " +
- "collections are missing UUIDs.");
-
- connection = MongoRunner.runMongod({dbpath: dbpath, binVersion: "latest", noCleanData: true});
- assert.eq(null, connection);
-
- jsTest.log("Using a v3.6 binary and upgrading to FCV 3.6 should update the data files to a " +
- "format acceptable to a v4.0 binary");
-
- connection = MongoRunner.runMongod({dbpath: dbpath, binVersion: "3.6", noCleanData: true});
- assert.neq(null, connection);
- assert.commandWorked(connection.adminCommand({setFeatureCompatibilityVersion: "3.6"}));
- MongoRunner.stopMongod(connection);
-
- jsTest.log("Now, finally, a v4.0 binary should start up on the FCV 3.6 data files");
-
- connection = MongoRunner.runMongod({dbpath: dbpath, binVersion: "latest", noCleanData: true});
- assert.neq(null, connection);
- MongoRunner.stopMongod(connection);
-
- jsTest.log("Done!");
-
-})();
diff --git a/jstests/multiVersion/verify_versions_test.js b/jstests/multiVersion/verify_versions_test.js
index 9f1b2a3be96..cbd8974a669 100644
--- a/jstests/multiVersion/verify_versions_test.js
+++ b/jstests/multiVersion/verify_versions_test.js
@@ -42,8 +42,8 @@ TestData.skipCheckingUUIDsConsistentAcrossCluster = true;
// The current version is in the 3.7 series. This has to be changed very time we bump
// the major version pair, but it provides a useful test of assumptions.
- assertBinVersionsEqual("3.7", version());
- assertBinVersionComparesEqual("3.7", version());
+ assertBinVersionsEqual("4.1", version());
+ assertBinVersionComparesEqual("4.1", version());
// "latest" is the same version as the shell, "last-stable" is not.
assertBinVersionsEqual("latest", version());
@@ -77,6 +77,7 @@ TestData.skipCheckingUUIDsConsistentAcrossCluster = true;
assertBinVersionComparesEqual("3.4", "3.4.0-abcd");
assertBinVersionComparesEqual("3.4.0", "3.4.0-abcd");
assertBinVersionComparesHigher("3.6.0", "3.4.0-abcd");
+ assertBinVersionComparesHigher("4.0.0", "3.6.99-abcd");
assertBinVersionComparesHigher("3.4.1", "3.4.0-abcd");
assertBinVersionComparesLower("3.4.0-abc", "3.4.1-xyz");
diff --git a/jstests/multiVersion/view_definition_feature_compatibility_version.js b/jstests/multiVersion/view_definition_feature_compatibility_version.js
deleted file mode 100644
index 2b78bc684db..00000000000
--- a/jstests/multiVersion/view_definition_feature_compatibility_version.js
+++ /dev/null
@@ -1,257 +0,0 @@
-/**
- * Test that mongod will not allow creation of a view using 4.0 aggregation features when the
- * feature compatibility version is older than 4.0.
- *
- * TODO SERVER-33321: Remove FCV 3.6 validation during the 4.1 development cycle.
- *
- * We restart mongod during the test and expect it to have the same data after restarting.
- * @tags: [requires_persistence]
- */
-
-(function() {
- "use strict";
-
- const testName = "view_definition_feature_compatibility_version_multiversion";
- const dbpath = MongoRunner.dataPath + testName;
-
- // In order to avoid restarting the server for each test case, we declare all the test cases up
- // front, and test them all at once.
- const pipelinesWithNewFeatures = [
- [{$project: {trimmed: {$trim: {input: " hi "}}}}],
- [{$project: {trimmed: {$ltrim: {input: " hi "}}}}],
- [{$project: {trimmed: {$rtrim: {input: " hi "}}}}],
- // The 'format' option was added in 4.0.
- [{
- $project: {
- dateFromStringWithFormat:
- {$dateFromString: {dateString: "2018-02-08", format: "$format"}}
- }
- }],
- // The 'onNull' option was added in 4.0.
- [{
- $project: {
- dateFromStringWithOnNull: {
- $dateFromString: {dateString: "$dateString", onNull: new Date("1970-01-01")}
- }
- }
- }],
- // The 'onError' option was added in 4.0.
- [{
- $project: {
- dateFromStringWithOnError: {
- $dateFromString:
- {dateString: "$dateString", onError: new Date("1970-01-01")}
- }
- }
- }],
- // The 'onNull' option was added in 4.0.
- [{
- $project: {
- dateToStringWithOnNull:
- {$dateToString: {date: "$date", format: "%Y-%m-%d", onNull: "null input"}}
- }
- }],
- // The 'format' option was made optional in 4.0.
- [{$project: {dateToStringWithoutFormat: {$dateToString: {date: "$date"}}}}],
- [{$project: {conversion: {$convert: {input: "$a", to: "int"}}}}],
- [{$project: {conversionWithOnNull: {$convert: {input: "$a", to: "int", onNull: 0}}}}],
- [{$project: {conversionWithOnError: {$convert: {input: "$a", to: "int", onError: 0}}}}],
- [{$project: {toInt: {$toInt: "$a"}}}],
- [{$project: {toLong: {$toLong: "$a"}}}],
- [{$project: {toDouble: {$toDouble: "$a"}}}],
- [{$project: {toDecimal: {$toDecimal: "$a"}}}],
- [{$project: {toDate: {$toDate: "$a"}}}],
- [{$project: {toObjectId: {$toObjectId: "$a"}}}],
- [{$project: {toBool: {$toBool: "$a"}}}],
- [{$project: {toString: {$toString: "$a"}}}],
- // Test using one of the prohibited expressions inside of an $expr within a MatchExpression
- // embedded in the pipeline.
- [{$match: {$expr: {$eq: [{$trim: {input: "$a"}}, "hi"]}}}],
- [{
- $graphLookup: {
- from: "foreign",
- startWith: "$start",
- connectFromField: "to",
- connectToField: "_id",
- as: "results",
- restrictSearchWithMatch: {$expr: {$eq: [{$trim: {input: "$a"}}, "hi"]}}
- }
- }],
- [{$facet: {withinMatch: [{$match: {$expr: {$eq: [{$trim: {input: "$a"}}, "hi"]}}}]}}],
- [{
- $facet: {
- withinGraphLookup: [{
- $graphLookup: {
- from: "foreign",
- startWith: "$start",
- connectFromField: "to",
- connectToField: "_id",
- as: "results",
- restrictSearchWithMatch:
- {$expr: {$eq: [{$trim: {input: "$a"}}, "hi"]}}
- }
- }]
- }
- }],
- [{
- $facet: {
- withinMatch: [{$match: {$expr: {$eq: [{$trim: {input: "$a"}}, "hi"]}}}],
- withinGraphLookup: [{
- $graphLookup: {
- from: "foreign",
- startWith: "$start",
- connectFromField: "to",
- connectToField: "_id",
- as: "results",
- restrictSearchWithMatch:
- {$expr: {$eq: [{$trim: {input: "$a"}}, "hi"]}}
- }
- }]
- }
- }]
- ];
-
- let conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: "latest"});
- assert.neq(null, conn, "mongod was unable to start up");
- let testDB = conn.getDB(testName);
-
- // Explicitly set feature compatibility version 4.0.
- assert.commandWorked(testDB.adminCommand({setFeatureCompatibilityVersion: "4.0"}));
-
- // Test that we are able to create a new view with any of the new features.
- pipelinesWithNewFeatures.forEach(
- (pipe, i) => assert.commandWorked(
- testDB.createView("firstView" + i, "coll", pipe),
- `Expected to be able to create view with pipeline ${tojson(pipe)} while in FCV 4.0`));
-
- // Test that we are able to create a new view with any of the new features.
- pipelinesWithNewFeatures.forEach(function(pipe, i) {
- assert(testDB["firstView" + i].drop(), `Drop of view with pipeline ${tojson(pipe)} failed`);
- assert.commandWorked(testDB.createView("firstView" + i, "coll", []));
- assert.commandWorked(
- testDB.runCommand({collMod: "firstView" + i, viewOn: "coll", pipeline: pipe}),
- `Expected to be able to modify view to use pipeline ${tojson(pipe)} while in FCV 4.0`);
- });
-
- // Create an empty view which we will attempt to update to use 4.0 query features under
- // feature compatibility mode 3.6.
- assert.commandWorked(testDB.createView("emptyView", "coll", []));
-
- // Set the feature compatibility version to 3.6.
- assert.commandWorked(testDB.adminCommand({setFeatureCompatibilityVersion: "3.6"}));
-
- // Read against an existing view using 4.0 query features should not fail.
- pipelinesWithNewFeatures.forEach(
- (pipe, i) => assert.commandWorked(testDB.runCommand({find: "firstView" + i}),
- `Failed to query view with pipeline ${tojson(pipe)}`));
-
- // Trying to create a new view using 4.0 query features should fail.
- pipelinesWithNewFeatures.forEach(
- (pipe, i) => assert.commandFailedWithCode(
- testDB.createView("view_fail" + i, "coll", pipe),
- ErrorCodes.QueryFeatureNotAllowed,
- `Expected *not* to be able to create view with pipeline ${tojson(pipe)} while in FCV 3.6`));
-
- // Trying to update existing view to use 4.0 query features should also fail.
- pipelinesWithNewFeatures.forEach(
- (pipe, i) => assert.commandFailedWithCode(
- testDB.runCommand({collMod: "emptyView", viewOn: "coll", pipeline: pipe}),
- ErrorCodes.QueryFeatureNotAllowed,
- `Expected *not* to be able to modify view to use pipeline ${tojson(pipe)} while in FCV 3.6`));
-
- MongoRunner.stopMongod(conn);
-
- // Starting up a 3.6 mongod with 4.0 query features will succeed.
- conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: "3.6", noCleanData: true});
- assert.neq(null, conn, "mongod 3.6 was unable to start up");
- testDB = conn.getDB(testName);
-
- // Reads will fail against views with 4.0 query features when running a 3.6 binary.
- // Not checking the code returned on failure as it is not uniform across the various
- // 'pipeline' arguments tested.
- pipelinesWithNewFeatures.forEach(
- (pipe, i) => assert.commandFailed(
- testDB.runCommand({find: "firstView" + i}),
- `Expected read against view with pipeline ${tojson(pipe)} to fail on 3.6 binary`));
-
- // Test that a read against a view that does not contain 4.0 query features succeeds.
- assert.commandWorked(testDB.runCommand({find: "emptyView"}));
-
- MongoRunner.stopMongod(conn);
-
- // Starting up a 4.0 mongod should succeed, even though the feature compatibility version is
- // still set to 3.6.
- conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: "latest", noCleanData: true});
- assert.neq(null, conn, "mongod was unable to start up");
- testDB = conn.getDB(testName);
-
- // Read against an existing view using 4.0 query features should not fail.
- pipelinesWithNewFeatures.forEach(
- (pipe, i) => assert.commandWorked(testDB.runCommand({find: "firstView" + i}),
- `Failed to query view with pipeline ${tojson(pipe)}`));
-
- // Set the feature compatibility version back to 4.0.
- assert.commandWorked(testDB.adminCommand({setFeatureCompatibilityVersion: "4.0"}));
-
- pipelinesWithNewFeatures.forEach(function(pipe, i) {
- assert.commandWorked(testDB.runCommand({find: "firstView" + i}),
- `Failed to query view with pipeline ${tojson(pipe)}`);
- // Test that we are able to create a new view with any of the new features.
- assert.commandWorked(
- testDB.createView("secondView" + i, "coll", pipe),
- `Expected to be able to create view with pipeline ${tojson(pipe)} while in FCV 4.0`);
-
- // Test that we are able to update an existing view to use any of the new features.
- assert(testDB["secondView" + i].drop(),
- `Drop of view with pipeline ${tojson(pipe)} failed`);
- assert.commandWorked(testDB.createView("secondView" + i, "coll", []));
- assert.commandWorked(
- testDB.runCommand({collMod: "secondView" + i, viewOn: "coll", pipeline: pipe}),
- `Expected to be able to modify view to use pipeline ${tojson(pipe)} while in FCV 4.0`);
- });
-
- // Set the feature compatibility version to 3.6 and then restart with
- // internalValidateFeaturesAsMaster=false.
- assert.commandWorked(testDB.adminCommand({setFeatureCompatibilityVersion: "3.6"}));
- MongoRunner.stopMongod(conn);
- conn = MongoRunner.runMongod({
- dbpath: dbpath,
- binVersion: "latest",
- noCleanData: true,
- setParameter: "internalValidateFeaturesAsMaster=false"
- });
- assert.neq(null, conn, "mongod was unable to start up");
- testDB = conn.getDB(testName);
-
- pipelinesWithNewFeatures.forEach(function(pipe, i) {
- // Even though the feature compatibility version is 3.6, we should still be able to create a
- // view using 4.0 query features, because internalValidateFeaturesAsMaster is false.
- assert.commandWorked(
- testDB.createView("thirdView" + i, "coll", pipe),
- `Expected to be able to create view with pipeline ${tojson(pipe)} while in FCV 3.6 ` +
- `with internalValidateFeaturesAsMaster=false`);
-
- // We should also be able to modify a view to use 4.0 query features.
- assert(testDB["thirdView" + i].drop(), `Drop of view with pipeline ${tojson(pipe)} failed`);
- assert.commandWorked(testDB.createView("thirdView" + i, "coll", []));
- assert.commandWorked(
- testDB.runCommand({collMod: "thirdView" + i, viewOn: "coll", pipeline: pipe}),
- `Expected to be able to modify view to use pipeline ${tojson(pipe)} while in FCV 3.6 ` +
- `with internalValidateFeaturesAsMaster=false`);
- });
-
- MongoRunner.stopMongod(conn);
-
- // Starting up a 3.6 mongod with 4.0 query features.
- conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: "3.6", noCleanData: true});
- assert.neq(null, conn, "mongod 3.6 was unable to start up");
- testDB = conn.getDB(testName);
-
- // Existing views with 4.0 query features can be dropped.
- pipelinesWithNewFeatures.forEach(
- (pipe, i) => assert(testDB["firstView" + i].drop(),
- `Drop of view with pipeline ${tojson(pipe)} failed`));
- assert(testDB.system.views.drop(), "Drop of system.views collection failed");
-
- MongoRunner.stopMongod(conn);
-}());