0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00

SERVER-49066: Extend generic targeted multiversion tests to include new mixed binary version configurations

This commit is contained in:
Lingzhi Deng 2020-08-04 14:26:49 -04:00 committed by Evergreen Agent
parent be2cec4693
commit bbe29a4bf1
16 changed files with 481 additions and 453 deletions

View File

@ -10,7 +10,7 @@ selector:
- jstests/multiVersion/libs/*.js
# TODO: SERVER-21578
- jstests/multiVersion/balancer_multiVersion_detect.js
- jstests/multiVersion/genericSetFCVUsage/balancer_multiVersion_detect.js
# TODO: SERVER-28104
- jstests/multiVersion/minor_version_tags_new_old_new.js

View File

@ -13,7 +13,7 @@ selector:
- jstests/multiVersion/libs/*.js
# TODO: SERVER-21578
- jstests/multiVersion/balancer_multiVersion_detect.js
- jstests/multiVersion/genericSetFCVUsage/balancer_multiVersion_detect.js
# TODO: SERVER-28104
- jstests/multiVersion/minor_version_tags_new_old_new.js

View File

@ -1,53 +0,0 @@
//
// Tests launching multi-version ReplSetTest replica sets
//
// Check our latest versions
var versionsToCheck = ["last-lts", "latest"];
load('./jstests/multiVersion/libs/verify_versions.js');
jsTest.log("Testing legacy versions...");
for (var i = 0; i < versionsToCheck.length; i++) {
var version = versionsToCheck[i];
// Set up a replica set
var rst = new ReplSetTest({nodes: 2});
rst.startSet({binVersion: version});
var nodes = rst.nodes;
// Make sure the started versions are actually the correct versions
for (var j = 0; j < nodes.length; j++)
assert.binVersion(nodes[j], version);
rst.stopSet();
}
jsTest.log("Testing mixed versions...");
// Set up a multi-version replica set
var rst = new ReplSetTest({nodes: 2});
rst.startSet({binVersion: versionsToCheck});
var nodes = rst.nodes;
// Make sure we have hosts of all the different versions
var versionsFound = [];
for (var j = 0; j < nodes.length; j++)
versionsFound.push(nodes[j].getBinVersion());
assert.allBinVersions(versionsToCheck, versionsFound);
rst.stopSet();
jsTest.log("Done!");
//
// End
//

View File

@ -1,52 +0,0 @@
//
// Tests launching multi-version ShardingTest clusters.
//
load('./jstests/multiVersion/libs/verify_versions.js');
(function() {
"use strict";
// Check our latest versions
var versionsToCheck = ["last-lts", "latest"];
var versionsToCheckConfig = ["latest"];
var versionsToCheckMongos = ["last-lts"];
jsTest.log("Testing mixed versions...");
// Set up a multi-version cluster
var st = new ShardingTest({
shards: 2,
mongos: 2,
other: {
mongosOptions: {binVersion: versionsToCheckMongos},
configOptions: {binVersion: versionsToCheckConfig},
shardOptions: {binVersion: versionsToCheck},
enableBalancer: true
}
});
var shards = [st.shard0, st.shard1];
var mongoses = [st.s0, st.s1];
var configs = [st.config0, st.config1, st.config2];
// Make sure we have hosts of all the different versions
var versionsFound = [];
for (var j = 0; j < shards.length; j++)
versionsFound.push(shards[j].getBinVersion());
assert.allBinVersions(versionsToCheck, versionsFound);
versionsFound = [];
for (var j = 0; j < mongoses.length; j++)
versionsFound.push(mongoses[j].getBinVersion());
assert.allBinVersions(versionsToCheckMongos, versionsFound);
versionsFound = [];
for (var j = 0; j < configs.length; j++)
versionsFound.push(configs[j].getBinVersion());
assert.allBinVersions(versionsToCheckConfig, versionsFound);
st.stop();
})();

View File

@ -1,97 +0,0 @@
//
// Tests upgrading then downgrading a replica set
//
load('./jstests/multiVersion/libs/multi_rs.js');
load('./jstests/libs/test_background_ops.js');
var oldVersion = "last-lts";
var nodes = {
n1: {binVersion: oldVersion},
n2: {binVersion: oldVersion},
a3: {binVersion: oldVersion}
};
var rst = new ReplSetTest({nodes: nodes});
rst.startSet();
rst.initiate();
// Wait for a primary node...
var primary = rst.getPrimary();
var otherOpConn = new Mongo(rst.getURL());
var insertNS = "test.foo";
jsTest.log("Starting parallel operations during upgrade...");
function findAndInsert(rsURL, coll) {
var coll = new Mongo(rsURL).getCollection(coll + "");
var count = 0;
jsTest.log("Starting finds and inserts...");
while (!isFinished()) {
try {
coll.insert({_id: count, hello: "world"});
assert.eq(null, coll.getDB().getLastError());
assert.neq(null, coll.findOne({_id: count}));
} catch (e) {
printjson(e);
}
count++;
}
jsTest.log("Finished finds and inserts...");
return count;
}
var joinFindInsert =
startParallelOps(primary, // The connection where the test info is passed and stored
findAndInsert,
[rst.getURL(), insertNS]);
jsTest.log("Upgrading replica set...");
rst.upgradeSet({binVersion: "latest"});
jsTest.log("Replica set upgraded.");
// We save a reference to the old primary so that we can call reconnect() on it before
// joinFindInsert() would attempt to send the node an update operation that signals the parallel
// shell running the background operations to stop.
var oldPrimary = primary;
// Wait for primary
var primary = rst.getPrimary();
printjson(rst.status());
// Allow more valid writes to go through
sleep(10 * 1000);
jsTest.log("Downgrading replica set...");
rst.upgradeSet({binVersion: oldVersion});
jsTest.log("Replica set downgraded.");
// Allow even more valid writes to go through
sleep(10 * 1000);
// Since the primary from before the upgrade took place was restarted as part of the
// upgrade/downgrade process, we explicitly reconnect to it so that sending it an update operation
// silently fails with an unchecked NotMaster error rather than a network error.
reconnect(oldPrimary.getDB("admin"));
joinFindInsert();
// Since the primary from after the upgrade took place was restarted as part of the downgrade
// process, we explicitly reconnect to it.
reconnect(primary.getDB("admin"));
var totalInserts = primary.getCollection(insertNS).find().sort({_id: -1}).next()._id + 1;
var dataFound = primary.getCollection(insertNS).count();
jsTest.log("Found " + dataFound + " docs out of " + tojson(totalInserts) + " inserted.");
assert.gt(dataFound / totalInserts, 0.5);
rst.stopSet();

View File

@ -1,31 +0,0 @@
//
// Test checks whether the balancer correctly detects a mixed set of shards
//
jsTest.log("Starting cluster...");
var options = {
mongosOptions: {verbose: 1, useLogFiles: true},
configOptions: {},
shardOptions: {binVersion: ["latest", "last-lts"]},
enableBalancer: true
};
var st = new ShardingTest({shards: 3, mongos: 1, other: options});
var mongos = st.s0;
var admin = mongos.getDB("admin");
var coll = mongos.getCollection("foo.bar");
printjson(admin.runCommand({enableSharding: coll.getDB() + ""}));
st.ensurePrimaryShard(coll.getDB().getName(), st.shard1.shardName);
printjson(admin.runCommand({shardCollection: coll + "", key: {_id: 1}}));
assert.soon(function() {
var log = cat(mongos.fullOptions.logFile);
return /multiVersion cluster detected/.test(log);
}, "multiVersion warning not printed!", 30 * 16 * 60 * 1000, 5 * 1000);
jsTest.log("DONE!");
st.stop();

View File

@ -0,0 +1,48 @@
//
// Tests launching multi-version ReplSetTest replica sets
//
load('./jstests/multiVersion/libs/verify_versions.js');
for (let version of ["last-lts", "last-continuous", "latest"]) {
jsTestLog("Testing single version: " + version);
// Set up a single-version replica set
var rst = new ReplSetTest({nodes: 2});
rst.startSet({binVersion: version});
var nodes = rst.nodes;
// Make sure the started versions are actually the correct versions
for (var j = 0; j < nodes.length; j++)
assert.binVersion(nodes[j], version);
rst.stopSet();
}
for (let versions of [["last-lts", "latest"], ["last-continuous", "latest"]]) {
jsTestLog("Testing mixed versions: " + tojson(versions));
// Set up a multi-version replica set
var rst = new ReplSetTest({nodes: 2});
rst.startSet({binVersion: versions});
var nodes = rst.nodes;
// Make sure we have hosts of all the different versions
var versionsFound = [];
for (var j = 0; j < nodes.length; j++)
versionsFound.push(nodes[j].getBinVersion());
assert.allBinVersions(versions, versionsFound);
rst.stopSet();
}
jsTestLog("Done!");
//
// End
//

View File

@ -0,0 +1,55 @@
//
// Tests launching multi-version ShardingTest clusters.
//
load('./jstests/multiVersion/libs/verify_versions.js');
(function() {
"use strict";
// Sharded cluster upgrade order: config servers -> shards -> mongos.
const mixedVersionsToCheck = [
{config: ["latest"], shard: ["last-lts", "latest"], mongos: ["last-lts"]},
{config: ["latest"], shard: ["last-continuous", "latest"], mongos: ["last-continuous"]},
];
for (let versions of mixedVersionsToCheck) {
jsTest.log("Testing mixed versions: " + tojson(versions));
// Set up a multi-version cluster
var st = new ShardingTest({
shards: 2,
mongos: 2,
other: {
mongosOptions: {binVersion: versions.mongos},
configOptions: {binVersion: versions.config},
shardOptions: {binVersion: versions.shard},
enableBalancer: true
}
});
var shards = [st.shard0, st.shard1];
var mongoses = [st.s0, st.s1];
var configs = [st.config0, st.config1, st.config2];
// Make sure we have hosts of all the different versions
var versionsFound = [];
for (var j = 0; j < shards.length; j++)
versionsFound.push(shards[j].getBinVersion());
assert.allBinVersions(versions.shard, versionsFound);
versionsFound = [];
for (var j = 0; j < mongoses.length; j++)
versionsFound.push(mongoses[j].getBinVersion());
assert.allBinVersions(versions.mongos, versionsFound);
versionsFound = [];
for (var j = 0; j < configs.length; j++)
versionsFound.push(configs[j].getBinVersion());
assert.allBinVersions(versions.config, versionsFound);
st.stop();
}
})();

View File

@ -0,0 +1,99 @@
//
// Tests upgrading then downgrading a replica set
//
load('./jstests/multiVersion/libs/multi_rs.js');
load('./jstests/libs/test_background_ops.js');
for (let oldVersion of ["last-lts", "last-continuous"]) {
jsTest.log("Testing upgrade/downgrade with " + oldVersion);
var nodes = {
n1: {binVersion: oldVersion},
n2: {binVersion: oldVersion},
a3: {binVersion: oldVersion}
};
var rst = new ReplSetTest({nodes: nodes});
rst.startSet();
rst.initiate();
// Wait for a primary node...
var primary = rst.getPrimary();
var otherOpConn = new Mongo(rst.getURL());
var insertNS = "test.foo";
jsTest.log("Starting parallel operations during upgrade...");
function findAndInsert(rsURL, coll) {
var coll = new Mongo(rsURL).getCollection(coll + "");
var count = 0;
jsTest.log("Starting finds and inserts...");
while (!isFinished()) {
try {
coll.insert({_id: count, hello: "world"});
assert.eq(null, coll.getDB().getLastError());
assert.neq(null, coll.findOne({_id: count}));
} catch (e) {
printjson(e);
}
count++;
}
jsTest.log("Finished finds and inserts...");
return count;
}
var joinFindInsert =
startParallelOps(primary, // The connection where the test info is passed and stored
findAndInsert,
[rst.getURL(), insertNS]);
jsTest.log("Upgrading replica set from " + oldVersion + " to latest");
rst.upgradeSet({binVersion: "latest"});
jsTest.log("Replica set upgraded.");
// We save a reference to the old primary so that we can call reconnect() on it before
// joinFindInsert() would attempt to send the node an update operation that signals the parallel
// shell running the background operations to stop.
var oldPrimary = primary;
// Wait for primary
var primary = rst.getPrimary();
printjson(rst.status());
// Allow more valid writes to go through
sleep(10 * 1000);
jsTest.log("Downgrading replica set from latest to " + oldVersion);
rst.upgradeSet({binVersion: oldVersion});
jsTest.log("Replica set downgraded.");
// Allow even more valid writes to go through
sleep(10 * 1000);
// Since the primary from before the upgrade took place was restarted as part of the
// upgrade/downgrade process, we explicitly reconnect to it so that sending it an update
// operation silently fails with an unchecked NotMaster error rather than a network error.
reconnect(oldPrimary.getDB("admin"));
joinFindInsert();
// Since the primary from after the upgrade took place was restarted as part of the downgrade
// process, we explicitly reconnect to it.
reconnect(primary.getDB("admin"));
var totalInserts = primary.getCollection(insertNS).find().sort({_id: -1}).next()._id + 1;
var dataFound = primary.getCollection(insertNS).count();
jsTest.log("Found " + dataFound + " docs out of " + tojson(totalInserts) + " inserted.");
assert.gt(dataFound / totalInserts, 0.5);
rst.stopSet();
}

View File

@ -20,6 +20,12 @@ assert.commandFailedWithCode(st.admin.runCommand({addshard: lastLTSMongod.host})
ErrorCodes.IncompatibleServerVersion);
MongoRunner.stopMongod(lastLTSMongod);
// Can't add a mongod with a lower binary version than our featureCompatibilityVersion.
var lastContinuousMongod = MongoRunner.runMongod({binVersion: "last-continuous", shardsvr: ""});
assert.commandFailedWithCode(st.admin.runCommand({addshard: lastContinuousMongod.host}),
ErrorCodes.IncompatibleServerVersion);
MongoRunner.stopMongod(lastContinuousMongod);
// Can't add config servers as shard.
assert.commandFailed(st.admin.runCommand({addshard: st._configDB}));

View File

@ -0,0 +1,34 @@
//
// Test checks whether the balancer correctly detects a mixed set of shards
//
// Test mixed version between "latest" and "last-lts"/"last-continuous".
for (let versions of [["latest", "last-lts"], ["latest", "last-continuous"]]) {
jsTest.log("Starting cluster with shard binVersion: " + tojson(versions));
var options = {
mongosOptions: {verbose: 1, useLogFiles: true},
configOptions: {},
shardOptions: {binVersion: versions},
enableBalancer: true
};
var st = new ShardingTest({shards: 3, mongos: 1, other: options});
var mongos = st.s0;
var admin = mongos.getDB("admin");
var coll = mongos.getCollection("foo.bar");
printjson(admin.runCommand({enableSharding: coll.getDB() + ""}));
st.ensurePrimaryShard(coll.getDB().getName(), st.shard1.shardName);
printjson(admin.runCommand({shardCollection: coll + "", key: {_id: 1}}));
assert.soon(function() {
var log = cat(mongos.fullOptions.logFile);
return /multiVersion cluster detected/.test(log);
}, "multiVersion warning not printed!", 30 * 16 * 60 * 1000, 5 * 1000);
st.stop();
jsTest.log("DONE!");
}

View File

@ -0,0 +1,28 @@
/*
* This is a regression test for SERVER-16189, to make sure a replica set with both current and
* prior version nodes can be initialized from the prior version node.
*/
(function() {
"use strict";
var name = "initialize_from_old";
// Test old version with both "last-lts" and "last-continuous".
for (let oldVersion of ["last-lts", "last-continuous"]) {
jsTestLog("Testing replSetInitiate with " + oldVersion);
var newVersion = 'latest';
var nodes = {
n0: {binVersion: oldVersion},
n1: {binVersion: newVersion},
n2: {binVersion: newVersion}
};
var rst = new ReplSetTest({nodes: nodes, name: name});
var conns = rst.startSet();
var oldNode = conns[0];
var config = rst.getReplSetConfig();
var response = oldNode.getDB("admin").runCommand({replSetInitiate: config});
assert.commandWorked(response);
// Wait for secondaries to finish their initial sync before shutting down the cluster.
rst.awaitSecondaryNodes();
rst.stopSet();
}
})();

