summaryrefslogtreecommitdiff
path: root/jstests/dur/diskfull.js
blob: 628db20bd923f828418b370052018269a6ac69c4 (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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/** Test running out of disk space with durability enabled.
To set up the test, it's required to set up a small partition something like the following:
sudo umount /data/db/diskfulltest/
rm -rf /data/db/diskfulltest
mkdir -p /data/images
dd bs=512 count=83968 if=/dev/zero of=/data/images/diskfulltest.img
/sbin/mkfs.ext2 -m 0 -F /data/images/diskfulltest.img
mkdir -p /data/db/diskfulltest
mount -o loop /data/images/diskfulltest.img /data/db/diskfulltest
*/

startPath = MongoRunner.dataDir + "/diskfulltest";
recoverPath = MongoRunner.dataDir + "/dur_diskfull";

doIt = false;
files = listFiles(MongoRunner.dataDir);
for (i in files) {
    if (files[i].name == startPath) {
        doIt = true;
    }
}

if (!doIt) {
    print("path " + startPath + " missing, skipping diskfull test");
    doIt = false;
}

function checkNoJournalFiles(path, pass) {
    var files = listFiles(path);
    if (files.some(function(f) {
            return f.name.indexOf("prealloc") < 0;
        })) {
        if (pass == null) {
            // wait a bit longer for mongod to potentially finish if it is still running.
            sleep(10000);
            return checkNoJournalFiles(path, 1);
        }
        print("\n\n\n");
        print("FAIL path:" + path);
        print("unexpected files:");
        printjson(files);
        assert(false, "FAIL a journal/lsn file is present which is unexpected");
    }
}

/** Clear dbpath without removing and recreating diskfulltest directory, as resetDbpath does */
function clear() {
    files = listFiles(startPath);
    files.forEach(function(x) {
        removeFile(x.name);
    });
}

function log(str) {
    print();
    if (str)
        print(testname + " step " + step++ + " " + str);
    else
        print(testname + " step " + step++);
}

function work() {
    log("work");
    try {
        var d = conn.getDB("test");
        var big = new Array(5000).toString();
        var bulk = d.foo.initializeUnorderedBulkOp();
        // This part of the test depends on the partition size used in the build env
        // Currently, unused, but with larger partitions insert enough documents here
        // to create a second db file
        for (i = 0; i < 1; ++i) {
            bulk.insert({_id: i, b: big});
        }
        assert.writeOK(bulk.execute());
    } catch (e) {
        print(e);
        raise(e);
    } finally {
        log("endwork");
    }
}

function verify() {
    log("verify");
    var d = conn.getDB("test");
    c = d.foo.count();
    v = d.foo.validate();
    // not much we can guarantee about the writes, just validate when possible
    if (c != 0 && !v.valid) {
        printjson(v);
        print(c);
        assert(v.valid);
        assert.gt(c, 0);
    }
}

function runFirstMongodAndFillDisk() {
    log();

    clear();
    conn = MongoRunner.runMongod({
        restart: true,
        cleanData: false,
        dbpath: startPath,
        journal: "",
        smallfiles: "",
        journalOptions: 8 + 64,
        noprealloc: ""
    });

    assert.throws(work, null, "no exception thrown when exceeding disk capacity");
    MongoRunner.stopMongod(conn);

    sleep(5000);
}

function runSecondMongdAndRecover() {
    // restart and recover
    log();
    conn = MongoRunner.runMongod({
        restart: true,
        cleanData: false,
        dbpath: startPath,
        journal: "",
        smallfiles: "",
        journalOptions: 8 + 64,
        noprealloc: ""
    });
    verify();

    log("stop");
    MongoRunner.stopMongod(conn);

    // stopMongod seems to be asynchronous (hmmm) so we sleep here.
    sleep(5000);

    // at this point, after clean shutdown, there should be no journal files
    log("check no journal files");
    checkNoJournalFiles(startPath + "/journal/");

    log();
}

function someWritesInJournal() {
    runFirstMongodAndFillDisk();
    runSecondMongdAndRecover();
}

function noWritesInJournal() {
    // It is too difficult to consistently trigger cases where there are no existing journal files
    // due to lack of disk space, but
    // if we were to test this case we would need to manualy remove the lock file.
    //    removeFile( startPath + "/mongod.lock" );
}

if (doIt) {
    var testname = "dur_diskfull";
    var step = 1;
    var conn = null;

    someWritesInJournal();
    noWritesInJournal();

    print(testname + " SUCCESS");
}