summaryrefslogtreecommitdiff
path: root/jstests/dur/checksum.js
blob: 1270e337a876602275da1cd3b732461616cf4b0b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// 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 = startMongodEmpty("--port", 30001, "--dbpath", path, "--dur");
    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})

    stopMongod(30001, /*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 startMongodNoReset("--port", 30001,
                              "--dbpath", path,
                              "--dur",
                              "--smallfiles",
                              "--durOptions", 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);
stopMongod(30001);


// 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"
stopMongod(30001);


// 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.
stopMongod(30001);

// 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", 30001,
                           "--dbpath", path,
                           "--dur",
                           "--smallfiles",
                           "--durOptions", 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");