View File

@ -0,0 +1,173 @@
/**
* Tests that CRUD and aggregation commands through the mongos continue to work as expected on both
* sharded and unsharded collection at each step of cluster upgrade/downgrade between last-lts and
* latest and between last-continuous and latest.
*/
(function() {
"use strict";
load('./jstests/multiVersion/libs/multi_rs.js');
load('./jstests/multiVersion/libs/multi_cluster.js');
// When checking UUID consistency, the shell attempts to run a command on the node it believes is
// primary in each shard. However, this test restarts shards, and the node that is elected primary
// after the restart may be different from the original primary. Since the shell does not retry on
// NotMaster errors, and whether or not it detects the new primary before issuing the command is
// nondeterministic, skip the consistency check for this test.
TestData.skipCheckingUUIDsConsistentAcrossCluster = true;
const kMinVersion = 5;
const kCurrentVerion = 6;
var testCRUDAndAgg = function(db) {
assert.commandWorked(db.foo.insert({x: 1}));
assert.commandWorked(db.foo.insert({x: -1}));
assert.commandWorked(db.foo.update({x: 1}, {$set: {y: 1}}));
assert.commandWorked(db.foo.update({x: -1}, {$set: {y: 1}}));
var doc1 = db.foo.findOne({x: 1});
assert.eq(1, doc1.y);
var doc2 = db.foo.findOne({x: -1});
assert.eq(1, doc2.y);
assert.commandWorked(db.foo.remove({x: 1}, true));
assert.commandWorked(db.foo.remove({x: -1}, true));
assert.eq(null, db.foo.findOne());
};
// Test upgrade/downgrade between "latest" and "last-lts"/"last-continuous".
for (let oldVersion of ["last-lts", "last-continuous"]) {
var st = new ShardingTest({
shards: 2,
mongos: 1,
other: {
mongosOptions: {binVersion: oldVersion},
configOptions: {binVersion: oldVersion},
shardOptions: {binVersion: oldVersion},
rsOptions: {binVersion: oldVersion},
rs: true,
}
});
st.configRS.awaitReplication();
// check that config.version document gets initialized properly
var version = st.s.getCollection('config.version').findOne();
assert.eq(version.minCompatibleVersion, kMinVersion);
assert.eq(version.currentVersion, kCurrentVerion);
var clusterID = version.clusterId;
assert.neq(null, clusterID);
assert.eq(version.excluding, undefined);
// Setup sharded collection
assert.commandWorked(st.s.adminCommand({enableSharding: 'sharded'}));
st.ensurePrimaryShard('sharded', st.shard0.shardName);
assert.commandWorked(st.s.adminCommand({shardCollection: 'sharded.foo', key: {x: 1}}));
assert.commandWorked(st.s.adminCommand({split: 'sharded.foo', middle: {x: 0}}));
assert.commandWorked(
st.s.adminCommand({moveChunk: 'sharded.foo', find: {x: 1}, to: st.shard1.shardName}));
testCRUDAndAgg(st.s.getDB('unsharded'));
testCRUDAndAgg(st.s.getDB('sharded'));
// upgrade the config servers first
jsTest.log('upgrading config servers');
st.upgradeCluster("latest", {upgradeMongos: false, upgradeShards: false});
testCRUDAndAgg(st.s.getDB('unsharded'));
testCRUDAndAgg(st.s.getDB('sharded'));
// Restart mongos to clear all cache and force it to do remote calls.
st.restartMongoses();
testCRUDAndAgg(st.s.getDB('unsharded'));
testCRUDAndAgg(st.s.getDB('sharded'));
// Then upgrade the shards.
jsTest.log('upgrading shard servers');
st.upgradeCluster("latest", {upgradeMongos: false, upgradeConfigs: false});
awaitRSClientHosts(st.s, st.rs0.getPrimary(), {ok: true, ismaster: true});
awaitRSClientHosts(st.s, st.rs1.getPrimary(), {ok: true, ismaster: true});
testCRUDAndAgg(st.s.getDB('unsharded'));
testCRUDAndAgg(st.s.getDB('sharded'));
// Restart mongos to clear all cache and force it to do remote calls.
st.restartMongoses();
testCRUDAndAgg(st.s.getDB('unsharded'));
testCRUDAndAgg(st.s.getDB('sharded'));
// Finally, upgrade mongos
jsTest.log('upgrading mongos servers');
st.upgradeCluster("latest", {upgradeConfigs: false, upgradeShards: false});
testCRUDAndAgg(st.s.getDB('unsharded'));
testCRUDAndAgg(st.s.getDB('sharded'));
// Restart mongos to clear all cache and force it to do remote calls.
st.restartMongoses();
testCRUDAndAgg(st.s.getDB('unsharded'));
testCRUDAndAgg(st.s.getDB('sharded'));
// Check that version document is unmodified.
version = st.s.getCollection('config.version').findOne();
assert.eq(version.minCompatibleVersion, kMinVersion);
assert.eq(version.currentVersion, kCurrentVerion);
assert.eq(clusterID, version.clusterId);
assert.eq(version.excluding, undefined);
///////////////////////////////////////////////////////////////////////////////////////////
// Downgrade back
jsTest.log('downgrading mongos servers');
st.upgradeCluster(oldVersion, {upgradeConfigs: false, upgradeShards: false});
testCRUDAndAgg(st.s.getDB('unsharded'));
testCRUDAndAgg(st.s.getDB('sharded'));
// Restart mongos to clear all cache and force it to do remote calls.
st.restartMongoses();
testCRUDAndAgg(st.s.getDB('unsharded'));
testCRUDAndAgg(st.s.getDB('sharded'));
jsTest.log('downgrading shard servers');
st.upgradeCluster(oldVersion, {upgradeMongos: false, upgradeConfigs: false});
awaitRSClientHosts(st.s, st.rs0.getPrimary(), {ok: true, ismaster: true});
awaitRSClientHosts(st.s, st.rs1.getPrimary(), {ok: true, ismaster: true});
testCRUDAndAgg(st.s.getDB('unsharded'));
testCRUDAndAgg(st.s.getDB('sharded'));
// Restart mongos to clear all cache and force it to do remote calls.
st.restartMongoses();
testCRUDAndAgg(st.s.getDB('unsharded'));
testCRUDAndAgg(st.s.getDB('sharded'));
jsTest.log('downgrading config servers');
st.upgradeCluster(oldVersion, {upgradeMongos: false, upgradeShards: false});
testCRUDAndAgg(st.s.getDB('unsharded'));
testCRUDAndAgg(st.s.getDB('sharded'));
// Restart mongos to clear all cache and force it to do remote calls.
st.restartMongoses();
testCRUDAndAgg(st.s.getDB('unsharded'));
testCRUDAndAgg(st.s.getDB('sharded'));
// Check that version document is unmodified.
version = st.s.getCollection('config.version').findOne();
assert.eq(version.minCompatibleVersion, kMinVersion);
assert.eq(version.currentVersion, kCurrentVerion);
assert.eq(clusterID, version.clusterId);
assert.eq(version.excluding, undefined);
st.stop();
}
})();

