94 lines
3.4 KiB
JavaScript
94 lines
3.4 KiB
JavaScript
// Test checksum validation of journal files.
|
|
|
|
var testname = "dur_checksum";
|
|
var path = MongoRunner.dataPath + testname;
|
|
|
|
if (0) {
|
|
// This is used to create the prototype journal file.
|
|
jsTest.log("Just creating prototype journal, not testing anything");
|
|
var conn = MongoRunner.runMongod({dbpath: path, journal: ""});
|
|
var db = conn.getDB("test");
|
|
|
|
// each insert is in it's own commit.
|
|
db.foo.insert({a: 1});
|
|
db.runCommand({getlasterror: 1, j: 1});
|
|
|
|
db.foo.insert({a: 2});
|
|
db.runCommand({getlasterror: 1, j: 1});
|
|
|
|
MongoRunner.stopMongod(conn.port, /*signal*/ 9);
|
|
|
|
jsTest.log("Journal file left at " + path + "/journal/j._0");
|
|
quit();
|
|
// A hex editor must be used to replace the checksums of specific journal sections with
|
|
// "0BADC0DE 1BADC0DE 2BADC0DE 3BADCD0E"
|
|
}
|
|
|
|
function startMongodWithJournal() {
|
|
return MongoRunner.runMongod({
|
|
restart: true,
|
|
cleanData: false,
|
|
dbpath: path,
|
|
journal: "",
|
|
smallfiles: "",
|
|
journalOptions: 1 /*DurDumpJournal*/
|
|
});
|
|
}
|
|
|
|
jsTest.log("Starting with good.journal to make sure everything works");
|
|
resetDbpath(path);
|
|
mkdir(path + '/journal');
|
|
copyFile("jstests/libs/dur_checksum_good.journal", path + "/journal/j._0");
|
|
var conn = startMongodWithJournal();
|
|
var db = conn.getDB('test');
|
|
assert.eq(db.foo.count(), 2);
|
|
MongoRunner.stopMongod(conn.port);
|
|
|
|
// dur_checksum_bad_last.journal is good.journal with the bad checksum on the last section.
|
|
jsTest.log("Starting with bad_last.journal");
|
|
resetDbpath(path);
|
|
mkdir(path + '/journal');
|
|
copyFile("jstests/libs/dur_checksum_bad_last.journal", path + "/journal/j._0");
|
|
conn = startMongodWithJournal();
|
|
var db = conn.getDB('test');
|
|
assert.eq(db.foo.count(), 1); // 2nd insert "never happened"
|
|
MongoRunner.stopMongod(conn.port);
|
|
|
|
// dur_checksum_bad_first.journal is good.journal with the bad checksum on the prior section.
|
|
// This means there is a good commit after the bad one. We currently ignore this, but a future
|
|
// version of the server may be able to detect this case.
|
|
jsTest.log("Starting with bad_first.journal");
|
|
resetDbpath(path);
|
|
mkdir(path + '/journal');
|
|
copyFile("jstests/libs/dur_checksum_bad_first.journal", path + "/journal/j._0");
|
|
conn = startMongodWithJournal();
|
|
var db = conn.getDB('test');
|
|
assert.eq(db.foo.count(), 0); // Neither insert happened.
|
|
MongoRunner.stopMongod(conn.port);
|
|
|
|
// If we detect an error in a non-final journal file, that is considered an error.
|
|
jsTest.log("Starting with bad_last.journal followed by good.journal");
|
|
resetDbpath(path);
|
|
mkdir(path + '/journal');
|
|
copyFile("jstests/libs/dur_checksum_bad_first.journal", path + "/journal/j._0");
|
|
copyFile("jstests/libs/dur_checksum_good.journal", path + "/journal/j._1");
|
|
|
|
exitCode = runMongoProgram("mongod",
|
|
"--port",
|
|
allocatePort(),
|
|
"--dbpath",
|
|
path,
|
|
"--journal",
|
|
"--smallfiles",
|
|
"--journalOptions",
|
|
1 /*DurDumpJournal*/
|
|
+
|
|
2 /*DurScanOnly*/);
|
|
|
|
assert.eq(exitCode, 100 /*EXIT_UNCAUGHT*/);
|
|
|
|
// TODO Possibly we could check the mongod log to verify that the correct type of exception was
|
|
// thrown. But that would introduce a dependency on the mongod log format, which we may not want.
|
|
|
|
jsTest.log("SUCCESS checksum.js");
|