mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 01:21:03 +01:00
263 lines
9.4 KiB
JavaScript
263 lines
9.4 KiB
JavaScript
// dumprestore_helpers.js
|
|
|
|
load('./jstests/multiVersion/libs/verify_collection_data.js');
|
|
|
|
// Given a "test spec" object, runs the specified test.
|
|
//
|
|
// The "test spec" object has the format:
|
|
//
|
|
// {
|
|
// 'serverSourceVersion' : "latest",
|
|
// 'serverDestVersion' : "2.4",
|
|
// 'mongoDumpVersion' : "2.2",
|
|
// 'mongoRestoreVersion' : "latest",
|
|
// 'dumpDir' : dumpDir,
|
|
// 'testDbpath' : testDbpath,
|
|
// 'dumpType' : "mongos",
|
|
// 'restoreType' : "mongod", // "mongos" also supported
|
|
// 'storageEngine': [ "mmapv1" ]
|
|
// }
|
|
//
|
|
// The first four fields are which versions of the various binaries to use in the test.
|
|
//
|
|
// The "dumpDir" field is the external directory to use as scratch space for database dumps.
|
|
//
|
|
// The "testDbpath" is the external directory to use as the server dbpath directory.
|
|
//
|
|
// For the "dumpType" and "restoreType" fields, the following values are supported:
|
|
// - "mongod" - Do the dump or restore by connecting to a single mongod node
|
|
// - "mongos" - Do the dump or restore by connecting to a sharded cluster
|
|
//
|
|
function multiVersionDumpRestoreTest(configObj) {
|
|
// First sanity check the arguments in our configObj
|
|
var requiredKeys = [
|
|
'serverSourceVersion',
|
|
'serverDestVersion',
|
|
'mongoDumpVersion',
|
|
'mongoRestoreVersion',
|
|
'dumpDir',
|
|
'testDbpath',
|
|
'dumpType',
|
|
'restoreType',
|
|
'storageEngine'
|
|
];
|
|
|
|
var i;
|
|
|
|
for (i = 0; i < requiredKeys.length; i++) {
|
|
assert(configObj.hasOwnProperty(requiredKeys[i]),
|
|
"Missing required key: " + requiredKeys[i] + " in config object");
|
|
}
|
|
|
|
resetDbpath(configObj.dumpDir);
|
|
resetDbpath(configObj.testDbpath);
|
|
if (configObj.dumpType === "mongos") {
|
|
var shardingTestConfig = {
|
|
name: testBaseName + "_sharded_source",
|
|
mongos: [{binVersion: configObj.serverSourceVersion}],
|
|
shards: [{
|
|
binVersion: configObj.serverSourceVersion,
|
|
storageEngine: configObj.storageEngine
|
|
}],
|
|
config: [{binVersion: configObj.serverSourceVersion}]
|
|
};
|
|
var shardingTest = new ShardingTest(shardingTestConfig);
|
|
var serverSource = shardingTest.s;
|
|
} else {
|
|
var serverSource = MongoRunner.runMongod({
|
|
binVersion: configObj.serverSourceVersion,
|
|
dbpath: configObj.testDbpath,
|
|
storageEngine: configObj.storageEngine
|
|
});
|
|
}
|
|
var sourceDB = serverSource.getDB(testBaseName);
|
|
|
|
// Create generators to create collections with our seed data
|
|
// Testing with both a capped collection and a normal collection
|
|
var cappedCollGen = new CollectionDataGenerator({"capped": true});
|
|
var collGen = new CollectionDataGenerator({"capped": false});
|
|
|
|
// Create collections using the different generators
|
|
var sourceCollCapped = createCollectionWithData(sourceDB, "cappedColl", cappedCollGen);
|
|
var sourceColl = createCollectionWithData(sourceDB, "coll", collGen);
|
|
|
|
// Record the current collection states for later validation
|
|
var cappedCollValid = new CollectionDataValidator();
|
|
cappedCollValid.recordCollectionData(sourceCollCapped);
|
|
var collValid = new CollectionDataValidator();
|
|
collValid.recordCollectionData(sourceColl);
|
|
|
|
// Dump using the specified version of mongodump from the running mongod or mongos instance.
|
|
if (configObj.dumpType === "mongod") {
|
|
MongoRunner.runMongoTool("mongodump", {
|
|
out: configObj.dumpDir,
|
|
binVersion: configObj.mongoDumpVersion,
|
|
host: serverSource.host,
|
|
db: testBaseName
|
|
});
|
|
MongoRunner.stopMongod(serverSource);
|
|
} else { /* "mongos" */
|
|
MongoRunner.runMongoTool("mongodump", {
|
|
out: configObj.dumpDir,
|
|
binVersion: configObj.mongoDumpVersion,
|
|
host: serverSource.host,
|
|
db: testBaseName
|
|
});
|
|
shardingTest.stop();
|
|
}
|
|
|
|
// Restore using the specified version of mongorestore
|
|
if (configObj.restoreType === "mongod") {
|
|
var serverDest = MongoRunner.runMongod(
|
|
{binVersion: configObj.serverDestVersion, storageEngine: configObj.storageEngine});
|
|
|
|
MongoRunner.runMongoTool("mongorestore", {
|
|
dir: configObj.dumpDir + "/" + testBaseName,
|
|
binVersion: configObj.mongoRestoreVersion,
|
|
host: serverDest.host,
|
|
db: testBaseName
|
|
});
|
|
} else { /* "mongos" */
|
|
var shardingTestConfig = {
|
|
name: testBaseName + "_sharded_dest",
|
|
mongos: [{binVersion: configObj.serverDestVersion}],
|
|
shards:
|
|
[{binVersion: configObj.serverDestVersion, storageEngine: configObj.storageEngine}],
|
|
config: [{binVersion: configObj.serverDestVersion}]
|
|
};
|
|
var shardingTest = new ShardingTest(shardingTestConfig);
|
|
serverDest = shardingTest.s;
|
|
MongoRunner.runMongoTool("mongorestore", {
|
|
dir: configObj.dumpDir + "/" + testBaseName,
|
|
binVersion: configObj.mongoRestoreVersion,
|
|
host: serverDest.host,
|
|
db: testBaseName
|
|
});
|
|
}
|
|
|
|
var destDB = serverDest.getDB(testBaseName);
|
|
|
|
// Get references to our destinations collections
|
|
// XXX: These are in the global scope (no "var"), but they need to be global to be in scope for
|
|
// the "assert.soon" calls below.
|
|
destColl = destDB.getCollection("coll");
|
|
destCollCapped = destDB.getCollection("cappedColl");
|
|
|
|
// Wait until we actually have data or timeout
|
|
assert.soon("destColl.findOne()", "no data after sleep");
|
|
assert.soon("destCollCapped.findOne()", "no data after sleep");
|
|
|
|
let destDbVersion = destDB.version();
|
|
|
|
// The mongorestore tool removes the "v" field when creating indexes from a dump. This allows
|
|
// indexes to be built with the latest supported index version. We therefore remove the "v"
|
|
// field when comparing whether the indexes we built are equivalent.
|
|
const options = {indexSpecFieldsToSkip: ["v"]};
|
|
|
|
// Validate that our collections were properly restored
|
|
assert(collValid.validateCollectionData(destColl, destDbVersion, options));
|
|
assert(cappedCollValid.validateCollectionData(destCollCapped, destDbVersion, options));
|
|
|
|
if (configObj.restoreType === "mongos") {
|
|
shardingTest.stop();
|
|
} else {
|
|
MongoRunner.stopMongod(serverDest);
|
|
}
|
|
}
|
|
|
|
// Given an object with list values, returns a cursor that returns an object for every combination
|
|
// of selections of the values in the lists.
|
|
//
|
|
// Usage:
|
|
// var permutationCursor = getPermutationIterator({"a":[0,1], "b":[2,3]});
|
|
// while (permutationCursor.hasNext()) {
|
|
// var permutation = permutationCursor.next();
|
|
// printjson(permutation);
|
|
// }
|
|
//
|
|
// This will print:
|
|
//
|
|
// { "a" : 0, "b" : 2 }
|
|
// { "a" : 1, "b" : 2 }
|
|
// { "a" : 0, "b" : 3 }
|
|
// { "a" : 1, "b" : 3 }
|
|
function getPermutationIterator(permsObj) {
|
|
function getAllPermutations(permsObj) {
|
|
// Split our permutations object into "first" and "rest"
|
|
var gotFirst = false;
|
|
var firstKey;
|
|
var firstValues;
|
|
var restObj = {};
|
|
for (var key in permsObj) {
|
|
if (permsObj.hasOwnProperty(key)) {
|
|
if (gotFirst) {
|
|
restObj[key] = permsObj[key];
|
|
} else {
|
|
firstKey = key;
|
|
firstValues = permsObj[key];
|
|
gotFirst = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Our base case is an empty object, which just has a single permutation, "{}"
|
|
if (!gotFirst) {
|
|
return [{}];
|
|
}
|
|
|
|
// Iterate the possibilities for "first" and for each one recursively get all the
|
|
// permutations for "rest"
|
|
var resultPermObjs = [];
|
|
var i = 0;
|
|
var j = 0;
|
|
for (i = 0; i < firstValues.length; i++) {
|
|
var subPermObjs = getAllPermutations(restObj);
|
|
for (j = 0; j < subPermObjs.length; j++) {
|
|
subPermObjs[j][firstKey] = firstValues[i];
|
|
resultPermObjs.push(subPermObjs[j]);
|
|
}
|
|
}
|
|
return resultPermObjs;
|
|
}
|
|
|
|
var allPermutations = getAllPermutations(permsObj);
|
|
var currentPermutation = 0;
|
|
|
|
return {
|
|
"next": function() {
|
|
return allPermutations[currentPermutation++];
|
|
},
|
|
"hasNext": function() {
|
|
return currentPermutation < allPermutations.length;
|
|
}
|
|
};
|
|
}
|
|
|
|
// Given a "test spec" object, runs all test combinations.
|
|
//
|
|
// The "test spec" object has the format:
|
|
//
|
|
// {
|
|
// 'serverSourceVersion' : [ "latest", "2.4" ],
|
|
// 'serverDestVersion' :[ "latest", "2.4" ],
|
|
// 'mongoDumpVersion' :[ "latest", "2.4" ],
|
|
// 'mongoRestoreVersion' :[ "latest", "2.4" ],
|
|
// 'dumpDir' : [ dumpDir ],
|
|
// 'testDbpath' : [ testDbpath ],
|
|
// 'dumpType' : [ "mongod", "mongos" ],
|
|
// 'restoreType' : [ "mongod", "mongos" ],
|
|
// 'storageEngine': [ "mmapv1" ]
|
|
// }
|
|
//
|
|
// This function will run a test for each possible combination of the parameters. See comments on
|
|
// "getPermutationIterator" above.
|
|
function runAllDumpRestoreTests(testCasePermutations) {
|
|
var testCaseCursor = getPermutationIterator(testCasePermutations);
|
|
while (testCaseCursor.hasNext()) {
|
|
var testCase = testCaseCursor.next();
|
|
print("Running multiversion mongodump mongorestore test:");
|
|
printjson(testCase);
|
|
multiVersionDumpRestoreTest(testCase);
|
|
}
|
|
}
|