View File

@ -1,25 +0,0 @@
/*
* This is a regression test for SERVER-16189, to make sure a replica set with both current and
* prior version nodes can be initialized from the prior version node.
*/
(function() {
"use strict";
var name = "initialize_from_old";
var oldVersion = 'last-lts';
var newVersion = 'latest';
var nodes = {
n0: {binVersion: oldVersion},
n1: {binVersion: newVersion},
n2: {binVersion: newVersion}
};
var rst = new ReplSetTest({nodes: nodes, name: name});
var conns = rst.startSet();
var oldNode = conns[0];
var config = rst.getReplSetConfig();
var response = oldNode.getDB("admin").runCommand({replSetInitiate: config});
assert.commandWorked(response);
// Wait for secondaries to finish their initial sync before shutting down the cluster.
rst.awaitSecondaryNodes();
rst.stopSet();
})();

View File

@ -1,169 +0,0 @@
/**
* Tests that CRUD and aggregation commands through the mongos continue to work as expected on both
* sharded and unsharded collection at each step of cluster upgrade from last-lts to latest.
*/
(function() {
"use strict";
load('./jstests/multiVersion/libs/multi_rs.js');
load('./jstests/multiVersion/libs/multi_cluster.js');
// When checking UUID consistency, the shell attempts to run a command on the node it believes is
// primary in each shard. However, this test restarts shards, and the node that is elected primary
// after the restart may be different from the original primary. Since the shell does not retry on
// NotMaster errors, and whether or not it detects the new primary before issuing the command is
// nondeterministic, skip the consistency check for this test.
TestData.skipCheckingUUIDsConsistentAcrossCluster = true;
const kMinVersion = 5;
const kCurrentVerion = 6;
var testCRUDAndAgg = function(db) {
assert.commandWorked(db.foo.insert({x: 1}));
assert.commandWorked(db.foo.insert({x: -1}));
assert.commandWorked(db.foo.update({x: 1}, {$set: {y: 1}}));
assert.commandWorked(db.foo.update({x: -1}, {$set: {y: 1}}));
var doc1 = db.foo.findOne({x: 1});
assert.eq(1, doc1.y);
var doc2 = db.foo.findOne({x: -1});
assert.eq(1, doc2.y);
assert.commandWorked(db.foo.remove({x: 1}, true));
assert.commandWorked(db.foo.remove({x: -1}, true));
assert.eq(null, db.foo.findOne());
};
var st = new ShardingTest({
shards: 2,
mongos: 1,
other: {
mongosOptions: {binVersion: "last-lts"},
configOptions: {binVersion: "last-lts"},
shardOptions: {binVersion: "last-lts"},
rsOptions: {binVersion: "last-lts"},
rs: true,
}
});
st.configRS.awaitReplication();
// check that config.version document gets initialized properly
var version = st.s.getCollection('config.version').findOne();
assert.eq(version.minCompatibleVersion, kMinVersion);
assert.eq(version.currentVersion, kCurrentVerion);
var clusterID = version.clusterId;
assert.neq(null, clusterID);
assert.eq(version.excluding, undefined);
// Setup sharded collection
assert.commandWorked(st.s.adminCommand({enableSharding: 'sharded'}));
st.ensurePrimaryShard('sharded', st.shard0.shardName);
assert.commandWorked(st.s.adminCommand({shardCollection: 'sharded.foo', key: {x: 1}}));
assert.commandWorked(st.s.adminCommand({split: 'sharded.foo', middle: {x: 0}}));
assert.commandWorked(
st.s.adminCommand({moveChunk: 'sharded.foo', find: {x: 1}, to: st.shard1.shardName}));
testCRUDAndAgg(st.s.getDB('unsharded'));
testCRUDAndAgg(st.s.getDB('sharded'));
// upgrade the config servers first
jsTest.log('upgrading config servers');
st.upgradeCluster("latest", {upgradeMongos: false, upgradeShards: false});
testCRUDAndAgg(st.s.getDB('unsharded'));
testCRUDAndAgg(st.s.getDB('sharded'));
// Restart mongos to clear all cache and force it to do remote calls.
st.restartMongoses();
testCRUDAndAgg(st.s.getDB('unsharded'));
testCRUDAndAgg(st.s.getDB('sharded'));
// Then upgrade the shards.
jsTest.log('upgrading shard servers');
st.upgradeCluster("latest", {upgradeMongos: false, upgradeConfigs: false});
awaitRSClientHosts(st.s, st.rs0.getPrimary(), {ok: true, ismaster: true});
awaitRSClientHosts(st.s, st.rs1.getPrimary(), {ok: true, ismaster: true});
testCRUDAndAgg(st.s.getDB('unsharded'));
testCRUDAndAgg(st.s.getDB('sharded'));
// Restart mongos to clear all cache and force it to do remote calls.
st.restartMongoses();
testCRUDAndAgg(st.s.getDB('unsharded'));
testCRUDAndAgg(st.s.getDB('sharded'));
// Finally, upgrade mongos
jsTest.log('upgrading mongos servers');
st.upgradeCluster("latest", {upgradeConfigs: false, upgradeShards: false});
testCRUDAndAgg(st.s.getDB('unsharded'));
testCRUDAndAgg(st.s.getDB('sharded'));
// Restart mongos to clear all cache and force it to do remote calls.
st.restartMongoses();
testCRUDAndAgg(st.s.getDB('unsharded'));
testCRUDAndAgg(st.s.getDB('sharded'));
// Check that version document is unmodified.
version = st.s.getCollection('config.version').findOne();
assert.eq(version.minCompatibleVersion, kMinVersion);
assert.eq(version.currentVersion, kCurrentVerion);
assert.eq(clusterID, version.clusterId);
assert.eq(version.excluding, undefined);
///////////////////////////////////////////////////////////////////////////////////////////
// Downgrade back
jsTest.log('downgrading mongos servers');
st.upgradeCluster("last-lts", {upgradeConfigs: false, upgradeShards: false});
testCRUDAndAgg(st.s.getDB('unsharded'));
testCRUDAndAgg(st.s.getDB('sharded'));
// Restart mongos to clear all cache and force it to do remote calls.
st.restartMongoses();
testCRUDAndAgg(st.s.getDB('unsharded'));
testCRUDAndAgg(st.s.getDB('sharded'));
jsTest.log('downgrading shard servers');
st.upgradeCluster("last-lts", {upgradeMongos: false, upgradeConfigs: false});
awaitRSClientHosts(st.s, st.rs0.getPrimary(), {ok: true, ismaster: true});
awaitRSClientHosts(st.s, st.rs1.getPrimary(), {ok: true, ismaster: true});
testCRUDAndAgg(st.s.getDB('unsharded'));
testCRUDAndAgg(st.s.getDB('sharded'));
// Restart mongos to clear all cache and force it to do remote calls.
st.restartMongoses();
testCRUDAndAgg(st.s.getDB('unsharded'));
testCRUDAndAgg(st.s.getDB('sharded'));
jsTest.log('downgrading config servers');
st.upgradeCluster("last-lts", {upgradeMongos: false, upgradeShards: false});
testCRUDAndAgg(st.s.getDB('unsharded'));
testCRUDAndAgg(st.s.getDB('sharded'));
// Restart mongos to clear all cache and force it to do remote calls.
st.restartMongoses();
testCRUDAndAgg(st.s.getDB('unsharded'));
testCRUDAndAgg(st.s.getDB('sharded'));
// Check that version document is unmodified.
version = st.s.getCollection('config.version').findOne();
assert.eq(version.minCompatibleVersion, kMinVersion);
assert.eq(version.currentVersion, kCurrentVerion);
assert.eq(clusterID, version.clusterId);
assert.eq(version.excluding, undefined);
st.stop();
})();

