diff options
author | Robert Guo <robert.guo@10gen.com> | 2018-05-22 13:04:28 -0400 |
---|---|---|
committer | Robert Guo <robert.guo@10gen.com> | 2018-05-22 15:15:53 -0400 |
commit | 27d3642878e8efd88334957b339708f96daa1dbd (patch) | |
tree | 3e90c42b467912de48d7f8bba07d705a746de78a /jstests/multiVersion | |
parent | 7d71638c84fe95e77e2bdd58cfe117b616aeb31a (diff) | |
download | mongo-27d3642878e8efd88334957b339708f96daa1dbd.tar.gz |
SERVER-35152 update tests for 4.0
Diffstat (limited to 'jstests/multiVersion')
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); -}()); |