View File

@ -14,35 +14,42 @@ checkFCV(adminDB, latestFCV);
// Updating the featureCompatibilityVersion document changes the featureCompatibilityVersion
// server parameter.
assert.commandWorked(adminDB.system.version.update({_id: "featureCompatibilityVersion"},
{$set: {version: lastLTSFCV}}));
checkFCV(adminDB, lastLTSFCV);
for (let oldVersion of [lastLTSFCV, lastContinuousFCV]) {
// Fully downgraded to oldVersion.
assert.commandWorked(adminDB.system.version.update({_id: "featureCompatibilityVersion"},
{$set: {version: oldVersion}}));
checkFCV(adminDB, oldVersion);
assert.commandWorked(adminDB.system.version.update(
{_id: "featureCompatibilityVersion"}, {$set: {version: lastLTSFCV, targetVersion: latestFCV}}));
checkFCV(adminDB, lastLTSFCV, latestFCV);
// Upgrading to lastest.
assert.commandWorked(
adminDB.system.version.update({_id: "featureCompatibilityVersion"},
{$set: {version: oldVersion, targetVersion: latestFCV}}));
checkFCV(adminDB, oldVersion, latestFCV);
assert.commandWorked(adminDB.system.version.update(
{_id: "featureCompatibilityVersion"},
{$set: {version: lastLTSFCV, targetVersion: lastLTSFCV, previousVersion: latestFCV}}));
checkFCV(adminDB, lastLTSFCV, lastLTSFCV);
// Downgrading to oldVersion.
assert.commandWorked(adminDB.system.version.update(
{_id: "featureCompatibilityVersion"},
{$set: {version: oldVersion, targetVersion: oldVersion, previousVersion: latestFCV}}));
checkFCV(adminDB, oldVersion, oldVersion);
// When present, "previousVersion" will always be the latestFCV.
assert.writeErrorWithCode(adminDB.system.version.update({_id: "featureCompatibilityVersion"},
{$set: {previousVersion: lastLTSFCV}}),
4926901);
checkFCV(adminDB, lastLTSFCV, lastLTSFCV);
// When present, "previousVersion" will always be the latestFCV.
assert.writeErrorWithCode(adminDB.system.version.update({_id: "featureCompatibilityVersion"},
{$set: {previousVersion: oldVersion}}),
4926901);
checkFCV(adminDB, oldVersion, oldVersion);
// Downgrading FCV must have a 'previousVersion' field.
assert.writeErrorWithCode(adminDB.system.version.update({_id: "featureCompatibilityVersion"},
{$unset: {previousVersion: true}}),
4926902);
checkFCV(adminDB, lastLTSFCV, lastLTSFCV);
// Downgrading FCV must have a 'previousVersion' field.
assert.writeErrorWithCode(adminDB.system.version.update({_id: "featureCompatibilityVersion"},
{$unset: {previousVersion: true}}),
4926902);
checkFCV(adminDB, oldVersion, oldVersion);
assert.commandWorked(adminDB.system.version.update(
{_id: "featureCompatibilityVersion"},
{$set: {version: latestFCV}, $unset: {targetVersion: true, previousVersion: true}}));
checkFCV(adminDB, latestFCV);
// Reset to latestFCV.
assert.commandWorked(adminDB.system.version.update(
{_id: "featureCompatibilityVersion"},
{$set: {version: latestFCV}, $unset: {targetVersion: true, previousVersion: true}}));
checkFCV(adminDB, latestFCV);
}
// Updating the featureCompatibilityVersion document with an invalid version fails.
assert.writeErrorWithCode(
@ -56,6 +63,11 @@ assert.writeErrorWithCode(adminDB.system.version.update({_id: "featureCompatibil
4926904);
checkFCV(adminDB, latestFCV);
assert.writeErrorWithCode(adminDB.system.version.update({_id: "featureCompatibilityVersion"},
{$set: {targetVersion: lastContinuousFCV}}),
4926904);
checkFCV(adminDB, latestFCV);
assert.writeErrorWithCode(adminDB.system.version.update({_id: "featureCompatibilityVersion"},
{$set: {targetVersion: latestFCV}}),
4926904);